From 578351136617d9a722fea846b9defdf3aa5d6680 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 2 Mar 2020 18:38:31 +0300 Subject: [PATCH 01/61] ASC.CRM: first commit --- products/ASC.CRM/Server/ASC.CRM.csproj | 159 + .../ASC.CRM/Server/Classes/CRMSettings.cs | 248 ++ products/ASC.CRM/Server/Classes/CSVReader.cs | 361 ++ .../Server/Classes/CSVReaderExtension.cs | 90 + .../Server/Classes/ContactPhotoManager.cs | 658 ++++ products/ASC.CRM/Server/Classes/Global.cs | 335 ++ .../Server/Classes/ImportFromCSVManager.cs | 107 + .../Server/Classes/InvoiceFormattedData.cs | 688 ++++ .../Server/Classes/LocalizedEnumConverter.cs | 292 ++ .../Server/Classes/OrganisationLogoManager.cs | 178 + .../ASC.CRM/Server/Classes/PathProvider.cs | 108 + .../ASC.CRM/Server/Classes/SignalRHelper.cs | 70 + .../SocialMedia/SocialMediaAccountNotFound.cs | 35 + .../SocialMediaImageDescription.cs | 41 + .../Classes/SocialMedia/SocialMediaUI.cs | 163 + .../Classes/SocialMedia/TwitterApiHelper.cs | 53 + .../ASC.CRM/Server/Classes/StringConverter.cs | 368 ++ .../Server/Classes/SubscriptionManager.cs | 136 + .../Server/Classes/TwilioController.cs | 498 +++ .../ASC.CRM/Server/Classes/UrlConstant.cs | 51 + products/ASC.CRM/Server/Classes/VoipEngine.cs | 296 ++ .../CRMsSpaceUsageStatManager.cs | 63 + .../Server/Configuration/ProductEntryPoint.cs | 331 ++ .../Server/Configuration/SearchHandler.cs | 70 + .../Server/Configuration/VoipModule.cs | 118 + products/ASC.CRM/Server/Core/CRMConstants.cs | 37 + products/ASC.CRM/Server/Core/DIHelper.cs | 75 + .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 316 ++ products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 602 ++++ .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 1921 ++++++++++ .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 343 ++ .../Server/Core/Dao/CurrencyInfoDao.cs | 95 + .../Server/Core/Dao/CurrencyRateDao.cs | 168 + .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 538 +++ .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 169 + products/ASC.CRM/Server/Core/Dao/DealDao.cs | 896 +++++ .../Server/Core/Dao/DealMilestoneDao.cs | 289 ++ products/ASC.CRM/Server/Core/Dao/FileDao.cs | 91 + .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 940 +++++ .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 490 +++ .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 289 ++ .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 262 ++ .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 586 ++++ .../Server/Core/Dao/ListItemHistoryDao.cs | 238 ++ .../ASC.CRM/Server/Core/Dao/ManagerDao.cs | 93 + .../Server/Core/Dao/RelationshipEventDao.cs | 660 ++++ products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 2231 ++++++++++++ products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 442 +++ products/ASC.CRM/Server/Core/Dao/TagDao.cs | 430 +++ products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 1099 ++++++ .../Core/Dao/TaskTemplateContainerDao.cs | 348 ++ products/ASC.CRM/Server/Core/DomainObject.cs | 70 + .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 691 ++++ products/ASC.CRM/Server/Core/EF/CrmCase.cs | 32 + products/ASC.CRM/Server/Core/EF/CrmContact.cs | 53 + .../ASC.CRM/Server/Core/EF/CrmContactInfo.cs | 33 + .../ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs | 29 + .../ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs | 35 + products/ASC.CRM/Server/Core/EF/CrmDeal.cs | 53 + .../Server/Core/EF/CrmDealMilestone.cs | 32 + .../Server/Core/EF/CrmEntityContact.cs | 22 + .../ASC.CRM/Server/Core/EF/CrmEntityTag.cs | 22 + .../Server/Core/EF/CrmFieldDescription.cs | 29 + .../ASC.CRM/Server/Core/EF/CrmFieldValue.cs | 30 + products/ASC.CRM/Server/Core/EF/CrmInvoice.cs | 65 + .../ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs | 49 + .../ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs | 37 + .../ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs | 35 + .../ASC.CRM/Server/Core/EF/CrmListItem.cs | 31 + .../Server/Core/EF/CrmOrganisationLogo.cs | 26 + .../ASC.CRM/Server/Core/EF/CrmProjects.cs | 22 + .../Server/Core/EF/CrmRelationshipEvent.cs | 39 + .../ASC.CRM/Server/Core/EF/CrmReportFile.cs | 25 + products/ASC.CRM/Server/Core/EF/CrmTag.cs | 23 + products/ASC.CRM/Server/Core/EF/CrmTask.cs | 51 + .../ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs | 48 + .../Core/EF/CrmTaskTemplateContainer.cs | 33 + .../Server/Core/EF/CrmTaskTemplateTask.cs | 22 + .../ASC.CRM/Server/Core/EF/CrmVoipCalls.cs | 48 + .../ASC.CRM/Server/Core/EF/CrmVoipNumber.cs | 25 + products/ASC.CRM/Server/Core/EF/IDbCrm.cs | 12 + .../ASC.CRM/Server/Core/Entities/Cases.cs | 62 + .../ASC.CRM/Server/Core/Entities/Comment.cs | 55 + .../ASC.CRM/Server/Core/Entities/Contact.cs | 143 + .../Server/Core/Entities/ContactInfo.cs | 92 + .../Server/Core/Entities/CurrencyInfo.cs | 95 + .../Server/Core/Entities/CurrencyRate.cs | 52 + .../Server/Core/Entities/CustomField.cs | 70 + products/ASC.CRM/Server/Core/Entities/Deal.cs | 118 + .../Server/Core/Entities/DealMilestone.cs | 65 + .../ASC.CRM/Server/Core/Entities/Filter.cs | 555 +++ .../ASC.CRM/Server/Core/Entities/Invoice.cs | 141 + .../Server/Core/Entities/InvoiceItem.cs | 89 + .../Server/Core/Entities/InvoiceLine.cs | 52 + .../Server/Core/Entities/InvoiceTax.cs | 71 + .../ASC.CRM/Server/Core/Entities/ListItem.cs | 65 + .../Server/Core/Entities/ListItemHistory.cs | 44 + .../ASC.CRM/Server/Core/Entities/OrderBy.cs | 53 + .../Server/Core/Entities/RelationshipEvent.cs | 82 + .../ASC.CRM/Server/Core/Entities/Report.cs | 109 + products/ASC.CRM/Server/Core/Entities/Task.cs | 80 + .../Core/Entities/TaskTemplateContainer.cs | 73 + .../ASC.CRM/Server/Core/Enums/BidTypeEnum.cs | 39 + .../Core/Enums/CommunicationTypeEnum.cs | 37 + .../Core/Enums/ContactInfoCategoryEnum.cs | 71 + .../Server/Core/Enums/ContactInfoTypeEnum.cs | 55 + .../Core/Enums/ContactListViewTypeEnum.cs | 48 + .../Core/Enums/ContactSelectorTypeEnum.cs | 43 + .../Server/Core/Enums/CustomFieldTypeEnum.cs | 42 + .../Server/Core/Enums/DealMilestoneStatus.cs | 44 + .../Server/Core/Enums/EntityTypeEnum.cs | 46 + .../Server/Core/Enums/InvoiceStatus.cs | 41 + .../Core/Enums/InvoiceTemplateTypeEnum.cs | 45 + .../ASC.CRM/Server/Core/Enums/ListTypeEnum.cs | 52 + .../Server/Core/Enums/ProgressStatus.cs | 36 + .../Server/Core/Enums/ReportTimePeriodEnum.cs | 53 + .../Server/Core/Enums/ReportTypeEnum.cs | 42 + .../ASC.CRM/Server/Core/Enums/ShareType.cs | 43 + .../Server/Core/Enums/SortedByTypeEnum.cs | 91 + .../Server/Core/Search/BundleSearch.cs | 160 + .../Server/Core/Search/CasesWrapper.cs | 53 + .../Server/Core/Search/ContactsWrapper.cs | 95 + .../Server/Core/Search/DealsWrapper.cs | 58 + .../Server/Core/Search/EmailWrapper.cs | 115 + .../Server/Core/Search/EventsWrapper.cs | 66 + .../Server/Core/Search/FieldsWrapper.cs | 64 + .../ASC.CRM/Server/Core/Search/InfoWrapper.cs | 101 + .../Server/Core/Search/InvoicesWrapper.cs | 65 + .../Server/Core/Search/TasksWrapper.cs | 58 + .../Security/CRMSecurityObjectProvider.cs | 124 + .../Server/Core/Security/CRMSecutiry.cs | 938 +++++ .../Core/Security/FileSecurityProvider.cs | 121 + ...ONLYOFFICE Sales funnel sample report.xlsx | Bin 0 -> 17143 bytes ... Summary for the moment sample report.xlsx | Bin 0 -> 21201 bytes ... Summary for the period sample report.xlsx | Bin 0 -> 21172 bytes ...ONLYOFFICE Sales funnel sample report.xlsx | Bin 0 -> 17490 bytes ... Summary for the moment sample report.xlsx | Bin 0 -> 21540 bytes ... Summary for the period sample report.xlsx | Bin 0 -> 21559 bytes .../HttpHandlers/ContactPhotoHandler.cs | 126 + .../Server/HttpHandlers/FileHandler.ashx.cs | 149 + .../HttpHandlers/FileUploaderHandler.cs | 83 + .../Server/HttpHandlers/ImportFileHandler.cs | 68 + .../HttpHandlers/OrganisationLogoHandler.cs | 87 + .../HttpHandlers/WebToLeadFromHandler.ashx.cs | 392 +++ .../Server/HttpHandlers/filehandler.ashx | 4 + .../HttpHandlers/webtoleadfromhandler.ashx | 4 + .../Server/InvoiceTemplates/template.docx | Bin 0 -> 12050 bytes products/ASC.CRM/Server/Program.cs | 26 + .../Server/Properties/launchSettings.json | 30 + .../SalesByManagers.docbuilder | 201 ++ .../ReportTemplates/SalesForecast.docbuilder | 165 + .../ReportTemplates/SalesFunnel.docbuilder | 329 ++ .../SummaryAtThisMoment.docbuilder | 327 ++ .../SummaryForThePeriod.docbuilder | 375 ++ .../WorkloadByContacts.docbuilder | 289 ++ .../WorkloadByDeals.docbuilder | 269 ++ .../WorkloadByInvoices.docbuilder | 211 ++ .../WorkloadByTasks.docbuilder | 348 ++ .../ReportTemplates/WorkloadByVoip.docbuilder | 256 ++ .../Resources/CRMCasesResource.Designer.cs | 468 +++ .../Server/Resources/CRMCasesResource.resx | 255 ++ .../Resources/CRMCommonResource.Designer.cs | 3079 +++++++++++++++++ .../Server/Resources/CRMCommonResource.resx | 1126 ++++++ .../Resources/CRMContactResource.Designer.cs | 1867 ++++++++++ .../Server/Resources/CRMContactResource.resx | 724 ++++ .../Resources/CRMDealResource.Designer.cs | 954 +++++ .../Server/Resources/CRMDealResource.resx | 417 +++ .../Resources/CRMEnumResource.Designer.cs | 684 ++++ .../Server/Resources/CRMEnumResource.resx | 327 ++ .../Resources/CRMErrorsResource.Designer.cs | 423 +++ .../Server/Resources/CRMErrorsResource.resx | 240 ++ .../Resources/CRMInvoiceResource.Designer.cs | 1575 +++++++++ .../Server/Resources/CRMInvoiceResource.resx | 624 ++++ .../Resources/CRMJSResource.Designer.cs | 1558 +++++++++ .../Server/Resources/CRMJSResource.resx | 619 ++++ .../Resources/CRMReportResource.Designer.cs | 1181 +++++++ .../Server/Resources/CRMReportResource.resx | 494 +++ .../Resources/CRMSettingResource.Designer.cs | 1580 +++++++++ .../Server/Resources/CRMSettingResource.resx | 629 ++++ .../CRMSocialMediaResource.Designer.cs | 216 ++ .../Resources/CRMSocialMediaResource.resx | 171 + .../Resources/CRMTaskResource.Designer.cs | 765 ++++ .../Server/Resources/CRMTaskResource.resx | 354 ++ .../Resources/CRMVoipResource.Designer.cs | 847 +++++ .../Server/Resources/CRMVoipResource.resx | 382 ++ .../CRMPatternResource.Designer.cs | 325 ++ .../NotifyService/CRMPatternResource.resx | 306 ++ .../Services/NotifyService/NotifyClient.cs | 553 +++ .../Services/NotifyService/NotifyConstants.cs | 71 + .../Services/NotifyService/NotifySource.cs | 79 + .../Services/NotifyService/patterns.xml | 148 + products/ASC.CRM/Server/Startup.cs | 49 + .../Server/Templates/CasesTemplates.html | 129 + .../CommonCustomFieldsTemplates.html | 144 + .../Server/Templates/CommonTemplates.html | 389 +++ .../Templates/ContactInfoCardTemplate.html | 87 + .../Templates/ContactSelectorTemplates.html | 161 + .../Server/Templates/ContactsTemplates.html | 366 ++ .../Templates/DealsSelectorTemplates.html | 26 + .../Server/Templates/DealsTemplates.html | 366 ++ .../Server/Templates/InvoicesTemplates.html | 624 ++++ .../Server/Templates/SettingsTemplates.html | 806 +++++ .../Templates/SimpleContactListTemplate.html | 73 + .../Server/Templates/TasksTemplates.html | 283 ++ .../Server/Templates/VoipTemplates.html | 364 ++ .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 356 ++ products/ASC.CRM/Server/Utils/ExportToCSV.cs | 1426 ++++++++ products/ASC.CRM/Server/Utils/FileHelper.cs | 94 + .../Server/Utils/Import/CSV/CsvReader.cs | 32 + .../Server/Utils/Import/CSV/ImportBase.cs | 49 + .../Utils/Import/CSV/ImportCSVSettings.cs | 103 + .../Server/Utils/Import/CSV/ImportCases.cs | 224 ++ .../Server/Utils/Import/CSV/ImportContacts.cs | 698 ++++ .../Utils/Import/CSV/ImportDataOperation.cs | 272 ++ .../Server/Utils/Import/CSV/ImportDeals.cs | 367 ++ .../Server/Utils/Import/CSV/ImportFromCSV.cs | 141 + .../Server/Utils/Import/CSV/ImportTasks.cs | 168 + products/ASC.CRM/Server/Utils/MailSender.cs | 1009 ++++++ products/ASC.CRM/Server/Utils/PdfCreator.cs | 720 ++++ .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 164 + products/ASC.CRM/Server/Utils/ReportHelper.cs | 227 ++ .../Server/appsettings.Development.json | 9 + products/ASC.CRM/Server/appsettings.json | 10 + 223 files changed, 62615 insertions(+) create mode 100644 products/ASC.CRM/Server/ASC.CRM.csproj create mode 100644 products/ASC.CRM/Server/Classes/CRMSettings.cs create mode 100644 products/ASC.CRM/Server/Classes/CSVReader.cs create mode 100644 products/ASC.CRM/Server/Classes/CSVReaderExtension.cs create mode 100644 products/ASC.CRM/Server/Classes/ContactPhotoManager.cs create mode 100644 products/ASC.CRM/Server/Classes/Global.cs create mode 100644 products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs create mode 100644 products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs create mode 100644 products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs create mode 100644 products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs create mode 100644 products/ASC.CRM/Server/Classes/PathProvider.cs create mode 100644 products/ASC.CRM/Server/Classes/SignalRHelper.cs create mode 100644 products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaAccountNotFound.cs create mode 100644 products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs create mode 100644 products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaUI.cs create mode 100644 products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs create mode 100644 products/ASC.CRM/Server/Classes/StringConverter.cs create mode 100644 products/ASC.CRM/Server/Classes/SubscriptionManager.cs create mode 100644 products/ASC.CRM/Server/Classes/TwilioController.cs create mode 100644 products/ASC.CRM/Server/Classes/UrlConstant.cs create mode 100644 products/ASC.CRM/Server/Classes/VoipEngine.cs create mode 100644 products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs create mode 100644 products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs create mode 100644 products/ASC.CRM/Server/Configuration/SearchHandler.cs create mode 100644 products/ASC.CRM/Server/Configuration/VoipModule.cs create mode 100644 products/ASC.CRM/Server/Core/CRMConstants.cs create mode 100644 products/ASC.CRM/Server/Core/DIHelper.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/AbstractDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/CasesDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/ContactDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/DaoFactory.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/DealDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/FileDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/ListItemDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/ManagerDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/ReportDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/SearchDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/TagDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/TaskDao.cs create mode 100644 products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs create mode 100644 products/ASC.CRM/Server/Core/DomainObject.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CRMDbContext.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmCase.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmContact.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmContactInfo.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmDeal.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmDealMilestone.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmEntityContact.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmEntityTag.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmFieldDescription.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmFieldValue.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmInvoice.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmListItem.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmOrganisationLogo.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmProjects.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmRelationshipEvent.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmReportFile.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmTag.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmTask.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmTaskTemplateContainer.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmTaskTemplateTask.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmVoipCalls.cs create mode 100644 products/ASC.CRM/Server/Core/EF/CrmVoipNumber.cs create mode 100644 products/ASC.CRM/Server/Core/EF/IDbCrm.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Cases.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Comment.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Contact.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/ContactInfo.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/CustomField.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Deal.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/DealMilestone.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Filter.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Invoice.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/ListItem.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/OrderBy.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Report.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/Task.cs create mode 100644 products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/BidTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/CommunicationTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ContactSelectorTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ReportTimePeriodEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ReportTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/ShareType.cs create mode 100644 products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs create mode 100644 products/ASC.CRM/Server/Core/Search/BundleSearch.cs create mode 100644 products/ASC.CRM/Server/Core/Search/CasesWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/DealsWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/EmailWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/EventsWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/InfoWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/TasksWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs create mode 100644 products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs create mode 100644 products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs create mode 100644 products/ASC.CRM/Server/DocStore/default/ONLYOFFICE Sales funnel sample report.xlsx create mode 100644 products/ASC.CRM/Server/DocStore/default/ONLYOFFICE Summary for the moment sample report.xlsx create mode 100644 products/ASC.CRM/Server/DocStore/default/ONLYOFFICE Summary for the period sample report.xlsx create mode 100644 products/ASC.CRM/Server/DocStore/ru-RU/ONLYOFFICE Sales funnel sample report.xlsx create mode 100644 products/ASC.CRM/Server/DocStore/ru-RU/ONLYOFFICE Summary for the moment sample report.xlsx create mode 100644 products/ASC.CRM/Server/DocStore/ru-RU/ONLYOFFICE Summary for the period sample report.xlsx create mode 100644 products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs create mode 100644 products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs create mode 100644 products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs create mode 100644 products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs create mode 100644 products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs create mode 100644 products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs create mode 100644 products/ASC.CRM/Server/HttpHandlers/filehandler.ashx create mode 100644 products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx create mode 100644 products/ASC.CRM/Server/InvoiceTemplates/template.docx create mode 100644 products/ASC.CRM/Server/Program.cs create mode 100644 products/ASC.CRM/Server/Properties/launchSettings.json create mode 100644 products/ASC.CRM/Server/ReportTemplates/SalesByManagers.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/SalesForecast.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/SalesFunnel.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/SummaryAtThisMoment.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/SummaryForThePeriod.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/WorkloadByContacts.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/WorkloadByDeals.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/WorkloadByInvoices.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/WorkloadByTasks.docbuilder create mode 100644 products/ASC.CRM/Server/ReportTemplates/WorkloadByVoip.docbuilder create mode 100644 products/ASC.CRM/Server/Resources/CRMCasesResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMCasesResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMCommonResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMCommonResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMContactResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMContactResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMDealResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMDealResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMEnumResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMEnumResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMErrorsResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMErrorsResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMInvoiceResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMInvoiceResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMJSResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMJSResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMReportResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMReportResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMSettingResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMSettingResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMSocialMediaResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMSocialMediaResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMTaskResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMTaskResource.resx create mode 100644 products/ASC.CRM/Server/Resources/CRMVoipResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Resources/CRMVoipResource.resx create mode 100644 products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs create mode 100644 products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.resx create mode 100644 products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs create mode 100644 products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs create mode 100644 products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs create mode 100644 products/ASC.CRM/Server/Services/NotifyService/patterns.xml create mode 100644 products/ASC.CRM/Server/Startup.cs create mode 100644 products/ASC.CRM/Server/Templates/CasesTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/CommonCustomFieldsTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/CommonTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/ContactInfoCardTemplate.html create mode 100644 products/ASC.CRM/Server/Templates/ContactSelectorTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/ContactsTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/DealsSelectorTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/DealsTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/InvoicesTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/SettingsTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/SimpleContactListTemplate.html create mode 100644 products/ASC.CRM/Server/Templates/TasksTemplates.html create mode 100644 products/ASC.CRM/Server/Templates/VoipTemplates.html create mode 100644 products/ASC.CRM/Server/Utils/CurrencyProvider.cs create mode 100644 products/ASC.CRM/Server/Utils/ExportToCSV.cs create mode 100644 products/ASC.CRM/Server/Utils/FileHelper.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs create mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs create mode 100644 products/ASC.CRM/Server/Utils/MailSender.cs create mode 100644 products/ASC.CRM/Server/Utils/PdfCreator.cs create mode 100644 products/ASC.CRM/Server/Utils/PdfQueueWorker.cs create mode 100644 products/ASC.CRM/Server/Utils/ReportHelper.cs create mode 100644 products/ASC.CRM/Server/appsettings.Development.json create mode 100644 products/ASC.CRM/Server/appsettings.json diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj new file mode 100644 index 00000000000..54e2b507b6d --- /dev/null +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -0,0 +1,159 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + + + + + + + + + True + True + CRMCasesResource.resx + + + True + True + CRMCommonResource.resx + + + True + True + CRMContactResource.resx + + + True + True + CRMDealResource.resx + + + True + True + CRMEnumResource.resx + + + True + True + CRMErrorsResource.resx + + + True + True + CRMInvoiceResource.resx + + + True + True + CRMJSResource.resx + + + True + True + CRMReportResource.resx + + + True + True + CRMSettingResource.resx + + + True + True + CRMSocialMediaResource.resx + + + True + True + CRMTaskResource.resx + + + True + True + CRMVoipResource.resx + + + True + True + CRMPatternResource.resx + + + + + + PublicResXFileCodeGenerator + CRMCasesResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMCommonResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMContactResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMDealResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMEnumResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMErrorsResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMInvoiceResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMJSResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMReportResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMSettingResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMSocialMediaResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMTaskResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMVoipResource.Designer.cs + + + PublicResXFileCodeGenerator + CRMPatternResource.Designer.cs + + + + + + + + + diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs new file mode 100644 index 00000000000..52a6f5ba935 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -0,0 +1,248 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.Core.Common.Settings; +using ASC.CRM.Core; +using System; +using System.Runtime.Serialization; + + +#endregion + +namespace ASC.Web.CRM.Classes +{ + [Serializable] + [DataContract] + public class SMTPServerSetting + { + + public SMTPServerSetting() + { + Host = String.Empty; + Port = 0; + EnableSSL = false; + RequiredHostAuthentication = false; + HostLogin = String.Empty; + HostPassword = String.Empty; + SenderDisplayName = String.Empty; + SenderEmailAddress = String.Empty; + } + + public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) + { + Host = smtpSettings.Host; + Port = smtpSettings.Port; + EnableSSL = smtpSettings.EnableSSL; + RequiredHostAuthentication = smtpSettings.EnableAuth; + HostLogin = smtpSettings.CredentialsUserName; + HostPassword = smtpSettings.CredentialsUserPassword; + SenderDisplayName = smtpSettings.SenderDisplayName; + SenderEmailAddress = smtpSettings.SenderAddress; + } + + [DataMember] + public String Host { get; set; } + + [DataMember] + public int Port { get; set; } + + [DataMember] + public bool EnableSSL { get; set; } + + [DataMember] + public bool RequiredHostAuthentication { get; set; } + + [DataMember] + public String HostLogin { get; set; } + + [DataMember] + public String HostPassword { get; set; } + + [DataMember] + public String SenderDisplayName { get; set; } + + [DataMember] + public String SenderEmailAddress { get; set; } + + } + + [Serializable] + [DataContract] + public class InvoiceSetting + { + public InvoiceSetting() + { + Autogenerated = false; + Prefix = String.Empty; + Number = String.Empty; + Terms = String.Empty; + } + + public static InvoiceSetting DefaultSettings + { + get + { + return new InvoiceSetting + { + Autogenerated = true, + Prefix = WebConfigurationManager.AppSettings["crm.invoice.prefix"] ?? "INV-", + Number = "0000001", + Terms = String.Empty, + CompanyName = String.Empty, + CompanyLogoID = 0, + CompanyAddress = String.Empty + }; + } + } + + [DataMember] + public bool Autogenerated { get; set; } + + [DataMember] + public String Prefix { get; set; } + + [DataMember] + public String Number { get; set; } + + [DataMember] + public String Terms { get; set; } + + [DataMember] + public String CompanyName { get; set; } + + [DataMember] + public Int32 CompanyLogoID { get; set; } + + [DataMember] + public String CompanyAddress { get; set; } + } + + + [Serializable] + [DataContract] + public class CRMSettings : BaseSettings + { + [DataMember(Name = "DefaultCurrency")] + private string defaultCurrency; + + //[DataMember] + public SMTPServerSetting SMTPServerSetting + { + get + { + return new SMTPServerSetting(CoreContext.Configuration.SmtpSettings); + } + } + + [DataMember(Name = "SMTPServerSetting")] + public SMTPServerSetting SMTPServerSettingOld { get; set; } + + [DataMember] + public InvoiceSetting InvoiceSetting { get; set; } + + [DataMember] + public Guid WebFormKey { get; set; } + + public override Guid ID + { + get { return new Guid("fdf39b9a-ec96-4eb7-aeab-63f2c608eada"); } + } + + public CurrencyInfo DefaultCurrency + { + get { return CurrencyProvider.Get(defaultCurrency); } + set { defaultCurrency = value.Abbreviation; } + } + + [DataMember(Name = "ChangeContactStatusGroupAuto")] + public string ChangeContactStatusGroupAutoWrapper { get; set; } + + [IgnoreDataMember] + public Boolean? ChangeContactStatusGroupAuto + { + get { return string.IsNullOrEmpty(ChangeContactStatusGroupAutoWrapper) ? null : (bool?)bool.Parse(ChangeContactStatusGroupAutoWrapper); } + set { ChangeContactStatusGroupAutoWrapper = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } + } + + [DataMember(Name = "AddTagToContactGroupAuto")] + public string AddTagToContactGroupAutoWrapper { get; set; } + + [IgnoreDataMember] + public Boolean? AddTagToContactGroupAuto + { + get { return string.IsNullOrEmpty(AddTagToContactGroupAutoWrapper) ? null : (bool?)bool.Parse(AddTagToContactGroupAutoWrapper); } + set { AddTagToContactGroupAutoWrapper = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } + } + + [DataMember(Name = "WriteMailToHistoryAuto")] + public Boolean WriteMailToHistoryAuto { get; set; } + + [DataMember(Name = "IsConfiguredPortal")] + public bool IsConfiguredPortal { get; set; } + + [DataMember(Name = "IsConfiguredSmtp")] + public bool IsConfiguredSmtp { get; set; } + + public override ISettings GetDefault() + { + var languageName = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; + + var findedCurrency = CurrencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); + + return new CRMSettings + { + defaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", + IsConfiguredPortal = false, + ChangeContactStatusGroupAuto = null, + AddTagToContactGroupAuto = null, + WriteMailToHistoryAuto = false, + WebFormKey = Guid.Empty, + InvoiceSetting = InvoiceSetting.DefaultSettings + }; + } + } + + + [Serializable] + [DataContract] + public class CRMReportSampleSettings : BaseSettings + { + [DataMember(Name = "NeedToGenerate")] + public bool NeedToGenerate { get; set; } + + public override Guid ID + { + get { return new Guid("{54CD64AD-E73B-45A3-89E4-4D42A234D7A3}"); } + } + + public override ISettings GetDefault() + { + return new CRMReportSampleSettings { NeedToGenerate = true }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/CSVReader.cs b/products/ASC.CRM/Server/Classes/CSVReader.cs new file mode 100644 index 00000000000..f658216e9af --- /dev/null +++ b/products/ASC.CRM/Server/Classes/CSVReader.cs @@ -0,0 +1,361 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +/* CSVReader - a simple open source C# class library to read CSV data + * by Andrew Stellman - http://www.stellman-greene.com/CSVReader + * + * CSVReader.cs - Class to read CSV data from a string, file or stream + * + * download the latest version: http://svn.stellman-greene.com/CSVReader + * + * (c) 2008, Stellman & Greene Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Stellman & Greene Consulting nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STELLMAN & GREENE CONSULTING ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL STELLMAN & GREENE CONSULTING BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Data; +using System.Text; + +namespace ASC.Web.CRM.Classes +{ + /// + /// Read CSV-formatted data from a file or TextReader + /// + public class CSVReader : IDisposable + { + public const string NEWLINE = "\r\n"; + public const string COMMASEP = ","; + public const string SEMICOLONSEP = ";"; + + // Field Separator (default is comma) + private static string FieldSep = COMMASEP; + + /// + /// This reader will read all of the CSV data + /// + private BinaryReader reader; + + /// + /// The number of rows to scan for types when building a DataTable (0 to scan the whole file) + /// + public int ScanRows = 0; + + #region Constructors + + /// + /// Read CSV-formatted data from a file + /// + /// Name of the CSV file + public CSVReader(FileInfo csvFileInfo) + { + if (csvFileInfo == null) + throw new ArgumentNullException("Null FileInfo passed to CSVReader"); + + this.reader = new BinaryReader(File.OpenRead(csvFileInfo.FullName)); + } + + /// + /// Read CSV-formatted data from a string + /// + /// String containing CSV data + public CSVReader(string csvData) + { + if (csvData == null) + throw new ArgumentNullException("Null string passed to CSVReader"); + + + this.reader = new BinaryReader(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(csvData))); + } + + /// + /// Read CSV-formatted data from a TextReader + /// + /// TextReader that's reading CSV-formatted data + public CSVReader(TextReader reader) + { + if (reader == null) + throw new ArgumentNullException("Null TextReader passed to CSVReader"); + + this.reader = new BinaryReader(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(reader.ReadToEnd()))); + } + + #endregion + + + + string currentLine = ""; + /// + /// Read the next row from the CSV data + /// + /// A list of objects read from the row, or null if there is no next row + public List ReadRow() + { + // ReadLine() will return null if there's no next line + if (reader.BaseStream.Position >= reader.BaseStream.Length) + return null; + + StringBuilder builder = new StringBuilder(); + + // Read the next line + while ((reader.BaseStream.Position < reader.BaseStream.Length) && (!builder.ToString().EndsWith(NEWLINE))) + { + char c = reader.ReadChar(); + builder.Append(c); + } + + currentLine = builder.ToString(); + if (currentLine.EndsWith(NEWLINE)) + currentLine = currentLine.Remove(currentLine.IndexOf(NEWLINE), NEWLINE.Length); + + // Build the list of objects in the line + List objects = new List(); + while (currentLine != "") + objects.Add(ReadNextObject()); + return objects; + } + + /// + /// Read the next object from the currentLine string + /// + /// The next object in the currentLine string + private object ReadNextObject() + { + if (currentLine == null) + return null; + + // Check to see if the next value is quoted + bool quoted = false; + if (currentLine.StartsWith("\"")) + quoted = true; + + // Find the end of the next value + string nextObjectString = ""; + int i = 0; + int len = currentLine.Length; + bool foundEnd = false; + while (!foundEnd && i <= len) + { + // Check if we've hit the end of the string + if ((!quoted && i == len) // non-quoted strings end with a comma or end of line + || (!quoted && currentLine.Substring(i, 1) == FieldSep) + // quoted strings end with a quote followed by a comma or end of line + || (quoted && i == len - 1 && currentLine.EndsWith("\"")) + || (quoted && currentLine.Substring(i, 2) == "\"" + FieldSep)) + foundEnd = true; + else + i++; + } + if (quoted) + { + if (i > len || !currentLine.Substring(i, 1).StartsWith("\"")) + throw new FormatException("Invalid CSV format: " + currentLine.Substring(0, i)); + i++; + } + nextObjectString = currentLine.Substring(0, i).Replace("\"\"", "\""); + + if (i < len) + currentLine = currentLine.Substring(i + 1); + else + currentLine = ""; + + if (quoted) + { + if (nextObjectString.StartsWith("\"")) + nextObjectString = nextObjectString.Substring(1); + if (nextObjectString.EndsWith("\"")) + nextObjectString = nextObjectString.Substring(0, nextObjectString.Length - 1); + return nextObjectString; + } + else + { + object convertedValue; + StringConverter.ConvertString(nextObjectString, out convertedValue); + return convertedValue; + } + } + + /// + /// Read the row data read using repeated ReadRow() calls and build a DataColumnCollection with types and column names + /// + /// True if the first row contains headers + /// System.Data.DataTable object populated with the row data + public DataTable CreateDataTable(bool headerRow) + { + // Read the CSV data into rows + List> rows = new List>(); + List readRow = null; + while ((readRow = ReadRow()) != null) + rows.Add(readRow); + + // The types and names (if headerRow is true) will be stored in these lists + List columnTypes = new List(); + List columnNames = new List(); + + // Read the column names from the header row (if there is one) + if (headerRow) + foreach (object name in rows[0]) + columnNames.Add(name.ToString()); + + // Read the column types from each row in the list of rows + bool headerRead = false; + foreach (List row in rows) + if (headerRead || !headerRow) + for (int i = 0; i < row.Count; i++) + // If we're adding a new column to the columnTypes list, use its type. + // Otherwise, find the common type between the one that's there and the new row. + if (columnTypes.Count < i + 1) + columnTypes.Add(row[i].GetType()); + else + columnTypes[i] = StringConverter.FindCommonType(columnTypes[i], row[i].GetType()); + else + headerRead = true; + + // Create the table and add the columns + DataTable table = new DataTable(); + for (int i = 0; i < columnTypes.Count; i++) + { + table.Columns.Add(); + table.Columns[i].DataType = columnTypes[i]; + if (i < columnNames.Count) + table.Columns[i].ColumnName = columnNames[i]; + } + + // Add the data from the rows + headerRead = false; + foreach (List row in rows) + if (headerRead || !headerRow) + { + DataRow dataRow = table.NewRow(); + for (int i = 0; i < row.Count; i++) + dataRow[i] = row[i]; + table.Rows.Add(dataRow); + } + else + headerRead = true; + + return table; + } + + /// + /// Read a CSV file into a table + /// + /// Filename of CSV file + /// True if the first row contains column names + /// The number of rows to scan for types when building a DataTable (0 to scan the whole file) + /// The field separator character + /// System.Data.DataTable object that contains the CSV data + public static DataTable ReadCSVFile(string filename, bool headerRow, int scanRows, String fieldSeparator) + { + FieldSep = fieldSeparator; + return ReadCSVFile(filename, headerRow, scanRows); + } + + /// + /// Read a CSV file into a table + /// + /// Filename of CSV file + /// True if the first row contains column names + /// The field separator character + /// System.Data.DataTable object that contains the CSV data + public static DataTable ReadCSVFile(string filename, bool headerRow, String fieldSeparator) + { + FieldSep = fieldSeparator; + return ReadCSVFile(filename, headerRow); + } + + /// + /// Read a CSV file into a table + /// + /// Filename of CSV file + /// True if the first row contains column names + /// The number of rows to scan for types when building a DataTable (0 to scan the whole file) + /// System.Data.DataTable object that contains the CSV data + public static DataTable ReadCSVFile(string filename, bool headerRow, int scanRows) + { + using (CSVReader reader = new CSVReader(new FileInfo(filename))) + { + reader.ScanRows = scanRows; + return reader.CreateDataTable(headerRow); + } + } + + /// + /// Read a CSV file into a table + /// + /// Filename of CSV file + /// True if the first row contains column names + /// System.Data.DataTable object that contains the CSV data + public static DataTable ReadCSVFile(string filename, bool headerRow) + { + using (CSVReader reader = new CSVReader(new FileInfo(filename))) + return reader.CreateDataTable(headerRow); + } + + + + #region IDisposable Members + + public void Dispose() + { + if (reader != null) + { + try + { + // Can't call BinaryReader.Dispose due to its protection level + reader.Close(); + } + catch { } + } + } + + #endregion + } +} diff --git a/products/ASC.CRM/Server/Classes/CSVReaderExtension.cs b/products/ASC.CRM/Server/Classes/CSVReaderExtension.cs new file mode 100644 index 00000000000..9dadc7b0247 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/CSVReaderExtension.cs @@ -0,0 +1,90 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +/* CSVReader - a simple open source C# class library to read CSV data + * by Andrew Stellman - http://www.stellman-greene.com/CSVReader + * + * CSVReaderExtension.cs - string extension methods to read CSV rows and tables + * + * download the latest version: http://svn.stellman-greene.com/CSVReader + * + * (c) 2008, Stellman & Greene Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Stellman & Greene Consulting nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STELLMAN & GREENE CONSULTING ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL STELLMAN & GREENE CONSULTING BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +using System; +using System.Collections.Generic; +using System.Data; + +namespace ASC.Web.CRM.Classes +{ + public static class CSVReaderExtension + { + /// + /// Convert a CSV-formatted string into a list of objects + /// + /// List of objects that contains the CSV data + public static List ReadCSVLine(this string input) + { + using (CSVReader reader = new CSVReader(input)) + return reader.ReadRow(); + } + + /// + /// Convert a CSV-formatted string into a DataTable + /// + /// True if the first row contains headers + /// System.Data.DataTable that contains the CSV data + public static DataTable ReadCSVTable(this string input, bool headerRow) + { + using (CSVReader reader = new CSVReader(input)) + return reader.CreateDataTable(headerRow); + } + } +} diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs new file mode 100644 index 00000000000..9f73567395a --- /dev/null +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -0,0 +1,658 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Caching; +using ASC.Common.Threading.Workers; +using ASC.CRM.Resources; +using ASC.Data.Storage; +using ASC.Web.Core; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM.Configuration; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Net; + +namespace ASC.Web.CRM.Classes +{ + public class ResizeWorkerItem + { + public int ContactID { get; set; } + + public bool UploadOnly { get; set; } + + public String TmpDirName { get; set; } + + public Size[] RequireFotoSize { get; set; } + + public byte[] ImageData { get; set; } + + public IDataStore DataStore { get; set; } + + public override bool Equals(object obj) + { + if (!(obj is ResizeWorkerItem)) return false; + + var item = (ResizeWorkerItem)obj; + + return item.ContactID.Equals(ContactID) && RequireFotoSize.Equals(item.RequireFotoSize) && ImageData.Length == item.ImageData.Length; + } + + public override int GetHashCode() + { + return ContactID ^ RequireFotoSize.GetHashCode() ^ ImageData.Length; + } + } + + public static class ContactPhotoManager + { + #region Members + + private const string PhotosBaseDirName = "photos"; + private const string PhotosDefaultTmpDirName = "temp"; + + private static readonly Dictionary> _photoCache = new Dictionary>(); + + private static readonly WorkerQueue ResizeQueue = new WorkerQueue(2, TimeSpan.FromSeconds(30), 1, true); + private static readonly ICacheNotify cachyNotify; + + private static readonly Size _oldBigSize = new Size(145, 145); + + private static readonly Size _bigSize = new Size(200, 200); + private static readonly Size _mediumSize = new Size(82, 82); + private static readonly Size _smallSize = new Size(40, 40); + + private static readonly object locker = new object(); + + #endregion + + #region Cache and DataStore Methods + + static ContactPhotoManager() + { + cachyNotify = AscCache.Notify; + cachyNotify.Subscribe>>( + (item, action) => + { + var contactID = item.Key; + var sizeUriPair = item.Value; + + switch (action) + { + case CacheNotifyAction.InsertOrUpdate: + ToPrivateCache(contactID, sizeUriPair.Value, sizeUriPair.Key); + break; + case CacheNotifyAction.Remove: + RemoveFromPrivateCache(contactID); + break; + } + }); + } + + private static String FromCache(int contactID, Size photoSize) + { + lock (locker) + { + if (_photoCache.ContainsKey(contactID)) + { + if (_photoCache[contactID].ContainsKey(photoSize)) + { + return _photoCache[contactID][photoSize]; + } + if (photoSize == _bigSize && _photoCache[contactID].ContainsKey(_oldBigSize)) + { + return _photoCache[contactID][_oldBigSize]; + } + } + } + return String.Empty; + } + + private static void RemoveFromCache(int contactID) + { + cachyNotify.Publish(CreateCacheItem(contactID, "", Size.Empty), CacheNotifyAction.Remove); + } + + private static void RemoveFromPrivateCache(int contactID) + { + lock (locker) + { + _photoCache.Remove(contactID); + } + } + + private static void ToCache(int contactID, String photoUri, Size photoSize) + { + cachyNotify.Publish(CreateCacheItem(contactID, photoUri, photoSize), CacheNotifyAction.InsertOrUpdate); + } + + private static void ToPrivateCache(int contactID, String photoUri, Size photoSize) + { + lock (locker) + { + if (_photoCache.ContainsKey(contactID)) + if (_photoCache[contactID].ContainsKey(photoSize)) + _photoCache[contactID][photoSize] = photoUri; + else + _photoCache[contactID].Add(photoSize, photoUri); + else + _photoCache.Add(contactID, new Dictionary {{photoSize, photoUri}}); + } + } + + private static KeyValuePair> CreateCacheItem(int contactID, String photoUri, Size photoSize) + { + var sizeUriPair = new KeyValuePair(photoSize, photoUri); + return new KeyValuePair>(contactID, sizeUriPair); + } + + private static String FromDataStore(int contactID, Size photoSize) + { + return FromDataStore(contactID, photoSize, false, null); + } + + private static String FromDataStore(int contactID, Size photoSize, Boolean isTmpDir, String tmpDirName) + { + var directoryPath = !isTmpDir + ? BuildFileDirectory(contactID) + : (String.IsNullOrEmpty(tmpDirName) ? BuildFileTmpDirectory(contactID) : BuildFileTmpDirectory(tmpDirName)); + + var filesURI = Global.GetStore().ListFiles(directoryPath, BuildFileName(contactID, photoSize) + "*", false); + + if (filesURI.Length == 0 && photoSize == _bigSize) + { + filesURI = Global.GetStore().ListFiles(directoryPath, BuildFileName(contactID, _oldBigSize) + "*", false); + } + + if (filesURI.Length == 0) + { + return String.Empty; + } + + return filesURI[0].ToString(); + } + + private static String FromDataStoreRelative(int contactID, Size photoSize, Boolean isTmpDir, String tmpDirName) + { + var directoryPath = !isTmpDir + ? BuildFileDirectory(contactID) + : (String.IsNullOrEmpty(tmpDirName) ? BuildFileTmpDirectory(contactID) : BuildFileTmpDirectory(tmpDirName)); + + var filesPaths = Global.GetStore().ListFilesRelative("", directoryPath, BuildFileName(contactID, photoSize) + "*", false); + + if (filesPaths.Length == 0 && photoSize == _bigSize) + { + filesPaths = Global.GetStore().ListFilesRelative("", directoryPath, BuildFileName(contactID, _oldBigSize) + "*", false); + } + + if (filesPaths.Length == 0) + { + return String.Empty; + } + + return Path.Combine(directoryPath, filesPaths[0]); + } + + private static PhotoData FromDataStore(Size photoSize, String tmpDirName) + { + var directoryPath = BuildFileTmpDirectory(tmpDirName); + + if (!Global.GetStore().IsDirectory(directoryPath)) + return null; + + var filesURI = Global.GetStore().ListFiles(directoryPath, BuildFileName(0, photoSize) + "*", false); + + if (filesURI.Length == 0) return null; + + return new PhotoData { Url = filesURI[0].ToString(), Path = tmpDirName }; + } + + #endregion + + #region Private Methods + + private static String GetPhotoUri(int contactID, bool isCompany, Size photoSize) + { + var photoUri = FromCache(contactID, photoSize); + + if (!String.IsNullOrEmpty(photoUri)) return photoUri; + + photoUri = FromDataStore(contactID, photoSize); + + if (String.IsNullOrEmpty(photoUri)) + photoUri = GetDefaultPhoto(isCompany, photoSize); + + ToCache(contactID, photoUri, photoSize); + + return photoUri; + } + + private static String BuildFileDirectory(int contactID) + { + var s = contactID.ToString("000000"); + + return String.Concat(PhotosBaseDirName, "/", s.Substring(0, 2), "/", + s.Substring(2, 2), "/", + s.Substring(4), "/"); + } + + private static String BuildFileTmpDirectory(int contactID) + { + return String.Concat(BuildFileDirectory(contactID), PhotosDefaultTmpDirName, "/"); + } + + private static String BuildFileTmpDirectory(string tmpDirName) + { + return String.Concat(PhotosBaseDirName, "/", tmpDirName.TrimEnd('/'), "/"); + } + + private static String BuildFileName(int contactID, Size photoSize) + { + return String.Format("contact_{0}_{1}_{2}", contactID, photoSize.Width, photoSize.Height); + } + + private static String BuildFilePath(int contactID, Size photoSize, String imageExtension) + { + if (photoSize.IsEmpty || contactID == 0) + throw new ArgumentException(); + + return String.Concat(BuildFileDirectory(contactID), BuildFileName(contactID, photoSize), imageExtension); + } + + private static String BuildFileTmpPath(int contactID, Size photoSize, String imageExtension, String tmpDirName) + { + if (photoSize.IsEmpty || (contactID == 0 && String.IsNullOrEmpty(tmpDirName))) + throw new ArgumentException(); + + return String.Concat( + String.IsNullOrEmpty(tmpDirName) + ? BuildFileTmpDirectory(contactID) + : BuildFileTmpDirectory(tmpDirName), + BuildFileName(contactID, photoSize), imageExtension); + } + + private static void ExecResizeImage(ResizeWorkerItem resizeWorkerItem) + { + foreach (var fotoSize in resizeWorkerItem.RequireFotoSize) + { + var data = resizeWorkerItem.ImageData; + using (var stream = new MemoryStream(data)) + using (var img = new Bitmap(stream)) + { + var imgFormat = img.RawFormat; + if (fotoSize != img.Size) + { + using (var img2 = CommonPhotoManager.DoThumbnail(img, fotoSize, false, false, false)) + { + data = CommonPhotoManager.SaveToBytes(img2, Global.GetImgFormatName(imgFormat)); + } + } + else + { + data = Global.SaveToBytes(img); + } + + var fileExtension = String.Concat("." + Global.GetImgFormatName(imgFormat)); + + var photoPath = !resizeWorkerItem.UploadOnly + ? BuildFilePath(resizeWorkerItem.ContactID, fotoSize, fileExtension) + : BuildFileTmpPath(resizeWorkerItem.ContactID, fotoSize, fileExtension, resizeWorkerItem.TmpDirName); + + using (var fileStream = new MemoryStream(data)) + { + var photoUri = resizeWorkerItem.DataStore.Save(photoPath, fileStream).ToString(); + photoUri = String.Format("{0}?cd={1}", photoUri, DateTime.UtcNow.Ticks); + + if (!resizeWorkerItem.UploadOnly) + { + ToCache(resizeWorkerItem.ContactID, photoUri, fotoSize); + } + } + } + } + } + + private static String GetDefaultPhoto(bool isCompany, Size photoSize) + { + int contactID; + + if (isCompany) + contactID = -1; + else + contactID = -2; + + var defaultPhotoUri = FromCache(contactID, photoSize); + + if (!String.IsNullOrEmpty(defaultPhotoUri)) return defaultPhotoUri; + + if (isCompany) + defaultPhotoUri = WebImageSupplier.GetAbsoluteWebPath(String.Format("empty_company_logo_{0}_{1}.png", photoSize.Height, photoSize.Width), ProductEntryPoint.ID); + else + defaultPhotoUri = WebImageSupplier.GetAbsoluteWebPath(String.Format("empty_people_logo_{0}_{1}.png", photoSize.Height, photoSize.Width), ProductEntryPoint.ID); + + ToCache(contactID, defaultPhotoUri, photoSize); + + return defaultPhotoUri; + } + + #endregion + + #region Delete Methods + + public static void DeletePhoto(int contactID) + { + DeletePhoto(contactID, false, null, true); + } + + public static void DeletePhoto(int contactID, bool isTmpDir, string tmpDirName, bool recursive) + { + if (contactID == 0) + throw new ArgumentException(); + + lock (locker) + { + ResizeQueue.GetItems().Where(item => item.ContactID == contactID) + .All(item => + { + ResizeQueue.Remove(item); + return true; + }); + + var photoDirectory = !isTmpDir + ? BuildFileDirectory(contactID) + : (String.IsNullOrEmpty(tmpDirName) ? BuildFileTmpDirectory(contactID) : BuildFileTmpDirectory(tmpDirName)); + var store = Global.GetStore(); + + if (store.IsDirectory(photoDirectory)) + { + store.DeleteFiles(photoDirectory, "*", recursive); + if (recursive) + { + store.DeleteDirectory(photoDirectory); + } + } + + if (!isTmpDir) + { + RemoveFromCache(contactID); + } + } + } + + public static void DeletePhoto(string tmpDirName) + { + lock (locker) + { + + var photoDirectory = BuildFileTmpDirectory(tmpDirName); + var store = Global.GetStore(); + + if (store.IsDirectory(photoDirectory)) + { + store.DeleteFiles(photoDirectory, "*", false); + } + } + } + + #endregion + + public static void TryUploadPhotoFromTmp(int contactID, bool isNewContact, string tmpDirName) + { + var directoryPath = BuildFileDirectory(contactID); + var dataStore = Global.GetStore(); + + try + { + if (dataStore.IsDirectory(directoryPath)) + { + DeletePhoto(contactID, false, null, false); + } + foreach (var photoSize in new[] {_bigSize, _mediumSize, _smallSize}) + { + var photoTmpPath = FromDataStoreRelative(isNewContact ? 0 : contactID, photoSize, true, tmpDirName); + if (string.IsNullOrEmpty(photoTmpPath)) throw new Exception("Temp phono not found"); + + var imageExtension = Path.GetExtension(photoTmpPath); + + var photoPath = String.Concat(directoryPath, BuildFileName(contactID, photoSize), imageExtension).TrimStart('/'); + + byte[] data; + using (var photoTmpStream = dataStore.GetReadStream(photoTmpPath)) + { + data = Global.ToByteArray(photoTmpStream); + } + using (var fileStream = new MemoryStream(data)) + { + var photoUri = dataStore.Save(photoPath, fileStream).ToString(); + photoUri = String.Format("{0}?cd={1}", photoUri, DateTime.UtcNow.Ticks); + ToCache(contactID, photoUri, photoSize); + } + } + DeletePhoto(contactID, true, tmpDirName, true); + } + catch(Exception ex) + { + LogManager.GetLogger("ASC.CRM").ErrorFormat("TryUploadPhotoFromTmp for contactID={0} failed witth error: {1}", contactID, ex); + return; + } + } + + #region Get Photo Methods + + public static String GetSmallSizePhoto(int contactID, bool isCompany) + { + if (contactID <= 0) + return GetDefaultPhoto(isCompany, _smallSize); + + return GetPhotoUri(contactID, isCompany, _smallSize); + } + + public static String GetMediumSizePhoto(int contactID, bool isCompany) + { + if (contactID <= 0) + return GetDefaultPhoto(isCompany, _mediumSize); + + return GetPhotoUri(contactID, isCompany, _mediumSize); + } + + public static String GetBigSizePhoto(int contactID, bool isCompany) + { + if (contactID <= 0) + return GetDefaultPhoto(isCompany, _bigSize); + + return GetPhotoUri(contactID, isCompany, _bigSize); + } + + #endregion + + private static PhotoData ResizeToBigSize(byte[] imageData, string tmpDirName) + { + return ResizeToBigSize(imageData, 0, true, tmpDirName); + } + + private static PhotoData ResizeToBigSize(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) + { + var resizeWorkerItem = new ResizeWorkerItem + { + ContactID = contactID, + UploadOnly = uploadOnly, + RequireFotoSize = new[] {_bigSize}, + ImageData = imageData, + DataStore = Global.GetStore(), + TmpDirName = tmpDirName + }; + + ExecResizeImage(resizeWorkerItem); + + if (!uploadOnly) + { + return new PhotoData { Url = FromCache(contactID, _bigSize) }; + } + else if (String.IsNullOrEmpty(tmpDirName)) + { + return new PhotoData { Url = FromDataStore(contactID, _bigSize, true, null), Path = PhotosDefaultTmpDirName }; + } + else + { + return FromDataStore(_bigSize, tmpDirName); + } + } + + private static void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadOnly) + { + ExecGenerateThumbnail(imageData, contactID, uploadOnly, null); + } + + private static void ExecGenerateThumbnail(byte[] imageData, string tmpDirName) + { + ExecGenerateThumbnail(imageData, 0, true, tmpDirName); + } + + + private static void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) + { + var resizeWorkerItem = new ResizeWorkerItem + { + ContactID = contactID, + UploadOnly = uploadOnly, + RequireFotoSize = new[] {_mediumSize, _smallSize}, + ImageData = imageData, + DataStore = Global.GetStore(), + TmpDirName = tmpDirName + }; + + if (!ResizeQueue.GetItems().Contains(resizeWorkerItem)) + ResizeQueue.Add(resizeWorkerItem); + + if (!ResizeQueue.IsStarted) ResizeQueue.Start(ExecResizeImage); + } + + private static byte[] ToByteArray(Stream inputStream, int streamLength) + { + using (var br = new BinaryReader(inputStream)) + { + return br.ReadBytes(streamLength); + } + } + + #region UploadPhoto Methods + + public static PhotoData UploadPhoto(String imageUrl, int contactID, bool uploadOnly, bool checkFormat = true) + { + var request = (HttpWebRequest)WebRequest.Create(imageUrl); + using (var response = request.GetResponse()) + { + using (var inputStream = response.GetResponseStream()) + { + var imageData = ToByteArray(inputStream, (int)response.ContentLength); + return UploadPhoto(imageData, contactID, uploadOnly, checkFormat); + } + } + } + + public static PhotoData UploadPhoto(Stream inputStream, int contactID, bool uploadOnly, bool checkFormat = true) + { + var imageData = Global.ToByteArray(inputStream); + return UploadPhoto(imageData, contactID, uploadOnly, checkFormat); + } + + public static PhotoData UploadPhoto(byte[] imageData, int contactID, bool uploadOnly, bool checkFormat = true) + { + if (contactID == 0) + throw new ArgumentException(); + + if (checkFormat) + CheckImgFormat(imageData); + + DeletePhoto(contactID, uploadOnly, null, false); + + ExecGenerateThumbnail(imageData, contactID, uploadOnly); + + return ResizeToBigSize(imageData, contactID, uploadOnly, null); + } + + + public static PhotoData UploadPhotoToTemp(String imageUrl, String tmpDirName, bool checkFormat = true) + { + var request = (HttpWebRequest)WebRequest.Create(imageUrl); + using (var response = request.GetResponse()) + { + using (var inputStream = response.GetResponseStream()) + { + var imageData = ToByteArray(inputStream, (int)response.ContentLength); + if (string.IsNullOrEmpty(tmpDirName)) + { + tmpDirName = Guid.NewGuid().ToString(); + } + return UploadPhotoToTemp(imageData, tmpDirName, checkFormat); + } + } + } + + public static PhotoData UploadPhotoToTemp(Stream inputStream, String tmpDirName, bool checkFormat = true) + { + var imageData = Global.ToByteArray(inputStream); + return UploadPhotoToTemp(imageData, tmpDirName, checkFormat); + } + + public static PhotoData UploadPhotoToTemp(byte[] imageData, String tmpDirName, bool checkFormat = true) + { + if (checkFormat) + CheckImgFormat(imageData); + + DeletePhoto(tmpDirName); + + ExecGenerateThumbnail(imageData, tmpDirName); + + return ResizeToBigSize(imageData, tmpDirName); + } + + public static ImageFormat CheckImgFormat(byte[] imageData) + { + using (var stream = new MemoryStream(imageData)) + using (var img = new Bitmap(stream)) + { + var format = img.RawFormat; + + if (!format.Equals(ImageFormat.Png) && !format.Equals(ImageFormat.Jpeg)) + throw new Exception(CRMJSResource.ErrorMessage_NotImageSupportFormat); + + return format; + } + } + + public class PhotoData + { + public string Url; + public string Path; + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs new file mode 100644 index 00000000000..42fdd1547e9 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -0,0 +1,335 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Data.Storage; +using ASC.Web.Core; +using ASC.Web.Core.Files; +using ASC.Web.Studio.Core; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.Globalization; +using System.IO; +using System.Text; + +namespace ASC.Web.CRM.Classes +{ + public class Global + { + public Global() + { + + } + + public static readonly int EntryCountOnPage = 25; + public static readonly int VisiblePageCount = 10; + + public static readonly int MaxCustomFieldSize = 150; + public static readonly int MaxCustomFieldRows = 25; + public static readonly int MaxCustomFieldCols = 150; + + public static readonly int DefaultCustomFieldSize = 40; + public static readonly int DefaultCustomFieldRows = 2; + public static readonly int DefaultCustomFieldCols = 40; + + public static readonly int MaxHistoryEventCharacters = 65000; + public static readonly decimal MaxInvoiceItemPrice = (decimal) 99999999.99; + + public static CRMSettings TenantSettings + { + get { return CRMSettings.Load(); } + } + + public static IDataStore GetStore() + { + return StorageFactory.GetStorage(TenantProvider.CurrentTenantID.ToString(), "crm"); + } + + public static IDataStore GetStoreTemplate() + { + return StorageFactory.GetStorage(String.Empty, "crm_template"); + } + + public static bool CanCreateProjects() + { + try + { + var apiUrl = String.Format("{0}project/securityinfo.json", SetupInfo.WebApiBaseUrl); + + var cacheKey = String.Format("{0}-{1}", ASC.Core.SecurityContext.CurrentAccount.ID, apiUrl); + + bool canCreateProject; + + if (HttpRuntime.Cache[cacheKey] != null) + return Convert.ToBoolean(HttpRuntime.Cache[cacheKey]); + + var apiServer = new Api.ApiServer(); + + var responseApi = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(apiServer.GetApiResponse(apiUrl, "GET"))))["response"]; + + if (responseApi.HasValues) + canCreateProject = Convert.ToBoolean(responseApi["canCreateProject"].Value()); + else + canCreateProject = false; + HttpRuntime.Cache.Remove(cacheKey); + HttpRuntime.Cache.Insert(cacheKey, canCreateProject, null, System.Web.Caching.Cache.NoAbsoluteExpiration, + TimeSpan.FromMinutes(5)); + + return canCreateProject; + + } + catch + { + return false; + } + + } + + public static bool CanDownloadInvoices + { + get + { + var canDownloadFiles = false; + + var value = WebConfigurationManager.AppSettings["crm.invoice.download.enable"]; + if (string.IsNullOrEmpty(value)) return false; + + canDownloadFiles = Convert.ToBoolean(value); + + if (canDownloadFiles && string.IsNullOrEmpty(FilesLinkUtility.DocServiceConverterUrl)) + { + canDownloadFiles = false; + } + + return canDownloadFiles; + } + } + + public static bool CanCreateReports + { + get + { + return !string.IsNullOrEmpty(FilesLinkUtility.DocServiceDocbuilderUrl) && CRMSecurity.IsAdmin; + } + } + + #region CRM Settings + + public static void SaveDefaultCurrencySettings(CurrencyInfo currency) + { + var tenantSettings = TenantSettings; + tenantSettings.DefaultCurrency = currency; + tenantSettings.Save(); + } + + #endregion + + #region Invoice PDF + + public static ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) + { + var existingFile = invoice.GetInvoiceFile(factory); + if (existingFile != null) + { + return existingFile; + } + else + { + var newFile = PdfCreator.CreateFile(invoice, factory); + invoice.FileID = Int32.Parse(newFile.ID.ToString()); + factory.InvoiceDao.UpdateInvoiceFileID(invoice.ID, invoice.FileID); + factory.RelationshipEventDao.AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + return newFile; + } + } + + #endregion + + //Code snippet + + public static String GetUpButtonHTML(Uri requestUrlReferrer) + { + return String.Format(@"", + CRMCommonResource.Up, + requestUrlReferrer != null ? "href='" + requestUrlReferrer.OriginalString + "'" : "", + requestUrlReferrer != null ? "" : " disable"); + } + + public static String RenderItemHeaderWithMenu(String title, EntityType entityType, Boolean isPrivate, Boolean canEdit) + { + var sbIcon = new StringBuilder(); + var sbPrivateMark = new StringBuilder(); + + string titleIconClass; + switch (entityType) + { + case EntityType.Contact: + titleIconClass = "group"; + break; + case EntityType.Person: + titleIconClass = "people"; + break; + case EntityType.Company: + titleIconClass = "company"; + break; + case EntityType.Case: + titleIconClass = "cases"; + break; + case EntityType.Opportunity: + titleIconClass = "opportunities"; + break; + case EntityType.Invoice: + titleIconClass = "documents"; + break; + default: + titleIconClass = string.Empty; + break; + } + if (!String.IsNullOrEmpty(titleIconClass)) + { + if (isPrivate) + { + sbPrivateMark.AppendFormat("
", CRMCommonResource.Private); + } + sbIcon.AppendFormat("{1}", titleIconClass, sbPrivateMark); + } + + return String.Format(@"
+ {0}{1} + {2} +
+ ", + sbIcon, + title, + canEdit ? "" : "" + ); + } + + + /// + /// The method to Decode your Base64 strings. + /// + /// The String containing the characters to decode. + /// A String containing the results of decoding the specified sequence of bytes. + public static string DecodeFrom64(string encodedData) + { + var encodedDataAsBytes = Convert.FromBase64String(encodedData); + return System.Text.Encoding.UTF8.GetString(encodedDataAsBytes); + } + + /// + /// The method create a Base64 encoded string from a normal string. + /// + /// The String containing the characters to encode. + /// The Base64 encoded string. + public static string EncodeTo64(string toEncode) + { + var toEncodeAsBytes = System.Text.Encoding.UTF8.GetBytes(toEncode); + + return Convert.ToBase64String(toEncodeAsBytes); + } + + public static byte[] ToByteArray(Stream inputStream) + { + var br = new MemoryStream(); + var data = new byte[1024]; + var readed = 0; + + while ((readed = inputStream.Read(data, 0, data.Length)) > 0) + { + br.Write(data, 0, readed); + } + br.Close(); + return br.ToArray(); + } + + #region CRM Images download + + public static string GetImgFormatName(ImageFormat format) + { + if (format.Equals(ImageFormat.Bmp)) return "bmp"; + if (format.Equals(ImageFormat.Emf)) return "emf"; + if (format.Equals(ImageFormat.Exif)) return "exif"; + if (format.Equals(ImageFormat.Gif)) return "gif"; + if (format.Equals(ImageFormat.Icon)) return "icon"; + if (format.Equals(ImageFormat.Jpeg)) return "jpeg"; + if (format.Equals(ImageFormat.MemoryBmp)) return "MemoryBMP"; + if (format.Equals(ImageFormat.Png)) return "png"; + if (format.Equals(ImageFormat.Tiff)) return "tiff"; + if (format.Equals(ImageFormat.Wmf)) return "wmf"; + + return "jpg"; + } + + public static byte[] SaveToBytes(Image img) + { + return CommonPhotoManager.SaveToBytes(img, GetImgFormatName(img.RawFormat)); + } + + #endregion + + #region Parse JOjbect with ApiDateTime + + private static readonly string[] Formats = new[] + { + "o", + "yyyy'-'MM'-'dd'T'HH'-'mm'-'ss'.'fffK", + "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK", + "yyyy-MM-ddTHH:mm:ss" + }; + + public static DateTime ApiDateTimeParse(string data) + { + if (string.IsNullOrEmpty(data)) throw new ArgumentNullException("data"); + + if (data.Length < 7) throw new ArgumentException(CRMErrorsResource.DateTimeFormatInvalid); + + DateTime dateTime; + if (DateTime.TryParseExact(data, Formats, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out dateTime)) + { + return new DateTime(dateTime.Ticks, DateTimeKind.Unspecified); + } + throw new ArgumentException(CRMErrorsResource.DateTimeFormatInvalid); + } + + public static JObject JObjectParseWithDateAsString(string data) + { + JsonReader reader = new JsonTextReader( + new StringReader(data) + ); + reader.DateParseHandling = DateParseHandling.None; + return JObject.Load(reader); + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs new file mode 100644 index 00000000000..195d33330da --- /dev/null +++ b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs @@ -0,0 +1,107 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Web; +using System.Linq; +using ASC.CRM.Core; +using ASC.MessagingSystem; +using ASC.Web.Core.Utility; +using System.IO; +using Newtonsoft.Json.Linq; +using ASC.CRM.Core.Enums; + +#endregion + +namespace ASC.Web.CRM.Classes +{ + public class ImportFromCSVManager + { + public void StartImport(EntityType entityType, String CSVFileURI, String importSettingsJSON) + { + ImportFromCSV.Start(entityType, CSVFileURI, importSettingsJSON); + + var action = GetMessageAction(entityType); + MessageService.Send(HttpContext.Current.Request, action); + } + + public FileUploadResult ProcessUploadFake(string fileTemp, string importSettingsJSON) + { + var fileUploadResult = new FileUploadResult(); + + if (String.IsNullOrEmpty(fileTemp) || String.IsNullOrEmpty(importSettingsJSON)) return fileUploadResult; + + if (!Global.GetStore().IsFile("temp", fileTemp)) return fileUploadResult; + + JObject jObject; + + //Read contents + using (Stream storeStream = Global.GetStore().GetReadStream("temp", fileTemp)) + { + using (var CSVFileStream = new MemoryStream()) + { + //Copy + var buffer = new byte[4096]; + int readed; + while ((readed = storeStream.Read(buffer, 0, 4096)) != 0) + { + CSVFileStream.Write(buffer, 0, readed); + } + CSVFileStream.Position = 0; + + jObject = ImportFromCSV.GetInfo(CSVFileStream, importSettingsJSON); + } + } + + jObject.Add("assignedPath", fileTemp); + + fileUploadResult.Success = true; + fileUploadResult.Data = Global.EncodeTo64(jObject.ToString()); + + return fileUploadResult; + } + + private static MessageAction GetMessageAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Contact: + return MessageAction.ContactsImportedFromCSV; + case EntityType.Task: + return MessageAction.CrmTasksImportedFromCSV; + case EntityType.Opportunity: + return MessageAction.OpportunitiesImportedFromCSV; + case EntityType.Case: + return MessageAction.CasesImportedFromCSV; + default: + throw new ArgumentException("entityType"); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs new file mode 100644 index 00000000000..00aa1cef506 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -0,0 +1,688 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Web.CRM.Resources; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Web; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Core; +using Autofac; + +namespace ASC.Web.CRM.Classes +{ + + public class InvoiceFormattedData + { + public int TemplateType { get; set; } + public Tuple Seller { get; set; } + public int LogoBase64Id { get; set; } + public string LogoBase64 { get; set; } + public string LogoSrcFormat { get; set; } + public Tuple Number { get; set; } + public List> Invoice { get; set; } + public Tuple Customer { get; set; } + public List TableHeaderRow { get; set; } + public List> TableBodyRows { get; set; } + public List> TableFooterRows { get; set; } + public Tuple TableTotalRow { get; set; } + public Tuple Terms { get; set; } + public Tuple Notes { get; set; } + public Tuple Consignee { get; set; } + + public int DeliveryAddressID { get; set; } + public int BillingAddressID { get; set; } + + public static InvoiceFormattedData GetData(Invoice invoice, int billingAddressID, int deliveryAddressID) + { + return invoice.JsonData != null ? ReadData(invoice.JsonData) : CreateData(invoice, billingAddressID, deliveryAddressID); + } + + public static InvoiceFormattedData GetDataAfterLinesUpdated(Invoice invoice) + { + if (invoice.JsonData != null) + { + var oldData = ReadData(invoice.JsonData); + return CreateDataAfterLinesUpdated(invoice, oldData); + } + else + { + return CreateData(invoice, 0, 0); + } + } + + private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, int deliveryAddressID) + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + + var data = new InvoiceFormattedData(); + var sb = new StringBuilder(); + var list = new List(); + var cultureInfo = string.IsNullOrEmpty(invoice.Language) + ? CultureInfo.CurrentCulture + : CultureInfo.GetCultureInfo(invoice.Language); + + + #region TemplateType + + data.TemplateType = (int) invoice.TemplateType; + + #endregion + + + #region Seller, LogoBase64, LogoSrcFormat + + var invoiceSettings = daoFactory.InvoiceDao.GetSettings(); + + if (!string.IsNullOrEmpty(invoiceSettings.CompanyName)) + { + sb.Append(invoiceSettings.CompanyName); + } + + if (!string.IsNullOrEmpty(invoiceSettings.CompanyAddress)) + { + var obj = JObject.Parse(invoiceSettings.CompanyAddress); + + var str = obj.Value("street"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("city"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("state"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("zip"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("country"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + if (list.Count > 0) + { + sb.AppendLine(); + sb.Append(string.Join(", ", list)); + } + } + + data.Seller = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Seller", cultureInfo), + sb.ToString()); + + if (invoiceSettings.CompanyLogoID != 0) + { + data.LogoBase64Id = invoiceSettings.CompanyLogoID; + //data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(invoiceSettings.CompanyLogoID); + data.LogoSrcFormat = OrganisationLogoManager.OrganisationLogoSrcFormat; + } + + #endregion + + + #region Number + + data.Number = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Invoice", cultureInfo), + invoice.Number); + + #endregion + + + #region Invoice + + data.Invoice = new List>(); + data.Invoice.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("IssueDate", cultureInfo), + invoice.IssueDate.ToShortDateString())); + if (!string.IsNullOrEmpty(invoice.PurchaseOrderNumber)) + { + data.Invoice.Add( + new Tuple( + CRMInvoiceResource.ResourceManager.GetString("PONumber", cultureInfo), + invoice.PurchaseOrderNumber)); + } + data.Invoice.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("DueDate", cultureInfo), + invoice.DueDate.ToShortDateString())); + + #endregion + + + #region Customer + + var customer = daoFactory.ContactDao.GetByID(invoice.ContactID); + + if (customer != null) + { + sb = new StringBuilder(); + + sb.Append(customer.GetTitle()); + + var billingAddress = billingAddressID != 0 + ? daoFactory.ContactInfoDao.GetByID(billingAddressID) + : null; + if (billingAddress != null && billingAddress.InfoType == ContactInfoType.Address && + billingAddress.Category == (int) AddressCategory.Billing) + { + list = new List(); + + var obj = JObject.Parse(billingAddress.Data); + + var str = obj.Value("street"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("city"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("state"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("zip"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("country"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + if (list.Count > 0) + { + sb.AppendLine(); + sb.Append(string.Join(", ", list)); + } + } + + data.Customer = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("BillTo", cultureInfo), + sb.ToString()); + } + + #endregion + + + #region TableHeaderRow, TableBodyRows, TableFooterRows, TableTotalRow + + data.TableHeaderRow = new List + { + CRMInvoiceResource.ResourceManager.GetString("ItemCol", cultureInfo), + CRMInvoiceResource.ResourceManager.GetString("QuantityCol", cultureInfo), + CRMInvoiceResource.ResourceManager.GetString("PriceCol", cultureInfo), + CRMInvoiceResource.ResourceManager.GetString("DiscountCol", cultureInfo), + CRMInvoiceResource.ResourceManager.GetString("TaxCol", cultureInfo), + CRMInvoiceResource.ResourceManager.GetString("TaxCol", cultureInfo), + CRMInvoiceResource.ResourceManager.GetString("AmountCol", cultureInfo) + }; + + data.TableBodyRows = new List>(); + + var invoiceLines = invoice.GetInvoiceLines(daoFactory); + var invoiceTaxes = new Dictionary(); + + decimal subtotal = 0; + decimal discount = 0; + decimal amount = 0; + + foreach (var line in invoiceLines) + { + var item = daoFactory.InvoiceItemDao.GetByID(line.InvoiceItemID); + var tax1 = line.InvoiceTax1ID > 0 + ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax1ID) + : null; + var tax2 = line.InvoiceTax2ID > 0 + ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax2ID) + : null; + + var subtotalValue = Math.Round(line.Quantity*line.Price, 2); + var discountValue = Math.Round(subtotalValue*line.Discount/100, 2); + + decimal rate = 0; + if (tax1 != null) + { + rate += tax1.Rate; + if (invoiceTaxes.ContainsKey(tax1.ID)) + { + invoiceTaxes[tax1.ID] = invoiceTaxes[tax1.ID] + + Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2); + } + else + { + invoiceTaxes.Add(tax1.ID, Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2)); + } + } + if (tax2 != null) + { + rate += tax2.Rate; + if (invoiceTaxes.ContainsKey(tax2.ID)) + { + invoiceTaxes[tax2.ID] = invoiceTaxes[tax2.ID] + + Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2); + } + else + { + invoiceTaxes.Add(tax2.ID, Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2)); + } + } + + decimal taxValue = Math.Round((subtotalValue - discountValue)*rate/100, 2); + decimal amountValue = Math.Round(subtotalValue - discountValue + taxValue, 2); + + subtotal += subtotalValue; + discount += discountValue; + amount += amountValue; + + data.TableBodyRows.Add(new List + { + item.Title + (string.IsNullOrEmpty(line.Description) ? string.Empty : ": " + line.Description), + line.Quantity.ToString(CultureInfo.InvariantCulture), + line.Price.ToString(CultureInfo.InvariantCulture), + line.Discount.ToString(CultureInfo.InvariantCulture), + tax1 != null ? tax1.Name : string.Empty, + tax2 != null ? tax2.Name : string.Empty, + (subtotalValue - discountValue).ToString(CultureInfo.InvariantCulture) + }); + } + + data.TableFooterRows = new List>(); + data.TableFooterRows.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Subtotal", cultureInfo), + (subtotal - discount).ToString(CultureInfo.InvariantCulture))); + + foreach (var invoiceTax in invoiceTaxes) + { + var iTax = daoFactory.InvoiceTaxDao.GetByID(invoiceTax.Key); + data.TableFooterRows.Add(new Tuple( + string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), + invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); + } + + //data.TableFooterRows.Add(new Tuple(CRMInvoiceResource.ResourceManager.GetString("Discount", cultureInfo), "-" + discount.ToString(CultureInfo.InvariantCulture))); + + data.TableTotalRow = + new Tuple( + string.Format("{0} ({1})", CRMInvoiceResource.ResourceManager.GetString("Total", cultureInfo), + invoice.Currency), amount.ToString(CultureInfo.InvariantCulture)); + + + #endregion + + + #region Terms + + data.Terms = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Terms", cultureInfo), + invoice.Terms); + + #endregion + + + #region Notes + + if (!string.IsNullOrEmpty(invoice.Description)) + { + data.Notes = + new Tuple( + CRMInvoiceResource.ResourceManager.GetString("ClientNotes", cultureInfo), + invoice.Description); + } + + #endregion + + + #region Consignee + + var consignee = daoFactory.ContactDao.GetByID(invoice.ConsigneeID); + + if (consignee != null) + { + sb = new StringBuilder(); + + sb.Append(consignee.GetTitle()); + + var deliveryAddress = deliveryAddressID != 0 + ? daoFactory.ContactInfoDao.GetByID(deliveryAddressID) + : null; + if (deliveryAddress != null && deliveryAddress.InfoType == ContactInfoType.Address && + deliveryAddress.Category == (int) AddressCategory.Postal) + { + list = new List(); + + var obj = JObject.Parse(deliveryAddress.Data); + + var str = obj.Value("street"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("city"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("state"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("zip"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + str = obj.Value("country"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + + if (list.Count > 0) + { + sb.AppendLine(); + sb.Append(string.Join(", ", list)); + } + } + + data.Consignee = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("ShipTo", cultureInfo), + sb.ToString()); + } + + #endregion + + #region Addresses + + data.BillingAddressID = billingAddressID; + data.DeliveryAddressID = deliveryAddressID; + + #endregion + + return data; + } + } + + private static InvoiceFormattedData ReadData(string jsonData) + { + var data = new InvoiceFormattedData(); + var jsonObj = JObject.Parse(jsonData); + + + #region TemplateType + + data.TemplateType = jsonObj.Value("TemplateType"); + + #endregion + + + #region Seller, LogoBase64, LogoSrcFormat + + var seller = jsonObj.Value("Seller"); + if (seller != null) + { + data.Seller = seller.ToObject>(); + } + + data.LogoBase64 = jsonObj.Value("LogoBase64"); + data.LogoBase64Id = !String.IsNullOrEmpty(jsonObj.Value("LogoBase64Id")) ? jsonObj.Value("LogoBase64Id") : 0; + + if (string.IsNullOrEmpty(data.LogoBase64) && data.LogoBase64Id != 0) + { + data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(data.LogoBase64Id); + } + + + data.LogoSrcFormat = jsonObj.Value("LogoSrcFormat"); + + #endregion + + + #region Number + + var number = jsonObj.Value("Number"); + if (number != null) + { + data.Number = number.ToObject>(); + } + + #endregion + + + #region Invoice + + var invoice = jsonObj.Value("Invoice"); + if (invoice != null) + { + data.Invoice = invoice.ToObject>>(); + } + + #endregion + + + #region Customer + + var customer = jsonObj.Value("Customer"); + if (customer != null) + { + data.Customer = customer.ToObject>(); + } + + #endregion + + + #region TableHeaderRow, TableBodyRows, TableFooterRows, Total + + var tableHeaderRow = jsonObj.Value("TableHeaderRow"); + if (tableHeaderRow != null) + { + data.TableHeaderRow = tableHeaderRow.ToObject>(); + } + + var tableBodyRows = jsonObj.Value("TableBodyRows"); + if (tableBodyRows != null) + { + data.TableBodyRows = tableBodyRows.ToObject>>(); + } + + var tableFooterRows = jsonObj.Value("TableFooterRows"); + if (tableFooterRows != null) + { + data.TableFooterRows = tableFooterRows.ToObject>>(); + } + + var tableTotalRow = jsonObj.Value("TableTotalRow"); + if (tableTotalRow != null) + { + data.TableTotalRow = tableTotalRow.ToObject>(); + } + + #endregion + + + #region Terms + + var terms = jsonObj.Value("Terms"); + if (terms != null) + { + data.Terms = terms.ToObject>(); + } + + #endregion + + + #region Notes + + var notes = jsonObj.Value("Notes"); + if (notes != null) + { + data.Notes = notes.ToObject>(); + } + + #endregion + + + #region Consignee + + var consignee = jsonObj.Value("Consignee"); + if (consignee != null) + { + data.Consignee = consignee.ToObject>(); + } + + #endregion + + + #region Addresses + + data.DeliveryAddressID = !String.IsNullOrEmpty(jsonObj.Value("DeliveryAddressID")) ? jsonObj.Value("DeliveryAddressID") : 0; + data.BillingAddressID = !String.IsNullOrEmpty(jsonObj.Value("BillingAddressID")) ? jsonObj.Value("BillingAddressID") : 0; + + #endregion + + return data; + } + + private static InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, + InvoiceFormattedData invoiceOldData) + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + + var data = invoiceOldData; + + var cultureInfo = string.IsNullOrEmpty(invoice.Language) + ? CultureInfo.CurrentCulture + : CultureInfo.GetCultureInfo(invoice.Language); + + #region TableBodyRows, TableFooterRows, TableTotalRow + + data.TableBodyRows = new List>(); + + var invoiceLines = invoice.GetInvoiceLines(daoFactory); + var invoiceTaxes = new Dictionary(); + + decimal subtotal = 0; + decimal discount = 0; + decimal amount = 0; + + foreach (var line in invoiceLines) + { + var item = daoFactory.InvoiceItemDao.GetByID(line.InvoiceItemID); + var tax1 = line.InvoiceTax1ID > 0 + ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax1ID) + : null; + var tax2 = line.InvoiceTax2ID > 0 + ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax2ID) + : null; + + var subtotalValue = Math.Round(line.Quantity*line.Price, 2); + var discountValue = Math.Round(subtotalValue*line.Discount/100, 2); + + decimal rate = 0; + if (tax1 != null) + { + rate += tax1.Rate; + if (invoiceTaxes.ContainsKey(tax1.ID)) + { + invoiceTaxes[tax1.ID] = invoiceTaxes[tax1.ID] + + Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2); + } + else + { + invoiceTaxes.Add(tax1.ID, Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2)); + } + } + if (tax2 != null) + { + rate += tax2.Rate; + if (invoiceTaxes.ContainsKey(tax2.ID)) + { + invoiceTaxes[tax2.ID] = invoiceTaxes[tax2.ID] + + Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2); + } + else + { + invoiceTaxes.Add(tax2.ID, Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2)); + } + } + + decimal taxValue = Math.Round((subtotalValue - discountValue)*rate/100, 2); + decimal amountValue = Math.Round(subtotalValue - discountValue + taxValue, 2); + + subtotal += subtotalValue; + discount += discountValue; + amount += amountValue; + + data.TableBodyRows.Add(new List + { + item.Title + (string.IsNullOrEmpty(line.Description) ? string.Empty : ": " + line.Description), + line.Quantity.ToString(CultureInfo.InvariantCulture), + line.Price.ToString(CultureInfo.InvariantCulture), + line.Discount.ToString(CultureInfo.InvariantCulture), + tax1 != null ? tax1.Name : string.Empty, + tax2 != null ? tax2.Name : string.Empty, + (subtotalValue - discountValue).ToString(CultureInfo.InvariantCulture) + }); + } + + data.TableFooterRows = new List>(); + data.TableFooterRows.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Subtotal", cultureInfo), + (subtotal - discount).ToString(CultureInfo.InvariantCulture))); + + foreach (var invoiceTax in invoiceTaxes) + { + var iTax = daoFactory.InvoiceTaxDao.GetByID(invoiceTax.Key); + data.TableFooterRows.Add(new Tuple( + string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), + invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); + } + + //data.TableFooterRows.Add(new Tuple(CRMInvoiceResource.ResourceManager.GetString("Discount", cultureInfo), "-" + discount.ToString(CultureInfo.InvariantCulture))); + + data.TableTotalRow = + new Tuple( + string.Format("{0} ({1})", CRMInvoiceResource.ResourceManager.GetString("Total", cultureInfo), + invoice.Currency), amount.ToString(CultureInfo.InvariantCulture)); + + + #endregion + + + return data; + } + } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs b/products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs new file mode 100644 index 00000000000..6ce73b107b8 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs @@ -0,0 +1,292 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.CRM.Resources; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Reflection; + +#endregion + +namespace ASC.CRM.Classes +{ + + public static class EnumExtension + { + public static String ToLocalizedString(this Enum value) + { + return LocalizedEnumConverter.ConvertToString(value); + } + + public static bool TryParse(string value, out T result) + where T : struct // error CS0702: Constraint cannot be special class 'System.Enum' + { + return TryParse(value, false, out result); + } + + public static bool TryParse(string value, bool ignoreCase, out T result) + where T : struct // error CS0702: Constraint cannot be special class 'System.Enum' + { + if (value == null) + value = String.Empty; + + result = default(T); + try + { + result = (T)Enum.Parse(typeof(T), value, ignoreCase); + return true; + } + catch { } + + return false; + } + + + } + + public class LocalizedEnumConverter : EnumConverter + { + private class LookupTable : Dictionary { } + private Dictionary _lookupTables = new Dictionary(); + private System.Resources.ResourceManager _resourceManager; + private bool _isFlagEnum = false; + private Array _flagValues; + + /// + /// GetList the lookup table for the given culture (creating if necessary) + /// + /// + /// + private LookupTable GetLookupTable(CultureInfo culture) + { + LookupTable result = null; + if (culture == null) + culture = CultureInfo.CurrentCulture; + + if (!_lookupTables.TryGetValue(culture, out result)) + { + result = new LookupTable(); + foreach (object value in GetStandardValues()) + { + string text = GetValueText(culture, value); + if (text != null) + { + result.Add(text, value); + } + } + _lookupTables.Add(culture, result); + } + return result; + } + + /// + /// Return the text to display for a simple value in the given culture + /// + /// The culture to get the text for + /// The enum value to get the text for + /// The localized text + private string GetValueText(CultureInfo culture, object value) + { + Type type = value.GetType(); + string resourceName = string.Format("{0}_{1}", type.Name, value.ToString()); + string result = _resourceManager.GetString(resourceName, culture); + if (result == null) + result = resourceName; + return result; + } + + /// + /// Return true if the given value is can be represented using a single bit + /// + /// + /// + private bool IsSingleBitValue(ulong value) + { + switch (value) + { + case 0: + return false; + case 1: + return true; + } + return ((value & (value - 1)) == 0); + } + + /// + /// Return the text to display for a flag value in the given culture + /// + /// The culture to get the text for + /// The flag enum value to get the text for + /// The localized text + private string GetFlagValueText(CultureInfo culture, object value) + { + // if there is a standard value then use it + // + if (Enum.IsDefined(value.GetType(), value)) + { + return GetValueText(culture, value); + } + + // otherwise find the combination of flag bit values + // that makes up the value + // + ulong lValue = Convert.ToUInt32(value); + string result = null; + foreach (object flagValue in _flagValues) + { + ulong lFlagValue = Convert.ToUInt32(flagValue); + if (IsSingleBitValue(lFlagValue)) + { + if ((lFlagValue & lValue) == lFlagValue) + { + string valueText = GetValueText(culture, flagValue); + if (result == null) + { + result = valueText; + } + else + { + result = string.Format("{0}, {1}", result, valueText); + } + } + } + } + return result; + } + + /// + /// Return the Enum value for a simple (non-flagged enum) + /// + /// The culture to convert using + /// The text to convert + /// The enum value + private object GetValue(CultureInfo culture, string text) + { + LookupTable lookupTable = GetLookupTable(culture); + object result = null; + lookupTable.TryGetValue(text, out result); + return result; + } + + private object GetFlagValue(CultureInfo culture, string text) + { + LookupTable lookupTable = GetLookupTable(culture); + string[] textValues = text.Split(','); + ulong result = 0; + foreach (string textValue in textValues) + { + object value = null; + string trimmedTextValue = textValue.Trim(); + if (!lookupTable.TryGetValue(trimmedTextValue, out value)) + { + return null; + } + result |= Convert.ToUInt32(value); + } + return Enum.ToObject(EnumType, result); + } + + public LocalizedEnumConverter(Type type) + : base(type) + { + _resourceManager = CRMEnumResource.ResourceManager; + object[] flagAttributes = type.GetCustomAttributes(typeof(FlagsAttribute), true); + _isFlagEnum = flagAttributes.Length > 0; + if (_isFlagEnum) + { + _flagValues = Enum.GetValues(type); + } + } + + public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) + { + if (value is string) + { + object result = (_isFlagEnum) ? + GetFlagValue(culture, (string)value) : GetValue(culture, (string)value); + if (result == null) + { + result = base.ConvertFrom(context, culture, value); + } + return result; + } + + return base.ConvertFrom(context, culture, value); + + } + + public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) + { + if (value != null && destinationType == typeof(string)) + { + object result = (_isFlagEnum) ? + GetFlagValueText(culture, value) : GetValueText(culture, value); + return result; + } + else + { + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public static string ConvertToString(Enum value) + { + TypeConverter converter = TypeDescriptor.GetConverter(value.GetType()); + return converter.ConvertToString(value); + } + + public static List> GetValues(Type enumType, CultureInfo culture) + { + List> result = new List>(); + TypeConverter converter = TypeDescriptor.GetConverter(enumType); + foreach (Enum value in Enum.GetValues(enumType)) + { + KeyValuePair pair = new KeyValuePair(value, converter.ConvertToString(null, culture, value)); + result.Add(pair); + } + return result; + } + + public static List> GetValues(Type enumType) + { + return GetValues(enumType, CultureInfo.CurrentUICulture); + } + + public static List GetLocalizedValues(Type enumType) + { + var converter = TypeDescriptor.GetConverter(enumType); + + return (from Enum value in Enum.GetValues(enumType) + select converter.ConvertToString(null, CultureInfo.CurrentUICulture, value)).ToList(); + + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs new file mode 100644 index 00000000000..253f2113b5f --- /dev/null +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -0,0 +1,178 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using ASC.Common.Logging; +using ASC.CRM.Core.Dao; +using ASC.Data.Storage; +using ASC.Web.Core; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM.Configuration; +using ASC.Web.CRM.Core; +using Autofac; + +namespace ASC.Web.CRM.Classes +{ + public static class OrganisationLogoManager + { + #region Members + + public static readonly String OrganisationLogoBaseDirName = "organisationlogo"; + public static readonly String OrganisationLogoImgName = "logo"; + + public static readonly String OrganisationLogoSrcFormat = "data:image/jpeg;base64,{0}"; + + public static readonly Size OrganisationLogoSize = new Size(200, 150); + + private static readonly Object _synchronizedObj = new Object(); + + #endregion + + #region Private Methods + + private static String BuildFileDirectory() + { + return String.Concat(OrganisationLogoBaseDirName, "/"); + } + + private static String BuildFilePath(String imageExtension) + { + return String.Concat(BuildFileDirectory(), OrganisationLogoImgName, imageExtension); + } + + + private static String ExecResizeImage(byte[] imageData, Size fotoSize, IDataStore dataStore, String photoPath) + { + var data = imageData; + using (var stream = new MemoryStream(data)) + using (var img = new Bitmap(stream)) + { + var imgFormat = img.RawFormat; + if (fotoSize != img.Size) + { + using (var img2 = CommonPhotoManager.DoThumbnail(img, fotoSize, false, false, false)) + { + data = CommonPhotoManager.SaveToBytes(img2, Global.GetImgFormatName(imgFormat)); + } + } + else + { + data = Global.SaveToBytes(img); + } + + using (var fileStream = new MemoryStream(data)) + { + var photoUri = dataStore.Save(photoPath, fileStream).ToString(); + photoUri = String.Format("{0}?cd={1}", photoUri, DateTime.UtcNow.Ticks); + return photoUri; + } + } + } + + + + #endregion + + public static String GetDefaultLogoUrl() + { + return WebImageSupplier.GetAbsoluteWebPath("org_logo_default.png", ProductEntryPoint.ID); + } + + public static String GetOrganisationLogoBase64(int logoID) + { + if (logoID <= 0) { return ""; } + using (var scope = DIHelper.Resolve()) + { + return scope.Resolve().InvoiceDao.GetOrganisationLogoBase64(logoID); + } + } + + public static String GetOrganisationLogoSrc(int logoID) + { + var bytestring = GetOrganisationLogoBase64(logoID); + return String.IsNullOrEmpty(bytestring) ? "" : String.Format(OrganisationLogoSrcFormat, bytestring); + } + + public static void DeletePhoto(bool recursive) + { + var photoDirectory = BuildFileDirectory(); + var store = Global.GetStore(); + + lock (_synchronizedObj) + { + if (store.IsDirectory(photoDirectory)) + { + store.DeleteFiles(photoDirectory, "*", recursive); + if (recursive) + { + store.DeleteDirectory(photoDirectory); + } + } + } + } + + public static int TryUploadOrganisationLogoFromTmp(DaoFactory factory) + { + var directoryPath = BuildFileDirectory(); + var dataStore = Global.GetStore(); + + if (!dataStore.IsDirectory(directoryPath)) + return 0; + + try + { + var photoPaths = Global.GetStore().ListFilesRelative("", directoryPath, OrganisationLogoImgName + "*", false); + if (photoPaths.Length == 0) + return 0; + + byte[] bytes; + using (var photoTmpStream = dataStore.GetReadStream(Path.Combine(directoryPath, photoPaths[0]))) + { + bytes = Global.ToByteArray(photoTmpStream); + } + + var logoID = factory.InvoiceDao.SaveOrganisationLogo(bytes); + dataStore.DeleteFiles(directoryPath, "*", false); + return logoID; + } + + catch (Exception ex) + { + LogManager.GetLogger("ASC.CRM").ErrorFormat("TryUploadOrganisationLogoFromTmp failed with error: {0}", ex); + return 0; + } + } + + public static String UploadLogo(byte[] imageData, ImageFormat imageFormat) + { + var photoPath = BuildFilePath("." + Global.GetImgFormatName(imageFormat)); + return ExecResizeImage(imageData, OrganisationLogoSize, Global.GetStore(), photoPath); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/PathProvider.cs b/products/ASC.CRM/Server/Classes/PathProvider.cs new file mode 100644 index 00000000000..8852854da77 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/PathProvider.cs @@ -0,0 +1,108 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Web; +using ASC.Common.Web; +using ASC.Data.Storage; +using ASC.Web.Studio.Utility; +using Microsoft.AspNetCore.Http; + +#endregion + +namespace ASC.Web.CRM +{ + public class PathProvider + { + public PathProvider(IHttpContextAccessor httpContextAccessor, + CommonLinkUtility commonLinkUtility) + { + CommonLinkUtility = commonLinkUtility; + HttpContext = httpContextAccessor.HttpContext; + + BaseAbsolutePath = CommonLinkUtility.ToAbsolute(BaseVirtualPath); + } + + public HttpContext HttpContext { get; } + + public CommonLinkUtility CommonLinkUtility { get; } + public WebPath WebPath { get; } + + public readonly String BaseVirtualPath = "~/Products/CRM/"; + public readonly String BaseAbsolutePath; + + public String StartURL() + { + return BaseVirtualPath; + } + + //public string BaseSiteUrl + //{ + // get + // { + // string baseUrl = HttpContext.Request.GetUrlRewriter().Scheme + "://" + HttpContext.Request.GetUrlRewriter().Authority + HttpContext.Request.ApplicationPath.TrimEnd('/') + '/'; + // return baseUrl; + // } + //} + + //public string GetVirtualPath(string physicalPath) + //{ + // string rootpath = HttpContext.Server.MapPath("~/"); + // physicalPath = physicalPath.Replace(rootpath, ""); + // physicalPath = physicalPath.Replace("\\", "/"); + + // return "~/" + physicalPath; + //} + + // TODO: Remove GetFileStaticRelativePath method + //public String GetFileStaticRelativePath(String fileName) + //{ + // if (fileName.EndsWith(".js")) + // { + // //Attention: Only for ResourceBundleControl + // return VirtualPathUtility.ToAbsolute("~/Products/CRM/js/" + fileName); + // } + // if (fileName.EndsWith(".ascx")) + // { + // return VirtualPathUtility.ToAbsolute("~/Products/CRM/Controls/" + fileName); + // } + // if (fileName.EndsWith(".css") || fileName.EndsWith(".less")) + // { + // //Attention: Only for ResourceBundleControl + // return VirtualPathUtility.ToAbsolute("~/Products/CRM/App_Themes/default/css/" + fileName); + // } + // if (fileName.EndsWith(".png") || fileName.EndsWith(".gif") || fileName.EndsWith(".jpg")) + // { + // return WebPath.GetPath("/Products/CRM/App_Themes/default/images/" + fileName); + // } + + // return fileName; + //} + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/SignalRHelper.cs b/products/ASC.CRM/Server/Classes/SignalRHelper.cs new file mode 100644 index 00000000000..1170ad1f6a3 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/SignalRHelper.cs @@ -0,0 +1,70 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using ASC.Core.Notify.Signalr; +using ASC.VoipService; + +namespace ASC.Web.CRM.Classes +{ + public class SignalRHelper + { + private readonly string numberId; + private readonly SignalrServiceClient signalrServiceClient; + + public SignalRHelper(string numberId) + { + signalrServiceClient = new SignalrServiceClient("voip"); + this.numberId = numberId.TrimStart('+'); + } + + public void Enqueue(string call, string agent) + { + signalrServiceClient.EnqueueCall(numberId, call, agent); + } + + public void Incoming(string call, string agent) + { + signalrServiceClient.IncomingCall(call, agent); + } + + public void MissCall(string call, string agent) + { + signalrServiceClient.MissCall(numberId, call, agent); + } + + public void Reload(string agentId = null) + { + signalrServiceClient.Reload(numberId, agentId); + } + + public Tuple GetAgent(List contactsResponsibles) + { + return signalrServiceClient.GetAgent>(numberId, contactsResponsibles); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaAccountNotFound.cs b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaAccountNotFound.cs new file mode 100644 index 00000000000..692ac745cb9 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaAccountNotFound.cs @@ -0,0 +1,35 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; + +namespace ASC.Web.CRM.SocialMedia +{ + public class SocialMediaAccountNotFound : Exception + { + public SocialMediaAccountNotFound(string message) : base(message) { } + } +} diff --git a/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs new file mode 100644 index 00000000000..fff25668c32 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs @@ -0,0 +1,41 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using ASC.Thrdparty; + +namespace ASC.Web.CRM.Classes.SocialMedia +{ + public class SocialMediaImageDescription + { + public SocialNetworks SocialNetwork { get; set; } + public string ImageUrl { get; set; } + public string Identity { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaUI.cs b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaUI.cs new file mode 100644 index 00000000000..d48f538f7c2 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaUI.cs @@ -0,0 +1,163 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.CRM.Classes.SocialMedia; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; + + +namespace ASC.Web.CRM.SocialMedia +{ + public class SocialMediaUI + { + private ILog _logger = LogManager.GetLogger("ASC"); + public DaoFactory DaoFactory { get; set; } + public TenantManager TenantManager { get; set; } + + public SocialMediaUI(DaoFactory factory, + TenantManager tenantManager) + { + DaoFactory = factory; + TenantManager = tenantManager; + } + + public List GetContactSMImages(int contactID) + { + var contact = DaoFactory.ContactDao.GetByID(contactID); + + var images = new List(); + + + var socialNetworks = DaoFactory.ContactInfoDao.GetList(contact.ID, null, null, null); + + var twitterAccounts = socialNetworks.Where(sn => sn.InfoType == ContactInfoType.Twitter).Select(sn => sn.Data.Trim()).ToList(); + + Func, Tenant, List> dlgGetTwitterImageDescriptionList = GetTwitterImageDescriptionList; + + // Parallelizing + + var waitHandles = new List(); + + var currentTenant = TenantManager.GetCurrentTenant(); + + var arGetAvatarsFromTwitter = dlgGetTwitterImageDescriptionList.BeginInvoke(twitterAccounts, currentTenant, null, null); + waitHandles.Add(arGetAvatarsFromTwitter.AsyncWaitHandle); + + WaitHandle.WaitAll(waitHandles.ToArray()); + + images.AddRange(dlgGetTwitterImageDescriptionList.EndInvoke(arGetAvatarsFromTwitter)); + + return images; + } + + public List GetContactSMImages(List twitter) + { + var images = new List(); + + Func, Tenant, List> dlgGetTwitterImageDescriptionList = GetTwitterImageDescriptionList; + + // Parallelizing + + var waitHandles = new List(); + + var currentTenant = TenantManager.GetCurrentTenant(); + + var arGetAvatarsFromTwitter = dlgGetTwitterImageDescriptionList.BeginInvoke(twitter, currentTenant, null, null); + waitHandles.Add(arGetAvatarsFromTwitter.AsyncWaitHandle); + + WaitHandle.WaitAll(waitHandles.ToArray()); + + images.AddRange(dlgGetTwitterImageDescriptionList.EndInvoke(arGetAvatarsFromTwitter)); + + return images; + } + + private List GetTwitterImageDescriptionList(List twitterAccounts, Tenant tenant) + { + var images = new List(); + + if (twitterAccounts.Count == 0) + return images; + + try + { + TenantManager.SetCurrentTenant(tenant); + + var provider = new TwitterDataProvider(TwitterApiHelper.GetTwitterApiInfoForCurrentUser()); + + twitterAccounts = twitterAccounts.Distinct().ToList(); + images.AddRange(from twitterAccount in twitterAccounts + let imageUrl = provider.GetUrlOfUserImage(twitterAccount, TwitterDataProvider.ImageSize.Small) + where imageUrl != null + select new SocialMediaImageDescription + { + Identity = twitterAccount, + ImageUrl = imageUrl, + SocialNetwork = SocialNetworks.Twitter + }); + } + catch (Exception ex) + { + _logger.Error(ex); + } + + return images; + } + + public Exception ProcessError(Exception exception, string methodName) + { + if (exception is ConnectionFailureException) + return new Exception(CRMSocialMediaResource.ErrorTwitterConnectionFailure); + + if (exception is RateLimitException) + return new Exception(CRMSocialMediaResource.ErrorTwitterRateLimit); + + if (exception is ResourceNotFoundException) + return new Exception(CRMSocialMediaResource.ErrorTwitterAccountNotFound); + + if (exception is UnauthorizedException) + return new Exception(CRMSocialMediaResource.ErrorTwitterUnauthorized); + + if (exception is SocialMediaException) + return new Exception(CRMSocialMediaResource.ErrorInternalServer); + + if (exception is SocialMediaAccountNotFound) + return exception; + + var unknownErrorText = String.Format("{0} error: Unknown exception:", methodName); + _logger.Error(unknownErrorText, exception); + return new Exception(CRMSocialMediaResource.ErrorInternalServer); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs b/products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs new file mode 100644 index 00000000000..eb8cd192199 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs @@ -0,0 +1,53 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.FederatedLogin.LoginProviders; +using ASC.Thrdparty.Twitter; + +namespace ASC.Web.CRM.Classes.SocialMedia +{ + public static class TwitterApiHelper + { + public static TwitterApiInfo GetTwitterApiInfoForCurrentUser() + { + TwitterApiInfo apiInfo = new TwitterApiInfo + { + ConsumerKey = TwitterLoginProvider.TwitterKey, + ConsumerSecret = TwitterLoginProvider.TwitterSecret + }; + + SetDefaultTokens(apiInfo); + + return apiInfo; + } + + private static void SetDefaultTokens(TwitterApiInfo apiInfo) + { + apiInfo.AccessToken = TwitterLoginProvider.TwitterDefaultAccessToken; + apiInfo.AccessTokenSecret = TwitterLoginProvider.TwitterAccessTokenSecret; + } + } +} diff --git a/products/ASC.CRM/Server/Classes/StringConverter.cs b/products/ASC.CRM/Server/Classes/StringConverter.cs new file mode 100644 index 00000000000..b1204c73971 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/StringConverter.cs @@ -0,0 +1,368 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +/* CSVReader - a simple open source C# class library to read CSV data + * by Andrew Stellman - http://www.stellman-greene.com/CSVReader + * + * StringConverter.cs - Class to convert strings to typed objects + * + * download the latest version: http://svn.stellman-greene.com/CSVReader + * + * (c) 2008, Stellman & Greene Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Stellman & Greene Consulting nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY STELLMAN & GREENE CONSULTING ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL STELLMAN & GREENE CONSULTING BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +using System; +using System.Collections.Generic; + +namespace ASC.Web.CRM.Classes +{ + /// + /// Static class to convert strings to typed values + /// + public static class StringConverter + { + public static Type ConvertString(string value, out object convertedValue) + { + // First check the whole number types, because floating point types will always parse whole numbers + // Start with the smallest types + byte byteResult; + if (byte.TryParse(value, out byteResult)) + { + convertedValue = byteResult; + return typeof(byte); + } + + short shortResult; + if (short.TryParse(value, out shortResult)) + { + convertedValue = shortResult; + return typeof(short); + } + + int intResult; + if (int.TryParse(value, out intResult)) + { + convertedValue = intResult; + return typeof(int); + } + + long longResult; + if (long.TryParse(value, out longResult)) + { + convertedValue = longResult; + return typeof(long); + } + + ulong ulongResult; + if (ulong.TryParse(value, out ulongResult)) + { + convertedValue = ulongResult; + return typeof(ulong); + } + + // No need to check the rest of the unsigned types, which will fit into the signed whole number types + + // Next check the floating point types + float floatResult; + if (float.TryParse(value, out floatResult)) + { + convertedValue = floatResult; + return typeof(float); + } + + + // It's not clear that there's anything that double.TryParse() and decimal.TryParse() will parse + // but which float.TryParse() won't + double doubleResult; + if (double.TryParse(value, out doubleResult)) + { + convertedValue = doubleResult; + return typeof(double); + } + + decimal decimalResult; + if (decimal.TryParse(value, out decimalResult)) + { + convertedValue = decimalResult; + return typeof(decimal); + } + + // It's not a number, so it's either a bool, char or string + bool boolResult; + if (bool.TryParse(value, out boolResult)) + { + convertedValue = boolResult; + return typeof(bool); + } + + char charResult; + if (char.TryParse(value, out charResult)) + { + convertedValue = charResult; + return typeof(char); + } + + convertedValue = value; + return typeof(string); + } + + /// + /// Compare two types and find a type that can fit both of them + /// + /// First type to compare + /// Second type to compare + /// The type that can fit both types, or string if they're incompatible + public static Type FindCommonType(Type typeA, Type typeB) + { + // Build the singleton type map (which will rebuild it in a typesafe manner + // if it's not already built). + BuildTypeMap(); + + if (!typeMap.ContainsKey(typeA)) + return typeof(string); + + if (!typeMap[typeA].ContainsKey(typeB)) + return typeof(string); + + return typeMap[typeA][typeB]; + } + + + // Dictionary to map two types to a common type that can hold both of them + private static Dictionary> typeMap = null; + + // Locker object to build the singleton typeMap in a typesafe manner + private static object locker = new object(); + + /// + /// Build the singleton type map in a typesafe manner. + /// This map is a dictionary that maps a pair of types to a common type. + /// So typeMap[typeof(float)][typeof(uint)] will return float, while + /// typemap[typeof(char)][typeof(bool)] will return string. + /// + private static void BuildTypeMap() + { + lock (locker) + { + if (typeMap == null) + { + typeMap = new Dictionary>() + { + // Comparing byte + {typeof(byte), new Dictionary() { + { typeof(byte), typeof(byte) }, + { typeof(short), typeof(short) }, + { typeof(int), typeof(int) }, + { typeof(long), typeof(long) }, + { typeof(ulong), typeof(ulong) }, + { typeof(float), typeof(float) }, + { typeof(double), typeof(double) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing short + {typeof(short), new Dictionary() { + { typeof(byte), typeof(short) }, + { typeof(short), typeof(short) }, + { typeof(int), typeof(int) }, + { typeof(long), typeof(long) }, + { typeof(ulong), typeof(ulong) }, + { typeof(float), typeof(float) }, + { typeof(double), typeof(double) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing int + {typeof(int), new Dictionary() { + { typeof(byte), typeof(int) }, + { typeof(short), typeof(int) }, + { typeof(int), typeof(int) }, + { typeof(long), typeof(long) }, + { typeof(ulong), typeof(ulong) }, + { typeof(float), typeof(float) }, + { typeof(double), typeof(double) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing long + {typeof(long), new Dictionary() { + { typeof(byte), typeof(long) }, + { typeof(short), typeof(long) }, + { typeof(int), typeof(long) }, + { typeof(long), typeof(long) }, + { typeof(ulong), typeof(ulong) }, + { typeof(float), typeof(float) }, + { typeof(double), typeof(double) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing ulong + {typeof(ulong), new Dictionary() { + { typeof(byte), typeof(ulong) }, + { typeof(short), typeof(ulong) }, + { typeof(int), typeof(ulong) }, + { typeof(long), typeof(ulong) }, + { typeof(ulong), typeof(ulong) }, + { typeof(float), typeof(float) }, + { typeof(double), typeof(double) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing float + {typeof(float), new Dictionary() { + { typeof(byte), typeof(float) }, + { typeof(short), typeof(float) }, + { typeof(int), typeof(float) }, + { typeof(long), typeof(float) }, + { typeof(ulong), typeof(float) }, + { typeof(float), typeof(float) }, + { typeof(double), typeof(double) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing double + {typeof(double), new Dictionary() { + { typeof(byte), typeof(double) }, + { typeof(short), typeof(double) }, + { typeof(int), typeof(double) }, + { typeof(long), typeof(double) }, + { typeof(ulong), typeof(double) }, + { typeof(float), typeof(double) }, + { typeof(double), typeof(double) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing decimal + {typeof(decimal), new Dictionary() { + { typeof(byte), typeof(decimal) }, + { typeof(short), typeof(decimal) }, + { typeof(int), typeof(decimal) }, + { typeof(long), typeof(decimal) }, + { typeof(ulong), typeof(decimal) }, + { typeof(float), typeof(decimal) }, + { typeof(double), typeof(decimal) }, + { typeof(decimal), typeof(decimal) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing bool + {typeof(bool), new Dictionary() { + { typeof(byte), typeof(string) }, + { typeof(short), typeof(string) }, + { typeof(int), typeof(string) }, + { typeof(long), typeof(string) }, + { typeof(ulong), typeof(string) }, + { typeof(float), typeof(string) }, + { typeof(double), typeof(string) }, + { typeof(decimal), typeof(string) }, + { typeof(bool), typeof(bool) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing char + {typeof(char), new Dictionary() { + { typeof(byte), typeof(string) }, + { typeof(short), typeof(string) }, + { typeof(int), typeof(string) }, + { typeof(long), typeof(string) }, + { typeof(ulong), typeof(string) }, + { typeof(float), typeof(string) }, + { typeof(double), typeof(string) }, + { typeof(decimal), typeof(string) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(char) }, + { typeof(string), typeof(string) }, + }}, + + // Comparing string + {typeof(string), new Dictionary() { + { typeof(byte), typeof(string) }, + { typeof(short), typeof(string) }, + { typeof(int), typeof(string) }, + { typeof(long), typeof(string) }, + { typeof(ulong), typeof(string) }, + { typeof(float), typeof(string) }, + { typeof(double), typeof(string) }, + { typeof(decimal), typeof(string) }, + { typeof(bool), typeof(string) }, + { typeof(char), typeof(string) }, + { typeof(string), typeof(string) }, + }}, + + }; + } + } + } + } +} diff --git a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs new file mode 100644 index 00000000000..039577bdeec --- /dev/null +++ b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs @@ -0,0 +1,136 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.CRM.Resources; +using ASC.Notify.Model; +using ASC.Web.Core.Subscriptions; +using ASC.Web.CRM.Services.NotifyService; +using System; +using System.Collections.Generic; + +#endregion + +namespace ASC.Web.CRM +{ + + public class ProductSubscriptionManager : IProductSubscriptionManager + { + + private readonly Guid _setAccess = new Guid("{D4D58C55-D32E-41dc-9D22-D123AFAFC7E7}"); + private readonly Guid _responsibleForTask = new Guid("{2479B115-EAEB-4d9a-86DA-51BD708DEFDC}"); + private readonly Guid _responsibleForOpprotunity = new Guid("{73720A31-1981-480f-AB34-074E8BAEDBA9}"); + private readonly Guid _addRelationshipEvent = new Guid("{4E16DBC5-A427-469e-9EF7-A8DEA0F61310}"); + private readonly Guid _exportCompleted = new Guid("{88D3DC5E-3E46-46a1-9FEF-6B8FFF020BA4}"); + private readonly Guid _importCompleted = new Guid("{6A717AAD-16AE-4713-A782-B887766BEB9F}"); + private readonly Guid _createNewContact = new Guid("{ADAC1E70-4163-41c1-8968-67A44E4D24E7}"); + + public List GetSubscriptionObjects(Guid subItem) + { + return new List(); + } + + public List GetSubscriptionTypes() + { + return new List + { + new SubscriptionType + { + ID = _setAccess, + Name = CRMCommonResource.SubscriptionType_SetAccess, + NotifyAction = NotifyConstants.Event_SetAccess, + Single = true, + CanSubscribe = true + }, + new SubscriptionType + { + ID = _responsibleForTask, + Name = CRMCommonResource.SubscriptionType_ResponsibleForTask, + NotifyAction = NotifyConstants.Event_ResponsibleForTask, + Single = true, + CanSubscribe = true + }, + new SubscriptionType + { + ID = _responsibleForOpprotunity, + Name = CRMCommonResource.SubscriptionType_ResponsibleForOpportunity, + NotifyAction = NotifyConstants.Event_ResponsibleForOpportunity, + Single = true, + CanSubscribe = true + }, + new SubscriptionType + { + ID = _addRelationshipEvent, + Name = CRMCommonResource.SubscriptionType_AddRelationshipEvent, + NotifyAction = NotifyConstants.Event_AddRelationshipEvent, + Single = true, + CanSubscribe = true + }, + new SubscriptionType + { + ID = _exportCompleted, + Name = CRMCommonResource.SubscriptionType_ExportCompleted, + NotifyAction = CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, + Single = true, + CanSubscribe = true + }, + new SubscriptionType + { + ID = _importCompleted, + Name = CRMCommonResource.SubscriptionType_ImportCompleted, + NotifyAction = CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, + Single = true, + CanSubscribe = true + }, + new SubscriptionType + { + ID = _createNewContact, + Name = CRMCommonResource.SubscriptionType_CreateNewContact, + NotifyAction = NotifyConstants.Event_CreateNewContact, + Single = true, + CanSubscribe = true + } + }; + } + + public ISubscriptionProvider SubscriptionProvider + { + get { return NotifySource.Instance.GetSubscriptionProvider(); } + } + + public GroupByType GroupByType + { + get { return GroupByType.Simple; } + } + + public List GetSubscriptionGroups() + { + return new List(); + } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/TwilioController.cs b/products/ASC.CRM/Server/Classes/TwilioController.cs new file mode 100644 index 00000000000..5ebaa54891b --- /dev/null +++ b/products/ASC.CRM/Server/Classes/TwilioController.cs @@ -0,0 +1,498 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Common.Configuration; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.VoipService; +using ASC.VoipService.Twilio; +using ASC.Web.CRM.Core; +using ASC.Web.Studio.Utility; +using Autofac; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Web; +using Twilio.TwiML; + +namespace ASC.Web.CRM.Classes +{ + [ValidateRequest] + public class TwilioController : ApiController + { + private static readonly ILog Log = LogManager.GetLogger("ASC"); + private static readonly object LockObj = new object(); + + [System.Web.Http.HttpPost] + public HttpResponseMessage Index(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) + { + try + { + lock (LockObj) + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + request.AddAdditionalFields(callerId, contactId); + var response = request.IsInbound ? Inbound(request, daoFactory) : Outbound(request, daoFactory); + return GetHttpResponse(response); + } + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage Client(TwilioVoiceRequest request, [FromUri]Guid callerId) + { + try + { + using (var scope = DIHelper.Resolve()) + { + request.AddAdditionalFields(callerId); + + new VoipEngine(scope.Resolve()).SaveOrUpdateCall(CallFromTwilioRequest(request)); + + return GetHttpResponse(new VoiceResponse()); + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage Dial(TwilioVoiceRequest request, [FromUri]Guid callerId, [FromUri]int contactId = 0, [FromUri]string reject = null) + { + try + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var voipEngine = new VoipEngine(daoFactory); + + request.AddAdditionalFields(callerId, contactId, reject); + + var call = CallFromTwilioRequest(request); + call = voipEngine.SaveOrUpdateCall(call); + + var parentCall = daoFactory.VoipDao.GetCall(call.ParentID); + + if (!string.IsNullOrEmpty(request.RecordingSid)) + { + if (parentCall.VoipRecord == null || string.IsNullOrEmpty(parentCall.VoipRecord.Id)) + { + parentCall.VoipRecord = new VoipRecord {Id = request.RecordingSid}; + } + + daoFactory.VoipDao.SaveOrUpdateCall(parentCall); + } + + voipEngine.SaveAdditionalInfo(parentCall.Id); + + return GetHttpResponse(request.Dial()); + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage Enqueue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) + { + try + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var voipEngine = new VoipEngine(daoFactory); + + request.AddAdditionalFields(callerId, contactId); + if (request.QueueResult != "bridged" && request.QueueResult != "redirected") + { + MissCall(request, voipEngine); + } + + return GetHttpResponse(request.Enqueue(request.QueueResult)); + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage Queue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) + { + try + { + request.AddAdditionalFields(callerId, contactId); + return GetHttpResponse(request.Queue()); + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage Dequeue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0, [FromUri]string reject = "") + { + try + { + using (var scope = DIHelper.Resolve()) + { + var voipEngine = new VoipEngine(scope.Resolve()); + request.AddAdditionalFields(callerId, contactId, reject); + + if (Convert.ToBoolean(request.Reject)) + { + MissCall(request, voipEngine); + return GetHttpResponse(request.Leave()); + } + + + voipEngine.AnswerCall(CallFromTwilioRequest(request)); + + return GetHttpResponse(request.Dequeue()); + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage Wait(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0, [FromUri]string redirectTo = null) + { + try + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var voipEngine = new VoipEngine(daoFactory); + + request.AddAdditionalFields(callerId, contactId, redirectTo: redirectTo); + if (Convert.ToInt32(request.QueueTime) == 0) + { + var history = CallFromTwilioRequest(request); + history.ParentID = history.Id; + voipEngine.SaveOrUpdateCall(history); + + var to = request.RedirectTo; + if (string.IsNullOrEmpty(to)) + { + request.GetSignalRHelper() + .Enqueue(request.CallSid, callerId.HasValue ? callerId.Value.ToString() : ""); + } + else + { + request.GetSignalRHelper().Incoming(request.CallSid, to); + } + } + + return GetHttpResponse(request.Wait()); + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage GatherQueue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) + { + try + { + request.AddAdditionalFields(callerId, contactId); + return GetHttpResponse(request.GatherQueue()); + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage Redirect(TwilioVoiceRequest request, [FromUri]string redirectTo, [FromUri]Guid? callerId = null) + { + try + { + request.AddAdditionalFields(callerId, redirectTo: redirectTo); + return GetHttpResponse(request.Redirect()); + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + [System.Web.Http.HttpPost] + public HttpResponseMessage VoiceMail(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) + { + try + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var voipEngine = new VoipEngine(daoFactory); + request.AddAdditionalFields(callerId, contactId); + + MissCall(request, voipEngine); + + return GetHttpResponse(request.VoiceMail()); + } + } + catch (Exception e) + { + Log.Error(e); + throw; + } + } + + private VoiceResponse Inbound(TwilioVoiceRequest request, DaoFactory daoFactory) + { + SecurityContext.AuthenticateMe(CoreContext.TenantManager.GetCurrentTenant().OwnerId); + var call = SaveCall(request, VoipCallStatus.Incoming, daoFactory); + + return request.Inbound(call, daoFactory); + } + + private VoiceResponse Outbound(TwilioVoiceRequest request, DaoFactory daoFactory) + { + SaveCall(request, VoipCallStatus.Outcoming, daoFactory); + + var history = CallFromTwilioRequest(request); + history.ParentID = history.Id; + new VoipEngine(daoFactory).SaveOrUpdateCall(history); + + return request.Outbound(); + } + + private VoipCall SaveCall(TwilioVoiceRequest request, VoipCallStatus status, DaoFactory daoFactory) + { + var call = CallFromTwilioRequest(request); + call.Status = status; + return daoFactory.VoipDao.SaveOrUpdateCall(call); + } + + private void MissCall(TwilioVoiceRequest request, VoipEngine voipEngine) + { + var voipCall = CallFromTwilioRequest(request); + voipCall.Status = VoipCallStatus.Missed; + + if (!string.IsNullOrEmpty(request.RecordingSid)) + { + if (voipCall.VoipRecord == null || string.IsNullOrEmpty(voipCall.VoipRecord.Id)) + { + voipCall.VoipRecord = new VoipRecord { Id = request.RecordingSid }; + } + } + + voipCall = voipEngine.SaveOrUpdateCall(voipCall); + request.GetSignalRHelper().MissCall(request.CallSid, voipCall.AnsweredBy.ToString()); + voipEngine.SaveAdditionalInfo(voipCall.Id); + } + + private VoipCall CallFromTwilioRequest(TwilioVoiceRequest request) + { + if (!string.IsNullOrEmpty(request.DialCallSid)) + { + return new VoipCall + { + Id = request.DialCallSid, + ParentID = request.CallSid, + From = request.From, + To = request.To, + AnsweredBy = request.CallerId, + EndDialDate = DateTime.UtcNow + }; + } + + return new VoipCall + { + Id = request.CallSid, + ParentID = request.ParentCallSid, + From = request.From, + To = request.To, + AnsweredBy = request.CallerId, + Date = DateTime.UtcNow, + ContactId = request.ContactId + }; + } + + + private static HttpResponseMessage GetHttpResponse(VoiceResponse response) + { + Log.Info(response); + return new HttpResponseMessage { Content = new StringContent(response.ToString(), Encoding.UTF8, "application/xml") }; + } + } + + public class TwilioVoiceRequest : VoiceRequest + { + public Guid CallerId { get; set; } + public int ContactId { get; set; } + public string ParentCallSid { get; set; } + public string QueueResult { get; set; } + public string QueueTime { get; set; } + public string QueueSid { get; set; } + public bool Reject { get; set; } + public string RedirectTo { get; set; } + public string CurrentQueueSize { get; set; } + + public bool Pause { get { return GetSettings().Pause; } } + + private TwilioResponseHelper twilioResponseHelper; + private TwilioResponseHelper GetTwilioResponseHelper() + { + return twilioResponseHelper ?? (twilioResponseHelper = new TwilioResponseHelper(GetSettings(), CommonLinkUtility.GetFullAbsolutePath(""))); + } + + private VoipSettings settings; + private VoipSettings GetSettings() + { + using (var scope = DIHelper.Resolve()) + { + return settings ?? (settings = scope.Resolve().VoipDao.GetNumber(IsInbound ? To : From).Settings); + } + } + + private SignalRHelper signalRHelper; + public SignalRHelper GetSignalRHelper() + { + return signalRHelper ?? (signalRHelper = new SignalRHelper(IsInbound ? To : From)); + } + + public bool IsInbound + { + get { return Direction == "inbound"; } + } + + public void AddAdditionalFields(Guid? callerId, int contactId = 0, string reject = null, string redirectTo = null) + { + if (callerId.HasValue && !callerId.Value.Equals(ASC.Core.Configuration.Constants.Guest.ID)) + { + CallerId = callerId.Value; + SecurityContext.AuthenticateMe(CallerId); + } + if (contactId != 0) + { + ContactId = contactId; + } + + if (!string.IsNullOrEmpty(reject)) + { + Reject = Convert.ToBoolean(reject); + } + + if (!string.IsNullOrEmpty(redirectTo)) + { + RedirectTo = redirectTo; + } + } + + internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) + { + var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered + ? call.From + : call.To; + + Contact contact; + var contacts = new VoipEngine(daoFactory).GetContacts(contactPhone, daoFactory); + var managers = contacts.SelectMany(CRMSecurity.GetAccessSubjectGuidsTo).ToList(); + var agent = GetSignalRHelper().GetAgent(managers); + + if (agent != null && agent.Item1 != null) + { + var agentId = agent.Item1.Id; + SecurityContext.AuthenticateMe(agentId); + call.AnsweredBy = agentId; + + contact = contacts.FirstOrDefault(CRMSecurity.CanAccessTo); + + daoFactory.VoipDao.SaveOrUpdateCall(call); + } + else + { + contact = contacts.FirstOrDefault(); + } + + if (contact == null) + { + contact = new VoipEngine(daoFactory).CreateContact(call.From.TrimStart('+')); + call.ContactId = contact.ID; + daoFactory.VoipDao.SaveOrUpdateCall(call); + } + + return GetTwilioResponseHelper().Inbound(agent); + } + internal VoiceResponse Outbound() { return GetTwilioResponseHelper().Outbound(); } + internal VoiceResponse Dial() { return GetTwilioResponseHelper().Dial(); } + internal VoiceResponse Enqueue(string queueResult) { return GetTwilioResponseHelper().Enqueue(queueResult); } + internal VoiceResponse Queue() { return GetTwilioResponseHelper().Queue(); } + internal VoiceResponse Leave() { return GetTwilioResponseHelper().Leave(); } + internal VoiceResponse Dequeue() { return GetTwilioResponseHelper().Dequeue(); } + internal VoiceResponse Wait() { return GetTwilioResponseHelper().Wait(QueueSid, QueueTime, QueueTime); } + internal VoiceResponse GatherQueue() { return GetTwilioResponseHelper().GatherQueue(Digits, To.Substring(1), new List()); } + internal VoiceResponse Redirect() { return GetTwilioResponseHelper().Redirect(RedirectTo); } + internal VoiceResponse VoiceMail() { return GetTwilioResponseHelper().VoiceMail(); } + } + + public class ValidateRequestAttribute : ActionFilterAttribute + { + public override void OnActionExecuting(ActionExecutingContext filterContext) + { + if (!new RequestValidationHelper().IsValidRequest(filterContext.HttpContext, ConsumerFactory.Get()["twilioAuthToken"], HttpContext.Current.Request.GetUrlRewriter().AbsoluteUri)) + filterContext.Result = new Twilio.AspNet.Mvc.HttpStatusCodeResult(HttpStatusCode.Forbidden); + base.OnActionExecuting(filterContext); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/UrlConstant.cs b/products/ASC.CRM/Server/Classes/UrlConstant.cs new file mode 100644 index 00000000000..60091339d3b --- /dev/null +++ b/products/ASC.CRM/Server/Classes/UrlConstant.cs @@ -0,0 +1,51 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; + +namespace ASC.CRM.Classes +{ + public static class UrlConstant + { + public const String Filter = "filter"; + public const String Tag = "tag"; + public const String Status = "status"; + public const String ID = "id"; + public const String Action = "action"; + public const String PageNumber = "page"; + public const String Version = "version"; + public const String Search = "searchbytext"; + public const String ReportType = "reportType"; + public const String UserID = "userID"; + public const String View = "view"; + public const String ContactID = "contactID"; + public const String Type = "type"; + public const String FullName = "fullname"; + public const String Email = "email"; + public const String LinkMessageId = "linkMessageId"; + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs new file mode 100644 index 00000000000..467a79bd7e5 --- /dev/null +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -0,0 +1,296 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.Common.Logging; +using ASC.Common.Threading.Workers; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.VoipService; +using ASC.VoipService.Dao; +using ASC.Web.CRM.Core; +using ASC.Web.CRM.Core.Enums; +using ASC.Web.CRM.Resources; +using Autofac; + +namespace ASC.Web.CRM.Classes +{ + public class VoipEngine + { + private static readonly WorkerQueue Queue = new WorkerQueue(1, TimeSpan.FromMinutes(30)); + private static readonly object Locker = new object(); + private readonly DaoFactory daoFactory; + + public VoipEngine(DaoFactory daoFactory) + { + this.daoFactory = daoFactory; + } + public VoipCall SaveOrUpdateCall(VoipCall callHistory) + { + var dao = daoFactory.VoipDao; + var call = dao.GetCall(callHistory.Id) ?? callHistory; + + if (string.IsNullOrEmpty(call.ParentID)) + { + GetContact(call); + } + + if (!callHistory.AnsweredBy.Equals(Guid.Empty)) + { + call.AnsweredBy = callHistory.AnsweredBy; + } + + if (!callHistory.Date.Equals(default(DateTime))) + { + call.Date = callHistory.Date; + } + + if (!callHistory.EndDialDate.Equals(default(DateTime))) + { + call.EndDialDate = callHistory.EndDialDate; + } + + if (call.Price == 0 && callHistory.Price != default(decimal)) + { + call.Price = callHistory.Price; + } + + if (call.DialDuration == 0) + { + call.DialDuration = callHistory.DialDuration; + } + + if (call.VoipRecord == null) + { + call.VoipRecord = new VoipRecord(); + } + + if (string.IsNullOrEmpty(call.VoipRecord.Id)) + { + call.VoipRecord.Id = callHistory.VoipRecord.Id; + } + + if (call.VoipRecord.Price == default(decimal)) + { + call.VoipRecord.Price = callHistory.VoipRecord.Price; + } + + if (string.IsNullOrEmpty(call.VoipRecord.Uri)) + { + call.VoipRecord.Uri = callHistory.VoipRecord.Uri; + } + + if (call.VoipRecord.Duration == 0) + { + call.VoipRecord.Duration = callHistory.VoipRecord.Duration; + } + + if (callHistory.Status.HasValue) + { + call.Status = callHistory.Status; + } + + return dao.SaveOrUpdateCall(call); + } + + public static void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) + { + var listItemDao = daoFactory.ListItemDao; + + if (call == null || call.ContactId == 0) return; + + var category = listItemDao.GetByTitle(ListType.HistoryCategory, CRMCommonResource.HistoryCategory_Call); + if (category == null) + { + category = new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png"); + category.ID = listItemDao.CreateItem(ListType.HistoryCategory, category); + } + var contact = daoFactory.ContactDao.GetByID(call.ContactId); + if (contact != null && CRMSecurity.CanAccessTo(contact)) + { + var note = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered + ? CRMContactResource.HistoryVoipIncomingNote + : CRMContactResource.HistoryVoipOutcomingNote; + var content = string.Format(note, call.DialDuration); + + var relationshipEvent = new RelationshipEvent + { + CategoryID = category.ID, + EntityType = EntityType.Any, + EntityID = 0, + Content = content, + ContactID = contact.ID, + CreateOn = TenantUtil.DateTimeFromUtc(DateTime.UtcNow), + CreateBy = SecurityContext.CurrentAccount.ID + }; + + daoFactory.RelationshipEventDao.CreateItem(relationshipEvent); + } + } + + public Contact GetContact(VoipCall call) + { + if (call.ContactId != 0) + { + return null; + } + + var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; + + var newContactIds = daoFactory.ContactDao.GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); + + foreach (var newContactId in newContactIds) + { + if (newContactId != 0) + { + var existContact = daoFactory.ContactDao.GetByID(newContactId); + if (CRMSecurity.CanAccessTo(existContact)) + { + call.ContactId = newContactId; + return existContact; + } + } + } + + return null; + } + + public List GetContacts(string contactPhone, DaoFactory daoFactory) + { + var dao = daoFactory.ContactDao; + var ids = dao.GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); + return ids.Select(r => dao.GetByID(r)).ToList(); + } + + public void SaveAdditionalInfo(string callId) + { + lock (Locker) + { + if (!Queue.IsStarted) + { + Queue.Start(SaveAdditionalInfoAction); + } + + Queue.Add(new QueueItem {CallID = callId, TenantID = CoreContext.TenantManager.GetCurrentTenant().TenantId}); + } + } + + private static void SaveAdditionalInfoAction(QueueItem queueItem) + { + try + { + CoreContext.TenantManager.SetCurrentTenant(queueItem.TenantID); + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var voipEngine = new VoipEngine(daoFactory); + var dao = daoFactory.VoipDao; + + var call = dao.GetCall(queueItem.CallID); + + GetPriceAndDuration(call); + + if (call.ChildCalls.Any()) + { + call.ChildCalls.ForEach(r => + { + GetPriceAndDuration(r); + voipEngine.SaveOrUpdateCall(r); + }); + } + + call = voipEngine.SaveOrUpdateCall(call); + + if (!string.IsNullOrEmpty(call.VoipRecord.Id)) + { + call.VoipRecord = VoipDao.GetProvider().GetRecord(call.Id, call.VoipRecord.Id); + voipEngine.SaveOrUpdateCall(call); + } + + SecurityContext.AuthenticateMe(call.AnsweredBy); + AddHistoryToCallContact(call, daoFactory); + } + } + catch (Exception ex) + { + LogManager.GetLogger("ASC").ErrorFormat("SaveAdditionalInfo {0}, {1}", ex, ex.StackTrace); + } + } + + private static void GetPriceAndDuration(VoipCall call) + { + var provider = VoipDao.GetProvider(); + var twilioCall = provider.GetCall(call.Id); + call.Price = twilioCall.Price; + call.DialDuration = twilioCall.DialDuration; + } + + public void AnswerCall(VoipCall call) + { + call.AnsweredBy = SecurityContext.CurrentAccount.ID; + call.Status = VoipCallStatus.Answered; + daoFactory.VoipDao.SaveOrUpdateCall(call); + } + + public Contact CreateContact(string contactPhone) + { + var contact = new Person + { + FirstName = contactPhone, + LastName = TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), + ShareType = ShareType.None, + CreateBy = SecurityContext.CurrentAccount.ID, + CreateOn = DateTime.UtcNow + }; + + contact.ID = daoFactory.ContactDao.SaveContact(contact); + + daoFactory.ContactInfoDao + .Save(new ContactInfo + { + ContactID = contact.ID, + IsPrimary = true, + InfoType = ContactInfoType.Phone, + Data = contactPhone + }); + + CRMSecurity.SetAccessTo(contact, new List {SecurityContext.CurrentAccount.ID}); + + return contact; + } + + private class QueueItem + { + public int TenantID { get; set; } + public string CallID { get; set; } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs new file mode 100644 index 00000000000..8925f5a093d --- /dev/null +++ b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs @@ -0,0 +1,63 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Web; +using ASC.CRM.Resources; +using ASC.Web.Core; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Web.CRM.Configuration +{ + public class CRMSpaceUsageStatManager : SpaceUsageStatManager + { + public override List GetStatData() + { + using (var filedb = new DbManager(FileConstant.DatabaseId)) + { + var q = new SqlQuery("files_file f") + .Select("b.right_node") + .SelectSum("f.content_length") + .InnerJoin("files_folder_tree t", Exp.EqColumns("f.folder_id", "t.folder_id")) + .InnerJoin("files_bunch_objects b", Exp.EqColumns("t.parent_id", "b.left_node")) + .Where("b.tenant_id", TenantProvider.CurrentTenantID) + .Where(Exp.Like("b.right_node", "crm/crm_common/", SqlLike.StartWith)) + .GroupBy(1); + + return filedb.ExecuteList(q) + .Select(r => new UsageSpaceStatItem + { + + Name = CRMCommonResource.WholeCRMModule, + SpaceUsage = Convert.ToInt64(r[1]), + Url = VirtualPathUtility.ToAbsolute(PathProvider.StartURL()) + }) + .ToList(); + } + } + } +} diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs new file mode 100644 index 00000000000..17f9a8871a1 --- /dev/null +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -0,0 +1,331 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Configuration; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.Core; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Core; +using ASC.Web.CRM.Services.NotifyService; +using Autofac; +using System; +using System.Linq; + + +namespace ASC.Web.CRM.Configuration +{ + public class ProductEntryPoint : Product + { + public ProductEntryPoint(SecurityContext securityContext, + UserManager userManager, + PathProvider pathProvider, + DaoFactory daoFactory) + { + SecurityContext = securityContext; + UserManager = userManager; + PathProvider = pathProvider; + DaoFactory = daoFactory; + } + + #region Property + + + #endregion + + public static readonly Guid ID = WebItemManager.CRMProductID; + private ProductContext context; + + private static readonly object Locker = new object(); + private static bool registered; + + public DaoFactory DaoFactory { get; } + + public PathProvider PathProvider { get; } + public SecurityContext SecurityContext { get; } + public UserManager UserManager { get; } + + // TODO: CRM: Реализовать проперти ApiURL + public override string ApiURL => throw new NotImplementedException(); + + public override Guid ProductID { get { return ID; } } + + public override string Name { get { return CRMCommonResource.ProductName; } } + + public override string Description + { + get + { + var id = SecurityContext.CurrentAccount.ID; + + if (UserManager.IsUserInGroup(id, ASC.Core.Users.Constants.GroupAdmin.ID) || UserManager.IsUserInGroup(id, ID)) + return CRMCommonResource.ProductDescriptionEx; + + return CRMCommonResource.ProductDescription; + } + } + + public override string StartURL { get { return PathProvider.StartURL(); } } + + public override string HelpURL { get { return string.Concat(PathProvider.BaseVirtualPath, "help.aspx"); } } + + public override string ProductClassName { get { return "crm"; } } + + public override bool Visible { get { return true; } } + + public override ProductContext Context { get { return context; } } + + public string ModuleSysName { get; set; } + + + public override void Init() + { + context = new ProductContext + { + DisabledIconFileName = "product_disabled_logo.png", + IconFileName = "product_logo.png", + LargeIconFileName = "product_logolarge.svg", + DefaultSortOrder = 30, + SubscriptionManager = new ProductSubscriptionManager(), + SpaceUsageStatManager = new CRMSpaceUsageStatManager(), + AdminOpportunities = () => CRMCommonResource.ProductAdminOpportunities.Split('|').ToList(), + UserOpportunities = () => CRMCommonResource.ProductUserOpportunities.Split('|').ToList(), + }; + + if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) + { + FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider()); + } + if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "opportunity")) + { + FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", new FileSecurityProvider()); + } + + SearchHandlerManager.Registry(new SearchHandler()); + + GlobalConfiguration.Configuration.Routes.MapHttpRoute( + name: "Twilio", + routeTemplate: "twilio/{action}", + defaults: new {controller = "Twilio", action = "index" }); + +// ClientScriptLocalization = new ClientLocalizationResources(); + DIHelper.Register(); + } + + + public static void ConfigurePortal() + { + if (!Global.TenantSettings.IsConfiguredPortal) + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + // Task Category + var listItemDao = daoFactory.ListItemDao; + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Call, "task_category_call.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Deal, "task_category_deal.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Demo, "task_category_demo.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Email, "task_category_email.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Fax, "task_category_fax.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_FollowUP, "task_category_follow_up.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Lunch, "task_category_lunch.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Meeting, "task_category_meeting.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Note, "task_category_note.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Ship, "task_category_ship.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_SocialNetworks, "task_category_social_networks.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_ThankYou, "task_category_thank_you.png")); + + // Deal Milestone New + var milestoneDao = daoFactory.DealMilestoneDao; + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_InitialContact_Title, + Description = CRMDealResource.DealMilestone_InitialContact_Description, + Probability = 1, + Color = "#e795c1", + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Preapproach_Title, + Description = CRMDealResource.DealMilestone_Preapproach_Description, + Probability = 2, + Color = "#df7895", + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Suspect_Title, + Description = CRMDealResource.DealMilestone_Suspect_Description, + Probability = 3, + Color = "#f48454", + SortOrder = 1, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Champion_Title, + Description = CRMDealResource.DealMilestone_Champion_Description, + Probability = 20, + Color = "#b58fd6", + SortOrder = 2, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Opportunity_Title, + Description = CRMDealResource.DealMilestone_Opportunity_Description, + Probability = 50, + Color = "#d28cc8", + SortOrder = 3, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Prospect_Title, + Description = CRMDealResource.DealMilestone_Prospect_Description, + Probability = 75, + Color = "#ffb45e", + SortOrder = 4, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Verbal_Title, + Description = CRMDealResource.DealMilestone_Verbal_Description, + Probability = 90, + Color = "#ffd267", + SortOrder = 5, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Won_Title, + Description = CRMDealResource.DealMilestone_Won_Description, + Probability = 100, + Color = "#6bbd72", + SortOrder = 6, + Status = DealMilestoneStatus.ClosedAndWon + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Lost_Title, + Description = CRMDealResource.DealMilestone_Lost_Description, + Probability = 0, + Color = "#f2a9be", + SortOrder = 7, + Status = DealMilestoneStatus.ClosedAndLost + }); + + // Contact Status + listItemDao.CreateItem(ListType.ContactStatus, new ListItem {Title = CRMContactResource.ContactStatus_Cold, Color = "#8a98d8", SortOrder = 1}); + listItemDao.CreateItem(ListType.ContactStatus, new ListItem {Title = CRMContactResource.ContactStatus_Warm, Color = "#ffd267", SortOrder = 2}); + listItemDao.CreateItem(ListType.ContactStatus, new ListItem {Title = CRMContactResource.ContactStatus_Hot, Color = "#df7895", SortOrder = 3}); + // Contact Type + listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Client, SortOrder = 1}); + listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Supplier, SortOrder = 2}); + listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Partner, SortOrder = 3}); + listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Competitor, SortOrder = 4}); + + // History Category + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Note, "event_category_note.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Email, "event_category_email.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Meeting, "event_category_meeting.png")); + // Tags + daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Lead, true); + daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Customer, true); + daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Supplier, true); + daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Staff, true); + + var tenantSettings = Global.TenantSettings; + tenantSettings.WebFormKey = Guid.NewGuid(); + tenantSettings.IsConfiguredPortal = true; + tenantSettings.Save(); + } + } + + if (!Global.TenantSettings.IsConfiguredSmtp) + { + var smtp = CRMSettings.Load().SMTPServerSettingOld; + if (smtp != null && CoreContext.Configuration.SmtpSettings.IsDefaultSettings) + { + try + { + var newSettings = new SmtpSettings(smtp.Host, smtp.Port, smtp.SenderEmailAddress, + smtp.SenderDisplayName) + { + EnableSSL = smtp.EnableSSL, + EnableAuth = smtp.RequiredHostAuthentication, + }; + + if (!string.IsNullOrEmpty(smtp.HostLogin) && !string.IsNullOrEmpty(smtp.HostPassword)) + { + newSettings.SetCredentials(smtp.HostLogin, smtp.HostPassword); + } + + CoreContext.Configuration.SmtpSettings = newSettings; + } + catch (Exception e) + { + LogManager.GetLogger("ASC").Error("ConfigurePortal", e); + } + } + var tenantSettings = Global.TenantSettings; + tenantSettings.IsConfiguredSmtp = true; + tenantSettings.Save(); + } + } + + public override void Shutdown() + { + if (registered) + { + NotifyClient.Instance.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask); + + } + } + + public static void RegisterSendMethods() + { + lock (Locker) + { + if (!registered) + { + registered = true; + + NotifyClient.Instance.Client.RegisterSendMethod(NotifyClient.SendAutoReminderAboutTask, "0 * * ? * *"); + + } + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Configuration/SearchHandler.cs b/products/ASC.CRM/Server/Configuration/SearchHandler.cs new file mode 100644 index 00000000000..7f154d780a6 --- /dev/null +++ b/products/ASC.CRM/Server/Configuration/SearchHandler.cs @@ -0,0 +1,70 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Web.Core.ModuleManagement.Common; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM.Core; +using Autofac; +using System; + +namespace ASC.Web.CRM.Configuration +{ + public class SearchHandler : BaseSearchHandlerEx + { + public override Guid ProductID + { + get { return ProductEntryPoint.ID; } + } + + public override Guid ModuleID + { + get { return ProductID; } + } + + public override ImageOptions Logo + { + get { return new ImageOptions { ImageFileName = "search_in_module.png", PartID = ProductID }; } + } + + public override string SearchName + { + get { return CRMContactResource.Search; } + } + + public override IItemControl Control + { + get { return new ResultsView(); } + } + + public override SearchResultItem[] Search(string searchText) + { + using (var scope = DIHelper.Resolve()) + { + return scope.Resolve().SearchDao.Search(searchText); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Configuration/VoipModule.cs b/products/ASC.CRM/Server/Configuration/VoipModule.cs new file mode 100644 index 00000000000..69c84f8b614 --- /dev/null +++ b/products/ASC.CRM/Server/Configuration/VoipModule.cs @@ -0,0 +1,118 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Data.Storage; +using ASC.Web.Core; +using ASC.Web.Core.WebZones; +using ASC.Web.Studio.Core; +using System; + +namespace ASC.Web.CRM.Configuration +{ + [WebZone(WebZoneType.CustomProductList)] + public class VoipModule : IAddon, IRenderCustomNavigation + { + public Guid ID + { + get { return WebItemManager.VoipModuleID; } + } + + public string Name + { + get { return CRMVoipResource.VoipModuleTitle; } + } + + public string Description + { + get { return CRMVoipResource.VoipModuleDescription; } + } + + public string StartURL + { + get { return PathProvider.StartURL() + "settings.aspx?type=voip.common&sysname=/modules/voip"; } + } + + public string HelpURL + { + get { return null; } + } + + public string ProductClassName { get { return "voip"; } } + + public bool Visible { get { return SetupInfo.VoipEnabled == "true"; } } + + public AddonContext Context { get; private set; } + + public void Init() + { + Context = new AddonContext + { + DefaultSortOrder = 90, + IconFileName = "voip_logo.png", + CanNotBeDisabled = true + }; + } + + public void Shutdown() + { + + } + + WebItemContext IWebItem.Context + { + get { return Context; } + } + + public Control LoadCustomNavigationControl(Page page) + { + return null; + } + + public string RenderCustomNavigation(Page page) + { + try + { + if (!VoipNumberData.CanMakeOrReceiveCall) return string.Empty; + } + catch (Exception) + { + return string.Empty; + } + page.RegisterBodyScripts("~/js/asc/core/voip.navigationitem.js"); + + return + string.Format(@"
  • + + + {2} + +
  • ", + "VoIP", + WebPath.GetPath("/"), + 0); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/CRMConstants.cs b/products/ASC.CRM/Server/Core/CRMConstants.cs new file mode 100644 index 00000000000..08c076f7ea4 --- /dev/null +++ b/products/ASC.CRM/Server/Core/CRMConstants.cs @@ -0,0 +1,37 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; + +namespace ASC.CRM.Core +{ + public static class CRMConstants + { + public static readonly String StorageModule = "crm"; + public static readonly String DatabaseId = "crm"; + public static readonly String FileKeyFormat = "{0}/{1}/{2}/{3}"; // ProjectID/FileID/FileVersion/FileTitle + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/DIHelper.cs b/products/ASC.CRM/Server/Core/DIHelper.cs new file mode 100644 index 00000000000..2fb79db1ed6 --- /dev/null +++ b/products/ASC.CRM/Server/Core/DIHelper.cs @@ -0,0 +1,75 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core.Dao; +using Autofac; + +namespace ASC.Web.CRM.Core +{ + public static class DIHelper + { + internal static IContainer Builder; + private static bool isRegistered; + private static readonly object Locker = new object(); + + public static void Register() + { + if (isRegistered) return; + + lock (Locker) + { + if (isRegistered) return; + + var container = AutofacConfigLoader.Load("crm"); + + container.Register(c => DbManager.FromHttpContext("default")) + .AsSelf() + .As() + .InstancePerRequest(); + + Builder = container.Build(); + isRegistered = true; + } + } + + public static ILifetimeScope Resolve() + { + return Resolve(TenantProvider.CurrentTenantID); + } + + + public static ILifetimeScope Resolve(int tenantID) + { + Register(); + + var scope = Builder.BeginLifetimeScope(Autofac.Core.Lifetime.MatchingScopeLifetimeTags.RequestLifetimeScopeTag); + scope.Resolve(); + scope.Resolve(new TypedParameter(typeof(int), tenantID)); + + return scope; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs new file mode 100644 index 00000000000..812b11763db --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -0,0 +1,316 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Enums; +using Microsoft.EntityFrameworkCore; + +namespace ASC.CRM.Core.Dao +{ + public class AbstractDao + { + protected readonly List _supportedEntityType = new List(); + protected readonly ILog _log = LogManager.GetLogger("ASC.CRM"); + + public CRMDbContext CRMDbContext { get; } + public SecurityContext SecurityContext { get; } + + protected readonly ICache _cache; + + public AbstractDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext + ) + { + _cache = AscCache.Memory; + CRMDbContext = dbContextManager.Get(CRMConstants.DatabaseId); + TenantID = tenantManager.GetCurrentTenant().TenantId; + SecurityContext = securityContext; + } + + /* + protected readonly String _invoiceItemCacheKey; + protected readonly String _invoiceTaxCacheKey; + protected readonly String _invoiceLineCacheKey; + */ + protected AbstractDao(int tenantID) + { + TenantID = tenantID; + + _supportedEntityType.Add(EntityType.Company); + _supportedEntityType.Add(EntityType.Person); + _supportedEntityType.Add(EntityType.Contact); + _supportedEntityType.Add(EntityType.Opportunity); + _supportedEntityType.Add(EntityType.Case); + + /* + _invoiceItemCacheKey = String.Concat(TenantID, "/invoiceitem"); + _invoiceTaxCacheKey = String.Concat(TenantID, "/invoicetax"); + _invoiceLineCacheKey = String.Concat(TenantID, "/invoiceline"); + + if (_cache.Get(_invoiceItemCacheKey) == null) + { + _cache.Insert(_invoiceItemCacheKey, String.Empty); + } + if (_cache.Get(_invoiceTaxCacheKey) == null) + { + _cache.Insert(_invoiceTaxCacheKey, String.Empty); + } + if (_cache.Get(_invoiceLineCacheKey) == null) + { + _cache.Insert(_invoiceLineCacheKey, String.Empty); + } + */ + } + + protected int TenantID { get; private set; } + + protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumerable tags) + { + if (tags == null || !tags.Any()) + throw new ArgumentException(); + + var tagIDs = new List(); + + foreach (var tag in tags) { + tagIDs.Add(CRMDbContext + .CrmTag + .Where(x => x.EntityType == (int)entityType && String.Compare(x.Title, tag.Trim(), true) == 0) + .Select(x => x.Id).Single()); + } + + Expression> exp = null; + + if (exceptIDs != null && exceptIDs.Length > 0) + exp = x => exceptIDs.Contains(x.EntityId) && x.EntityType == (int)entityType; + else + exp = x => x.EntityType == (int)entityType; + + + throw new NotImplementedException(); + + // exp.Update() Exp.In("tag_id", tagIDs) + // return CRMDbContext.CrmEntityTag.Where(exp).GroupBy(x => x.EntityId).Select(x=>) + // .Where(x => true).Select(x=>x); + + //var sqlQuery = new SqlQuery("crm_entity_tag") + // .Select("entity_id") + // .Select("count(*) as count") + // .GroupBy("entity_id") + // .Having(Exp.Eq("count", tags.Count())); + + //if (exceptIDs != null && exceptIDs.Length > 0) + // sqlQuery.Where(Exp.In("entity_id", exceptIDs) & Exp.Eq("entity_type", (int)entityType)); + //else + // sqlQuery.Where(Exp.Eq("entity_type", (int)entityType)); + + //sqlQuery.Where(Exp.In("tag_id", tagIDs)); + + //return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToInt32(row[0])); + } + + protected Dictionary GetRelativeToEntity(int[] contactID, EntityType entityType, int[] entityID) + { + Expression> exp = null; + + if (contactID != null && contactID.Length > 0 && (entityID == null || entityID.Length == 0)) + exp = x => x.EntityType == (int)entityType && contactID.Contains(x.ContactId); + else if (entityID != null && entityID.Length > 0 && (contactID == null || contactID.Length == 0)) + exp = x => x.EntityType == (int)entityType && entityID.Contains(x.EntityId); + + return CRMDbContext.CrmEntityContact.Where(exp).GroupBy(x => x.EntityId).ToDictionary( + x => x.Key, + x => x.Select(x => Convert.ToInt32(x.ContactId)).ToArray()); + } + + protected int[] GetRelativeToEntity(int? contactID, EntityType entityType, int? entityID) + { + return GetRelativeToEntityInDb(contactID, entityType, entityID); + } + + protected int[] GetRelativeToEntityInDb(int? contactID, EntityType entityType, int? entityID) + { + if (contactID.HasValue && !entityID.HasValue) + return CRMDbContext.CrmEntityContact + .Where(x => x.EntityType == (int)entityType && x.ContactId == contactID.Value) + .Select(x => x.EntityId) + .ToArray(); + + if (!contactID.HasValue && entityID.HasValue) + return CRMDbContext.CrmEntityContact + .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID.Value) + .Select(x => x.ContactId) + .ToArray(); + + throw new ArgumentException(); + } + + protected void SetRelative(int[] contactID, EntityType entityType, int entityID) + { + if (entityID == 0) + throw new ArgumentException(); + + using var tx = CRMDbContext.Database.BeginTransaction(); + + var exists = CRMDbContext.CrmEntityContact + .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID) + .Select(x => x.ContactId) + .ToArray(); + + foreach (var existContact in exists) + { + var items = CRMDbContext.CrmEntityContact + .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID && x.ContactId == existContact); + + CRMDbContext.CrmEntityContact.RemoveRange(items); + } + + if (!(contactID == null || contactID.Length == 0)) + foreach (var id in contactID) + SetRelative(id, entityType, entityID); + + tx.Commit(); + } + + protected void SetRelative(int contactID, EntityType entityType, int entityID) + { + CRMDbContext.CrmEntityContact.Add(new CrmEntityContact + { + ContactId = contactID, + EntityType = (int)entityType, + EntityId = entityID + }); + + CRMDbContext.SaveChanges(); + } + + protected void RemoveRelativeInDb(int[] contactID, EntityType entityType, int[] entityID) + { + if ((contactID == null || contactID.Length == 0) && (entityID == null || entityID.Length == 0)) + throw new ArgumentException(); + + Expression> expr = null; + + if (contactID != null && contactID.Length > 0) + expr = x => contactID.Contains(x.ContactId); + + if (entityID != null && entityID.Length > 0) + expr = x => entityID.Contains(x.EntityId) && x.EntityType == (int)entityType; + + var dbCrmEntity = CRMDbContext.CrmEntityContact; + + dbCrmEntity.RemoveRange(dbCrmEntity.Where(expr)); + + CRMDbContext.SaveChanges(); + } + + protected void RemoveRelative(int contactID, EntityType entityType, int entityID) + { + int[] contactIDs = null; + int[] entityIDs = null; + + + if (contactID > 0) + contactIDs = new[] { contactID }; + + if (entityID > 0) + entityIDs = new[] { entityID }; + + + RemoveRelativeInDb(contactIDs, entityType, entityIDs); + } + + + public int SaveOrganisationLogo(byte[] bytes) + { + var entity = new CrmOrganisationLogo + { + Content = Convert.ToBase64String(bytes), + CreateOn = DateTime.UtcNow, + CreateBy = SecurityContext.CurrentAccount.ID.ToString() + }; + + CRMDbContext.CrmOrganisationLogo.Add(entity); + + CRMDbContext.SaveChanges(); + + return entity.Id; + } + + public string GetOrganisationLogoBase64(int logo_id) + { + + if (logo_id <= 0) throw new ArgumentException(); + + + return CRMDbContext.CrmOrganisationLogo + .Where(x => x.Id == logo_id) + .Select(x => x.Content) + .FirstOrDefault(); + } + + + #region HasCRMActivity + + public bool HasActivity() + { + return Db.ExecuteScalar(@"select exists(select 1 from crm_case where tenant_id = @tid) or " + + "exists(select 1 from crm_deal where tenant_id = @tid) or exists(select 1 from crm_task where tenant_id = @tid) or " + + "exists(select 1 from crm_contact where tenant_id = @tid)", new { tid = TenantID }); + } + + #endregion + + protected IQueryable Query(DbSet set) where T : class, IDbCrm + { + return set.Where(r => r.TenantId == TenantID); + } + + protected string GetTenantColumnName(string table) + { + var tenant = "tenant_id"; + if (!table.Contains(" ")) return tenant; + return table.Substring(table.IndexOf(" ")).Trim() + "." + tenant; + } + + + protected static Guid ToGuid(object guid) + { + var str = guid as string; + return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty; + } + + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs new file mode 100644 index 00000000000..1656604a113 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -0,0 +1,602 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Collections; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.CRM.Core.Search; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; +using OrderBy = ASC.CRM.Core.Entities.OrderBy; + +namespace ASC.CRM.Core.Dao +{ + public class CachedCasesDao : CasesDao + { + private readonly HttpRequestDictionary _casesCache = new HttpRequestDictionary("crm_cases"); + + public CachedCasesDao(int tenantID) + : base(tenantID) + { + } + + public override Cases GetByID(int caseID) + { + return _casesCache.Get(caseID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(caseID)); + } + + private Cases GetByIDBase(int caseID) + { + return base.GetByID(caseID); + } + + public override void UpdateCases(Cases cases) + { + if (cases != null && cases.ID > 0) + ResetCache(cases.ID); + + base.UpdateCases(cases); + } + + public override Cases DeleteCases(int casesID) + { + ResetCache(casesID); + + return base.DeleteCases(casesID); + } + + private void ResetCache(int taskID) + { + _casesCache.Reset(taskID.ToString(CultureInfo.InvariantCulture)); + } + } + + public class CasesDao : AbstractDao + { + public CasesDao(int tenantID) + : base(tenantID) + { + + } + + #region Property + + public CRMSecurity CRMSecurity { get; } + + #endregion + + public CasesDao(CRMSecurity cRMSecurity) + { + CRMSecurity = cRMSecurity; + } + + public void AddMember(int caseID, int memberID) + { + SetRelative(memberID, EntityType.Case, caseID); + } + + public Dictionary GetMembers(int[] caseID) + { + return GetRelativeToEntity(null, EntityType.Case, caseID); + } + + public int[] GetMembers(int caseID) + { + return GetRelativeToEntity(null, EntityType.Case, caseID); + } + + public void SetMembers(int caseID, int[] memberID) + { + SetRelative(memberID, EntityType.Case, caseID); + } + + public void RemoveMember(int caseID, int memberID) + { + RemoveRelative(memberID, EntityType.Case, caseID); + } + + public virtual int[] SaveCasesList(List items) + { + using (var tx = Db.BeginTransaction()) + { + var result = items.Select(item => CreateCasesInDb(item.Title)).ToArray(); + tx.Commit(); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "cases.*")); + return result; + } + } + + + public Cases CloseCases(int caseID) + { + if (caseID <= 0) throw new ArgumentException(); + + var cases = GetByID(caseID); + + if (cases == null) return null; + + CRMSecurity.DemandAccessTo(cases); + + Db.ExecuteNonQuery( + Update("crm_case") + .Set("is_closed", true) + .Where("id", caseID) + ); + cases.IsClosed = true; + return cases; + } + + public Cases ReOpenCases(int caseID) + { + if (caseID <= 0) throw new ArgumentException(); + + var cases = GetByID(caseID); + + if (cases == null) return null; + + CRMSecurity.DemandAccessTo(cases); + + Db.ExecuteNonQuery( + Update("crm_case") + .Set("is_closed", false) + .Where("id", caseID) + ); + cases.IsClosed = false; + return cases; + } + + public int CreateCases(String title) + { + var result = CreateCasesInDb(title); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + return result; + } + + private int CreateCasesInDb(String title) + { + return Db.ExecuteScalar( + Insert("crm_case") + .InColumnValue("id", 0) + .InColumnValue("title", title) + .InColumnValue("is_closed", false) + .InColumnValue("create_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + } + + public virtual void UpdateCases(Cases cases) + { + CRMSecurity.DemandEdit(cases); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + Db.ExecuteNonQuery( + Update("crm_case") + .Set("title", cases.Title) + .Set("is_closed", cases.IsClosed) + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Where("id", cases.ID) + ); + } + + public virtual Cases DeleteCases(int casesID) + { + if (casesID <= 0) return null; + + var cases = GetByID(casesID); + if (cases == null) return null; + + CRMSecurity.DemandDelete(cases); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + DeleteBatchCases(new[] { casesID }); + return cases; + } + + public virtual List DeleteBatchCases(List caseses) + { + caseses = caseses.FindAll(CRMSecurity.CanDelete).ToList(); + if (!caseses.Any()) return caseses; + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + DeleteBatchCasesExecute(caseses); + + return caseses; + } + + public virtual List DeleteBatchCases(int[] casesID) + { + if (casesID == null || !casesID.Any()) return null; + + var cases = GetCases(casesID).FindAll(CRMSecurity.CanDelete).ToList(); + if (!cases.Any()) return cases; + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + DeleteBatchCasesExecute(cases); + + return cases; + } + + private void DeleteBatchCasesExecute(List caseses) + { + var casesID = caseses.Select(x => x.ID).ToArray(); + + using (var tagdao = FilesIntegration.GetTagDao()) + { + var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id") + .Where(Exp.Eq("have_files", true) & Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))) + .Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); + var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + + using (var tx = Db.BeginTransaction(true)) + { + Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(Delete("crm_case").Where(Exp.In("id", casesID))); + + tx.Commit(); + } + + caseses.ForEach(item => CoreContext.AuthorizationManager.RemoveAllAces(item)); + + if (0 < tagNames.Length) + { + using (var filedao = FilesIntegration.GetFileDao()) + { + foreach (var filesID in filesIDs) + { + filedao.DeleteFile(filesID); + } + } + } + } + //todo: remove indexes + } + + public List GetAllCases() + { + return GetCases(String.Empty, 0, null, null, 0, 0, new OrderBy(SortedByType.Title, true)); + } + + public int GetCasesCount() + { + return GetCasesCount(String.Empty, 0, null, null); + } + + public int GetCasesCount( + String searchText, + int contactID, + bool? isClosed, + IEnumerable tags) + { + + var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + + "cases" + + SecurityContext.CurrentAccount.ID.ToString() + + searchText + + contactID; + + if (tags != null) + cacheKey += String.Join("", tags.ToArray()); + + if (isClosed.HasValue) + cacheKey += isClosed.Value; + + var fromCache = _cache.Get(cacheKey); + + if (fromCache != null) return Convert.ToInt32(fromCache); + + + var withParams = !(String.IsNullOrEmpty(searchText) && + contactID <= 0 && + isClosed == null && + (tags == null || !tags.Any())); + + + var exceptIDs = CRMSecurity.GetPrivateItems(typeof(Cases)).ToList(); + + int result; + + if (withParams) + { + var whereConditional = WhereConditional(exceptIDs, searchText, contactID, isClosed, tags); + result = whereConditional != null ? Db.ExecuteScalar(Query("crm_case").Where(whereConditional).SelectCount()) : 0; + } + else + { + var countWithoutPrivate = Db.ExecuteScalar(Query("crm_case").SelectCount()); + var privateCount = exceptIDs.Count; + + if (privateCount > countWithoutPrivate) + { + _log.ErrorFormat(@"Private cases count more than all cases. Tenant: {0}. CurrentAccount: {1}", + TenantID, + SecurityContext.CurrentAccount.ID); + + privateCount = 0; + } + + result = countWithoutPrivate - privateCount; + + } + + if (result > 0) + { + _cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30)); + } + return result; + } + + + private Exp WhereConditional( + ICollection exceptIDs, + String searchText, + int contactID, + bool? isClosed, + IEnumerable tags) + { + + var conditions = new List(); + + var ids = new List(); + + if (!String.IsNullOrEmpty(searchText)) + { + searchText = searchText.Trim(); + + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + .ToArray(); + + if (keywords.Length > 0) + { + if (!BundleSearch.TrySelectCase(searchText, out ids)) + { + conditions.Add(BuildLike(new[] {"title"}, keywords)); + } + else if(!ids.Any()) + { + return null; + + } + } + } + + if (contactID > 0) + { + + var sqlQuery = new SqlQuery("crm_entity_contact") + .Select("entity_id") + .Where(Exp.Eq("contact_id", contactID) & Exp.Eq("entity_type", (int)EntityType.Case)); + + if (ids.Count > 0) + sqlQuery.Where(Exp.In("entity_id", ids)); + + ids = Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList(); + if (ids.Count == 0) return null; + } + + if (isClosed.HasValue) + conditions.Add(Exp.Eq("is_closed", isClosed)); + + if (tags != null && tags.Any()) + { + ids = SearchByTags(EntityType.Case, ids.ToArray(), tags); + + if (ids.Count == 0) return null; + } + + if (ids.Count > 0) + { + if (exceptIDs.Count > 0) + { + ids = ids.Except(exceptIDs).ToList(); + + if (ids.Count == 0) return null; + } + + conditions.Add(Exp.In("id", ids)); + + } + else if (exceptIDs.Count > 0) + { + conditions.Add(!Exp.In("id", exceptIDs.ToArray())); + } + + if (conditions.Count == 0) return null; + + return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + } + + public List GetCases(IEnumerable casesID) + { + + if (casesID == null || !casesID.Any()) return new List(); + + var sqlQuery = GetCasesSqlQuery(Exp.In("id", casesID.ToArray())); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToCases).FindAll(CRMSecurity.CanAccessTo); + } + + public List GetCases( + String searchText, + int contactID, + bool? isClosed, + IEnumerable tags, + int from, + int count, + OrderBy orderBy) + { + var sqlQuery = GetCasesSqlQuery(null); + + var withParams = !(String.IsNullOrEmpty(searchText) && + contactID <= 0 && + isClosed == null && + (tags == null || !tags.Any())); + + var whereConditional = WhereConditional(CRMSecurity.GetPrivateItems(typeof(Cases)).ToList(), searchText, + contactID, isClosed, + tags); + + if (withParams && whereConditional == null) + return new List(); + + sqlQuery.Where(whereConditional); + + if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); + if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + + sqlQuery.OrderBy("is_closed", true); + + if (orderBy != null && Enum.IsDefined(typeof(SortedByType), orderBy.SortedBy)) + switch ((SortedByType)orderBy.SortedBy) + { + case SortedByType.Title: + sqlQuery.OrderBy("title", orderBy.IsAsc); + break; + case SortedByType.CreateBy: + sqlQuery.OrderBy("create_by", orderBy.IsAsc); + break; + case SortedByType.DateAndTime: + sqlQuery.OrderBy("create_on", orderBy.IsAsc); + break; + } + + + return Db.ExecuteList(sqlQuery).ConvertAll(ToCases); + } + + public List GetCasesByPrefix(String prefix, int from, int count) + { + if (count == 0) + throw new ArgumentException(); + + prefix = prefix.Trim(); + + var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); + + var q = GetCasesSqlQuery(null); + + if (keywords.Length == 1) + { + q.Where(Exp.Like("title", keywords[0])); + } + else + { + foreach (var k in keywords) + { + q.Where(Exp.Like("title", k)); + } + } + + if (0 < from && from < int.MaxValue) q.SetFirstResult(from); + if (0 < count && count < int.MaxValue) q.SetMaxResults(count); + + var sqlResult = Db.ExecuteList(q).ConvertAll(row => ToCases(row)).FindAll(CRMSecurity.CanAccessTo); + return sqlResult.OrderBy(cases => cases.Title).ToList(); + } + + public virtual List GetByID(int[] ids) + { + return Db.ExecuteList(GetCasesSqlQuery(Exp.In("id", ids))).ConvertAll(ToCases); + } + + public virtual Cases GetByID(int id) + { + if (id <= 0) return null; + + var cases = GetByID(new[] { id }); + + return cases.Count == 0 ? null : cases[0]; + } + + #region Private Methods + + private static Cases ToCases(object[] row) + { + return new Cases + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + CreateBy = ToGuid(row[2]), + CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[3].ToString())), + IsClosed = Convert.ToBoolean(row[4]) + }; + } + + private SqlQuery GetCasesSqlQuery(Exp where) + { + var sqlQuery = Query("crm_case") + .Select("id", "title", "create_by", "create_on", "is_closed"); + + if (where != null) + { + sqlQuery.Where(where); + } + + return sqlQuery; + } + + #endregion + + + public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) + { + var cases = GetAllCases(); + + foreach (var item in cases) + { + var responsibles = CRMSecurity.GetAccessSubjectGuidsTo(item); + + if (!responsibles.Any()) continue; + + responsibles.Remove(fromUserId); + responsibles.Add(toUserId); + + CRMSecurity.SetAccessTo(item, responsibles.Distinct().ToList()); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs new file mode 100644 index 00000000000..08389edd0c9 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -0,0 +1,1921 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Collections; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; +using OrderBy = ASC.CRM.Core.Entities.OrderBy; + +namespace ASC.CRM.Core.Dao +{ + public class CachedContactDao : ContactDao + { + + private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_contact"); + + public CachedContactDao(int tenantID) + : base(tenantID) + { + + } + + public override Contact GetByID(int contactID) + { + return _contactCache.Get(contactID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(contactID)); + } + + private Contact GetByIDBase(int contactID) + { + return base.GetByID(contactID); + } + + public override Contact DeleteContact(int contactID) + { + ResetCache(contactID); + + return base.DeleteContact(contactID); + } + + public override void UpdateContact(Contact contact) + { + if (contact != null && contact.ID > 0) + ResetCache(contact.ID); + + base.UpdateContact(contact); + } + + + public override int SaveContact(Contact contact) + { + if (contact != null) + { + ResetCache(contact.ID); + } + + return base.SaveContact(contact); + + } + + private void ResetCache(int contactID) + { + _contactCache.Reset(contactID.ToString()); + } + } + + + + + public class ContactDao : AbstractDao + { + #region Constructor + + public ContactDao(int tenantID) + : base(tenantID) + { + } + + #endregion + + #region Members + + private readonly String _displayNameSeparator = "!=!"; + + #endregion + + public List GetContactsByPrefix(String prefix, int searchType, int from, int count) + { + if (count == 0) + throw new ArgumentException(); + + var keywords = prefix.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + + var query = Query("crm_contact c").Select(GetContactColumnsTable("c")); + + switch (searchType) + { + case 0: // Company + query.Where(Exp.Eq("c.is_company", true)); + break; + case 1: // Persons + query.Where(Exp.Eq("c.is_company", false)); + break; + case 2: // PersonsWithoutCompany + query.Where(Exp.Eq("c.company_id", 0) & Exp.Eq("c.is_company", false)); + break; + case 3: // CompaniesAndPersonsWithoutCompany + query.Where(Exp.Eq("c.company_id", 0)); + break; + } + + foreach (var k in keywords) + { + query.Where(Exp.Like("c.display_name", k)); + } + + if (!CRMSecurity.IsAdmin) + { + var sharedContacts = Exp.Gt("c.is_shared", 0); + + var oldContacts = Exp.And(Exp.Eq("c.is_shared", null), !ExistAclRecord(false, "c")); + + var privateContacts = Exp.And(Exp.Eq("c.is_shared", 0), ExistAclRecord(true, "c")); + + query.Where(Exp.Or(sharedContacts, Exp.Or(oldContacts, privateContacts))); + } + + query.OrderBy("c.display_name", true); + + if (0 < from && from < int.MaxValue) query.SetFirstResult(from); + if (0 < count && count < int.MaxValue) query.SetMaxResults(count); + + return Db.ExecuteList(query).ConvertAll(ToContact); + } + + private static Exp ExistAclRecord(bool forCurrentUser, string contactTebleAlias = "") + { + var alias = string.IsNullOrEmpty(contactTebleAlias) ? string.Empty : contactTebleAlias + "."; + + var query = new SqlQuery("core_acl a") + .Select("a.object") + .Where(Exp.EqColumns("a.tenant", alias + "tenant_id")) + .Where(Exp.Eq("a.action", CRMSecurity._actionRead.ID)); + + if (forCurrentUser) + query.Where(Exp.Eq("a.subject", SecurityContext.CurrentAccount.ID)); + + query.Where( + Exp.Or( + Exp.EqColumns("a.object", string.Format("concat('ASC.CRM.Core.Entities.Company|', {0}id)", alias)), + Exp.EqColumns("a.object", string.Format("concat('ASC.CRM.Core.Entities.Person|', {0}id)", alias)) + ) + ); + + return Exp.Exists(query); + } + + public int GetAllContactsCount() + { + return GetContactsCount(String.Empty, null, -1, -1, ContactListViewType.All, DateTime.MinValue, DateTime.MinValue); + } + + public List GetAllContacts() + { + return GetContacts(String.Empty, new List(), -1, -1, ContactListViewType.All, DateTime.MinValue, DateTime.MinValue, 0, 0, + new OrderBy(ContactSortedByType.DisplayName, true)); + } + + public int GetContactsCount(String searchText, + IEnumerable tags, + int contactStage, + int contactType, + ContactListViewType contactListView, + DateTime fromDate, + DateTime toDate, + Guid? responsibleid = null, + bool? isShared = null) + { + + var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + + "contacts" + + SecurityContext.CurrentAccount.ID + + searchText + + contactStage + + contactType + + (int)contactListView + + responsibleid + + isShared; + + if (tags != null) + cacheKey += String.Join("", tags.ToArray()); + + if (fromDate != DateTime.MinValue) + cacheKey += fromDate.ToString(); + + if (toDate != DateTime.MinValue) + cacheKey += toDate.ToString(); + + var fromCache = _cache.Get(cacheKey); + + if (fromCache != null) return Convert.ToInt32(fromCache); + + var withParams = HasSearchParams(searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + responsibleid, + isShared); + int result; + + if (withParams) + { + ICollection excludedContactIDs; + + switch (contactListView) + { + case ContactListViewType.Person: + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) + .Except(Db.ExecuteList(Query("crm_contact").Select("id") + .Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite }) & Exp.Eq("is_company", false))) + .Select(x => Convert.ToInt32(x[0]))).ToList(); + break; + case ContactListViewType.Company: + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)) + .Except(Db.ExecuteList(Query("crm_contact").Select("id") + .Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite }) & Exp.Eq("is_company", true))) + .Select(x => Convert.ToInt32(x[0]))).ToList(); + + break; + default: + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)).Union(CRMSecurity.GetPrivateItems(typeof(Person))) + .Except(Db.ExecuteList(Query("crm_contact").Select("id").Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite }))) + .Select(x => Convert.ToInt32(x[0]))).ToList(); + + + + break; + } + + var whereConditional = WhereConditional(excludedContactIDs, + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + responsibleid, + isShared); + + if (whereConditional != null) + { + if (!isShared.HasValue) + { + var sqlQuery = Query("crm_contact").SelectCount().Where(whereConditional); + result = Db.ExecuteScalar(sqlQuery); + } + else + { + var sqlQuery = Query("crm_contact").Select("id, is_company, is_shared").Where(whereConditional); + var sqlResultRows = Db.ExecuteList(sqlQuery); + + var resultContactsNewScheme_Count = sqlResultRows.Where(row => row[2] != null).ToList().Count; //new scheme + + var fakeContactsOldScheme = sqlResultRows + .Where(row => row[2] == null).ToList() // old scheme + .ConvertAll(row => Convert.ToBoolean(row[1]) == true ? new Company() {ID = Convert.ToInt32(row[0])} as Contact : new Person() {ID = Convert.ToInt32(row[0])} as Contact ); + var resultFakeContactsOldScheme_Count = fakeContactsOldScheme.Where(fc => { + var accessSubjectToContact = CRMSecurity.GetAccessSubjectTo(fc); + if (isShared.Value == true) + { + return !accessSubjectToContact.Any(); + } + else + { + return accessSubjectToContact.Any(); + } + }).ToList().Count; + + return resultContactsNewScheme_Count + resultFakeContactsOldScheme_Count; + } + } + else + { + result = 0; + } + } + else + { + var countWithoutPrivate = Db.ExecuteScalar(Query("crm_contact").SelectCount()); + + var privateCount = CRMSecurity.GetPrivateItemsCount(typeof(Person)) + + CRMSecurity.GetPrivateItemsCount(typeof(Company)) - + Db.ExecuteScalar(Query("crm_contact").Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite })).SelectCount()); + + if (privateCount < 0) + privateCount = 0; + + if (privateCount > countWithoutPrivate) + { + _log.Error("Private contacts count more than all contacts"); + + privateCount = 0; + } + + result = countWithoutPrivate - privateCount; + } + if (result > 0) + { + _cache.Insert(cacheKey, result, TimeSpan.FromMinutes(1)); + } + + return result; + } + + public List SearchContactsByEmail(string searchText, int maxCount) + { + var contacts = new List(); + + if (string.IsNullOrEmpty(searchText) || maxCount <= 0) + return contacts; + + Func getBaseQuery = () => + { + var query = new SqlQuery("crm_contact cc") + .Select(GetContactColumnsTable("cc")) + .InnerJoin("crm_contact_info cci", + Exp.EqColumns("cc.tenant_id", "cci.tenant_id") & + Exp.EqColumns("cc.id", "cci.contact_id")) + .Where("cci.type", (int) ContactInfoType.Email) + .Where("cc.tenant_id", TenantID); + + return query; + }; + + var ids = new List(); + + List contactsIds; + if (FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out contactsIds)) + { + if (!contactsIds.Any()) + return contacts; + + ids = contactsIds.Select(r => Convert.ToInt32(r)).ToList(); + } + + var isAdmin = CRMSecurity.IsAdmin; + const int count_per_query = 100; + + var f = 0; + do + { + var query = getBaseQuery(); + + if (ids.Any()) + { + var partIds = ids.Skip(f).Take(count_per_query).ToList(); + + if (!partIds.Any()) + break; + + query + .Where(Exp.In("cc.id", partIds)); + } + else + { + query + .Where(Exp.Like("concat(cc.display_name, ' ', cci.data)", searchText, SqlLike.AnyWhere)) + .SetFirstResult(f) + .SetMaxResults(count_per_query); + } + + var partContacts = Db.ExecuteList(query) + .ConvertAll(ToContact); + + foreach (var partContact in partContacts) + { + if (maxCount - contacts.Count == 0) + return contacts; + + if (isAdmin || CRMSecurity.CanAccessTo(partContact)) + contacts.Add(partContact); + } + + if (maxCount - contacts.Count == 0 || !partContacts.Any() || partContacts.Count < count_per_query) + break; + + f += count_per_query; + + } while (true); + + return contacts; + } + + public List GetContacts(String searchText, + IEnumerable tags, + int contactStage, + int contactType, + ContactListViewType contactListView, + DateTime fromDate, + DateTime toDate, + int from, + int count, + OrderBy orderBy, + Guid? responsibleId = null, + bool? isShared = null) + { + if (CRMSecurity.IsAdmin) + { + if (!isShared.HasValue) + { + return GetCrudeContacts( + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + from, + count, + orderBy, + responsibleId, + isShared, + false); + } + else + { + var crudeContacts = GetCrudeContacts( + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + 0, + from + count, + orderBy, + responsibleId, + isShared, + false); + + if (crudeContacts.Count == 0) return crudeContacts; + + var result = crudeContacts.Where(c => (isShared.Value == true ? c.ShareType != ShareType.None : c.ShareType == ShareType.None)).ToList(); + + if (result.Count == crudeContacts.Count) return result.Skip(from).ToList(); + + var localCount = count; + var localFrom = from + count; + + while (true) + { + crudeContacts = GetCrudeContacts( + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + localFrom, + localCount, + orderBy, + responsibleId, + isShared, + false); + + if (crudeContacts.Count == 0) break; + + result.AddRange(crudeContacts.Where(c => (isShared.Value == true ? c.ShareType != ShareType.None : c.ShareType == ShareType.None))); + + if ((result.Count >= count + from) || (crudeContacts.Count < localCount)) break; + + localFrom += localCount; + localCount = localCount * 2; + } + + return result.Skip(from).Take(count).ToList(); + } + } + else + { + var crudeContacts = GetCrudeContacts( + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + 0, + from + count, + orderBy, + responsibleId, + isShared, + false); + + if (crudeContacts.Count == 0) return crudeContacts; + + var tmp = isShared.HasValue ? crudeContacts.Where(c => (isShared.Value == true ? c.ShareType != ShareType.None : c.ShareType == ShareType.None)).ToList() : crudeContacts; + + if (crudeContacts.Count < from + count) + { + return tmp.FindAll(CRMSecurity.CanAccessTo).Skip(from).ToList(); + } + + var result = tmp.FindAll(CRMSecurity.CanAccessTo); + + if (result.Count == crudeContacts.Count) return result.Skip(from).ToList(); + + var localCount = count; + var localFrom = from + count; + + while (true) + { + crudeContacts = GetCrudeContacts( + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + localFrom, + localCount, + orderBy, + responsibleId, + isShared, + false); + + if (crudeContacts.Count == 0) break; + + tmp = isShared.HasValue ? crudeContacts.Where(c => (isShared.Value == true ? c.ShareType != ShareType.None : c.ShareType == ShareType.None)).ToList() : crudeContacts; + + result.AddRange(tmp.Where(CRMSecurity.CanAccessTo)); + + if ((result.Count >= count + from) || (crudeContacts.Count < localCount)) break; + + localFrom += localCount; + localCount = localCount * 2; + } + + return result.Skip(from).Take(count).ToList(); + } + } + + private bool HasSearchParams(String searchText, + IEnumerable tags, + int contactStage, + int contactType, + ContactListViewType contactListView, + DateTime fromDate, + DateTime toDate, + Guid? responsibleid = null, + bool? isShared = null) + { + var hasNoParams = String.IsNullOrEmpty(searchText) && + (tags == null || !tags.Any()) && + contactStage < 0 && + contactType < 0 && + contactListView == ContactListViewType.All && + !isShared.HasValue && + fromDate == DateTime.MinValue && + toDate == DateTime.MinValue && + !responsibleid.HasValue; + + return !hasNoParams; + } + + private Exp WhereConditional( + ICollection exceptIDs, + String searchText, + IEnumerable tags, + int contactStage, + int contactType, + ContactListViewType contactListView, + DateTime fromDate, + DateTime toDate, + Guid? responsibleid = null, + bool? isShared = null) + { + var conditions = new List(); + + var ids = new List(); + + if (responsibleid.HasValue) + { + + if (responsibleid != default(Guid)) + { + ids = CRMSecurity.GetContactsIdByManager(responsibleid.Value).ToList(); + if (ids.Count == 0) return null; + } + else + { + if (exceptIDs == null) + exceptIDs = new List(); + + exceptIDs = exceptIDs.Union(CRMSecurity.GetContactsIdByManager(Guid.Empty)).ToList(); + + if (!exceptIDs.Any()) // HACK + exceptIDs.Add(0); + } + + } + + if (!String.IsNullOrEmpty(searchText)) + { + searchText = searchText.Trim(); + + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + .ToArray(); + + List contactsIds; + if (!BundleSearch.TrySelectContact(searchText, out contactsIds)) + { + _log.Debug("FullTextSearch.SupportModule('CRM.Contacts') = false"); + conditions.Add(BuildLike(new[] { "display_name" }, keywords)); + } + else + { + _log.Debug("FullTextSearch.SupportModule('CRM.Contacts') = true"); + _log.DebugFormat("FullTextSearch.Search: searchText = {0}", searchText); + var full_text_ids = contactsIds; + + if (full_text_ids.Count == 0) return null; + + if (ids.Count != 0) + { + ids = ids.Where(full_text_ids.Contains).ToList(); + if (ids.Count == 0) return null; + } + else + { + ids = full_text_ids; + } + + if (contactListView == ContactListViewType.All || contactListView == ContactListViewType.Person) + { + ids.AddRange(GetContactIDsByCompanyIds(ids)); + } + } + } + + if (tags != null && tags.Any()) + { + ids = SearchByTags(EntityType.Contact, ids.ToArray(), tags); + + if (ids.Count == 0) return null; + } + + + switch (contactListView) + { + case ContactListViewType.Company: + conditions.Add(Exp.Eq("is_company", true)); + break; + case ContactListViewType.Person: + conditions.Add(Exp.Eq("is_company", false)); + break; + case ContactListViewType.WithOpportunity: + if (ids.Count > 0) + { + ids = Db.ExecuteList(new SqlQuery("crm_entity_contact").Select("contact_id") + .Distinct() + .Where(Exp.In("contact_id", ids) & Exp.Eq("entity_type", (int)EntityType.Opportunity))) + .ConvertAll(row => Convert.ToInt32(row[0])); + } + else + { + ids = Db.ExecuteList(new SqlQuery("crm_entity_contact").Select("contact_id") + .Distinct() + .Where(Exp.Eq("entity_type", (int)EntityType.Opportunity))) + .ConvertAll(row => Convert.ToInt32(row[0])); + } + + if (ids.Count == 0) return null; + + break; + } + + if (contactStage >= 0) + conditions.Add(Exp.Eq("status_id", contactStage)); + if (contactType >= 0) + conditions.Add(Exp.Eq("contact_type_id", contactType)); + + if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) + conditions.Add(Exp.Between("create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1)))); + else if (fromDate != DateTime.MinValue) + conditions.Add(Exp.Ge("create_on", TenantUtil.DateTimeToUtc(fromDate))); + else if (toDate != DateTime.MinValue) + conditions.Add(Exp.Le("create_on", TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1)))); + + if (isShared.HasValue) + { + if (isShared.Value == true) { + conditions.Add(Exp.Or(Exp.In("is_shared", new[]{(int)ShareType.Read , (int)ShareType.ReadWrite}), Exp.Eq("is_shared", null))); + } else { + conditions.Add(Exp.Or(Exp.Eq("is_shared", (int)ShareType.None), Exp.Eq("is_shared", null))); + } + } + + if (ids.Count > 0) + { + if (exceptIDs.Count > 0) + { + ids = ids.Except(exceptIDs).ToList(); + if (ids.Count == 0) return null; + } + + conditions.Add(Exp.In("id", ids)); + + } + else if (exceptIDs.Count > 0) + { + var _MaxCountForSQLNotIn = 500; + + if (exceptIDs.Count > _MaxCountForSQLNotIn) + { + ids = Db.ExecuteList(Query("crm_contact").Select("id")).ConvertAll(row => Convert.ToInt32(row[0])); //get all contact ids + ids = ids.Except(exceptIDs).ToList(); + if (ids.Count == 0) return null; + + conditions.Add(Exp.In("id", ids)); + + } else { + conditions.Add(!Exp.In("id", exceptIDs.ToArray())); + } + } + + if (conditions.Count == 0) return null; + + return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + } + + private List GetCrudeContacts( + String searchText, + IEnumerable tags, + int contactStage, + int contactType, + ContactListViewType contactListView, + DateTime fromDate, + DateTime toDate, + int from, + int count, + OrderBy orderBy, + Guid? responsibleid = null, + bool? isShared = null, + bool selectIsSharedInNewScheme = true) + { + + var sqlQuery = GetContactSqlQuery(null); + + var withParams = HasSearchParams(searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + responsibleid, + isShared); + + var whereConditional = WhereConditional(new List(), + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + responsibleid, + isShared); + + if (withParams && whereConditional == null) + return new List(); + + sqlQuery.Where(whereConditional); + + if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); + if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + + if (orderBy != null) + { + + if (!Enum.IsDefined(typeof(ContactSortedByType), orderBy.SortedBy.ToString())) + orderBy.SortedBy = ContactSortedByType.Created; + + switch ((ContactSortedByType)orderBy.SortedBy) + { + case ContactSortedByType.DisplayName: + sqlQuery.OrderBy("display_name", orderBy.IsAsc); + break; + case ContactSortedByType.Created: + sqlQuery.OrderBy("create_on", orderBy.IsAsc); + break; + case ContactSortedByType.ContactType: + sqlQuery.OrderBy("status_id", orderBy.IsAsc); + break; + case ContactSortedByType.FirstName: + sqlQuery.OrderBy("first_name", orderBy.IsAsc); + sqlQuery.OrderBy("last_name", orderBy.IsAsc); + break; + case ContactSortedByType.LastName: + sqlQuery.OrderBy("last_name", orderBy.IsAsc); + sqlQuery.OrderBy("first_name", orderBy.IsAsc); + break; + case ContactSortedByType.History: + sqlQuery.Select("last_event_modifed_on"); + + var subSqlQuery = Query("crm_relationship_event") + .Select("contact_id") + .Select("max(last_modifed_on) as last_event_modifed_on") + .Where(Exp.Gt("contact_id", 0)) + .GroupBy("contact_id"); + + sqlQuery.LeftOuterJoin(subSqlQuery, "evt", Exp.EqColumns("id", "evt.contact_id")); + sqlQuery.OrderBy("last_event_modifed_on", orderBy.IsAsc); + sqlQuery.OrderBy("create_on", orderBy.IsAsc); + break; + default: + sqlQuery.OrderBy("display_name", orderBy.IsAsc); + break; + } + } + + + var data = Db.ExecuteList(sqlQuery); + + var contacts = data.ConvertAll(ToContact); + + return selectIsSharedInNewScheme && isShared.HasValue ? + contacts.Where(c => (isShared.Value ? c.ShareType != ShareType.None : c.ShareType == ShareType.None)).ToList() : + contacts; + } + + public List GetContactsByName(String title, bool isCompany) + { + if (String.IsNullOrEmpty(title)) return new List(); + + title = title.Trim(); + + if (isCompany) + { + return Db.ExecuteList( + GetContactSqlQuery(Exp.Eq("display_name", title) & Exp.Eq("is_company", true))) + .ConvertAll(ToContact) + .FindAll(CRMSecurity.CanAccessTo); + } + else + { + var titleParts = title.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); + + if (titleParts.Length == 1 || titleParts.Length == 2) + { + if (titleParts.Length == 1) + return Db.ExecuteList( + GetContactSqlQuery(Exp.Eq("display_name", title) & Exp.Eq("is_company", false))) + .ConvertAll(ToContact) + .FindAll(CRMSecurity.CanAccessTo); + else + return Db.ExecuteList( + GetContactSqlQuery(Exp.Eq("display_name", String.Concat(titleParts[0], _displayNameSeparator, titleParts[1])) & Exp.Eq("is_company", false))) + .ConvertAll(ToContact) + .FindAll(CRMSecurity.CanAccessTo); + } + } + return GetContacts(title, null, -1, -1, isCompany ? ContactListViewType.Company : ContactListViewType.Person, DateTime.MinValue, DateTime.MinValue, 0, 0, null); + } + + public void RemoveMember(int[] peopleID) + { + if ((peopleID == null) || (peopleID.Length == 0)) return; + + Db.ExecuteNonQuery(Update("crm_contact").Set("company_id", 0).Where(Exp.In("id", peopleID))); + RemoveRelativeInDb(null, EntityType.Person, peopleID); + } + + public void RemoveMember(int peopleID) + { + Db.ExecuteNonQuery(Update("crm_contact").Set("company_id", 0).Where("id", peopleID)); + RemoveRelative(0, EntityType.Person, peopleID); + } + + public void AddMemberInDb(int peopleID, int companyID) + { + Db.ExecuteNonQuery(Update("crm_contact") + .Set("company_id", companyID) + .Where("id", peopleID)); + SetRelative(companyID, EntityType.Person, peopleID); + } + + public void AddMember(int peopleID, int companyID) + { + AddMemberInDb(peopleID, companyID); + } + + public void SetMembers(int companyID, params int[] peopleIDs) + { + if (companyID == 0) + throw new ArgumentException(); + + using (var tx = Db.BeginTransaction()) + { + Db.ExecuteNonQuery(new SqlDelete("crm_entity_contact") + .Where(Exp.Eq("entity_type", EntityType.Person) & + Exp.Eq("contact_id", companyID))); + + Db.ExecuteNonQuery(Update("crm_contact") + .Set("company_id", 0) + .Where(Exp.Eq("company_id", companyID))); + + + if (!(peopleIDs == null || peopleIDs.Length == 0)) + { + Db.ExecuteNonQuery(Update("crm_contact") + .Set("company_id", companyID) + .Where(Exp.In("id", peopleIDs))); + foreach (var peopleID in peopleIDs) + SetRelative(companyID, EntityType.Person, peopleID); + } + + tx.Commit(); + + } + + } + + public void SetRelativeContactProject(IEnumerable contactid, int projectid) + { + using (var tx = Db.BeginTransaction()) + { + foreach (var id in contactid) + { + + Db.ExecuteNonQuery(Insert("crm_projects") + .InColumnValue("contact_id", id) + .InColumnValue("project_id", projectid)); + } + + tx.Commit(); + } + } + + public void RemoveRelativeContactProject(int contactid, int projectid) + { + Db.ExecuteNonQuery(Delete("crm_projects") + .Where(Exp.Eq("contact_id", contactid) & Exp.Eq("project_id", projectid))); + } + + + public IEnumerable GetContactsByProjectID(int projectid) + { + var contactIds = Db.ExecuteList(Query("crm_projects") + .Select("contact_id") + .Where("project_id", projectid)).Select(x => Convert.ToInt32(x[0])); + + + if (!contactIds.Any()) return new List(); + + return GetContacts(contactIds.ToArray()); + } + + public List GetMembers(int companyID) + { + return GetContacts(GetRelativeToEntity(companyID, EntityType.Person, null)); + } + + public List GetRestrictedMembers(int companyID) + { + return GetRestrictedContacts(GetRelativeToEntity(companyID, EntityType.Person, null)); + } + + public Dictionary GetMembersCount(int[] companyID) + { + + var sqlQuery = new SqlQuery("crm_entity_contact") + .Select("contact_id") + .SelectCount() + .Where(Exp.In("contact_id", companyID) & Exp.Eq("entity_type", (int)EntityType.Person)) + .GroupBy("contact_id"); + + var sqlResult = Db.ExecuteList(sqlQuery); + + return sqlResult.ToDictionary(item => Convert.ToInt32(item[0]), item => Convert.ToInt32(item[1])); + } + + + public int GetMembersCount(int companyID) + { + return Db.ExecuteScalar( + new SqlQuery("crm_entity_contact") + .SelectCount() + .Where(Exp.Eq("contact_id", companyID) & Exp.Eq("entity_type", (int)EntityType.Person))); + } + + public List GetMembersIDs(int companyID) + { + return Db.ExecuteList( + new SqlQuery("crm_entity_contact") + .Select("entity_id") + .Where(Exp.Eq("contact_id", companyID) & Exp.Eq("entity_type", (int)EntityType.Person))) + .ConvertAll(row => (int)(row[0])); + } + + public Dictionary GetMembersIDsAndShareType(int companyID) + { + var result = new Dictionary(); + + var query = new SqlQuery("crm_entity_contact ec") + .Select("ec.entity_id") + .Select("c.is_shared") + .LeftOuterJoin("crm_contact c", Exp.EqColumns("ec.entity_id", "c.id")) + .Where(Exp.Eq("ec.contact_id", companyID) & Exp.Eq("ec.entity_type", (int)EntityType.Person)); + var rows = Db.ExecuteList(query); + + foreach (var row in rows) { + if (row[1] == null) + { + result.Add((int)(row[0]), null); + } + else + { + result.Add((int)(row[0]), (ShareType)(Convert.ToInt32(row[1]))); + } + } + + return result; + } + + + public virtual void UpdateContact(Contact contact) + { + UpdateContactFromDb(contact); + } + + private void UpdateContactFromDb(Contact contact) + { + var originalContact = GetByID(contact.ID); + if (originalContact == null) throw new ArgumentException(); + CRMSecurity.DemandEdit(originalContact); + + String firstName; + String lastName; + String companyName; + String title; + int companyID; + + var displayName = String.Empty; + + if (contact is Company) + { + firstName = String.Empty; + lastName = String.Empty; + title = String.Empty; + companyName = ((Company)contact).CompanyName.Trim(); + companyID = 0; + displayName = companyName; + + if (String.IsNullOrEmpty(companyName)) + throw new ArgumentException(); + + } + else + { + var people = (Person)contact; + + firstName = people.FirstName.Trim(); + lastName = people.LastName.Trim(); + title = people.JobTitle; + companyName = String.Empty; + companyID = people.CompanyID; + + displayName = String.Concat(firstName, _displayNameSeparator, lastName); + + RemoveMember(people.ID); + + if (companyID > 0) + { + AddMemberInDb(people.ID, companyID); + } + + if (String.IsNullOrEmpty(firstName))// || String.IsNullOrEmpty(lastName)) lastname is not required field now + throw new ArgumentException(); + + } + + if (!String.IsNullOrEmpty(title)) + title = title.Trim(); + + if (!String.IsNullOrEmpty(contact.About)) + contact.About = contact.About.Trim(); + + if (!String.IsNullOrEmpty(contact.Industry)) + contact.Industry = contact.Industry.Trim(); + + + Db.ExecuteNonQuery( + Update("crm_contact") + .Set("first_name", firstName) + .Set("last_name", lastName) + .Set("company_name", companyName) + .Set("title", title) + .Set("notes", contact.About) + .Set("industry", contact.Industry) + .Set("status_id", contact.StatusID) + .Set("company_id", companyID) + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Set("display_name", displayName) + .Set("is_shared", (int)contact.ShareType) + .Set("contact_type_id", contact.ContactTypeID) + .Set("currency", contact.Currency) + .Where(Exp.Eq("id", contact.ID))); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + FactoryIndexer.UpdateAsync(contact); + } + + public void UpdateContactStatus(IEnumerable contactid, int statusid) + { + Db.ExecuteNonQuery( + Update("crm_contact") + .Set("status_id", statusid) + .Where(Exp.In("id", contactid.ToArray()))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + } + + public List FindDuplicateByEmail(List items, bool resultReal) + { + //resultReal - true => real, false => fake + if (items.Count == 0) return new List(); + + var result = new List(); + var emails = items.ConvertAll(i => i.Data).ToList(); + var sqlQuery = Query("crm_contact_info") + .Select("contact_id", "data") + .Where(Exp.In("data", emails) & Exp.Eq("type", (int)ContactInfoType.Email)); + + if (resultReal) + { + result = Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToInt32(row[0])); + } + else + { + List emailsAlreadyExists; + + emailsAlreadyExists = Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToString(row[1])); + + if (emailsAlreadyExists.Count != 0) { + result = items.Where(i => emailsAlreadyExists.Contains(i.Data)).Select(i => i.ContactID).ToList(); + } + + } + + return result; + } + + public virtual Dictionary SaveContactList(List items) + { + using (var tx = Db.BeginTransaction()) + { + var result = new Dictionary(); + + for (int index = 0; index < items.Count; index++) + { + var item = items[index]; + + if (item.ID == 0) + item.ID = index; + + result.Add(item.ID, SaveContactToDb(item)); + } + + tx.Commit(); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + + return result; + } + } + + public virtual void UpdateContactList(List items) + { + using (var tx = Db.BeginTransaction()) + { + for (int index = 0; index < items.Count; index++) + { + var item = items[index]; + + if (item.ID == 0) + item.ID = index; + + UpdateContactFromDb(item); + } + + tx.Commit(); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + } + } + + public void MakePublic(int contactId, bool isShared) + { + if (contactId <= 0) throw new ArgumentException(); + + Db.ExecuteNonQuery( + Update("crm_contact") + .Set("is_shared", isShared) + .Where(Exp.Eq("id", contactId))); + + } + + public virtual int SaveContact(Contact contact) + { + var result = SaveContactToDb(contact); + FactoryIndexer.IndexAsync(contact); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + return result; + } + + private int SaveContactToDb(Contact contact) + { + String firstName; + String lastName; + bool isCompany; + String companyName; + String title; + int companyID; + + var displayName = String.Empty; + + if (contact is Company) + { + firstName = String.Empty; + lastName = String.Empty; + title = String.Empty; + companyName = (((Company) contact).CompanyName ?? "").Trim(); + isCompany = true; + companyID = 0; + displayName = companyName; + + if (String.IsNullOrEmpty(companyName)) + throw new ArgumentException(); + + } + else + { + var people = (Person)contact; + + firstName = people.FirstName.Trim(); + lastName = people.LastName.Trim(); + title = people.JobTitle; + companyName = String.Empty; + isCompany = false; + + if (IsExist(people.CompanyID)) + companyID = people.CompanyID; + else + companyID = 0; + + displayName = String.Concat(firstName, _displayNameSeparator, lastName); + + + if (String.IsNullOrEmpty(firstName))// || String.IsNullOrEmpty(lastName)) lastname is not required field now + throw new ArgumentException(); + + } + + if (!String.IsNullOrEmpty(title)) + title = title.Trim(); + + if (!String.IsNullOrEmpty(contact.About)) + contact.About = contact.About.Trim(); + + if (!String.IsNullOrEmpty(contact.Industry)) + contact.Industry = contact.Industry.Trim(); + + var contactID = Db.ExecuteScalar( + Insert("crm_contact") + .InColumnValue("id", 0) + .InColumnValue("first_name", firstName) + .InColumnValue("last_name", lastName) + .InColumnValue("company_name", companyName) + .InColumnValue("title", title) + .InColumnValue("notes", contact.About) + .InColumnValue("is_company", isCompany) + .InColumnValue("industry", contact.Industry) + .InColumnValue("status_id", contact.StatusID) + .InColumnValue("company_id", companyID) + .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("create_on", TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn)) + .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn)) + .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("display_name", displayName) + .InColumnValue("is_shared", (int)contact.ShareType) + .InColumnValue("contact_type_id", contact.ContactTypeID) + .InColumnValue("currency", contact.Currency) + .Identity(1, 0, true)); + + contact.ID = contactID; + + if (companyID > 0) + AddMemberInDb(contactID, companyID); + + return contactID; + } + + public Boolean IsExist(int contactID) + { + return Db.ExecuteScalar("select exists(select 1 from crm_contact where tenant_id = @tid and id = @id)", + new { tid = TenantID, id = contactID }); + } + + public Boolean CanDelete(int contactID) + { + return Db.ExecuteScalar("select count(*) from crm_invoice where tenant_id = @tid and (contact_id = @id or consignee_id = @id)", + new { tid = TenantID, id = contactID }) == 0; + } + + public Dictionary CanDelete(int[] contactID) + { + var result = new Dictionary(); + if (contactID.Length == 0) return result; + + var contactIDs = contactID.Distinct().ToList(); + var contactIDsDBString = ""; + contactIDs.ForEach(id => contactIDsDBString += String.Format("{0},", id)); + contactIDsDBString = contactIDsDBString.TrimEnd(','); + + List hasInvoiceIDs; + + var query = String.Format( + @"select distinct contact_id from crm_invoice where tenant_id = {0} and contact_id in ({1}) + union all + select distinct consignee_id from crm_invoice where tenant_id = {0} and consignee_id in ({1})", TenantID, contactIDsDBString); + + hasInvoiceIDs = Db.ExecuteList(query).ConvertAll(row => Convert.ToInt32(row[0])); + + foreach (var cid in contactIDs) + { + result.Add(cid, !hasInvoiceIDs.Contains(cid)); + } + + return result; + } + + public virtual Contact GetByID(int contactID) + { + return GetByIDFromDb(contactID); + } + + public Contact GetByIDFromDb(int contactID) + { + SqlQuery sqlQuery = GetContactSqlQuery(Exp.Eq("id", contactID)); + + var contacts = Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)); + + if (contacts.Count == 0) return null; + + return contacts[0]; + } + + public List GetContacts(int[] contactID) + { + if (contactID == null || contactID.Length == 0) return new List(); + + SqlQuery sqlQuery = GetContactSqlQuery(Exp.In("id", contactID)); + + return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)).FindAll(CRMSecurity.CanAccessTo); + } + + public List GetRestrictedContacts(int[] contactID) + { + if (contactID == null || contactID.Length == 0) return new List(); + + SqlQuery sqlQuery = GetContactSqlQuery(Exp.In("id", contactID)); + + return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)).FindAll(cont => !CRMSecurity.CanAccessTo(cont)); + } + + public List GetRestrictedAndAccessedContacts(int[] contactID) + { + if (contactID == null || contactID.Length == 0) return new List(); + + SqlQuery sqlQuery = GetContactSqlQuery(Exp.In("id", contactID)); + + return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)); + } + + public virtual List DeleteBatchContact(int[] contactID) + { + if (contactID == null || contactID.Length == 0) return null; + + var contacts = GetContacts(contactID).Where(CRMSecurity.CanDelete).ToList(); + if (!contacts.Any()) return contacts; + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + + DeleteBatchContactsExecute(contacts); + + return contacts; + } + + public virtual List DeleteBatchContact(List contacts) + { + contacts = contacts.FindAll(CRMSecurity.CanDelete).ToList(); + if (!contacts.Any()) return contacts; + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + + DeleteBatchContactsExecute(contacts); + + return contacts; + } + + public virtual Contact DeleteContact(int contactID) + { + if (contactID <= 0) return null; + + var contact = GetByID(contactID); + if (contact == null) return null; + + CRMSecurity.DemandDelete(contact); + + DeleteBatchContactsExecute(new List() { contact }); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + + var person = contact as Person; + if (person != null) + { + FactoryIndexer.DeleteAsync(person); + } + else + { + FactoryIndexer.DeleteAsync(contact as Company); + } + + return contact; + } + + private void DeleteBatchContactsExecute(List contacts) + { + var personsID = new List(); + var companyID = new List(); + var newContactID = new List(); + + foreach (var contact in contacts) + { + newContactID.Add(contact.ID); + + if (contact is Company) + companyID.Add(contact.ID); + else + personsID.Add(contact.ID); + } + + var contactID = newContactID.ToArray(); + var filesIDs = new object[0]; + + using (var tx = Db.BeginTransaction()) + using (var tagdao = FilesIntegration.GetTagDao()) + { + var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id").Where(Exp.In("contact_id", contactID) & Exp.Eq("have_files", true))).Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); + if (0 < tagNames.Length) + { + filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + } + + Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", contactID) & Exp.In("entity_type", new[] { (int)EntityType.Contact, (int)EntityType.Person, (int)EntityType.Company }))); + Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("contact_id", contactID))); + Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", contactID) & Exp.Eq("entity_type", (int)EntityType.Contact))); + + Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("contact_id", contactID))); + Db.ExecuteNonQuery(Update("crm_deal").Set("contact_id", 0).Where(Exp.In("contact_id", contactID))); + + if (companyID.Count > 0) + { + Db.ExecuteNonQuery(Update("crm_contact").Set("company_id", 0).Where(Exp.In("company_id", companyID))); + } + if (personsID.Count > 0) + { + RemoveRelativeInDb(null, EntityType.Person, personsID.ToArray()); + } + RemoveRelativeInDb(contactID, EntityType.Any, null); + + Db.ExecuteNonQuery(Delete("crm_contact_info").Where(Exp.In("contact_id", contactID))); + Db.ExecuteNonQuery(Delete("crm_contact").Where(Exp.In("id", contactID))); + + tx.Commit(); + } + + contacts.ForEach(contact => CoreContext.AuthorizationManager.RemoveAllAces(contact)); + + using (var filedao = FilesIntegration.GetFileDao()) + { + foreach (var filesID in filesIDs) + { + filedao.DeleteFile(filesID); + } + } + + //todo: remove indexes + } + + private void MergeContactInfo(Contact fromContact, Contact toContact) + { + + if ((toContact is Person) && (fromContact is Person)) + { + var fromPeople = (Person)fromContact; + var toPeople = (Person)toContact; + + if (toPeople.CompanyID == 0) + toPeople.CompanyID = fromPeople.CompanyID; + + if (String.IsNullOrEmpty(toPeople.JobTitle)) + toPeople.JobTitle = fromPeople.JobTitle; + } + + if (String.IsNullOrEmpty(toContact.Industry)) + toContact.Industry = fromContact.Industry; + + if (toContact.StatusID == 0) + toContact.StatusID = fromContact.StatusID; + if (toContact.ContactTypeID == 0) + toContact.ContactTypeID = fromContact.ContactTypeID; + + if (String.IsNullOrEmpty(toContact.About)) + toContact.About = fromContact.About; + + UpdateContactFromDb(toContact); + } + + public void MergeDublicate(int fromContactID, int toContactID) + { + if (fromContactID == toContactID) + { + if (GetByID(fromContactID) == null) + throw new ArgumentException(); + return; + } + + var fromContact = GetByID(fromContactID); + var toContact = GetByID(toContactID); + + if (fromContact == null || toContact == null) + throw new ArgumentException(); + + using (var tx = Db.BeginTransaction()) + { + ISqlInstruction q = Update("crm_task") + .Set("contact_id", toContactID) + .Where(Exp.Eq("contact_id", fromContactID)); + Db.ExecuteNonQuery(q); + + // crm_entity_contact + q = new SqlQuery("crm_entity_contact l") + .From("crm_entity_contact r") + .Select("l.entity_id", "l.entity_type", "l.contact_id") + .Where(Exp.EqColumns("l.entity_id", "r.entity_id") & Exp.EqColumns("l.entity_type", "r.entity_type")) + .Where("l.contact_id", fromContactID) + .Where("r.contact_id", toContactID); + Db.ExecuteList(q) + .ForEach(row => + Db.ExecuteNonQuery(new SqlDelete("crm_entity_contact").Where("entity_id", row[0]).Where("entity_type", row[1]).Where("contact_id", row[2])) + ); + + q = new SqlUpdate("crm_entity_contact") + .Set("contact_id", toContactID) + .Where("contact_id", fromContactID); + Db.ExecuteNonQuery(q); + + // crm_deal + q = Update("crm_deal") + .Set("contact_id", toContactID) + .Where("contact_id", fromContactID); + Db.ExecuteNonQuery(q); + + // crm_invoice + q = Update("crm_invoice") + .Set("contact_id", toContactID) + .Where("contact_id", fromContactID); + Db.ExecuteNonQuery(q); + + // crm_projects + q = new SqlQuery("crm_projects p") + .Select("p.project_id") + .From("crm_projects r") + .Where(Exp.EqColumns("p.project_id", "r.project_id")) + .Where("p.contact_id", fromContactID) + .Where("r.contact_id", toContactID); + var dublicateProjectID = Db.ExecuteList(q).ConvertAll(row => row[0]); + + q = new SqlDelete("crm_projects").Where(Exp.Eq("contact_id", fromContactID) & Exp.In("project_id", dublicateProjectID)); + Db.ExecuteNonQuery(q); + + q = new SqlUpdate("crm_projects").Set("contact_id", toContactID).Where("contact_id", fromContactID); + Db.ExecuteNonQuery(q); + + // crm_relationship_event + q = Update("crm_relationship_event") + .Set("contact_id", toContactID) + .Where("contact_id", fromContactID); + Db.ExecuteNonQuery(q); + + // crm_entity_tag + q = new SqlQuery("crm_entity_tag l") + .Select("l.tag_id") + .From("crm_entity_tag r") + .Where(Exp.EqColumns("l.tag_id", "r.tag_id") & Exp.EqColumns("l.entity_type", "r.entity_type")) + .Where("l.entity_id", fromContactID) + .Where("r.entity_id", toContactID); + var dublicateTagsID = Db.ExecuteList(q).ConvertAll(row => row[0]); + + q = new SqlDelete("crm_entity_tag").Where(Exp.Eq("entity_id", fromContactID) & Exp.Eq("entity_type", (int)EntityType.Contact) & Exp.In("tag_id", dublicateTagsID)); + Db.ExecuteNonQuery(q); + + q = new SqlUpdate("crm_entity_tag").Set("entity_id", toContactID).Where("entity_id", fromContactID).Where("entity_type", (int)EntityType.Contact); + Db.ExecuteNonQuery(q); + + // crm_field_value + q = Query("crm_field_value l") + .From("crm_field_value r") + .Select("l.field_id") + .Where(Exp.EqColumns("l.tenant_id", "r.tenant_id") & Exp.EqColumns("l.field_id", "r.field_id") & Exp.EqColumns("l.entity_type", "r.entity_type")) + .Where("l.entity_id", fromContactID) + .Where("r.entity_id", toContactID); + var dublicateCustomFieldValueID = Db.ExecuteList(q).ConvertAll(row => row[0]); + + q = Delete("crm_field_value") + .Where("entity_id", fromContactID) + .Where(Exp.In("entity_type", new[] { (int)EntityType.Contact, (int)EntityType.Person, (int)EntityType.Company })) + .Where(Exp.In("field_id", dublicateCustomFieldValueID)); + Db.ExecuteNonQuery(q); + + q = Update("crm_field_value") + .Set("entity_id", toContactID) + .Where("entity_id", fromContactID) + .Where("entity_type", (int)EntityType.Contact); + Db.ExecuteNonQuery(q); + + + // crm_contact_info + + q = Query("crm_contact_info l") + .From("crm_contact_info r") + .Select("l.id") + .Where(Exp.Eq("l.is_primary", true)) + .Where(Exp.Eq("r.is_primary", true)) + .Where(Exp.EqColumns("l.tenant_id", "r.tenant_id")) + .Where(Exp.EqColumns("l.type", "r.type")) + .Where(Exp.EqColumns("l.category", "r.category")) + .Where(!Exp.EqColumns("l.data", "r.data")) + .Where("l.contact_id", fromContactID) + .Where("r.contact_id", toContactID); + var dublicatePrimaryContactInfoID = Db.ExecuteList(q).ConvertAll(row => row[0]); + + q = Update("crm_contact_info") + .Set("is_primary", false) + .Where("contact_id", fromContactID) + .Where(Exp.In("id", dublicatePrimaryContactInfoID)); + Db.ExecuteNonQuery(q); + + q = Query("crm_contact_info l") + .From("crm_contact_info r") + .Select("l.id") + .Where(Exp.EqColumns("l.tenant_id", "r.tenant_id")) + .Where(Exp.EqColumns("l.type", "r.type")) + .Where(Exp.EqColumns("l.is_primary", "r.is_primary")) + .Where(Exp.EqColumns("l.category", "r.category")) + .Where(Exp.EqColumns("l.data", "r.data")) + .Where("l.contact_id", fromContactID) + .Where("r.contact_id", toContactID); + var dublicateContactInfoID = Db.ExecuteList(q).ConvertAll(row => row[0]); + + q = Delete("crm_contact_info") + .Where("contact_id", fromContactID) + .Where(Exp.In("id", dublicateContactInfoID)); + Db.ExecuteNonQuery(q); + + + q = Update("crm_contact_info") + .Set("contact_id", toContactID) + .Where("contact_id", fromContactID); + Db.ExecuteNonQuery(q); + + + MergeContactInfo(fromContact, toContact); + + // crm_contact + if ((fromContact is Company) && (toContact is Company)) + { + q = Update("crm_contact") + .Set("company_id", toContactID) + .Where("company_id", fromContactID); + Db.ExecuteNonQuery(q); + } + + q = Delete("crm_contact").Where("id", fromContactID); + Db.ExecuteNonQuery(q); + + tx.Commit(); + } + + CoreContext.AuthorizationManager.RemoveAllAces(fromContact); + } + + public List GetContactIDsByCompanyIds(List companyIDs) + { + return Db.ExecuteList(Query("crm_contact") + .Select("id") + .Distinct() + .Where(Exp.In("company_id", companyIDs) & Exp.Eq("is_company", false))) + .ConvertAll(row => Convert.ToInt32(row[0])); + } + + public List GetContactIDsByContactInfo(ContactInfoType infoType, String data, int? category, bool? isPrimary) + { + List ids; + var q = Query("crm_contact_info") + .Select("contact_id") + .Where(Exp.Eq("type", (int)infoType)); + + if (!string.IsNullOrWhiteSpace(data)) + { + q = q.Where(Exp.Like("data", data, SqlLike.AnyWhere)); + } + + if (category.HasValue) + { + q = q.Where("category", category.Value); + } + if (isPrimary.HasValue) + { + q = q.Where("is_primary", isPrimary.Value); + } + + ids = Db.ExecuteList(q).ConvertAll(row => (int)row[0]); + return ids; + } + + protected static Contact ToContact(object[] row) + { + Contact contact; + + var isCompany = Convert.ToBoolean(row[6]); + + if (isCompany) + contact = new Company + { + CompanyName = Convert.ToString(row[3]) + }; + else + contact = new Person + { + FirstName = Convert.ToString(row[1]), + LastName = Convert.ToString(row[2]), + JobTitle = Convert.ToString(row[4]), + CompanyID = Convert.ToInt32(row[9]) + }; + + contact.ID = Convert.ToInt32(row[0]); + contact.About = Convert.ToString(row[5]); + contact.Industry = Convert.ToString(row[7]); + contact.StatusID = Convert.ToInt32(row[8]); + contact.CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[10])); + contact.CreateBy = ToGuid(row[11]); + contact.ContactTypeID = Convert.ToInt32(row[14]); + contact.Currency = Convert.ToString(row[15]); + + if (row[13] == null) + { + var accessSubjectToContact = CRMSecurity.GetAccessSubjectTo(contact); + + contact.ShareType = !accessSubjectToContact.Any() ? ShareType.ReadWrite : ShareType.None; + } + else + contact.ShareType = (ShareType)(Convert.ToInt32(row[13])); + + return contact; + } + + private static string[] GetContactColumnsTable(String alias) + { + if (!String.IsNullOrEmpty(alias)) + alias = alias + "."; + + var result = new List + { + "id", + "first_name", + "last_name", + "company_name", + "title", + "notes", + "is_company", + "industry", + "status_id", + "company_id", + "create_on", + "create_by", + "display_name", + "is_shared", + "contact_type_id", + "currency" + }; + + return string.IsNullOrEmpty(alias) ? result.ToArray() : result.ConvertAll(item => string.Concat(alias, item)).ToArray(); + } + + private SqlQuery GetContactSqlQuery(Exp where) + { + var sqlQuery = Query("crm_contact").UseIndex("company_id"); + + sqlQuery.Select(GetContactColumnsTable(String.Empty)); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + + } + + + public void ReassignContactsResponsible(Guid fromUserId, Guid toUserId) + { + var ids = CRMSecurity.GetContactsIdByManager(fromUserId).ToList(); + + foreach (var id in ids) + { + var contact = GetByID(id); + + if (contact == null) continue; + + var responsibles = CRMSecurity.GetAccessSubjectGuidsTo(contact); + + if (!responsibles.Any()) continue; + + responsibles.Remove(fromUserId); + responsibles.Add(toUserId); + + CRMSecurity.SetAccessTo(contact, responsibles.Distinct().ToList()); + } + } + + + /// + /// Test method + /// + /// + /// + public void SetContactCreationDate(int contactId, DateTime creationDate) + { + Db.ExecuteNonQuery( + Update("crm_contact") + .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) + .Where(Exp.Eq("id", contactId))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + } + + /// + /// Test method + /// + /// + /// + public void SetContactLastModifedDate(int contactId, DateTime lastModifedDate) + { + Db.ExecuteNonQuery( + Update("crm_contact") + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) + .Where(Exp.Eq("id", contactId))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs new file mode 100644 index 00000000000..6abb2440164 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -0,0 +1,343 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.Collections; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core.Tenants; +using ASC.Common.Data; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.Web.CRM.Core.Search; +using ASC.CRM.Core.Enums; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + public class CachedContactInfo : ContactInfoDao + { + private readonly HttpRequestDictionary _contactInfoCache = new HttpRequestDictionary("crm_contact_info"); + + public CachedContactInfo(int tenantID) + : base(tenantID) + { + + } + + public override ContactInfo GetByID(int id) + { + return _contactInfoCache.Get(id.ToString(), () => GetByIDBase(id)); + } + + public override void Delete(int id) + { + + ResetCache(id); + + base.Delete(id); + } + + private ContactInfo GetByIDBase(int id) + { + return base.GetByID(id); + } + + private void ResetCache(int id) + { + _contactInfoCache.Reset(id.ToString()); + } + + public override void DeleteByContact(int contactID) + { + _contactInfoCache.Clear(); + + base.DeleteByContact(contactID); + } + + public override int Update(ContactInfo contactInfo) + { + ResetCache(contactInfo.ID); + + return base.Update(contactInfo); + } + + } + + public class ContactInfoDao : AbstractDao + { + #region Constructor + + public ContactInfoDao(int tenantID) + : base(tenantID) + { + } + + #endregion + + public virtual ContactInfo GetByID(int id) + { + var sqlResult = Db.ExecuteList(GetSqlQuery(Exp.Eq("id", id))).ConvertAll(row => ToContactInfo(row)); + + if (sqlResult.Count == 0) return null; + + return sqlResult[0]; + } + + public virtual void Delete(int id) + { + Db.ExecuteNonQuery(Delete("crm_contact_info").Where(Exp.Eq("id", id))); + FactoryIndexer.DeleteAsync(r => r.Where(a => a.Id, id)); + } + + public virtual void DeleteByContact(int contactID) + { + if (contactID <= 0) return; + Db.ExecuteNonQuery(Delete("crm_contact_info").Where(Exp.Eq("contact_id", contactID))); + FactoryIndexer.DeleteAsync(r => r.Where(a => a.ContactId, contactID)); + + var infos = GetList(contactID, ContactInfoType.Email, null, null); + FactoryIndexer.Update(new EmailWrapper { Id = contactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); + } + + public virtual int Update(ContactInfo contactInfo) + { + var result = UpdateInDb(contactInfo); + + if (contactInfo.InfoType == ContactInfoType.Email) + { + var infos = GetList(contactInfo.ContactID, ContactInfoType.Email, null, null); + + FactoryIndexer.Update(new EmailWrapper { Id = contactInfo.ContactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); + } + + FactoryIndexer.UpdateAsync(contactInfo); + + return result; + } + + private int UpdateInDb(ContactInfo contactInfo) + { + if (contactInfo == null || contactInfo.ID == 0 || contactInfo.ContactID == 0) + throw new ArgumentException(); + + Db.ExecuteNonQuery(Update("crm_contact_info") + .Where("id", contactInfo.ID) + .Set("data", contactInfo.Data) + .Set("category", contactInfo.Category) + .Set("is_primary", contactInfo.IsPrimary) + .Set("contact_id", contactInfo.ContactID) + .Set("type", (int)contactInfo.InfoType) + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + ); + return contactInfo.ID; + } + + + public int Save(ContactInfo contactInfo) + { + var id = SaveInDb(contactInfo); + + contactInfo.ID = id; + + FactoryIndexer.IndexAsync(contactInfo); + + if (contactInfo.InfoType == ContactInfoType.Email) + { + FactoryIndexer.Index(new EmailWrapper + { + Id = contactInfo.ContactID, + TenantId = TenantID, + EmailInfoWrapper = new List + { + contactInfo + } + }); + } + + return id; + } + + private int SaveInDb(ContactInfo contactInfo) + { + return Db.ExecuteScalar(Insert("crm_contact_info") + .InColumnValue("id", 0) + .InColumnValue("data", contactInfo.Data) + .InColumnValue("category", contactInfo.Category) + .InColumnValue("is_primary", contactInfo.IsPrimary) + .InColumnValue("contact_id", contactInfo.ContactID) + .InColumnValue("type", (int)contactInfo.InfoType) + .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + } + + public List GetListData(int contactID, ContactInfoType infoType) + { + return GetList(contactID, infoType, null, null).ConvertAll(item => item.Data); + } + + public List GetAll() + { + return GetList(0, null, null, null); + } + + public List GetAll(int[] contactID) + { + + if (contactID == null || contactID.Length == 0) return null; + + SqlQuery sqlQuery = GetSqlQuery(null); + + sqlQuery.Where(Exp.In("contact_id", contactID)); + + return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContactInfo(row)); + } + + public virtual List GetList(int contactID, ContactInfoType? infoType, int? categoryID, bool? isPrimary) + { + SqlQuery sqlQuery = GetSqlQuery(null); + + if (contactID > 0) + sqlQuery.Where(Exp.Eq("contact_id", contactID)); + + if (infoType.HasValue) + sqlQuery.Where(Exp.Eq("type", infoType.Value)); + + if (categoryID.HasValue) + sqlQuery.Where(Exp.Eq("category", categoryID.Value)); + + if (isPrimary.HasValue) + sqlQuery.Where(Exp.Eq("is_primary", isPrimary.Value)); + + sqlQuery.OrderBy("type", true); + // sqlQuery.OrderBy("category", true); + // sqlQuery.OrderBy("is_primary", true); + + + return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContactInfo(row)); + } + + + public int[] UpdateList(List items, Contact contact = null) + { + + if (items == null || items.Count == 0) return null; + + var result = new List(); + + using (var tx = Db.BeginTransaction(true)) + { + foreach (var contactInfo in items) + result.Add(UpdateInDb(contactInfo)); + + + tx.Commit(); + } + + if (contact != null) + { + FactoryIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) + { + FactoryIndexer.IndexAsync(item); + } + } + + return result.ToArray(); + } + + + + + public int[] SaveList(List items, Contact contact = null) + { + if (items == null || items.Count == 0) return null; + + var result = new List(); + + using (var tx = Db.BeginTransaction(true)) + { + foreach (var contactInfo in items) + { + var contactInfoId = SaveInDb(contactInfo); + contactInfo.ID = contactInfoId; + result.Add(contactInfoId); + } + + + tx.Commit(); + } + + if (contact != null) + { + FactoryIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) + { + FactoryIndexer.IndexAsync(item); + } + } + + return result.ToArray(); + } + + protected static ContactInfo ToContactInfo(object[] row) + { + return new ContactInfo + { + ID = Convert.ToInt32(row[0]), + Category = Convert.ToInt32(row[1]), + Data = row[2].ToString(), + InfoType = (ContactInfoType)Convert.ToInt32(row[3]), + IsPrimary = Convert.ToBoolean(row[4]), + ContactID = Convert.ToInt32(row[5]) + }; + } + + private SqlQuery GetSqlQuery(Exp where) + { + var sqlQuery = Query("crm_contact_info") + .Select("id", + "category", + "data", + "type", + "is_primary", + "contact_id"); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs new file mode 100644 index 00000000000..92b66e9c583 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -0,0 +1,95 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + public class CurrencyInfoDao : AbstractDao + { + public CurrencyInfoDao(int tenantID) + : base(tenantID) + { + } + + public virtual List GetAll() + { + return Db.ExecuteList(GetSqlQuery(null)).ConvertAll(ToCurrencyInfo); + } + + public virtual CurrencyInfo GetByAbbreviation(string abbreviation) + { + var currencies = Db.ExecuteList(GetSqlQuery(Exp.Eq("abbreviation", abbreviation))).ConvertAll(ToCurrencyInfo); + + return currencies.Count > 0 ? currencies[0] : null; + } + + public List GetBasic() + { + return Db.ExecuteList(GetSqlQuery(Exp.Eq("is_basic", true))).ConvertAll(ToCurrencyInfo); + } + + public List GetOther() + { + return Db.ExecuteList(GetSqlQuery(Exp.Eq("is_basic", false))).ConvertAll(ToCurrencyInfo); + } + + private SqlQuery GetSqlQuery(Exp where) + { + var sqlQuery = new SqlQuery("crm_currency_info") + .Select("resource_key", + "abbreviation", + "symbol", + "culture_name", + "is_convertable", + "is_basic"); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + } + + private static CurrencyInfo ToCurrencyInfo(object[] row) + { + return new CurrencyInfo( + Convert.ToString(row[0]), + Convert.ToString(row[1]), + Convert.ToString(row[2]), + Convert.ToString(row[3]), + Convert.ToBoolean(row[4]), + Convert.ToBoolean(row[5]) + ); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs new file mode 100644 index 00000000000..3d95fcdc38b --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -0,0 +1,168 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + public class CurrencyRateDao : AbstractDao + { + public CurrencyRateDao(int tenantID) + : base(tenantID) + { + } + + public virtual List GetAll() + { + return Db.ExecuteList(GetSqlQuery(null)).ConvertAll(ToCurrencyRate); + } + + public virtual CurrencyRate GetByID(int id) + { + var rates = Db.ExecuteList(GetSqlQuery(Exp.Eq("id", id))).ConvertAll(ToCurrencyRate); + + return rates.Count > 0 ? rates[0] : null; + } + + public CurrencyRate GetByCurrencies(string fromCurrency, string toCurrency) + { + var rates = Db.ExecuteList(GetSqlQuery(Exp.Eq("from_currency", fromCurrency.ToUpper()) & Exp.Eq("to_currency", toCurrency.ToUpper()))) + .ConvertAll(ToCurrencyRate); + + return rates.Count > 0 ? rates[0] : null; + } + + public int SaveOrUpdate(CurrencyRate currencyRate) + { + if (String.IsNullOrEmpty(currencyRate.FromCurrency) || String.IsNullOrEmpty(currencyRate.ToCurrency) || currencyRate.Rate < 0) + throw new ArgumentException(); + + if (currencyRate.ID > 0 && currencyRate.Rate == 0) + return Delete(currencyRate.ID); + + if (Db.ExecuteScalar(Query("crm_currency_rate").SelectCount().Where(Exp.Eq("id", currencyRate.ID))) == 0) + { + var query = Insert("crm_currency_rate") + .InColumnValue("id", 0) + .InColumnValue("from_currency", currencyRate.FromCurrency.ToUpper()) + .InColumnValue("to_currency", currencyRate.ToCurrency.ToUpper()) + .InColumnValue("rate", currencyRate.Rate) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("create_on", DateTime.UtcNow) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", DateTime.UtcNow) + .Identity(1, 0, true); + + currencyRate.ID = Db.ExecuteScalar(query); + } + else + { + Db.ExecuteNonQuery( + Update("crm_currency_rate") + .Set("from_currency", currencyRate.FromCurrency.ToUpper()) + .Set("to_currency", currencyRate.ToCurrency.ToUpper()) + .Set("rate", currencyRate.Rate) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", currencyRate.ID))); + } + + return currencyRate.ID; + } + + public int Delete(int id) + { + if (id <= 0) throw new ArgumentException(); + + var sqlQuery = Delete("crm_currency_rate") + .Where(Exp.Eq("id", id)); + + Db.ExecuteNonQuery(sqlQuery); + + return id; + } + + public List SetCurrencyRates(List rates) + { + using (var tx = Db.BeginTransaction()) + { + Db.ExecuteNonQuery(Delete("crm_currency_rate")); + + foreach (var rate in rates) + { + var query = Insert("crm_currency_rate") + .InColumnValue("id", 0) + .InColumnValue("from_currency", rate.FromCurrency.ToUpper()) + .InColumnValue("to_currency", rate.ToCurrency.ToUpper()) + .InColumnValue("rate", rate.Rate) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("create_on", DateTime.UtcNow) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", DateTime.UtcNow) + .Identity(1, 0, true); + + rate.ID = Db.ExecuteScalar(query); + } + + tx.Commit(); + + return rates; + } + } + + private SqlQuery GetSqlQuery(Exp where) + { + var sqlQuery = Query("crm_currency_rate") + .Select("id", + "from_currency", + "to_currency", + "rate"); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + } + + private static CurrencyRate ToCurrencyRate(object[] row) + { + return new CurrencyRate{ + ID = Convert.ToInt32(row[0]), + FromCurrency = Convert.ToString(row[1]), + ToCurrency = Convert.ToString(row[2]), + Rate = Convert.ToDecimal(row[3]) + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs new file mode 100644 index 00000000000..21b1e4864fd --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -0,0 +1,538 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.Core.Tenants; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.CRM.Core.Entities; +using ASC.Web.CRM.Classes; +using Newtonsoft.Json; +using ASC.Common.Data; +using ASC.Core; +using ASC.ElasticSearch; +using ASC.Web.CRM.Core.Search; +using Newtonsoft.Json.Linq; +using ASC.Web.CRM.Resources; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + public class CustomFieldDao : AbstractDao + { + public CustomFieldDao(int tenantID) + : base(tenantID) + { + + } + + public void SaveList(List items) + { + if (items == null || items.Count == 0) return; + + using (var tx = Db.BeginTransaction(true)) + { + foreach (var customField in items) + { + SetFieldValueInDb(customField.EntityType, customField.EntityID, customField.ID, customField.Value); + } + + tx.Commit(); + } + + } + + public void SetFieldValue(EntityType entityType, int entityID, int fieldID, String fieldValue) + { + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + fieldValue = fieldValue.Trim(); + + SetFieldValueInDb(entityType, entityID, fieldID, fieldValue); + } + + private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, String fieldValue) + { + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + fieldValue = fieldValue.Trim(); + + Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType) & Exp.Eq("field_id", fieldID))); + + if (!String.IsNullOrEmpty(fieldValue)) + { + var lastModifiedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); + var id = Db.ExecuteScalar( + Insert("crm_field_value") + .InColumnValue("id", 0) + .InColumnValue("entity_id", entityID) + .InColumnValue("value", fieldValue) + .InColumnValue("field_id", fieldID) + .InColumnValue("entity_type", (int)entityType) + .InColumnValue("last_modifed_on", lastModifiedOn) + .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true) + ); + + FactoryIndexer.IndexAsync(new FieldsWrapper + { + Id = id, + EntityId = entityID, + EntityType = (int)entityType, + Value = fieldValue, + FieldId = fieldID, + LastModifiedOn = lastModifiedOn, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }); + } + } + + private string GetValidMask(CustomFieldType customFieldType, String mask) + { + var resultMask = new JObject(); + + if (customFieldType == CustomFieldType.CheckBox || customFieldType == CustomFieldType.Heading || customFieldType == CustomFieldType.Date) + return String.Empty; + + if(String.IsNullOrEmpty(mask)) + throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); + + try + { + var maskObj = JToken.Parse(mask); + if (customFieldType == CustomFieldType.TextField) + { + var size = maskObj.Value("size"); + if (size == 0) + { + resultMask.Add("size", 1); + } + else if (size > Global.MaxCustomFieldSize) + { + resultMask.Add("size", Global.MaxCustomFieldSize); + } + else + { + resultMask.Add("size", size); + } + } + if (customFieldType == CustomFieldType.TextArea) + { + var rows = maskObj.Value("rows"); + var cols = maskObj.Value("cols"); + + if (rows == 0) + { + resultMask.Add("rows", 1); + } + else if (rows > Global.MaxCustomFieldRows) + { + resultMask.Add("rows", Global.MaxCustomFieldRows); + } + else + { + resultMask.Add("rows", rows); + } + + if (cols == 0) + { + resultMask.Add("cols", 1); + } + else if (cols > Global.MaxCustomFieldCols) + { + resultMask.Add("cols", Global.MaxCustomFieldCols); + } + else + { + resultMask.Add("cols", cols); + } + } + if (customFieldType == CustomFieldType.SelectBox) + { + if (maskObj is JArray) + { + return mask; + } + else + { + throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); + } + } + } + catch (Exception ex) + { + if (customFieldType == CustomFieldType.TextField) + { + resultMask.Add("size", Global.DefaultCustomFieldSize); + } + if (customFieldType == CustomFieldType.TextArea) + { + resultMask.Add("rows", Global.DefaultCustomFieldRows); + resultMask.Add("cols", Global.DefaultCustomFieldCols); + } + if (customFieldType == CustomFieldType.SelectBox) + { + _log.Error(ex); + throw ex; + } + } + return JsonConvert.SerializeObject(resultMask); + } + + public int CreateField(EntityType entityType, String label, CustomFieldType customFieldType, String mask) + { + if (!_supportedEntityType.Contains(entityType) || String.IsNullOrEmpty(label)) + throw new ArgumentException(); + var resultMask = GetValidMask(customFieldType, mask); + + var sortOrder = Db.ExecuteScalar(Query("crm_field_description").SelectMax("sort_order")) + 1; + + return Db.ExecuteScalar( + Insert("crm_field_description") + .InColumnValue("id", 0) + .InColumnValue("label", label) + .InColumnValue("type", (int)customFieldType) + .InColumnValue("mask", resultMask) + .InColumnValue("sort_order", sortOrder) + .InColumnValue("entity_type", (int)entityType) + .Identity(1, 0, true)); + } + + public String GetValue(EntityType entityType, int entityID, int fieldID) + { + var sqlQuery = Query("crm_field_value") + .Select("value") + .Where(Exp.Eq("field_id", fieldID) + & BuildEntityTypeConditions(entityType, "entity_type") + & Exp.Eq("entity_id", entityID)); + + return Db.ExecuteScalar(sqlQuery); + } + + public List GetEntityIds(EntityType entityType, int fieldID, String fieldValue) + { + var sqlQuery = Query("crm_field_value") + .Select("entity_id") + .Where(Exp.Eq("field_id", fieldID) + & BuildEntityTypeConditions(entityType, "entity_type") + & Exp.Eq("value", fieldValue)); + + return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToInt32(row[0])); + } + + public bool IsExist(int id) + { + return Db.ExecuteScalar("select exists(select 1 from crm_field_description where tenant_id = @tid and id = @id)", + new { tid = TenantID, id = id }); + } + + public int GetFieldId(EntityType entityType, String label, CustomFieldType customFieldType) + { + var result = Db.ExecuteList(GetFieldDescriptionSqlQuery( + Exp.Eq("type", (int)customFieldType) + & BuildEntityTypeConditions(entityType, "entity_type") + & Exp.Eq("label", label))).ConvertAll(row => ToCustomField(row)); + + if (result.Count == 0) return 0; + else return result[0].ID; + } + + public void EditItem(CustomField customField) + { + if (String.IsNullOrEmpty(customField.Label)) + throw new ArgumentException(); + + if (HaveRelativeLink(customField.ID)) + { + try + { + var resultMask = ""; + + var row = Db.ExecuteList(Query("crm_field_description") + .Where(Exp.Eq("id", customField.ID)) + .Select("type", "mask")).FirstOrDefault(); + + var fieldType = (CustomFieldType)Convert.ToInt32(row[0]); + var oldMask = Convert.ToString(row[1]); + + if (fieldType == CustomFieldType.SelectBox) + { + if (oldMask == customField.Mask || customField.Mask == "") + { + resultMask = oldMask; + } + else + { + var maskObjOld = JToken.Parse(oldMask); + var maskObjNew =JToken.Parse(customField.Mask); + + if (!(maskObjOld is JArray && maskObjNew is JArray)) + { + throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); + } + var inm = (((JArray)maskObjNew).ToList()).Intersect(((JArray)maskObjOld).ToList()).ToList(); + if (inm.Count == ((JArray)maskObjOld).ToList().Count) + { + resultMask = customField.Mask; + } + else + { + throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); + } + } + } + else + { + resultMask = GetValidMask(fieldType, customField.Mask); + } + + } + catch (Exception ex) + { + _log.Error(ex); + throw ex; + } + + Db.ExecuteNonQuery( + Update("crm_field_description") + .Set("label", customField.Label) + .Set("mask", customField.Mask) + .Where(Exp.Eq("id", customField.ID))); + } + else + { + var resultMask = GetValidMask(customField.FieldType, customField.Mask); + Db.ExecuteNonQuery( + Update("crm_field_description") + .Set("label", customField.Label) + .Set("type", (int)customField.FieldType) + .Set("mask", resultMask) + .Where(Exp.Eq("id", customField.ID))); + } + } + + public void ReorderFields(int[] fieldID) + { + for (int index = 0; index < fieldID.Length; index++) + Db.ExecuteNonQuery(Update("crm_field_description") + .Set("sort_order", index) + .Where(Exp.Eq("id", fieldID[index]))); + } + + private bool HaveRelativeLink(int fieldID) + { + return + Db.ExecuteScalar( + Query("crm_field_value").Where(Exp.Eq("field_id", fieldID)).SelectCount()) > 0; + } + + public String GetContactLinkCountJSON(EntityType entityType) + { + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + var sqlQuery = Query("crm_field_description tblFD") + .Select("count(tblFV.field_id)") + .LeftOuterJoin("crm_field_value tblFV", Exp.EqColumns("tblFD.id", "tblFV.field_id")) + .OrderBy("tblFD.sort_order", true) + .GroupBy("tblFD.id"); + + sqlQuery.Where(BuildEntityTypeConditions(entityType, "tblFD.entity_type")); + + var queryResult = Db.ExecuteList(sqlQuery); + + return JsonConvert.SerializeObject(queryResult.ConvertAll(row => row[0])); + } + + public int GetContactLinkCount(EntityType entityType, int entityID) + { + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + var sqlQuery = Query("crm_field_description tblFD") + .Select("count(tblFV.field_id)") + .LeftOuterJoin("crm_field_value tblFV", Exp.EqColumns("tblFD.id", "tblFV.field_id")) + .Where(Exp.Eq("tblFD.id", entityID)) + .OrderBy("tblFD.sort_order", true); + + sqlQuery.Where(BuildEntityTypeConditions(entityType, "tblFD.entity_type")); + + return Db.ExecuteScalar(sqlQuery); + } + + public List GetEnityFields(EntityType entityType, int entityID, bool includeEmptyFields) + { + return GetEnityFields(entityType, entityID == 0 ? null : new[] { entityID }, includeEmptyFields); + } + + public List GetEnityFields(EntityType entityType, int[] entityID) + { + return GetEnityFields(entityType, entityID, false); + } + + private List GetEnityFields(EntityType entityType, int[] entityID, bool includeEmptyFields) + { + // TODO: Refactoring Query!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + SqlQuery sqlQuery = Query("crm_field_description tbl_field") + .Select("tbl_field.id", + "tbl_field_value.entity_id", + "tbl_field.label", + "tbl_field_value.value", + "tbl_field.type", + "tbl_field.sort_order", + "tbl_field.mask", + "tbl_field.entity_type"); + + sqlQuery.Where(BuildEntityTypeConditions(entityType, "tbl_field.entity_type")); + + if (entityID != null && entityID.Length > 0) + sqlQuery.LeftOuterJoin("crm_field_value tbl_field_value", + Exp.EqColumns("tbl_field_value.field_id", "tbl_field.id") & + Exp.In("tbl_field_value.entity_id", entityID)) + .OrderBy("tbl_field.sort_order", true); + else + sqlQuery.LeftOuterJoin("crm_field_value tbl_field_value", + Exp.EqColumns("tbl_field_value.field_id", "tbl_field.id")) + .Where(Exp.Eq("tbl_field_value.tenant_id", TenantID)) + .OrderBy("tbl_field_value.entity_id", true) + .OrderBy("tbl_field.sort_order", true); + + if (!includeEmptyFields) + return Db.ExecuteList(sqlQuery) + .ConvertAll(row => ToCustomField(row)).FindAll(item => + { + if (item.FieldType == CustomFieldType.Heading) + return true; + + return !String.IsNullOrEmpty(item.Value.Trim()); + + }).ToList(); + + return Db.ExecuteList(sqlQuery) + .ConvertAll(row => ToCustomField(row)); + } + + public CustomField GetFieldDescription(int fieldID) + { + + var sqlQuery = GetFieldDescriptionSqlQuery(null); + + sqlQuery.Where(Exp.Eq("id", fieldID)); + + var fields = Db.ExecuteList(sqlQuery).ConvertAll(row => ToCustomField(row)); + + return fields.Count == 0 ? null : fields[0]; + } + + public List GetFieldsDescription(EntityType entityType) + { + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + SqlQuery sqlQuery = GetFieldDescriptionSqlQuery(null); + + sqlQuery.Where(BuildEntityTypeConditions(entityType, "entity_type")); + + return Db.ExecuteList(sqlQuery) + .ConvertAll(row => ToCustomField(row)); + } + + private SqlQuery GetFieldDescriptionSqlQuery(Exp where) + { + var sqlQuery = Query("crm_field_description") + .Select("id", + "-1", + "label", + "\" \"", + "type", + "sort_order", + "mask", + "entity_type") + .OrderBy("sort_order", true); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + } + + private Exp BuildEntityTypeConditions(EntityType entityType, String dbFieldName) + { + switch (entityType) + { + case EntityType.Company: + case EntityType.Person: + return Exp.In(dbFieldName, new[] { (int)entityType, (int)EntityType.Contact }); + + default: + return Exp.Eq(dbFieldName, (int)entityType); + + } + + } + + public void DeleteField(int fieldID) + { + //if (HaveRelativeLink(fieldID)) + // throw new ArgumentException(); + + using (var tx = Db.BeginTransaction()) + { + Db.ExecuteNonQuery(Delete("crm_field_description").Where(Exp.Eq("id", fieldID))); + Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.Eq("field_id", fieldID))); + + tx.Commit(); + } + } + + public static CustomField ToCustomField(object[] row) + { + return new CustomField + { + ID = Convert.ToInt32(row[0]), + EntityID = Convert.ToInt32(row[1]), + EntityType = (EntityType)Convert.ToInt32(row[7]), + Label = Convert.ToString(row[2]), + Value = Convert.ToString(row[3]), + FieldType = (CustomFieldType)Convert.ToInt32(row[4]), + Position = Convert.ToInt32(row[5]), + Mask = Convert.ToString(row[6]) + }; + } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs new file mode 100644 index 00000000000..7d62d5e84d8 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -0,0 +1,169 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.VoipService.Dao; +using Autofac; + +namespace ASC.CRM.Core.Dao +{ + public class DaoFactory + { + private readonly TypedParameter tenant; + public ILifetimeScope Container { get; set; } + + #region Constructor + + public DaoFactory(int tenantID) + { + tenant = GetParameter(tenantID); + } + + #endregion + + #region Methods + + public TaskDao TaskDao + { + get { return Container.Resolve(tenant); } + } + + public ListItemDao CachedListItem + { + get { return Container.Resolve(tenant); } + } + + public ContactDao ContactDao + { + get { return Container.Resolve(tenant); } + } + + public CustomFieldDao CustomFieldDao + { + get { return Container.Resolve(tenant); } + } + + public DealDao DealDao + { + get { return Container.Resolve(tenant); } + } + + public DealMilestoneDao DealMilestoneDao + { + get { return Container.Resolve(tenant); } + } + + public ListItemDao ListItemDao + { + get { return Container.Resolve(tenant); } + } + + public TagDao TagDao + { + get { return Container.Resolve(tenant); } + } + + public SearchDao SearchDao + { + get { return Container.Resolve(tenant, GetParameter(this)); } + } + + public RelationshipEventDao RelationshipEventDao + { + get { return Container.Resolve(tenant); } + } + + public FileDao FileDao + { + get { return Container.Resolve(tenant); } + } + + public CasesDao CasesDao + { + get { return Container.Resolve(tenant); } + } + + public TaskTemplateContainerDao TaskTemplateContainerDao + { + get { return Container.Resolve(tenant); } + } + + public TaskTemplateDao TaskTemplateDao + { + get { return Container.Resolve(tenant); } + } + + public ReportDao ReportDao + { + get { return Container.Resolve(tenant); } + } + + public CurrencyRateDao CurrencyRateDao + { + get { return Container.Resolve(tenant); } + } + + public CurrencyInfoDao CurrencyInfoDao + { + get { return Container.Resolve(tenant); } + } + + public ContactInfoDao ContactInfoDao + { + get { return Container.Resolve(tenant); } + } + + public InvoiceDao InvoiceDao + { + get { return Container.Resolve(tenant); } + } + + public InvoiceItemDao InvoiceItemDao + { + get { return Container.Resolve(tenant); } + } + + public InvoiceTaxDao InvoiceTaxDao + { + get { return Container.Resolve(tenant); } + } + + public InvoiceLineDao InvoiceLineDao + { + get { return Container.Resolve(tenant); } + } + + public VoipDao VoipDao + { + get { return Container.Resolve(tenant); } + } + + private TypedParameter GetParameter(T data) + { + return new TypedParameter(typeof(T), data); + } + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs new file mode 100644 index 00000000000..f3a91467a1f --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -0,0 +1,896 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using System.Globalization; + +using ASC.Collections; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.Files.Core; +using ASC.Web.Files.Api; +using ASC.Web.CRM.Core.Search; +using OrderBy = ASC.CRM.Core.Entities.OrderBy; +using ASC.CRM.Core.Enums; + +namespace ASC.CRM.Core.Dao +{ + public class CachedDealDao : DealDao + { + private readonly HttpRequestDictionary _dealCache = new HttpRequestDictionary("crm_deal"); + + public CachedDealDao(int tenantID) + : base(tenantID) + { + } + + public override void EditDeal(Deal deal) + { + ResetCache(deal.ID); + base.EditDeal(deal); + } + + public override Deal GetByID(int dealID) + { + return _dealCache.Get(dealID.ToString(), () => GetByIDBase(dealID)); + } + + private Deal GetByIDBase(int dealID) + { + return base.GetByID(dealID); + } + + public override Deal DeleteDeal(int dealID) + { + ResetCache(dealID); + return base.DeleteDeal(dealID); + } + + public override int CreateNewDeal(Deal deal) + { + deal.ID = base.CreateNewDeal(deal); + _dealCache.Add(deal.ID.ToString(), deal); + return deal.ID; + } + + private void ResetCache(int dealID) + { + _dealCache.Reset(dealID.ToString()); + } + } + + public class DealDao : AbstractDao + { + #region Constructor + + public DealDao(int tenantID) + : base(tenantID) + { + } + + #endregion + + #region Methods + + public void AddMember(int dealID, int memberID) + { + SetRelative(memberID, EntityType.Opportunity, dealID); + } + + public Dictionary GetMembers(int[] dealID) + { + return GetRelativeToEntity(null, EntityType.Opportunity, dealID); + } + + public int[] GetMembers(int dealID) + { + return GetRelativeToEntity(null, EntityType.Opportunity, dealID); + } + + public void SetMembers(int dealID, int[] memberID) + { + SetRelative(memberID, EntityType.Opportunity, dealID); + } + + public void RemoveMember(int dealID, int memberID) + { + RemoveRelative(memberID, EntityType.Opportunity, dealID); + } + + public virtual List GetDeals(int[] id) + { + if (id == null || !id.Any()) return new List(); + + return Db.ExecuteList(GetDealSqlQuery(Exp.In("tblDeal.id", id))) + .ConvertAll(ToDeal).FindAll(CRMSecurity.CanAccessTo).ToList(); + } + + public virtual Deal GetByID(int dealID) + { + if (dealID <= 0) return null; + + var deals = GetDeals(new[] { dealID }); + + return deals.Count == 0 ? null : deals[0]; + } + + public virtual int CreateNewDeal(Deal deal) + { + var result = CreateNewDealInDb(deal); + + deal.ID = result; + + FactoryIndexer.IndexAsync(deal); + + return result; + } + + private int CreateNewDealInDb(Deal deal) + { + if (String.IsNullOrEmpty(deal.Title) || deal.ResponsibleID == Guid.Empty || deal.DealMilestoneID <= 0) + throw new ArgumentException(); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + + + var dealID = Db.ExecuteScalar( + Insert("crm_deal") + .InColumnValue("id", 0) + .InColumnValue("title", deal.Title) + .InColumnValue("description", deal.Description) + .InColumnValue("responsible_id", deal.ResponsibleID) + .InColumnValue("contact_id", deal.ContactID) + .InColumnValue("bid_currency", deal.BidCurrency) + .InColumnValue("bid_value", deal.BidValue) + .InColumnValue("bid_type", deal.BidType) + .InColumnValue("deal_milestone_id", deal.DealMilestoneID) + .InColumnValue("deal_milestone_probability", deal.DealMilestoneProbability) + .InColumnValue("expected_close_date", TenantUtil.DateTimeToUtc(deal.ExpectedCloseDate)) + .InColumnValue("actual_close_date", TenantUtil.DateTimeToUtc(deal.ActualCloseDate)) + .InColumnValue("per_period_value", deal.PerPeriodValue) + .InColumnValue("create_on", TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn)) + .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn)) + .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + + // if (deal.ContactID > 0) + // AddMember(dealID, deal.ContactID); + + return dealID; + } + + public virtual int[] SaveDealList(List items) + { + using (var tx = Db.BeginTransaction()) + { + var result = items.Select(item => CreateNewDealInDb(item)).ToArray(); + tx.Commit(); + foreach (var item in items) + { + FactoryIndexer.IndexAsync(item); + } + return result; + } + } + + public virtual void EditDeal(Deal deal) + { + CRMSecurity.DemandEdit(deal); + + // var oldDeal = GetByID(deal.ID); + + // if (oldDeal.ContactID > 0) + // RemoveMember(oldDeal.ID, oldDeal.ContactID); + + // AddMember(deal.ID, deal.ContactID); + + Db.ExecuteNonQuery( + Update("crm_deal") + .Set("title", deal.Title) + .Set("description", deal.Description) + .Set("responsible_id", deal.ResponsibleID) + .Set("contact_id", deal.ContactID) + .Set("bid_currency", deal.BidCurrency) + .Set("bid_value", deal.BidValue) + .Set("bid_type", deal.BidType) + .Set("deal_milestone_id", deal.DealMilestoneID) + .Set("deal_milestone_probability", deal.DealMilestoneProbability) + .Set("expected_close_date", TenantUtil.DateTimeToUtc(deal.ExpectedCloseDate)) + .Set("per_period_value", deal.PerPeriodValue) + .Set("actual_close_date", TenantUtil.DateTimeToUtc(deal.ActualCloseDate)) + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", deal.ID)) + ); + + FactoryIndexer.IndexAsync(deal); + } + + + public int GetDealsCount() + { + return GetDealsCount(String.Empty, Guid.Empty, 0, null, 0, null, null, DateTime.MinValue, DateTime.MinValue); + } + + public List GetAllDeals() + { + return GetDeals(String.Empty, + Guid.Empty, + 0, + null, + 0, + null, + null, + DateTime.MinValue, + DateTime.MinValue, + 0, + 0, + new OrderBy(DealSortedByType.Stage, true)); + } + + private Exp WhereConditional( + ICollection exceptIDs, + String searchText, + Guid responsibleID, + int milestoneID, + IEnumerable tags, + int contactID, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant) + { + var conditions = new List(); + + var ids = new List(); + + if (!String.IsNullOrEmpty(searchText)) + { + searchText = searchText.Trim(); + + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); + + if (keywords.Length > 0) + { + if (!BundleSearch.TrySelectOpportunity(searchText, out ids)) + { + conditions.Add(BuildLike(new[] {"tblDeal.title", "tblDeal.description"}, keywords)); + } + else if (ids.Count == 0) return null; + } + + } + + if (tags != null && tags.Any()) + { + ids = SearchByTags(EntityType.Opportunity, ids.ToArray(), tags); + + if (ids.Count == 0) return null; + } + + if (contactID > 0) + { + if (contactAlsoIsParticipant.HasValue && contactAlsoIsParticipant.Value) + { + var relativeContactsID = GetRelativeToEntity(contactID, EntityType.Opportunity, null).ToList(); + + if (relativeContactsID.Count == 0) + { + conditions.Add(Exp.Eq("tblDeal.contact_id", contactID)); + } + else + { + if (ids.Count > 0) + { + ids = relativeContactsID.Intersect(ids).ToList(); + + if (ids.Count == 0) return null; + } + else + { + ids = relativeContactsID; + } + } + } + else + { + conditions.Add(Exp.Eq("tblDeal.contact_id", contactID)); + } + } + + if (0 < milestoneID && milestoneID < int.MaxValue) + { + conditions.Add(Exp.Eq("tblDeal.deal_milestone_id", milestoneID)); + } + + if (responsibleID != Guid.Empty) + { + conditions.Add(Exp.Eq("tblDeal.responsible_id", responsibleID)); + } + + if (stageType != null) + { + conditions.Add(Exp.Eq("tblDM.status", (int)stageType.Value)); + } + + if (ids.Count > 0) + { + if (exceptIDs.Count > 0) + { + ids = ids.Except(exceptIDs).ToList(); + if (ids.Count == 0) return null; + } + + conditions.Add(Exp.In("tblDeal.id", ids)); + } + else if (exceptIDs.Count > 0) + { + conditions.Add(!Exp.In("tblDeal.id", exceptIDs.ToArray())); + } + + if (conditions.Count == 0) return null; + + return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + } + + public int GetDealsCount(String searchText, + Guid responsibleID, + int milestoneID, + IEnumerable tags, + int contactID, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + DateTime fromDate, + DateTime toDate) + { + var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + + "deals" + + SecurityContext.CurrentAccount.ID.ToString() + + searchText + + responsibleID + + milestoneID + + contactID; + + if (tags != null) + cacheKey += String.Join("", tags.ToArray()); + + if (stageType.HasValue) + cacheKey += stageType.Value; + + if (contactAlsoIsParticipant.HasValue) + cacheKey += contactAlsoIsParticipant.Value; + + if (fromDate != DateTime.MinValue) + cacheKey += fromDate.ToString(); + + if (toDate != DateTime.MinValue) + cacheKey += toDate.ToString(); + + var fromCache = _cache.Get(cacheKey); + + if (fromCache != null) return Convert.ToInt32(fromCache); + + var withParams = !(String.IsNullOrEmpty(searchText) && + responsibleID == Guid.Empty && + milestoneID <= 0 && + (tags == null || !tags.Any()) && + contactID <= 0 && + stageType == null && + contactAlsoIsParticipant == null && + fromDate == DateTime.MinValue && + toDate == DateTime.MinValue); + + ICollection exceptIDs = CRMSecurity.GetPrivateItems(typeof(Deal)).ToList(); + + int result; + + if (withParams) + { + var whereConditional = WhereConditional(exceptIDs, searchText, responsibleID, milestoneID, tags, + contactID, stageType, contactAlsoIsParticipant); + + + var sqlQuery = GetDealSqlQuery(whereConditional); + + if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) + { + sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + + result = Db.ExecuteList(sqlQuery).Count; + + } + else if (whereConditional == null) + { + result = 0; + } + else + { + result = Db.ExecuteList(sqlQuery).Count; + } + + } + else + { + + var countWithoutPrivate = Db.ExecuteScalar(Query("crm_deal").SelectCount()); + var privateCount = exceptIDs.Count; + + if (privateCount > countWithoutPrivate) + { + _log.Error("Private deals count more than all deals"); + + privateCount = 0; + } + + result = countWithoutPrivate - privateCount; + } + if (result > 0) + { + _cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30)); + } + return result; + + } + + public List GetDeals( + String searchText, + Guid responsibleID, + int milestoneID, + IEnumerable tags, + int contactID, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + DateTime fromDate, + DateTime toDate, + int from, + int count, + OrderBy orderBy) + { + + if (CRMSecurity.IsAdmin) + return GetCrudeDeals(searchText, + responsibleID, + milestoneID, + tags, + contactID, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate, + from, + count, + orderBy); + + var crudeDeals = GetCrudeDeals(searchText, + responsibleID, + milestoneID, + tags, + contactID, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate, + 0, + from + count, + orderBy); + + if (crudeDeals.Count == 0) return crudeDeals; + + if (crudeDeals.Count < from + count) return crudeDeals.FindAll(CRMSecurity.CanAccessTo).Skip(from).ToList(); + + var result = crudeDeals.FindAll(CRMSecurity.CanAccessTo); + + if (result.Count == crudeDeals.Count) return result.Skip(from).ToList(); + + var localCount = count; + var localFrom = from + count; + + while (true) + { + crudeDeals = GetCrudeDeals(searchText, + responsibleID, + milestoneID, + tags, + contactID, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate, + localFrom, + localCount, + orderBy); + + if (crudeDeals.Count == 0) break; + + result.AddRange(crudeDeals.Where(CRMSecurity.CanAccessTo)); + + if ((result.Count >= count + from) || (crudeDeals.Count < localCount)) break; + + localFrom += localCount; + localCount = localCount * 2; + } + + return result.Skip(from).Take(count).ToList(); + } + + + private List GetCrudeDeals( + String searchText, + Guid responsibleID, + int milestoneID, + IEnumerable tags, + int contactID, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + DateTime fromDate, + DateTime toDate, + int from, + int count, + OrderBy orderBy) + { + var sqlQuery = GetDealSqlQuery(null); + + var withParams = !(String.IsNullOrEmpty(searchText) && + responsibleID == Guid.Empty && + milestoneID <= 0 && + (tags == null || !tags.Any()) && + contactID <= 0 && + stageType == null && + contactAlsoIsParticipant == null && + fromDate == DateTime.MinValue && + toDate == DateTime.MinValue); + + var whereConditional = WhereConditional(new List(), + searchText, + responsibleID, + milestoneID, + tags, + contactID, + stageType, + contactAlsoIsParticipant); + + + + if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) + sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + else if (withParams && whereConditional == null) + return new List(); + + sqlQuery.Where(whereConditional); + + if (0 < from && from < int.MaxValue) + sqlQuery.SetFirstResult(from); + + if (0 < count && count < int.MaxValue) + sqlQuery.SetMaxResults(count); + + if (orderBy != null && Enum.IsDefined(typeof(DealSortedByType), orderBy.SortedBy)) + switch ((DealSortedByType)orderBy.SortedBy) + { + case DealSortedByType.Title: + sqlQuery.OrderBy("tblDeal.title", orderBy.IsAsc); + break; + case DealSortedByType.BidValue: + sqlQuery.OrderBy("tblDeal.bid_value", orderBy.IsAsc); + break; + case DealSortedByType.Responsible: + + sqlQuery.OrderBy("tblDeal.responsible_id", orderBy.IsAsc) + .OrderBy("tblDM.sort_order", orderBy.IsAsc) + .OrderBy("tblDeal.contact_id", true) + .OrderBy("tblDeal.actual_close_date", false) + .OrderBy("tblDeal.expected_close_date", true) + .OrderBy("tblDeal.title", true); + + break; + case DealSortedByType.Stage: + sqlQuery.OrderBy("tblDM.sort_order", orderBy.IsAsc) + .OrderBy("tblDeal.contact_id", true) + .OrderBy("tblDeal.actual_close_date", false) + .OrderBy("tblDeal.expected_close_date", true) + .OrderBy("tblDeal.title", true); + break; + case DealSortedByType.DateAndTime: + sqlQuery.OrderBy("close_date", orderBy.IsAsc); + break; + default: + throw new ArgumentException(); + } + else + sqlQuery.OrderBy("tblDM.sort_order", true) + .OrderBy("tblDeal.contact_id", true) + .OrderBy("tblDeal.title", true); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToDeal); + } + + public List GetDealsByContactID(int contactID) + { + + return GetDeals(String.Empty, Guid.Empty, 0, null, contactID, null, true, DateTime.MinValue, + DateTime.MinValue, 0, 0, new OrderBy(DealSortedByType.Title, true)); + + } + + public List GetDealsByPrefix(String prefix, int from, int count, int contactId = 0, bool internalSearch = true) + { + if (count == 0) + throw new ArgumentException(); + + prefix = prefix.Trim(); + + var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); + + var q = GetDealSqlQuery(null); + + if (keywords.Length == 1) + { + q.Where(Exp.Like("tblDeal.title", keywords[0])); + } + else + { + foreach (var k in keywords) + { + q.Where(Exp.Like("tblDeal.title", k)); + } + } + + if (0 < from && from < int.MaxValue) q.SetFirstResult(from); + if (0 < count && count < int.MaxValue) q.SetMaxResults(count); + + if (contactId > 0) + { + var ids = GetRelativeToEntity(contactId, EntityType.Opportunity, null); + + if (internalSearch) + q.Where(Exp.Eq("tblDeal.contact_id", contactId) | Exp.In("tblDeal.id", ids)); + else + q.Where(!Exp.Eq("tblDeal.contact_id", contactId) & !Exp.In("tblDeal.id", ids)); + } + + var sqlResult = Db.ExecuteList(q).ConvertAll(ToDeal).FindAll(CRMSecurity.CanAccessTo); + + return sqlResult.OrderBy(deal => deal.Title).ToList(); + } + + public virtual Deal DeleteDeal(int dealID) + { + if (dealID <= 0) return null; + + var deal = GetByID(dealID); + if (deal == null) return null; + + CRMSecurity.DemandDelete(deal); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + + DeleteBatchDealsExecute(new List() { deal }); + + FactoryIndexer.DeleteAsync(deal); + + return deal; + } + + public List DeleteBatchDeals(int[] dealID) + { + var deals = GetDeals(dealID).FindAll(CRMSecurity.CanDelete).ToList(); + if (!deals.Any()) return deals; + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + + DeleteBatchDealsExecute(deals); + return deals; + } + + public List DeleteBatchDeals(List deals) + { + deals = deals.FindAll(CRMSecurity.CanDelete).ToList(); + if (!deals.Any()) return deals; + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + + DeleteBatchDealsExecute(deals); + return deals; + } + + private void DeleteBatchDealsExecute(List deals) + { + if (deals == null || !deals.Any()) return; + + var dealID = deals.Select(x => x.ID).ToArray(); + object[] filesIDs; + + using (var tagdao = FilesIntegration.GetTagDao()) + { + var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id") + .Where(Exp.Eq("have_files", true) & Exp.In("entity_id", dealID) & Exp.Eq("entity_type", (int)EntityType.Opportunity))) + .Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); + filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + + using (var tx = Db.BeginTransaction(true)) + { + + Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", (int)EntityType.Opportunity))); + Db.ExecuteNonQuery(new SqlDelete("crm_entity_contact").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); + Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); + Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); + Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); + Db.ExecuteNonQuery(Delete("crm_deal").Where(Exp.In("id", dealID))); + + tx.Commit(); + } + + deals.ForEach(deal => CoreContext.AuthorizationManager.RemoveAllAces(deal)); + } + + using (var filedao = FilesIntegration.GetFileDao()) + { + foreach (var filesID in filesIDs) + { + filedao.DeleteFile(filesID); + } + } + } + + #region Private Methods + + private static Deal ToDeal(object[] row) + { + return new Deal + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + Description = Convert.ToString(row[2]), + ResponsibleID = ToGuid(row[3]), + ContactID = Convert.ToInt32(row[4]), + BidCurrency = Convert.ToString(row[5]), + BidValue = Convert.ToDecimal(row[6]), + BidType = (BidType)Convert.ToInt32(row[7]), + DealMilestoneID = Convert.ToInt32(row[8]), + ExpectedCloseDate = Convert.ToDateTime(row[9]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[9])), + PerPeriodValue = Convert.ToInt32(row[10]), + DealMilestoneProbability = Convert.ToInt32(row[11]), + CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[12])), + CreateBy = ToGuid(row[13]), + ActualCloseDate = Convert.ToDateTime(row[14]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[14])) + }; + } + + private SqlQuery GetDealSqlQuery(Exp where) + { + + SqlQuery sqlQuery = Query("crm_deal tblDeal") + .Select( + "tblDeal.id", + "tblDeal.title", + "tblDeal.description", + "tblDeal.responsible_id", + "tblDeal.contact_id", + "tblDeal.bid_currency", + "tblDeal.bid_value", + "tblDeal.bid_type", + "tblDeal.deal_milestone_id", + "tblDeal.expected_close_date", + "tblDeal.per_period_value", + "tblDeal.deal_milestone_probability", + "tblDeal.create_on", + "tblDeal.create_by", + "tblDeal.actual_close_date" + ) + .Select(@"case tblDM.status + when 0 + then tblDeal.expected_close_date + else + tblDeal.actual_close_date + end as close_date") + .LeftOuterJoin("crm_deal_milestone tblDM", + Exp.EqColumns("tblDeal.deal_milestone_id", "tblDM.id")); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + } + + #endregion + + + public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) + { + var deals = GetDeals(String.Empty, + fromUserId, + 0, + null, + 0, + DealMilestoneStatus.Open, + null, + DateTime.MinValue, + DateTime.MinValue, + 0, + 0, + null); + + foreach (var deal in deals) + { + deal.ResponsibleID = toUserId; + + EditDeal(deal); + + var responsibles = CRMSecurity.GetAccessSubjectGuidsTo(deal); + + if (!responsibles.Any()) continue; + + responsibles.Remove(fromUserId); + responsibles.Add(toUserId); + + CRMSecurity.SetAccessTo(deal, responsibles.Distinct().ToList()); + } + } + + #endregion + + + /// + /// Test method + /// + /// + /// + public void SetDealCreationDate(int opportunityid, DateTime creationDate) + { + Db.ExecuteNonQuery( + Update("crm_deal") + .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) + .Where(Exp.Eq("id", opportunityid))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + } + + /// + /// Test method + /// + /// + /// + public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) + { + Db.ExecuteNonQuery( + Update("crm_deal") + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) + .Where(Exp.Eq("id", opportunityid))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs new file mode 100644 index 00000000000..ddc6eb84f5f --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -0,0 +1,289 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.Collections; +using ASC.CRM.Core.Entities; +using System; +using System.Collections.Generic; +using System.Linq; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + public class CachedDealMilestoneDao : DealMilestoneDao + { + private readonly HttpRequestDictionary _dealMilestoneCache = + new HttpRequestDictionary("crm_deal_milestone"); + + public CachedDealMilestoneDao(int tenantID) + : base(tenantID) + { + + } + + private void ResetCache(int id) + { + _dealMilestoneCache.Reset(id.ToString()); + } + + public override int Create(DealMilestone item) + { + item.ID = base.Create(item); + + _dealMilestoneCache.Add(item.ID.ToString(), item); + + return item.ID; + } + + public override void Delete(int id) + { + ResetCache(id); + + base.Delete(id); + } + + public override void Edit(DealMilestone item) + { + ResetCache(item.ID); + + base.Edit(item); + } + + + private DealMilestone GetByIDBase(int id) + { + return base.GetByID(id); + } + + public override DealMilestone GetByID(int id) + { + return _dealMilestoneCache.Get(id.ToString(), () => GetByIDBase(id)); + } + + public override void Reorder(int[] ids) + { + _dealMilestoneCache.Clear(); + + base.Reorder(ids); + } + } + + public class DealMilestoneDao : AbstractDao + { + + #region Constructor + + public DealMilestoneDao(int tenantID) + : base(tenantID) + { + + + } + + #endregion + + public virtual void Reorder(int[] ids) + { + using (var tx = Db.BeginTransaction()) + { + for (int index = 0; index < ids.Length; index++) + Db.ExecuteNonQuery(Update("crm_deal_milestone") + .Set("sort_order", index) + .Where(Exp.Eq("id", ids[index]))); + + tx.Commit(); + } + } + + public int GetCount() + { + return Db.ExecuteScalar(Query("crm_deal_milestone").SelectCount()); + } + + + public Dictionary GetRelativeItemsCount() + { + var sqlQuery = Query("crm_deal_milestone tbl_deal_milestone") + .Select("tbl_deal_milestone.id") + .OrderBy("tbl_deal_milestone.sort_order", true) + .GroupBy("tbl_deal_milestone.id"); + + sqlQuery.LeftOuterJoin("crm_deal tbl_crm_deal", + Exp.EqColumns("tbl_deal_milestone.id", "tbl_crm_deal.deal_milestone_id")) + .Select("count(tbl_crm_deal.deal_milestone_id)"); + + var queryResult = Db.ExecuteList(sqlQuery); + return queryResult.ToDictionary(x => Convert.ToInt32(x[0]), y => Convert.ToInt32(y[1])); + } + + public int GetRelativeItemsCount(int id) + { + + var sqlQuery = Query("crm_deal") + .Select("count(*)") + .Where(Exp.Eq("deal_milestone_id", id)); + + return Db.ExecuteScalar(sqlQuery); + } + + public virtual int Create(DealMilestone item) + { + + if (String.IsNullOrEmpty(item.Title) || String.IsNullOrEmpty(item.Color)) + throw new ArgumentException(); + + int id; + + using (var tx = Db.BeginTransaction()) + { + if (item.SortOrder == 0) + item.SortOrder = Db.ExecuteScalar(Query("crm_deal_milestone") + .SelectMax("sort_order")) + 1; + + id = Db.ExecuteScalar( + Insert("crm_deal_milestone") + .InColumnValue("id", 0) + .InColumnValue("title", item.Title) + .InColumnValue("description", item.Description) + .InColumnValue("color", item.Color) + .InColumnValue("probability", item.Probability) + .InColumnValue("status", (int)item.Status) + .InColumnValue("sort_order", item.SortOrder) + .Identity(1, 0, true)); + tx.Commit(); + } + + return id; + + } + + + public virtual void ChangeColor(int id, String newColor) + { + Db.ExecuteNonQuery(Update("crm_deal_milestone") + .Set("color", newColor) + .Where(Exp.Eq("id", id))); + } + + public virtual void Edit(DealMilestone item) + { + + if (HaveContactLink(item.ID)) + throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.DealMilestoneHasRelatedDeals)); + + Db.ExecuteNonQuery(Update("crm_deal_milestone") + .Set("title", item.Title) + .Set("description", item.Description) + .Set("color", item.Color) + .Set("probability", item.Probability) + .Set("status", (int)item.Status) + .Where(Exp.Eq("id", item.ID))); + } + + public bool HaveContactLink(int dealMilestoneID) + { + SqlQuery sqlQuery = Query("crm_deal") + .Where(Exp.Eq("deal_milestone_id", dealMilestoneID)) + .SelectCount() + .SetMaxResults(1); + + return Db.ExecuteScalar(sqlQuery) >= 1; + } + + public virtual void Delete(int id) + { + if (HaveContactLink(id)) + throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.DealMilestoneHasRelatedDeals)); + + Db.ExecuteNonQuery(Delete("crm_deal_milestone").Where(Exp.Eq("id", id))); + } + + public virtual DealMilestone GetByID(int id) + { + var dealMilestones = Db.ExecuteList(GetDealMilestoneQuery(Exp.Eq("id", id))).ConvertAll(row => ToDealMilestone(row)); + + if (dealMilestones.Count == 0) + return null; + + return dealMilestones[0]; + } + + public Boolean IsExist(int id) + { + return Db.ExecuteScalar("select exists(select 1 from crm_deal_milestone where tenant_id = @tid and id = @id)", + new { tid = TenantID, id = id }); + } + + public List GetAll(int[] id) + { + return Db.ExecuteList(GetDealMilestoneQuery(Exp.In("id", id))).ConvertAll(row => ToDealMilestone(row)); + } + + public List GetAll() + { + return Db.ExecuteList(GetDealMilestoneQuery(null)).ConvertAll(row => ToDealMilestone(row)); + } + + private SqlQuery GetDealMilestoneQuery(Exp where) + { + SqlQuery sqlQuery = Query("crm_deal_milestone") + .Select("id", + "title", + "description", + "color", + "probability", + "status", + "sort_order") + .OrderBy("sort_order", true); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + + } + + private static DealMilestone ToDealMilestone(object[] row) + { + return new DealMilestone + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + Description = Convert.ToString(row[2]), + Color = Convert.ToString(row[3]), + Probability = Convert.ToInt32(row[4]), + Status = (DealMilestoneStatus)Convert.ToInt32(row[5]), + SortOrder = Convert.ToInt32(row[6]) + }; + } + + + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs new file mode 100644 index 00000000000..bfadba290fd --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -0,0 +1,91 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.Core; +using ASC.Files.Core; +using ASC.Web.Files.Api; + +namespace ASC.CRM.Core.Dao +{ + public class FileDao : AbstractDao + { + public FileDao(int tenantID) + : base(tenantID) + { + } + + #region Public Methods + + public File GetFile(int id, int version) + { + using (var dao = FilesIntegration.GetFileDao()) + { + var file = 0 < version ? dao.GetFile(id, version) : dao.GetFile(id); + return file; + } + } + + public void DeleteFile(int id) + { + using (var dao = FilesIntegration.GetFileDao()) + { + dao.DeleteFile(id); + } + } + + public object GetRoot() + { + return FilesIntegration.RegisterBunch("crm", "crm_common", ""); + } + + public object GetMy() + { + return FilesIntegration.RegisterBunch("files", "my", SecurityContext.CurrentAccount.ID.ToString()); + } + + public File SaveFile(File file, System.IO.Stream stream) + { + using (var dao = FilesIntegration.GetFileDao()) + { + return dao.SaveFile(file, stream); + } + } + + public List GetEventsByFile(int id) + { + using (var tagdao = FilesIntegration.GetTagDao()) + { + var tags = tagdao.GetTags(id, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); + return tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs new file mode 100644 index 00000000000..7891531ed03 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -0,0 +1,940 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; +using ASC.Collections; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Core.Search; +using Newtonsoft.Json; +using SecurityContext = ASC.Core.SecurityContext; + +namespace ASC.CRM.Core.Dao +{ + public class CachedInvoiceDao : InvoiceDao + { + private readonly HttpRequestDictionary _invoiceCache = new HttpRequestDictionary("crm_invoice"); + + public CachedInvoiceDao(int tenantID) + : base(tenantID) + { + } + + public override Invoice GetByID(int invoiceID) + { + return _invoiceCache.Get(invoiceID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceID)); + } + + private Invoice GetByIDBase(int invoiceID) + { + return base.GetByID(invoiceID); + } + + public override int SaveOrUpdateInvoice(Invoice invoice) + { + if (invoice != null && invoice.ID > 0) + ResetCache(invoice.ID); + + return base.SaveOrUpdateInvoice(invoice); + } + + public override Invoice DeleteInvoice(int invoiceID) + { + ResetCache(invoiceID); + + return base.DeleteInvoice(invoiceID); + } + + private void ResetCache(int invoiceID) + { + _invoiceCache.Reset(invoiceID.ToString(CultureInfo.InvariantCulture)); + } + } + + public class InvoiceDao : AbstractDao + { + public List> invoiceStatusMap = new List>() + { + new KeyValuePair(InvoiceStatus.Draft, InvoiceStatus.Sent), + new KeyValuePair(InvoiceStatus.Sent, InvoiceStatus.Paid), + new KeyValuePair(InvoiceStatus.Sent, InvoiceStatus.Rejected), + new KeyValuePair(InvoiceStatus.Rejected, InvoiceStatus.Draft), + new KeyValuePair(InvoiceStatus.Paid, InvoiceStatus.Sent)//Bug 23450 + }; + + public InvoiceDao(int tenantID) + : base(tenantID) + { + } + + public Boolean IsExist(int invoiceID) + { + return IsExistFromDb(invoiceID); + } + + + public Boolean IsExistFromDb(int invoiceID) + { + return Db.ExecuteScalar(@"select exists(select 1 from crm_invoice where tenant_id = @tid and id = @id)", + new { tid = TenantID, id = invoiceID }); + } + + public Boolean IsExist(string number) + { + return IsExistFromDb(number); + } + + public Boolean IsExistFromDb(string number) + { + var q = new SqlQuery("crm_invoice") + .SelectCount() + .Where("tenant_id", TenantID) + .Where("number", number); + return Db.ExecuteScalar(q) > 0; + } + + #region Get + + public virtual List GetAll() + { + return Db.ExecuteList(GetInvoiceSqlQuery(null, null)).ConvertAll(ToInvoice); + } + + public virtual List GetByID(int[] ids) + { + return Db.ExecuteList(GetInvoiceSqlQuery(Exp.In("id", ids), null)).ConvertAll(ToInvoice); + } + + public virtual Invoice GetByID(int id) + { + return GetByIDFromDb(id); + } + + public virtual Invoice GetByIDFromDb(int id) + { + var invoices = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("id", id), null)).ConvertAll(ToInvoice); + return invoices.Count > 0 ? invoices[0] : null; + } + + public Invoice GetByNumber(string number) + { + var invoices = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("number", number), null)).ConvertAll(ToInvoice); + return invoices.Count > 0 ? invoices[0] : null; + } + + public Invoice GetByFileId(Int32 fileID) + { + var invoices = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("file_id", fileID), null)).ConvertAll(ToInvoice); + return invoices.Count > 0 ? invoices[0] : null; + } + + public List GetInvoices( + String searchText, + InvoiceStatus? status, + DateTime issueDateFrom, + DateTime issueDateTo, + DateTime dueDateFrom, + DateTime dueDateTo, + EntityType entityType, + int entityID, + String currency, + int from, + int count, + OrderBy orderBy) + { + + if (CRMSecurity.IsAdmin) + return GetCrudeInvoices( + searchText, + status, + issueDateFrom, + issueDateTo, + dueDateFrom, + dueDateTo, + entityType, + entityID, + currency, + from, + count, + orderBy); + + + var crudeInvoices = GetCrudeInvoices( + searchText, + status, + issueDateFrom, + issueDateTo, + dueDateFrom, + dueDateTo, + entityType, + entityID, + currency, + 0, + from + count, + orderBy); + + if (crudeInvoices.Count == 0) return crudeInvoices; + + if (crudeInvoices.Count < from + count) return CRMSecurity.FilterRead(crudeInvoices).Skip(from).ToList(); + + var result = CRMSecurity.FilterRead(crudeInvoices).ToList(); + + if (result.Count == crudeInvoices.Count) return result.Skip(from).ToList(); + + var localCount = count; + var localFrom = from + count; + + while (true) + { + crudeInvoices = GetCrudeInvoices( + searchText, + status, + issueDateFrom, + issueDateTo, + dueDateFrom, + dueDateTo, + entityType, + entityID, + currency, + localFrom, + localCount, + orderBy); + + if (crudeInvoices.Count == 0) break; + + result.AddRange(CRMSecurity.FilterRead(crudeInvoices)); + + if ((result.Count >= count + from) || (crudeInvoices.Count < localCount)) break; + + localFrom += localCount; + localCount = localCount * 2; + } + + return result.Skip(from).Take(count).ToList(); + } + + + public List GetCrudeInvoices( + String searchText, + InvoiceStatus? status, + DateTime issueDateFrom, + DateTime issueDateTo, + DateTime dueDateFrom, + DateTime dueDateTo, + EntityType entityType, + int entityID, + String currency, + int from, + int count, + OrderBy orderBy) + { + var invoicesTableAlias = "i_tbl"; + + var sqlQuery = GetInvoiceSqlQuery(null, invoicesTableAlias); + + var withParams = hasParams(searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); + + var whereConditional = WhereConditional(invoicesTableAlias, new List(), searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); + // WhereConditional(CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(), searchText); + + if (withParams && whereConditional == null) + return new List(); + + sqlQuery.Where(whereConditional); + + if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); + if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + + if (orderBy != null && Enum.IsDefined(typeof(InvoiceSortedByType), orderBy.SortedBy)) + { + switch ((InvoiceSortedByType)orderBy.SortedBy) + { + case InvoiceSortedByType.Number: + sqlQuery.OrderBy(invoicesTableAlias + ".number", orderBy.IsAsc); + break; + case InvoiceSortedByType.Status: + sqlQuery.OrderBy(invoicesTableAlias + ".status", orderBy.IsAsc); + break; + case InvoiceSortedByType.DueDate: + sqlQuery.OrderBy(invoicesTableAlias + ".due_date", orderBy.IsAsc); + break; + case InvoiceSortedByType.IssueDate: + sqlQuery.OrderBy(invoicesTableAlias + ".issue_date", orderBy.IsAsc); + break; + case InvoiceSortedByType.Contact: + sqlQuery.LeftOuterJoin("crm_contact c_tbl", Exp.EqColumns(invoicesTableAlias + ".contact_id", "c_tbl.id") & Exp.EqColumns(invoicesTableAlias + ".tenant_id", "c_tbl.tenant_id")) + .OrderBy("case when c_tbl.display_name is null then 1 else 0 end, c_tbl.display_name", orderBy.IsAsc) + .OrderBy(invoicesTableAlias + ".number", true); + break; + default: + sqlQuery.OrderBy(invoicesTableAlias + ".number", true); + break; + } + } + else + { + sqlQuery.OrderBy(invoicesTableAlias + ".number", true); + } + + return Db.ExecuteList(sqlQuery).ConvertAll(ToInvoice); + } + + public int GetAllInvoicesCount() + { + return Db.ExecuteScalar(Query("crm_invoice").SelectCount()); + } + + + public int GetInvoicesCount() + { + return GetInvoicesCount(String.Empty, null, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, EntityType.Any, 0, null); + } + + public int GetInvoicesCount( + String searchText, + InvoiceStatus? status, + DateTime issueDateFrom, + DateTime issueDateTo, + DateTime dueDateFrom, + DateTime dueDateTo, + EntityType entityType, + int entityID, + String currency) + { + var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + + "invoice" + + SecurityContext.CurrentAccount.ID.ToString() + + searchText; + + var fromCache = _cache.Get(cacheKey); + + if (fromCache != null) return Convert.ToInt32(fromCache); + + var withParams = hasParams(searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); + + var exceptIDs = CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(); + + int result; + + if (withParams) + { + var whereConditional = WhereConditional(null, exceptIDs, searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); + result = whereConditional != null ? Db.ExecuteScalar(Query("crm_invoice").Where(whereConditional).SelectCount()) : 0; + } + else + { + var countWithoutPrivate = Db.ExecuteScalar(Query("crm_invoice").SelectCount()); + var privateCount = exceptIDs.Count; + + if (privateCount > countWithoutPrivate) + { + _log.ErrorFormat(@"Private invoice count more than all cases. Tenant: {0}. CurrentAccount: {1}", + TenantID, + SecurityContext.CurrentAccount.ID); + + privateCount = 0; + } + + result = countWithoutPrivate - privateCount; + } + + if (result > 0) + { + _cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30)); + } + return result; + } + + public List GetInvoices(int[] ids) + { + if (ids == null || !ids.Any()) return new List(); + + return Db.ExecuteList(GetInvoiceSqlQuery(Exp.In("id", ids), null)) + .ConvertAll(ToInvoice).FindAll(CRMSecurity.CanAccessTo).ToList(); + } + + public List GetEntityInvoices(EntityType entityType, int entityID) + { + var result = new List(); + if (entityID <= 0) + return result; + + if (entityType == EntityType.Opportunity) + return Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType), null)) + .ConvertAll(ToInvoice) + .FindAll(CRMSecurity.CanAccessTo) + .ToList(); + + if (entityType == EntityType.Contact || entityType == EntityType.Person || entityType == EntityType.Company) + return GetContactInvoices(entityID); + + return result; + } + + public List GetContactInvoices(int contactID) + { + var result = new List(); + if (contactID <= 0) + return result; + + return Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("contact_id", contactID), null)) + .ConvertAll(ToInvoice) + .FindAll(CRMSecurity.CanAccessTo) + .ToList(); + } + + public string GetNewInvoicesNumber() + { + var settings = GetSettings(); + + if (!settings.Autogenerated) + return string.Empty; + + var query = Query("crm_invoice") + .Select("number") + .OrderBy("id", false) + .SetMaxResults(1); + + var stringNumber = Db.ExecuteScalar(query); + + if (string.IsNullOrEmpty(stringNumber) || !stringNumber.StartsWith(settings.Prefix)) + return string.Concat(settings.Prefix, settings.Number); + + if (!string.IsNullOrEmpty(settings.Prefix)) + stringNumber = stringNumber.Replace(settings.Prefix, string.Empty); + + int intNumber; + if (!Int32.TryParse(stringNumber, out intNumber)) + intNumber = 0; + + var format = string.Empty; + for (var i = 0; i < settings.Number.Length; i++) + { + format += "0"; + } + + var nextNumber = intNumber + 1; + + return settings.Prefix + (string.IsNullOrEmpty(format) ? nextNumber.ToString(CultureInfo.InvariantCulture) : nextNumber.ToString(format)); + } + + public InvoiceSetting GetSettings() + { + return Global.TenantSettings.InvoiceSetting ?? InvoiceSetting.DefaultSettings; + } + + #endregion + + #region SaveOrUpdate + + public virtual int SaveOrUpdateInvoice(Invoice invoice) + { + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + var result = SaveOrUpdateInvoiceInDb(invoice); + + FactoryIndexer.IndexAsync(invoice); + + return result; + } + + private int SaveOrUpdateInvoiceInDb(Invoice invoice) + { + if (String.IsNullOrEmpty(invoice.Number) || + invoice.IssueDate == DateTime.MinValue || + invoice.ContactID <= 0 || + invoice.DueDate == DateTime.MinValue || + String.IsNullOrEmpty(invoice.Currency) || + invoice.ExchangeRate <= 0 || + String.IsNullOrEmpty(invoice.Terms)) + throw new ArgumentException(); + + + + invoice.PurchaseOrderNumber = !String.IsNullOrEmpty(invoice.PurchaseOrderNumber) ? invoice.PurchaseOrderNumber : String.Empty; + + if (!IsExistFromDb(invoice.ID)) + { + if (IsExistFromDb(invoice.Number)) + throw new ArgumentException(); + + invoice.ID = Db.ExecuteScalar( + Insert("crm_invoice") + .InColumnValue("id", 0) + .InColumnValue("status", (int)invoice.Status) + .InColumnValue("number", invoice.Number) + .InColumnValue("issue_date", TenantUtil.DateTimeToUtc(invoice.IssueDate)) + .InColumnValue("template_type", invoice.TemplateType) + .InColumnValue("contact_id", invoice.ContactID) + .InColumnValue("consignee_id", invoice.ConsigneeID) + .InColumnValue("entity_type", (int)invoice.EntityType) + .InColumnValue("entity_id", invoice.EntityID) + .InColumnValue("due_date", TenantUtil.DateTimeToUtc(invoice.DueDate)) + .InColumnValue("language", invoice.Language) + .InColumnValue("currency", invoice.Currency) + .InColumnValue("exchange_rate", invoice.ExchangeRate) + .InColumnValue("purchase_order_number", invoice.PurchaseOrderNumber) + .InColumnValue("terms", invoice.Terms) + .InColumnValue("description", invoice.Description) + .InColumnValue("json_data", null) + .InColumnValue("file_id", 0) + .InColumnValue("create_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + } + else + { + + var oldInvoice = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("id", invoice.ID), null)) + .ConvertAll(ToInvoice) + .FirstOrDefault(); + + CRMSecurity.DemandEdit(oldInvoice); + + Db.ExecuteNonQuery( + Update("crm_invoice") + .Set("status", (int)invoice.Status) + .Set("issue_date", TenantUtil.DateTimeToUtc(invoice.IssueDate)) + .Set("template_type", invoice.TemplateType) + .Set("contact_id", invoice.ContactID) + .Set("consignee_id", invoice.ConsigneeID) + .Set("entity_type", (int)invoice.EntityType) + .Set("entity_id", invoice.EntityID) + .Set("due_date", TenantUtil.DateTimeToUtc(invoice.DueDate)) + .Set("language", invoice.Language) + .Set("currency", invoice.Currency) + .Set("exchange_rate", invoice.ExchangeRate) + .Set("purchase_order_number", invoice.PurchaseOrderNumber) + .Set("terms", invoice.Terms) + .Set("description", invoice.Description) + .Set("json_data", null) + .Set("file_id", 0) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", invoice.ID))); + } + + return invoice.ID; + } + + public virtual Invoice UpdateInvoiceStatus(int invoiceid, InvoiceStatus status) + { + return UpdateInvoiceStatusInDb(invoiceid, status); + } + + public List UpdateInvoiceBatchStatus(int[] invoiceids, InvoiceStatus status) + { + if (invoiceids == null || !invoiceids.Any()) + throw new ArgumentException(); + + var invoices = new List(); + + foreach (var id in invoiceids) + { + var inv = UpdateInvoiceStatusInDb(id, status); + if (inv != null) + { + invoices.Add(inv); + } + } + return invoices; + } + + private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) + { + var invoice = GetByIDFromDb(invoiceid); + if (invoice == null) + { + _log.Error("Invoice not found"); + return null; + } + CRMSecurity.DemandAccessTo(invoice); + + if (!invoiceStatusMap.Contains(new KeyValuePair(invoice.Status, status))) + { + _log.ErrorFormat("Status for invoice with ID={0} can't be changed. Return without changes", invoiceid); + return invoice; + } + + Db.ExecuteNonQuery( + Update("crm_invoice") + .Set("status", (int)status) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", invoiceid))); + + invoice.Status = status; + return invoice; + } + + public virtual int UpdateInvoiceJsonData(int invoiceId, string jsonData) + { + return UpdateInvoiceJsonDataInDb(invoiceId, jsonData); + } + + private int UpdateInvoiceJsonDataInDb(int invoiceId, string jsonData) + { + Db.ExecuteNonQuery( + Update("crm_invoice") + .Set("json_data", jsonData) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", invoiceId))); + + return invoiceId; + } + + public void UpdateInvoiceJsonData(Invoice invoice, int billingAddressID, int deliveryAddressID) + { + var jsonData = InvoiceFormattedData.GetData(invoice, billingAddressID, deliveryAddressID); + if (jsonData.LogoBase64Id != 0) + { + jsonData.LogoBase64 = null; + } + invoice.JsonData = JsonConvert.SerializeObject(jsonData); + UpdateInvoiceJsonData(invoice.ID, invoice.JsonData); + } + + public void UpdateInvoiceJsonDataAfterLinesUpdated(Invoice invoice) + { + var jsonData = InvoiceFormattedData.GetDataAfterLinesUpdated(invoice); + if (jsonData.LogoBase64Id != 0) + { + jsonData.LogoBase64 = null; + } + UpdateInvoiceJsonData(invoice.ID, invoice.JsonData); + } + + public virtual int UpdateInvoiceFileID(int invoiceId, int fileId) + { + return UpdateInvoiceFileIDInDb(invoiceId, fileId); + } + + private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) + { + Db.ExecuteNonQuery( + Update("crm_invoice") + .Set("file_id", fileId) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", invoiceId))); + + return invoiceId; + } + + public InvoiceSetting SaveInvoiceSettings(InvoiceSetting invoiceSetting) + { + var tenantSettings = Global.TenantSettings; + tenantSettings.InvoiceSetting = invoiceSetting; + tenantSettings.Save(); + + return tenantSettings.InvoiceSetting; + } + + #endregion + + #region Delete + + + public virtual Invoice DeleteInvoice(int invoiceID) + { + if (invoiceID <= 0) return null; + + var invoice = GetByID(invoiceID); + if (invoice == null) return null; + + CRMSecurity.DemandDelete(invoice); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + DeleteBatchInvoicesExecute(new List { invoice }); + + return invoice; + } + + public List DeleteBatchInvoices(int[] invoiceID) + { + var invoices = GetInvoices(invoiceID).Where(CRMSecurity.CanDelete).ToList(); + if (!invoices.Any()) return invoices; + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + DeleteBatchInvoicesExecute(invoices); + + return invoices; + } + + private void DeleteBatchInvoicesExecute(List invoices) + { + + var invoiceID = invoices.Select(x => x.ID).ToArray(); + + using (var tx = Db.BeginTransaction()) + { + Db.ExecuteNonQuery(Delete("crm_invoice_line").Where(Exp.In("invoice_id", invoiceID))); + Db.ExecuteNonQuery(Delete("crm_invoice").Where(Exp.In("id", invoiceID))); + + tx.Commit(); + } + invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(invoice)); + } + + #endregion + + #region Private Methods + + private static Invoice ToInvoice(object[] row) + { + return new Invoice + { + ID = Convert.ToInt32(row[0]), + Status = (InvoiceStatus)Convert.ToInt32(row[1]), + Number = Convert.ToString(row[2]), + IssueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[3].ToString())), + TemplateType = (InvoiceTemplateType)Convert.ToInt32(row[4]), + ContactID = Convert.ToInt32(row[5]), + ConsigneeID = Convert.ToInt32(row[6]), + EntityType = (EntityType)Convert.ToInt32(row[7]), + EntityID = Convert.ToInt32(row[8]), + DueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[9].ToString())), + Language = Convert.ToString(row[10]), + Currency = Convert.ToString(row[11]), + ExchangeRate = Convert.ToDecimal(row[12]), + PurchaseOrderNumber = Convert.ToString(row[13]), + Terms = Convert.ToString(row[14]), + Description = Convert.ToString(row[15]), + JsonData = Convert.ToString(row[16]), + FileID = Convert.ToInt32(row[17]), + CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[18].ToString())), + CreateBy = ToGuid(row[19]), + LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[20].ToString())), + LastModifedBy = ToGuid(row[21]) + }; + } + + private SqlQuery GetInvoiceSqlQuery(Exp where, String alias) + { + var q = Query("crm_invoice"); + + if (!string.IsNullOrEmpty(alias)) + { + q = new SqlQuery("crm_invoice " + alias) + .Where(alias + ".tenant_id", TenantID); + q.Select(GetInvoiceColumnsTable(alias)); + + } + else + { + q.Select(GetInvoiceColumnsTable(String.Empty)); + } + + if (where != null) + q.Where(where); + + return q; + } + + private String[] GetInvoiceColumnsTable(String alias) + { + var result = new string[] + { + "id", + "status", + "number", + "issue_date", + "template_type", + "contact_id", + "consignee_id", + "entity_type", + "entity_id", + "due_date", + "language", + "currency", + "exchange_rate", + "purchase_order_number", + "terms", + "description", + "json_data", + "file_id", + "create_on", + "create_by", + "last_modifed_on", + "last_modifed_by" + }; + + return string.IsNullOrEmpty(alias) ? result : result.Select(c => alias + "." + c).ToArray(); + } + + private Exp WhereConditional(String tblAlias, + ICollection exceptIDs, + String searchText, + InvoiceStatus? status, + DateTime issueDateFrom, + DateTime issueDateTo, + DateTime dueDateFrom, + DateTime dueDateTo, + EntityType entityType, + int entityID, + String currency) + { + var tblAliasPrefix = !String.IsNullOrEmpty(tblAlias) ? tblAlias + "." : ""; + var conditions = new List(); + + if (entityID > 0) + switch (entityType) + { + case EntityType.Contact: + case EntityType.Person: + case EntityType.Company: + conditions.Add(Exp.Eq(tblAliasPrefix + "contact_id", entityID)); + break; + case EntityType.Case: + case EntityType.Opportunity: + conditions.Add(Exp.Eq(tblAliasPrefix + "entity_id", entityID) & + Exp.Eq(tblAliasPrefix + "entity_type", (int)entityType)); + break; + } + + if (status != null) + { + conditions.Add(Exp.Eq(tblAliasPrefix + "status", (int)status.Value)); + } + + + if (!String.IsNullOrEmpty(searchText)) + { + searchText = searchText.Trim(); + + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + .ToArray(); + + if (keywords.Length > 0) + { + List invoicesIds; + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out invoicesIds)) + { + conditions.Add(BuildLike(new[] {tblAliasPrefix + "number", tblAliasPrefix + "description"}, keywords)); + } + else + { + conditions.Add(Exp.In(tblAliasPrefix + "id", invoicesIds)); + } + } + } + + if (exceptIDs.Count > 0) + { + conditions.Add(!Exp.In(tblAliasPrefix + "id", exceptIDs.ToArray())); + } + + if (issueDateFrom != DateTime.MinValue && issueDateTo != DateTime.MinValue) + conditions.Add(Exp.Between(tblAliasPrefix + "issue_date", TenantUtil.DateTimeToUtc(issueDateFrom), TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1)))); + else if (issueDateFrom != DateTime.MinValue) + conditions.Add(Exp.Ge(tblAliasPrefix + "issue_date", TenantUtil.DateTimeToUtc(issueDateFrom))); + else if (issueDateTo != DateTime.MinValue) + conditions.Add(Exp.Le(tblAliasPrefix + "issue_date", TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1)))); + + + if (dueDateFrom != DateTime.MinValue && dueDateTo != DateTime.MinValue) + conditions.Add(Exp.Between(tblAliasPrefix + "due_date", TenantUtil.DateTimeToUtc(dueDateFrom), TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1)))); + else if (dueDateFrom != DateTime.MinValue) + conditions.Add(Exp.Ge(tblAliasPrefix + "due_date", TenantUtil.DateTimeToUtc(dueDateFrom))); + else if (dueDateTo != DateTime.MinValue) + conditions.Add(Exp.Le(tblAliasPrefix + "due_date", TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1)))); + + if (!String.IsNullOrEmpty(currency)) + { + conditions.Add(Exp.Eq(tblAliasPrefix + "currency", currency)); + } + + if (conditions.Count == 0) return null; + + return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + } + + private bool hasParams( + String searchText, + InvoiceStatus? status, + DateTime issueDateFrom, + DateTime issueDateTo, + DateTime dueDateFrom, + DateTime dueDateTo, + EntityType entityType, + int entityID, + String currency) + { + return !(String.IsNullOrEmpty(searchText) && !status.HasValue && + issueDateFrom == DateTime.MinValue && issueDateTo == DateTime.MinValue && + dueDateFrom == DateTime.MinValue && dueDateTo == DateTime.MinValue && + entityID == 0 && String.IsNullOrEmpty(currency)); + } + + #endregion + + + /// + /// Test method + /// + /// + /// + public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) + { + Db.ExecuteNonQuery( + Update("crm_invoice") + .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) + .Where(Exp.Eq("id", invoiceId))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + } + + /// + /// Test method + /// + /// + /// + public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) + { + Db.ExecuteNonQuery( + Update("crm_invoice") + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) + .Where(Exp.Eq("id", invoiceId))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs new file mode 100644 index 00000000000..a80a8f7796d --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -0,0 +1,490 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Web.Caching; +using ASC.Collections; +using ASC.Common.Data; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.Web.CRM.Classes; + +namespace ASC.CRM.Core.Dao +{ + public class CachedInvoiceItemDao : InvoiceItemDao + { + private readonly HttpRequestDictionary _invoiceItemCache = new HttpRequestDictionary("crm_invoice_item"); + + public CachedInvoiceItemDao(int tenantID) + : base(tenantID) + { + } + + public override InvoiceItem GetByID(int invoiceItemID) + { + return _invoiceItemCache.Get(invoiceItemID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceItemID)); + } + + private InvoiceItem GetByIDBase(int invoiceItemID) + { + return base.GetByID(invoiceItemID); + } + + public override InvoiceItem SaveOrUpdateInvoiceItem(InvoiceItem invoiceItem) + { + if (invoiceItem != null && invoiceItem.ID > 0) + ResetCache(invoiceItem.ID); + + return base.SaveOrUpdateInvoiceItem(invoiceItem); + } + + public override InvoiceItem DeleteInvoiceItem(int invoiceItemID) + { + ResetCache(invoiceItemID); + + return base.DeleteInvoiceItem(invoiceItemID); + } + + private void ResetCache(int invoiceItemID) + { + _invoiceItemCache.Reset(invoiceItemID.ToString(CultureInfo.InvariantCulture)); + } + } + + public class InvoiceItemDao : AbstractDao + { + public InvoiceItemDao(int tenantID) + : base(tenantID) + { + } + + + public Boolean IsExist(int invoiceItemID) + { + return IsExistInDb(invoiceItemID); + } + + public Boolean IsExistInDb(int invoiceItemID) + { + return Db.ExecuteScalar(@"select exists(select 1 from crm_invoice_item where tenant_id = @tid and id = @id)", + new { tid = TenantID, id = invoiceItemID }); + } + + public Boolean CanDelete(int invoiceItemID) + { + return Db.ExecuteScalar(@"select count(*) from crm_invoice_line where tenant_id = @tid and invoice_item_id = @id", + new { tid = TenantID, id = invoiceItemID }) == 0; + } + + #region Get + + public virtual List GetAll() + { + return GetAllInDb(); + } + public virtual List GetAllInDb() + { + return Db.ExecuteList(GetInvoiceItemSqlQuery(null)).ConvertAll(ToInvoiceItem); + } + + public virtual List GetByID(int[] ids) + { + return Db.ExecuteList(GetInvoiceItemSqlQuery(Exp.In("id", ids))).ConvertAll(ToInvoiceItem); + } + + public virtual InvoiceItem GetByID(int id) + { + var invoiceItems = Db.ExecuteList(GetInvoiceItemSqlQuery(Exp.Eq("id", id))).ConvertAll(ToInvoiceItem); + + return invoiceItems.Count > 0 ? invoiceItems[0] : null; + } + + public List GetInvoiceItems(IEnumerable ids) + { + if (ids == null || !ids.Any()) return new List(); + + var sqlQuery = GetInvoiceItemSqlQuery(Exp.In("id", ids.ToArray())); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToInvoiceItem); + } + + public List GetInvoiceItems( + string searchText, + int status, + bool? inventoryStock, + int from, + int count, + OrderBy orderBy) + { + + var sqlQuery = GetInvoiceItemSqlQuery(null); + + var withParams = !(String.IsNullOrEmpty(searchText) || status != 0 || inventoryStock.HasValue); + + + var whereConditional = WhereConditional(new List(), searchText, status, inventoryStock); + // WhereConditional(CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(), searchText); + + if (withParams && whereConditional == null) + return new List(); + + sqlQuery.Where(whereConditional); + + if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); + if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + + if (orderBy != null && Enum.IsDefined(typeof(InvoiceItemSortedByType), orderBy.SortedBy)) + { + switch ((InvoiceItemSortedByType)orderBy.SortedBy) + { + case InvoiceItemSortedByType.Name: + sqlQuery.OrderBy("title", orderBy.IsAsc); + break; + case InvoiceItemSortedByType.SKU: + sqlQuery.OrderBy("stock_keeping_unit", orderBy.IsAsc); + break; + case InvoiceItemSortedByType.Price: + sqlQuery.OrderBy("price", orderBy.IsAsc); + break; + case InvoiceItemSortedByType.Quantity: + sqlQuery.OrderBy("stock_quantity", orderBy.IsAsc).OrderBy("title", true); + break; + case InvoiceItemSortedByType.Created: + sqlQuery.OrderBy("create_on", orderBy.IsAsc); + break; + default: + sqlQuery.OrderBy("title", true); + break; + } + } + else + { + sqlQuery.OrderBy("title", true); + } + + return Db.ExecuteList(sqlQuery).ConvertAll(ToInvoiceItem); + } + + + public int GetInvoiceItemsCount() + { + return GetInvoiceItemsCount(String.Empty, 0, null); + } + + public int GetInvoiceItemsCount( + String searchText, + int status, + bool? inventoryStock) + { + var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + + "invoiceItem" + + SecurityContext.CurrentAccount.ID.ToString() + + searchText; + + var fromCache = _cache.Get(cacheKey); + + if (fromCache != null) return Convert.ToInt32(fromCache); + + var withParams = !(String.IsNullOrEmpty(searchText) || status != 0 || inventoryStock.HasValue); + + var exceptIDs = CRMSecurity.GetPrivateItems(typeof(InvoiceItem)).ToList(); + + int result; + + if (withParams) + { + var whereConditional = WhereConditional(exceptIDs, searchText, status, inventoryStock); + result = whereConditional != null ? Db.ExecuteScalar(Query("crm_invoice_item").Where(whereConditional).SelectCount()) : 0; + } + else + { + var countWithoutPrivate = Db.ExecuteScalar(Query("crm_invoice_item").SelectCount()); + var privateCount = exceptIDs.Count; + + if (privateCount > countWithoutPrivate) + { + _log.ErrorFormat(@"Private invoice items count more than all cases. Tenant: {0}. CurrentAccount: {1}", + TenantID, + SecurityContext.CurrentAccount.ID); + + privateCount = 0; + } + + result = countWithoutPrivate - privateCount; + } + + if (result > 0) + { + _cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30)); + } + return result; + } + + #endregion + + + #region SaveOrUpdate + + public virtual InvoiceItem SaveOrUpdateInvoiceItem(InvoiceItem invoiceItem) + { + /*_cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ + + return SaveOrUpdateInvoiceItemInDb(invoiceItem); + } + + private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) + { + if (invoiceItem.Price <= 0 || String.IsNullOrEmpty(invoiceItem.Title)) + throw new ArgumentException(); + + if (invoiceItem.Price > Global.MaxInvoiceItemPrice) + throw new ArgumentException("Max Invoice Item Price: " + Global.MaxInvoiceItemPrice); + + if (!CRMSecurity.IsAdmin) CRMSecurity.CreateSecurityException(); + + if (String.IsNullOrEmpty(invoiceItem.Description)) { + invoiceItem.Description = String.Empty; + } + if (String.IsNullOrEmpty(invoiceItem.StockKeepingUnit)) + { + invoiceItem.StockKeepingUnit = String.Empty; + } + + if (!IsExistInDb(invoiceItem.ID)) + { + invoiceItem.ID = Db.ExecuteScalar( + Insert("crm_invoice_item") + .InColumnValue("id", 0) + .InColumnValue("title", invoiceItem.Title) + .InColumnValue("description", invoiceItem.Description) + .InColumnValue("stock_keeping_unit", invoiceItem.StockKeepingUnit) + .InColumnValue("price", invoiceItem.Price) + .InColumnValue("stock_quantity", invoiceItem.StockQuantity) + .InColumnValue("track_inventory", invoiceItem.TrackInventory) + .InColumnValue("invoice_tax1_id", invoiceItem.InvoiceTax1ID) + .InColumnValue("invoice_tax2_id", invoiceItem.InvoiceTax2ID) + .InColumnValue("currency", String.Empty) + .InColumnValue("create_on", DateTime.UtcNow) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", DateTime.UtcNow) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + + invoiceItem.CreateOn = DateTime.UtcNow; + invoiceItem.LastModifedOn = invoiceItem.CreateOn; + invoiceItem.CreateBy = SecurityContext.CurrentAccount.ID; + invoiceItem.LastModifedBy = invoiceItem.CreateBy; + } + else + { + + var oldInvoiceItem = Db.ExecuteList(GetInvoiceItemSqlQuery(Exp.Eq("id", invoiceItem.ID))) + .ConvertAll(ToInvoiceItem) + .FirstOrDefault(); + + CRMSecurity.DemandEdit(oldInvoiceItem); + + Db.ExecuteNonQuery( + Update("crm_invoice_item") + .Set("title", invoiceItem.Title) + .Set("description", invoiceItem.Description) + .Set("stock_keeping_unit", invoiceItem.StockKeepingUnit) + .Set("price", invoiceItem.Price) + .Set("stock_quantity", invoiceItem.StockQuantity) + .Set("track_inventory", invoiceItem.TrackInventory) + .Set("invoice_tax1_id", invoiceItem.InvoiceTax1ID) + .Set("invoice_tax2_id", invoiceItem.InvoiceTax2ID) + .Set("currency", String.Empty) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", invoiceItem.ID))); + + invoiceItem.LastModifedOn = DateTime.UtcNow; + invoiceItem.LastModifedBy = SecurityContext.CurrentAccount.ID; + } + + return invoiceItem; + } + + #endregion + + + #region Delete + + public virtual InvoiceItem DeleteInvoiceItem(int invoiceItemID) + { + var invoiceItem = GetByID(invoiceItemID); + if (invoiceItem == null) return null; + + CRMSecurity.DemandDelete(invoiceItem); + + Db.ExecuteNonQuery(Delete("crm_invoice_item").Where("id", invoiceItemID)); + + /*_cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ + + return invoiceItem; + } + + public virtual List DeleteBatchInvoiceItems(int[] invoiceItemIDs) + { + if (invoiceItemIDs == null || !invoiceItemIDs.Any()) return null; + + var items = GetInvoiceItems(invoiceItemIDs).Where(CRMSecurity.CanDelete).ToList(); + if (!items.Any()) return items; + + // Delete relative keys + /*_cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ + + DeleteBatchItemsExecute(items); + + return items; + } + + #endregion + + + #region Private Methods + + private void DeleteBatchItemsExecute(List items) + { + var ids = items.Select(x => x.ID).ToArray(); + + //using (var tx = db.BeginTransaction(true)) + ///{ + Db.ExecuteNonQuery(Delete("crm_invoice_item").Where(Exp.In("id", ids))); + // tx.Commit(); + //} + } + + private static InvoiceItem ToInvoiceItem(object[] row) + { + return new InvoiceItem + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + Description = Convert.ToString(row[2]), + StockKeepingUnit = Convert.ToString(row[3]), + Price = Convert.ToDecimal(row[4]), + StockQuantity = Convert.ToDecimal(row[5]), + TrackInventory = Convert.ToBoolean(row[6]), + InvoiceTax1ID = Convert.ToInt32(row[7]), + InvoiceTax2ID = Convert.ToInt32(row[8]), + Currency = Convert.ToString(row[9]), + CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[10].ToString())), + CreateBy = ToGuid(row[11]), + LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[12].ToString())), + LastModifedBy = ToGuid(row[13]) + }; + } + + private SqlQuery GetInvoiceItemSqlQuery(Exp where) + { + var sqlQuery = Query("crm_invoice_item") + .Select( + "id", + "title", + "description", + "stock_keeping_unit", + "price", + "stock_quantity", + "track_inventory", + "invoice_tax1_id", + "invoice_tax2_id", + "currency", + "create_on", + "create_by", + "last_modifed_on", + "last_modifed_by"); + + if (where != null) + { + sqlQuery.Where(where); + } + + return sqlQuery; + } + + private Exp WhereConditional( + ICollection exceptIDs, + String searchText, + int status, + bool? inventoryStock) + { + var conditions = new List(); + + //if (status != null) + //{ + // conditions.Add(Exp.Eq("status", (int)status.Value)); + //} + + + if (!String.IsNullOrEmpty(searchText)) + { + searchText = searchText.Trim(); + + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + .ToArray(); + + if (keywords.Length > 0) + //if (FullTextSearch.SupportModule(FullTextSearch.CRMInvoiceItemModule)) + //{ + // ids = FullTextSearch.Search(searchText, FullTextSearch.CRMInvoiceItemModule) + // .GetIdentifiers() + // .Select(item => Convert.ToInt32(item.Split('_')[1])).Distinct().ToList(); + + // if (ids.Count == 0) return null; + //} + //else + conditions.Add(BuildLike(new[] {"title", "description", "stock_keeping_unit" }, keywords)); + } + + if (exceptIDs.Count > 0) + { + conditions.Add(!Exp.In("id", exceptIDs.ToArray())); + } + + + if (inventoryStock.HasValue) { + conditions.Add(Exp.Eq("track_inventory", inventoryStock.Value)); + } + + if (conditions.Count == 0) return null; + + return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs new file mode 100644 index 00000000000..8fac8e076ab --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -0,0 +1,289 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using ASC.Collections; +using ASC.Common.Data; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.CRM.Core.Entities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.Text.RegularExpressions; + +namespace ASC.CRM.Core.Dao +{ + public class CachedInvoiceLineDao : InvoiceLineDao + { + private readonly HttpRequestDictionary _invoiceLineCache = new HttpRequestDictionary("crm_invoice_line"); + + public CachedInvoiceLineDao(int tenantID) + : base(tenantID) + { + } + + public override InvoiceLine GetByID(int invoiceLineID) + { + return _invoiceLineCache.Get(invoiceLineID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceLineID)); + } + + private InvoiceLine GetByIDBase(int invoiceLineID) + { + return base.GetByID(invoiceLineID); + } + + public override int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) + { + if (invoiceLine != null && invoiceLine.ID > 0) + ResetCache(invoiceLine.ID); + + return base.SaveOrUpdateInvoiceLine(invoiceLine); + } + + public override void DeleteInvoiceLine(int invoiceLineID) + { + ResetCache(invoiceLineID); + + base.DeleteInvoiceLine(invoiceLineID); + } + + private void ResetCache(int invoiceLineID) + { + _invoiceLineCache.Reset(invoiceLineID.ToString(CultureInfo.InvariantCulture)); + } + } + + public class InvoiceLineDao : AbstractDao + { + public InvoiceLineDao(int tenantID) + : base(tenantID) + { + } + + + public static string GetJson(InvoiceItem invoiceItem) { + return invoiceItem == null ? + string.Empty : + JsonConvert.SerializeObject(new + { + id = invoiceItem.ID, + title = invoiceItem.Title, + description = invoiceItem.Description + }); + } + public static string GetJson(InvoiceTax invoiceTax) { + return invoiceTax == null ? + string.Empty : + JsonConvert.SerializeObject(new + { + id = invoiceTax.ID, + name = invoiceTax.Name, + rate = invoiceTax.Rate, + description = invoiceTax.Description + }); + } + + #region Get + + public virtual List GetAll() + { + return Db.ExecuteList(GetInvoiceLineSqlQuery(null)).ConvertAll(ToInvoiceLine); + } + + public virtual List GetByID(int[] ids) + { + return Db.ExecuteList(GetInvoiceLineSqlQuery(Exp.In("id", ids))).ConvertAll(ToInvoiceLine); + } + + public virtual InvoiceLine GetByID(int id) + { + var invoiceLines = Db.ExecuteList(GetInvoiceLineSqlQuery(Exp.Eq("id", id))).ConvertAll(ToInvoiceLine); + + return invoiceLines.Count > 0 ? invoiceLines[0] : null; + } + + public List GetInvoiceLines(int invoiceID) + { + return GetInvoiceLinesInDb(invoiceID); + } + + public List GetInvoiceLinesInDb(int invoiceID) + { + return Db.ExecuteList(GetInvoiceLineSqlQuery(Exp.Eq("invoice_id", invoiceID)).OrderBy("sort_order", true)).ConvertAll(ToInvoiceLine); + } + + #endregion + + + #region SaveOrUpdate + + public virtual int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) + { + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); + + return SaveOrUpdateInvoiceLineInDb(invoiceLine); + } + + private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) + { + if (invoiceLine.InvoiceID <= 0 || invoiceLine.InvoiceItemID <= 0) + throw new ArgumentException(); + + if (String.IsNullOrEmpty(invoiceLine.Description)) + { + invoiceLine.Description = String.Empty; + } + + if (Db.ExecuteScalar(Query("crm_invoice_line").SelectCount().Where(Exp.Eq("id", invoiceLine.ID))) == 0) + { + invoiceLine.ID = Db.ExecuteScalar( + Insert("crm_invoice_line") + .InColumnValue("id", 0) + .InColumnValue("invoice_id", invoiceLine.InvoiceID) + .InColumnValue("invoice_item_id", invoiceLine.InvoiceItemID) + .InColumnValue("invoice_tax1_id", invoiceLine.InvoiceTax1ID) + .InColumnValue("invoice_tax2_id", invoiceLine.InvoiceTax2ID) + .InColumnValue("sort_order", invoiceLine.SortOrder) + .InColumnValue("description", invoiceLine.Description) + .InColumnValue("quantity", invoiceLine.Quantity) + .InColumnValue("price", invoiceLine.Price) + .InColumnValue("discount", invoiceLine.Discount) + .Identity(1, 0, true)); + } + else + { + + Db.ExecuteNonQuery( + Update("crm_invoice_line") + .Set("invoice_id", invoiceLine.InvoiceID) + .Set("invoice_item_id", invoiceLine.InvoiceItemID) + .Set("invoice_tax1_id", invoiceLine.InvoiceTax1ID) + .Set("invoice_tax2_id", invoiceLine.InvoiceTax2ID) + .Set("sort_order", invoiceLine.SortOrder) + .Set("description", invoiceLine.Description) + .Set("quantity", invoiceLine.Quantity) + .Set("price", invoiceLine.Price) + .Set("discount", invoiceLine.Discount) + .Where(Exp.Eq("id", invoiceLine.ID))); + } + return invoiceLine.ID; + } + + #endregion + + + #region Delete + + public virtual void DeleteInvoiceLine(int invoiceLineID) + { + var invoiceLine = GetByID(invoiceLineID); + + if (invoiceLine == null) return; + + Db.ExecuteNonQuery(Delete("crm_invoice_line").Where("id", invoiceLineID)); + + /*_cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ + } + + public void DeleteInvoiceLines(int invoiceID) + { + Db.ExecuteNonQuery(Delete("crm_invoice_line").Where(Exp.Eq("invoice_id", invoiceID))); + + /*_cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ + } + + public Boolean CanDelete(int invoiceLineID) + { + return CanDeleteInDb(invoiceLineID); + } + + public Boolean CanDeleteInDb(int invoiceLineID) + { + + var invoiceID = Db.ExecuteScalar(Query("crm_invoice_line").Select("invoice_id") + .Where(Exp.Eq("id", invoiceLineID))); + + if (invoiceID == 0) return false; + + var count = Db.ExecuteScalar(Query("crm_invoice_line").SelectCount() + .Where(Exp.Eq("invoice_id", invoiceID))); + + return count > 1; + } + + #endregion + + + #region Private Methods + + private static InvoiceLine ToInvoiceLine(object[] row) + { + return new InvoiceLine + { + ID = Convert.ToInt32(row[0]), + InvoiceID = Convert.ToInt32(row[1]), + InvoiceItemID = Convert.ToInt32(row[2]), + InvoiceTax1ID = Convert.ToInt32(row[3]), + InvoiceTax2ID = Convert.ToInt32(row[4]), + SortOrder = Convert.ToInt32(row[5]), + Description = Convert.ToString(row[6]), + Quantity = Convert.ToDecimal(row[7]), + Price = Convert.ToDecimal(row[8]), + Discount = Convert.ToDecimal(row[9]) + }; + } + + private SqlQuery GetInvoiceLineSqlQuery(Exp where) + { + var sqlQuery = Query("crm_invoice_line") + .Select( + "id", + "invoice_id", + "invoice_item_id", + "invoice_tax1_id", + "invoice_tax2_id", + "sort_order", + "description", + "quantity", + "price", + "discount"); + + if (where != null) + { + sqlQuery.Where(where); + } + + return sqlQuery; + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs new file mode 100644 index 00000000000..b179c0cad82 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -0,0 +1,262 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using ASC.Collections; +using ASC.Common.Data; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; + +namespace ASC.CRM.Core.Dao +{ + public class CachedInvoiceTaxDao : InvoiceTaxDao + { + private readonly HttpRequestDictionary _invoiceTaxCache = new HttpRequestDictionary("crm_invoice_tax"); + + public CachedInvoiceTaxDao(int tenantID) + : base(tenantID) + { + } + + public override InvoiceTax GetByID(int invoiceTaxID) + { + return _invoiceTaxCache.Get(invoiceTaxID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceTaxID)); + } + + private InvoiceTax GetByIDBase(int invoiceTaxID) + { + return base.GetByID(invoiceTaxID); + } + + public override InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) + { + if (invoiceTax != null && invoiceTax.ID > 0) + ResetCache(invoiceTax.ID); + + return base.SaveOrUpdateInvoiceTax(invoiceTax); + } + + public override InvoiceTax DeleteInvoiceTax(int invoiceTaxID) + { + ResetCache(invoiceTaxID); + + return base.DeleteInvoiceTax(invoiceTaxID); + } + + private void ResetCache(int invoiceTaxID) + { + _invoiceTaxCache.Reset(invoiceTaxID.ToString(CultureInfo.InvariantCulture)); + } + } + + public class InvoiceTaxDao : AbstractDao + { + public InvoiceTaxDao(int tenantID) + : base(tenantID) + { + } + + + public Boolean IsExist(int invoiceTaxID) + { + return Db.ExecuteScalar( + @"select exists(select 1 from crm_invoice_tax where tenant_id = @tid and id = @id)", + new {tid = TenantID, id = invoiceTaxID}); + } + + public Boolean IsExist(String invoiceName) + { + var q = new SqlQuery("crm_invoice_tax") + .Select("1") + .Where("tenant_id", TenantID) + .Where("name", invoiceName) + .SetMaxResults(1); + + return Db.ExecuteScalar(q); + } + + public Boolean CanDelete(int invoiceTaxID) + { + var count1 = Db.ExecuteScalar(@"select count(*) from crm_invoice_item where tenant_id = @tid and (invoice_tax1_id = @id or invoice_tax2_id = @id)", + new { tid = TenantID, id = invoiceTaxID }); + var count2 = Db.ExecuteScalar(@"select count(*) from crm_invoice_line where tenant_id = @tid and (invoice_tax1_id = @id or invoice_tax2_id = @id)", + new { tid = TenantID, id = invoiceTaxID }); + + return count1 == 0 && count2 == 0; + } + + #region Get + + public virtual List GetAll() + { + return Db.ExecuteList(GetInvoiceTaxSqlQuery(null)).ConvertAll(ToInvoiceTax); + } + + public DateTime GetMaxLastModified() + { + return Db.ExecuteScalar(Query("crm_invoice_tax").Select("last_modifed_on")); + } + + public virtual List GetByID(int[] ids) + { + return Db.ExecuteList(GetInvoiceTaxSqlQuery(Exp.In("id", ids))).ConvertAll(ToInvoiceTax); + } + + public virtual InvoiceTax GetByID(int id) + { + var invoiceTaxes = Db.ExecuteList(GetInvoiceTaxSqlQuery(Exp.Eq("id", id))).ConvertAll(ToInvoiceTax); + + return invoiceTaxes.Count > 0 ? invoiceTaxes[0] : null; + } + + #endregion + + #region SaveOrUpdate + + public virtual InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) + { + /*_cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ + + return SaveOrUpdateInvoiceTaxInDb(invoiceTax); + } + + private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) + { + if (String.IsNullOrEmpty(invoiceTax.Name)) + throw new ArgumentException(); + + invoiceTax.LastModifedBy = SecurityContext.CurrentAccount.ID; + invoiceTax.LastModifedOn = DateTime.UtcNow; + + if (Db.ExecuteScalar(Query("crm_invoice_tax").SelectCount().Where(Exp.Eq("id", invoiceTax.ID))) == 0) + { + invoiceTax.CreateOn = DateTime.UtcNow; + invoiceTax.CreateBy = SecurityContext.CurrentAccount.ID; + + invoiceTax.ID = Db.ExecuteScalar( + Insert("crm_invoice_tax") + .InColumnValue("id", 0) + .InColumnValue("name", invoiceTax.Name) + .InColumnValue("description", invoiceTax.Description) + .InColumnValue("rate", invoiceTax.Rate) + .InColumnValue("create_on", invoiceTax.CreateOn) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", invoiceTax.LastModifedOn) + .InColumnValue("last_modifed_by", invoiceTax.LastModifedBy) + .Identity(1, 0, true)); + } + else + { + var oldInvoiceTax = Db.ExecuteList(GetInvoiceTaxSqlQuery(Exp.Eq("id", invoiceTax.ID))) + .ConvertAll(ToInvoiceTax) + .FirstOrDefault(); + + CRMSecurity.DemandEdit(oldInvoiceTax); + + Db.ExecuteNonQuery( + Update("crm_invoice_tax") + .Set("name", invoiceTax.Name) + .Set("description", invoiceTax.Description) + .Set("rate", invoiceTax.Rate) + .Set("last_modifed_on", invoiceTax.LastModifedOn) + .Set("last_modifed_by", invoiceTax.LastModifedBy) + .Where(Exp.Eq("id", invoiceTax.ID))); + } + + return invoiceTax; + } + + #endregion + + + #region Delete + + public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) + { + var invoiceTax = GetByID(invoiceTaxID); + + if (invoiceTax == null) return null; + + CRMSecurity.DemandDelete(invoiceTax); + + Db.ExecuteNonQuery(Delete("crm_invoice_tax").Where("id", invoiceTaxID)); + + /* _cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ + return invoiceTax; + } + + #endregion + + + #region Private Methods + + private static InvoiceTax ToInvoiceTax(object[] row) + { + return new InvoiceTax + { + ID = Convert.ToInt32(row[0]), + Name = Convert.ToString(row[1]), + Description = Convert.ToString(row[2]), + Rate = Convert.ToDecimal(row[3]), + CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[4].ToString())), + CreateBy = ToGuid(row[5]), + LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[6].ToString())), + LastModifedBy = ToGuid(row[7]) + }; + } + + private SqlQuery GetInvoiceTaxSqlQuery(Exp where) + { + var sqlQuery = Query("crm_invoice_tax") + .Select( + "id", + "name", + "description", + "rate", + "create_on", + "create_by", + "last_modifed_on", + "last_modifed_by"); + + if (where != null) + { + sqlQuery.Where(where); + } + + return sqlQuery; + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs new file mode 100644 index 00000000000..13ae3b83e1b --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -0,0 +1,586 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using ASC.Collections; +using ASC.Web.CRM.Classes; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.CRM.Core.Entities; +using ASC.Web.CRM.Resources; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + + public class CachedListItem : ListItemDao + { + + #region Members + + private readonly HttpRequestDictionary _listItemCache = new HttpRequestDictionary("crm_list_item"); + + #endregion + + #region Constructor + + public CachedListItem(int tenantID) + : base(tenantID) + { + + + } + + #endregion + + #region Members + + public override void ChangeColor(int id, string newColor) + { + ResetCache(id); + + base.ChangeColor(id, newColor); + } + + public override void DeleteItem(ListType listType, int itemID, int toItemID) + { + ResetCache(itemID); + + base.DeleteItem(listType, itemID, toItemID); + } + + public override void ChangePicture(int id, string newPicture) + { + ResetCache(id); + + base.ChangePicture(id, newPicture); + } + + public override void EditItem(ListType listType, ListItem enumItem) + { + ResetCache(enumItem.ID); + + base.EditItem(listType, enumItem); + } + + public override void ReorderItems(ListType listType, string[] titles) + { + _listItemCache.Clear(); + + base.ReorderItems(listType, titles); + } + + public override ListItem GetByID(int id) + { + return _listItemCache.Get(id.ToString(), () => GetByIDBase(id)); + } + + private ListItem GetByIDBase(int id) + { + return base.GetByID(id); + } + + private void ResetCache(int id) + { + _listItemCache.Reset(id.ToString()); + } + + #endregion + + + } + + public class ListItemDao : AbstractDao + { + #region Constructor + + public ListItemDao(int tenantID) + : base(tenantID) + { + + + } + + #endregion + + + + public bool IsExist(ListType listType, String title) + { + var q = new SqlQuery("crm_list_item") + .Select("1") + .Where("tenant_id", TenantID) + .Where("list_type", (int)listType) + .Where("title", title) + .SetMaxResults(1); + + return Db.ExecuteScalar(q); + } + + public bool IsExist(int id) + { + return Db.ExecuteScalar("select exists(select 1 from crm_list_item where tenant_id = @tid and id = @id)", + new { tid = TenantID, id = id }); + } + + public List GetItems() + { + var sqlQuery = GetListItemSqlQuery(null).OrderBy("sort_order", true); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToListItem); + } + + public List GetItems(ListType listType) + { + var sqlQuery = GetListItemSqlQuery(Exp.Eq("list_type", (int)listType)) + .OrderBy("sort_order", true); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToListItem); + } + + public int GetItemsCount(ListType listType) + { + SqlQuery sqlQuery = Query("crm_list_item").SelectCount().Where(Exp.Eq("list_type", (int)listType)) + .OrderBy("sort_order", true); + + return Db.ExecuteScalar(sqlQuery); + } + + public ListItem GetSystemListItem(int id) + { + switch (id) + { + case (int)HistoryCategorySystem.TaskClosed: + return new ListItem + { + ID = -1, + Title = HistoryCategorySystem.TaskClosed.ToLocalizedString(), + AdditionalParams = "event_category_close.png" + }; + case (int)HistoryCategorySystem.FilesUpload: + return new ListItem + { + ID = -2, + Title = HistoryCategorySystem.FilesUpload.ToLocalizedString(), + AdditionalParams = "event_category_attach_file.png" + }; + case (int)HistoryCategorySystem.MailMessage: + return new ListItem + { + ID = -3, + Title = HistoryCategorySystem.MailMessage.ToLocalizedString(), + AdditionalParams = "event_category_email.png" + }; + default: + return null; + } + + } + + public List GetSystemItems() + { + return new List + { + new ListItem + { + ID = (int)HistoryCategorySystem.TaskClosed, + Title = HistoryCategorySystem.TaskClosed.ToLocalizedString(), + AdditionalParams = "event_category_close.png" + }, + new ListItem + { + ID = (int)HistoryCategorySystem.FilesUpload, + Title = HistoryCategorySystem.FilesUpload.ToLocalizedString(), + AdditionalParams = "event_category_attach_file.png" + }, + new ListItem + { + ID =(int)HistoryCategorySystem.MailMessage, + Title = HistoryCategorySystem.MailMessage.ToLocalizedString(), + AdditionalParams = "event_category_email.png" + } + }; + } + + public virtual ListItem GetByID(int id) + { + if (id < 0) return GetSystemListItem(id); + + var result = Db.ExecuteList(GetListItemSqlQuery(Exp.Eq("id", id))).ConvertAll(ToListItem); + + return result.Count > 0 ? result[0] : null; + } + + public virtual List GetItems(int[] id) + { + var sqlResult = Db.ExecuteList(GetListItemSqlQuery(Exp.In("id", id))).ConvertAll(ToListItem); + + var systemItem = id.Where(item => item < 0).Select(GetSystemListItem); + + return systemItem.Any() ? sqlResult.Union(systemItem).ToList() : sqlResult; + } + + public virtual List GetAll() + { + return Db.ExecuteList(GetListItemSqlQuery(null)).ConvertAll(ToListItem); + } + + public virtual void ChangeColor(int id, string newColor) + { + Db.ExecuteNonQuery(Update("crm_list_item") + .Set("color", newColor) + .Where(Exp.Eq("id", id))); + } + + public NameValueCollection GetColors(ListType listType) + { + var where = Exp.Eq("list_type", (int)listType); + + var result = new NameValueCollection(); + + Db.ExecuteList(Query("crm_list_item") + .Select("id", "color") + .Where(where)) + .ForEach(row => result.Add(row[0].ToString(), row[1].ToString())); + return result; + + } + + public ListItem GetByTitle(ListType listType, string title) + { + var result = Db.ExecuteList(GetListItemSqlQuery(Exp.Eq("title", title) & Exp.Eq("list_type", (int)listType))).ConvertAll(ToListItem); + + return result.Count > 0 ? result[0] : null; + } + + public int GetRelativeItemsCount(ListType listType, int id) + { + + SqlQuery sqlQuery; + + + switch (listType) + { + case ListType.ContactStatus: + sqlQuery = Query("crm_contact") + .Select("count(*)") + .Where(Exp.Eq("status_id", id)); + break; + case ListType.ContactType: + sqlQuery = Query("crm_contact") + .Select("count(*)") + .Where(Exp.Eq("contact_type_id", id)); + break; + case ListType.TaskCategory: + sqlQuery = Query("crm_task") + .Select("count(*)") + .Where(Exp.Eq("category_id", id)); + break; + case ListType.HistoryCategory: + sqlQuery = Query("crm_relationship_event") + .Select("count(*)") + .Where(Exp.Eq("category_id", id)); + + break; + default: + throw new ArgumentException(); + + } + + return Db.ExecuteScalar(sqlQuery); + } + + public Dictionary GetRelativeItemsCount(ListType listType) + { + var sqlQuery = Query("crm_list_item tbl_list_item") + .Where(Exp.Eq("tbl_list_item.list_type", (int)listType)) + .Select("tbl_list_item.id") + .OrderBy("tbl_list_item.sort_order", true) + .GroupBy("tbl_list_item.id"); + + switch (listType) + { + case ListType.ContactStatus: + sqlQuery.LeftOuterJoin("crm_contact tbl_crm_contact", + Exp.EqColumns("tbl_list_item.id", "tbl_crm_contact.status_id") + & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_contact.tenant_id")) + .Select("count(tbl_crm_contact.status_id)"); + break; + case ListType.ContactType: + sqlQuery.LeftOuterJoin("crm_contact tbl_crm_contact", + Exp.EqColumns("tbl_list_item.id", "tbl_crm_contact.contact_type_id") + & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_contact.tenant_id")) + .Select("count(tbl_crm_contact.contact_type_id)"); + break; + case ListType.TaskCategory: + sqlQuery.LeftOuterJoin("crm_task tbl_crm_task", + Exp.EqColumns("tbl_list_item.id", "tbl_crm_task.category_id") + & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_task.tenant_id")) + .Select("count(tbl_crm_task.category_id)"); + break; + case ListType.HistoryCategory: + sqlQuery.LeftOuterJoin("crm_relationship_event tbl_crm_relationship_event", + Exp.EqColumns("tbl_list_item.id", "tbl_crm_relationship_event.category_id") + & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_relationship_event.tenant_id")) + .Select("count(tbl_crm_relationship_event.category_id)"); + + break; + default: + throw new ArgumentException(); + } + + var queryResult = Db.ExecuteList(sqlQuery); + + return queryResult.ToDictionary(x => Convert.ToInt32(x[0]), y => Convert.ToInt32(y[1])); + } + + public virtual int CreateItem(ListType listType, ListItem enumItem) + { + + if (IsExist(listType, enumItem.Title)) + return GetByTitle(listType, enumItem.Title).ID; + + if (string.IsNullOrEmpty(enumItem.Title)) + throw new ArgumentException(); + + if (listType == ListType.TaskCategory || listType == ListType.HistoryCategory) + if (string.IsNullOrEmpty(enumItem.AdditionalParams)) + throw new ArgumentException(); + else + enumItem.AdditionalParams = System.IO.Path.GetFileName(enumItem.AdditionalParams); + + if (listType == ListType.ContactStatus) + if (string.IsNullOrEmpty(enumItem.Color)) + throw new ArgumentException(); + + var sortOrder = enumItem.SortOrder; + + if (sortOrder == 0) + sortOrder = Db.ExecuteScalar(Query("crm_list_item") + .Where(Exp.Eq("list_type", (int)listType)) + .SelectMax("sort_order")) + 1; + + return Db.ExecuteScalar( + Insert("crm_list_item") + .InColumnValue("id", 0) + .InColumnValue("list_type", (int)listType) + .InColumnValue("description", enumItem.Description) + .InColumnValue("title", enumItem.Title) + .InColumnValue("additional_params", enumItem.AdditionalParams) + .InColumnValue("color", enumItem.Color) + .InColumnValue("sort_order", sortOrder) + .Identity(1, 0, true)); + } + + public virtual void EditItem(ListType listType, ListItem enumItem) + { + + if (HaveRelativeItemsLink(listType, enumItem.ID)) + switch (listType) + { + case ListType.ContactStatus: + case ListType.ContactType: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.HasRelatedContacts)); + case ListType.TaskCategory: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.TaskCategoryHasRelatedTasks)); + case ListType.HistoryCategory: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.HistoryCategoryHasRelatedEvents)); + default: + throw new ArgumentException(string.Format("{0}.", CRMErrorsResource.BasicCannotBeEdited)); + } + + Db.ExecuteNonQuery(Update("crm_list_item") + .Set("description", enumItem.Description) + .Set("title", enumItem.Title) + .Set("additional_params", enumItem.AdditionalParams) + .Set("color", enumItem.Color) + .Where(Exp.Eq("id", enumItem.ID))); + } + + public virtual void ChangePicture(int id, String newPicture) + { + Db.ExecuteNonQuery(Update("crm_list_item") + .Set("additional_params", newPicture) + .Where(Exp.Eq("id", id))); + } + + private bool HaveRelativeItemsLink(ListType listType, int itemID) + { + SqlQuery sqlQuery; + + switch (listType) + { + + case ListType.ContactStatus: + sqlQuery = Query("crm_contact") + .Where(Exp.Eq("status_id", itemID)); + break; + case ListType.ContactType: + sqlQuery = Query("crm_contact") + .Where(Exp.Eq("contact_type_id", itemID)); + + break; + case ListType.TaskCategory: + sqlQuery = Query("crm_task") + .Where(Exp.Eq("category_id", itemID)); + break; + case ListType.HistoryCategory: + sqlQuery = Query("crm_relationship_event") + .Where(Exp.Eq("category_id", itemID)); + break; + default: + throw new ArgumentException(); + } + + return Db.ExecuteScalar(sqlQuery.SelectCount()) > 0; + } + + public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toItemID) + { + if (!IsExist(fromItemID)) + throw new ArgumentException("", "toItemID"); + + if (!HaveRelativeItemsLink(listType, fromItemID)) return; + + if (!IsExist(toItemID)) + throw new ArgumentException("", "toItemID"); + + SqlUpdate sqlUpdate; + + switch (listType) + { + case ListType.ContactStatus: + sqlUpdate = Update("crm_contact") + .Set("status_id", toItemID) + .Where(Exp.Eq("status_id", fromItemID)); + break; + case ListType.ContactType: + sqlUpdate = Update("crm_contact") + .Set("contact_type_id", toItemID) + .Where(Exp.Eq("contact_type_id", fromItemID)); + break; + case ListType.TaskCategory: + sqlUpdate = Update("crm_task") + .Set("category_id", toItemID) + .Where(Exp.Eq("category_id", fromItemID)); + break; + case ListType.HistoryCategory: + sqlUpdate = Update("crm_relationship_event") + .Set("category_id", toItemID) + .Where(Exp.Eq("category_id", fromItemID)); + break; + default: + throw new ArgumentException(); + } + + Db.ExecuteNonQuery(sqlUpdate); + } + + public virtual void DeleteItem(ListType listType, int itemID, int toItemID) + { + if (HaveRelativeItemsLink(listType, itemID)) + { + switch (listType) + { + case ListType.ContactStatus: + case ListType.ContactType: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.HasRelatedContacts)); + case ListType.TaskCategory: + var exMsg = string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.TaskCategoryHasRelatedTasks); + if (itemID == toItemID) throw new ArgumentException(exMsg); + ChangeRelativeItemsLink(listType, itemID, toItemID); + break; + case ListType.HistoryCategory: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.HistoryCategoryHasRelatedEvents)); + default: + throw new ArgumentException(string.Format("{0}.", CRMErrorsResource.BasicCannotBeDeleted)); + } + } + + Db.ExecuteNonQuery(Delete("crm_list_item").Where(Exp.Eq("id", itemID) & Exp.Eq("list_type", (int)listType))); + } + + public virtual void ReorderItems(ListType listType, String[] titles) + { + using (var tx = Db.BeginTransaction()) + { + for (int index = 0; index < titles.Length; index++) + Db.ExecuteNonQuery(Update("crm_list_item") + .Set("sort_order", index) + .Where(Exp.Eq("title", titles[index]) & Exp.Eq("list_type", (int)listType))); + + tx.Commit(); + } + } + + private SqlQuery GetListItemSqlQuery(Exp where) + { + var result = Query("crm_list_item") + .Select( + "id", + "title", + "description", + "color", + "sort_order", + "additional_params", + "list_type" + ); + + if (where != null) + result.Where(where); + + return result; + + } + + public static ListItem ToListItem(object[] row) + { + var result = new ListItem + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + Description = Convert.ToString(row[2]), + Color = Convert.ToString(row[3]), + SortOrder = Convert.ToInt32(row[4]), + AdditionalParams = Convert.ToString(row[5]) + }; + + ListType listType; + if (Enum.TryParse(Convert.ToString(row[6]), out listType)) + { + result.ListType = listType; + } + + return result; + } + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs new file mode 100644 index 00000000000..3a64e6e717e --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs @@ -0,0 +1,238 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Globalization; +using ASC.Collections; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.Web.CRM.Classes; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.CRM.Core.Entities; + + +#endregion + +namespace ASC.CRM.Core.Dao +{ + + public class CachedListItemHistory : ListItemHistoryDao + { + + #region Members + + private readonly HttpRequestDictionary _listItemHistoryCache = new HttpRequestDictionary("crm_list_item_history"); + + #endregion + + #region Constructor + + public CachedListItemHistory(int tenantId, DaoFactory factory) + : base(tenantId, factory) + { + + } + + #endregion + + #region Members + + public override ListItemHistory GetByID(int id) + { + return _listItemHistoryCache.Get(id.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(id)); + } + + private ListItemHistory GetByIDBase(int id) + { + return base.GetByID(id); + } + + private void ResetCache(int id) + { + _listItemHistoryCache.Reset(id.ToString(CultureInfo.InvariantCulture)); + } + + #endregion + + + } + + public class ListItemHistoryDao : AbstractDao + { + #region Constructor + + private DaoFactory DaoFactory { get; set; } + + public ListItemHistoryDao(int tenantId, DaoFactory daoFactory) + : base(tenantId) + { + DaoFactory = daoFactory; + } + + #endregion + + public List GetItems(EntityType entityType, int statusID, DateTime? startDate, DateTime? endDate) + { + var sqlQuery = GetListItemSqlQuery(Exp.Eq("entity_type", (int)entityType) & Exp.Eq("status", statusID)); + + if (startDate.HasValue) + sqlQuery.Where(Exp.Gt("modifed_on", startDate)); + + if (endDate.HasValue) + sqlQuery.Where(Exp.Lt("modifed_on", endDate)); + + return Db.ExecuteList(sqlQuery.OrderBy("entity_id", true)) + .ConvertAll(ToListItemHistory); + } + + public int GetItemsCount(EntityType entityType, int statusID, DateTime? startDate, DateTime? endDate) + { + var sqlQuery = Query("crm_item_history") + .SelectCount() + .Where(Exp.Eq("entity_type", (int) entityType) & Exp.Eq("status", statusID)); + + if (startDate.HasValue) + sqlQuery.Where(Exp.Gt("modifed_on", startDate)); + + if (endDate.HasValue) + sqlQuery.Where(Exp.Lt("modifed_on", endDate)); + + return Db.ExecuteScalar(sqlQuery); + } + + public virtual ListItemHistory GetByID(int id) + { + var sqlQuery = GetListItemSqlQuery(Exp.Eq("id", id)); + + var result = Db.ExecuteList(sqlQuery).ConvertAll(ToListItemHistory); + + return result.Count > 0 ? result[0] : null; + } + + public virtual List GetAll(EntityType entityType) + { + var sqlQuery = GetListItemSqlQuery(Exp.Eq("entity_type", (int) entityType)) + .OrderBy("entity_id", true); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToListItemHistory); + } + + public virtual int CreateItem(ListItemHistory item) + { + if (item.EntityType != EntityType.Opportunity || item.EntityType != EntityType.Contact) + throw new ArgumentException(); + + if (item.EntityType == EntityType.Opportunity && + (DaoFactory.DealDao.GetByID(item.EntityID) == null || + DaoFactory.DealMilestoneDao.GetByID(item.StatusID) == null)) + throw new ArgumentException(); + + if (item.EntityType == EntityType.Contact && + (DaoFactory.ContactDao.GetByID(item.EntityID) == null || + DaoFactory.ListItemDao.GetByID(item.StatusID) == null)) + throw new ArgumentException(); + + var sqlQuery = Insert("crm_item_history") + .InColumnValue("id", 0) + .InColumnValue("entity_id", item.EntityID) + .InColumnValue("entity_type", (int) item.EntityType) + .InColumnValue("status", item.StatusID) + .InColumnValue("modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .InColumnValue("modifed_by", SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true); + + return Db.ExecuteScalar(sqlQuery); + } + + public virtual void DeleteItem(EntityType entityType, int statusID) + { + if (HaveRelativeItems(entityType, statusID)) + throw new ArgumentException(); + + var sqlQuery = Delete("crm_item_history") + .Where(Exp.Eq("entity_type", (int) entityType) & Exp.Eq("status", statusID)); + + Db.ExecuteNonQuery(sqlQuery); + } + + private bool HaveRelativeItems(EntityType entityType, int statusID) + { + SqlQuery sqlQuery; + + switch (entityType) + { + case EntityType.Contact: + sqlQuery = Query("crm_contact") + .Where(Exp.Eq("status_id", statusID)); + break; + case EntityType.Opportunity: + sqlQuery = Query("crm_deal") + .Where(Exp.Eq("deal_milestone_id", statusID)); + break; + default: + throw new ArgumentException(); + } + + return Db.ExecuteScalar(sqlQuery.SelectCount()) > 0; + } + + private SqlQuery GetListItemSqlQuery(Exp where) + { + var result = Query("crm_list_item_history") + .Select( + "id", + "entity_id", + "entity_type", + "status", + "modifed_on", + "modifed_by" + ); + + if (where != null) + result.Where(where); + + return result; + + } + + public static ListItemHistory ToListItemHistory(object[] row) + { + return new ListItemHistory + { + ID = Convert.ToInt32(row[0]), + EntityID = Convert.ToInt32(row[1]), + EntityType = (EntityType)Convert.ToInt32(row[2]), + StatusID = Convert.ToInt32(row[3]), + ModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[4].ToString())), + ModifedBy = ToGuid(row[5]), + }; + } + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs b/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs new file mode 100644 index 00000000000..cbba83fa91a --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs @@ -0,0 +1,93 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.CRM.Core.Entities; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core.Users; +using ASC.Files.Core; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Configuration; +using ASC.Web.Files.Api; +using ASC.Web.Studio.Helpers; +using ASC.Web.Studio.Utility; +using log4net; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + + public class ManagerDao : AbstractDao + { + + #region Constructor + + public ManagerDao(int tenantID, String storageKey) + : base(tenantID, storageKey) + { + + + } + + #endregion + + #region Methods + + public void Add(Guid managerID) + { + DbManager.ExecuteNonQuery(Insert("crm_manager").InColumnValue("id", managerID)); + + } + + public void Remove(Guid managerID) + { + + DbManager.ExecuteNonQuery(Delete("crm_manager").Where(Exp.Eq("id", managerID))); + + } + + public List GetAll(bool includeAdmins) + { + + var managers = DbManager.ExecuteList(Query("crm_manager").Select("id")).ConvertAll(row=> ASC.Core.CoreContext.UserManager.GetUsers(ToGuid(row[0]))); + + if (includeAdmins) + return managers.Union(ASC.Core.CoreContext.UserManager.GetUsersByGroup(Constants.GroupAdmin.ID)).Distinct().ToList(); + + return managers; + } + + #endregion + + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs new file mode 100644 index 00000000000..8812af3e59d --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -0,0 +1,660 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; + +using ASC.Collections; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.Files.Core; + +using ASC.Web.CRM; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Core.Search; +using ASC.Web.Files.Api; +using ASC.Web.Studio.Core; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +using OrderBy = ASC.CRM.Core.Entities.OrderBy; +using File = ASC.Files.Core.File; +using ASC.CRM.Core.Enums; + +namespace ASC.CRM.Core.Dao +{ + + public class CachedRelationshipEventDao : RelationshipEventDao + { + #region Import + + private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_relationshipEvent"); + + #endregion + + #region Constructor + + public CachedRelationshipEventDao(int tenantID) + : base(tenantID) + { + + } + + + #endregion + + #region Methods + + public override RelationshipEvent GetByID(int eventID) + { + return _contactCache.Get(eventID.ToString(), () => GetByIDBase(eventID)); + + } + + private RelationshipEvent GetByIDBase(int eventID) + { + return base.GetByID(eventID); + } + + private void ResetCache(int dealID) + { + _contactCache.Reset(dealID.ToString()); + } + + #endregion + + } + + public class RelationshipEventDao : AbstractDao + { + #region Members + + + #endregion + + #region Constructor + + public RelationshipEventDao(int tenantID) + : base(tenantID) + { + + } + + #endregion + + #region Methods + + public RelationshipEvent AttachFiles(int contactID, EntityType entityType, int entityID, int[] fileIDs) + { + if (entityID > 0 && !_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + + var relationshipEvent = new RelationshipEvent + { + CategoryID = (int)HistoryCategorySystem.FilesUpload, + ContactID = contactID, + EntityType = entityType, + EntityID = entityID, + Content = HistoryCategorySystem.FilesUpload.ToLocalizedString() + }; + + relationshipEvent = CreateItem(relationshipEvent); + + AttachFiles(relationshipEvent.ID, fileIDs); + + return relationshipEvent; + } + + public void AttachFiles(int eventID, int[] fileIDs) + { + if (fileIDs.Length == 0) return; + + using (var dao = FilesIntegration.GetTagDao()) + { + var tags = fileIDs.ToList().ConvertAll(fileID => new Tag("RelationshipEvent_" + eventID, TagType.System, Guid.Empty) { EntryType = FileEntryType.File, EntryId = fileID }); + + dao.SaveTags(tags); + } + + if (fileIDs.Length > 0) + Db.ExecuteNonQuery(Update("crm_relationship_event").Set("have_files", true).Where("id", eventID)); + } + + public int GetFilesCount(int[] contactID, EntityType entityType, int entityID) + { + return GetFilesIDs(contactID, entityType, entityID).Length; + } + + private object[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID) + { + if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) + throw new ArgumentException(); + + + var sqlQuery = Query("crm_relationship_event").Select("id"); + + if (contactID != null && contactID.Length > 0) + sqlQuery.Where(Exp.In("contact_id", contactID)); + + if (entityID > 0) + sqlQuery.Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType)); + + sqlQuery.Where(Exp.Eq("have_files", true)); + + var tagNames = Db.ExecuteList(sqlQuery).ConvertAll(row => String.Format("RelationshipEvent_{0}", row[0])); + using (var tagdao = FilesIntegration.GetTagDao()) + { + return tagdao.GetTags(tagNames.ToArray(), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + } + } + + public List GetAllFiles(int[] contactID, EntityType entityType, int entityID) + { + using (var filedao = FilesIntegration.GetFileDao()) + { + var ids = GetFilesIDs(contactID, entityType, entityID); + var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); + + files.ForEach(CRMSecurity.SetAccessTo); + + return files.ToList(); + } + } + + public Dictionary> GetFiles(int[] eventID) + { + + if (eventID == null || eventID.Length == 0) + throw new ArgumentException("eventID"); + + using (var tagdao = FilesIntegration.GetTagDao()) + using (var filedao = FilesIntegration.GetFileDao()) + { + + + var findedTags = tagdao.GetTags(eventID.Select(item => String.Concat("RelationshipEvent_", item)).ToArray(), + TagType.System).Where(t => t.EntryType == FileEntryType.File); + + var filesID = findedTags.Select(t => t.EntryId).ToArray(); + + var files = 0 < filesID.Length ? filedao.GetFiles(filesID) : new List(); + + var filesTemp = new Dictionary(); + + files.ForEach(item => + { + if (!filesTemp.ContainsKey(item.ID)) + filesTemp.Add(item.ID, item); + }); + + return findedTags.Where(x => filesTemp.ContainsKey(x.EntryId)).GroupBy(x => x.TagName).ToDictionary(x => Convert.ToInt32(x.Key.Split(new[] { '_' })[1]), + x => x.Select(item => filesTemp[item.EntryId]).ToList()); + + + + } + + } + + public List GetFiles(int eventID) + { + if (eventID == 0) + throw new ArgumentException("eventID"); + + using (var tagdao = FilesIntegration.GetTagDao()) + using (var filedao = FilesIntegration.GetFileDao()) + { + var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); + + files.ForEach(CRMSecurity.SetAccessTo); + + return files.ToList(); + } + } + + private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID) + { + + if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) + { + throw new ArgumentException(); + } + + var files = GetAllFiles(contactID, entityType, entityID); + using (var dao = FilesIntegration.GetFileDao()) + { + foreach (var file in files) + { + dao.DeleteFile(file.ID); + } + } + } + + public List RemoveFile(File file) + { + CRMSecurity.DemandDelete(file); + + List eventIDs; + + using (var tagdao = FilesIntegration.GetTagDao()) + { + var tags = tagdao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); + eventIDs = tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); + } + using (var dao = FilesIntegration.GetFileDao()) + { + dao.DeleteFile(file.ID); + } + + foreach (var eventID in eventIDs) + { + if (GetFiles(eventID).Count == 0) + { + Db.ExecuteNonQuery(Update("crm_relationship_event").Set("have_files", false).Where("id", eventID)); + } + } + + Db.ExecuteNonQuery(Update("crm_invoice").Set("file_id", 0).Where("file_id", file.ID)); + + return eventIDs; + } + + + public int GetCount(int[] contactID, EntityType entityType, int entityID) + { + if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) + throw new ArgumentException(); + + var sqlQuery = Query("crm_relationship_event").SelectCount(); + + contactID = contactID.Where(item => item != 0).ToArray(); + + if (contactID.Length > 0) + sqlQuery.Where(Exp.In("contact_id", contactID)); + + if (entityID > 0) + sqlQuery.Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType)); + + return Db.ExecuteScalar(sqlQuery); + } + + public RelationshipEvent CreateItem(RelationshipEvent item) + { + CRMSecurity.DemandCreateOrUpdate(item); + + var htmlBody = String.Empty; + + if (item.CreateOn == DateTime.MinValue) + item.CreateOn = TenantUtil.DateTimeNow(); + item.CreateBy = ASC.Core.SecurityContext.CurrentAccount.ID; + item.LastModifedBy = ASC.Core.SecurityContext.CurrentAccount.ID; + + if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) + { + var jsonObj = JObject.Parse(item.Content); + var messageId = jsonObj.Value("message_id"); + + var apiServer = new Api.ApiServer(); + var msg = apiServer.GetApiResponse( + String.Format("{0}mail/messages/{1}.json?id={1}&loadImages=true&needSanitize=true", SetupInfo.WebApiBaseUrl, messageId), "GET"); + + if (msg == null) + throw new ArgumentException("Mail message cannot be found"); + + var msgResponseWrapper = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg))); + var msgRequestObj = msgResponseWrapper.Value("response"); + string messageUrl; + + htmlBody = msgRequestObj.Value("htmlBody"); + + using (var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(htmlBody))) + { + var filePath = String.Format("folder_{0}/message_{1}.html", (messageId/1000 + 1)*1000, messageId); + + Global.GetStore().Save("mail_messages",filePath,fileStream); + + messageUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=mailmessage&message_id={1}", PathProvider.BaseAbsolutePath, messageId).ToLower(); + + } + + var msg_date_created = msgRequestObj.Value("date"); + var message_id = msgRequestObj.Value("id"); + item.Content = JsonConvert.SerializeObject(new + { + @from = msgRequestObj.Value("from"), + to = msgRequestObj.Value("to"), + cc = msgRequestObj.Value("cc"), + bcc = msgRequestObj.Value("bcc"), + subject = msgRequestObj.Value("subject"), + important = msgRequestObj.Value("important"), + chain_id = msgRequestObj.Value("chainId"), + is_sended = msgRequestObj.Value("folder") != 1, + date_created = msg_date_created, + introduction = msgRequestObj.Value("introduction"), + message_id = message_id, + message_url = messageUrl + }); + + item.CreateOn = DateTime.Parse(msg_date_created, CultureInfo.InvariantCulture); + + var sqlQueryFindMailsAlready = Query("crm_relationship_event") + .SelectCount() + .Where("contact_id", item.ContactID) + .Where(Exp.Like("content", string.Format("\"message_id\":{0},", message_id))) + .Where("entity_type", (int)item.EntityType) + .Where("entity_id", item.EntityID) + .Where("category_id", item.CategoryID); + if (Db.ExecuteScalar(sqlQueryFindMailsAlready) > 0) + throw new Exception("Already exists"); + } + + + item.ID = Db.ExecuteScalar( + Insert("crm_relationship_event") + .InColumnValue("id", 0) + .InColumnValue("contact_id", item.ContactID) + .InColumnValue("content", item.Content) + .InColumnValue("create_on", TenantUtil.DateTimeToUtc(item.CreateOn)) + .InColumnValue("create_by", item.CreateBy) + .InColumnValue("entity_type", (int)item.EntityType) + .InColumnValue("entity_id", item.EntityID) + .InColumnValue("category_id", item.CategoryID) + .InColumnValue("last_modifed_on", DateTime.UtcNow) + .InColumnValue("last_modifed_by", item.LastModifedBy) + .InColumnValue("have_files", false) + .Identity(1, 0, true)); + + if (item.CreateOn.Kind == DateTimeKind.Utc) + item.CreateOn = TenantUtil.DateTimeFromUtc(item.CreateOn); + + FactoryIndexer.IndexAsync(item); + return item; + } + + public virtual RelationshipEvent GetByID(int eventID) + { + return Db.ExecuteList(GetRelationshipEventQuery(Exp.Eq("id", eventID))) + .ConvertAll(ToRelationshipEvent).FirstOrDefault(); + } + + public int GetAllItemsCount() + { + return Db.ExecuteScalar(Query("crm_relationship_event").SelectCount()); + } + + public List GetAllItems() + { + return GetItems(String.Empty, + EntityType.Any, + 0, + Guid.Empty, + 0, + DateTime.MinValue, + DateTime.MinValue, + 0, + 0, null); + } + + public List GetItems( + String searchText, + EntityType entityType, + int entityID, + Guid createBy, + int categoryID, + DateTime fromDate, + DateTime toDate, + int from, + int count, + OrderBy orderBy) + { + var sqlQuery = GetRelationshipEventQuery(null); + + if (entityID > 0) + switch (entityType) + { + case EntityType.Contact: + var isCompany = false; + isCompany = Db.ExecuteScalar(Query("crm_contact").Select("is_company").Where(Exp.Eq("id", entityID))); + + if (isCompany) + return GetItems(searchText, EntityType.Company, entityID, createBy, categoryID, fromDate, toDate, from, count, orderBy); + else + return GetItems(searchText, EntityType.Person, entityID, createBy, categoryID, fromDate, toDate, from, count, orderBy); + case EntityType.Person: + sqlQuery.Where(Exp.Eq("contact_id", entityID)); + break; + case EntityType.Company: + + var personIDs = GetRelativeToEntity(entityID, EntityType.Person, null).ToList(); + + if (personIDs.Count == 0) + sqlQuery.Where(Exp.Eq("contact_id", entityID)); + else + { + personIDs.Add(entityID); + sqlQuery.Where(Exp.In("contact_id", personIDs)); + } + + break; + case EntityType.Case: + case EntityType.Opportunity: + sqlQuery.Where(Exp.Eq("entity_id", entityID) & + Exp.Eq("entity_type", (int)entityType)); + break; + } + + if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) + sqlQuery.Where(Exp.Between("create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1)))); + else if (fromDate != DateTime.MinValue) + sqlQuery.Where(Exp.Ge("create_on", TenantUtil.DateTimeToUtc(fromDate))); + else if (toDate != DateTime.MinValue) + sqlQuery.Where(Exp.Le("create_on", TenantUtil.DateTimeToUtc(toDate).AddDays(1).AddMinutes(-1))); + + if (createBy != Guid.Empty) + sqlQuery.Where(Exp.Eq("create_by", createBy)); + + if (categoryID != 0) + sqlQuery.Where(Exp.Eq("category_id", categoryID)); + + if (!String.IsNullOrEmpty(searchText)) + { + searchText = searchText.Trim(); + + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + .ToArray(); + + List eventsIds; + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out eventsIds)) + { + if (keywords.Length > 0) + sqlQuery.Where(BuildLike(new[] { "content" }, keywords)); + } + else + { + if (eventsIds.Count == 0) return new List(); + sqlQuery.Where(Exp.In("id", eventsIds)); + } + } + + if (0 < from && from < int.MaxValue) + sqlQuery.SetFirstResult(from); + + if (0 < count && count < int.MaxValue) + sqlQuery.SetMaxResults(count); + + if (orderBy != null && Enum.IsDefined(typeof(RelationshipEventByType), orderBy.SortedBy)) + switch ((RelationshipEventByType)orderBy.SortedBy) + { + + case RelationshipEventByType.Category: + sqlQuery.OrderBy("category_id", orderBy.IsAsc); + break; + case RelationshipEventByType.Content: + sqlQuery.OrderBy("content", orderBy.IsAsc); + break; + case RelationshipEventByType.CreateBy: + sqlQuery.OrderBy("create_by", orderBy.IsAsc); + break; + case RelationshipEventByType.Created: + sqlQuery.OrderBy("create_on", orderBy.IsAsc); + break; + } + else + sqlQuery.OrderBy("create_on", false); + + return Db.ExecuteList(sqlQuery) + .ConvertAll(row => ToRelationshipEvent(row)); + } + + + private static RelationshipEvent ToRelationshipEvent(object[] row) + { + return new RelationshipEvent + { + + ID = Convert.ToInt32(row[0]), + ContactID = Convert.ToInt32(row[1]), + Content = Convert.ToString(row[2]), + EntityID = Convert.ToInt32(row[3]), + EntityType = (EntityType)Convert.ToInt32(row[4]), + CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[5])), + CreateBy = ToGuid(row[6]), + CategoryID = Convert.ToInt32(row[7]) + }; + } + + private SqlQuery GetRelationshipEventQuery(Exp where) + { + SqlQuery sqlQuery = Query("crm_relationship_event") + .Select("id", + "contact_id", + "content", + "entity_id", + "entity_type", + "create_on", + "create_by", + "category_id" + ); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + } + + public void DeleteItem(int id) + { + var item = GetByID(id); + if (item == null) throw new ArgumentException(); + + DeleteItem(item); + } + + public void DeleteItem(RelationshipEvent item) + { + CRMSecurity.DemandDelete(item); + + var relativeFiles = GetFiles(item.ID); + + var nowFilesEditing = relativeFiles.Where(file => (file.FileStatus & FileStatus.IsEditing) == FileStatus.IsEditing); + + if (nowFilesEditing.Count() != 0) + throw new ArgumentException(); + + relativeFiles.ForEach(f => RemoveFile(f)); + + Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.Eq("id", item.ID))); + + FactoryIndexer.DeleteAsync(item); + } + + #endregion + + [DataContract] + internal class CrmHistoryContent + { + [DataMember] + public string to; + [DataMember] + public string from; + [DataMember] + public string cc; + [DataMember] + public string bcc; + [DataMember] + public string subject; + [DataMember] + public bool important; + [DataMember] + public string chain_id; + [DataMember] + public bool is_sended; + [DataMember] + public string date_created; + [DataMember] + public string introduction; + [DataMember] + public long message_id; + } + + private static string GetHistoryContentJson(JObject apiResponse) + { + var content_struct = new CrmHistoryContent + { + @from = apiResponse.Value("from"), + to = apiResponse.Value("to"), + cc = apiResponse.Value("cc"), + bcc = apiResponse.Value("bcc"), + subject = apiResponse.Value("subject"), + important = apiResponse.Value("important"), + chain_id = apiResponse.Value("chainId"), + is_sended = apiResponse.Value("folder") == 1, + date_created = apiResponse.Value("date"), + introduction = apiResponse.Value("introduction"), + message_id = apiResponse.Value("id") + }; + + var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent)); + using (var stream = new MemoryStream()) + { + serializer.WriteObject(stream, content_struct); + return Encoding.UTF8.GetString(stream.ToArray()); + } + } + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs new file mode 100644 index 00000000000..930895e2301 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -0,0 +1,2231 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.Data.Storage.S3; +using ASC.VoipService; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Resources; +using ASC.CRM.Core.Entities; +using ASC.Web.Files.Api; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; + + +#endregion + +namespace ASC.CRM.Core.Dao +{ + public class ReportDao : AbstractDao + { + const string TimeFormat = "[h]:mm:ss;@"; + const string ShortDateFormat = "M/d/yyyy"; + + private DaoFactory DaoFactory {get; set; } + + #region Constructor + + public ReportDao(int tenantID, DaoFactory daoFactory) + : base(tenantID) + { + this.DaoFactory = daoFactory; + } + + #endregion + + + #region Common Methods + + private static void GetTimePeriod(ReportTimePeriod timePeriod, out DateTime fromDate, out DateTime toDate) + { + var now = TenantUtil.DateTimeNow().Date; + + var diff = (int)now.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; + if (diff < 0) + { + diff += 7; + } + + var quarter = (now.Month + 2) / 3; + + var year = now.Year; + + switch (timePeriod) + { + case ReportTimePeriod.Today: + fromDate = now; + toDate = now.AddDays(1).AddSeconds(-1); + break; + case ReportTimePeriod.Yesterday: + fromDate = now.AddDays(-1); + toDate = now.AddSeconds(-1); + break; + case ReportTimePeriod.Tomorrow: + fromDate = now.AddDays(1); + toDate = now.AddDays(2).AddSeconds(-1); + break; + case ReportTimePeriod.CurrentWeek: + fromDate = now.AddDays(-1 * diff); + toDate = now.AddDays(-1 * diff + 7).AddSeconds(-1); + break; + case ReportTimePeriod.PreviousWeek: + fromDate = now.AddDays(-1 * diff - 7); + toDate = now.AddDays(-1 * diff).AddSeconds(-1); + break; + case ReportTimePeriod.NextWeek: + fromDate = now.AddDays(-1 * diff + 7); + toDate = now.AddDays(-1 * diff + 14).AddSeconds(-1); + break; + case ReportTimePeriod.CurrentMonth: + fromDate = new DateTime(now.Year, now.Month, 1); + toDate = new DateTime(now.Year, now.Month, 1).AddMonths(1).AddSeconds(-1); + break; + case ReportTimePeriod.PreviousMonth: + toDate = new DateTime(now.Year, now.Month, 1).AddSeconds(-1); + fromDate = new DateTime(toDate.Year, toDate.Month, 1); + break; + case ReportTimePeriod.NextMonth: + fromDate = new DateTime(now.Year, now.Month, 1).AddMonths(1); + toDate = new DateTime(now.Year, now.Month, 1).AddMonths(2).AddSeconds(-1); + break; + case ReportTimePeriod.CurrentQuarter: + fromDate = new DateTime(now.Year, quarter * 3 - 2, 1); + toDate = new DateTime(now.Year, fromDate.Month, 1).AddMonths(3).AddSeconds(-1); + break; + case ReportTimePeriod.PreviousQuarter: + quarter--; + if (quarter == 0) + { + year--; + quarter = 4; + } + fromDate = new DateTime(year, quarter * 3 - 2, 1); + toDate = new DateTime(year, fromDate.Month, 1).AddMonths(3).AddSeconds(-1); + break; + case ReportTimePeriod.NextQuarter: + quarter++; + if (quarter == 5) + { + year++; + quarter = 1; + } + fromDate = new DateTime(year, quarter * 3 - 2, 1); + toDate = new DateTime(year, fromDate.Month, 1).AddMonths(3).AddSeconds(-1); + break; + case ReportTimePeriod.CurrentYear: + fromDate = new DateTime(now.Year, 1, 1); + toDate = new DateTime(now.Year, 1, 1).AddYears(1).AddSeconds(-1); + break; + case ReportTimePeriod.PreviousYear: + toDate = new DateTime(now.Year, 1, 1).AddSeconds(-1); + fromDate = new DateTime(toDate.Year, 1, 1); + break; + case ReportTimePeriod.NextYear: + fromDate = new DateTime(now.Year, 1, 1).AddYears(1); + toDate = new DateTime(now.Year, 1, 1).AddYears(2).AddSeconds(-1); + break; + case ReportTimePeriod.DuringAllTime: + fromDate = DateTime.MinValue; + toDate = DateTime.MaxValue; + break; + default: + fromDate = DateTime.MinValue; + toDate = DateTime.MinValue; + break; + } + } + + private static string GetTimePeriodText(ReportTimePeriod timePeriod) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + switch (timePeriod) + { + case ReportTimePeriod.Today: + case ReportTimePeriod.Yesterday: + case ReportTimePeriod.Tomorrow: + return fromDate.ToShortDateString(); + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.PreviousWeek: + case ReportTimePeriod.NextWeek: + return string.Format("{0}-{1}", fromDate.ToShortDateString(), toDate.ToShortDateString()); + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.PreviousMonth: + case ReportTimePeriod.NextMonth: + return fromDate.ToString("Y"); + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.PreviousQuarter: + case ReportTimePeriod.NextQuarter: + return string.Format("{0}-{1}", fromDate.ToString("Y"), toDate.ToString("Y")); + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.PreviousYear: + case ReportTimePeriod.NextYear: + return fromDate.Year.ToString(CultureInfo.InvariantCulture); + case ReportTimePeriod.DuringAllTime: + return CRMReportResource.DuringAllTime; + default: + return string.Empty; + } + } + + public List GetMissingRates(string defaultCurrency) + { + var existingRatesQuery = Query("crm_currency_rate r") + .Select("distinct r.from_currency") + .Where("r.to_currency", defaultCurrency); + + var missingRatesQuery = Query("crm_deal d") + .Select("distinct d.bid_currency") + .Where(!Exp.Eq("d.bid_currency", defaultCurrency)) + .Where(!Exp.In("d.bid_currency", existingRatesQuery)); + + + return Db.ExecuteList(missingRatesQuery).ConvertAll(row => row[0].ToString()); + } + + #endregion + + + #region Report Files + + public List SaveSampleReportFiles() + { + var result = new List(); + + var storeTemplate = Global.GetStoreTemplate(); + + if (storeTemplate == null) return result; + + var culture = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture() ?? + CoreContext.TenantManager.GetCurrentTenant().GetCulture(); + + var path = culture + "/"; + + if (!storeTemplate.IsDirectory(path)) + { + path = "default/"; + if (!storeTemplate.IsDirectory(path)) return result; + } + + foreach (var filePath in storeTemplate.ListFilesRelative("", path, "*", false).Select(x => path + x)) + { + using (var stream = storeTemplate.GetReadStream("", filePath)) + { + var document = new Files.Core.File + { + Title = Path.GetFileName(filePath), + FolderID = DaoFactory.FileDao.GetRoot(), + ContentLength = stream.Length + }; + + var file = DaoFactory.FileDao.SaveFile(document, stream); + + SaveFile((int) file.ID, -1); + + result.Add(file); + } + } + + return result; + } + + public List GetFiles() + { + return GetFiles(SecurityContext.CurrentAccount.ID); + } + + public List GetFiles(Guid userId) + { + var query = Query("crm_report_file") + .Select("file_id") + .Where("create_by", userId); + + using (var filedao = FilesIntegration.GetFileDao()) + { + var fileIds = Db.ExecuteList(query).ConvertAll(row => row[0]).ToArray(); + return fileIds.Length > 0 ? filedao.GetFiles(fileIds) : new List(); + } + } + + public List GetFileIds(Guid userId) + { + var query = Query("crm_report_file") + .Select("file_id") + .Where("create_by", userId); + + return Db.ExecuteList(query).ConvertAll(row => Convert.ToInt32(row[0])); + } + + public Files.Core.File GetFile(int fileid) + { + return GetFile(fileid, SecurityContext.CurrentAccount.ID); + } + + public Files.Core.File GetFile(int fileid, Guid userId) + { + var query = Query("crm_report_file") + .SelectCount() + .Where("file_id", fileid) + .Where("create_by", userId); + + using (var filedao = FilesIntegration.GetFileDao()) + { + return Db.ExecuteScalar(query) > 0 ? filedao.GetFile(fileid) : null; + } + } + + public void DeleteFile(int fileid) + { + var query = Delete("crm_report_file") + .Where("file_id", fileid) + .Where("create_by", SecurityContext.CurrentAccount.ID); + + using (var filedao = FilesIntegration.GetFileDao()) + { + Db.ExecuteNonQuery(query); + filedao.DeleteFile(fileid); + } + } + + public void DeleteFiles(Guid userId) + { + var fileIds = GetFileIds(userId); + + var query = Delete("crm_report_file") + .Where("create_by", userId); + + using (var filedao = FilesIntegration.GetFileDao()) + { + Db.ExecuteNonQuery(query); + + foreach (var fileId in fileIds) + { + filedao.DeleteFile(fileId); + } + } + } + + public void SaveFile(int fileId, int reportType) + { + Db.ExecuteScalar( + Insert("crm_report_file") + .InColumnValue("file_id", fileId) + .InColumnValue("report_type", reportType) + .InColumnValue("create_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + } + + #endregion + + + #region SalesByManagersReport + + public bool CheckSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_deal d") + .Select("d.id") + .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) + .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + return Db.ExecuteList(sqlQuery).Any(); + } + + public object GetSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSalesByManagersReport(timePeriod, managers, defaultCurrency); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildSalesByManagersReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + string dateSelector; + + switch (timePeriod) + { + case ReportTimePeriod.Today: + case ReportTimePeriod.Yesterday: + dateSelector = "date_add(date(d.actual_close_date), interval extract(hour from d.actual_close_date) hour) as close_date"; + break; + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.PreviousWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.PreviousMonth: + dateSelector = "date(d.actual_close_date) as close_date"; + break; + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.PreviousQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.PreviousYear: + dateSelector = "date_sub(date(d.actual_close_date), interval (extract(day from d.actual_close_date) - 1) day) as close_date"; + break; + default: + return null; + } + + var sqlQuery = Query("crm_deal d") + .Select("d.responsible_id", + "concat(u.firstname, ' ', u.lastname) as full_name", + string.Format(@"sum((case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end)) as bid_value", defaultCurrency), + dateSelector) + .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) + .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) + .Where("m.status", (int) DealMilestoneStatus.ClosedAndWon) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("responsible_id", "close_date"); + + + return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesByManagers); + } + + private static SalesByManager ToSalesByManagers(object[] row) + { + return new SalesByManager + { + UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + UserName = Convert.ToString(row[1]), + Value = Convert.ToDecimal(row[2]), + Date = Convert.ToDateTime(row[3]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[3])) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + switch (timePeriod) + { + case ReportTimePeriod.Today: + case ReportTimePeriod.Yesterday: + return GenerateReportDataByHours(timePeriod, data); + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.PreviousWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.PreviousMonth: + return GenerateReportDataByDays(timePeriod, data); + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.PreviousQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.PreviousYear: + return GenerateReportByMonths(timePeriod, data); + default: + return null; + } + } + + private static object GenerateReportDataByHours(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var res = new Dictionary>(); + + var users = data.Select(x => x.UserId).Distinct().ToList(); + + foreach (var userId in users) + { + var date = fromDate; + + while (date < toDate) + { + if (res.ContainsKey(userId)) + { + res[userId].Add(date, 0); + } + else + { + res.Add(userId, new Dictionary {{date, 0}}); + } + + date = date.AddHours(1); + } + } + + foreach (var item in data) + { + var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day, item.Date.Hour, 0, 0); + + if (itemDate < res[item.UserId].First().Key) + itemDate = res[item.UserId].First().Key; + + if (itemDate > res[item.UserId].Last().Key) + itemDate = res[item.UserId].Last().Key; + + res[item.UserId][itemDate] += item.Value; + } + + var body = new List>(); + + foreach (var resItem in res) + { + var bodyItem = new List + { + data.First(x => x.UserId == resItem.Key).UserName + }; + + bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + + body.Add(bodyItem); + } + + var head = new List(); + + foreach (var key in res.First().Value.Keys) + { + head.Add(new {format = "H:mm", value = key.ToShortTimeString()}); + } + + return new + { + resource = new + { + manager = CRMReportResource.Manager, + summary = CRMReportResource.Sum, + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesByManagersReport, + header = CRMReportResource.SalesByManagersReport, + header1 = CRMReportResource.SalesByHour + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByHour + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } + + private static object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var res = new Dictionary>(); + + var users = data.Select(x => x.UserId).Distinct().ToList(); + + foreach (var userId in users) + { + var date = fromDate; + + while (date < toDate) + { + if (res.ContainsKey(userId)) + { + res[userId].Add(date, 0); + } + else + { + res.Add(userId, new Dictionary { { date, 0 } }); + } + + date = date.AddDays(1); + } + } + + foreach (var item in data) + { + var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); + + if (itemDate < res[item.UserId].First().Key) + itemDate = res[item.UserId].First().Key; + + if (itemDate > res[item.UserId].Last().Key) + itemDate = res[item.UserId].Last().Key; + + res[item.UserId][itemDate] += item.Value; + } + + var body = new List>(); + + foreach (var resItem in res) + { + var bodyItem = new List + { + data.First(x => x.UserId == resItem.Key).UserName + }; + + bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + + body.Add(bodyItem); + } + + var head = new List(); + var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); + var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); + + foreach (var key in res.First().Value.Keys) + { + head.Add(new { format = pattern, value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); + } + + return new + { + resource = new + { + manager = CRMReportResource.Manager, + summary = CRMReportResource.Sum, + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesByManagersReport, + header = CRMReportResource.SalesByManagersReport, + header1 = CRMReportResource.SalesByDay + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByDay + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } + + private static object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var res = new Dictionary>(); + + var users = data.Select(x => x.UserId).Distinct().ToList(); + + foreach (var userId in users) + { + var date = fromDate; + + while (date < toDate) + { + if (res.ContainsKey(userId)) + { + res[userId].Add(date, 0); + } + else + { + res.Add(userId, new Dictionary { { date, 0 } }); + } + + date = date.AddMonths(1); + } + } + + foreach (var item in data) + { + var itemDate = new DateTime(item.Date.Year, item.Date.Month, 1); + + if (itemDate < res[item.UserId].First().Key) + itemDate = res[item.UserId].First().Key; + + if (itemDate > res[item.UserId].Last().Key) + itemDate = res[item.UserId].Last().Key; + + res[item.UserId][itemDate] += item.Value; + } + + var body = new List>(); + + foreach (var resItem in res) + { + var bodyItem = new List + { + data.First(x => x.UserId == resItem.Key).UserName + }; + + bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + + body.Add(bodyItem); + } + + var head = new List(); + + foreach (var key in res.First().Value.Keys) + { + head.Add(new { format = "MMM-yy", value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); + } + + return new + { + resource = new + { + manager = CRMReportResource.Manager, + summary = CRMReportResource.Sum, + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesByManagersReport, + header = CRMReportResource.SalesByManagersReport, + header1 = CRMReportResource.SalesByMonth + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByMonth + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } + + #endregion + + + #region SalesForecastReport + + public bool CheckSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_deal d") + .Select("d.id") + .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where("m.status", (int)DealMilestoneStatus.Open) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + return Db.ExecuteList(sqlQuery).Any(); + } + + public object GetSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSalesForecastReport(timePeriod, managers, defaultCurrency); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildSalesForecastReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + string dateSelector; + + switch (timePeriod) + { + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.NextWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.NextMonth: + dateSelector = "d.expected_close_date as close_date"; + break; + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.NextQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.NextYear: + dateSelector = "date_sub(date(d.expected_close_date), interval (extract(day from d.expected_close_date) - 1) day) as close_date"; + break; + default: + return null; + } + + var sqlQuery = Query("crm_deal d") + .Select(string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as value", defaultCurrency), + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 + end) as value_with_probability", defaultCurrency), + dateSelector) + .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) + .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + .Where("m.status", (int)DealMilestoneStatus.Open) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("close_date"); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesForecast); + } + + private static SalesForecast ToSalesForecast(object[] row) + { + return new SalesForecast + { + Value = Convert.ToDecimal(row[0]), + ValueWithProbability = Convert.ToDecimal(row[1]), + Date = Convert.ToDateTime(row[2]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[2])) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + switch (timePeriod) + { + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.NextWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.NextMonth: + return GenerateReportDataByDays(timePeriod, data); + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.NextQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.NextYear: + return GenerateReportByMonths(timePeriod, data); + default: + return null; + } + } + + private static object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var res = new Dictionary>(); + + var date = fromDate; + + while (date < toDate) + { + res.Add(date, new Tuple(0, 0)); + date = date.AddDays(1); + } + + foreach (var item in data) + { + var key = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); + + if (key < res.First().Key) + key = res.First().Key; + + if (key > res.Last().Key) + key = res.Last().Key; + + res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, + res[key].Item2 + item.Value); + } + + var body = new List>(); + var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); + var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); + + foreach (var resItem in res) + { + var bodyItem = new List + { + new {format = pattern, value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} + }; + + body.Add(bodyItem); + } + + var head = new List + { + CRMReportResource.Day, + CRMReportResource.WithRespectToProbability, + CRMReportResource.IfAllOpportunitiesWon + }; + + return new + { + resource = new + { + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesForecastReport, + header = CRMReportResource.SalesForecastReport, + header1 = CRMReportResource.SalesForecastReport + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName = CRMReportResource.SalesForecastReport + ", " + Global.TenantSettings.DefaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } + + private static object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var res = new Dictionary>(); + + var date = fromDate; + + while (date < toDate) + { + res.Add(date, new Tuple(0, 0)); + date = date.AddMonths(1); + } + + foreach (var item in data) + { + var key = new DateTime(item.Date.Year, item.Date.Month, 1); + + if (key < res.First().Key) + key = res.First().Key; + + if (key > res.Last().Key) + key = res.Last().Key; + + res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, + res[key].Item2 + item.Value); + } + + var body = new List>(); + + foreach (var resItem in res) + { + var bodyItem = new List + { + new {format = "MMM-yy", value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} + }; + + body.Add(bodyItem); + } + + var head = new List + { + CRMReportResource.Month, + CRMReportResource.WithRespectToProbability, + CRMReportResource.IfAllOpportunitiesWon + }; + + return new + { + resource = new + { + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesForecastReport, + header = CRMReportResource.SalesForecastReport, + header1 = CRMReportResource.SalesForecastReport + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName = CRMReportResource.SalesForecastReport + ", " + Global.TenantSettings.DefaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } + + #endregion + + + #region SalesFunnelReport + + public bool CheckSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_deal d") + .Select("d.id") + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + return Db.ExecuteList(sqlQuery).Any(); + } + + public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSalesFunnelReport(timePeriod, managers, defaultCurrency); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_deal_milestone m") + .Select("m.status", "m.title", + "count(d.id) as deals_count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency), + "avg(if(m.status = 1, datediff(d.actual_close_date, d.create_on), 0)) as deals_duration") + .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & + Exp.EqColumns("d.deal_milestone_id", "m.id") & + (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & + Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "m.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .GroupBy("m.id") + .OrderBy("m.sort_order", true); + + + return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesFunnel); + } + + private static SalesFunnel ToSalesFunnel(object[] row) + { + return new SalesFunnel + { + Status = (DealMilestoneStatus)Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + Count = Convert.ToInt32(row[2]), + Value = Convert.ToDecimal(row[3]), + Duration = Convert.ToInt32(row[4]) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + var totalCount = data.Sum(x => x.Count); + + if (totalCount == 0) return null; + + var totalBudget = data.Sum(x => x.Value); + + var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); + + var reportData = data.Select(item => new List + { + item.Title, + item.Status, + item.Count, + item.Value + }).ToList(); + + return new + { + resource = new + { + header = CRMReportResource.SalesFunnelReport, + sheetName = CRMReportResource.SalesFunnelReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.SalesFunnelByCount, + chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.DealsCount, + chartName3 = CRMReportResource.DealsBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + + totalCountLabel = CRMReportResource.TotalDealsCount, + totalCountValue = totalCount, + + totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + totalBudgetValue = totalBudget, + + averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + averageBidValue = totalBudget/totalCount, + + averageDurationLabel = CRMReportResource.AverageDealsDuration, + averageDurationValue = closed.Sum(x => x.Duration)/closed.Count, + + header1 = CRMReportResource.ByCount, + header2 = CRMReportResource.ByBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + + stage = CRMReportResource.Stage, + count = CRMReportResource.Count, + budget = CRMReportResource.Budget, + conversion = CRMReportResource.Conversion, + + deals = CRMDealResource.Deals, + status0 = DealMilestoneStatus.Open.ToLocalizedString(), + status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), + status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByContactsReport + + public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_contact c") + .Select("c.id") + .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + return Db.ExecuteList(sqlQuery).Any(); + + } + + public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByContactsReport(timePeriod, managers); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildWorkloadByContactsReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_contact c") + .Select("c.create_by", + "concat(u.firstname, ' ', u.lastname) as full_name", + "i.id", + "i.title", + "count(c.id) as total", + "count(d.id) as `with deals`") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & Exp.Eq("i.list_type", (int)ListType.ContactType)) + .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "c.tenant_id") & Exp.EqColumns("d.contact_id", "c.id")) + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.create_by")) + .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("c.create_by", "i.id") + .OrderBy("i.sort_order, i.title", true); + + return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByContacts); + } + + private static WorkloadByContacts ToWorkloadByContacts(object[] row) + { + return new WorkloadByContacts + { + UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + UserName = Convert.ToString(row[1]), + CategoryId = Convert.ToInt32(row[2]), + CategoryName = Convert.ToString(row[3]), + Count = Convert.ToInt32(row[4]), + WithDeals = Convert.ToInt32(row[5]) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + { + return new + { + resource = new + { + header = CRMReportResource.WorkloadByContactsReport, + sheetName = CRMReportResource.WorkloadByContactsReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + header1 = CRMReportResource.NewContacts, + header2 = CRMReportResource.NewContactsWithAndWithoutDeals, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, + + noSet = CRMCommonResource.NoSet, + withDeals = CRMReportResource.ContactsWithDeals, + withouthDeals = CRMReportResource.ContactsWithoutDeals, + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByTasksReport + + public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlNewTasksQuery = Query("crm_task t") + .Select("t.id") + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var sqlClosedTasksQuery = Query("crm_task t") + .Select("t.id") + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(Exp.Eq("t.is_closed", 1)) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var sqlOverdueTasksQuery = Query("crm_task t") + .Select("t.id") + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) + .SetMaxResults(1); + + bool res; + + using (var tx = Db.BeginTransaction()) + { + res = Db.ExecuteList(sqlNewTasksQuery).Any() || + Db.ExecuteList(sqlClosedTasksQuery).Any() || + Db.ExecuteList(sqlOverdueTasksQuery).Any(); + + tx.Commit(); + } + + return res; + } + + public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByTasksReport(timePeriod, managers); + + if (reportData == null || !reportData.Any()) return null; + + var hasData = reportData.Any(item => item.Value.Count > 0); + + return hasData ? GenerateReportData(timePeriod, reportData) : null; + } + + private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlNewTasksQuery = Query("crm_task t") + .Select("i.id", + "i.title", + "t.responsible_id", + "concat(u.firstname, ' ', u.lastname) as full_name", + "count(t.id) as count") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("i.id", "t.responsible_id") + .OrderBy("i.sort_order", true); + + var sqlClosedTasksQuery = Query("crm_task t") + .Select("i.id", + "i.title", + "t.responsible_id", + "concat(u.firstname, ' ', u.lastname) as full_name", + "count(t.id) as count") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(Exp.Eq("t.is_closed", 1)) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("i.id", "t.responsible_id") + .OrderBy("i.sort_order", true); + + var sqlOverdueTasksQuery = Query("crm_task t") + .Select("i.id", + "i.title", + "t.responsible_id", + "concat(u.firstname, ' ', u.lastname) as full_name", + "count(t.id) as count") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) + .GroupBy("i.id", "t.responsible_id") + .OrderBy("i.sort_order", true); + + Dictionary> res; + + using (var tx = Db.BeginTransaction()) + { + res = new Dictionary> + { + {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, + {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, + {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} + }; + + tx.Commit(); + } + + return res; + } + + private static WorkloadByTasks ToWorkloadByTasks(object[] row) + { + return new WorkloadByTasks + { + CategoryId = Convert.ToInt32(row[0]), + CategoryName = Convert.ToString(row[1]), + UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), + UserName = Convert.ToString(row[3]), + Count = Convert.ToInt32(row[4]) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) + { + return new + { + resource = new + { + header = CRMReportResource.WorkloadByTasksReport, + sheetName = CRMReportResource.WorkloadByTasksReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + header1 = CRMReportResource.ClosedTasks, + header2 = CRMReportResource.NewTasks, + header3 = CRMReportResource.OverdueTasks, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByDealsReport + + public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_deal d") + .Select("d.id") + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + Exp.Empty : + Exp.Or(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), + Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) + .SetMaxResults(1); + + return Db.ExecuteList(sqlQuery).Any(); + } + + public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildWorkloadByDealsReport(timePeriod, managers, defaultCurrency); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildWorkloadByDealsReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_deal d") + .Select("d.responsible_id", + "concat(u.firstname, ' ', u.lastname) as full_name", + "m.status", + "count(d.id) as deals_count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) + .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + Exp.Empty : + Exp.Or(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), + Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) + .GroupBy("d.responsible_id", "m.status"); + + + return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByDeals); + } + + private static WorkloadByDeals ToWorkloadByDeals(object[] row) + { + return new WorkloadByDeals + { + UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + UserName = Convert.ToString(row[1]), + Status = (DealMilestoneStatus)Convert.ToInt32(row[2]), + Count = Convert.ToInt32(row[3]), + Value = Convert.ToDecimal(row[4]) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + var reportData = data.Select(item => new List + { + item.UserId, + item.UserName, + (int)item.Status, + item.Count, + item.Value + }).ToList(); + + return new + { + resource = new + { + header = CRMReportResource.WorkloadByDealsReport, + sheetName = CRMReportResource.WorkloadByDealsReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.DealsCount, + chartName1 = CRMReportResource.DealsBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + + header1 = CRMReportResource.ByCount, + header2 = CRMReportResource.ByBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, + + status0 = CRMReportResource.New, + status1 = CRMReportResource.Won, + status2 = CRMReportResource.Lost + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByInvoicesReport + + public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sent = !Exp.Eq("i.status", (int)InvoiceStatus.Draft) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.issue_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + var paid = Exp.Eq("i.status", (int)InvoiceStatus.Paid) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + var rejected = Exp.Eq("i.status", (int)InvoiceStatus.Rejected) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + var overdue = (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.due_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) & Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")); + + var sqlQuery = Query("crm_invoice i") + .Select("i.id") + .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + .Where(Exp.Or(Exp.Or(sent, paid), Exp.Or(rejected, overdue))) + .SetMaxResults(1); + + return Db.ExecuteList(sqlQuery).Any(); + } + + public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByInvoicesReport(timePeriod, managers); + + if (reportData == null || !reportData.Any()) return null; + + var hasData = reportData.Any(item => item.SentCount > 0 || item.PaidCount > 0 || item.RejectedCount > 0 || item.OverdueCount > 0); + + return hasData ? GenerateReportData(timePeriod, reportData) : null; + } + + private List BuildWorkloadByInvoicesReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.issue_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); + var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); + var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); + var overdue = Exp.Sum(Exp.If((timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.due_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) & Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); + + var sqlQuery = Query("crm_invoice i") + .Select("i.create_by", "concat(u.firstname, ' ', u.lastname) as full_name") + .Select(sent) + .Select(paid) + .Select(rejected) + .Select(overdue) + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "i.tenant_id") & Exp.EqColumns("u.id", "i.create_by")) + .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + .GroupBy("i.create_by"); + + + return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByInvoices); + } + + private static WorkloadByInvoices ToWorkloadByInvoices(object[] row) + { + return new WorkloadByInvoices + { + UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + UserName = Convert.ToString(row[1]), + SentCount = Convert.ToInt32(row[2]), + PaidCount = Convert.ToInt32(row[3]), + RejectedCount = Convert.ToInt32(row[4]), + OverdueCount = Convert.ToInt32(row[5]) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + { + return new + { + resource = new + { + header = CRMReportResource.WorkloadByInvoicesReport, + sheetName = CRMReportResource.WorkloadByInvoicesReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.BilledInvoices, + chartName1 = CRMInvoiceResource.Invoices, + + header1 = CRMInvoiceResource.Invoices, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, + + billed = CRMReportResource.Billed, + paid = CRMReportResource.Paid, + rejected = CRMReportResource.Rejected, + overdue = CRMReportResource.Overdue + }, + data = reportData + }; + } + + #endregion + + + #region GetWorkloadByViopReport + + public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_voip_calls c") + .Select("c.id") + .Where(Exp.EqColumns("c.parent_call_id", "''")) + .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + Exp.Empty : + Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + return Db.ExecuteList(sqlQuery).Any(); + } + + public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByViopReport(timePeriod, managers); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildWorkloadByViopReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlQuery = Query("crm_voip_calls c") + .Select("c.answered_by", + "concat(u.firstname, ' ', u.lastname) as full_name", + "c.status", + "count(c.id) as calls_count", + "sum(c.dial_duration) as duration") + .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.answered_by")) + .Where(Exp.EqColumns("c.parent_call_id", "''")) + .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + Exp.Empty : + Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("c.answered_by", "c.status"); + + + return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByViop); + } + + private static WorkloadByViop ToWorkloadByViop(object[] row) + { + return new WorkloadByViop + { + UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + UserName = Convert.ToString(row[1] ?? string.Empty), + Status = (VoipCallStatus)Convert.ToInt32(row[2] ?? 0), + Count = Convert.ToInt32(row[3]), + Duration = Convert.ToInt32(row[4]) + }; + } + + private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + var reportData = data.Select(item => new List + { + item.UserId, + item.UserName, + (int) item.Status, + item.Count, + new {format = TimeFormat, value = SecondsToTimeFormat(item.Duration)} + }).ToList(); + + return new + { + resource = new + { + header = CRMReportResource.WorkloadByVoipReport, + sheetName = CRMReportResource.WorkloadByVoipReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.CallsCount, + chartName1 = CRMReportResource.CallsDuration, + + header1 = CRMReportResource.CallsCount, + header2 = CRMReportResource.CallsDuration, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, + + incoming = CRMReportResource.Incoming, + outcoming = CRMReportResource.Outcoming, + + timeFormat = TimeFormat + }, + data = reportData + }; + } + + private static string SecondsToTimeFormat(int duration) + { + var timeSpan = TimeSpan.FromSeconds(duration); + + return string.Format("{0}:{1}:{2}", + ((timeSpan.TotalHours < 10 ? "0" : "") + (int)timeSpan.TotalHours), + ((timeSpan.Minutes < 10 ? "0" : "") + timeSpan.Minutes), + ((timeSpan.Seconds < 10 ? "0" : "") + timeSpan.Seconds)); + } + + #endregion + + + #region SummaryForThePeriodReport + + public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var newDealsSqlQuery = Query("crm_deal d") + .Select("d.id") + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var closedDealsSqlQuery = Query("crm_deal d") + .Select("d.id") + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where(!Exp.Eq("m.status", (int)DealMilestoneStatus.Open)) + .SetMaxResults(1); + + var overdueDealsSqlQuery = Query("crm_deal d") + .Select("d.id") + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where( + Exp.And( + Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), + Exp.Or(Exp.Eq("m.status", (int)DealMilestoneStatus.Open) & Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), + Exp.Eq("m.status", (int)DealMilestoneStatus.ClosedAndWon) & Exp.Sql("d.actual_close_date > d.expected_close_date")))); + + var invoicesSqlQuery = Query("crm_invoice i") + .Select("i.id") + .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + .Where(Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var contactsSqlQuery = Query("crm_contact c") + .Select("c.id") + .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + .Where(Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var tasksSqlQuery = Query("crm_task t") + .Select("t.id") + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var voipSqlQuery = Query("crm_voip_calls c") + .Select("c.id") + .Where(Exp.EqColumns("c.parent_call_id", "''")) + .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) + .Where(Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("c.status"); + + bool res; + + using (var tx = Db.BeginTransaction()) + { + res = Db.ExecuteList(newDealsSqlQuery).Any() || + Db.ExecuteList(closedDealsSqlQuery).Any() || + Db.ExecuteList(overdueDealsSqlQuery).Any() || + Db.ExecuteList(invoicesSqlQuery).Any() || + Db.ExecuteList(contactsSqlQuery).Any() || + Db.ExecuteList(tasksSqlQuery).Any() || + Db.ExecuteList(voipSqlQuery).Any(); + + tx.Commit(); + } + + return res; + } + + public object GetSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSummaryForThePeriodReport(timePeriod, managers, defaultCurrency); + + if (reportData == null) return null; + + return GenerateSummaryForThePeriodReportData(timePeriod, reportData); + } + + private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var newDealsSqlQuery = Query("crm_deal d") + .Select("count(d.id) as count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "d.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + + var wonDealsSqlQuery = Query("crm_deal d") + .Select("count(d.id) as count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "d.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where("m.status", (int) DealMilestoneStatus.ClosedAndWon); + + var lostDealsSqlQuery = Query("crm_deal d") + .Select("count(d.id) as count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "d.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where("m.status", (int) DealMilestoneStatus.ClosedAndLost); + + var overdueDealsSqlQuery = Query("crm_deal d") + .Select("count(d.id) as count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "d.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where( + Exp.And( + Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), + Exp.Or(Exp.Eq("m.status", (int)DealMilestoneStatus.Open) & Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), + Exp.Eq("m.status", (int) DealMilestoneStatus.ClosedAndWon) & Exp.Sql("d.actual_close_date > d.expected_close_date")))); + + var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft), 1, 0)); + var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid), 1, 0)); + var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected), 1, 0)); + var overdue = Exp.Sum(Exp.If(Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), + Exp.Eq("i.status", (int) InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); + + var invoicesSqlQuery = Query("crm_invoice i") + .Select(sent) + .Select(paid) + .Select(rejected) + .Select(overdue) + .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + .Where(Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + + + var contactsSqlQuery = Query("crm_contact c") + .Select("i.title", + "count(c.id)") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + Exp.EqColumns("i.id", "c.contact_type_id") & + Exp.Eq("i.list_type", (int) ListType.ContactType)) + .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + .Where(Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("i.id") + .OrderBy("i.sort_order, i.title", true); + + var tasksSqlQuery = Query("crm_task t") + .Select("i.title") + .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 1) & Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), 1, 0))) + .Select(Exp.Sum(Exp.If(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")), 1, 0))) + .Select("count(t.id)") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("i.id") + .OrderBy("i.sort_order, i.title", true); + + var voipSqlQuery = Query("crm_voip_calls c") + .Select("c.status", + "count(c.id) as calls_count", + "sum(c.dial_duration) as duration") + .Where(Exp.EqColumns("c.parent_call_id", "''")) + .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) + .Where(Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("c.status"); + + object res; + + using (var tx = Db.BeginTransaction()) + { + res = new + { + DealsInfo = new + { + Created = Db.ExecuteList(newDealsSqlQuery), + Won = Db.ExecuteList(wonDealsSqlQuery), + Lost = Db.ExecuteList(lostDealsSqlQuery), + Overdue = Db.ExecuteList(overdueDealsSqlQuery), + }, + InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), + ContactsInfo = Db.ExecuteList(contactsSqlQuery), + TasksInfo = Db.ExecuteList(tasksSqlQuery), + VoipInfo = Db.ExecuteList(voipSqlQuery) + }; + + tx.Commit(); + } + + return res; + } + + private static object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) + { + return new + { + resource = new + { + header = CRMReportResource.SummaryForThePeriodReport, + sheetName = CRMReportResource.SummaryForThePeriodReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + chartName = CRMReportResource.DealsByBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName1=CRMReportResource.DealsByCount, + chartName2=CRMReportResource.ContactsByType, + chartName3=CRMReportResource.TasksForThePeriod, + chartName4=CRMReportResource.InvoicesForThePeriod, + chartName5 = CRMReportResource.CallsForThePeriod, + header1 = CRMDealResource.Deals, + header2 = CRMContactResource.Contacts, + header3 = CRMTaskResource.Tasks, + header4 = CRMInvoiceResource.Invoices, + header5 = CRMReportResource.Calls, + byBudget = CRMReportResource.ByBudget, + currency = Global.TenantSettings.DefaultCurrency.Symbol, + byCount = CRMReportResource.ByCount, + item = CRMReportResource.Item, + type = CRMReportResource.Type, + won = CRMReportResource.Won, + lost = CRMReportResource.Lost, + created = CRMReportResource.Created, + closed = CRMReportResource.Closed, + overdue = CRMReportResource.Overdue, + notSpecified = CRMCommonResource.NoSet, + total = CRMReportResource.Total, + status = CRMReportResource.Status, + billed = CRMReportResource.Billed, + paid = CRMReportResource.Paid, + rejected = CRMReportResource.Rejected, + count = CRMReportResource.Count, + duration = CRMReportResource.Duration, + incoming = CRMReportResource.Incoming, + outcoming = CRMReportResource.Outcoming, + missed = CRMReportResource.MissedCount, + timeFormat = TimeFormat + }, + data = reportData + }; + } + + #endregion + + + #region SummaryAtThisMomentReport + + public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var dealsSqlQuery = Query("crm_deal d") + .Select("d.id") + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where("m.status", (int)DealMilestoneStatus.Open) + .SetMaxResults(1); + + var contactsSqlQuery = Query("crm_contact c") + .Select("c.id") + .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var tasksSqlQuery = Query("crm_task t") + .Select("t.id") + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + var invoicesSqlQuery = Query("crm_invoice i") + .Select("i.id") + .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .SetMaxResults(1); + + bool res; + + using (var tx = Db.BeginTransaction()) + { + res = Db.ExecuteList(dealsSqlQuery).Any() || + Db.ExecuteList(contactsSqlQuery).Any() || + Db.ExecuteList(tasksSqlQuery).Any() || + Db.ExecuteList(invoicesSqlQuery).Any(); + + tx.Commit(); + } + + return res; + } + + public object GetSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSummaryAtThisMomentReport(timePeriod, managers, defaultCurrency); + + if (reportData == null) return null; + + return GenerateSummaryAtThisMomentReportData(timePeriod, reportData); + } + + private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var openDealsSqlQuery = Query("crm_deal d") + .Select("count(d.id) as count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "d.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where("m.status", (int)DealMilestoneStatus.Open); + + var overdueDealsSqlQuery = Query("crm_deal d") + .Select("count(d.id) as count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "d.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where("m.status", (int)DealMilestoneStatus.Open) + .Where(Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()))); + + var nearDealsSqlQuery = Query("crm_deal d") + .Select("count(d.id) as count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_currency_rate r", + Exp.EqColumns("r.tenant_id", "d.tenant_id") & + Exp.EqColumns("r.from_currency", "d.bid_currency")) + .LeftOuterJoin("crm_deal_milestone m", + Exp.EqColumns("m.tenant_id", "d.tenant_id") & + Exp.EqColumns("m.id", "d.deal_milestone_id")) + .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .Where("m.status", (int)DealMilestoneStatus.Open) + .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow().AddDays(30)))); + + var dealsByStageSqlQuery = Query("crm_deal_milestone m") + .Select("m.title", + "count(d.id) as deals_count", + string.Format(@"sum(case d.bid_type + when 0 then + d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + else + d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + end) as deals_value", defaultCurrency)) + .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & + Exp.EqColumns("d.deal_milestone_id", "m.id") & + (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & + (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) + .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "m.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + .Where("m.status", (int)DealMilestoneStatus.Open) + .GroupBy("m.id") + .OrderBy("m.sort_order, m.title", true); + + var contactsByTypeSqlQuery = Query("crm_contact c") + .Select("i.title", + "count(c.id) as count") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + Exp.EqColumns("i.id", "c.contact_type_id") & + Exp.Eq("i.list_type", (int) ListType.ContactType)) + .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("i.id") + .OrderBy("i.sort_order, i.title", true); + + var contactsByStageSqlQuery = Query("crm_contact c") + .Select("i.title", + "count(c.id) as count") + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + Exp.EqColumns("i.id", "c.status_id") & + Exp.Eq("i.list_type", (int)ListType.ContactStatus)) + .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("i.id") + .OrderBy("i.sort_order, i.title", true); + + var tasksSqlQuery = Query("crm_task t") + .Select("i.title") + .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0), 1, 0))) + .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0))) + .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + .GroupBy("i.id") + .OrderBy("i.sort_order, i.title", true); + + var sent = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent), 1, 0)); + var overdue = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0)); + + var invoicesSqlQuery = Query("crm_invoice i") + .Select(sent) + .Select(overdue) + .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + + object res; + + using (var tx = Db.BeginTransaction()) + { + res = new + { + DealsInfo = new + { + Open = Db.ExecuteList(openDealsSqlQuery), + Overdue = Db.ExecuteList(overdueDealsSqlQuery), + Near = Db.ExecuteList(nearDealsSqlQuery), + ByStage = Db.ExecuteList(dealsByStageSqlQuery) + }, + ContactsInfo = new + { + ByType = Db.ExecuteList(contactsByTypeSqlQuery), + ByStage = Db.ExecuteList(contactsByStageSqlQuery) + }, + TasksInfo = Db.ExecuteList(tasksSqlQuery), + InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), + }; + + tx.Commit(); + } + + return res; + } + + private static object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) + { + return new + { + resource = new + { + header = CRMReportResource.SummaryAtThisMomentReport, + sheetName = CRMReportResource.SummaryAtThisMomentReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + chartName = CRMReportResource.DealsByStatus + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.DealsByStage + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + chartName2=CRMReportResource.ContactsByType, + chartName3 = CRMReportResource.ContactsByStage, + chartName4 = CRMReportResource.TasksByStatus, + chartName5 = CRMReportResource.InvoicesByStatus, + header1 = CRMDealResource.Deals, + header2 = CRMContactResource.Contacts, + header3 = CRMTaskResource.Tasks, + header4 = CRMInvoiceResource.Invoices, + budget = CRMReportResource.Budget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + count = CRMReportResource.Count, + open = CRMReportResource.Opened, + overdue = CRMReportResource.Overdue, + near = CRMReportResource.Near, + stage = CRMReportResource.Stage, + temperature = CRMContactResource.ContactStage, + type = CRMReportResource.Type, + total = CRMReportResource.Total, + billed = CRMReportResource.Billed, + notSpecified = CRMCommonResource.NoSet, + status = CRMReportResource.Status, + }, + data = reportData + }; + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs new file mode 100644 index 00000000000..4e374c81b94 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -0,0 +1,442 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Common.Utils; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; +using ASC.Web.Core.ModuleManagement.Common; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Configuration; +using ASC.Web.CRM.Core.Search; + +namespace ASC.CRM.Core.Dao +{ + public class SearchDao : AbstractDao + { + #region Members + + private Dictionary> _findedIDs; + private bool _fullTextSearchEnable; + private DaoFactory DaoFactory { get; set; } + + #endregion + + #region Constructor + + public SearchDao(int tenantID, DaoFactory daoFactory) + : base(tenantID) + { + DaoFactory = daoFactory; + } + + #endregion + + #region Methods + + #region Public + + public SearchResultItem[] Search(String searchText) + { + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + .ToArray(); + + if (keywords.Length == 0) return new List().ToArray(); + + _fullTextSearchEnable = BundleSearch.Support(EntityType.Case) + && BundleSearch.Support(EntityType.Contact) + && BundleSearch.Support(EntityType.Opportunity) + && BundleSearch.Support(EntityType.Task) + && BundleSearch.Support(EntityType.Invoice); + + if (_fullTextSearchEnable) + { + _findedIDs = new Dictionary>(); + + List casesId; + if (BundleSearch.TrySelectCase(searchText, out casesId)) + { + _findedIDs.Add(EntityType.Case, casesId); + } + + List contactsId; + if (BundleSearch.TrySelectContact(searchText, out contactsId)) + { + _findedIDs.Add(EntityType.Contact, contactsId); + } + + List dealsId; + if (BundleSearch.TrySelectOpportunity(searchText, out dealsId)) + { + _findedIDs.Add(EntityType.Opportunity, dealsId); + } + + List tasksId; + if (FactoryIndexer.TrySelectIds(r => r.MatchAll(searchText), out tasksId)) + { + _findedIDs.Add(EntityType.Task, tasksId); + } + + List invoicesId; + if (FactoryIndexer.TrySelectIds(r => r.MatchAll(searchText), out invoicesId)) + { + _findedIDs.Add(EntityType.Invoice, invoicesId); + } + } + else + { + _findedIDs = SearchByCustomFields(keywords) + .Union(SearchByRelationshipEvent(keywords)) + .Union(SearchByContactInfos(keywords)) + .ToLookup(pair => pair.Key, pair => pair.Value) + .ToDictionary(group => group.Key, group => group.First()); + } + + + var searchQuery = GetSearchQuery(keywords); + + if (searchQuery == null) return new SearchResultItem[0]; + + return ToSearchResultItem(Db.ExecuteList(searchQuery)); + } + + #endregion + + #region Private + + private Dictionary> SearchByRelationshipEvent(String[] keywords) + { + var historyQuery = Query("crm_relationship_event") + .Select( + "contact_id", + "entity_id", + "entity_type") + .Distinct() + .Where(BuildLike(new[] { "content" }, keywords)); + + return Db.ExecuteList(historyQuery).ConvertAll(row => + { + var entityID = Convert.ToInt32(row[1]); + + if (entityID > 0) + return new[] { row[1], row[2] }; + + return new[] { row[0], (int)EntityType.Contact }; + + }).GroupBy(row => row[1]) + .ToDictionary(x => (EntityType)x.Key, x => x.SelectMany(item => item).Select(Convert.ToInt32)); + } + + private Dictionary> SearchByCustomFields(String[] keywords) + { + + var customFieldQuery = Query("crm_field_value") + .Select("entity_id", + "entity_type") + .Distinct() + .Where(BuildLike(new[] { "value" }, keywords)); + + return Db.ExecuteList(customFieldQuery) + .GroupBy(row => row[1]) + .ToDictionary(x => (EntityType)x.Key, x => x.SelectMany(item => item).Select(Convert.ToInt32)); + } + + private Dictionary> SearchByContactInfos(String[] keywords) + { + var sqlResult = Db.ExecuteList(Query("crm_contact_info").Distinct() + .Select("contact_id") + .Where(BuildLike(new[] { "data" }, keywords))).Select(item => Convert.ToInt32(item[0])); + + + return new Dictionary> { { EntityType.Contact, sqlResult } }; + } + + private String ToColumn(EntityType entityType) + { + return String.Format("{0} as container_type", (int)entityType); + } + + + private Exp BuildWhereExp(EntityType entityType, String[] keywords) + { + Exp where = Exp.Empty; + + if (_findedIDs.ContainsKey(entityType)) + where = Exp.In("id", _findedIDs[entityType].ToArray()); + + if (BundleSearch.Support(entityType)) return where; + + Exp byField; + + switch (entityType) + { + case EntityType.Contact: + byField = BuildLike(new[] + { + "first_name", + "last_name", + "company_name", + "title", + "notes" + }, keywords); + break; + case EntityType.Opportunity: + byField = BuildLike(new[] + { + "title", + "description" + }, keywords); + break; + case EntityType.Task: + byField = BuildLike(new[] + { + "title", + "description" + }, keywords); + break; + case EntityType.Case: + byField = BuildLike(new[] + { + "title" + }, keywords); + break; + case EntityType.Invoice: + byField = BuildLike(new[] + { + "number", + "description" + }, keywords); + break; + default: + throw new ArgumentException(); + + } + + if (where != Exp.Empty) + where &= byField; + else + where = byField; + + return where; + } + + private bool IncludeToSearch(EntityType entityType) + { + return !BundleSearch.Support(entityType) || _findedIDs.ContainsKey(entityType); + } + + private SqlQuery GetSearchQuery(String[] keywords) + { + var queries = new List(); + + if (IncludeToSearch(EntityType.Task)) + queries.Add(Query("crm_task") + .Select(ToColumn(EntityType.Task), "id", "title", "description", "contact_id", "entity_id", + "entity_type", "create_on") + .Where(BuildWhereExp(EntityType.Task, keywords))); + + if (IncludeToSearch(EntityType.Opportunity)) + queries.Add(Query("crm_deal") + .Select(ToColumn(EntityType.Opportunity), "id", "title", "description", "contact_id", "0 as entity_id", "0 as entity_type", "create_on") + .Where(BuildWhereExp(EntityType.Opportunity, keywords))); + + if (IncludeToSearch(EntityType.Contact)) + queries.Add(Query("crm_contact") + .Select(ToColumn(EntityType.Contact), + "id", + String.Format(@"case is_company + when 0 then + concat(first_name, ' ', last_name) + else + company_name + end as title"), + "notes as description", "0 as contact_id", "0 as entity_id", "0 as entity_type", "create_on") + .Where(BuildWhereExp(EntityType.Contact, keywords))); + + + if (IncludeToSearch(EntityType.Case)) + queries.Add(Query("crm_case") + .Select(ToColumn(EntityType.Case), "id", "title", "'' as description", "0 as contact_id", "0 as entity_id", "0 as entity_type", "create_on") + .Where(BuildWhereExp(EntityType.Case, keywords))); + + if (IncludeToSearch(EntityType.Invoice)) + queries.Add(Query("crm_invoice") + .Select(ToColumn(EntityType.Invoice), "id", "number as title", "description", "contact_id", "entity_id", "entity_type", "create_on") + .Where(BuildWhereExp(EntityType.Invoice, keywords))); + + + if (queries.Count == 0) return null; + if (queries.Count == 1) return queries[0]; + return queries[0].UnionAll(queries.Skip(1).ToArray()); + } + + private SearchResultItem[] ToSearchResultItem(IEnumerable rows) + { + var result = new List(); + + foreach (var row in rows) + { + var containerType = ((EntityType)Convert.ToInt32(row[0])); + var id = row[1]; + string imageRef; + String url; + + switch (containerType) + { + case EntityType.Contact: + { + + var contact = DaoFactory.ContactDao.GetByID(Convert.ToInt32(id)); + + if (contact == null || !CRMSecurity.CanAccessTo(contact)) continue; + + url = String.Format("default.aspx?id={0}", id); + + if (contact is Company) + imageRef = WebImageSupplier.GetAbsoluteWebPath("companies_widget.png", + ProductEntryPoint.ID); + else + imageRef = WebImageSupplier.GetAbsoluteWebPath("people_widget.png", + ProductEntryPoint.ID); + + break; + } + case EntityType.Opportunity: + { + + var deal = DaoFactory.DealDao.GetByID(Convert.ToInt32(id)); + + if (deal == null || !CRMSecurity.CanAccessTo(deal)) continue; + + url = String.Format("deals.aspx?id={0}", id); + + imageRef = WebImageSupplier.GetAbsoluteWebPath("deal_widget.png", + ProductEntryPoint.ID); + break; + } + case EntityType.Case: + { + var cases = DaoFactory.CasesDao.GetByID(Convert.ToInt32(id)); + + if (cases == null || !CRMSecurity.CanAccessTo(cases)) continue; + + url = String.Format("cases.aspx?id={0}", id); + + imageRef = WebImageSupplier.GetAbsoluteWebPath("cases_widget.png", + ProductEntryPoint.ID); + + break; + } + case EntityType.Task: + { + var task = DaoFactory.TaskDao.GetByID(Convert.ToInt32(id)); + + if (task == null || !CRMSecurity.CanAccessTo(task)) continue; + + url = ""; + + imageRef = WebImageSupplier.GetAbsoluteWebPath("tasks_widget.png", + ProductEntryPoint.ID); + break; + } + case EntityType.Invoice: + { + var invoice = DaoFactory.InvoiceDao.GetByID(Convert.ToInt32(id)); + + if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) continue; + + url = String.Format("invoices.aspx?id={0}", id); + + imageRef = WebImageSupplier.GetAbsoluteWebPath("invoices_widget.png", + ProductEntryPoint.ID); + + break; + } + default: + throw new ArgumentException(); + } + + result.Add(new SearchResultItem + { + Name = Convert.ToString(row[2]), + Description = HtmlUtil.GetText(Convert.ToString(row[3]), 120), + URL = !string.IsNullOrEmpty(url) ? String.Concat(PathProvider.BaseAbsolutePath, url) : string.Empty, + Date = TenantUtil.DateTimeFromUtc(DateTime.Parse(Convert.ToString(row[7]))), + Additional = new Dictionary + { { "imageRef", imageRef }, + {"relativeInfo", GetPath( + Convert.ToInt32(row[4]), + Convert.ToInt32(row[5]), + (EntityType)Convert.ToInt32(row[6]))}, + {"typeInfo", containerType.ToLocalizedString()} + } + }); + } + + return result.ToArray(); + + } + + private String GetPath(int contactID, int entityID, EntityType entityType) + { + + if (contactID == 0) return String.Empty; + + if (entityID == 0) + return DaoFactory.ContactDao.GetByID(contactID).GetTitle(); + + switch (entityType) + { + case EntityType.Company: + case EntityType.Person: + case EntityType.Contact: + var contact = DaoFactory.ContactDao.GetByID(contactID); + return contact == null ? string.Empty : contact.GetTitle(); + case EntityType.Opportunity: + var opportunity = DaoFactory.DealDao.GetByID(entityID); + return opportunity == null ? string.Empty : opportunity.Title; + case EntityType.Case: + var @case = DaoFactory.CasesDao.GetByID(entityID); + return @case == null ? string.Empty : @case.Title; + default: + throw new ArgumentException(); + } + } + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs new file mode 100644 index 00000000000..081b1833851 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -0,0 +1,430 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.Common.Data; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.CRM.Core.Entities; +using Newtonsoft.Json; +using ASC.Web.CRM.Resources; +using ASC.CRM.Core.Enums; + +namespace ASC.CRM.Core.Dao +{ + public class TagDao : AbstractDao + { + #region Constructor + + public TagDao(int tenantID) + : base(tenantID) + { + + + } + + #endregion + + #region Methods + + public bool IsExist(EntityType entityType, String tagName) + { + if (String.IsNullOrEmpty(tagName)) + throw new ArgumentNullException(tagName); + + return IsExistInDb(entityType, tagName); + } + + private bool IsExistInDb(EntityType entityType, String tagName) + { + var q = new SqlQuery("crm_tag") + .Select("1") + .Where("tenant_id", TenantID) + .Where("entity_type", (int)entityType) + .Where("trim(lower(title))", tagName.Trim().ToLower()) + .SetMaxResults(1); + + return Db.ExecuteScalar(q); + } + + private int GetTagId(EntityType entityType, String tagName) + { + var q = new SqlQuery("crm_tag") + .Select("id") + .Where("tenant_id", TenantID) + .Where("entity_type", (int)entityType) + .Where("trim(lower(title))", tagName.Trim().ToLower()) + .SetMaxResults(1); + + return Db.ExecuteScalar(q); + } + + public String[] GetAllTags(EntityType entityType) + { + return Db.ExecuteList( + Query("crm_tag") + .Select("title") + .Where(Exp.Eq("entity_type", (int)entityType)) + .OrderBy("title", true)).ConvertAll(row => row[0].ToString()).ToArray(); + } + + public List> GetAllTags() + { + return Db.ExecuteList( + Query("crm_tag") + .Select("title", "entity_type") + .OrderBy("title", true)) + .ConvertAll(row => new KeyValuePair( + (EntityType)Enum.Parse(typeof(EntityType), row[1].ToString(), true), + row[0].ToString())); + } + + public String GetTagsLinkCountJSON(EntityType entityType) + { + int[] tags = GetTagsLinkCount(entityType).ToArray(); + return JsonConvert.SerializeObject(tags); + } + + public IEnumerable GetTagsLinkCount(EntityType entityType) + { + var sqlQuery = new SqlQuery("crm_tag tbl_tag") + .SelectCount("tag_id") + .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) + .Where(Exp.Eq("tbl_tag.entity_type", (int)entityType) & Exp.Eq("tbl_tag.tenant_id", TenantID)) + .OrderBy("title", true) + .GroupBy("tbl_tag.id"); + + var queryResult = Db.ExecuteList(sqlQuery); + return queryResult.ConvertAll(row => Convert.ToInt32(row[0])); + } + + + public Dictionary> GetEntitiesTags(EntityType entityType) + { + + var result = new Dictionary>(); + + var sqlQuery = + new SqlQuery("crm_entity_tag") + .Select("entity_id", "title") + .LeftOuterJoin("crm_tag", Exp.EqColumns("id", "tag_id")) + .Where(Exp.Eq("crm_tag.entity_type", (int)entityType) & Exp.Eq("crm_tag.tenant_id", TenantID)); + + Db.ExecuteList(sqlQuery).ForEach(row => + { + var entityID = Convert.ToInt32(row[0]); + var tagTitle = Convert.ToString(row[1]); + + if (!result.ContainsKey(entityID)) + result.Add(entityID, new List + { + tagTitle + }); + else + result[entityID].Add(tagTitle); + + }); + return result; + } + + public String[] GetEntityTags(EntityType entityType, int entityID) + { + + SqlQuery sqlQuery = Query("crm_tag") + .Select("title") + .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) + .Where(Exp.Eq("entity_id", entityID) & Exp.Eq("crm_tag.entity_type", (int)entityType)); + + return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToString(row[0])).ToArray(); + } + + + + public String[] GetUnusedTags(EntityType entityType) + { + return Db.ExecuteList(Query("crm_tag") + .Select("title") + .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) + .Where(Exp.Eq("tag_id", Exp.Empty) & Exp.Eq("crm_tag.entity_type", (int)entityType))).ConvertAll(row => Convert.ToString(row[0])).ToArray(); + } + + public bool CanDeleteTag(EntityType entityType, String tagName) + { + var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") + .Where(Exp.Eq("trim(lower(title))", tagName.Trim().ToLower()) & Exp.Eq("entity_type", (int)entityType))); + + return tagID != 0; + } + + public void DeleteTag(EntityType entityType, String tagName) + { + if (!CanDeleteTag(entityType, tagName)) throw new ArgumentException(); + + DeleteTagFromEntity(entityType, 0, tagName); + } + + public void DeleteTagFromEntity(EntityType entityType, int entityID, String tagName) + { + var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") + .Where(Exp.Eq("trim(lower(title))", tagName.Trim().ToLower()) & Exp.Eq("entity_type", (int)entityType))); + + if (tagID == 0) return; + + var sqlQuery = new SqlDelete("crm_entity_tag") + .Where(Exp.Eq("entity_type", (int)entityType) & Exp.Eq("tag_id", tagID)); + + if (entityID > 0) + sqlQuery.Where(Exp.Eq("entity_id", entityID)); + + Db.ExecuteNonQuery(sqlQuery); + + if (entityID == 0) + Db.ExecuteNonQuery(Delete("crm_tag") + .Where(Exp.Eq("id", tagID) & Exp.Eq("entity_type", (int)entityType))); + } + + public void DeleteAllTagsFromEntity(EntityType entityType, int entityID) + { + if (entityID <= 0) return; + + var sqlQuery = new SqlDelete("crm_entity_tag") + .Where(Exp.Eq("entity_type", (int)entityType) & Exp.Eq("entity_id", entityID)); + + Db.ExecuteNonQuery(sqlQuery); + } + + public void DeleteUnusedTags(EntityType entityType) + { + + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException(); + + using (var tx = Db.BeginTransaction()) + { + + var sqlSubQuery = Query("crm_tag") + .Select("id") + .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) + .Where(Exp.Eq("crm_tag.entity_type", (int)entityType) & Exp.Eq("tag_id", Exp.Empty)); + + var tagIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => Convert.ToInt32(row[0])); + + if (tagIDs.Count > 0) + Db.ExecuteNonQuery(Delete("crm_tag").Where(Exp.In("id", tagIDs) & Exp.Eq("entity_type", (int)entityType))); + + + tx.Commit(); + } + + } + + public int AddTag(EntityType entityType, String tagName, bool returnExisted = false) + { + tagName = CorrectTag(tagName); + + if (String.IsNullOrEmpty(tagName)) + throw new ArgumentNullException(CRMErrorsResource.TagNameNotSet); + + var existedTagId = GetTagId(entityType, tagName); + + if (existedTagId > 0) + { + if (returnExisted) + return existedTagId; + + throw new ArgumentException(CRMErrorsResource.TagNameBusy); + } + return AddTagInDb(entityType, tagName); + } + + private int AddTagInDb(EntityType entityType, String tagName) + { + return Db.ExecuteScalar( + Insert("crm_tag") + .InColumnValue("id", 0) + .InColumnValue("title", tagName) + .InColumnValue("entity_type", (int)entityType) + .Identity(1, 0, true)); + } + + + public Dictionary GetAndAddTags(EntityType entityType, String[] tags) + { + tags = tags.Select(CorrectTag).Where(t => !string.IsNullOrWhiteSpace(t)).ToArray(); + + var tagNamesAndIds = new Dictionary(); + + using (var tx = Db.BeginTransaction()) + { + + Db.ExecuteList(Query("crm_tag").Select("id", "title") + .Where(Exp.In("trim(lower(title))", tags.ToList().ConvertAll(t => t.ToLower())) & Exp.Eq("entity_type", (int)entityType))) + .ForEach(row => + { tagNamesAndIds[row[1].ToString()] = (int)row[0]; }); + + var tagsForCreate = tags.Where(t => !tagNamesAndIds.ContainsKey(t)); + + foreach (var tagName in tagsForCreate) + { + tagNamesAndIds.Add(tagName, AddTagInDb(entityType, tagName)); + } + + tx.Commit(); + return tagNamesAndIds; + } + } + + + private int AddTagToEntityInDb(EntityType entityType, int entityID, String tagName) + { + tagName = CorrectTag(tagName); + + if (String.IsNullOrEmpty(tagName) || entityID == 0) + throw new ArgumentException(); + + var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") + .Where(Exp.Eq("trim(lower(title))", tagName.ToLower()) & Exp.Eq("entity_type", (int)entityType))); + + if (tagID == 0) + tagID = AddTagInDb(entityType, tagName); + + Db.ExecuteNonQuery(new SqlInsert("crm_entity_tag", true) + .InColumnValue("entity_id", entityID) + .InColumnValue("entity_type", (int)entityType) + .InColumnValue("tag_id", tagID)); + + return tagID; + } + + public int AddTagToEntity(EntityType entityType, int entityID, String tagName) + { + return AddTagToEntityInDb(entityType, entityID, tagName); + } + + public int AddTagToContacts(int[] contactID, String tagName) + { + tagName = CorrectTag(tagName); + + if (String.IsNullOrEmpty(tagName) || contactID == null || contactID.Length == 0) + throw new ArgumentException(); + + using (var tx = Db.BeginTransaction()) + { + var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") + .Where(Exp.Eq("trim(lower(title))", tagName.ToLower()) & Exp.Eq("entity_type", (int)EntityType.Contact))); + + if (tagID == 0) + tagID = AddTagInDb(EntityType.Contact, tagName); + + foreach (var id in contactID) + { + Db.ExecuteNonQuery(new SqlInsert("crm_entity_tag", true) + .InColumnValue("entity_id", id) + .InColumnValue("entity_type", (int)EntityType.Contact) + .InColumnValue("tag_id", tagID)); + } + tx.Commit(); + return tagID; + } + } + + public int DeleteTagFromContacts(int[] contactID, String tagName) + { + if (String.IsNullOrEmpty(tagName) || contactID == null || contactID.Length == 0) + throw new ArgumentException(); + + using (var tx = Db.BeginTransaction()) + { + var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") + .Where(Exp.Eq("trim(lower(title))", tagName.Trim().ToLower()) & Exp.Eq("entity_type", (int)EntityType.Contact))); + + if (tagID == 0) + throw new ArgumentException(); + + + foreach (var id in contactID) + { + Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag") + .Where(Exp.Eq("entity_id", id) & + Exp.Eq("entity_type", (int)EntityType.Contact) & + Exp.Eq("tag_id", tagID))); + + } + tx.Commit(); + return tagID; + } + } + + public void SetTagToEntity(EntityType entityType, int entityID, String[] tags) + { + using (var tx = Db.BeginTransaction()) + { + Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag") + .Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType))); + + foreach (var tagName in tags.Where(t => !string.IsNullOrWhiteSpace(t))) + { + AddTagToEntityInDb(entityType, entityID, tagName); + } + tx.Commit(); + } + } + + private void AddTagToEntityInDb(EntityType entityType, int entityID, int tagID) + { + Db.ExecuteNonQuery(new SqlInsert("crm_entity_tag", true) + .InColumnValue("entity_id", entityID) + .InColumnValue("entity_type", (int)entityType) + .InColumnValue("tag_id", tagID)); + } + + public void AddTagToEntity(EntityType entityType, int entityID, int[] tagIDs) + { + using (var tx = Db.BeginTransaction()) + { + foreach (var tagID in tagIDs) + { + AddTagToEntityInDb(entityType, entityID, tagID); + } + tx.Commit(); + } + } + + private static string CorrectTag(string tag) + { + return tag == null + ? null + : tag.Trim() + .Replace("\r\n", string.Empty) + .Replace("\n", string.Empty) + .Replace("\r", string.Empty); + } + + #endregion + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs new file mode 100644 index 00000000000..b38db2f2b63 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -0,0 +1,1099 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + +using ASC.Collections; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; +using ASC.Web.CRM.Core.Search; + +namespace ASC.CRM.Core.Dao +{ + public class CachedTaskDao : TaskDao + { + + private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_task"); + + public CachedTaskDao(int tenantID) + : base(tenantID) + { + + } + + public override Task GetByID(int taskID) + { + return _contactCache.Get(taskID.ToString(), () => GetByIDBase(taskID)); + + } + + private Task GetByIDBase(int taskID) + { + return base.GetByID(taskID); + } + + public override void DeleteTask(int taskID) + { + ResetCache(taskID); + + base.DeleteTask(taskID); + } + + public override Task SaveOrUpdateTask(Task task) + { + + if (task != null && task.ID > 0) + { + ResetCache(task.ID); + } + + return base.SaveOrUpdateTask(task); + } + + private void ResetCache(int taskID) + { + _contactCache.Reset(taskID.ToString()); + } + + } + + public class TaskDao : AbstractDao + { + #region Constructor + + public TaskDao(int tenantID) + : base(tenantID) + { + + + } + + #endregion + + #region Methods + + public void OpenTask(int taskID) + { + var task = GetByID(taskID); + + if (task == null) + throw new ArgumentException(); + + CRMSecurity.DemandEdit(task); + + Db.ExecuteNonQuery( + Update("crm_task") + .Set("is_closed", false) + .Where(Exp.Eq("id", taskID)) + ); + } + + public void CloseTask(int taskID) + { + var task = GetByID(taskID); + + if (task == null) + throw new ArgumentException(); + + CRMSecurity.DemandEdit(task); + + Db.ExecuteNonQuery( + Update("crm_task") + .Set("is_closed", true) + .Where(Exp.Eq("id", taskID)) + ); + } + + public virtual Task GetByID(int taskID) + { + var tasks = Db.ExecuteList(GetTaskQuery(Exp.Eq("id", taskID))) + .ConvertAll(row => ToTask(row)); + + return tasks.Count > 0 ? tasks[0] : null; + } + + public List GetTasks(EntityType entityType, int entityID, bool? onlyActiveTask) + { + return GetTasks(String.Empty, Guid.Empty, 0, onlyActiveTask, DateTime.MinValue, DateTime.MinValue, + entityType, entityID, 0, 0, null); + } + public int GetAllTasksCount() + { + return Db.ExecuteScalar(Query("crm_task").SelectCount()); + } + + public List GetAllTasks() + { + return Db.ExecuteList( + GetTaskQuery(null) + .OrderBy("deadline", true) + .OrderBy("title", true)) + .ConvertAll(row => ToTask(row)).FindAll(CRMSecurity.CanAccessTo); + } + + public void ExecAlert(IEnumerable ids) + { + if (!ids.Any()) return; + + Db.ExecuteNonQuery(new SqlUpdate("crm_task").Set("exec_alert", true).Where(Exp.In("id", ids.ToArray()))); + } + + public List GetInfoForReminder(DateTime scheduleDate) + { + var sqlQuery = new SqlQuery("crm_task") + .Select( + "tenant_id", + "id", + "deadline", + "alert_value", + "responsible_id" + ) + .Where( + Exp.Eq("is_closed", false) & + !Exp.Eq("alert_value", 0) & + Exp.Eq("exec_alert", false) & + Exp.Between("DATE_ADD(deadline, interval -alert_value minute)", scheduleDate.AddHours(-1), scheduleDate.AddHours(1)) + ); + + return Db.ExecuteList(sqlQuery); + } + + public List GetTasks( + String searchText, + Guid responsibleID, + int categoryID, + bool? isClosed, + DateTime fromDate, + DateTime toDate, + EntityType entityType, + int entityID, + int from, + int count, + OrderBy orderBy) + { + + if (CRMSecurity.IsAdmin) + return GetCrudeTasks( + searchText, + responsibleID, + categoryID, + isClosed, + fromDate, + toDate, + entityType, + entityID, + from, + count, + orderBy); + + + var crudeTasks = GetCrudeTasks( + searchText, + responsibleID, + categoryID, + isClosed, + fromDate, + toDate, + entityType, + entityID, + 0, + from + count, + orderBy); + + if (crudeTasks.Count == 0) return crudeTasks; + + if (crudeTasks.Count < from + count) return CRMSecurity.FilterRead(crudeTasks).Skip(from).ToList(); + + var result = CRMSecurity.FilterRead(crudeTasks).ToList(); + + if (result.Count == crudeTasks.Count) return result.Skip(from).ToList(); + + var localCount = count; + var localFrom = from + count; + + while (true) + { + crudeTasks = GetCrudeTasks( + searchText, + responsibleID, + categoryID, + isClosed, + fromDate, + toDate, + entityType, + entityID, + localFrom, + localCount, + orderBy); + + if (crudeTasks.Count == 0) break; + + result.AddRange(CRMSecurity.FilterRead(crudeTasks)); + + if ((result.Count >= count + from) || (crudeTasks.Count < localCount)) break; + + localFrom += localCount; + localCount = localCount * 2; + } + + return result.Skip(from).Take(count).ToList(); + } + + + private List GetCrudeTasks( + String searchText, + Guid responsibleID, + int categoryID, + bool? isClosed, + DateTime fromDate, + DateTime toDate, + EntityType entityType, + int entityID, + int from, + int count, + OrderBy orderBy) + { + var taskTableAlias = "t"; + var sqlQuery = WhereConditional(GetTaskQuery(null, taskTableAlias), taskTableAlias, responsibleID, + categoryID, isClosed, fromDate, toDate, entityType, entityID, from, count, + orderBy); + + if (!String.IsNullOrEmpty(searchText)) + { + searchText = searchText.Trim(); + + + var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + .ToArray(); + + if (keywords.Length > 0) + { + List tasksIds; + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out tasksIds)) + { + sqlQuery.Where(BuildLike(new[] {taskTableAlias + ".title", taskTableAlias + ".description"}, keywords)); + } + else + { + if (tasksIds.Any()) + sqlQuery.Where(Exp.In(taskTableAlias + ".id", tasksIds)); + else + return new List(); + } + + } + } + + return Db.ExecuteList(sqlQuery) + .ConvertAll(row => ToTask(row)); + } + + public int GetTasksCount( + String searchText, + Guid responsibleId, + int categoryId, + bool? isClosed, + DateTime fromDate, + DateTime toDate, + EntityType entityType, + int entityId) + { + + int result = 0; + + LogManager.GetLogger("ASC.CRM").DebugFormat("Starting GetTasksCount: {0}", DateTime.Now.ToString()); + + var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + + "tasks" + + SecurityContext.CurrentAccount.ID.ToString() + + searchText + + responsibleId + + categoryId + + fromDate.ToString(CultureInfo.InvariantCulture) + + toDate.ToString(CultureInfo.InvariantCulture) + + (int)entityType + + entityId; + + if (!String.IsNullOrEmpty(_cache.Get(cacheKey))) + { + LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. From cache", DateTime.Now.ToString()); + + return Convert.ToInt32(_cache.Get(cacheKey)); + } + + + if (!String.IsNullOrEmpty(searchText)) + { + var tasks = GetCrudeTasks(searchText, + responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null); + + if (CRMSecurity.IsAdmin) + result = tasks.Count(); + else + result = CRMSecurity.FilterRead(tasks).Count(); + } + else + { + if (CRMSecurity.IsAdmin) + { + + var sqlQuery = Query("crm_task tbl_tsk").SelectCount(); + + sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", + responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null); + + result = Db.ExecuteScalar(sqlQuery); + } + else + { + var taskIds = new List(); + + var sqlQuery = Query("crm_task tbl_tsk") + .Select("tbl_tsk.id") + .LeftOuterJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) + .Where(Exp.Or(Exp.Eq("tbl_ctc.is_shared", Exp.Empty), Exp.Gt("tbl_ctc.is_shared", 0))); + + sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", + responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null); + + // count tasks without entityId and only open contacts + + taskIds = Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList(); + + LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks without entityId and only open contacts", DateTime.Now.ToString()); + + + sqlQuery = Query("crm_task tbl_tsk") + .Select("tbl_tsk.id") + .InnerJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) + .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_ctc.tenant_id", "tbl_cl.tenant") & + Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & + Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Company|', tbl_ctc.id)")) + .Where(Exp.Eq("tbl_ctc.is_shared", 0)) + .Where(Exp.Eq("tbl_ctc.is_company", 1)); + + sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", + responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null); + + // count tasks with entityId and only close contacts + taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); + + LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); + + sqlQuery = Query("crm_task tbl_tsk") + .Select("tbl_tsk.id") + .InnerJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) + .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_ctc.tenant_id", "tbl_cl.tenant") & + Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & + Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Person|', tbl_ctc.id)")) + .Where(Exp.Eq("tbl_ctc.is_shared", 0)) + .Where(Exp.Eq("tbl_ctc.is_company", 0)); + + sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", + responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null); + + // count tasks with entityId and only close contacts + taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); + + LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); + + + sqlQuery = Query("crm_task tbl_tsk") + .Select("tbl_tsk.id") + .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & + Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & + Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Deal|', tbl_tsk.entity_id)")) + .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Opportunity) & Exp.Eq("tbl_tsk.contact_id", 0)); + + sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", + responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null); + + // count tasks with entityId and without contact + taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); + + LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); + + sqlQuery = Query("crm_task tbl_tsk") + .Select("tbl_tsk.id") + .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & + Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & + Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Cases|', tbl_tsk.entity_id)")) + .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Case) & Exp.Eq("tbl_tsk.contact_id", 0)); + + sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", + responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null); + + // count tasks with entityId and without contact + taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); + + result = taskIds.Distinct().Count(); + + LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); + + LogManager.GetLogger("ASC.CRM").Debug("Finish"); + + } + } + + + if (result > 0) + { + _cache.Insert(cacheKey, result, TimeSpan.FromMinutes(1)); + } + + return result; + } + + + private SqlQuery WhereConditional( + SqlQuery sqlQuery, + String alias, + Guid responsibleID, + int categoryID, + bool? isClosed, + DateTime fromDate, + DateTime toDate, + EntityType entityType, + int entityID, + int from, + int count, + OrderBy orderBy) + { + var aliasPrefix = !String.IsNullOrEmpty(alias) ? alias + "." : ""; + + if (responsibleID != Guid.Empty) + sqlQuery.Where(Exp.Eq("responsible_id", responsibleID)); + + if (entityID > 0) + switch (entityType) + { + case EntityType.Contact: + var isCompany = true; + isCompany = Db.ExecuteScalar(Query("crm_contact").Select("is_company").Where(Exp.Eq("id", entityID))); + + if (isCompany) + return WhereConditional(sqlQuery, alias, responsibleID, categoryID, isClosed, fromDate, toDate, EntityType.Company, entityID, from, count, orderBy); + else + return WhereConditional(sqlQuery, alias, responsibleID, categoryID, isClosed, fromDate, toDate, EntityType.Person, entityID, from, count, orderBy); + + case EntityType.Person: + sqlQuery.Where(Exp.Eq(aliasPrefix + "contact_id", entityID)); + break; + case EntityType.Company: + + var personIDs = GetRelativeToEntity(entityID, EntityType.Person, null).ToList(); + + if (personIDs.Count == 0) + sqlQuery.Where(Exp.Eq(aliasPrefix + "contact_id", entityID)); + else + { + personIDs.Add(entityID); + sqlQuery.Where(Exp.In(aliasPrefix + "contact_id", personIDs)); + } + + break; + case EntityType.Case: + case EntityType.Opportunity: + sqlQuery.Where(Exp.Eq(aliasPrefix + "entity_id", entityID) & + Exp.Eq(aliasPrefix + "entity_type", (int)entityType)); + break; + } + + + + if (isClosed.HasValue) + sqlQuery.Where(aliasPrefix + "is_closed", isClosed); + + if (categoryID > 0) + sqlQuery.Where(Exp.Eq(aliasPrefix + "category_id", categoryID)); + + if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) + sqlQuery.Where(Exp.Between(aliasPrefix + "deadline", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + else if (fromDate != DateTime.MinValue) + sqlQuery.Where(Exp.Ge(aliasPrefix + "deadline", TenantUtil.DateTimeToUtc(fromDate))); + else if (toDate != DateTime.MinValue) + sqlQuery.Where(Exp.Le(aliasPrefix + "deadline", TenantUtil.DateTimeToUtc(toDate))); + + if (0 < from && from < int.MaxValue) + sqlQuery.SetFirstResult(from); + + if (0 < count && count < int.MaxValue) + sqlQuery.SetMaxResults(count); + + sqlQuery.OrderBy(aliasPrefix + "is_closed", true); + + if (orderBy != null && Enum.IsDefined(typeof(TaskSortedByType), orderBy.SortedBy)) + { + switch ((TaskSortedByType)orderBy.SortedBy) + { + case TaskSortedByType.Title: + sqlQuery + .OrderBy(aliasPrefix + "title", orderBy.IsAsc) + .OrderBy(aliasPrefix + "deadline", true); + break; + case TaskSortedByType.DeadLine: + sqlQuery.OrderBy(aliasPrefix + "deadline", orderBy.IsAsc) + .OrderBy(aliasPrefix + "title", true); + break; + case TaskSortedByType.Category: + sqlQuery.OrderBy(aliasPrefix + "category_id", orderBy.IsAsc) + .OrderBy(aliasPrefix + "deadline", true) + .OrderBy(aliasPrefix + "title", true); + break; + case TaskSortedByType.ContactManager: + sqlQuery.LeftOuterJoin("core_user u", Exp.EqColumns(aliasPrefix + "responsible_id", "u.id")) + .OrderBy("case when u.lastname is null or u.lastname = '' then 1 else 0 end, u.lastname", orderBy.IsAsc) + .OrderBy("case when u.firstname is null or u.firstname = '' then 1 else 0 end, u.firstname", orderBy.IsAsc) + .OrderBy(aliasPrefix + "deadline", true) + .OrderBy(aliasPrefix + "title", true); + break; + case TaskSortedByType.Contact: + sqlQuery.LeftOuterJoin("crm_contact c_tbl", Exp.EqColumns(aliasPrefix + "contact_id", "c_tbl.id")) + .OrderBy("case when c_tbl.display_name is null then 1 else 0 end, c_tbl.display_name", orderBy.IsAsc) + .OrderBy(aliasPrefix + "deadline", true) + .OrderBy(aliasPrefix + "title", true); + break; + } + } + else + { + sqlQuery + .OrderBy(aliasPrefix + "deadline", true) + .OrderBy(aliasPrefix + "title", true); + } + + return sqlQuery; + + } + + public Dictionary GetNearestTask(int[] contactID) + { + var sqlSubQuery = + Query("crm_task") + .SelectMin("id") + .SelectMin("deadline") + .Select("contact_id") + .Where(Exp.In("contact_id", contactID) & Exp.Eq("is_closed", false)) + .GroupBy("contact_id"); + + var taskIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => row[0]); + + if (taskIDs.Count == 0) return new Dictionary(); + + var tasks = Db.ExecuteList(GetTaskQuery(Exp.In("id", taskIDs))).ConvertAll(row=>ToTask(row)).Where(CRMSecurity.CanAccessTo); + + var result = new Dictionary(); + + foreach (var task in tasks.Where(task => !result.ContainsKey(task.ContactID))) + { + result.Add(task.ContactID, task); + } + + return result; + } + + public IEnumerable GetResponsibles(int categoryID) + { + var q = Query("crm_task") + .Select("responsible_id") + .GroupBy(1); + + if (0 < categoryID) q.Where("category_id", categoryID); + + return Db.ExecuteList(q) + .ConvertAll(r => (string)r[0]) + .Select(r => new Guid(r)) + .Where(g => g != Guid.Empty) + .ToList(); + } + + + public Dictionary GetTasksCount(int[] contactID) + { + var sqlQuery = Query("crm_task") + .Select("contact_id") + .SelectCount() + .Where(Exp.In("contact_id", contactID)) + .GroupBy("contact_id"); + + var sqlResult = Db.ExecuteList(sqlQuery); + + return sqlResult.ToDictionary(item => Convert.ToInt32(item[0]), item => Convert.ToInt32(item[1])); + } + + public int GetTasksCount(int contactID) + { + var result = GetTasksCount(new[] { contactID }); + + if (result.Count == 0) return 0; + + return result[contactID]; + } + + public Dictionary HaveLateTask(int[] contactID) + { + var sqlQuery = Query("crm_task") + .Select("contact_id") + .Where(Exp.In("contact_id", contactID)) + .Where(Exp.Eq("is_closed", false) & + Exp.Lt("deadline", DateTime.UtcNow)) + .SelectCount() + .GroupBy("contact_id"); + + var sqlResult = Db.ExecuteList(sqlQuery); + + return sqlResult.ToDictionary(item => Convert.ToInt32(item[0]), item => Convert.ToInt32(item[1]) > 0); + } + + + public bool HaveLateTask(int contactID) + { + var result = HaveLateTask(new[] { contactID }); + + if (result.Count == 0) return false; + + return result[contactID]; + } + + public virtual Task SaveOrUpdateTask(Task newTask) + { + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + return SaveOrUpdateTaskInDb(newTask); + } + + public virtual Task[] SaveOrUpdateTaskList(List newTasks) + { + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + var result = new List(); + foreach (var newTask in newTasks) + { + result.Add(SaveOrUpdateTaskInDb(newTask)); + } + return result.ToArray(); + } + + private Task SaveOrUpdateTaskInDb(Task newTask) + { + if (String.IsNullOrEmpty(newTask.Title) || newTask.DeadLine == DateTime.MinValue || + newTask.CategoryID <= 0) + throw new ArgumentException(); + + if (newTask.ID == 0 || Db.ExecuteScalar(Query("crm_task").SelectCount().Where(Exp.Eq("id", newTask.ID))) == 0) + { + newTask.CreateOn = DateTime.UtcNow; + newTask.CreateBy = ASC.Core.SecurityContext.CurrentAccount.ID; + + newTask.LastModifedOn = DateTime.UtcNow; + newTask.LastModifedBy = ASC.Core.SecurityContext.CurrentAccount.ID; + + newTask.ID = Db.ExecuteScalar( + Insert("crm_task") + .InColumnValue("id", 0) + .InColumnValue("title", newTask.Title) + .InColumnValue("description", newTask.Description) + .InColumnValue("deadline", TenantUtil.DateTimeToUtc(newTask.DeadLine)) + .InColumnValue("responsible_id", newTask.ResponsibleID) + .InColumnValue("contact_id", newTask.ContactID) + .InColumnValue("entity_type", (int)newTask.EntityType) + .InColumnValue("entity_id", newTask.EntityID) + .InColumnValue("is_closed", newTask.IsClosed) + .InColumnValue("category_id", newTask.CategoryID) + .InColumnValue("create_on", newTask.CreateOn) + .InColumnValue("create_by", newTask.CreateBy) + .InColumnValue("last_modifed_on", newTask.LastModifedOn) + .InColumnValue("last_modifed_by", newTask.LastModifedBy) + .InColumnValue("alert_value", newTask.AlertValue) + .Identity(1, 0, true)); + } + else + { + var oldTask = Db.ExecuteList(GetTaskQuery(Exp.Eq("id", newTask.ID))) + .ConvertAll(row => ToTask(row)) + .FirstOrDefault(); + + CRMSecurity.DemandEdit(oldTask); + + newTask.CreateOn = oldTask.CreateOn; + newTask.CreateBy = oldTask.CreateBy; + + newTask.LastModifedOn = DateTime.UtcNow; + newTask.LastModifedBy = ASC.Core.SecurityContext.CurrentAccount.ID; + + newTask.IsClosed = oldTask.IsClosed; + + Db.ExecuteNonQuery( + Update("crm_task") + .Set("title", newTask.Title) + .Set("description", newTask.Description) + .Set("deadline", TenantUtil.DateTimeToUtc(newTask.DeadLine)) + .Set("responsible_id", newTask.ResponsibleID) + .Set("contact_id", newTask.ContactID) + .Set("entity_type", (int)newTask.EntityType) + .Set("entity_id", newTask.EntityID) + .Set("category_id", newTask.CategoryID) + .Set("last_modifed_on", newTask.LastModifedOn) + .Set("last_modifed_by", newTask.LastModifedBy) + .Set("alert_value", (int)newTask.AlertValue) + .Set("exec_alert", 0) + .Where(Exp.Eq("id", newTask.ID))); + } + + FactoryIndexer.IndexAsync(newTask); + return newTask; + } + + public virtual int SaveTask(Task newTask) + { + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + return SaveTaskInDb(newTask); + } + + private int SaveTaskInDb(Task newTask) + { + if (String.IsNullOrEmpty(newTask.Title) || newTask.DeadLine == DateTime.MinValue || + newTask.CategoryID == 0) + throw new ArgumentException(); + + var result = Db.ExecuteScalar( + Insert("crm_task") + .InColumnValue("id", 0) + .InColumnValue("title", newTask.Title) + .InColumnValue("description", newTask.Description) + .InColumnValue("deadline", TenantUtil.DateTimeToUtc(newTask.DeadLine)) + .InColumnValue("responsible_id", newTask.ResponsibleID) + .InColumnValue("contact_id", newTask.ContactID) + .InColumnValue("entity_type", (int)newTask.EntityType) + .InColumnValue("entity_id", newTask.EntityID) + .InColumnValue("is_closed", newTask.IsClosed) + .InColumnValue("category_id", newTask.CategoryID) + .InColumnValue("create_on", newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn) + .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn) + .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("alert_value", (int)newTask.AlertValue) + .Identity(1, 0, true)); + + newTask.ID = result; + FactoryIndexer.IndexAsync(newTask); + + return result; + } + + public virtual int[] SaveTaskList(List items) + { + using (var tx = Db.BeginTransaction()) + { + var result = new List(); + + foreach (var item in items) + { + result.Add(SaveTaskInDb(item)); + } + + tx.Commit(); + + return result.ToArray(); + } + } + + + public virtual void DeleteTask(int taskID) + { + var task = GetByID(taskID); + + if (task == null) return; + + CRMSecurity.DemandEdit(task); + + Db.ExecuteNonQuery(Delete("crm_task").Where("id", taskID)); + + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + FactoryIndexer.DeleteAsync(task); + } + + public List CreateByTemplate(List templateItems, EntityType entityType, int entityID) + { + if (templateItems == null || templateItems.Count == 0) return new List(); + + var result = new List(); + + using (var tx = Db.BeginTransaction()) + { + foreach (var templateItem in templateItems) + { + var task = new Task + { + ResponsibleID = templateItem.ResponsibleID, + Description = templateItem.Description, + DeadLine = TenantUtil.DateTimeNow().AddTicks(templateItem.Offset.Ticks), + CategoryID = templateItem.CategoryID, + Title = templateItem.Title, + CreateOn = TenantUtil.DateTimeNow(), + CreateBy = templateItem.CreateBy + }; + + switch (entityType) + { + case EntityType.Contact: + case EntityType.Person: + case EntityType.Company: + task.ContactID = entityID; + break; + case EntityType.Opportunity: + task.EntityType = EntityType.Opportunity; + task.EntityID = entityID; + break; + case EntityType.Case: + task.EntityType = EntityType.Case; + task.EntityID = entityID; + break; + default: + throw new NotImplementedException(); + } + + task = SaveOrUpdateTask(task); + + result.Add(task); + + Db.ExecuteNonQuery(Insert("crm_task_template_task") + .InColumnValue("task_id", task.ID) + .InColumnValue("task_template_id", templateItem.ID)); + + } + + tx.Commit(); + } + + return result; + } + + #region Private Methods + + private static Task ToTask(object[] row) + { + return new Task + { + ID = Convert.ToInt32(row[0]), + ContactID = Convert.ToInt32(row[1]), + Title = Convert.ToString(row[2]), + Description = Convert.ToString(row[3]), + DeadLine = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[4])), + ResponsibleID = ToGuid(row[5]), + IsClosed = Convert.ToBoolean(row[6]), + CategoryID = Convert.ToInt32(row[7]), + EntityID = Convert.ToInt32(row[8]), + EntityType = (EntityType)Convert.ToInt32(row[9]), + CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[10])), + CreateBy = ToGuid(row[11]), + AlertValue = Convert.ToInt32(row[12]) + }; + } + + + private String[] GetTaskColumnsTable(String alias) + { + if (!String.IsNullOrEmpty(alias)) + alias = alias + "."; + + var result = new List + { + "id", + "contact_id", + "title", + "description", + "deadline", + "responsible_id", + "is_closed", + "category_id", + "entity_id", + "entity_type", + "create_on", + "create_by", + "alert_value" + }; + + if (String.IsNullOrEmpty(alias)) return result.ToArray(); + + return result.ConvertAll(item => String.Concat(alias, item)).ToArray(); + } + + private SqlQuery GetTaskQuery(Exp where, String alias) + { + + var sqlQuery = Query("crm_task"); + + if (!String.IsNullOrEmpty(alias)) + { + sqlQuery = new SqlQuery(String.Concat("crm_task ", alias)) + .Where(Exp.Eq(alias + ".tenant_id", TenantID)); + sqlQuery.Select(GetTaskColumnsTable(alias)); + + } + else + sqlQuery.Select(GetTaskColumnsTable(String.Empty)); + + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + + } + + private SqlQuery GetTaskQuery(Exp where) + { + return GetTaskQuery(where, String.Empty); + + } + + + #endregion + + + public void ReassignTasksResponsible(Guid fromUserId, Guid toUserId) + { + var tasks = GetTasks(String.Empty, fromUserId, 0, false, DateTime.MinValue, DateTime.MinValue, + EntityType.Any, 0, 0, 0, null); + + foreach (var task in tasks) + { + task.ResponsibleID = toUserId; + + SaveOrUpdateTask(task); + } + } + + #endregion + + + /// + /// Test method + /// + /// + /// + public void SetTaskCreationDate(int taskId, DateTime creationDate) + { + Db.ExecuteNonQuery( + Update("crm_task") + .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) + .Where(Exp.Eq("id", taskId))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + } + + /// + /// Test method + /// + /// + /// + public void SetTaskLastModifedDate(int taskId, DateTime lastModifedDate) + { + Db.ExecuteNonQuery( + Update("crm_task") + .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) + .Where(Exp.Eq("id", taskId))); + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + } + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs new file mode 100644 index 00000000000..42f5d33e33b --- /dev/null +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -0,0 +1,348 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using ASC.Common.Data.Sql; +using ASC.Common.Data.Sql.Expressions; +using ASC.Core.Tenants; +using ASC.CRM.Core.Entities; + +#endregion + +namespace ASC.CRM.Core.Dao +{ + public class CachedTaskTemplateContainerDao : TaskTemplateContainerDao + { + #region Constructor + + public CachedTaskTemplateContainerDao(int tenantID) + : base(tenantID) + { + + + } + + #endregion + + } + + public class CachedTaskTemplateDao : TaskTemplateDao + { + + #region Constructor + + public CachedTaskTemplateDao(int tenantID) + : base(tenantID) + { + + + } + + #endregion + } + + public class TaskTemplateContainerDao : AbstractDao + { + #region Constructor + + public TaskTemplateContainerDao(int tenantID) + : base(tenantID) + { + + + } + + #endregion + + #region Methods + + public virtual int SaveOrUpdate(TaskTemplateContainer item) + { + if (item.ID == 0 && Db.ExecuteScalar(Query("crm_task_template_container").SelectCount().Where(Exp.Eq("id", item.ID))) == 0) + { + + item.ID = Db.ExecuteScalar( + Insert("crm_task_template_container") + .InColumnValue("id", 0) + .InColumnValue("title", item.Title) + .InColumnValue("entity_type", (int)item.EntityType) + .InColumnValue("create_on", DateTime.UtcNow) + .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", DateTime.UtcNow) + .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + + } + else + { + + Db.ExecuteScalar( + Update("crm_task_template_container") + .Set("title", item.Title) + .Set("entity_type", (int)item.EntityType) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Where(Exp.Eq("id", item.ID))); + + + + } + + + return item.ID; + } + + public virtual void Delete(int id) + { + + if (id <= 0) + throw new ArgumentException(); + + Db.ExecuteNonQuery(Delete("crm_task_template_container").Where("id", id)); + } + + public virtual TaskTemplateContainer GetByID(int id) + { + + if (id <= 0) + throw new ArgumentException(); + + var result = Db.ExecuteList(GetQuery(null).Where(Exp.Eq("id", id))).ConvertAll(row => ToObject(row)); + + if (result.Count == 0) return null; + + return result[0]; + } + + public virtual List GetItems(EntityType entityType) + { + if (!_supportedEntityType.Contains(entityType)) + throw new ArgumentException("", entityType.ToString()); + + return Db.ExecuteList(GetQuery(Exp.Eq("entity_type", (int)entityType))) + .ConvertAll(row => ToObject(row)); + } + + #endregion + + protected SqlQuery GetQuery(Exp where) + { + + var sqlQuery = Query("crm_task_template_container") + .Select("id", + "title", + "entity_type"); + + if (where != null) + sqlQuery.Where(where); + + return sqlQuery; + } + + protected TaskTemplateContainer ToObject(object[] row) + { + return new TaskTemplateContainer + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + EntityType = (EntityType)Convert.ToInt32(row[2]) + }; + } + } + + public class TaskTemplateDao : AbstractDao + { + #region Constructor + + public TaskTemplateDao(int tenantID) + : base(tenantID) + { + + } + + #endregion + + #region Methods + + public int SaveOrUpdate(TaskTemplate item) + { + if (item.ID == 0 && Db.ExecuteScalar(Query("crm_task_template").SelectCount().Where(Exp.Eq("id", item.ID))) == 0) + { + + item.ID = Db.ExecuteScalar( + Insert("crm_task_template") + .InColumnValue("id", 0) + .InColumnValue("title", item.Title) + .InColumnValue("category_id", item.CategoryID) + .InColumnValue("description", item.Description) + .InColumnValue("responsible_id", item.ResponsibleID) + .InColumnValue("is_notify", item.isNotify) + .InColumnValue("offset", item.Offset.Ticks) + .InColumnValue("deadLine_is_fixed", item.DeadLineIsFixed) + .InColumnValue("container_id", item.ContainerID) + .InColumnValue("create_on", DateTime.UtcNow) + .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_on", DateTime.UtcNow) + .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Identity(1, 0, true)); + + } + else + { + + Db.ExecuteNonQuery( + Update("crm_task_template") + .Set("title", item.Title) + .Set("category_id", item.CategoryID) + .Set("description", item.Description) + .Set("responsible_id", item.ResponsibleID) + .Set("is_notify", item.isNotify) + .Set("offset", item.Offset.Ticks) + .Set("deadLine_is_fixed", item.DeadLineIsFixed) + .Set("container_id", item.ContainerID) + .Set("last_modifed_on", DateTime.UtcNow) + .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Where("id", item.ID)); + + } + + return item.ID; + } + + public TaskTemplate GetNext(int taskID) + { + using (var tx = Db.BeginTransaction()) + { + var sqlResult = Db.ExecuteList( + Query("crm_task_template_task tblTTT") + .Select("tblTT.container_id") + .Select("tblTT.sort_order") + .LeftOuterJoin("crm_task_template tblTT", Exp.EqColumns("tblTT.tenant_id", "tblTTT.tenant_id") & Exp.EqColumns("tblTT.id", "tblTTT.task_template_id")) + .Where(Exp.Eq("tblTTT.task_id", taskID) & Exp.Eq("tblTT.tenant_id", TenantID))); + + if (sqlResult.Count == 0) return null; + + var result = Db.ExecuteList(GetQuery(Exp.Eq("container_id", sqlResult[0][0]) & + Exp.Gt("sort_order", sqlResult[0][1]) & + Exp.Eq("deadLine_is_fixed", false)).SetMaxResults(1)).ConvertAll( + row => ToObject(row)); + + Db.ExecuteNonQuery(Delete("crm_task_template_task").Where(Exp.Eq("task_id", taskID))); + + tx.Commit(); + + if (result.Count == 0) return null; + + return result[0]; + } + } + + public List GetAll() + { + return Db.ExecuteList(GetQuery(null)) + .ConvertAll(row => ToObject(row)); + } + + public List GetList(int containerID) + { + if (containerID <= 0) + throw new NotImplementedException(); + + return Db.ExecuteList(GetQuery(Exp.Eq("container_id", containerID))) + .ConvertAll(row => ToObject(row)); + } + + public virtual TaskTemplate GetByID(int id) + { + if (id <= 0) + throw new NotImplementedException(); + + var items = Db.ExecuteList(GetQuery(Exp.Eq("id", id))).ConvertAll(row => ToObject(row)); + + if (items.Count == 0) + return null; + + return items[0]; + } + + public virtual void Delete(int id) + { + if (id <= 0) + throw new NotImplementedException(); + + Db.ExecuteNonQuery(Delete("crm_task_template").Where("id", id)); + } + + protected TaskTemplate ToObject(object[] row) + { + return new TaskTemplate + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + CategoryID = Convert.ToInt32(row[2]), + Description = Convert.ToString(row[3]), + ResponsibleID = ToGuid(row[4]), + isNotify = Convert.ToBoolean(row[5]), + Offset = TimeSpan.FromTicks((long)row[6]), + DeadLineIsFixed = Convert.ToBoolean(row[7]), + ContainerID = Convert.ToInt32(row[8]), + CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[9])), + CreateBy = ToGuid(row[10]) + }; + } + + protected SqlQuery GetQuery(Exp where) + { + var sqlQuery = Query("crm_task_template") + .Select("id", + "title", + "category_id", + "description", + "responsible_id", + "is_notify", + "offset", + "deadLine_is_fixed", + "container_id", + "create_on", + "create_by" + ); + + if (where != null) + sqlQuery.Where(where); + + sqlQuery.OrderBy("sort_order", true); + + return sqlQuery; + } + + #endregion + + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/DomainObject.cs b/products/ASC.CRM/Server/Core/DomainObject.cs new file mode 100644 index 00000000000..84c04aa4d04 --- /dev/null +++ b/products/ASC.CRM/Server/Core/DomainObject.cs @@ -0,0 +1,70 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; + +#endregion + +namespace ASC.CRM.Core +{ + [DataContract] + [Serializable] + public class DomainObject + { + + [DataMember(Name = "id")] + public virtual int ID + { + get; + set; + } + + public override int GetHashCode() + { + return (GetType().FullName + "|" + ID.GetHashCode()).GetHashCode(); + } + + public override bool Equals(object obj) + { + var compareTo = obj as DomainObject; + return compareTo != null && ( + (!IsTransient() && !compareTo.IsTransient() && ID.Equals(compareTo.ID)) || + ((IsTransient() || compareTo.IsTransient()) && GetHashCode().Equals(compareTo.GetHashCode()))); + } + + private bool IsTransient() + { + return ID.Equals(default(int)); + } + + } +} diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs new file mode 100644 index 00000000000..fbd77613b57 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -0,0 +1,691 @@ +using System; +using ASC.Core.Common.EF; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; + +namespace ASC.CRM.Core.EF +{ + public partial class CRMDbContext : BaseDbContext + { + //public CRMDbContext() + //{ + //} + + //public CRMDbContext(DbContextOptions options) + // : base(options) + //{ + //} + + public virtual DbSet CrmCase { get; set; } + public virtual DbSet CrmContact { get; set; } + public virtual DbSet CrmContactInfo { get; set; } + public virtual DbSet CrmCurrencyInfo { get; set; } + public virtual DbSet CrmCurrencyRate { get; set; } + public virtual DbSet CrmDeal { get; set; } + public virtual DbSet CrmDealMilestone { get; set; } + public virtual DbSet CrmEntityContact { get; set; } + public virtual DbSet CrmEntityTag { get; set; } + public virtual DbSet CrmFieldDescription { get; set; } + public virtual DbSet CrmFieldValue { get; set; } + public virtual DbSet CrmInvoice { get; set; } + public virtual DbSet CrmInvoiceItem { get; set; } + public virtual DbSet CrmInvoiceLine { get; set; } + public virtual DbSet CrmInvoiceTax { get; set; } + public virtual DbSet CrmListItem { get; set; } + public virtual DbSet CrmOrganisationLogo { get; set; } + public virtual DbSet CrmProjects { get; set; } + public virtual DbSet CrmRelationshipEvent { get; set; } + public virtual DbSet CrmReportFile { get; set; } + public virtual DbSet CrmTag { get; set; } + public virtual DbSet CrmTask { get; set; } + public virtual DbSet CrmTaskTemplate { get; set; } + public virtual DbSet CrmTaskTemplateContainer { get; set; } + public virtual DbSet CrmTaskTemplateTask { get; set; } + public virtual DbSet CrmVoipCalls { get; set; } + public virtual DbSet CrmVoipNumber { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => new { e.LastModifedOn, e.TenantId }) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.CompanyId }) + .HasName("company_id"); + + entity.HasIndex(e => new { e.TenantId, e.DisplayName }) + .HasName("display_name"); + + entity.Property(e => e.CompanyName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Currency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.DisplayName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.FirstName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Industry) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Notes) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.ContactId }) + .HasName("IX_Contact"); + + entity.Property(e => e.Data) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Abbreviation) + .HasName("PRIMARY"); + + entity.Property(e => e.Abbreviation) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.CultureName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ResourceKey) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Symbol) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.FromCurrency) + .HasName("from_currency"); + + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.FromCurrency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ToCurrency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => e.DealMilestoneId) + .HasName("deal_milestone_id"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.ContactId }) + .HasName("contact_id"); + + entity.Property(e => e.BidCurrency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ResponsibleId) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.Color) + .HasDefaultValueSql("'0'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.EntityId, e.EntityType, e.ContactId }) + .HasName("PRIMARY"); + + entity.HasIndex(e => e.ContactId) + .HasName("IX_Contact"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.EntityId, e.EntityType, e.TagId }) + .HasName("PRIMARY"); + + entity.HasIndex(e => e.TagId) + .HasName("tag_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => new { e.TenantId, e.EntityType, e.SortOrder }) + .HasName("entity_type"); + + entity.Property(e => e.Label) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Mask) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.FieldId) + .HasName("field_id"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType, e.FieldId }) + .HasName("tenant_id"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Value) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.ConsigneeId).HasDefaultValueSql("'-1'"); + + entity.Property(e => e.ContactId).HasDefaultValueSql("'-1'"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Currency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ExchangeRate).HasDefaultValueSql("'1.00'"); + + entity.Property(e => e.FileId).HasDefaultValueSql("'-1'"); + + entity.Property(e => e.JsonData) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Language) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Number) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.PurchaseOrderNumber) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Status).HasDefaultValueSql("'1'"); + + entity.Property(e => e.Terms) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Currency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.StockKeepingUnit) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Name) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => new { e.TenantId, e.ListType }) + .HasName("list_type"); + + entity.Property(e => e.AdditionalParams) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Color) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.Content) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.TenantId, e.ContactId, e.ProjectId }) + .HasName("PRIMARY"); + + entity.HasIndex(e => new { e.TenantId, e.ContactId }) + .HasName("contact_id"); + + entity.HasIndex(e => new { e.TenantId, e.ProjectId }) + .HasName("project_id"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.ContactId) + .HasName("IX_Contact"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.HasIndex(e => new { e.EntityId, e.EntityType }) + .HasName("IX_Entity"); + + entity.Property(e => e.Content) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.FileId) + .HasName("PRIMARY"); + + entity.HasIndex(e => e.CreateBy) + .HasName("create_by"); + + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_bin"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => e.Deadline) + .HasName("deadline"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.ContactId }) + .HasName("IX_Contact"); + + entity.HasIndex(e => new { e.TenantId, e.ResponsibleId }) + .HasName("responsible_id"); + + entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType }) + .HasName("IX_Entity"); + + entity.Property(e => e.ContactId).HasDefaultValueSql("'-1'"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ResponsibleId) + .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => new { e.TenantId, e.ContainerId }) + .HasName("template_id"); + + entity.Property(e => e.CreateBy) + .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ResponsibleId) + .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => new { e.TenantId, e.EntityType }) + .HasName("entity_type"); + + entity.Property(e => e.CreateBy) + .HasDefaultValueSql("'0'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasDefaultValueSql("'0'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.TenantId, e.TaskId, e.TaskTemplateId }) + .HasName("PRIMARY"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.HasIndex(e => new { e.ParentCallId, e.TenantId }) + .HasName("parent_call_id"); + + entity.Property(e => e.Id) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.AnsweredBy) + .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.NumberFrom) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.NumberTo) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ParentCallId) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.RecordSid) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.RecordUrl) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.Id) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Alias) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Number) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Settings) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmCase.cs b/products/ASC.CRM/Server/Core/EF/CrmCase.cs new file mode 100644 index 00000000000..61a865d503a --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmCase.cs @@ -0,0 +1,32 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_case")] + public partial class CrmCase + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Column("is_closed")] + public bool IsClosed { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmContact.cs b/products/ASC.CRM/Server/Core/EF/CrmContact.cs new file mode 100644 index 00000000000..ffd1609b019 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmContact.cs @@ -0,0 +1,53 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_contact")] + public partial class CrmContact + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("is_company")] + public bool IsCompany { get; set; } + [Column("notes", TypeName = "text")] + public string Notes { get; set; } + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Column("first_name", TypeName = "varchar(255)")] + public string FirstName { get; set; } + [Column("last_name", TypeName = "varchar(255)")] + public string LastName { get; set; } + [Column("company_name", TypeName = "varchar(255)")] + public string CompanyName { get; set; } + [Column("industry", TypeName = "varchar(255)")] + public string Industry { get; set; } + [Column("status_id", TypeName = "int(11)")] + public int StatusId { get; set; } + [Column("company_id", TypeName = "int(11)")] + public int CompanyId { get; set; } + [Column("contact_type_id", TypeName = "int(11)")] + public int ContactTypeId { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("display_name", TypeName = "varchar(255)")] + public string DisplayName { get; set; } + [Column("is_shared", TypeName = "tinyint(4)")] + public sbyte? IsShared { get; set; } + [Column("currency", TypeName = "varchar(3)")] + public string Currency { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmContactInfo.cs b/products/ASC.CRM/Server/Core/EF/CrmContactInfo.cs new file mode 100644 index 00000000000..772723612b8 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmContactInfo.cs @@ -0,0 +1,33 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_contact_info")] + public partial class CrmContactInfo + { + [Key] + [Column("id", TypeName = "int(10)")] + public int Id { get; set; } + [Required] + [Column("data", TypeName = "text")] + public string Data { get; set; } + [Column("category", TypeName = "int(255)")] + public int Category { get; set; } + [Column("tenant_id", TypeName = "int(255)")] + public int TenantId { get; set; } + [Column("is_primary", TypeName = "tinyint(4)")] + public sbyte IsPrimary { get; set; } + [Column("contact_id", TypeName = "int(11)")] + public int ContactId { get; set; } + [Column("type", TypeName = "int(255)")] + public int Type { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs b/products/ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs new file mode 100644 index 00000000000..8368513e568 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs @@ -0,0 +1,29 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_currency_info")] + public partial class CrmCurrencyInfo + { + [Required] + [Column("resource_key", TypeName = "varchar(255)")] + public string ResourceKey { get; set; } + [Key] + [Column("abbreviation", TypeName = "varchar(255)")] + public string Abbreviation { get; set; } + [Required] + [Column("symbol", TypeName = "varchar(255)")] + public string Symbol { get; set; } + [Required] + [Column("culture_name", TypeName = "varchar(255)")] + public string CultureName { get; set; } + [Column("is_convertable", TypeName = "tinyint(4)")] + public sbyte IsConvertable { get; set; } + [Column("is_basic", TypeName = "tinyint(4)")] + public sbyte IsBasic { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs b/products/ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs new file mode 100644 index 00000000000..fc63ba28d09 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs @@ -0,0 +1,35 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_currency_rate")] + public partial class CrmCurrencyRate + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("from_currency", TypeName = "varchar(255)")] + public string FromCurrency { get; set; } + [Required] + [Column("to_currency", TypeName = "varchar(255)")] + public string ToCurrency { get; set; } + [Column("rate", TypeName = "decimal(10,2)")] + public decimal Rate { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmDeal.cs b/products/ASC.CRM/Server/Core/EF/CrmDeal.cs new file mode 100644 index 00000000000..dd14d6353b8 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmDeal.cs @@ -0,0 +1,53 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_deal")] + public partial class CrmDeal + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Column("description", TypeName = "text")] + public string Description { get; set; } + [Required] + [Column("responsible_id", TypeName = "char(38)")] + public string ResponsibleId { get; set; } + [Column("contact_id", TypeName = "int(11)")] + public int ContactId { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("bid_currency", TypeName = "varchar(255)")] + public string BidCurrency { get; set; } + [Column("bid_value", TypeName = "decimal(50,9)")] + public decimal BidValue { get; set; } + [Column("bid_type", TypeName = "int(11)")] + public int BidType { get; set; } + [Column("deal_milestone_id", TypeName = "int(11)")] + public int DealMilestoneId { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("expected_close_date", TypeName = "datetime")] + public DateTime ExpectedCloseDate { get; set; } + [Column("per_period_value", TypeName = "int(11)")] + public int PerPeriodValue { get; set; } + [Column("deal_milestone_probability", TypeName = "int(11)")] + public int? DealMilestoneProbability { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("actual_close_date", TypeName = "datetime")] + public DateTime? ActualCloseDate { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmDealMilestone.cs b/products/ASC.CRM/Server/Core/EF/CrmDealMilestone.cs new file mode 100644 index 00000000000..cf07306ae1a --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmDealMilestone.cs @@ -0,0 +1,32 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_deal_milestone")] + public partial class CrmDealMilestone + { + [Key] + [Column("id", TypeName = "int(10)")] + public int Id { get; set; } + [Required] + [Column("color", TypeName = "varchar(50)")] + public string Color { get; set; } + [Column("sort_order", TypeName = "int(10)")] + public int SortOrder { get; set; } + [Required] + [Column("title", TypeName = "varchar(250)")] + public string Title { get; set; } + [Column("description", TypeName = "text")] + public string Description { get; set; } + [Column("probability", TypeName = "int(10)")] + public int Probability { get; set; } + [Column("status", TypeName = "int(10)")] + public int Status { get; set; } + [Column("tenant_id", TypeName = "int(10)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmEntityContact.cs b/products/ASC.CRM/Server/Core/EF/CrmEntityContact.cs new file mode 100644 index 00000000000..580f94ba475 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmEntityContact.cs @@ -0,0 +1,22 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_entity_contact")] + public partial class CrmEntityContact + { + [Key] + [Column("entity_id", TypeName = "int(11)")] + public int EntityId { get; set; } + [Key] + [Column("entity_type", TypeName = "int(11)")] + public int EntityType { get; set; } + [Key] + [Column("contact_id", TypeName = "int(11)")] + public int ContactId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmEntityTag.cs b/products/ASC.CRM/Server/Core/EF/CrmEntityTag.cs new file mode 100644 index 00000000000..aeb57f1b898 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmEntityTag.cs @@ -0,0 +1,22 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_entity_tag")] + public partial class CrmEntityTag + { + [Key] + [Column("tag_id", TypeName = "int(11)")] + public int TagId { get; set; } + [Key] + [Column("entity_id", TypeName = "int(11)")] + public int EntityId { get; set; } + [Key] + [Column("entity_type", TypeName = "int(10)")] + public int EntityType { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmFieldDescription.cs b/products/ASC.CRM/Server/Core/EF/CrmFieldDescription.cs new file mode 100644 index 00000000000..02f6fb15db8 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmFieldDescription.cs @@ -0,0 +1,29 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_field_description")] + public partial class CrmFieldDescription + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Required] + [Column("label", TypeName = "varchar(255)")] + public string Label { get; set; } + [Column("type", TypeName = "int(11)")] + public int Type { get; set; } + [Column("sort_order", TypeName = "int(11)")] + public int SortOrder { get; set; } + [Column("mask", TypeName = "text")] + public string Mask { get; set; } + [Column("entity_type", TypeName = "int(255)")] + public int EntityType { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmFieldValue.cs b/products/ASC.CRM/Server/Core/EF/CrmFieldValue.cs new file mode 100644 index 00000000000..7eaf7c0066b --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmFieldValue.cs @@ -0,0 +1,30 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_field_value")] + public partial class CrmFieldValue + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Column("value", TypeName = "text")] + public string Value { get; set; } + [Column("entity_id", TypeName = "int(11)")] + public int EntityId { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("field_id", TypeName = "int(11)")] + public int FieldId { get; set; } + [Column("entity_type", TypeName = "int(10)")] + public int EntityType { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoice.cs b/products/ASC.CRM/Server/Core/EF/CrmInvoice.cs new file mode 100644 index 00000000000..6ba2358ced3 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmInvoice.cs @@ -0,0 +1,65 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_invoice")] + public partial class CrmInvoice + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Column("status", TypeName = "int(11)")] + public int Status { get; set; } + [Required] + [Column("number", TypeName = "varchar(255)")] + public string Number { get; set; } + [Column("issue_date", TypeName = "datetime")] + public DateTime IssueDate { get; set; } + [Column("template_type", TypeName = "int(11)")] + public int TemplateType { get; set; } + [Column("contact_id", TypeName = "int(11)")] + public int ContactId { get; set; } + [Column("consignee_id", TypeName = "int(11)")] + public int ConsigneeId { get; set; } + [Column("entity_type", TypeName = "int(11)")] + public int EntityType { get; set; } + [Column("entity_id", TypeName = "int(11)")] + public int EntityId { get; set; } + [Column("due_date", TypeName = "datetime")] + public DateTime DueDate { get; set; } + [Required] + [Column("language", TypeName = "varchar(255)")] + public string Language { get; set; } + [Required] + [Column("currency", TypeName = "varchar(255)")] + public string Currency { get; set; } + [Column("exchange_rate", TypeName = "decimal(10,2)")] + public decimal ExchangeRate { get; set; } + [Required] + [Column("purchase_order_number", TypeName = "varchar(255)")] + public string PurchaseOrderNumber { get; set; } + [Column("terms", TypeName = "text")] + public string Terms { get; set; } + [Column("description", TypeName = "text")] + public string Description { get; set; } + [Column("json_data", TypeName = "text")] + public string JsonData { get; set; } + [Column("file_id", TypeName = "int(11)")] + public int FileId { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs b/products/ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs new file mode 100644 index 00000000000..d6ec6d9961c --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs @@ -0,0 +1,49 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_invoice_item")] + public partial class CrmInvoiceItem + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Required] + [Column("description", TypeName = "text")] + public string Description { get; set; } + [Required] + [Column("stock_keeping_unit", TypeName = "varchar(255)")] + public string StockKeepingUnit { get; set; } + [Column("price", TypeName = "decimal(10,2)")] + public decimal Price { get; set; } + [Column("stock_quantity", TypeName = "decimal(10,2)")] + public decimal StockQuantity { get; set; } + [Column("track_inventory", TypeName = "tinyint(4)")] + public sbyte TrackInventory { get; set; } + [Column("invoice_tax1_id", TypeName = "int(11)")] + public int InvoiceTax1Id { get; set; } + [Column("invoice_tax2_id", TypeName = "int(11)")] + public int InvoiceTax2Id { get; set; } + [Required] + [Column("currency", TypeName = "varchar(255)")] + public string Currency { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs b/products/ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs new file mode 100644 index 00000000000..fc0082da34e --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs @@ -0,0 +1,37 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_invoice_line")] + public partial class CrmInvoiceLine + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Column("invoice_id", TypeName = "int(11)")] + public int InvoiceId { get; set; } + [Column("invoice_item_id", TypeName = "int(11)")] + public int InvoiceItemId { get; set; } + [Column("invoice_tax1_id", TypeName = "int(11)")] + public int InvoiceTax1Id { get; set; } + [Column("invoice_tax2_id", TypeName = "int(11)")] + public int InvoiceTax2Id { get; set; } + [Required] + [Column("description", TypeName = "text")] + public string Description { get; set; } + [Column("quantity", TypeName = "decimal(10,2)")] + public decimal Quantity { get; set; } + [Column("price", TypeName = "decimal(10,2)")] + public decimal Price { get; set; } + [Column("discount", TypeName = "decimal(10,2)")] + public decimal Discount { get; set; } + [Column("sort_order", TypeName = "int(11)")] + public int SortOrder { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs b/products/ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs new file mode 100644 index 00000000000..dea1fe96d21 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs @@ -0,0 +1,35 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_invoice_tax")] + public partial class CrmInvoiceTax + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("name", TypeName = "varchar(255)")] + public string Name { get; set; } + [Required] + [Column("description", TypeName = "text")] + public string Description { get; set; } + [Column("rate", TypeName = "decimal(10,2)")] + public decimal Rate { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmListItem.cs b/products/ASC.CRM/Server/Core/EF/CrmListItem.cs new file mode 100644 index 00000000000..30e2d845801 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmListItem.cs @@ -0,0 +1,31 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_list_item")] + public partial class CrmListItem + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Column("sort_order", TypeName = "int(11)")] + public int SortOrder { get; set; } + [Column("color", TypeName = "varchar(255)")] + public string Color { get; set; } + [Column("additional_params", TypeName = "varchar(255)")] + public string AdditionalParams { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("list_type", TypeName = "int(255)")] + public int? ListType { get; set; } + [Column("description", TypeName = "varchar(255)")] + public string Description { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmOrganisationLogo.cs b/products/ASC.CRM/Server/Core/EF/CrmOrganisationLogo.cs new file mode 100644 index 00000000000..778fa075fdc --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmOrganisationLogo.cs @@ -0,0 +1,26 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_organisation_logo")] + public partial class CrmOrganisationLogo + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("content", TypeName = "mediumtext")] + public string Content { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmProjects.cs b/products/ASC.CRM/Server/Core/EF/CrmProjects.cs new file mode 100644 index 00000000000..ce04722c982 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmProjects.cs @@ -0,0 +1,22 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_projects")] + public partial class CrmProjects + { + [Key] + [Column("project_id", TypeName = "int(10)")] + public int ProjectId { get; set; } + [Key] + [Column("contact_id", TypeName = "int(10)")] + public int ContactId { get; set; } + [Key] + [Column("tenant_id", TypeName = "int(10)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/CrmRelationshipEvent.cs new file mode 100644 index 00000000000..8ef51ce22fb --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmRelationshipEvent.cs @@ -0,0 +1,39 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_relationship_event")] + public partial class CrmRelationshipEvent + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Column("contact_id", TypeName = "int(11)")] + public int ContactId { get; set; } + [Column("content", TypeName = "text")] + public string Content { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("entity_type", TypeName = "int(11)")] + public int EntityType { get; set; } + [Column("entity_id", TypeName = "int(11)")] + public int EntityId { get; set; } + [Column("category_id", TypeName = "int(11)")] + public int CategoryId { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("have_files", TypeName = "int(11)")] + public int HaveFiles { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmReportFile.cs b/products/ASC.CRM/Server/Core/EF/CrmReportFile.cs new file mode 100644 index 00000000000..011241dc107 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmReportFile.cs @@ -0,0 +1,25 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_report_file")] + public partial class CrmReportFile + { + [Key] + [Column("file_id", TypeName = "int(11)")] + public int FileId { get; set; } + [Column("report_type", TypeName = "int(11)")] + public int ReportType { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTag.cs b/products/ASC.CRM/Server/Core/EF/CrmTag.cs new file mode 100644 index 00000000000..810441e4c31 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmTag.cs @@ -0,0 +1,23 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_tag")] + public partial class CrmTag + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("entity_type", TypeName = "int(11)")] + public int EntityType { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTask.cs b/products/ASC.CRM/Server/Core/EF/CrmTask.cs new file mode 100644 index 00000000000..b339f9fdd10 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmTask.cs @@ -0,0 +1,51 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_task")] + public partial class CrmTask + { + [Key] + [Column("id", TypeName = "int(11)")] + public int Id { get; set; } + [Required] + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Column("description", TypeName = "text")] + public string Description { get; set; } + [Column("deadline", TypeName = "datetime")] + public DateTime Deadline { get; set; } + [Required] + [Column("responsible_id", TypeName = "char(38)")] + public string ResponsibleId { get; set; } + [Column("contact_id", TypeName = "int(11)")] + public int ContactId { get; set; } + [Column("is_closed", TypeName = "int(1)")] + public int IsClosed { get; set; } + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + [Column("entity_type", TypeName = "int(11)")] + public int EntityType { get; set; } + [Column("entity_id", TypeName = "int(11)")] + public int EntityId { get; set; } + [Column("category_id", TypeName = "int(11)")] + public int CategoryId { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Column("alert_value", TypeName = "int(10)")] + public int AlertValue { get; set; } + [Column("exec_alert", TypeName = "int(10)")] + public int ExecAlert { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs b/products/ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs new file mode 100644 index 00000000000..3b694981a7d --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs @@ -0,0 +1,48 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_task_template")] + public partial class CrmTaskTemplate + { + [Key] + [Column("id", TypeName = "int(10)")] + public int Id { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime LastModifedOn { get; set; } + [Required] + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + [Required] + [Column("title", TypeName = "varchar(255)")] + public string Title { get; set; } + [Column("category_id", TypeName = "int(10)")] + public int CategoryId { get; set; } + [Column("description", TypeName = "tinytext")] + public string Description { get; set; } + [Required] + [Column("responsible_id", TypeName = "char(38)")] + public string ResponsibleId { get; set; } + [Column("is_notify", TypeName = "tinyint(4)")] + public sbyte IsNotify { get; set; } + [Column("offset", TypeName = "bigint(20)")] + public long Offset { get; set; } + [Column("sort_order", TypeName = "int(11)")] + public int SortOrder { get; set; } + [Column("deadLine_is_fixed", TypeName = "tinyint(4)")] + public sbyte DeadLineIsFixed { get; set; } + [Column("tenant_id", TypeName = "int(10)")] + public int TenantId { get; set; } + [Column("container_id", TypeName = "int(10)")] + public int ContainerId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateContainer.cs new file mode 100644 index 00000000000..5105b10bf5c --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateContainer.cs @@ -0,0 +1,33 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_task_template_container")] + public partial class CrmTaskTemplateContainer + { + [Key] + [Column("id", TypeName = "int(10)")] + public int Id { get; set; } + [Required] + [Column("title", TypeName = "varchar(256)")] + public string Title { get; set; } + [Column("entity_type", TypeName = "int(10)")] + public int EntityType { get; set; } + [Column("tenant_id", TypeName = "int(10)")] + public int TenantId { get; set; } + [Column("create_on", TypeName = "datetime")] + public DateTime CreateOn { get; set; } + [Required] + [Column("create_by", TypeName = "char(38)")] + public string CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] + public DateTime LastModifedOn { get; set; } + [Required] + [Column("last_modifed_by", TypeName = "char(38)")] + public string LastModifedBy { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateTask.cs b/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateTask.cs new file mode 100644 index 00000000000..cc51f2c0249 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateTask.cs @@ -0,0 +1,22 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_task_template_task")] + public partial class CrmTaskTemplateTask + { + [Key] + [Column("task_id", TypeName = "int(10)")] + public int TaskId { get; set; } + [Key] + [Column("task_template_id", TypeName = "int(10)")] + public int TaskTemplateId { get; set; } + [Key] + [Column("tenant_id", TypeName = "int(10)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmVoipCalls.cs b/products/ASC.CRM/Server/Core/EF/CrmVoipCalls.cs new file mode 100644 index 00000000000..b493c90d0f1 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmVoipCalls.cs @@ -0,0 +1,48 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_voip_calls")] + public partial class CrmVoipCalls + { + [Key] + [Column("id", TypeName = "varchar(50)")] + public string Id { get; set; } + [Required] + [Column("parent_call_id", TypeName = "varchar(50)")] + public string ParentCallId { get; set; } + [Required] + [Column("number_from", TypeName = "varchar(50)")] + public string NumberFrom { get; set; } + [Required] + [Column("number_to", TypeName = "varchar(50)")] + public string NumberTo { get; set; } + [Column("status", TypeName = "int(10)")] + public int? Status { get; set; } + [Required] + [Column("answered_by", TypeName = "varchar(50)")] + public string AnsweredBy { get; set; } + [Column("dial_date", TypeName = "datetime")] + public DateTime? DialDate { get; set; } + [Column("dial_duration", TypeName = "int(11)")] + public int? DialDuration { get; set; } + [Column("record_sid", TypeName = "varchar(50)")] + public string RecordSid { get; set; } + [Column("record_url", TypeName = "text")] + public string RecordUrl { get; set; } + [Column("record_duration", TypeName = "int(11)")] + public int? RecordDuration { get; set; } + [Column("record_price", TypeName = "decimal(10,4)")] + public decimal RecordPrice { get; set; } + [Column("contact_id", TypeName = "int(10)")] + public int? ContactId { get; set; } + [Column("price", TypeName = "decimal(10,4)")] + public decimal? Price { get; set; } + [Column("tenant_id", TypeName = "int(10)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmVoipNumber.cs b/products/ASC.CRM/Server/Core/EF/CrmVoipNumber.cs new file mode 100644 index 00000000000..41d8e66a3a1 --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmVoipNumber.cs @@ -0,0 +1,25 @@ +// This file has been auto generated by EF Core Power Tools. +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ASC.CRM.Core.EF +{ + [Table("crm_voip_number")] + public partial class CrmVoipNumber + { + [Key] + [Column("id", TypeName = "varchar(50)")] + public string Id { get; set; } + [Required] + [Column("number", TypeName = "varchar(50)")] + public string Number { get; set; } + [Column("alias", TypeName = "varchar(255)")] + public string Alias { get; set; } + [Column("settings", TypeName = "text")] + public string Settings { get; set; } + [Column("tenant_id", TypeName = "int(10)")] + public int TenantId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/IDbCrm.cs b/products/ASC.CRM/Server/Core/EF/IDbCrm.cs new file mode 100644 index 00000000000..0a0e9d354cb --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/IDbCrm.cs @@ -0,0 +1,12 @@ +namespace ASC.CRM.Core.EF +{ + public interface IDbCrm + { + public int TenantId { get; set; } + } + + public interface IDbSearch + { + public string Title { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/Cases.cs b/products/ASC.CRM/Server/Core/Entities/Cases.cs new file mode 100644 index 00000000000..9d5ed23945a --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Cases.cs @@ -0,0 +1,62 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using ASC.Common.Security; + +namespace ASC.CRM.Core.Entities +{ + public class Cases : DomainObject, ISecurityObjectId + { + public Guid CreateBy { get; set; } + + public DateTime CreateOn { get; set; } + + public Guid? LastModifedBy { get; set; } + + public DateTime? LastModifedOn { get; set; } + + public String Title { get; set; } + + public bool IsClosed { get; set; } + + public HashSet Members { get; set; } + + // TODO: to finish the field + public DateTime ClosedDate { get; set; } + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Comment.cs b/products/ASC.CRM/Server/Core/Entities/Comment.cs new file mode 100644 index 00000000000..b62375240f8 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Comment.cs @@ -0,0 +1,55 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + public class Comment + { + public Guid Parent { get; set; } + + public string Content { get; set; } + + public bool Inactive { get; set; } + + public String TargetUniqID { get; set; } + + public Guid CreateBy { get; set; } + + public DateTime CreateOn { get; set; } + + public override int GetHashCode() + { + return (GetType().FullName + "|" + Content + "|" + CreateBy.GetHashCode() + "|" + Parent.GetHashCode()).GetHashCode(); + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Contact.cs b/products/ASC.CRM/Server/Core/Entities/Contact.cs new file mode 100644 index 00000000000..88cb679fc79 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Contact.cs @@ -0,0 +1,143 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Security; +using ASC.CRM.Classes; +using ASC.CRM.Core.Enums; +using System; + +namespace ASC.CRM.Core.Entities +{ + [Serializable] + public class Person : Contact + { + public Person() + { + FirstName = String.Empty; + LastName = String.Empty; + CompanyID = 0; + JobTitle = String.Empty; + } + + public String FirstName { get; set; } + + public String LastName { get; set; } + + public int CompanyID { get; set; } + + public String JobTitle { get; set; } + } + + [Serializable] + public class Company : Contact + { + public Company() + { + CompanyName = String.Empty; + } + + public String CompanyName { get; set; } + } + + public static class ContactExtension + { + public static String GetTitle(this Contact contact) + { + if (contact == null) + return String.Empty; + + if (contact is Company) + { + var company = (Company)contact; + + return company.CompanyName; + } + + var people = (Person)contact; + + return String.Format("{0} {1}", people.FirstName, people.LastName); + } + + public static String RenderLinkForCard(this Contact contact) + { + var isCompany = contact is Company; + var popupID = Guid.NewGuid(); + + return !CRMSecurity.CanAccessTo(contact) ? + String.Format(@"{0}", GetTitle(contact).HtmlEncode()) : + String.Format(@" + {4} + ", + isCompany ? "crm-companyInfoCardLink" : "crm-peopleInfoCardLink", + UrlConstant.ID, contact != null ? contact.ID : 0, + isCompany ? String.Empty : String.Format("&{0}=people", UrlConstant.Type), + GetTitle(contact).HtmlEncode(), popupID); + } + } + + [Serializable] + public abstract class Contact : DomainObject, ISecurityObjectId + { + protected Contact() + { + About = String.Empty; + Industry = String.Empty; + StatusID = 0; + ContactTypeID = 0; + ShareType = ShareType.None; + } + + public Guid CreateBy { get; set; } + + public DateTime CreateOn { get; set; } + + public Guid? LastModifedBy { get; set; } + + public DateTime? LastModifedOn { get; set; } + + public String About { get; set; } + + public String Industry { get; set; } + + public int StatusID { get; set; } + + public int ContactTypeID { get; set; } + + public ShareType ShareType { get; set; } + + public string Currency { get; set; } + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs new file mode 100644 index 00000000000..1790cda1988 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs @@ -0,0 +1,92 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Classes; +using ASC.CRM.Core.Enums; +using System; +using System.Runtime.Serialization; + +namespace ASC.CRM.Core +{ + [DataContract] + public class ContactInfo : DomainObject + { + [DataMember(Name = "contactID")] + public int ContactID { get; set; } + + [DataMember(Name = "infoType")] + public ContactInfoType InfoType { get; set; } + + [DataMember(Name = "category")] + public int Category { get; set; } + + [DataMember(Name = "data")] + public String Data { get; set; } + + [DataMember(Name = "isPrimary")] + public bool IsPrimary { get; set; } + + + public static int GetDefaultCategory(ContactInfoType infoTypeEnum) + { + switch (infoTypeEnum) + { + case ContactInfoType.Phone: + return (int)PhoneCategory.Work; + case ContactInfoType.Address: + return (int)AddressCategory.Work; + default: + return (int)ContactInfoBaseCategory.Work; + } + } + + public String CategoryToString() + { + switch (InfoType) + { + case ContactInfoType.Phone: + return ((PhoneCategory)Category).ToLocalizedString(); + case ContactInfoType.Address: + return ((AddressCategory)Category).ToLocalizedString(); + default: + return ((ContactInfoBaseCategory)Category).ToLocalizedString(); + } + } + + public static Type GetCategory(ContactInfoType infoType) + { + switch (infoType) + { + case ContactInfoType.Phone: + return typeof(PhoneCategory); + case ContactInfoType.Address: + return typeof(AddressCategory); + default: + return typeof(ContactInfoBaseCategory); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs new file mode 100644 index 00000000000..f9b9afc4873 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -0,0 +1,95 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Resources; +using System; +using System.Runtime.Serialization; + +namespace ASC.CRM.Core +{ + [DataContract] + public class CurrencyInfo + { + private String _resourceKey; + + [DataMember(Name = "title")] + public String Title + { + get + { + + if (String.IsNullOrEmpty(_resourceKey)) + return String.Empty; + + return CRMCommonResource.ResourceManager.GetString(_resourceKey); + + } + } + + [DataMember(Name = "symbol")] + public string Symbol { get; set; } + + [DataMember(Name = "abbreviation")] + public string Abbreviation { get; set; } + + [DataMember(Name = "cultureName")] + public string CultureName { get; set; } + + [DataMember(Name = "isConvertable")] + public bool IsConvertable { get; set; } + + [DataMember(Name = "isBasic")] + public bool IsBasic { get; set; } + + + public CurrencyInfo(string resourceKey, string abbreviation, string symbol, string cultureName, bool isConvertable, bool isBasic) + { + _resourceKey = resourceKey; + Symbol = symbol; + Abbreviation = abbreviation; + CultureName = cultureName; + IsConvertable = isConvertable; + IsBasic = isBasic; + } + + public override bool Equals(object obj) + { + var ci = obj as CurrencyInfo; + return ci != null && string.Compare(Title, ci.Title, true) == 0; + } + + public override int GetHashCode() + { + return ToString().GetHashCode(); + } + + public override string ToString() + { + return string.Concat(Abbreviation, "-", Title); + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs new file mode 100644 index 00000000000..83ad8d09415 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs @@ -0,0 +1,52 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Runtime.Serialization; + +namespace ASC.CRM.Core +{ + [DataContract] + public class CurrencyRate : DomainObject + { + [DataMember(Name = "fromCurrency")] + public string FromCurrency { get; set; } + + [DataMember(Name = "toCurrency")] + public string ToCurrency { get; set; } + + [DataMember(Name = "rate")] + public decimal Rate { get; set; } + + public Guid CreateBy { get; set; } + + public DateTime CreateOn { get; set; } + + public Guid? LastModifedBy { get; set; } + + public DateTime? LastModifedOn { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/CustomField.cs b/products/ASC.CRM/Server/Core/Entities/CustomField.cs new file mode 100644 index 00000000000..e1b2619468b --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/CustomField.cs @@ -0,0 +1,70 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.CRM.Core.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + + [DataContract] + public class CustomField : DomainObject + { + [DataMember(Name = "entity_type")] + public EntityType EntityType { get; set; } + + [DataMember(Name = "entity_id")] + public int EntityID { get; set; } + + [DataMember(Name = "label")] + public String Label { get; set; } + + [DataMember(Name = "value")] + public String Value { get; set; } + + [DataMember(Name = "fieldType")] + public CustomFieldType FieldType { get; set; } + + [DataMember(Name = "position")] + public int Position { get; set; } + + [DataMember(Name = "mask")] + public String Mask { get; set; } + + public override int GetHashCode() + { + return string.Format("{0}|{1}|{2}", GetType().FullName, Label, (int)FieldType).GetHashCode(); + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs new file mode 100644 index 00000000000..c8fba077e59 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -0,0 +1,118 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Usings + +using System; +using System.Runtime.Serialization; +using ASC.Common.Security; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + [DataContract] + public class Deal : DomainObject, ISecurityObjectId + { + public Guid CreateBy { get; set; } + + public DateTime CreateOn { get; set; } + + public Guid? LastModifedBy { get; set; } + + public DateTime? LastModifedOn { get; set; } + + [DataMember(Name = "contact_id")] + public int ContactID { get; set; } + + [DataMember(Name = "contact")] + public Contact Contact { get; set; } + + [DataMember(Name = "title")] + public string Title { get; set; } + + [DataMember(Name = "description")] + public string Description { get; set; } + + [DataMember(Name = "responsible_id")] + public Guid ResponsibleID { get; set; } + + [DataMember(Name = "bid_type")] + public BidType BidType { get; set; } + + [DataMember(Name = "bid_value")] + public decimal BidValue { get; set; } + + [DataMember(Name = "bid_currency")] + public string BidCurrency { get; set; } + + [DataMember(Name = "per_period_value")] + public int PerPeriodValue { get; set; } + + [DataMember(Name = "deal_milestone")] + public int DealMilestoneID { get; set; } + + [DataMember(Name = "deal_milestone_probability")] + public int DealMilestoneProbability { get; set; } + + public DateTime ActualCloseDate { get; set; } + + [DataMember(Name = "actual_close_date")] + private String ActualCloseDateStr + { + get + { + return ActualCloseDate.Date == DateTime.MinValue.Date + ? string.Empty : ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern); + } + set { ; } + } + + + public DateTime ExpectedCloseDate { get; set; } + + [DataMember(Name = "expected_close_date")] + private String ExpectedCloseDateStr + { + get + { + return ExpectedCloseDate.Date == DateTime.MinValue.Date + ? string.Empty : ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern); + } + set { ; } + } + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs new file mode 100644 index 00000000000..d9e5b5bc3ca --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs @@ -0,0 +1,65 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using ASC.Common.Security; +using ASC.Common.Security.Authorizing; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + + [DataContract] + public class DealMilestone : DomainObject + { + [DataMember(Name = "title")] + public String Title { get; set; } + + [DataMember(Name = "description")] + public String Description { get; set; } + + [DataMember(Name = "color")] + public String Color { get; set; } + + [DataMember(Name = "sort_order")] + public int SortOrder { get; set; } + + [DataMember(Name = "probability")] + public int Probability { get; set; } + + [DataMember(Name = "status")] + public DealMilestoneStatus Status { get; set; } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Filter.cs b/products/ASC.CRM/Server/Core/Entities/Filter.cs new file mode 100644 index 00000000000..2c7e5f4f375 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Filter.cs @@ -0,0 +1,555 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Enums; +using ASC.Web.CRM.Classes; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using EnumExtension = ASC.CRM.Classes.EnumExtension; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + public abstract class FilterObject + { + public string SortBy { get; set; } + public string SortOrder { get; set; } + public string FilterValue { get; set; } + + public bool IsAsc + { + get + { + return !String.IsNullOrEmpty(SortOrder) && SortOrder != "descending"; + } + } + + public abstract ICollection GetItemsByFilter(DaoFactory daofactory); + } + + public class CasesFilterObject : FilterObject + { + public bool? IsClosed { get; set; } + public List Tags { get; set; } + + public CasesFilterObject() + { + SortBy = "title"; + SortOrder = "ascending"; + } + + public CasesFilterObject(string base64String) + { + if(string.IsNullOrEmpty(base64String)) return; + + var json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); + + var jsonArray = json.Split(';'); + + foreach (var filterItem in jsonArray) + { + var filterObj = JObject.Parse(filterItem); + + var paramString = filterObj.Value("params"); + + if (string.IsNullOrEmpty(paramString)) continue; + + var filterParam = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + + switch (filterObj.Value("id")) + { + case "sorter": + SortBy = filterParam.Value("id"); + SortOrder = filterParam.Value("sortOrder"); + break; + + case "text": + FilterValue = filterParam.Value("value"); + break; + + case "closed": + case "opened": + IsClosed = filterParam.Value("value"); + break; + + case "tags": + Tags = filterParam.Value("value").ToList().ConvertAll(n => n.ToString()); + break; + } + } + } + + public override ICollection GetItemsByFilter(DaoFactory daofactory) + { + SortedByType sortBy; + if (!EnumExtension.TryParse(SortBy, true, out sortBy)) + { + sortBy = SortedByType.Title; + } + + return daofactory.CasesDao.GetCases( + FilterValue, + 0, + IsClosed, + Tags, + 0, 0, + new OrderBy(sortBy, IsAsc)); + } + } + + public class TaskFilterObject : FilterObject + { + public int CategoryId { get; set; } + public int ContactId { get; set; } + public Guid ResponsibleId { get; set; } + public bool? IsClosed { get; set; } + public DateTime FromDate { get; set; } + public DateTime ToDate { get; set; } + + public TaskFilterObject() + { + IsClosed = null; + FromDate = DateTime.MinValue; + ToDate = DateTime.MinValue; + SortBy = "deadline"; + SortOrder = "ascending"; + } + + public TaskFilterObject(string base64String) + { + if (string.IsNullOrEmpty(base64String)) return; + + var json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); + + var jsonArray = json.Split(';'); + + foreach (var filterItem in jsonArray) + { + var filterObj = JObject.Parse(filterItem); + + var paramString = filterObj.Value("params"); + + if (string.IsNullOrEmpty(paramString)) continue; + + var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + + switch (filterObj.Value("id")) + { + case "sorter": + SortBy = filterParam.Value("id"); + SortOrder = filterParam.Value("sortOrder"); + break; + + case "text": + FilterValue = filterParam.Value("value"); + break; + + case "my": + case "responsibleID": + ResponsibleId = new Guid(filterParam.Value("value")); + break; + + case "overdue": + case "today": + case "theNext": + var valueString = filterParam.Value("value"); + var fromToArray = JsonConvert.DeserializeObject>(valueString); + if (fromToArray.Count != 2) continue; + FromDate = !String.IsNullOrEmpty(fromToArray[0]) + ? Global.ApiDateTimeParse(fromToArray[0]) : DateTime.MinValue; + ToDate = !String.IsNullOrEmpty(fromToArray[1]) + ? Global.ApiDateTimeParse(fromToArray[1]) : DateTime.MinValue; + break; + + case "fromToDate": + FromDate = filterParam.Value("from"); + ToDate = (filterParam.Value("to")).AddDays(1).AddSeconds(-1); + break; + + case "categoryID": + CategoryId = filterParam.Value("value"); + break; + + case "openTask": + case "closedTask": + IsClosed = filterParam.Value("value"); + break; + + case "contactID": + ContactId = filterParam.Value("id"); + break; + } + } + } + + public override ICollection GetItemsByFilter(DaoFactory daofactory) + { + TaskSortedByType sortBy; + if (!EnumExtension.TryParse(SortBy, true, out sortBy)) + { + sortBy = TaskSortedByType.DeadLine; + } + + return daofactory.TaskDao.GetTasks( + FilterValue, + ResponsibleId, + CategoryId, + IsClosed, + FromDate, + ToDate, + ContactId > 0 ? EntityType.Contact : EntityType.Any, + ContactId, + 0, 0, + new OrderBy(sortBy, IsAsc)); + } + } + + public class DealFilterObject : FilterObject + { + public Guid ResponsibleId { get; set; } + public String StageType { get; set; } + public int OpportunityStageId { get; set; } + public DateTime FromDate { get; set; } + public DateTime ToDate { get; set; } + public int ContactId { get; set; } + public bool? ContactAlsoIsParticipant { get; set; } + public List Tags { get; set; } + + public DealFilterObject() + { + ContactAlsoIsParticipant = null; + FromDate = DateTime.MinValue; + ToDate = DateTime.MinValue; + SortBy = "stage"; + SortOrder = "ascending"; + } + + public DealFilterObject(string base64String) + { + if (string.IsNullOrEmpty(base64String)) return; + + var json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); + + var jsonArray = json.Split(';'); + + foreach (var filterItem in jsonArray) + { + var filterObj = JObject.Parse(filterItem); + + var paramString = filterObj.Value("params"); + + if (string.IsNullOrEmpty(paramString)) continue; + + var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + + switch (filterObj.Value("id")) + { + case "sorter": + SortBy = filterParam.Value("id"); + SortOrder = filterParam.Value("sortOrder"); + break; + + case "text": + FilterValue = filterParam.Value("value"); + break; + + case "my": + case "responsibleID": + ResponsibleId = new Guid(filterParam.Value("value")); + break; + + case "stageTypeOpen": + case "stageTypeClosedAndWon": + case "stageTypeClosedAndLost": + StageType = filterParam.Value("value"); + break; + + case "opportunityStagesID": + OpportunityStageId = filterParam.Value("value"); + break; + + case "lastMonth": + case "yesterday": + case "today": + case "thisMonth": + var valueString = filterParam.Value("value"); + var fromToArray = JsonConvert.DeserializeObject>(valueString); + if (fromToArray.Count != 2) continue; + FromDate = Global.ApiDateTimeParse(fromToArray[0]); + ToDate = Global.ApiDateTimeParse(fromToArray[1]); + break; + + case "fromToDate": + FromDate = Global.ApiDateTimeParse(filterParam.Value("from")); + ToDate = Global.ApiDateTimeParse(filterParam.Value("to")); + break; + + case "participantID": + ContactId = filterParam.Value("id"); + ContactAlsoIsParticipant = true; + break; + + case "contactID": + ContactId = filterParam.Value("id"); + ContactAlsoIsParticipant = false; + break; + + case "tags": + Tags = filterParam.Value("value").ToList().ConvertAll(n => n.ToString()); + break; + } + } + + } + + public override ICollection GetItemsByFilter(DaoFactory daofactory) + { + DealSortedByType sortBy; + EnumExtension.TryParse(SortBy, true, out sortBy); + + DealMilestoneStatus? stageType = null; + DealMilestoneStatus stage; + if (EnumExtension.TryParse(StageType, true, out stage)) + { + stageType = stage; + } + + return daofactory.DealDao.GetDeals( + FilterValue, + ResponsibleId, + OpportunityStageId, + Tags, + ContactId, + stageType, + ContactAlsoIsParticipant, + FromDate, + ToDate, + 0, 0, + new OrderBy(sortBy, IsAsc)); + } + } + + public class ContactFilterObject : FilterObject + { + public List Tags { get; set; } + public string ContactListView { get; set; } + public int ContactStage { get; set; } + public int ContactType { get; set; } + public Guid? ResponsibleId { get; set; } + public bool? IsShared { get; set; } + public DateTime FromDate { get; set; } + public DateTime ToDate { get; set; } + + public ContactFilterObject() + { + FromDate = DateTime.MinValue; + ToDate = DateTime.MinValue; + ResponsibleId = null; + ContactStage = -1; + ContactType = -1; + SortBy = "created"; + SortOrder = "descending"; + } + + public ContactFilterObject(string base64String) + { + ContactStage = -1; + ContactType = -1; + + if (string.IsNullOrEmpty(base64String)) return; + + var json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); + + var jsonArray = json.Split(';'); + + foreach (var filterItem in jsonArray) + { + var filterObj = JObject.Parse(filterItem); + + var paramString = filterObj.Value("params"); + + if (string.IsNullOrEmpty(paramString)) continue; + + var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + + switch (filterObj.Value("id")) + { + case "sorter": + SortBy = filterParam.Value("id"); + SortOrder = filterParam.Value("sortOrder"); + break; + + case "text": + FilterValue = filterParam.Value("value"); + break; + + case "my": + case "responsibleID": + case "noresponsible": + ResponsibleId = new Guid(filterParam.Value("value")); + break; + + case "tags": + Tags = filterParam.Value("value").ToList().ConvertAll(n => n.ToString()); + break; + + case "withopportunity": + case "person": + case "company": + ContactListView = filterParam.Value("value"); + break; + + case "contactType": + ContactType = filterParam.Value("value"); + break; + + case "contactStage": + ContactStage = filterParam.Value("value"); + break; + + case "lastMonth": + case "yesterday": + case "today": + case "thisMonth": + var valueString = filterParam.Value("value"); + var fromToArray = JsonConvert.DeserializeObject>(valueString); + if (fromToArray.Count != 2) continue; + FromDate = Global.ApiDateTimeParse(fromToArray[0]); + ToDate = Global.ApiDateTimeParse(fromToArray[1]); + break; + + case "fromToDate": + FromDate = Global.ApiDateTimeParse(filterParam.Value("from")); + ToDate = Global.ApiDateTimeParse(filterParam.Value("to")); + break; + + case "restricted": + case "shared": + IsShared = filterParam.Value("value"); + break; + } + } + } + + public override ICollection GetItemsByFilter(DaoFactory daofactory) + { + ContactSortedByType sortBy; + if (!EnumExtension.TryParse(SortBy, true, out sortBy)) + { + sortBy = ContactSortedByType.Created; + } + + ContactListViewType contactListViewType; + EnumExtension.TryParse(ContactListView, true, out contactListViewType); + + return daofactory.ContactDao.GetContacts( + FilterValue, + Tags, + ContactStage, + ContactType, + contactListViewType, + FromDate, + ToDate, + 0, + 0, + new OrderBy(sortBy, IsAsc), + ResponsibleId, + IsShared); + } + }; + + public class InvoiceItemFilterObject : FilterObject + { + public bool? InventoryStock { get; set; } + + public InvoiceItemFilterObject() + { + InventoryStock = null; + SortBy = "name"; + SortOrder = "ascending"; + } + + public InvoiceItemFilterObject(string base64String) + { + if (string.IsNullOrEmpty(base64String)) return; + + var json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); + + var jsonArray = json.Split(';'); + + foreach (var filterItem in jsonArray) + { + var filterObj = JObject.Parse(filterItem); + + var paramString = filterObj.Value("params"); + + if(string.IsNullOrEmpty(paramString)) continue; + + var filterParam = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + + switch (filterObj.Value("id")) + { + case "sorter": + SortBy = filterParam.Value("id"); + SortOrder = filterParam.Value("sortOrder"); + break; + + case "text": + FilterValue = filterParam.Value("value"); + break; + + case "withInventoryStock": + case "withoutInventoryStock": + InventoryStock = filterParam.Value("value"); + break; + } + } + + } + + public override ICollection GetItemsByFilter(DaoFactory daofactory) + { + InvoiceItemSortedByType sortBy; + EnumExtension.TryParse(SortBy, true, out sortBy); + + return daofactory.InvoiceItemDao.GetInvoiceItems( + FilterValue, + 0, + InventoryStock, + 0, 0, + new OrderBy(sortBy, IsAsc)); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs new file mode 100644 index 00000000000..579b3160d10 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -0,0 +1,141 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Security; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Enums; +using System; +using System.Collections.Generic; + + +namespace ASC.CRM.Core.Entities +{ + public class Invoice : DomainObject, ISecurityObjectId + { + public InvoiceStatus Status { get; set; } + + public string Number { get; set; } + + public DateTime IssueDate { get; set; } + + public InvoiceTemplateType TemplateType { get; set; } + + public int ContactID { get; set; } + + public int ConsigneeID { get; set; } + + public EntityType EntityType { get; set; } + + public int EntityID { get; set; } + + public DateTime DueDate { get; set; } + + public string Language { get; set; } + + public string Currency { get; set; } + + public decimal ExchangeRate { get; set; } + + public string PurchaseOrderNumber { get; set; } + + public string Terms { get; set; } + + public string Description { get; set; } + + public string JsonData { get; set; } + + public int FileID { get; set; } + + + public DateTime CreateOn { get; set; } + + public Guid CreateBy { get; set; } + + public DateTime? LastModifedOn { get; set; } + + public Guid? LastModifedBy { get; set; } + + + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + + + public List GetInvoiceLines(DaoFactory daoFactory) + { + return daoFactory.InvoiceLineDao.GetInvoiceLines(ID); + } + + public File GetInvoiceFile(DaoFactory daoFactory) + { + return daoFactory.FileDao.GetFile(FileID, 0); + } + + public decimal GetInvoiceCost(DaoFactory daoFactory) + { + var lines = GetInvoiceLines(daoFactory); + decimal cost = 0; + foreach (var line in lines) + { + var linePrice = Math.Round(line.Price * line.Quantity, 2); + var lineDiscount = Math.Round(linePrice * line.Discount / 100, 2); + + linePrice = linePrice - lineDiscount; + + decimal lineTax1 = 0; + if (line.InvoiceTax1ID > 0) + { + var tax1 = daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax1ID); + if (tax1 != null) + { + lineTax1 = Math.Round(linePrice * tax1.Rate / 100, 2); + } + } + + decimal lineTax2 = 0; + if (line.InvoiceTax2ID > 0) + { + var tax2 = daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax2ID); + if (tax2 != null) + { + lineTax2 = Math.Round(linePrice * tax2.Rate / 100, 2); + } + } + + cost += linePrice + lineTax1 + lineTax2; + } + + return Math.Round(cost, 2); + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs new file mode 100644 index 00000000000..a5eacbb5196 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs @@ -0,0 +1,89 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Runtime.Serialization; +using ASC.Common.Security; + + +namespace ASC.CRM.Core.Entities +{ + [DataContract] + public class InvoiceItem : DomainObject, ISecurityObjectId + { + [DataMember(Name = "title")] + public string Title { get; set; } + + [DataMember(Name = "description")] + public string Description { get; set; } + + [DataMember(Name = "stockKeepingUnit")] + public string StockKeepingUnit { get; set; } + + [DataMember(Name = "price")] + public decimal Price { get; set; } + + [DataMember(Name = "stockQuantity")] + public decimal StockQuantity { get; set; } + + [DataMember(Name = "trackInventory")] + public bool TrackInventory { get; set; } + + [DataMember(Name = "invoiceTax1ID")] + public int InvoiceTax1ID { get; set; } + + [DataMember(Name = "invoiceTax2ID")] + public int InvoiceTax2ID { get; set; } + + [DataMember(Name = "currency")] + public string Currency { get; set; } + + + [DataMember(Name = "createOn")] + public DateTime CreateOn { get; set; } + + [DataMember(Name = "createBy")] + public Guid CreateBy { get; set; } + + [DataMember(Name = "lastModifedOn")] + public DateTime? LastModifedOn { get; set; } + + [DataMember(Name = "lastModifedBy")] + public Guid? LastModifedBy { get; set; } + + + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs new file mode 100644 index 00000000000..06b47c6372c --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs @@ -0,0 +1,52 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; + +namespace ASC.CRM.Core.Entities +{ + public class InvoiceLine : DomainObject + { + public int InvoiceID { get; set; } + + public int InvoiceItemID { get; set; } + + public int InvoiceTax1ID { get; set; } + + public int InvoiceTax2ID { get; set; } + + public int SortOrder { get; set; } + + public string Description { get; set; } + + public decimal Quantity { get; set; } + + public decimal Price { get; set; } + + public decimal Discount { get; set; } + } +} + diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs new file mode 100644 index 00000000000..982e3e7108b --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -0,0 +1,71 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Runtime.Serialization; +using ASC.Common.Security; + + +namespace ASC.CRM.Core.Entities +{ + [DataContract] + public class InvoiceTax : DomainObject, ISecurityObjectId + { + [DataMember(Name = "name")] + public string Name { get; set; } + + [DataMember(Name = "description")] + public string Description { get; set; } + + [DataMember(Name = "rate")] + public decimal Rate { get; set; } + + + [DataMember(Name = "createOn")] + public DateTime CreateOn { get; set; } + + [DataMember(Name = "createBy")] + public Guid CreateBy { get; set; } + + [DataMember(Name = "lastModifedOn")] + public DateTime? LastModifedOn { get; set; } + + [DataMember(Name = "lastModifedBy")] + public Guid? LastModifedBy { get; set; } + + + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/ListItem.cs b/products/ASC.CRM/Server/Core/Entities/ListItem.cs new file mode 100644 index 00000000000..302d1f0b06f --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/ListItem.cs @@ -0,0 +1,65 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core.Enums; +using System; +using System.Runtime.Serialization; + +namespace ASC.CRM.Core.Entities +{ + [DataContract] + public class ListItem : DomainObject + { + [DataMember(Name = "title")] + public string Title { get; set; } + + [DataMember(Name = "description")] + public string Description { get; set; } + + [DataMember(Name = "color")] + public string Color { get; set; } + + [DataMember(Name = "sort_order")] + public int SortOrder { get; set; } + + [DataMember(Name = "additional_params")] + public string AdditionalParams { get; set; } + + [DataMember(Name = "list_type")] + public ListType? ListType { get; set; } + + + public ListItem() + { + } + + public ListItem(string title, string addparams) + { + Title = title; + AdditionalParams = addparams; + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs b/products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs new file mode 100644 index 00000000000..6e11a339dbd --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs @@ -0,0 +1,44 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core.Enums; +using System; + +namespace ASC.CRM.Core.Entities +{ + public class ListItemHistory: DomainObject + { + public int EntityID { get; set; } + + public EntityType EntityType { get; set; } + + public int StatusID { get; set; } + + public DateTime ModifedOn { get; set; } + + public Guid ModifedBy { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/OrderBy.cs b/products/ASC.CRM/Server/Core/Entities/OrderBy.cs new file mode 100644 index 00000000000..c82ddfac6ef --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/OrderBy.cs @@ -0,0 +1,53 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; + +namespace ASC.CRM.Core.Entities +{ + public class OrderBy + { + + public bool IsAsc + { + get; + set; + } + + + public Enum SortedBy + { + get; + set; + } + + public OrderBy(Enum sortedByType, bool isAsc) + { + IsAsc = isAsc; + SortedBy = sortedByType; + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs new file mode 100644 index 00000000000..095856fc319 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs @@ -0,0 +1,82 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using ASC.Common.Security; +using ASC.Common.Security.Authorizing; +using ASC.Core.Users; +using ASC.CRM.Core.Enums; +#endregion + +namespace ASC.CRM.Core.Entities +{ + [DataContract] + public class RelationshipEvent : DomainObject, ISecurityObjectId + { + [DataMember(Name = "createBy")] + public Guid CreateBy { get; set; } + + [DataMember(Name = "createOn")] + public DateTime CreateOn { get; set; } + + [DataMember(Name = "lastModifedBy")] + public Guid? LastModifedBy { get; set; } + + [DataMember(Name = "lastModifedOn")] + public DateTime? LastModifedOn { get; set; } + + [DataMember(Name = "content")] + public String Content { get; set; } + + [DataMember(Name = "contactID")] + public int ContactID { get; set; } + + [DataMember(Name = "entityType")] + public EntityType EntityType { get; set; } + + [DataMember(Name = "entityID")] + public int EntityID { get; set; } + + [DataMember(Name = "categoryID")] + public int CategoryID { get; set; } + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Report.cs b/products/ASC.CRM/Server/Core/Entities/Report.cs new file mode 100644 index 00000000000..260a6a3c419 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Report.cs @@ -0,0 +1,109 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using ASC.CRM.Core.Enums; +using ASC.VoipService; +using ASC.Web.Core.Files; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + public class SalesByManager + { + public Guid UserId { get; set; } + public string UserName { get; set; } + public decimal Value { get; set; } + public DateTime Date { get; set; } + } + + public class SalesForecast + { + public decimal Value { get; set; } + public decimal ValueWithProbability { get; set; } + public DateTime Date { get; set; } + } + + public class SalesFunnel + { + public DealMilestoneStatus Status { get; set; } + public string Title { get; set; } + public int Count { get; set; } + public decimal Value { get; set; } + public int Duration { get; set; } + } + + public class WorkloadByDeals + { + public Guid UserId { get; set; } + public string UserName { get; set; } + public DealMilestoneStatus Status { get; set; } + public int Count { get; set; } + public decimal Value { get; set; } + } + + public class WorkloadByTasks + { + public int CategoryId { get; set; } + public string CategoryName { get; set; } + public Guid UserId { get; set; } + public string UserName { get; set; } + public int Count { get; set; } + } + + public class WorkloadByInvoices + { + public Guid UserId { get; set; } + public string UserName { get; set; } + public int SentCount { get; set; } + public int PaidCount { get; set; } + public int RejectedCount { get; set; } + public int OverdueCount { get; set; } + } + + public class WorkloadByViop + { + public Guid UserId { get; set; } + public string UserName { get; set; } + public VoipCallStatus Status { get; set; } + public int Count { get; set; } + public int Duration { get; set; } + } + + public class WorkloadByContacts + { + public int CategoryId { get; set; } + public string CategoryName { get; set; } + public Guid UserId { get; set; } + public string UserName { get; set; } + public int Count { get; set; } + public int WithDeals { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Task.cs b/products/ASC.CRM/Server/Core/Entities/Task.cs new file mode 100644 index 00000000000..b91a42b4c06 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/Task.cs @@ -0,0 +1,80 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Usings + +using System; +using ASC.Common.Security; +using ASC.CRM.Core.Enums; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + public class Task : DomainObject, ISecurityObjectId + { + + public Guid CreateBy { get; set; } + + public DateTime CreateOn { get; set; } + + public Guid? LastModifedBy { get; set; } + + public DateTime? LastModifedOn { get; set; } + + public int ContactID { get; set; } + + public Contact Contact { get; set; } + + public string Title { get; set; } + + public string Description { get; set; } + + public DateTime DeadLine { get; set; } + + public Guid ResponsibleID { get; set; } + + public bool IsClosed { get; set; } + + public int CategoryID { get; set; } + + public EntityType EntityType { get; set; } + + public int EntityID { get; set; } + + public int AlertValue { get; set; } + + public object SecurityId + { + get { return ID; } + } + + public Type ObjectType + { + get { return GetType(); } + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs new file mode 100644 index 00000000000..4eb845e4f90 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs @@ -0,0 +1,73 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using ASC.Common.Security; +using ASC.CRM.Core.Enums; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + public class TaskTemplateContainer : DomainObject + { + + public String Title { get; set; } + + public EntityType EntityType { get; set; } + + } + + public class TaskTemplate : DomainObject + { + public int ContainerID { get; set; } + + public String Title { get; set; } + + public String Description { get; set; } + + public Guid ResponsibleID { get; set; } + + public int CategoryID { get; set; } + + public bool isNotify { get; set; } + + public TimeSpan Offset { get; set; } + + public bool DeadLineIsFixed { get; set; } + + public Guid CreateBy { get; set; } + + public DateTime CreateOn { get; set; } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/BidTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/BidTypeEnum.cs new file mode 100644 index 00000000000..3a2c9a8ff3f --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/BidTypeEnum.cs @@ -0,0 +1,39 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.CRM.Core.Enums +{ + public enum BidType + { + FixedBid = 0, + PerHour = 1, + PerDay = 2, + PerWeek = 3, + PerMonth = 4, + PerYear = 5 + + } +} diff --git a/products/ASC.CRM/Server/Core/Enums/CommunicationTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/CommunicationTypeEnum.cs new file mode 100644 index 00000000000..321dd5d35f0 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/CommunicationTypeEnum.cs @@ -0,0 +1,37 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.CRM.Core.Enums +{ + public enum CommunicationType + { + + Email = 0, + Telephone = 1, + Meeting = 2 + + } +} diff --git a/products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs b/products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs new file mode 100644 index 00000000000..c4ca6ed4669 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs @@ -0,0 +1,71 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.ComponentModel; +using ASC.CRM.Classes; + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof (LocalizedEnumConverter))] + public enum ContactInfoBaseCategory + { + Home, + Work, + Other + } + + [TypeConverter(typeof (LocalizedEnumConverter))] + public enum PhoneCategory + { + Home, + Work, + Mobile, + Fax, + Direct, + Other + } + + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum AddressPart + { + Street, + City, + State, + Zip, + Country + } + + [TypeConverter(typeof (LocalizedEnumConverter))] + public enum AddressCategory + { + Home, + Postal, + Office, + Billing, + Other, + Work + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs new file mode 100644 index 00000000000..9209c132da5 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs @@ -0,0 +1,55 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.ComponentModel; +using ASC.CRM.Classes; + + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum ContactInfoType + { + Phone, + Email, + Website, + Skype, + Twitter, + LinkedIn, + Facebook, + Address, + LiveJournal, + MySpace, + GMail, + Blogger, + Yahoo, + MSN, + ICQ, + Jabber, + AIM, + VK + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs new file mode 100644 index 00000000000..9f286de083d --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs @@ -0,0 +1,48 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.ComponentModel; +using ASC.CRM.Classes; + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum ContactListViewType + { + All, + Company, + Person, + WithOpportunity + } + +} + + + + + + + diff --git a/products/ASC.CRM/Server/Core/Enums/ContactSelectorTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ContactSelectorTypeEnum.cs new file mode 100644 index 00000000000..cb065ae7d1e --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ContactSelectorTypeEnum.cs @@ -0,0 +1,43 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +namespace ASC.CRM.Core.Enums +{ + public enum ContactSelectorTypeEnum + { + All = -1, + Companies = 0, + Persons = 1, + PersonsWithoutCompany = 2, + CompaniesAndPersonsWithoutCompany = 3 + } +} + + + + + + + diff --git a/products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs new file mode 100644 index 00000000000..d927471818c --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs @@ -0,0 +1,42 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.ComponentModel; +using ASC.CRM.Classes; + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum CustomFieldType + { + TextField = 0, + TextArea = 1, + SelectBox = 2, + CheckBox = 3, + Heading = 4, + Date = 5 + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs b/products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs new file mode 100644 index 00000000000..f1190315489 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs @@ -0,0 +1,44 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.CRM.Classes; +using System.ComponentModel; + +#endregion + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum DealMilestoneStatus + { + Open = 0, + ClosedAndWon = 1, + ClosedAndLost = 2 + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs new file mode 100644 index 00000000000..5c5942e27e0 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs @@ -0,0 +1,46 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Classes; +using System.ComponentModel; + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum EntityType + { + Any = -1, + Contact = 0, + Opportunity = 1, + RelationshipEvent = 2, + Task = 3, + Company = 4, + Person = 5, + File = 6, + Case = 7, + Invoice = 8 + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs b/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs new file mode 100644 index 00000000000..cdcc18a234a --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs @@ -0,0 +1,41 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Classes; +using System.ComponentModel; + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum InvoiceStatus + { + Draft = 1, + Sent = 2, + Rejected = 3, + Paid = 4, + Archived = 5 + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs new file mode 100644 index 00000000000..70170ea78a0 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs @@ -0,0 +1,45 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.ComponentModel; +using ASC.CRM.Classes; + +namespace ASC.CRM.Core.Enums +{ + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum InvoiceTemplateType + { + Eur = 0, + Rus = 1 + } + + public enum InvoiceActionType + { + Create, + Edit, + Duplicate + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs new file mode 100644 index 00000000000..3c6ee1b6748 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs @@ -0,0 +1,52 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.CRM.Classes; +using System.ComponentModel; + +#endregion + +namespace ASC.CRM.Core.Enums +{ + public enum ListType + { + ContactStatus = 1, + TaskCategory = 2, + HistoryCategory = 3, + ContactType = 4 + } + + [TypeConverter(typeof(LocalizedEnumConverter))] + public enum HistoryCategorySystem + { + TaskClosed = -1, + FilesUpload = -2, + MailMessage = -3 + } + +} diff --git a/products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs b/products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs new file mode 100644 index 00000000000..9c31f8297ea --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs @@ -0,0 +1,36 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.CRM.Core.Enums +{ + public enum ProgressStatus + { + Queued, + Started, + Done, + Failed + } +} diff --git a/products/ASC.CRM/Server/Core/Enums/ReportTimePeriodEnum.cs b/products/ASC.CRM/Server/Core/Enums/ReportTimePeriodEnum.cs new file mode 100644 index 00000000000..15946bf56ed --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ReportTimePeriodEnum.cs @@ -0,0 +1,53 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.CRM.Core.Enums +{ + public enum ReportTimePeriod + { + Today, + Yesterday, + Tomorrow, + + CurrentWeek, + PreviousWeek, + NextWeek, + + CurrentMonth, + PreviousMonth, + NextMonth, + + CurrentQuarter, + PreviousQuarter, + NextQuarter, + + CurrentYear, + PreviousYear, + NextYear, + + DuringAllTime + } +} diff --git a/products/ASC.CRM/Server/Core/Enums/ReportTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ReportTypeEnum.cs new file mode 100644 index 00000000000..8294e51b598 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ReportTypeEnum.cs @@ -0,0 +1,42 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.CRM.Core.Enums +{ + public enum ReportType + { + SalesByManagers, + SalesForecast, + SalesFunnel, + WorkloadByContacts, + WorkloadByTasks, + WorkloadByDeals, + WorkloadByInvoices, + WorkloadByVoip, + SummaryForThePeriod, + SummaryAtThisMoment + } +} diff --git a/products/ASC.CRM/Server/Core/Enums/ShareType.cs b/products/ASC.CRM/Server/Core/Enums/ShareType.cs new file mode 100644 index 00000000000..2b6bb9fcb61 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/ShareType.cs @@ -0,0 +1,43 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.Runtime.Serialization; + +namespace ASC.CRM.Core.Enums +{ + [DataContract(Name = "contactShare", Namespace = "")] + public enum ShareType + { + [EnumMember(Value = "0")] + None, + + [EnumMember(Value = "1")] + ReadWrite, + + [EnumMember(Value = "2")] + Read + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs new file mode 100644 index 00000000000..578c59d0c1a --- /dev/null +++ b/products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs @@ -0,0 +1,91 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.CRM.Core.Enums +{ + + public enum TaskSortedByType + { + Title, + Category, + DeadLine, + Contact, + ContactManager + } + + public enum DealSortedByType + { + Title, + Responsible, + Stage, + BidValue, + DateAndTime + } + + public enum RelationshipEventByType + { + Created, + CreateBy, + Category, + Content + } + + public enum ContactSortedByType + { + DisplayName, + ContactType, + Created, + FirstName, + LastName, + History + } + + public enum SortedByType + { + DateAndTime, + Title, + CreateBy + } + + public enum InvoiceSortedByType + { + Number, + IssueDate, + Contact, + DueDate, + Status + } + + public enum InvoiceItemSortedByType + { + Name, + Price, + Quantity, + SKU, + Created + } + +} diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs new file mode 100644 index 00000000000..cb7c74dd37f --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -0,0 +1,160 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.Collections.Generic; +using System.Linq; +using ASC.CRM.Core; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public class BundleSearch + { + public static bool Support(EntityType entityType) + { + switch (entityType) + { + case EntityType.Person: + case EntityType.Contact: + case EntityType.Company: + return FactoryIndexer.Support && + FactoryIndexer.Support && + FactoryIndexer.Support && + FactoryIndexer.Support; + case EntityType.Opportunity: + return FactoryIndexer.Support && + FactoryIndexer.Support && + FactoryIndexer.Support; + case EntityType.RelationshipEvent: + return FactoryIndexer.Support; + case EntityType.Task: + return FactoryIndexer.Support; + case EntityType.Case: + return FactoryIndexer.Support && + FactoryIndexer.Support && + FactoryIndexer.Support; + case EntityType.Invoice: + return FactoryIndexer.Support; + } + + return false; + } + + public static bool TrySelectCase(string text, out List result) + { + var success = false; + result = new List(); + + List casesId; + if (FactoryIndexer.TrySelectIds(s => s.MatchAll(text), out casesId)) + { + result.AddRange(casesId); + success = true; + } + + IReadOnlyCollection casesCustom; + if (FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7), out casesCustom)) + { + result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); + success = true; + } + + IReadOnlyCollection events; + if (!FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) + { + result.AddRange(events.Select(r => r.EntityId).ToList()); + success = true; + } + + return success; + } + + public static bool TrySelectContact(string text, out List result) + { + var success = false; + result = new List(); + + List contactsId; + if (FactoryIndexer.TrySelectIds(s => s.MatchAll(text), out contactsId)) + { + result.AddRange(contactsId); + success = true; + } + + IReadOnlyCollection infos; + if (FactoryIndexer.TrySelect(s => s.MatchAll(text), out infos)) + { + result.AddRange(infos.Select(r => r.ContactId).ToList()); + success = true; + } + + IReadOnlyCollection personCustom; + if (FactoryIndexer.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] {0, 4, 5}), out personCustom)) + { + result.AddRange(personCustom.Select(r => r.EntityId).ToList()); + success = true; + } + + IReadOnlyCollection events; + if (FactoryIndexer.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events)) + { + result.AddRange(events.Select(r => r.ContactId).ToList()); + success = true; + } + + return success; + } + + public static bool TrySelectOpportunity(string text, out List result) + { + var success = false; + result = new List(); + + List dealsId; + if (FactoryIndexer.TrySelectIds(s => s.MatchAll(text), out dealsId)) + { + result.AddRange(dealsId); + success = true; + } + + IReadOnlyCollection casesCustom; + if (FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1), out casesCustom)) + { + result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); + success = true; + } + + IReadOnlyCollection events; + if (!FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1).Gt(r => r.EntityId, 0), out events)) + { + result.AddRange(events.Select(r => r.EntityId).ToList()); + success = true; + } + + return success; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs new file mode 100644 index 00000000000..81b8c232448 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs @@ -0,0 +1,53 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Core; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public sealed class CasesWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [Column("title", 1)] + public string Title { get; set; } + + protected override string Table { get { return "crm_case"; } } + + public static implicit operator CasesWrapper(ASC.CRM.Core.Entities.Cases d) + { + return new CasesWrapper + { + Id = d.ID, + Title = d.Title, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs new file mode 100644 index 00000000000..a10a52787cd --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs @@ -0,0 +1,95 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Core; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public class ContactsWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [Column("title", 1)] + public string Title { get; set; } + + [Column("first_name", 2)] + public string FirstName { get; set; } + + [Column("last_name", 3)] + public string LastName { get; set; } + + [Column("company_name", 4)] + public string CompanyName { get; set; } + + [Column("notes", 5)] + public string Notes { get; set; } + + [Column("industry", 6)] + public string Industry { get; set; } + + protected override string Table { get { return "crm_contact"; } } + + public static implicit operator ContactsWrapper(Contact d) + { + var person = d as Person; + if (person != null) + { + return person; + } + return d as Company; + } + + public static implicit operator ContactsWrapper(Person d) + { + return new ContactsWrapper + { + Id = d.ID, + Title = d.JobTitle, + FirstName = d.FirstName, + LastName = d.LastName, + Industry = d.Industry, + Notes = d.About, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + + public static implicit operator ContactsWrapper(Company d) + { + return new ContactsWrapper + { + Id = d.ID, + CompanyName = d.CompanyName, + Industry = d.Industry, + Notes = d.About, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs b/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs new file mode 100644 index 00000000000..9665c1c67da --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs @@ -0,0 +1,58 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Core; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public sealed class DealsWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [Column("title", 1)] + public string Title { get; set; } + + [Column("description", 2)] + public string Description { get; set; } + + protected override string Table { get { return "crm_deal"; } } + + public static implicit operator DealsWrapper(Deal deal) + { + return new DealsWrapper + { + Id = deal.ID, + Title = deal.Title, + Description = deal.Description, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs b/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs new file mode 100644 index 00000000000..5bfb737a8a7 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs @@ -0,0 +1,115 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public class EmailWrapper : ContactsWrapper + { + [Join(JoinTypeEnum.Sub, "id:contact_id", "tenant_id:tenant_id")] + public List EmailInfoWrapper { get; set; } + + protected override string IndexName + { + get + { + return "crm_contact_email"; + } + } + + public static EmailWrapper ToEmailWrapper(Contact contact, List contactInfo) + { + var result = new EmailWrapper(); + + var person = contact as Person; + if (person != null) + { + result = new EmailWrapper + { + Id = person.ID, + Title = person.JobTitle, + FirstName = person.FirstName, + LastName = person.LastName, + Industry = person.Industry, + Notes = person.About, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + var company = contact as Company; + if (company != null) + { + result = new EmailWrapper + { + Id = company.ID, + CompanyName = company.CompanyName, + Industry = company.Industry, + Notes = company.About, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + + result.EmailInfoWrapper = contactInfo.Select(r => (EmailInfoWrapper)r).ToList(); + + return result; + } + } + + public class EmailInfoWrapper: Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [ColumnCondition("contact_id", 1)] + public int ContactId { get; set; } + + [Column("data", 2, Analyzer = Analyzer.uax_url_email)] + public string Data { get; set; } + + [ColumnCondition("type", 3, 1)] + public int Type { get; set; } + + protected override string Table { get { return "crm_contact_info"; } } + + public static implicit operator EmailInfoWrapper(ContactInfo cf) + { + return new EmailInfoWrapper + { + Id = cf.ID, + ContactId = cf.ContactID, + Data = cf.Data, + Type = (int)cf.InfoType, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs b/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs new file mode 100644 index 00000000000..7783c4039d6 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs @@ -0,0 +1,66 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Core; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public sealed class EventsWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [ColumnCondition("contact_id", 1)] + public int ContactId { get; set; } + + [ColumnCondition("entity_id", 2)] + public int EntityId { get; set; } + + [ColumnCondition("entity_type", 2)] + public int EntityType { get; set; } + + [Column("content", 3, charFilter: CharFilter.html)] + public string Content { get; set; } + + protected override string Table { get { return "crm_relationship_event"; } } + + public static implicit operator EventsWrapper(RelationshipEvent relationshipEvent) + { + return new EventsWrapper + { + Id = relationshipEvent.ID, + ContactId = relationshipEvent.ContactID, + EntityId = relationshipEvent.EntityID, + EntityType = (int)relationshipEvent.EntityType, + Content = relationshipEvent.Content, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs b/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs new file mode 100644 index 00000000000..38ff55187ab --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs @@ -0,0 +1,64 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Core; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public sealed class FieldsWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [ColumnCondition("field_id", 1)] + public int FieldId { get; set; } + + [ColumnCondition("entity_id", 2)] + public int EntityId { get; set; } + + [ColumnCondition("entity_type", 3)] + public int EntityType { get; set; } + + [Column("value", 4)] + public string Value { get; set; } + + protected override string Table { get { return "crm_field_value"; } } + + public static implicit operator FieldsWrapper(ASC.CRM.Core.Entities.CustomField cf) + { + return new FieldsWrapper + { + Id = cf.ID, + EntityId = cf.EntityID, + EntityType = (int)cf.EntityType, + Value = cf.Value, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs new file mode 100644 index 00000000000..74c85419f15 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs @@ -0,0 +1,101 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Text; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core; +using ASC.ElasticSearch; +using Newtonsoft.Json.Linq; + +namespace ASC.Web.CRM.Core.Search +{ + public class InfoWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [ColumnCondition("contact_id", 1)] + public int ContactId { get; set; } + + [ColumnMeta("type", 2)] + public int Type { get; set; } + + [Column("data", 3)] + public string Data + { + get + { + if (Type == (int)ContactInfoType.Address && !string.IsNullOrEmpty(data)) + { + try + { + var result = new StringBuilder(); + var obj = JObject.Parse(data); + foreach (var o in obj.Values()) + { + var val = o.ToString(); + if(!string.IsNullOrEmpty(val)) + { + result.AppendFormat("{0} ", val); + } + } + return result.ToString().TrimEnd(); + } + catch (Exception e) + { + LogManager.GetLogger("ASC").Error("Index Contact Adrress Parse", e); + } + + return ""; + } + + return data; + } + set + { + data = value; + } + } + + protected override string Table { get { return "crm_contact_info"; } } + + private string data; + + public static implicit operator InfoWrapper(ContactInfo cf) + { + return new InfoWrapper + { + Id = cf.ID, + ContactId = cf.ContactID, + Data = cf.Data, + Type = (int)cf.InfoType, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs b/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs new file mode 100644 index 00000000000..e151316682e --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs @@ -0,0 +1,65 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Core; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public sealed class InvoicesWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [Column("number", 1)] + public string Number { get; set; } + + [Column("terms", 2)] + public string Terms { get; set; } + + [Column("description", 3)] + public string Description { get; set; } + + [Column("purchase_order_number", 4)] + public string PurchaseOrderNumber { get; set; } + + protected override string Table { get { return "crm_invoice"; } } + + public static implicit operator InvoicesWrapper(ASC.CRM.Core.Entities.Invoice invoice) + { + return new InvoicesWrapper + { + Id = invoice.ID, + Number = invoice.Number, + Terms = invoice.Terms, + Description = invoice.Description, + PurchaseOrderNumber = invoice.PurchaseOrderNumber, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs b/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs new file mode 100644 index 00000000000..7fdb9b55148 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs @@ -0,0 +1,58 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Core; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; + +namespace ASC.Web.CRM.Core.Search +{ + public sealed class TasksWrapper : Wrapper + { + [ColumnLastModified("last_modifed_on")] + public override DateTime LastModifiedOn { get; set; } + + [Column("title", 1)] + public string Title { get; set; } + + [Column("description", 2)] + public string Description { get; set; } + + protected override string Table { get { return "crm_task"; } } + + public static implicit operator TasksWrapper(Task task) + { + return new TasksWrapper + { + Id = task.ID, + Title = task.Title, + Description = task.Description, + TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs new file mode 100644 index 00000000000..3b8a31294bd --- /dev/null +++ b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs @@ -0,0 +1,124 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Common.Security; +using ASC.Common.Security.Authorizing; +using ASC.Core; +using Action = ASC.Common.Security.Authorizing.Action; +using ASC.CRM.Core.Enums; +#endregion + +namespace ASC.CRM.Core +{ + public class CRMSecurityObjectProvider : ISecurityObjectProvider + { + public ISecurityObjectId InheritFrom(ISecurityObjectId objectId) + { + int contactId; + int entityId; + EntityType entityType; + + if (objectId is Task) + { + var task = (Task)objectId; + + contactId = task.ContactID; + entityId = task.EntityID; + entityType = task.EntityType; + } + else if (objectId is RelationshipEvent) + { + var eventObj = (RelationshipEvent)objectId; + + contactId = eventObj.ContactID; + entityId = eventObj.EntityID; + entityType = eventObj.EntityType; + + } + else + { + return null; + } + + if (entityId == 0 && contactId == 0) return null; + + if (entityId == 0) + return new Company + { + ID = contactId, + CompanyName = "fakeCompany" + }; + + // return _daoFactory.ContactDao.GetByID(contactId); + + switch (entityType) + { + + case EntityType.Opportunity: + return new Deal + { + ID = entityId, + Title = "fakeDeal" + }; + // return _daoFactory.DealDao.GetByID(entityId); + case EntityType.Case: + return new Cases + { + ID = entityId, + Title = "fakeCases" + }; + // return _daoFactory.CasesDao.GetByID(entityId); + } + + return null; + } + + public bool InheritSupported + { + get { return true; } + } + + public bool ObjectRolesSupported + { + get { return false; } + } + + public IEnumerable GetObjectRoles(ISubject account, ISecurityObjectId objectId, SecurityCallContext callContext) + { + + // Constants.Everyone + // if (_daoFactory.GetManagerDao().GetAll(false).Contains(ASC.Core.CoreContext.UserManager.GetUsers(account.ID))) + // return new Action[] + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs new file mode 100644 index 00000000000..38a93624a28 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -0,0 +1,938 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Security; +using ASC.Common.Security.Authorizing; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.Core; +using ASC.Web.Core.Users; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Core; +using Autofac; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; +using Action = ASC.Common.Security.Authorizing.Action; +using Constants = ASC.Core.Users.Constants; +using SecurityContext = ASC.Core.SecurityContext; + +namespace ASC.CRM.Core +{ + public class CRMSecurity + { + #region Members + + public readonly IAction _actionRead = new Action(new Guid("{6F05C382-8BCA-4469-9424-C807A98C40D7}"), "", true, false); + + #endregion + + #region Constructor + public CRMSecurity(SecurityContext securityContext, + AuthorizationManager authorizationManager, + UserManager userManager, + DisplayUserSettingsHelper displayUserSettingsHelper, + DaoFactory daoFactory) + { + SecurityContext = securityContext; + AuthorizationManager = authorizationManager; + UserManager = userManager; + DisplayUserSettingsHelper = displayUserSettingsHelper; + DaoFactory = daoFactory; + } + + #endregion + + #region Property + + public DaoFactory DaoFactory { get; } + + public SecurityContext SecurityContext { get; } + + public AuthorizationManager AuthorizationManager { get; } + + public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } + + public UserManager UserManager { get; } + #endregion + + #region Check Permissions + + private ISecurityObjectProvider GetCRMSecurityProvider() + { + return new CRMSecurityObjectProvider(); + } + + public bool IsPrivate(ISecurityObjectId entity) + { + return GetAccessSubjectTo(entity).Any(); + } + + public bool CanAccessTo(ISecurityObjectId entity) + { + return CanAccessTo(entity, SecurityContext.CurrentAccount.ID); + } + + public bool CanAccessTo(ISecurityObjectId entity, Guid userId) + { + return IsAdministrator(userId) || SecurityContext.CheckPermissions(entity, GetCRMSecurityProvider(), _actionRead); + } + + public void MakePublic(ISecurityObjectId entity) + { + SetAccessTo(entity, new List()); + } + + public IEnumerable GetPrivateItems(Type objectType) + { + if (IsAdmin) return new List(); + + return GetPrivateItems(objectType, Guid.Empty, true); + + } + + private IEnumerable GetPrivateItems(Type objectType, Guid userId, bool withoutUser) + { + var query = AuthorizationManager + .GetAces(userId, _actionRead.ID) + .Where( + item => + !String.IsNullOrEmpty(item.ObjectId) && + item.ObjectId.StartsWith(objectType.FullName)) + .GroupBy(item => item.ObjectId, item => item.SubjectId); + + if (withoutUser) + { + if (userId != Guid.Empty) + query = query.Where(item => !item.Contains(userId)); + else + query = query.Where(item => !item.Contains(SecurityContext.CurrentAccount.ID)); + + } + + return query.Select(item => Convert.ToInt32(item.Key.Split(new[] { '|' })[1])); + } + + public IEnumerable GetContactsIdByManager(Guid userId) + { + return GetPrivateItems(typeof(Company), userId, false) + .Union(GetPrivateItems(typeof(Person), userId, false)); + } + + public int GetPrivateItemsCount(Type objectType) + { + if (IsAdmin) return 0; + + return GetPrivateItems(objectType).Count(); + } + + private Dictionary GetAccessSubjectTo(ISecurityObjectId entity, EmployeeStatus employeeStatus) + { + var allAces = AuthorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, + GetCRMSecurityProvider()) + .Where(item => item.SubjectId != Constants.GroupEveryone.ID); + + var result = new Dictionary(); + + foreach (var azRecord in allAces) + { + if (!result.ContainsKey(azRecord.SubjectId)) + { + var userInfo = UserManager.GetUsers(azRecord.SubjectId); + var displayName = employeeStatus == EmployeeStatus.All || userInfo.Status == employeeStatus + ? userInfo.DisplayUserName(DisplayUserSettingsHelper) + : Constants.LostUser.DisplayUserName(DisplayUserSettingsHelper); + result.Add(azRecord.SubjectId, displayName); + } + } + return result; + } + + public Dictionary GetAccessSubjectTo(ISecurityObjectId entity) + { + return GetAccessSubjectTo(entity, EmployeeStatus.All); + } + + public List GetAccessSubjectGuidsTo(ISecurityObjectId entity) + { + var allAces = AuthorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, + GetCRMSecurityProvider()) + .Where(item => item.SubjectId != Constants.GroupEveryone.ID); + + var result = new List(); + + foreach (var azRecord in allAces) + { + if (!result.Contains(azRecord.SubjectId)) + result.Add(azRecord.SubjectId); + } + return result; + } + + public void SetAccessTo(ISecurityObjectId entity, List subjectID) + { + + if (subjectID.Count == 0) + { + AuthorizationManager.RemoveAllAces(entity); + return; + } + + var aces = AuthorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, GetCRMSecurityProvider()); + foreach (var r in aces) + { + if (!subjectID.Contains(r.SubjectId) && (r.SubjectId != Constants.GroupEveryone.ID || r.Reaction != AceType.Allow)) + { + AuthorizationManager.RemoveAce(r); + } + } + + var oldSubjects = aces.Select(r => r.SubjectId).ToList(); + + foreach (var s in subjectID) + { + if (!oldSubjects.Contains(s)) + { + AuthorizationManager.AddAce(new AzRecord(s, _actionRead.ID, AceType.Allow, entity)); + } + } + + AuthorizationManager.AddAce(new AzRecord(Constants.GroupEveryone.ID, _actionRead.ID, AceType.Deny, entity)); + } + + #endregion + + #region SetAccessTo + + public void SetAccessTo(File file) + { + if (IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID) + file.Access = FileShare.None; + else + file.Access = FileShare.Read; + } + + public void SetAccessTo(Deal deal, List subjectID) + { + if (IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) + { + SetAccessTo((ISecurityObjectId)deal, subjectID); + } + } + + public void SetAccessTo(Cases cases, List subjectID) + { + if (IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) + { + SetAccessTo((ISecurityObjectId)cases, subjectID); + } + } + + #endregion + + #region CanAccessTo + + + public bool CanAccessTo(RelationshipEvent relationshipEvent) + { + return CanAccessTo(relationshipEvent, SecurityContext.CurrentAccount.ID); + } + + public bool CanAccessTo(RelationshipEvent relationshipEvent, Guid userId) + { + if (IsAdministrator(userId)) + return true; + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + + if (relationshipEvent.ContactID > 0) + { + var contactObj = daoFactory.ContactDao.GetByID(relationshipEvent.ContactID); + if (contactObj != null) return CanAccessTo(contactObj, userId); + } + + if (relationshipEvent.EntityType == EntityType.Case) + { + var caseObj = daoFactory.CasesDao.GetByID(relationshipEvent.EntityID); + if (caseObj != null) return CanAccessTo(caseObj, userId); + } + + if (relationshipEvent.EntityType == EntityType.Opportunity) + { + var dealObj = daoFactory.DealDao.GetByID(relationshipEvent.EntityID); + if (dealObj != null) return CanAccessTo(dealObj, userId); + } + + return false; + } + } + + public bool CanAccessTo(Contact contact) + { + return CanAccessTo(contact, SecurityContext.CurrentAccount.ID); + } + + public bool CanAccessTo(Contact contact, Guid userId) + { + return contact.ShareType == ShareType.Read || + contact.ShareType == ShareType.ReadWrite || + IsAdministrator(userId) || + GetAccessSubjectTo(contact).ContainsKey(userId); + } + + public bool CanAccessTo(int contactID, EntityType entityType, ShareType? shareType, int companyID) + { + if (shareType.HasValue && (shareType.Value == ShareType.Read || shareType.Value == ShareType.ReadWrite) || IsAdmin) + { + return true; + } + if (entityType == EntityType.Company){ + var fakeContact = new Company() { ID = contactID }; + return GetAccessSubjectTo(fakeContact).ContainsKey(SecurityContext.CurrentAccount.ID); + } + else if (entityType == EntityType.Person) + { + var fakeContact = new Person() { ID = contactID, CompanyID = companyID }; + return GetAccessSubjectTo(fakeContact).ContainsKey(SecurityContext.CurrentAccount.ID); + } + return false; + } + + public bool CanAccessTo(Task task) + { + return CanAccessTo(task, SecurityContext.CurrentAccount.ID); + } + + public bool CanAccessTo(Task task, Guid userId) + { + if (IsAdministrator(userId) || task.ResponsibleID == userId || + (task.ContactID == 0 && task.EntityID == 0) || task.CreateBy == userId) + return true; + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + if (task.ContactID > 0) + { + var contactObj = daoFactory.ContactDao.GetByID(task.ContactID); + if (contactObj != null) return CanAccessTo(contactObj, userId); + } + + if (task.EntityType == EntityType.Case) + { + var caseObj = daoFactory.CasesDao.GetByID(task.EntityID); + if (caseObj != null) return CanAccessTo(caseObj, userId); + } + + if (task.EntityType == EntityType.Opportunity) + { + var dealObj = daoFactory.DealDao.GetByID(task.EntityID); + if (dealObj != null) return CanAccessTo(dealObj, userId); + } + + return false; + } + } + + public bool CanAccessTo(Invoice invoice) + { + return CanAccessTo(invoice, SecurityContext.CurrentAccount.ID); + } + + public bool CanAccessTo(Invoice invoice, Guid userId) + { + if (IsAdministrator(userId) || invoice.CreateBy == userId) return true; + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + if (invoice.ContactID > 0) + return CanAccessTo(daoFactory.ContactDao.GetByID(invoice.ContactID), userId); + + if (invoice.EntityType == EntityType.Opportunity) + return CanAccessTo(daoFactory.DealDao.GetByID(invoice.EntityID), userId); + + return false; + } + } + + public bool CanAccessTo(InvoiceTax invoiceTax) + { + return CanAccessTo(invoiceTax, SecurityContext.CurrentAccount.ID); + } + + public bool CanAccessTo(InvoiceTax invoiceTax, Guid userId) + { + if (IsAdministrator(userId) || invoiceTax.CreateBy == userId) return true; + + return false; + } + + #endregion + + #region CanEdit + + public bool CanEdit(File file) + { + if (!(IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID)) + return false; + + if ((file.FileStatus & FileStatus.IsEditing) == FileStatus.IsEditing) + return false; + + return true; + } + + public bool CanEdit(Deal deal) + { + return (IsAdmin || deal.ResponsibleID == SecurityContext.CurrentAccount.ID || deal.CreateBy == SecurityContext.CurrentAccount.ID || + !IsPrivate(deal) || GetAccessSubjectTo(deal).ContainsKey(SecurityContext.CurrentAccount.ID)); + } + + public bool CanEdit(RelationshipEvent relationshipEvent) + { + var userId = SecurityContext.CurrentAccount.ID; + + if (IsAdmin) return true; + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + + if (relationshipEvent.ContactID > 0) + { + var contactObj = daoFactory.ContactDao.GetByID(relationshipEvent.ContactID); + if (contactObj != null) + { + if(CanEdit(contactObj)) return true; + + return CanAccessTo(contactObj, userId) && relationshipEvent.CreateBy == userId; + } + } + + if (relationshipEvent.EntityType == EntityType.Case) + { + var caseObj = daoFactory.CasesDao.GetByID(relationshipEvent.EntityID); + if (caseObj != null) + { + if (CanEdit(caseObj)) return true; + + return CanAccessTo(caseObj, userId) && relationshipEvent.CreateBy == userId; + } + } + + if (relationshipEvent.EntityType == EntityType.Opportunity) + { + var dealObj = daoFactory.DealDao.GetByID(relationshipEvent.EntityID); + if (dealObj != null) + { + if (CanEdit(dealObj)) return true; + + return CanAccessTo(dealObj, userId) && relationshipEvent.CreateBy == userId; + } + } + + return false; + } + } + + public bool CanEdit(Contact contact) + { + return contact.ShareType == ShareType.ReadWrite || IsAdmin || GetAccessSubjectTo(contact).ContainsKey(SecurityContext.CurrentAccount.ID); + } + + public bool CanEdit(Task task) + { + return (IsAdmin || task.ResponsibleID == SecurityContext.CurrentAccount.ID || task.CreateBy == SecurityContext.CurrentAccount.ID); + } + + public bool CanEdit(Cases cases) + { + return (IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID || + !IsPrivate(cases) || GetAccessSubjectTo(cases).ContainsKey(SecurityContext.CurrentAccount.ID)); + } + + public bool CanEdit(Invoice invoice) + { + return (IsAdmin || invoice.CreateBy == SecurityContext.CurrentAccount.ID) && invoice.Status == InvoiceStatus.Draft; + } + + public bool CanEdit(InvoiceTax invoiceTax) + { + return IsAdmin; + } + + public bool CanEdit(InvoiceItem invoiceItem) + { + return IsAdmin; + } + + #endregion + + #region CanDelete + + public bool CanDelete(Contact contact) + { + using (var scope = DIHelper.Resolve()) + { + return CanEdit(contact) && scope.Resolve().ContactDao.CanDelete(contact.ID); + } + } + + public bool CanDelete(Invoice invoice) + { + return (IsAdmin || invoice.CreateBy == SecurityContext.CurrentAccount.ID); + } + + public bool CanDelete(InvoiceItem invoiceItem) + { + using (var scope = DIHelper.Resolve()) + { + return CanEdit(invoiceItem) && scope.Resolve().InvoiceItemDao.CanDelete(invoiceItem.ID); + } + } + + public bool CanDelete(InvoiceTax invoiceTax) + { + using (var scope = DIHelper.Resolve()) + { + return CanEdit(invoiceTax) && scope.Resolve().InvoiceTaxDao.CanDelete(invoiceTax.ID); + } + } + + public bool CanDelete(Deal deal) + { + return CanEdit(deal); + } + + public bool CanDelete(Cases cases) + { + return CanEdit(cases); + } + + public bool CanDelete(RelationshipEvent relationshipEvent) + { + return CanEdit(relationshipEvent); + } + + #endregion + + #region IsPrivate + + public bool IsPrivate(Contact contact) + { + return contact.ShareType == ShareType.None; + } + + #endregion + + + #region DemandAccessTo + + public void DemandAccessTo(File file) + { + // if (!CanAccessTo((File)file)) CreateSecurityException(); + } + + public void DemandAccessTo(Deal deal) + { + if (!CanAccessTo(deal)) throw CreateSecurityException(); + } + + public void DemandAccessTo(RelationshipEvent relationshipEvent) + { + if (!CanAccessTo(relationshipEvent)) throw CreateSecurityException(); + } + + public void DemandAccessTo(Contact contact) + { + if (!CanAccessTo(contact)) throw CreateSecurityException(); + } + + public void DemandAccessTo(Task task) + { + if (!CanAccessTo(task)) throw CreateSecurityException(); + } + + public void DemandAccessTo(Cases cases) + { + if (!CanAccessTo(cases)) throw CreateSecurityException(); + } + + public void DemandAccessTo(Invoice invoice) + { + if (!CanAccessTo(invoice)) throw CreateSecurityException(); + } + + public void DemandAccessTo(InvoiceTax invoiceTax) + { + if (!CanAccessTo(invoiceTax)) throw CreateSecurityException(); + } + + #endregion + + #region DemandEdit + + public void DemandEdit(File file) + { + if (!CanEdit(file)) throw CreateSecurityException(); + } + + public void DemandEdit(Deal deal) + { + if (!CanEdit(deal)) throw CreateSecurityException(); + } + + public void DemandEdit(RelationshipEvent relationshipEvent) + { + if (!CanEdit(relationshipEvent)) throw CreateSecurityException(); + } + + public void DemandEdit(Contact contact) + { + if (!CanEdit(contact)) throw CreateSecurityException(); + } + + public void DemandEdit(Task task) + { + if (!CanEdit(task)) throw CreateSecurityException(); + } + + public void DemandEdit(Cases cases) + { + if (!CanEdit(cases)) throw CreateSecurityException(); + } + + public void DemandEdit(Invoice invoice) + { + if (!CanEdit(invoice)) throw CreateSecurityException(); + } + + public void DemandEdit(InvoiceTax invoiceTax) + { + if (!CanEdit(invoiceTax)) throw CreateSecurityException(); + } + + public void DemandEdit(InvoiceItem invoiceItem) + { + if (!CanEdit(invoiceItem)) throw CreateSecurityException(); + } + + #endregion + + #region DemandDelete + + public void DemandDelete(File file) + { + if (!CanEdit(file)) throw CreateSecurityException(); + } + + + public void DemandDelete(Contact contact) + { + if (!CanDelete(contact)) throw CreateSecurityException(); + } + + public void DemandDelete(Invoice invoice) + { + if (!CanDelete(invoice)) throw CreateSecurityException(); + } + + public void DemandDelete(Deal deal) + { + if (!CanDelete(deal)) throw CreateSecurityException(); + } + + public void DemandDelete(Cases cases) + { + if (!CanDelete(cases)) throw CreateSecurityException(); + } + + public void DemandDelete(InvoiceItem invoiceItem) + { + if (!CanDelete(invoiceItem)) throw CreateSecurityException(); + } + + public void DemandDelete(InvoiceTax invoiceTax) + { + if (!CanDelete(invoiceTax)) throw CreateSecurityException(); + } + + public void DemandDelete(RelationshipEvent relationshipEvent) + { + if (!CanDelete(relationshipEvent)) throw CreateSecurityException(); + } + + #endregion + + #region DemandCreateOrUpdate + + public void DemandCreateOrUpdate(RelationshipEvent relationshipEvent) + { + if (String.IsNullOrEmpty(relationshipEvent.Content) || relationshipEvent.CategoryID == 0 || (relationshipEvent.ContactID == 0 && relationshipEvent.EntityID == 0)) + throw new ArgumentException(); + + if (relationshipEvent.EntityID > 0 && relationshipEvent.EntityType != EntityType.Opportunity && relationshipEvent.EntityType != EntityType.Case) + throw new ArgumentException(); + + if (relationshipEvent.Content.Length > Global.MaxHistoryEventCharacters) + throw new ArgumentException(CRMErrorsResource.HistoryEventDataTooLong); + + if (!CanAccessTo(relationshipEvent)) throw CreateSecurityException(); + } + + public void DemandCreateOrUpdate(Deal deal) + { + if (string.IsNullOrEmpty(deal.Title) || deal.ResponsibleID == Guid.Empty || + deal.DealMilestoneID <= 0 || string.IsNullOrEmpty(deal.BidCurrency)) + throw new ArgumentException(); + + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var listItem = daoFactory.DealMilestoneDao.GetByID(deal.DealMilestoneID); + if (listItem == null) throw new ArgumentException(CRMErrorsResource.DealMilestoneNotFound); + + if (deal.ContactID != 0) + { + var contact = daoFactory.ContactDao.GetByID(deal.ContactID); + if (contact == null) throw new ArgumentException(); + + if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); + } + } + if (string.IsNullOrEmpty(deal.BidCurrency)) + { + throw new ArgumentException(); + } + else + { + if (CurrencyProvider.Get(deal.BidCurrency.ToUpper()) == null) + { + throw new ArgumentException(); + } + } + } + + public void DemandCreateOrUpdate(InvoiceLine line, Invoice targetInvoice) + { + if (line.InvoiceID <= 0 || line.InvoiceItemID <= 0 || + line.Quantity < 0 || line.Price < 0 || line.Discount < 0 || line.Discount > 100 || + line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0) + throw new ArgumentException(); + + if (targetInvoice == null || targetInvoice.ID != line.InvoiceID) throw new ArgumentException(); + if (!CanEdit(targetInvoice)) throw CreateSecurityException(); + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + if (!daoFactory.InvoiceItemDao.IsExist(line.InvoiceItemID)) + throw new ArgumentException(); + + if (line.InvoiceTax1ID > 0 && !daoFactory.InvoiceTaxDao.IsExist(line.InvoiceTax1ID)) + throw new ArgumentException(); + + if (line.InvoiceTax2ID > 0 && !daoFactory.InvoiceTaxDao.IsExist(line.InvoiceTax2ID)) + throw new ArgumentException(); + } + } + + public void DemandCreateOrUpdate(Invoice invoice) + { + if (invoice.IssueDate == DateTime.MinValue || + invoice.ContactID <= 0 || + invoice.DueDate == DateTime.MinValue || + String.IsNullOrEmpty(invoice.Currency) || + invoice.ExchangeRate <= 0 || + String.IsNullOrEmpty(invoice.Terms)) + throw new ArgumentException(); + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var contact = daoFactory.ContactDao.GetByID(invoice.ContactID); + if (contact == null) throw new ArgumentException(); + if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); + + if (invoice.ConsigneeID != 0 && invoice.ConsigneeID != invoice.ContactID) + { + var consignee = daoFactory.ContactDao.GetByID(invoice.ConsigneeID); + if (consignee == null) throw new ArgumentException(); + if (!CanAccessTo(consignee)) throw new SecurityException(CRMErrorsResource.AccessDenied); + } + + if (invoice.EntityID != 0) + { + var deal = daoFactory.DealDao.GetByID(invoice.EntityID); + if (deal == null) throw new ArgumentException(); + if (!CanAccessTo(deal)) throw new SecurityException(CRMErrorsResource.AccessDenied); + + var dealMembers = daoFactory.DealDao.GetMembers(invoice.EntityID); + if (!dealMembers.Contains(invoice.ContactID)) + throw new ArgumentException(); + } + } + + if (CurrencyProvider.Get(invoice.Currency.ToUpper()) == null) + { + throw new ArgumentException(); + } + } + + #endregion + + public Exception CreateSecurityException() + { + throw new SecurityException(CRMErrorsResource.AccessDenied); + } + + public bool IsAdmin + { + get + { + return IsAdministrator(SecurityContext.CurrentAccount.ID); + } + } + + public bool IsAdministrator(Guid userId) + { + return WebItemSecurity.IsProductAdministrator(ProductEntryPoint.ID, userId); + } + + public IEnumerable FilterRead(IEnumerable tasks) + { + if (tasks == null || !tasks.Any()) return new List(); + + if (IsAdmin) return tasks; + + var result = tasks.ToList(); + var contactIDs = result + .Where(x => x.ResponsibleID != SecurityContext.CurrentAccount.ID) + .Select(x => x.ContactID) + .Distinct() + .ToList(); + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + if (contactIDs.Any()) + { + contactIDs = daoFactory.ContactDao + .GetContacts(contactIDs.ToArray()) + .Select(x => x.ID) + .ToList(); + + result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); + + if (!result.Any()) return Enumerable.Empty(); + } + + var casesIds = result.Where(x => x.EntityType == EntityType.Case && x.ResponsibleID != SecurityContext.CurrentAccount.ID) + .Select(x => x.EntityID) + .Distinct() + .ToList(); + + if (casesIds.Any()) + { + casesIds = daoFactory.CasesDao + .GetCases(casesIds.ToArray()) + .Select(x => x.ID) + .ToList(); + + result = result.Where(x => x.EntityID == 0 || casesIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); + + if (!result.Any()) return Enumerable.Empty(); + } + + var dealsIds = result.Where(x => x.EntityType == EntityType.Opportunity && x.ResponsibleID != SecurityContext.CurrentAccount.ID) + .Select(x => x.EntityID) + .Distinct() + .ToList(); + + if (dealsIds.Any()) + { + dealsIds = daoFactory.DealDao + .GetDeals(dealsIds.ToArray()) + .Select(x => x.ID) + .ToList(); + + result = result + .Where(x => x.EntityID == 0 || dealsIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID) + .ToList(); + + if (!result.Any()) return Enumerable.Empty(); + } + + return result; + } + + } + + public IEnumerable FilterRead(IEnumerable invoices) + { + if (invoices == null || !invoices.Any()) return new List(); + + if (IsAdmin) return invoices; + + var result = invoices.ToList(); + var contactIDs = result.Select(x => x.ContactID).Distinct().ToList(); + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + if (contactIDs.Any()) + { + contactIDs = daoFactory.ContactDao + .GetContacts(contactIDs.ToArray()) + .Select(x => x.ID) + .ToList(); + + result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID)).ToList(); + + if (!result.Any()) return Enumerable.Empty(); + } + } + + return result; + } + + public bool CanGoToFeed(Task task) + { + return IsAdmin || task.ResponsibleID == SecurityContext.CurrentAccount.ID || task.CreateBy == SecurityContext.CurrentAccount.ID; + } + + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs new file mode 100644 index 00000000000..9a5f204d1cb --- /dev/null +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -0,0 +1,121 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.CRM.Core.Dao; +using ASC.Files.Core; +using ASC.Files.Core.Security; +using ASC.Web.CRM.Core; +using ASC.Web.Files.Api; +using Autofac; + +namespace ASC.CRM.Core +{ + public class FileSecurity : IFileSecurity + { + public bool CanCreate(FileEntry entry, Guid userId) + { + return true; + } + + public bool CanComment(FileEntry entry, Guid userId) + { + return CanEdit(entry, userId); + } + + public bool CanFillForms(FileEntry entry, Guid userId) + { + return CanEdit(entry, userId); + } + + public bool CanReview(FileEntry entry, Guid userId) + { + return CanEdit(entry, userId); + } + + public bool CanDelete(FileEntry entry, Guid userId) + { + return CanEdit(entry, userId); + } + + public bool CanEdit(FileEntry entry, Guid userId) + { + return + CanRead(entry, userId) && + entry.CreateBy == userId || entry.ModifiedBy == userId || CRMSecurity.IsAdministrator(userId); + } + + public bool CanRead(FileEntry entry, Guid userId) + { + if (entry.FileEntryType == FileEntryType.Folder) return false; + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var invoice = daoFactory.InvoiceDao.GetByFileId(Convert.ToInt32(entry.ID)); + if (invoice != null) + return CRMSecurity.CanAccessTo(invoice, userId); + + var reportFile = daoFactory.ReportDao.GetFile(Convert.ToInt32(entry.ID), userId); + if (reportFile != null) + return true; + + using (var tagDao = FilesIntegration.GetTagDao()) + { + var eventIds = tagDao.GetTags(entry.ID, FileEntryType.File, TagType.System) + .Where(x => x.TagName.StartsWith("RelationshipEvent_")) + .Select(x => Convert.ToInt32(x.TagName.Split(new[] { '_' })[1])) + .ToList(); + + if (!eventIds.Any()) return false; + + var eventItem = daoFactory.RelationshipEventDao.GetByID(eventIds.First()); + return CRMSecurity.CanAccessTo(eventItem, userId); + } + } + } + + public IEnumerable WhoCanRead(FileEntry entry) + { + throw new NotImplementedException(); + } + } + + public class FileSecurityProvider : IFileSecurityProvider + { + public IFileSecurity GetFileSecurity(string data) + { + return new FileSecurity(); + } + + public Dictionary GetFileSecurity(Dictionary data) + { + return data.ToDictionary, object, IFileSecurity>(d => d.Key, d => new FileSecurity()); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/DocStore/default/ONLYOFFICE Sales funnel sample report.xlsx b/products/ASC.CRM/Server/DocStore/default/ONLYOFFICE Sales funnel sample report.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7be4510326e53c4bef5eca8d46087643771143a9 GIT binary patch literal 17143 zcmdUWWmF!^wk_^XaQEOE+}+*X-QC^Y-7UCVAh^4`2X_b-AiyKp=bh}$J!g#j?~Mn1 zG`1$)v%1$@RW+Ba1Te@40001pw--J@>a6}?J|F-9(A&4jZ$Hrxu(5VDvUb!_bh9;b z(4uj*vg}WivRR-HQVX}-&%+$^DGe6rFOdHhdXa4rwTQ606GPA4c53pFB$>RGA zh#}FF+HI|gs}O_|c3Y$qgzi~stoVd9npu9q(qwzUZ}toiq>7gqo>lf&TlGh@rh5hB zk?R#lFU&)0t`pwY(9q@E48j(PV-3{VU%iD&`ByPP*-J!3;@MSOvUq$)G_k=r1y#Qi zqN@ySL8HJBC|7Z%nrkIx0m@xrMK>0#&qTyU zf(@J-j`$Q7Fz_*UND$=X^F23>|8Ve+7Y(Q)RO253%hvG1s^a(GIeJ<~z4eH*pi~q| zY0;vQK360Al0P}R+{(fU=KYX%Sw0!)^KAN~3j3bS#N*sRx6m>7bzkw2On{y=7L&tQ zGOP0v7dD;+bs{^L1xLW-F`?_u^>NK3gZ>*u;T~t;-ZHqf#aZFi1>}@U!C}hmlXu$g zvJal%&Fkf|kL*8&^b(r8GZhE`02CGg;Ozsz)soi1(aqAx;n!e}r>NN!&>;+VhVR`c z^VV|_=B@~cCOMZUrHenAcOh7K;jcQ1@jOSv?wYFKiZ*Fo`3|N%jBoBl^rd8N9Y&k? zCQ916a(0J~@Fz(wKz3xAh#a6}NEnK>#4~kEm|q%UVzuqw81t110mPDaLtA91A*AZ_ zfzl6_$tVrEh zH#d(!F4?{NsY)<%(CZ=7HD2dltgHKA8#nd3? zDg@23RU;t1BwNKUrgw1x1R8N+-NRQbW?UY~SnXjEt>#I(MC_hMOoURsDQU;xE#u*E zL+r~D^BOs9%ADpruG-VMGo7qa7*C;<=O3N{#6Z$uJ| zrQ76|dgHuP*?qh@DKBmy-KN_>_|P5c{PPxu;Gg3|f6Gb}Z!h@2ZebT2dkcLV z8;f5zag?l-O%EN+GiBTbQ4tI?g5M}p6xPfVYe-)aVweJnUr(ow`dsaf^o#4AhqrcB z^+X+Xuqh`bdJL4V=!k`Y2%t{e{bvwhFC-~Np z{VW=jkSB5I&fK7C= z%)4}GH^~u8ZZ^+cLvs@`IjiQDgI-bT4e(DAx5Q`8GT#Vf1O)*2mGFP%0aHDDBSQs8 zdoyd3-|3)IQO^R4{*B3j8XGNIO3O%F7o$=1Q;Eg6UGNg__5Q5{E(w~^&YYQGy7(El z8XNAM4Ud_G-MhO*>@gzayEyizb9X)1_=tedrS+@hi_LhIdVrYtf;|)Gac5SW3=wj~ zb|x-_X3I>c&aA*XgMo!U1F0qm&tnR``Cm-B z=a2YFJU6++sM!1z%#8HLVoaYtffzEP62e#!d97mm>i}B*j3m{&vr}CFbT%c10ueCs z?y~%5sxM9-K}v!9fTxB#LYJpmqnUR0DDer!G)K4RRf0JYCV!k~%5VD{HbV@_&+hh4 z2H?{Z@t3bW?9Qm`K0f{JFXuu-84_@XWmF5F8G1Ha5HLb0){=iz4|!7`uRiQi%-BVg z1$N+gPJOYB1Ibj>J1@ZJD)3)aKsi(p?`~5Fd6sjz(bv4orvy~ubO{XrG`=;intzeQ z|1nKTw>JbydwhD~AQ`vq8Kz_vo_;`Z5}~GMrXW6GoZzS0Uf!rlcI{?&oS(x#sa!T~ zQvC}1&(U1NtYhAP8%3$N%nto_)Uh|RbfBgA^|>;>Te_DHhS!JWyO$FSao|*)7Q&1* zL=rq**s7A%&PV#GXRdAET%-)=E%ZTe@20Qole4B9YL7I$Wa8bXRvXeI8ouDzfqzg#Wfd3il`izpKXPdRLw*?lsc^V}L1+Qw~ad zUK+?KAF0F#oGrJaS?%bpovAvUfW$85sdh-YlRrJ~Lt~b9RlpeYgTTxc1*5~r)()&q z=AU#VuU2rKywOnpc7r3n9Sv;^WbJKi9cT?~?2Ufq2&Y&niC$iW;8*b_kGe2_QBnEJ ztzrLM|3y9L6`FDH8pibf%{Ev}%DJ7fr_<%KE-dtb&)VaC=8TT$8Zcqm3ZaR8NNCGDU;3BI14JzwjX7h1s~EN&TA+vhcInTY zKsbA{Z=|#~%|w8}KyK7j2j)vUlE74qev0l8(v_GIi)gE|C>8jq2d4#-*l384uZjHvYxp{bhHaq%#e&*3ZLDc*ZrYRMIxG--vMS#W{B-zT^)nu4+ zjP2FrzIkgK`k&0WF=KT+zA>`+#tg#WnbEVg{Y6YxoSa3^uL?kXxUCq=5=M+DKavXu zThR-CxDi%@mLN>O^SLT~zP6d`<-+A*odj{z;UXNl&yY*`)J(e$NY=xkwsOh)p4-Df zXap+C9yd=Pn7AqN8|5Pay@n_#B%M;lC>s^4OlyF45t|BHeMk+S+P8qPm7=^7Sj5?`))y61`G`6o|0I^}k;zyJX5NPktnZ|Tv|)X2){ug~d5w)a zg=E@O)!jG2R$YY?($5dGq@>12xG)os>Kj2mo*C$mrq|dN&4C`71%$7^=;{vDA*t}8 z*A1f@TC|0Mp8!mg&V;ROX+hm7yfK`gbWGGS0|_uF^g83ln9Dl9!R3lux5aLP*<@ zh$=yr=;H{8cYPu!Jc~}GaXCiu0AWWLJ60uU+JHVVIVrXD>`Y1H)n98VMIUx8<*9onx$nd+~4I1V688Js8!VMlMHwJu3to-2+Krt+C)|y>BQE+LKwHowj4M%`tJ70a=q1OEH33WrUZ7vQf1c?0 zNip&RyGB!QH@?RbZEm)UpplNE?_q{nAzZ1XP>;tkpj)IE50+d1F6&v|-weuNgUGD- zR{aa=K(gC+{mRR9Z*an`IErHsdhXiwvq1A(X^9u)E6=n5sB`P~32x0B-Ifu*c=zuW zY{HWbJGt(m!P&FD&$I$pH0a^4Jc-mUpUd}^m%n{`ULi+Sr!|~aC_%Hou!0zC-hRdu zj#}`hZ4?=0F>B1O7;>$PW`R4n2g7{5r1QBz_bH%UI=E<0dL{P?7|=aUgNb&6y_iEi z%|RAJl3oRyT@cCn3H+ZAur&>3s{j}P05}-{z}qwYtG@Z$ z1N{5>RhP0s7D0cZENDmb!2;jTU8>Cs;!Q-Sh~Bw%bs0LHFgMQJ(f}P4Pb!-!3n9E+ z5ST}WEYv=%7L%Bl59^$Aakers>9i~n@Er&l;$WP-_8xnpubM7{;*=im4hR0k@l;SjoZim}ULxHf8G9%@RWDh9@pZDoIlC?&ae0Pz&*a}_b z9w;sX-u{55t7>j|G-7_QZ*4ZR+YmmHRByv0@FnE5a7ECyRk*-t|bX$)7YOhYm99Gg;iXAB<_;c zl3wU=f0->mkeR*;Fd2mR=JNh=`J z^+D(B-8@oYIFYvJ_3osJjJD@fzYY&KMUNFEXXFmp91+qwv50AmhpuOwD8mOE2%MJG zfjo^4qS}~GEf5O|Re)`5{ZwBrz}{$vZ6V5?LM5z{KF1I~Ytzp+Mf}!!f)R={p%xOM z53adr-si<~l||wnCWc)Ta;2B2zAgxHOA5HFP9Y^3DFLJ4j3J2P94hl+#^I-LEa6Wr z@u=tJyr!-A7?f5CIq+G15x7HHqk?KVcxHF?5{|&c?ddFzl3umEE-QOeeta!@$`Aah zwa_Y8f_l|U6sNVUyI{)Jc?3@idRSOwC?E*}=pyZiadilu5|Xe9RR$ls`{NpWi?bmS z!*M_GTkB5j#9DbzIn|-a~W>LAnh_Ic9cR zJJp?IMAo}&RV`<>c4*biCmmR#w)BLaA;RG);Hb!N(lJ{*W_ken=g=!|sadSf)LsDbI!d@oC-D_L#dwtDTS3zSwZME_8 zq?Oi!g4@jiBI7~fvx-wyk;FmR(rR;2XYNer)RdGUw6bq#ulpG`)TagqsRqz$dt$W@b9raf1C6-HmIC(T?4tndq024=7qIvhL0Z099NX*)RXS#!w<=cdWKykEt4?zYD)tTO-ai)uEPlRH*s+C z2r@#sU^Yrcj#%@Nqyy$30(`}_bBxNC)#@k}zN7g@0-@6MQQ2NqR5yJ;krGUq2n~7} z)*7OFFl5~>nEkGGM*UcotDN(6Zt2BRj?+ihC^v%0ycP~3EUFUH)E{KecGK2XE#N29H%vPLEN)Xl#+}4sbKzt3ZSb z9z@x&NTr&c4h&qkNM(bPdK2nZ$C{rEKSOUSa)-+cs2J6PeO1$uszwOGX9SC=NZHY$ zi+Mt+7^B;WOLumklP_#oqR%O*+`zCGe!;7Tkz|s?GnR>KDnKp=uY*7pbhWxmKhgdv zIjBL)Njq!wlDjZehY*z8#3dhiUR1T|^k#H@k2zIIT zCT>d}06;iXu!?|ziB3GY7Kb*)ll;b${IBa?E}kyf_ru@6wJyS{L)(s|BOQFk5bmKH zO;StxvAUR%KpC0&Ie2yeQ|?=o?T=RV8|?52YQUhK0hDg)+M5n)2s=qAsr6E;Ajs(z z|6=Zz8bWMSv`{AjV>M?!O=y36vY^XR^zN{j^X}qOhMfl!Cxa7p`r3w5Y3Lmy$k59E%n0~Dsp3!@XHe+GPGi^7 zI%yf*Uv60u>9!p+^aQZ!C!FpI9hhKDd-Odb<>UmN*VWKjDtue!WGCLQ@NJT>#mZF| z?5p6BtXZAoeEQk}TIj0VI~2$pMjs#UfY?OeTYATQ^3r91`q)6 zI6C5|@2dD?=vt3tC;&_5nJHiAKIjvLE&LJj-s#fw=7?U01{~RglIj9Wb=ZR(GI(j& zGS7Tpju)ZvgEf~V$xT^)3v2i{d?CBLPOpy}nG7^BBdnrEnVpFYLqD)op5LvtaFB&* zc)ZmjHW>fDF@7yrIhYz5IXb*8ySyEK-xx`0RyM25zm{Khb^E~@P;+9&;yEq>EfF`zXIOxl)Ljk{kL|Pa9LI zn{!UcyhInA+U?Qy4Hz2t_V_y5Q~tvWJv*;j%gkt8-8>;%Mb&xJVBN_1J^HeBfB%^i z%T*4cPg&NzSUY8ocUAapbwB-}twDMNxvfre&dPS1)BSXF9jB+J(V2N-taGJjPW8$b zF-8aH{>As_7vn2FUHN5ru$@PTB%8%){Hs{S4QM}g5#{%(%2U3qE7N2C9&fR|J z#ax5s^y(3>^=BDncqawi7wUy^IPk0D2!q#juOsc8N5n=DahQ;4_myZ^=Tpl;ZQ~(u z0h-C=#4pKaGHVCg3x>^$N)L$*EPcaBpNW-DP`Dawy!l_9npvY4e;n;lf04#pRl0+*a8zj##4(JwJ2tdLK) zj{Z4(Sad}+!y!IoZSG(nj%9IdaQ}MgCm}PT1E9Y}EDRG%ZRo0H3Splycav?c-_w#l zu7+UE7gR;yX-R}(pYnfwL>;Lw2E8)A4sYwZSeKR|R@Xjh;M zn>w5hH6A){>karrFEl*-1Xk#6+501wyUdK3QZyONS^y^q+eKHt6H5)@B%<%wLnEE0 zLAKluS;cDTY>{dLp-A4p5{*kPGna@Cof*xx=|y9>Cx4&3r#rXL@Y6utWxifhgdq5Y zrR^5Es_ZBvV7=p@kb>nha8S(Mj0xY8Pp&=YfDDu<0XYL(>TACW zP_*s+WCdU+VjaBZ*a52xnG~*sY9>?A4>fM|G?8iJ@%0;WO%Rk2 zH*gU}Y1ASkf}oRh{bz`hKkjiS!am~G6oHb8N8}vyX5+~b2AIQnJMqDCo$?@9_FkI> zhO>6k6P$@%tEPoxYZr|M@`uPP$pwNb_KI9vKtneN zZYTEKN}DJow9G@G7-wXU$laL*p(z0&Q`OavanPNl2yMB;*w>U?31g$b0=~NfGt~SE z;}BfYe_h!FoA@g5>Wku=OZx2qI#+MT)f^-ZBKLba>JYszMSldeIuNfNe`L=kdA|W* z0|~UQ|2i$l7L>@ym((Q=h^6@F)$y<5=81*k9uk}}Ly`!pnmOh2>M7=8qI?{qlY8r7LjNe4nO+Amb!_fS^&cFKRBj?d`dtb$o66YoY#y*z_zUTIN2a$N(Wo)1o0UN86zV`ZtwB*`Muy70by*xMtMejZvtJTW_kl0Z0yt^GEy{!K~JCK z?`kkb;3ZDKiv>F^D+k*X5pfXn6F&u96S?lWZc$XRl+0+LYq9^K z#^oV{9mv%X`YxhUG~6`pE-*Zf7&Z%+6Hhl1F&(@w%yzNS%gh2pZ^pK*$@N~(ekl9s zPB2nrurSt>eqCfkn&bXlKv`CAJcQ(tDdnv=$#oi$39_|Qn{|)88Bpw54X?A!j?ibY zZ>6TGnAj6jFM>emBAfKI8i9yXJ@S%$l83Njmt(xgy2}#|Py-rFj6jh%{O}ZllGh`M zHG+J~@l*8hwb)Id$VDT7a(tGuQ?{~%&=^P$!UE308tdt-5V_&3o8}{*MkJCR++H5w z+IZn)t@H1N?@5pNjChDiqrzvVxoaJ!GOD|u`I95oM8_Dj zg<7jA2;WIKh~WJV$}HZ@&UEjM(4+m0)8o^j*dwL5PEobq4_2?_4ooiQQ5tjG?Gf*gS18e{#%iNWCK4oM$IggZQ6z%qh#66$MKFTYc`?A~j= zN6Q6%i36G&qEOt=lOj3*$2-#n(+VI{JZ+V|`Z_(UCUFK!%aE++DQl$lh00Lm78N@;WU=mgr%dh)62`Zh)E)J4K;H(aj%qI; zwytdmitXW}aMfnB0CtSrFnkyipY4)=2yO5xX7EfE{an5=TfH%pDTdG0BK1<2Xgq$* zG&G%Gph#llTQ8$lG5%(FwNzGBJ-08YSgx*9IS~`oQ;691re3Z+6k&M8BnT;7-1YMKy8Mi3x*we zQC)WFYkR^MHALLg9-&DBX-OEX1jQLJ_&dRcPCAjW%L9Jx6ebYz{0+eZhR$qJN8%U3Mxf)wI;A$=<$O;xcp8l+_SclkBct-I zuTGo78&xAUcRD37^Iwv>>zKp135iDsqdkU^>O@a`Xfl6(XTf3Y5Sgc*2ri08l}E8* z7=xb^E+%(0+S#`ny)h?k%3aE&&~rQZB+$>NvVsHcV85b_2g_(?JIG7)fz>=V;kkAy z`fj}O|q*J7vq_lXQIyRWQ` zFYo4Zy?}<;w{Oxo`Jbhc;rGh2nv4yW(1%Wai_R zE`xWm%V|c&%(Wi={#&wwF`}BWKR}8Q6xFvFD>@NvjGY%Z`Z5Z0`N>s}jqlpsI@9i5 zHY}^ZazvrC6UxhVduV&L?-TR@Bg%81ySZGPRyc7MGVK!>`zK_x5RG^=zdl;1_*>I; z%j5O2;zRJZ9D{M$)2F|yJLV|CI4nbJBCK>P~{y^^{+GjCuY_j3|3Ip&8 z=?kHdJvur%6fqqNwwn$SA8LEXORT3F06G^qKp_%AQzR3(r-xJxN*E5PFN!hG2%X*w za=VX_844!blzLOWbuJrN?{$=+XNmVT^AmFT zunFU#NN>O~#w%=&Yl&5LRzSc2ghQm2t<}dDL(VkORvI01Vu}uOP>_h8pD;RT4)Sw4 zl96FU0+W4U$dl@~Rg^>MKgwwGmoirUTN$S=U1i=Yqx)aV*igQvjP{o@3j9}PbpEJ& zuK%WtT>n-^bb33OzbPXZJdOnRJ?E{RKZ&R=E&xW4)aXy6T%%x>U&?5#=OCE1XQu)w zEKm^TMXx3dCduw_Y_>k3Ck9gN*x+2QJnFeWv>d2W5SLLSmkwaaK^42csz06N=SqR8 z3>L!J(3uD@Fzqrn`l%7$SQYMjrvKHabPT`&I6W8?!eX~Q2-SRi zO0mOK5!DGW|1kMI-x7T0kEX2DaX~O)o_Pcs+se(Pa6l!56V2)NQQzf_yt92edTHW- z6EhCm>08AHWS3(^#b#|?h7#+gV5H~y?>3uy`pdVa`mW{;Sq*o6Hz-H37648%SlJ~u zNen`h?uSlcOmajEt}z|~<0#`c2LG*$t0VtVMngkkqQ8{!(CxP}B38emMhCf@e0ftw zEE{bvhx+*-lh1m-A{Z+G0TEW_hk%)0X;$oil<^p4_F^XCf$V7KX87mmP4h#*4O$|% zluyX^^Nrl2qxUA2i(zBfEra#R0T%tl)-0B!*cMwiz%J$kQaU&w zeGRU}ka1vs6&3XXfyG!%##00!#|M@^$;0%e^wT<{E+;wd4sA$X=MYlo5LT%9bqLvX zj#Q4HR8F`3Bf!dap-gATmu2%sbF^K7&JFVg_W4=NhlZ%AeKu39hX(b}ZgA?TTF=rR z<#Jq^xKSn1x579!7Ia|m1A6w)q{hd?FCF2leBkWN^i4HB z$1}UO($-Z4vxx`tAboEwBoIZsC0t2?R)_JK$HmuoCX8A`anNP4&+5{GV?68-0yhVenwkTdXMV?aw^liYQf4ObDAm)k`~{h``a1kt9VC;GK}nAW-U zV+kaJ`gF>ad9~!4)KflcBwlPET_;y=zZzLMEmN@4uA?QSlruQKKquw7=^52jlnde^ z$M5Y-wHrdJ72fioNqav?#9(yFyvd~TZ<*9FO2sQXlTG%#wN+f3Vs->^+EP)$FhCW033F! zn?+`N$6j}s9;(*(&2@X%e!^1FIl0l#z1NWASHOSHAPrN3#8}^~WoB>QvVYmj{yu|b z`pZBuYK_J6VIA#|rzRk`d}VGZ8LzCUD|wsBe9=G2P-fhgxCh&w-`;SzoSPZ+5pew$ zt8TcMcU33$r6grHvM`Q>2MI(fz?`0tmKJ`v*Wp6*=+nur`DCX$gmM%YInguDznN_5PGPxK4ZvBiQm zqmfYP5{2SnepQ%Ts&QBVGHg|g<{nFaAfNzl@V<$3auX^sX|xG}LN|)SZsI{#_~G{Y zzJOeYX*AO_B3Wc4$Ly0$glWbA(lhpYkP!uxkEABy$I1XtjTXUeQdXpy?x8ix&G@d|-Q!$DnfGFjR%qJx*=;lfS1Wta zu*<=E!3vA$Z3Z=_OWcIx9g$>OK~{_oF;#Us^ioxp&?@Quxjv34GtD)2x{SPD68_h6 z8-oop-(7iO<00eKNRx&^86(Y448DH8Eg(Ec5~^a(r4D`u+fqBnNfFsLBy`w;F=8|q zhhRHYI#=j@K|J2n96|?*+7$*n9}>?%Q!Iv9R;H9?VzBm&oM_xU&R1ezwIi5BKZxd_ zp#VFjUaCG)yZ`Fifha%ow!V`kWCBAs8OD59SlLyQ3C3)YD&b13x#9c58q%V-vdVWR zzYcaN99MyI$igN^7Z3_DhEH2CB0X3FWYY`kG2wEMNwl9vCPmE_ab~7DD2#GuyLZI2 zGxc!E2};p!RV`PJ;<7&;)N2&)8j=+boT}vzed-Y*vbEMjgQdwQFKHKP zo-$Py%@UmiLBw5XpYmYHfRRE&9>9**vWf*npd@}EtF?06m=P&ee&zEvBzo701q!q6 z&qC_YJbdcUvxHU$v&3g#CmZ1pVZMjQl|4sYXSkd#$!=t_VtSk=D~AQzD?S0xtxjEK2=t$|(OUvY;JDFgM482l{ zXw46^B5BeDp2*9z0>x0|SBx^9dPz5w_gN*v4i&Q}_;{aOot?$GTK(y)-r6q#s8V1n zUQ3@D=VL#VwR5lCPOBjgYl3Ac9?PE_f8$+|1f^;Ro2jz;_b6M^EzWc8V^^rC<$Y zayZO)1f&-5wrf?3nA^tH?nfx+xE1c(dv9CHc6NLK*`1+0&8*sR<$b6TTyQ)H(W7`| zjXfq`OgUq_GyecIs@@c zRo~hXlmHH+0y>)S^lNv6VyF}lyWNZEf70_sYCe4A(>w=d&M^`4uf_$VeHB=Gd1rJ{tget|ddsxB z|2fk#{>Mz)TSq-Fzcplw)@aZzUiaCU6-f_{jexCgR|ziz=-K!D5q8;7A@__{)Mrk@ zUU+6G9uLyLm9G&!E+r*ocl(P=mE(1x`pjfQo)OnL@4x#BJt3-O#4kV z&H_M&wMvQN=`GW;0XzWs2GYrmslcbv?xY6Y2nMV1|2xy_m(ondgJ+Qu98*ZR@TV05 z(CcQVl>$@i_8f0eX9fm|n`2~XrKVhzu%>2t`oh~$9~1*Ciu6sH*Vly%1U3hV`&Pyw z)8BwmIBVax%MD8kG98PPY{{$qOsH`hgH-~`ZIwr7ZDVv6K|&Qtxv?7fFnP25ZQ4 zMsAr=>T#3!9B%4qrqMDt2L4>|Ikv+u3OEB0Qxz#Q<~w)sHG>40A^`?bTCseZBwcSw z6Ze3JIuAuYuH3FY^osqG4M2APhMnC9>0$=P30bDzD;2v*I(!-EH4W3STgG_;zaOgLzE$#>T528D)w+d-c`ah+tNO|tNdW46&2 z&R!-0?qf_3WH;cTCrx)5!#DuOq>frl;T<5bNP2LTXq9CEXi>&D0Y5VnK^Y?;`eW=G zDNY|@Chb^#(VcwQ@OS9rye=#vF^S`fI$0{o*Q(;oGM0DZ=9KUiw^_AOqxi>deQW%yf;ZX5$nW8Xp+8R;7 zAir2^*a-1{UQ=aG>&>}MVp>XACZ1ek!psI&*X=v|I826ek_>%o@#cQ=+_ssg)02%$ zJSFRL(Mg(T=g*ZF&5h!i-;w)LiW*z=L?Z;FUDGJ7erpz|{3H{r?4e#bpF?V90$kf`ukOiCm{qs6W=a-N?9Sd9u2*hVD%lGIXL(bx*%VQR0r_^6_vci_*`A z$4=wd)b#cTwd7NYc~$Cmy+{5_Gx80>;#suIwx8m72mYAxju^aT%-W|YnF(TS;yoVx zhDem3;UPmrXe#r}xUrnM{Mbou7Ha5r_6lVbC}4xJ%2I?N=Pc(iYp}|TQ;~tkiKBSc z^dZE*32X~FT@YII3=LcF_Al|nZ+I`c%Es-#5W4XSa-Hjhgiu267UVXZDgdMGPwh>{ zjc$IH$2=}lX6}MvC_E5^O`94TF?Q)xdpQLcwW?jMsPUM(1U$mTUB5H8I3EY-x1Jsk zXjy``=n}NL zgeuDi@!J4deH8B2d%e4a@mKXIZ`+dV_65nfJ;vb}cMH_S5;F`Y1C3_u5EUEHt1g8= z^y(-TIR12yiiy$4b_}+cPnBcXYSfiT-nT#@s-fYx1dsR%4DYm#=?S|(S8$-?JTw^_ zy^Fvm;A9?)@>7v`uz-RAWfzY*g3XF`^4q*&WXkuBK6`0Md-l9_yAgP4l{7K0#eF+v zEL`@l^XS+2-fRy}C$#^p^{q?X3;W+VX?x>_=$-H7FOvT5e)&yOd;BQWo6TIvhh%J{ z5FQb6)>_b(@)kJQ@v(~;QtZRiJ(!{_g5CVy*j_eU#By@8ovw;~2a7uY2(oTrQmMzf zIIGfAKV~X?i3N5fDI~Jn$B45yFqqnJZ5!^W7%LKo{54nvUyn@%C!eAnzx9Wk@;Zkk;~~{ge`le3pvM+=Vy_Xo!w3_X1^cS`qvX)uE7BeJr#2 zMu-slTw*M_V@^{#i-o_LJpSV0 zkJaNh3sIB5Spc2VfvjgS(+U-Rqv25b7#wE!#&0};nEUbGxIoo*+kT(Hq($kPiLp%~ zG@%|zTpNI>JTv)y8tbbY`140^c}K@%|L=Tpl1y1MgYg`NzM;?e&(4104qx150a^ixz9PN`>5Y8zXaJVbE z#kZ|3@3vFv+(M%2ROo~Nc*wC0ZE^!Vw6M}}Ot6T6B@ZqOYKcNvBZ?%~L=iKrJ9>>N zloT?s8E}K>)@RJE$`^s>cQ&p6)p`FeoBlsM@89ds{~w)ix8A-Fec$BxCo~!4cj(`R=Y8<| z=Dt6{t8X)fU;p=gtKWNs_YGx#5K6)S(O&jG@O|smpTL$kQvXLI*8A}H{YihqXCVI; z{;zJO_tEdWcK$>^LjAt(zqJ7THZi;hc;7Yf2cYfE)cHSq2;RrPw}AeMr$PB0{~ryZ z?@`|S1^=Lkp#4Vqo3Q+ml=mp_O&otve&GB@`TK(0e`MqRUe_N4WRm}Z@H_LoKZp0r zfPWC!ss0DT?;P+R;r;aX4?-dR|3LViwcjJWFWvqiK(YKr_%DUrdz|-W&L137*55e) z9^3y?^t=arUordvq+|hT))I#n=vG6Te5cv1v`6 z^AZRjTK$e42PD-CP8^e=dV6!w)lxu0ZceZ?%`bosd+=cPQg;gjX=GJt5FgcLK>H0G zGCb#A)1ug}=hin)ub&f1nG3*$2}7G^$LcTrdkoKsxg$8E`&@Wr6X%*PFebPbO;&w9ldwL?|9*$pFY>VCFoivRS@v9Z%C zmJKi;2g%1n+)ceu-!wdA_lxaI8F!WJ)6>wiKXD20YnEWiHB2-wKx!?Z*vc#0^%jA7 zzWz0&#yqc6-?y9^o@=hB<-BNCD?Kh3+va*x}GYvDO((AVyP1F`+SMe>|BZ=?m$)Keu^f+uG*cm;P zrY-7&HVInVf+5FkX2P3w%%D&olgh>7B&m-gJE$FtJt1b4l8+P5my8>cI6=s1j-fzE zL$(W5hp1*Kg#Jw!5g^R?*N@db3T4`3?44}Hl7>1z*xo`|liUI#H(&cd*IgSB?N2(zn|nTi2GUOnAH zoCUGX-48kAPBmT;u}wc55AJL-F$XunBnhh39Dn9IUkTfmEPfov;SUX9eTChl2(#*Jn4W*1!j z;2C2**=Ua1sqP!hTF9;mW$|WnzVch8y0!}JIF*lh=7Y32YYZ(Yv>q>nTu}>f)fvbp zT4)NEcht1B?nGaS9YOGE{uZ_(v6PoD`FoPtC)5)wfu4+qYe($&ohOTlYR=P88a^6Z z(cj?o?$}s0bs!@iLS1tF*^dCXZ%a~)`utv+`yg}1YJuU~xOg*_6|;NH_y+#(e3-v6 zMZo!yxs{&>{=fO)YU^NWU~6mnPew$`job9mBYdD*UJnwYXdr}0Dkozrm~(JF1*i_V z7-0kX>XK6w59d7b)H97gE-qaJ5GJ?+4HW`ma2~R>7W!3hzRy$Fq!rEAJ;8x)(D!*X zT6wc8Z{@1-y2|^B|5dlcOBSHsA7MMWJJ<%z*Ggosyf64kbt-QB@#LO_dBJ zQO1kCePp2T8Qlpt+HFb~4X{et*4$qEWN6~z>eA?{azQ{A=tH}$B~=7aUCY#!J3jn) zc@D2YqR^#?#xrpUn9yNiN*TW+mV4wNiBck+_<)urfsWC0KMq!?IM7{ds}Ppg)&NRi znmImt;Ju%8t6(;fb9A>^jIx@Ui;3n7K&!vDT06oFTHMNPDvsbvu&(SPGZ?r-6wpL~ z!+FDOS(?ovwBjqcJme370P8YOl=q1QB(f(n!cT>-T11h0@`|=*^6;0;+mjg5G4D=!3a2Z&21&ojSDfGGi!e#cHEaOtbm5=Nc>dc z>?!9HH~H8QV#(|`w>1!3U)G!r3?wdWEuDo@4!B+l6{(nc!(&A!3wFOhp#hZK{0kO? zoQj@ltBHQ>pcNkFZnaJ-umJWV&KU0YD)cXqAPe>rR zNbY{bpkQ1j5_B_3_;qqr?QrkDh+d6i{6_jQ6_zg>wMIZmJ2e9~FS0V6W(&TEmq|P) zUbr>-2E=mV=hbs-NS`C(!E!}u0ENRNq>5eCU+Eoob#m~5SN=Zw6$2jOy*Jr1?Q`|+ zAr7jK_Q$SfPN2H?;(oq3)-NW_-GKj2z74E8)}x=bBK@;&pnpbP2V*NoI@*8Ul?lB+ zwFL~nFX^4PGaE_JOr18uoDD=WJbn1Ovh_X%!^|hou3sKfrppe-u#Znu$L93B*%rs4 zPC&4;a^UXHz;k~6%^Y{tRgY2ej(JiKnoO2{_d4&rn1;k%ZR{$F$Ou|Y*)1MJJF#pM zbvVwLEVVh&ujvJS5;nQvmcQqkQr(y}Mp%wFXmh>Qz07|`mV1h=J%{18}0;F)2hT3jpWHuW3~~`RHV+jV2;-ihHS_Q12JaPWsZC zr{5Mb#l8@lyP;xs8Qa-|waflH94YG+Jm)`QDF4wS#Glc~)=OWINEN9#iCx=pLoCMzgV}Hv7zCm ztcC4Tl~yhf;081N>{7L@jy>$8QtQFS2>hcnIbgx$grNx&o}(C+G=PM@y5BmuQXVK~ z)o8*U2VBLt>(~N4>VLp+=?uc%m-8U4y=^WE1P1b;t~Rt-+La8ZYWyL#Pefm8P9mzK z#-?28tDb-Gau!J1N|2q*F{k`Mu62sMj+#~SH^T;MI3j$jzAtT z;!(LU*Qo=N^E9ljT=9A4^)&oF1{Ljqmu~<}(v-AE{RY6GDFzBjuUs+CLBlTF7N}Fq zp-(dRvQjR^(6qr8y;yVmwgPPOrIk{RGleOL~0v-z~d+@s93Z+TUs8EaO zU6+7&xB;H4TOQNKyF0RAX{Ej-r%M| zb^^#AQh(%kRL1wKCorvh9JCoEv%ad{fhmsaD%{XPL6{X~bpfKKxdb%7NXp5qpa69J z#-121jHqlN0)u5Y52!9FMU;Mb%xY+{7DhorFfDphj}QYUHx7}5 z)rV7&s|w(jc^S!%R%DK@=V5)(Vio|=avkG{8<$_>XQ_=^et!~Zg90k>?RCNib*a+= z)J`S=M5rT@=vrH51Narw6+mhf{P=UQmpZYSUKj6F3GQsO*}iaield#wwvAB;x=rXd zcnKCSsTiP8hse(oo3U{%(}FplT&*fiha00X8>(QYSt{2x!X;=Ho~w-r8}Aua6X-VNH7D?mg3 z8S#SV9fxE_DQ+(^RT>4i9IKfcD%ubsNBDN4&3@t>I`L`31992!7}}BnVN#juN`rxh zNTDVLFG+`4>-|IJk=Qp18?o-Wst?AjN}*ctyg*= z)Rj%=6tC8UUdxz&g2!D2hsbopex65INX~r!C!NqOEk?vQU(zqvKjlX%t9yH&Ym{gj zbVl=vrRWaV)({iTyPsGh(MvvbjiTdh=8ZWOBW`suY;ecVU|8Qb^uE^^zJ=5)$Jd?7 z-;~~gLwXnKFfq=s*9&MDxyYjLutf?T->G7)9!RFvv_3kO45~Ps!bmRf|6dhlLrdKz z1O@;AP7VO@lf(a1QU6Z@|0jPnq-~K!F}|n^JJEfy!FTgkYV(8nlQ5`a_8;9`M=qu; zOtN+~L5C%h%jU{Li5{1P7SSM!bWW--XrrwesBE=H$ zzuzI*XjUoo7AuIa(MKJE;vwK44QaWl^%mMm5c|jaEgBYEv~JM2r@f)w)q)o_4;fk@ zGtVR~kqJ7!;RW(_CC~@;$!CUpbD`jXYs`AJ7&ytL^94^kP_;|t2~Dh_h2h^80=8Du z4Adym&o+(i4paSNmjHv5qi>926j_GnBh!u|Sg5g>gEVc~DStS}MsH4BQ-ZaI+UeA( zUN0vp9^PGP>Mcz6ity-GJ|$rm^Fw0>&2SozcHl`QtCaqgYf?CW%FJ44Wwb#skv#x6j>5qV16|JKxe~zp3Xdp5j|e&8z);($ckwO1_EF>RfSsL z;8&a+=7U@;ie}!7S^H)oj^^=#hwiOrDrTZ4kN?-4e`p0v3*A#l;5Pih4z;(IG@L{8 zXxh9nt^pKQY5k3)M^0O2smtSQzWi8r_BPOT7~Y4+=jG<5m+tqC<%;XxO)8()>-7Hg z%(iT|@9W7qDL*Fo*X{jr_xIBxQcwi3j@SLcw5hC)*ZZI@A1_s(H6(Y`KG*^=(k6+h zS*)j?SG*V_iY)|gOWIJrW*2d7EK3W-l42ELJI5eR>owR1B*J;KFtYC>=I^EEbwAs)#94>YKxrJ^KZ6kRZd zQC-4hQRW;!{Nji{v?ZcHSM!^85@J!?B;~>94MgEi6U9G)lRGl6Ggaxk~%h z^Lwlv%mfLv8K_YN(`unrZ-w=%SEw#(*$==}Z1M@;74@;P$x%TPg)l@r5##F+ydUf%5DQy2kR=G&O>P`}Ivo zvz8b88AYBsFcjd6gsu%C`=;`<=CGCCgE?>IZRLYCHc)k%XfkTbIZ_+<);3>2 zv6e(#mQxb56|Ihtq_Lm%UyPbDWT!O`D;K* z!ag@+%n$)YyDMm!uJ|fJy8N3iio%UcYk^+(B+X0h@gDw?|+-_EI%7^`wOnt`V7uQBglL;=#S0 z&$EG6o13tSfR6fPdGcCYVd3L;AhF4?$YsTanrPB6?B8k&F&Ew}m$cN>VD}Xx#*C1X zMUgQd39^Q^d*rI=TeH5~!wTb8 zn`v`bLTiGewV}D_uzqFnYev3)-&ErwcEAA^B|Ls2oj)JTVRw~Q+ z^WWQBBIo5>BFpxl3{s`l_h_ngZG(d`2H2*?ml?75i>S?&YwUyjUVh1u5BTiz^7>2$ z#S_cqPk`Hj9YT?+_z-2IqLu3Qx-f9PqLmHG8ck@oT^s(gf{guX$X%{qpyD)34pmL3 zYMP;he-JFAqvXa%t`~`KG6SNGYYw7#Do4AFt#7pj`3gQ7&+*>{^Qx{{^#Srg=5;R%};YMM0fDc z+fqy-BcGq;*BP_u=_hEJ?|yCBIASLOv{U7N%lI zkXg!Yz?r17gL(bmfB-D)z7P_AYD=vHqa%0d0?8fbS-U zgG>d`<7}qD%+euUpc{6wiJEi4*RrW|yw|q?k;0w(#nyy_7{-JX?AD|4Ts)iW@zA-S z^JQJ$%T{EqmoHV})#Cb5mncyt@t%C-Hy46js_IlM6+Zo23hl(pIrq2vP?<5R{^p+m z4j^7mF+vSp4fMGjv_;`wKID%2*R(3VB)mvV#*yoCM{Od0uF}zr;yQXEA-`x|fwFi21YIC|2`#6-a(V-}Ja-f9>%XxuN;eS!Xa>1aW-iYWZ_dx+8h z@6!3FdFE(lZ0zLt)BgDx{XK*-%9NfSRu1{}|89vY|DUMhm_oIdp%O5&uD!og8JnP2h zs^PF$t60|;Rt%7R(Pq5dZ(fR*EgumGW1D*|TI~s~FR`6FC*ljIvrwx?N@%($B&(PE zmVLJUO&)3DDdnz01TfMz`Hc#XXtN+{FtS-SG8j0qEg|11gg_djUS4kt_j^-nw#%9i z#kRaI5$`l9HhHgKk7GD69KD*xffT#dQni(4c;Q3-jwLs`eu6JSE&cCu^IIaE)_HFy z%5cHw*0C9B(rY|#jzY??eEK%`CH3FB)IyzAUIQ=Jb*?YPFhxV}*o;8#&$5Wi)B+@r zR_Aml(i@^fOH-e3rjbXcI7K_t<5*GOdJw|(u6$bEZcJ{OVm(J-4YMFTdC zW!L6&rq)kyiL=_=3O?lq)b@+Z6`$lk+rqVc4H=x5JFVQTpWhU|mKy3`npW$9tY`Y@ zi#O@s=X|n(!4(uBIP;L5Q9{IU+4d)f{MFwM!Ek*t)VdDM| zdM5tinSDEbp{KHxVt{svHQEUM{-ZK~cmLq=Ilr2x<$mGtF?~$zo6_>t2Y6155B=5v znrZ-Xqn^fHn>}0`qiX?C$>C1~dJuv0&jfBbMkSxfd`%Yxa`)Q`0}|lnaXO8chKIO2 zwT7Pn-s7L>B3=0-O3Tx9irhu-u}&-wWGouR9zXEMwfXCWX|6x%!co1UnoETd~xqf=E@2T)P}5q!JWMutc~n%14my$WJ075$r*`fr;( zdtcfOYo52LO_UPAS-lbi%$vgYc9#dtLShUGB$GA7KxoBFo3T+yncKvj6vGlY^}XCh zTANm*;30q#91O_ow%Je}UOAp9T7+MC9x3EwrRevvQX`TEE_e>7*878yIPTK5jNe5; zTH$(6=3xw}D@`F({YotN%3Mc1{@(NJxi~#!qyf~)7xudjS-9`ZMV=n%AN;-Sih*k!Dzf^6Z>YjK+{{^4uTgru7kW~{nNWtH zysnF4yQfj6V*Gm@aEN+GY!hW&x+15kM)&L<^m+69-#YAFxQ7r34gfGm@_&2phCjXc z9}WJ`!17<;C~u41is(Z(^W8%m(6vfUnL_h79xet3Jd_ii_-PZ+yU>L)oF#RGxV0(i z4+;EaKPvlLR^~1+@$9eQMZUARjpT-uB?pfw7V}>O)K_-wS(rXd{ZU@W ziS`3Ckns^vTeoGIKeCD!7I&vV{QhBPTX;%X%mB}ToaNL3DZfR&sr$7jGXp20cGiyp z4&skcwI(o(ZI0XQtqV$wq~Azs(5G)hU=+mCF_w=n;RV%4e6&oJ9AX>nmJaZN4-rOx z`0C-F{AfU*2e^tVfP`3;jUbM(v;)XeP&-!qTeXh7?~Xm34G3|NpgJ(Ub1N7 z&*sq0g!7XlGDc3Au%;j{%o>m&>=x8Sl-}?V5d}>aZb={; zvU|wi$NqBSA5NI$MDmQKJ!0;I23%8gthtILjPr7DI{>jr?#fKbkiUk zU`iL{^BeXHSM0$xM4(gR;LOt+5yj(7X1{VfD+iHO^LGa@@=H#6m6RQq(i!dL%(b2L ziYdM4wxRAdGpnejBg+tr6+f2YsnWnp5#EsywOpW1zL>z_Fm$8GU=LXb1tVDBm8$d1 zv~5GOL!YTZ!kL==0-Bi=z)w%r?h7N+2SjE-_7FwVf-2%o>Ew3N>yTt32MOSS6dD0x zm}C;}K?0o>6=ZV{I4mMhqcDQt2d&M^+il@TV}>18E@!|32{N&_e3XrMzV{ly4%I{lsO(R^*btf@%D%B$ZV8Rt< z0TptXzUamM?XaOum_*4Y@N&At#26&#BnSnLrsr)eq>2af_yU%ZsteTdn z>!)H*U---{z^fb?d`;qwuhZ_i=6O?qk-5$0yUlLN-2OXqW3NX^*YEPp$KM`c+j>+I zx&ROQwsL1U3!JjL(%qDa8)=|2Z@@QQH2dpQuU*-^wI(^zxykE`S-EG9H)rXPV-8nK zA23^3r!_}|#vhAg#aA!bVy{APP(>Z-Ukp5K<~{tq6t`tc2Uu1DyzVeSzD`#l{yUXy z{4ZQ?ucSCnhJjk;@8#5gvS>gEX(rHR3oJ*o5yCqM#XwrG(ZU;9c9*SLmq8W1rBR%* zi*ekA8>lP|@;%#?qH*SvQI5~cMfR>_sTMWQ zC7jLO#|{5B2p%Q3sc39AEnPBDFBB6w2&*m&wCY%xJ34=A$(KlS_@pr6UOlJRow|_7 zT$6qB5{Ev>Gt6fG#aqhVHB0Z34G9YECQU3(2PTrX*C@b8YE_s+Py03V0lFB%{*@5o zk;HOYR(V0Cuc=g9XtU6SiyF%ZYpPt+C{=#6hmMVmAj-90w@B3!b(i1XDMvr*qKB(0 z{OZj;MM6s-(xj|VgBS}hyfk>i1(h|XQxtDG_jKXCi?=Ima70LoWVg+GI82hItxoje zNf>Kp=Y>CRNFD(#Qzt$)PQGn<4wtXkUBam5wgLuw6tYL z`!G~jUuwFXt}Zz-oB2qs?Pyj0dZs-XEi&lM8+K)I?pxgoaZ47gz_o86Wnz>78V-1R z9fqR*(4)EgHuYu&u9xf#+gr|o+Mp^t9l#FFV$Y|aag|FiMm5OH6zQEuOYX1LcrFWM zMObnzj@3t1uq9gI(*bx^?Jzx^#=VU5RJMN}+U_ zQ2ACn|2Ume3d~W6i2nLqu*!s1f9*QSjtt8?+dg-Q1++C6MQMAXn(B(_>NYInWq+ZQvEC z;m07~@3SxLe?vP;L)+Ekr`3x=@V`R)zn)ut)@Gd*#T&oIcPGd|R??{59?7#YazG%$ zKpdIG8vG(U#Viy0cNxjyiuc)CDD26+kKTK*wONz1&@=2E{$)av5q0f4v-MI#IX=o= zLPuK%_i>z(%?8eI7}#(nrJEF0?JBph8~&iAXU(n7_I1f~JO!+K1g2i`actznO)KBG z(dax(n3{!91~>>HaxIp?6t)>oo3}0~Fp@qC^?@KEP1z9$%hIu~A5_Ck{Rh>`+nl$I z;4eUML{jd&Iyt5tCy!?QO~P@)L6*nDNFgjn{IF&f4z{zcN67l_NduDpVFq@y#ZhOq z&Kd2HWz?o0|3P(*PKdp_@aw?D4vX(*wQ;MtP?=DLc%!_!fY5}7&ftA?y#AIeSYPTD zE@$C?P>q<-UoiC$8*l_RFYI8qh^W=SQCZ7`aO2>_k4K_}w0K9Lb3b(^p?JzbJoUR# zfl21Wzz?@Q8uNT_XQace#BtVn?P}WFJA_biMv2J)nwSd~3ucYYuAaK@w(CKfp()ne z{41!)RZqg_ZyHP6aF_5IAqd>+gWNJn?^AqLtj+acZ5-#Wl460JtCd{Uk6$xeo_`?b z-WW#0r@3LZb^+{Rirt+4(|4mrvW9hMFoVL+QJTD@DDVN{9P9cULbyL1EhoE9=?(1% z*d+^hKft!`>Bl`3%uczRD#?zt9!s0V-6svars?whGu}2HInE}iV1|sYU|%EMdkm+t zHqmfso{lh05waC18XIodgKyY_U6zGALwg_uk1L7O%>78vizK3l=ZCpdY^-x?mj0?) z(?feq{d)@0Iel1~6a#kB%4)DC!YR$^bfK{9vOfVr;nb@9QG!&H$#jbI;?bk3|4{*) ze%)Yqb+Lpl8@fZ$EDahi)yx;{#w7nbV+>7SII$)uJPopw5K;%Ch&ClVOGs|3KphFF zH!GBvLQu-F7(%VUFPOwBT8L&Cw^vx45&(4|ARweLL471{Bw>(H%iNvcqhx_8Kg z`G_%U?Ldg5K_F!UQRXAZOtZetBXTfG*a#+Up%Ex-5$4#&}#94z`MUTzTf4 z^Z7KtumtSjVCW-V-sTVN-BL0kS4(L|lRx{G zRGYR4+-d)v+x$ZB8(hrPnyVN-!8a;quK6nY+{A0tXWU3@&Xu8x##J3>rxXnqNBDMJ z_U{}5nEO!j*-W7hCTRPc7Y&5!rDdu-dDA$a$9>uUhx(q+fbl<++B`z1XU1|KmwQQH z?spWQrgz!iKDjwXbaUv};Ek5}e?NVTp4OD}T`pl7EmH+9A0rh!zclCZ$z|tE6Uh^Y zDL#omjoUH{AJ~$*TpPdUL{vJ^3ka<8GU!segTAbzQgXeNZvN0g51EmFr_Pe=A@ zT+Qv6p^p=z)1hY>5h`}I$OqysRiqs?94gozLiAp?%2zM)prnmE#OlKiQo!x*O}yL5 zn|NPcO;jsoC@ycoKs`#CM66fUS1(VK@;zD3z4BquRH|%TOL(!XecyCp18f${Sr{s% z1WiaW-eAS~2o;TtKsP3^*VC>8s2Ssf5R|u~7N`oNS7m2MZU&jRF&Xv5Vk+O57J*kd zGMBojV+~Z*f%WP%;hG=tBDz`;G((UhF%bld=^3u(e}n}MI&`=eILFI|<0tR(sfL_U zC-<^iBY8`S4GmY78wJsreO~Px@cLN#5*sk{avQwVmolie$u8oV z?$4!QD4^OhPQ)&VfKjlw$WA|N9_c__;tbeu>KA7Z&vk9Xvg&buu1^ye`OWpe+;Jj=0B|J!mn}tVU?<-5m!^9TVv$H z?;loSGykwE=6_g~ywZ8rrr&mOlaqIul5g3}8~7o@MMAnNQ9+_TTX}Ah2j%R; zn-Gc*55FjxN{%Q5E=)z`wp?Dlz%A@XAUGzfeLZzq8To%{wVa7`sD0)A(p#K|996sE z`46oSsyGFfu`O|3y>vkhe~cxOL7xB{3S%FZ&fy3=DKE%P*lV;#<)tP99dM5?AVFW! z@z)*qmjQbbU@KJs36U1pKfV$Hkfo${Y_`C0lDyA>FPsjHC<4&n$KWeMXY_+S9zkY> zfhkZhEKu*HMpNXb+3Vade~O@G;stRIWGt{*NIUtdFPFP_Au>*g%J9Doa(T*7{O%J% zdI~r(uRoUr?A z{!VgI>J+aX>F+zeU06vd7#YNp2q*StJLa(9S&*W1xM1L4{ns!IV?ioy^K~>G6-ZgcRBi z8jcGW%ELFTu`YFRAZU+!=5eC1-*{Z;1d+Vy;Rax+ksSXht~L%)t?i;cnj|_3Ya7{* zL5d17VSO63qM9?E3s#gpTM8jX44NBVtJL_V$wWQ{V*?jDrPpW#V6aXTx4GUiU);ep z6jFR(=l_KMVuSY92@4cA!~oHCWfiYmdM`XJ=VXxlA!Fb#(mthi--A z3E(iKb2*f41On+5kaCiF1CRdD0J*=wg3vQp?RanTWN7b3f)RthPV_qUGrBDH5f&#q z$u<$u?vRO*Cx4an2OdFQu_MJ|t_OZw61Z zHm;ich({uePnZQ&06P%+?UHH0lf#R5jyFjJOl4A+eJ3l7>-z^+VEu1Ej6AIT(>bcx zIn$At9ZGKeBH1!d4W7or+@41YZ_altIsB=v3?31H&q!=erzhBsPO;oH%qcw8#~JR% zP<(Y-P$il>IQ1V6G9`88mT zb#dLZIV~O6f5@(=pi{X(5PC?n*EcG>jpi%#8H=!Rid`u(F62)+9%{E8Y=Y8Xfr2j} zJ|(iDd~AwlFbs7O#Zy@UMSW&Lu4|iJ&RM^_bgwH-+hlq5ETbjQy48&hWduQ)w3d}r zFGfa&=?yF1O~6Q8<4&ENYt_T*ud=!*G%g5L_(R7TnW;gUKITncy&54jr10*zO8zzy z>&B`0CW`Ie#ARvC!0-8`y9Q;mt=3qyYZViia8 zr%tVN)5Ac4vIe4?hKaZ6-^YKR$^Q+#t|@j@uAkj4`k#%_|2fh8|8`ZG|9hHl(gvFi zp$q+lt0pq<&)ULRiuK=kAkh%V(s>A#1g=Id>R)}NY$U2FUT2k|cpfL%C@0tr{E>O5 z)FZYFgss%(#;@eC0VM*kZY(%(q5ZMj6EP1rvo!lgP!fL>oC58d5r3{zL@6>{fzjpU zUg3ZWW0M&S75mxHgX40ad4H|;mm*82G4^Nu=AQ|l$u7l~iW=ogIx_>poNs3Y_je3e z!enAsGQ^^G@tS_d?@1Q`c_5i| zKK#|b?9N!CgZe5%Qjen@rI3@+>Zs8g-uG$gQ^%~JFg|dx*Tz_Irsr}?$Wt(hl!+&Z z%LJ_7UMpJ?|Ft}V}a$J<_yOXSR${y3k7WYD(N$P zU~-hBgH{2w4O_3nW!kR0a55{<6_GV#2~wNZ&Qcchm>8|I4!atYPFnTe>HLW_v_emz zzZa6pHHtao0k3XKZ0O#eL>J&fCgpL6Ck;vKy@lK_h{S{_e@izS+;&AlO&2RHolENknLJ~rUwJ-z%| z`@&Pj94b9FBnml#-D5?RiuYXybz@&O2dFL7GW+V2jYL~h)H_a9b`eMo%7rOkm-Bjbwf^o%aBAU&0!=8s^6_zsHmR?EHMn^`ZZ5{EZqxZ}HB z2kTRJKxfrpHeCUMT0d0_)Ix<+$w*1UoZLyj{UzP=&>?AB$9A~5k1fB(h@La)Tzq-< zP;Q$=;gC|9<4V@&S-_=WltM8K|8XW8Mr~!JQ#Dj-x?(S^gRN}QrtzSkku&QiiC<@B zvQ}vVU07=+!Olcs;vO}DWN3th4=r29#kNWy0_jq2Ri5H?^H#Xjx%TThahQkkY}4m= z3twU!FI46LA;tyjaFvgY)+cZBoZlY}ZGY+&j2uQ5nP9RM)^_mAw`~Fb1y~PFR2O(n zUc&61&UJam{tnz7$rYP6?*x@vy_?@UXfJR2CvWiHo&Wz;fGiUpRhb{Ltw8->#g^%R z728;2&9dU2_+1=}<$&Y^8T;0`J}n0!2kTLCHl9aRk5g(8P#_e_1k<>!QXvP`xwVAL z1&A|{Mg8A!rXfF48&}`{?388aG?f%nYzDqKDdCrv#~3wOgWKU{-%^WBU>yblnHta- z2sz(7Kh?Z_F^h(aX#7T*595!Vui1bb6(z2TVaaI#Ih)C73^YXa7s(*6JcM2804R$b z=V#B#`XURY75I)0hlB(zxU(&`GpZo14p_WC2y#E0VkjICf$tN_B054lekOik=zw{7ona>{gdnVFFk~Y#%KE^e zay3x0K0NsYr|8VVnq17B-!m<0z~sp3nB){04Wxw2d8%t-u>Qo%E$k_TMi`?}FdG`l ztkdaI2z8Y%c^E7kW?D%gE0Q(2^Zl2AxBSFKKN?GzJ=c%n zg@%$zIbP?5gbHMAdS1 zlzuBL$2s1%45t!9+J^lS4sLn3Nb{E>-8I?3L+SeZ;mDM!Cb|rDDPramZNKlbkXcS8 zXd{EFk2(x&BKPgI9DXT}D2XFIO;8OAuwvM$@V!(RY1ilb$Ouy6p!ldt)4)*45Whp; zTxuG(#vs(7$V?4YUfk-m{zapeeAgbs;1)gSG+X=;*~>_P%BL3oa$m%}MSOHK%~<4y zLcrxO6scW$Rt0AtJCFM+TCHWjHN1)}Z@u za@JP;MZ>W^XQ3@qi$j`f2s(E<-Nok3tjRqQ&mCo!;W(syOK#^eqV)(Xd+0Qw+if_7 zQtWh2Q-Nd81c^^WKFK_)90H2Ocua;QF-`OL+Up!{&pJih)#IjYqOngGNUP@dAM+ux zf>T`i!N?3TaxDqaa>+Tr{l{1KJEJSpC$016BBOT0U-hL*v^HNUzA2yd&h)PAFOGNE zimmGU(qA-NQ&l~C{STWL7TGS|h~uI&UVQJ)E{#+~9Ua^qJqXkC!O3fU@ucwJ&F4Lr zw1Ln*e2^O^mGt%+dIiz%0ZcvV{I2eO2idUA9 z1*59e`Uq5^Ufz})!pi%<0GgEwi8Ube9gfMz5P7nvn0SR{otbA9s8mW$sa zdLsualM6OCu4=b)UFR~xgUL^FO{UEQ0sW`Lqn?3(b2zwj7+aC;3-Iq^moo@lnd+y* z1BLUy>M!emJ3Rj`c7Ki#7?#HaX@&&mxfra7Lp_LG#*i%iqrk?Lf0|P99L}L1P$Pgi zP*0hDirw952@OpN9C8~U1YDJaxU6hUpL=_X%}%x{c1-^{sR$P(-Rj>U!bFN>V3#MO z`=5=KVP-b4&Wi9y_fzw9*bA0GBMNSyPVSM`PRk{&#I@mvR9Z~#%e$6Y z!Ikjh;0Q4VRm@vQT(jI(-!?O6+TBrJu!Joq$@yhx`Am7tlaaNCPA8QkogF(Ysf$l< zgdKtj_anhJHAX9~lA1i}GBHY4nXR5Ul<&!c-z!af5=<~}!|_CK99S{4QDW0zy_51j zF{j)J#OI-8o#CJ@lnuD7J_*@CL_7r%c-3;u_)phErsghM9=)f+XhV==CUXgC)+^;! z#Uk^Nr`fn;D2`ERA|g|o#gpD~n1oG>F(@QMurss%PbE{Dhelkq2fX_m!O@Ws1WySo z-SglZp#z~A2&B=Cktf`%rlt3O7KS|5q9UjW>UH$7H?zlgF!{qAB{1_kG5o1#?!r?j zlk4$5DssWprDAeXBaCGiPSH?rDi@WpuR}CPL9Zk8DJfaSOW4b`kf7RCUhI=CS4THQ z{c;|wCiN=No=1cFeT6>TvMt)_eg?}~=1-lklBot)Kv*dO{otHBJ#CvO!%g+zI50)1 zQU_WYxS&p?aUM#};}5-0c+di3B+po2VqhH9;zYZ_Lm)v5@G+$sPNb=*3H(Zaz@U=D zsI^Lzr4a+fTG-Ao-s@+YZ9;Op_A@aKMo4nRVVv7@T4&d?5isr!f^qEOm_VaNhdO*u zla-sAk82^1mH0|7lwjL~Jx=k{QagDF=t47`v0zSxOrQH7gRj-c-O}F~Up$|tZw_x3 zZ)YEa55>yt4us?02S*Y6t-JMF-rJNdKqXtK86+p&!)5v>dZTqu$b;43JE#sBkeSi& zZ}9qlp>q&aT&Z{uEl-}=#A4A(+1DF;>dP^(hpRTT=l1OS)8*%va;X`i%ZAoe~mt`;brhU`DBL76e3AZWhXEEu(v$YaGI*E8Yh;50CRO48L%Z>vmfrU$}@; ztz3dUbUS!oFgZzRUw%=?L=JVrVWyRm(teb`jgN^nqJZ(xNtn$oZmU*{DCgf6Hs}QW z_&?R0c{J2(7{|xnxMWLVxSG&ht}G*?L94>dbR~tP8;%h{k_lgd*A1I#_*Wr0d4XIoOGr(79~fC2po&pr8$J??~SA|%(SSG5s1LZNQWSqp*u9Sp8M z%AnSzMw+wMt~ALcd$WPFGiDQHfq{`2^9Q(Gx6ZFa8O5rufz&RZ{ihX*dL+#iu@|vH zT_KY=W4yfTXQjyo{{TK4@evM*4wLXs7qvo-C-pQaXVHdFE_$Y*f`5$jQ>r(bubZy8 zwqI6*ug~J{4axq$)-kp9MnX~hh?{B3qt-<0{&lU-eFMBQeNwE1>1q$>ngpV>@S&I& zJg0bt#|wsZuviDDZ+*S%tfmJaUU8l16qr>A3!Dl2kRodPWr7mvC!)EYa^Naeemc`j zK5PF_S#tQH`(h{>?MpfRb>U!nH>Yl{igd7@B%Rav4c%)x_U^cs`6fI%=P6UYXN{QZ zA7oEmD{qa&)}GYk>!}^}j3JXqdiNZchh9NR73C{hqP$+{mCa7>YauTZTZ1kfH4Xax zEo$`buWD&ww8mM6@25gZk)l2B7B=6E+HjdJejo036{`j6RE0mJd(T)OdlB+zL&=2^ z9*6##2cz0^K$&mFdr!;&lv!R5Wtl?<2=hfvtV&<@O8bSX-`&ph9Yyjs*;~~ckrfrl zgqyK$@zT2tZR@KO&e^vN-_m1h4kbxR z77>}egXzjQPL$eJTvn{^R5G-*41OjgGRGz4(=8Ps$Y{?PvhuBKj*T7=ChGY($BKVF zEMJ?Ugcl!>B}5S2wl(*6oQO;ur&oI!p}n-zx;>u=8JS-t1$Hq!%`m@emv=}^Oi_t5 zKJQh3_Pf9368&2so76*9n{q7M{K&p%8HqgyA2!ncwnlzVtZ>Dcd0a_$ndKG{i^Mgh z`r9jdo2bxZ^3nE}xWmT66kLpU!|T^I9Sp+cFuCcpKBevqZ{)vt(`*bn`;Ge@6oZS& z@1H@cO3`)g%;EYZ(I4)i^WMVMQ8i7lQiV2p`zFVBtpxAn_D6ye{ZBQk(zR{%((CS+ z6gTq*Xg#N2>iulGcG&OU9fFkSK?LnuL|z6%Cn%PD7> z1j#Ii4HDH{&kt4q^0Zi?3$>j7ylB|wzW1#elTYCBWN>4s{Epcv`-~$e`@9%Y0a+3cZ-q_cgLh!d%PwUvGLlIpc-qPN2)qeksd~|$_GKN5wI5f_O zO_zFXJHwHvKvW|Jx(JTWyQmY`d>kx9b{aWC=BAHZayDp^Xfne% zu5dp^m;T;fYT2++YNlLX(l7C$Lg?i{gz>Xpa;RIwG)`ANEU7!%`y@3c%p_k~y0m{J!6^J~F zpH05dt^!npZ5t4E5!4n1x^A`_aCl_`0btoU0`P^J8vP8If076FU=1Lme+TWyLi!&u z341gGQowRBgdz_W7D5y@M~=8~kOCGnAe3Agn8JPt2m2S00A^Mq1RI4#geC0>=DQ#S zLFGjRc{VNzMSW|?SA*X?QN~roK@>b{pf3q z-be2>OFaN9zKW-Vsk1Jfhpo*> z>Xh6N1A?gk$UPbwnS_5f3z6|{oE!S!n3R$u zGtG2O)Z-m%QjbB~XTxK7sr_>;$auMK?Bry*p~F{LkwP2hy_umSaKQ|mhV4@X&o0fR z8+Qqy({^3*D$SH~8*8H?AD+P=y5Z?%Y~`8g?j^!WzwHLKW^o_JphSUjWcaf{Y#L*Z z!?Hae6AB9dwljaZcx1`=P;qGp$pQ7MzM)X)dR|}N&FU{|r`imQTPC`+!yNC_z`5HK zQ7;w4Sw?FzFX<^l$=>a#+$2Ux0di%)V?)AY9 zuhynckrn>+Sf2q~dBVvVpK@TyFC&)<9+F)_M+{wlXW@z-|3yL+Jc_-zUL1Q-#Gf%y0aw$?$azf zRTwYw-WZH27eQ5)F@3U&NzO4?(yD@?YBZzJt9w%0Qs31>Z_~9LYdu0 ziEL$^W>9{VEeXp)OEQwm*kaM6oRWfIJv$K+lc;bZ4byqR3Cn*oSI9e3SzCAxgEm9W z4M`sEo>VM_nE{1PJ_%>iY<4|D(sRbSs{8aeIlzwIX+4h!6jA)K0p=!};663%KkRTOyR~dedg386b z?slSW7DQ8FW~bB0{Ftx6*P_c`m35K`#HRviGn!$EcFfFuvrpp1!0VsIyWf4UE9!Ys z+R#t>i)zHf}}QEj8&dfykSUY!E~7e*SWt)DJO!78tjM`NYI2Hj*g@afz3`Tzo( zX{Ow()`0U4ODiQos&3vhcx`qnS!vM*-OyUsl2mcvT8V-R*YV;RLVj~58*L48KA4as zFL@(0p0xQOJ&9|`5YCAhH2Hnj+H zof9-i^6sX&HY_V+I$iQ})3)ZAmHeVUDfTk=g|}#jSZYyE75l~TgiS{?!JBmCbrcc- z`=AjMJ+-QDE2N+1&xLe7ILiTyLs?gvzdH>9YIQNQA$b+Pad)l1A!y#jK;@dcUzzQu zweI(&(M4SMuP6SzBlv&UI;p235$+F#t^Zu`|E+a*dnaondwc7Dsy$X=%5IPW;V-K7 z%?Kfi7DAY`Y6`ZJB`5cDkovHj2{w?wJ~>6nSne}#6Z6#5%IakhVWKDeRFG4_D37>QehgwfIV|&uH4wTl3v8hy1fb{RAc)GgYF4z9^1_^3{t9B z*y`yX!{?SXJ$ErgYW)EIjijeRv%%{Ricz2d0RKqDKdfP4=wxc5?BZl;XZ|1Zh*jCN zLuN$yM4h^E84`sMolrY3O`$?nlAy}fyTuS=F-iUNlPele3{PAgXI9G)~WV;Bwc@I4v*)Mrm((des(b3p5Xq_3x$|z zve|K(TZF&5l7gFo2#*s!m57}VBk+-(rt%axg3S%U!sW?=!9xqPfW~~0G}`#C`>J@KH#~(kK!kwf{nsNh}1mhzN$;058bts(jE(#dhf{iA(*@+{aKb z(tF(J+?Vrrj^E8Y{tN!Qw%d2__ww%ZPn&>CMkkmhZIgu9t0b%ezyWm_>AFy__RWs4F@`}E#Az zc9#h#-YJ1JlWuVw0-|;jF`?ht{?2o2P^m@Kx@mJr3MVtrA%yUq0v*fHz$bY)!!i-t z;N1X?9zYdApO~Zr&s!o}2>Npi9Ui)jJRfBU5=_C15~F&L89G0=<4CwhrxXa zO)#Fcg7%%GO}fkka8AL1s+&tuD@{)qO4Xol4|W_EyWy!N-!~&B!x;1P zYwg~iTe8^UJk|>ebyW@C-y41@Xu4hGslDzuDcQ43?njf$HtgHvdyvqQx^Ia4jUqOV z_N(#^kFkqbKAAcaXHuTpl8AP0*^q=?VXVF4LR+Q}v)%;D`4(+)pl*PrY<#W1#MXNZ z{$Pg;?p+-INR!j!xhh@Ccd-}77)uJb3Y7l3B7|8fMpY0vS8+q9&c#nJTVo;#iA&N) z^OX9qaAC%u&NAb!h&k?+(9#1Hv)9zY5v)u8-;I;HSePCy_sPvW)}=?n8;k^h~!}; z^xuaaBkNVc5;iSnJn_J_O#9C5&=Y}2j90E8JcGH9vbwvL;y_>^kD3~zE9Jc@VCtrS zB@T%g$}LI6^)%R3i~KbUj$Y4$NjnH~QaBe?AIWvjkT+4YODi(%&{=kOPhYNFhvKZS6eFCwQhgzs+CT_V%Iwjf^K7cJKQSB5Oa$ApF0` z7&;G_>)4-MGJP zlOj$z-$Wq~oA9b#TIw|dDR>(<)U5lx@Oc}HPC~^x;T0GGle8uuP`?8(YD<7ZGN@Kh zanf+ecLwW~a2k>7$F9`hy{`kCed(mu;ml&r2V{gwj@OQkP=2dhb>qEA zhi@Z{laEk=n72&2hu3ohqG8Cd)sE)Cjy;ZNZIH%|Kc zRgUq%003S{|DD5ssMp29)YkOBE8{;@Pg`i;w7vA;#GR4QMYciQ|DOuJBl^_oK^mts0Akcp$@CrV3qb4aN&y17*sDEQ%x^3A>IC=pIqY9JytGV` zqV~U(Lhcg#j9x<}ORI+|G$9JICFbqiD|KKlW`5U}XTVKTSd3P)WieJ!Wwc9O0=tP) zt&XfQDK75Ucep0&2m#u&fcZJoOLlZ$A?&-df_5Fp)(3lxx;Xh=-Kqp-e((kD2nGed zumueb9Ak=sV}=bWV{mQAMH^cM&Ol$rp=d{s01Sy-^$???2-PJqTmA7E+@y5mR$2tX ziKWwHrVY|kd_laV`M@EWSBXD}PLoB!t-@-fhKe;t$Q8Mp?sS~KfKGaz_Cj0>IDxii zM3_;fy4GT(p)yQOm~I7_6}iE9@G6__{Yy3Zic_y+c$7G3gTB1fPuRjhHT<^7rW~bO zUTnzk5Ply6Gk;8BCi447Z8us6$SmwCwIAF#zr-QQ^v9bQQ0wsd}aHH_*wTp~zr zAK?FPU^_bMPGK+r0B~{ufS(@zXLkC38u&l`t0ilXEROL-UDSi_j}5+`zur&~Dv*pp z_3QA-!+rd6*2*k!EgG5v1#_0`h_5&Fg6cAk;gHW#TbZba zIxFpt^cX3QK;YvZ$xgdgX`n<&a)Tk}7!(fy|Iet7hsHpWgA{RKT)>KPiB-oIjc58h z+I<6faoeb|6*9|w@+z5-^E+NJe{Ui~$e?0Yq%SuL4!G8WPrH$eLI!{6oD)@-Ouq2+ z23iFET@heM9nEmP3d2I{j9dmSPLZRiKrAK-@mWvFQ8I0Jea{qYw!Xh?I z3osA>ln6iM5^*%kHq3^1D@io3S3GoI4RZ-I4MqG4OM%gKFdcMnVZpn| zM+ek_2GU4Q?LTvtE%D8uuqvDHB>f7ya;v>wUrSXd@(Xvt=40@Fyne5@uLJa=x7O?K z2e)bbK5uh}bMw3Meg1E!7o-B1;9qwSCw#SJ~`?BBVka|T*;?#%V85U@5i$FY)0Ul{l z$;!k?!zjC9ilDkh$fGPe{|$&I`l~Ay`}w<|buTdvwNqLVe91^0?o`3Fs7?`{%}cAC zJ0y93A&0wsNVA~d*2zMMK$npkMJT-iTK!JMux_2|vVr3WOwF!<@I%=U8=D*zBuN-U zyazF%5y3}V1~#eIm||cgp=GEv7ZNcF4@Jn%VD>QH)^Fam0Uc#i)R!IZT?0>`)S!7v zwZU&|+VB$wJNok&(KQ_DDGc?T&2{V2V3`@&@VQf^XmKX`otl+itiZcx8UD0sl&v@BayNq|Z8xf5d{zF7FiD6)T=09!75`2(2iPX0~-SW7cikC`@;wt@?F z)^6wHW?DnrB@|m}%vBX7F?;dvagub7^P$TL3l_Y4TD!17XnojdsSFJPE}-yW35O?2 z)$879;Q0z8QWB2Ec~izHAi8}a>kQ>LDbh7j`WOliZk=TY{nKHA zGn3*W7Q~|m2fr61olXxCGeJGgnW~hH&Z45H-C$y~F|n)aOAYblG1!VaD+xEgY`65Z zv{27=6Q<0t(kEta$cF_)jGb~e8k56(+t~d?5d9v2Bgt)TM(4k+rql^CNz-J_oe#*h zb9WYlcgNMH9d>h;?u51k#T%oGu@OV6k~d8JL#iucy7m)i@0BhaYRg(FFDp@}l*EG* z9x^s5n8ytjA*U8(RXY!nL`J)~xCMk+5xg)v72;{1 z17d*C=!R(=?yBor?=NIU(q!%1z(NK}cJcINq@m~dD~!b4zPIPK448{@g{<BLcEr{kKN)4p>mJb5={rY8ei>n#n_gwcJ*=R%)ogH#9Qp*L zL_gwlC@LB<8a;hpL~x2RWmdgtp7#-x8&qGI2w`u7%=u9ua5Cw$uV&fT{EVFgC6($hT+a0T)YfEi~6Cq`O&n^Y5Gb zo3iLeFN;bfTh4N!D2%yl+?aL)CfZ@LQT|^39a;vZ%&6p4rCW@fjzRc|N=d?v3RVJV zo$~Q?#@UuyVj+|%Ptld0>JEkl86nXYMnhqxd~RZ$lwsHG_;M@`S=HGNJ$FQ#r&CNT zR9X@LuVO2cRMeO{Qt#UK`5cJbL@Q@hDtfDxD%F$941=BMOF6{fk`mVOG1O1bQ=Q!G z_O}UX$KV4_kU7-Any%DjQzorMpN%iRQ;ox(j%}-iKu&4X-0oeMzT#aqE0}#tw_?Pr z!|N|HuD>iXTH_k9UBJ$sZ30$32k-*bx*sC0%7}N9XmfqH`2eYuioy~Y0x^t}(Jd!s z*}2yL@LhUw-l~Q7PCkn^=1pc}KmU@5zk|wxsbmZH)L(99E$FGa+_M(`3|+6P7d&hk z>wQx^Wo+m?&hNIpzy|gKDCj&2hR@`^yvepjjem^kY)LY2=9Go1q zXxoh3W}g4>9~rr>_1_Y5kL_Ia`>Tx;X!Y zLO4}y`czHcr4LUgjuDE2N4I{}=A(xdQ7&Z~pI@At=F!-{L@GX?FpVOIzC z)zQ2BTlyWZi#eDV#F6%$x<1z*&vso`lgw4oc0<~$5>pA$ou|h&9JXC*^#=?==Tm5a z@wOL*RtJ&$a^0c9_;IQe&)q(?noIH|LAp_Tl{d4ho0hG0;p}&~B91BYl}{Q-FG;3< zf+NS&)l2qp`Jb~A*Q7GPlU=0I=QPvo5!KKSrkp?IklOC|b1S7+{IOZJf}rxwt`eh| zex2W6KUC}&dUTGD|BAUA`aFG=AF0i8#dS6J`_xnk*RKkjaF}AjRN9Mtpbvg~F#LPY zeez_i31fp05E!ki!3jc6buHL=P?t?lw`s^Uhv{&z-mKy9Vx46YH2*edbZq2baGtiFES_K_T1v z(H2LEgXM63Ge86I4kqMOwqFDg8F&~QfB_WK3peAOa4ChcZHYv7Lho^8sAq4@B3&4U zZIKjdD0mVvEIRLq*qyke+5LVq4cwv67gOV?4g`xOJKrPh05OV&!Us2Vdfp`D05Jq$ zdeuP$T5hKPjK$6F_Ob9KZWpnxt>gY^7MI-SqslIQ&6`@$~^oDD5Lvd z1oln^o9fB%is!;h(lWD%{3izIjr2)$3QWUCICsu)otUzh#lo1d@ma;h6=@jrGZx21 zOu^OCdC0-(ei9LR7$gMt64YafHuEOMrJ9NevslMX<5=VmFYG=zX>sg2K)(fL-IPy3 z5juF~-(&z~wo=>m({(S#RBvrfOR38BQ6V}fFDnK5m0MZ5CgORNY8y>C!9p^uiv3uL=+6>Gn|TbQQ3qE{v5}KOLNcUEzwQIK;KZ+m_cNc80Vw5KuG?$b8}nJ)oWVdwvc}pEigzw@7X`>uVH` z$%OC@9YEJbfSb~0!0gck670e|A;W(|&^%YwEW_!z0oDCBp z!772@nNb_0H96|o-V`awGFCsm;3b>#RdJSD1iqFl$S2pJo&2(#a}F4IJr&^KURK2O zLS6brRnr7Yx`yx;hrfm_TkIT7H($^?mgrXkFqz%gt`ih1q=hNP<668O1eKQ1d?S~$IvF7Z`({c(V{k;qTA2xZa)bT^#dog;uF5_tfbhY)}m z6SBy&_{Y+klPe2J!WjuDhLI#?9NxR$lcy-h`H5kJEI}Km+ zLl|ephEja^D|g2!QTnJ#e1LNfJ|y=QL-go5aE@G+*>4+{|1MiFTZ z$4N@5JxMuX=xh-PGy>$kDH^B;UHrQpo5b~*KIUtIFOfM>>|R68*!-dv)MD7v$A<*J z?}hIdM;kxp=rZS^5YlXBZJ(AS?z9jd;;MCL9{y#uP5UpE2+;_qu&iqc>6fI{8-I6h zn-E`;WxpVy%K$_&Y{R81>J%0p`7mD`;*Lq=>HOL$(HNAis9bbN7no7wbI=s2ZDz5p zX@GZ7Fe4F-9X*|5-WxZ`h&E4-2u9`Ah<+5x+knd?kw2>k&@<#>2M+PoAv|*ZBH;>! zVxtyzWRF$QZbnE@be`%pLR~f@Z^JH!uJ%LFOuNnfD~L+#yVWW=#3EUCBTvooM5|3e z(`tOXZ9)U!G(SEV8Z4Tt2tPcQwzA&9pmHW7r~})uYp%fggz(Er03=lweYEQ1u?n_A z3`HB+k91zFTM~H54P0?UaKGT%L(H>~tLA0)l5Z%Uj-rr)Ewms54DzF9vwUHH!9w1n zGd+DOcb*^dns1r3PGOqr%2b}?9uWqo`-}_s3Z#g*`j-_hfhPs7hNSpYLz01@M=@%$ z>XKBtsJBFZIB99=N~?SOAK;gJPX(3(U{erJMjM9+_I7HT(vSgexszAEID*M}0mrpz zbqQDahjmAniZdu2D&@dmZY8+q&B@dkUZd_1C8LhXGmu=b5EqH&7d)F?uDz~tu3d)^ zwT}?E86n&t)i*>HkJ(wZNWhop!v%Q#CDLz<{qaf=_(U~00&^q8Yn*5lmYw%gfJpN| z4G6;lOr-Z&tw1EHHL8e^3O_AaLcU}ajGJ!%yu zRpuiZgTZ!dRMn^`0ya^|Q_prAXBn?qLn9ds4Zohv9O}~k3hde#N1^_LI+dVM*9Iz5 zl5mZ;I4J-*woT+DJX+Q|6*Q8N$Yl`XibsgyXiO28h}p=#7a9amF#v`_f`vAsBcg#q zigv9S7T#JZsg?5upvn&`%@R->IDqJ?;m;45ihBWPJepq6IsM%kXV+qHtM<6unK8l! zw2O^i&Q{EpQc^TcI~h2j$NJpa)v0PHKo}-=R z2V5(Fh_2C|?{chHY`>)Z+Dlivp|aN2X&%S&iI(}r{fSx2ADD4+XrFzT^l0jp*ej`D zHaBGh=K1XpENh`t+U91r%P&Aq4$xh8IA(^_`u)g%wt3fdw{*W#<$1G4jRBb1wPfp$yZ(d5AAvqtgb)vK*dxOh2HLuk^W0?fcM8vo1jkit6TMd~)>Q&*ALK zKf*fg|5@lmJKJO_?E3Is^+P(+kYAW~=t%2%$fP2fPA+Fm)Agj*rO!H5424#Yd3YSn z>ys;~q0`?&MQ~{lTpi9td|!GZ-no-X2u*6?MeDW|9$`gy|5@~*M0Z&WJYFXAYOSa8 zYNznkofB)pO6CeZbyTdary}07#UF7t1$&YuoHg#m5MGo#Q?x;w%*oyK`ID>Q|Nl2wDg@u8V(y#p;^X0S6i z<4Jvq5UtFyA%2;)HZYjWMW)n(T&P8b<%w}Jzkgvi5-{_7_W~5Ou+mu53X4Eq{O*AX zq|9(utwKe1!-r*#W{yhWyrY;#gnjXF!&qoQ(n!hC;Cw!9v3*8(VHg5ZTubl)xZWha zL=aDcm5KQp907!czae(CkY${8P?OZ~JWk0S;hbeO=tNuAAzubJ){R0zIRp`-)0}ff zxMK9?YjsIub{|fu5vAQckdbSx_9=2JsEOkg=zZPalj|dfkYCdrl})RtFsUAGVeG6Hj@Q)>Yp;1z`&~n{wmnDYfrVbKKv%M zeUn~Ft>_G1VI0+LJYCPC(Ux(V{f3kCn&SAN3;R7UD~)`6g897m@;=w%b#}r&ezHSj z#gf`fa1U5i1f(x6Lgr3k6z)U~jAC<9*7a@M^LtGiK!$5Z~z_&db?x7qlq4)?dyO1TBpE79r#a(4S@N-P6_`_6ELUju-R|*^1u7(f^w~t zm1s7Vh(TL{zy+_?>yuDUW4oj!t2>UujwY4lXuT++cHV(S7w{?O!LCTp=*Rt+_l-$w zXh-CL*w2jNshv2OvoU9*tGM0AFvW>0S&|BoSJtc%3yBgak%Q$PUl(>Z+(McOiAZ&z zHX_MX#NE5_{T#?G$%PB2CFPK!0wU+HijiSsCpIxIOeB~K*G%O=tDj0HBLXY1_EZv> z4RRf~%2(JLjFCXWj$koNLLw9Obi?(YKWGYGOq5JiFy=%Qiz{5GrLp7b7{8L%(V+?(BzA0akk{Va#s>dJ98l6&b%b8$_MU zf!uHKUSQkWl4X0LJ!uUw4KM?VcZqYvNjh1v>j~r*%&y%nUIoMd4m1o?X2;-W)nK~Z zA-vKkO(G7xVsNh`HuYE9;BO_?!3-1q=2DX22Ob#6M2xCI#QAm4QR)MbJboBP#Kl*TeW#Cg}n@O4Hu4{iJ>Iimd(1w z!3+-v0q(;$&Y>#^z<@p5@ww@(R2ugth@Hk2&fcPX@Af$#|Mvv%WJQ7H2)Ps8%&$U| z65>S+{6dKM8v+0TQBa!Gk7%?Xq})MZXk=`qxL6-rh1 z^G51lD>ssfAdO-C+Cw3NrdEyeA^N@sYY~8C)h~Rf{KdfIN5onSEZcD%bl_7lO^+^> zhEG)V_9;6rsdlPSWtMOfVwKnAa$~=jYhjOn+aZo+=hmC6vR*00rH7Mr!R(d+uYWLe zbu>GPr0`}+-y&D0I(Z3saB#zWvzs}MWgr|@rE!(|a-VND!tw#y%92kO5Gk=1D!v#e zN`Ib7CJ6TA5m*4kV=5&pkC>dV@pZO%TRT_5-qd7n7vjG@L%bG8n=S<(;8Zsw9&8dg zkmRip;B+nJmC~2>$@^!0G5Iq3I(~gVc9^m{F`bwt6zVDc1<>%9@#pr;0gI8)4=SzJ3-*`MsIdbuzuJ&BA``OY6+u zYCSWfbw!2Et`+-kRlQi*hP^qnqESMM{p9t4gr$dqJ9iZvJaS7zK8N#ykFpni$42mW zLc=;VPr0gH(A@4v@iN~sni`&X7wnRHbRlgJ+wa!^6;yT=qpo-n;y@ABo5`p!(ejB$ zZF~?A13U&gyu5N8^~=PEM0g^GmxNef%2mGsrM$d1a>GOPb8yN8fPZ5O=Kdum7x{=U zG#YS!eq#a%&NVMmIdhh&!T2tMv<%##<_-#~{UubCOpSiW;w1{fC8Nfy2(w_AEycIJ zc7S0@(1{joUg19Qw&ys-b~yBz!9#-i5uvGeeyA;L?VNV2=Hfl}X~S%W|3)-;`~Br< zEgp2wuf~0JMFz2-C8XAMk-j{Uu+&iPOv+>0y}w525Jru*fS{+;Y;Zp0uLEQMn@WJ1^768`6OzIYalWwD^fk{rZKP+2$LaN%(VedN0+jg0qNa z*!Ys1kigvV^Lh(Xoga1m4!IN_G*3lIYtp56Dw1P`TTuCQ?2qjx?`DbSZjgyHVQ9+s z3KZ&??=eYgt5YW!wk!}U&KSn^d1N>lDaKr+-5+N`p7ONNu6NA6-9?%19rcAZ$OIim zL%DKB1v8ySJf%dX7V?sUo!^xJ`2@gF74H2ZVym{R?Aj~l%tBV6TYi>0yH@WqhhVu~ zIjnT~ZA9f5ZcE3}?a81a^iDUO=*a`o{yHw-K>xO;4}ji;%s--|{u4C*pHpZ5uQg@* zk2Tet`4Jt2Ui4G$`snFubiI1p9?C0@YDb1}YoUmJLw!RukLm7l8hkqA(z3r2om_SN0P;&Bn^`Idl zG{|Hgxd)QQz^yj{7s8@KoG9~=V+6rp+;;tM?6!V^t7J6Aj0!0Hs7^aFOw7cFVfi6o zu}a+(3`p%$u~fxC#d&ySA$mE_v0;(gCQMFZzJkDaNKi79;$&6U_>^AUh=cy9C)A(^ zDHI25L;zmBOxngG_U|Mm*IaY!1{r1*M8?_abxPWm;io^Wyp+)?%Z=u%inSbymg%TF zP;EnEfirYMISRl}Ia*0Dls6zP1kECHqPxff)x4Y!BBag<0*fh9dnL1XWscr)*a|?Z zt|bf>UBqtSNbKZgw>0KZF68|WKdLj+%4Q6wC)%@GFEv;Zki?sxEzZK%hCRn9uW5d< zKX?U=-v~Se1I~`Y$*jS%-Xp!4ATvr%)jTxqE0_G4B5ZRiDZ-@xGIMaYYQAa``v!>+(fQeKDt}75|gCn$yNBO6sc~Ro;T4>LH z4)=9O$54a;giDG?>w?|w!yCl=apc0{267UvXm|`O{^AXdEbc%>P7pTtbmPB|?cDxb0mh$3#Y3H5-bSN`ifqtpVp-3vj5@O=amDw(_RFAYBR&jpLQGAA9a2DFqvq;uy zS?jMsbn18-%$3}Dxn&TQWwxzWEeFp$9R?iNPdr0np@0*194nXRO|s~nd#HUHr(}4i z4zo{JDg3QTAN>OYN_W3vq?^hD=v*rzD(x_3IeO=y5R4{z!ubA##iVc&|LGX@2pOh_ ztH5$6O-soR)B~KQ)L^QNFOd@1u6&^DQ0pU)HJ--*vV%nqOO~Ac0@=Tyztm#UiTjWC zT=E9-{dpu*p^=3nuH|LJ)T>OedLbs~$=PTL>|UQMiWtK5)=O!V*0sW0c;xy-ct54i z>wn#tgru;3V136d56#R~(hE4ST&efdO}Ko zM8lOIhH&X8!Cb-5H>FHdVI0JonhqEbgOU`f|FJjwl~WVj`f0a8>lL~~H!|fWXw<3k z4V9cJx`z>TeX#`k{&sy7K2bGMm!wa|FRLe~r{~A*X{ZXjox#jZuSieYD_pxv#;@G|2g9d~Qn zvt989dtkfLc1;~{%gU~Lu&Je|1FApv%IgqIqv&&LAx22_Y=ECjJk~)Tpsss7c)%yy z@jCeg4*gSnq_afn@3jh#>4OJiA6gG!P`9X$Q)Bnhk3n`TYU}$Hy{g-IHO2Tc+SD@pHanH_ZR0Ov?{B`KCQKKnDQj4&zM{ zF@CB3>tlVM`MtX#d(kA zXl##NWLYuM7d>!^eO^a%vC@tl$XvMXZ_4%Qq1~TkKkY5ab}r*$?U9Hwj0Up<88!aV z7ywxTTnWp5Ztau+q-OYZuMZguqir)^=d$-EOoWyYyKkGe-j(}|QP^%bZfhOGUC4T) zby;-!uw%{JThBkbFHwy9f4_mL8)f$vTS-T&R(I)&~MTX_S`RD%?85?v#`4;s= zf1`>7AnmZ=d^e+YNvKD$tN&kQTGQ~HE`Xcs5KzWTL>JZLcguyH+)GyE4|d7eDu<$Q z5}TNZZm_>3;PK#$|G)}RQF$!Y)vEcxdr%Nfddq&lHT9&>?kZ>AMlcK%oW%*e!E5XL z-4Xm`o&qzXjT>kitd3%3}VU;XM)mmAlc8I}60U7fuzx zO4HZJ3Rv_JUE*XYDNvilUO19-y+Xr`S$yk^gA6_-*2LTJ9s=)#JvlORuY=P9iiwzf zn=dTi0ps8zNyMd_WixXCU#D&1ozyWfBUQ8o^y3*^=8DGkyc`PXgEKIr^P=}~2n9l|)!c{lJOBllzC)n7jQfy|kIWBIS zH(ha8rEnE&qC?Hpv$|afZ_VcG5pd|{2T=BAMEIFgbPe(esSJq>h3usXqyv`;8*`i? zrn*?5g(%XO=7(b9=XsPvXjI3AB6JP|#uc?06em$4pz8DU7wSpSn1D1BIYOvuLiJl+r}(oCY)G=Io6(6dUCv1CR6WfvMOwlVR~Z&?TnR{ zG>Ik;3VEAn3jnt*V*RtlriXETY6-V$+SVC>#I zcU5+Pl*yqcfnkK^s8 zLT4K}0%yy^x+o>>Iel#DwKD@QS7HWQJv=hs93Pf{@!BN+cvdZ*y>A0pJ>3gzx3kFE zAIjN#9j*{hys#{O(mbhOV9s4aayc%hZ1|Fs4vi@W#@B#0dX@UUZ=oRd@anK>g@)|k zO(f?iY;1Y2uPcPQ(fEC9(`E=Gz5n-~;;CkAqQr ziVYcCX zt{&TN84^#LnVt~@3yq~&LO}uqtYg)yN&n)N?vY}9njn>)BRy|~uxA=oZau=3WB zgUrBSy2XnB0#GtJ8quQUZGzhr(=c_X!dTIXTBV*3wIV+`ATZ6mhR3)!rlJN>t^hBA zc2f8(bwc>ac1EZ*^=^3HqV?Xyx`*J97>q|D8VNPcyGM?QI%{{8ykKf;_%;vw=3%z+ zWno?~#hot$z{KaSO+;+We<}-BW^j(SX|qXE0{rBO{QPzvNr_PG^B#sMRWz=D45}>4 zj+K%&5>ag&g5X!&#LRa%XIg|j>f zgd^w`AnhLKbd0%PZMQm=C%c;@eMClGy|e2O(hOR*y==w2eZhClF)fYG4%R_y;giX6 zI?I79^G#m(ME`FS#Kg_vF8_1jq6YPU)hFiv=#$34KPIRL{gnSdCMelts$p3oka&o5 z*%E|$BIm$~bnqVwWJ_7b!uy2obw&>Y3WP$LXdnOeBTnjzlS-E?5a%E(hN5uhVMAl= zN0&QY{F0!Z1{)5f+={+!XoO@HQ5`t0g=O+`Zg9jVGzpA|QjKyfrevMFpU+v|&9Y-6 zn}T8#!h0f_Y*!-2)=g}qVZSt`rfVnDLmEWRk~L1x5r46EfSgqH$7)>xc#|vc2mFNw zr`&IBUSn@immH+zR%4ORXdZ|(3(^qikMT5C;<5qQtn#hcdjRXL@9u20zRWvv))8Nhk{2gsjyx}5wOmVo-1t6c_ubm z(_l!<2{i8!dS+LY*FMXLJl)tn7%4;HU5xo#syL=eFM|hNMBZDfoN508v@U(u2v44> zHsx1Ft;9j^b}`3vxbVR9FMevxHXDodBn2pN(RJ0S647JJBR|BiTQ$yFVi20pq^38) zXOOzVRq3>p&sq~0z5Et9txvbW)mI_`>n*zZ=U#~UXFGI@k2d7yr2>Y1l<7T&Rw;M? zTd(L^Z0xEjaJ*4K|A9(@L4~;WJV`HAzexz3f-;@P7T~qG*uB5sk+O9fPZ@3wx(V>< zI~-HYL{vLf>QCWzvud72z6Yu;{qacHRy@9=NNZ9$j?n4Cce{~H<=7d$28u7p`VHMocXbT z95!9e`{urKKUuw*z1jVbvvpoAn7b;q>0Q6md-A@S{8_zuKb*g?HF~zq7BsZFbNfJ| z-J94S(l(o4QX9I#XWAb0Pw3f2L)6p4(=ZM|E9;eB$R8e;2Ch6EysP$tcH@BBb~t$2 z;Z({qYK0pd=R4s#hg|7BShc!CK+p;HMP(maOkb=TNo%k1AUr0xsPu2GLT9ZOUUqv} z_ge0kjT>#AR0FfkX0u$oO`4;Pv3@T3`QjK8UeqfA6>i$Go@8bFiBu z&5H{ka~hyQ%_s2lkA3~+Q=DuRXsHCC8IRy4@)|A?{KeJ^n~o<&IL zOYGs^Gn(l|9i+V>+v$mr)*x`}sfKgAGP1W)SH123KMcaQmZ{VO2mpZQ&;PgnmlTTa zzXUvEcgXhN6l$=rOxD8l@NatqdSuY!d@=j@zY!)akT{GtN~&MZt{MuE?(S1L4%=@0#SD|T;3Atb4k==}0t*kmu$ z{y=0(9Z!ZJ)uhj4M((-x|6C!wT7+D1(?FO+phzf{_Ffp?D2#3>Ku$$&s(~Uiq*LZ1 zM+@_cQI@S0^rUm>TG<%UlT@K3_!bb9Yp-6rIH^|G9Hrz|Y@W_&7W{{PBLXsR2bVYQ z&EJxceO1x4RgOW+F&qc3wy0}X<~>ewbF-CeVkR%ys;g)!ah;=IZu#ug8_tBwm5nrg z<~IbDiM$l42Y*pU;DCcAY1@YfR;W@cr;Cj@#uL-D1$i3% z+1_(mkfp;{Xvv1_8fs$0S@VNnQZIRm$t>0deFG~RHN;}TD_D5y zkRqItuv9(zTp9J7Q~4EN;uhQZoo5v7UP=xOjIR}*5PDGzn1{%3cH64lo*!P4_;2~i(FtW8>MHmlO{3* zMMPN-sI9gZJbW&-3tWb6)Y}xnc|dqyY@NJU@h}RnBh?^siXg`w-4jFM3}L!=<)&40 zJ`L1`)IQ!wa9c?TU?We*629QH6kDz>JS652B5;V>+!gG12u3c$FtrFq232sGV0I)( zfSOI}3M3nuODPZw|X6RVKsEan^5#gp*Q~U{EK=N3DU+F<(z!fD$Fj z@elvHiaPZ{@cXI2T|fXz6?nPfiOSDY+2~Z+WV;g^-x6tE2uAl+=eP8Y=PMcs56!31 zIIH~OB8?c3EksA14@u8$EdQpZOn$Tb|Ef9nXsFXLj%#Qbxz^g`5|*+gWfF#LTdp(H zDn*pmWnFR?5oO)eG9jg+ExB`|mToIXMG39Jlo{2kOkyymLGHKO-~7huH@$I=|MqZ> zKjzGNKA!jS{@(X_fA8~r?U~fydVDSzQX+;sC(INELS}tB{Gc=EDwN*TcQ-M?rsU@t z3X(O6@!qJ!)`zpBoSycF{!tI7yE%_PWR*u5nC%M)bg}DxfACW|Icu#$jNLEQ#N9)W zLd)vzyIqPpA#zSCHeVV=ov~K&EWa9L$a#G0S6}w?zFn28fu&T?>jhfkN2MeY* zJq|VwKDsI-g5B!T5MaM0&{3z_V?eEap(#KzU3LOpJ6l$BGaBntM!(6SCo zk;&M2Cf&R21Ufkxt$pKFSViyfNZYe86SBhyCC-X0*k+*XK4^_`bIgy{!lBg?Z;EA~ z2uj=PY*WLrc@rM-or)6tI!mqY50vkMu7|6js&hGB#W}C@m%rhDt_ygFH&-;I^al^8Mk|8G zI)Yw7s$ZJI&z7!@wHHr%Jg+M+J>t2_M80y6Ftdr-Biob?sst}Ew9JvSVK!{N|zMQB*Z&a zX2wRXK2H-X)1{<$8s}%w(n)tqO8@wvHpmJSWSH|N@E=JlyG!_p7tFx@@@oyN=(5A( zk+{i_ejtPY@j5P?3dN)m>f%)8#pX*jJ}*f8HTiIm?zc9HqEw`+hwRQ)6p84XFWu4XDpea` zakkky30K&s(5h3fmFcR-%qTiasaJ3}w3s}WP`djbs3xF$k>yhc1ws>Q{hbR4Uky1g zBuFJW9FXLeMp396csbPxb6el**96N}f79OmEMc*yBQZ^JYClbld*s<4c^AaQ9=>Ng zth)Gxfrqb#mwiM#Pohlc+TMC68T`YAI=FwB+>&vim*? ztK`Z(b?$0TYr+r2)|{{3EOLfL5=`{7W}8mvIs0MTyfHcSb!GlTBa)n{$i2bAERTjl zrR^srCK{e#6J4^^Vur^#t1fQ4t;`}^H*5oDK;L9dS~xV|%h0b9ZwAa=Wbpcnd#IrQncm*K`f8;SYi?wS|E&RclN zkLfs2WzyBr&xKu6Dre;wH$Iun0(~Tl@*A!YU4nkYH7iTdZ}`N&1pS7uYnPzk@D0HK z@AoojXXPG0=2z!}z7T*`)488{w7T{XzXpIhP+UtMfGfzr)pz-#3I&>ivO0+AW9XO! zney-XpfRW%1W;iFA?QP~;Vr1}zY8=3wKxz%bId%-9H2QUSb>;3 zi}IPz$yb2Zpo{}zodC(CK;!1?35QoE5CFE3BLF<4ZS*yOdn5(z!Ja_Gz6yG?2-$zh zN%*r7kOH=UA(Yinkp@KJ+sKhE9Hf9f2MDEC5vK5$dBFP%NC4{*5rV|}ZwT|o6D%%4 z2ysv+1T+$UAKqasnY>wtqu_GYpUb zX6^_<+Y~17o+$ojdfulC%yJP9!3^ennO{60|16sq2xf^0(7_xA@=Y}!5}9!G0>Nws z0q(Nkj};FF|d_ys&eQi{dHvh=p1^@s6|2Xggl4tb?a{&PWK7G7J`uL58fQ_}Ik+q|a;#XTE z2Q3;`E6e@_DeF}__`phjTMbdi*xb*MqiS`>H4syG08DH(=(lj#qzyKkIhJ6exm9R@A?OP>p{CG*iP9tAgKe_xNQQ_1-Kc= zsY#1Q`a+GYId^h&xrK!j)axnbs&q2I`_1%61@JONc3zyrZPq7q67P zWp6yeyPsFf-m?F=q-&Tp%m*KrQtA@`0My4>$KJ@&ftKd4*YenI>0UZ$UT=~cPbU`Q zfTP1US0TRVAz4&-7DoT-!d`h-uDS=!0Hf4Q=a_v!)wt``UhiPD=jUTYZl? zwO2Eo6&GEG1zTqEU8vIOdY!A>x1#FeH`P(g$ihRY-%74=>060p;weM1M`S3?2&pIM z^oUtx2b+pdH6%MRsthq5u25&XE4!J#4=r{TSh)|v?QD?3K8wKZsj;~}lqQRN&U8Q< zV2b0Eg3w+R2QbP$Q7)_b;UC2dW`Oc$)PBa0u*!2dfldbYNI5t9)kXVF6kKiDZg+**ib z2`xsH8^HyQt>_6iTn{5bOAxBx`Bo7&U){*{e(CbGPJ%G%a2bZwXUL^|W~N>9N!Hz< zx_rs&k=xxsXaq9S9ydoHh`1qshw>SKUPBZFf=;Pyl#Pm2ro~^ofK88h=EqX0Bz?mg zOXPgj_45*t@w;YXCH4fylut^a*igklKlx7;^ETW^iQskkA+ml7V3Yb0N0DYB7E9V- zVDGXhso+zNp`@>0eH*EUbo{x6)4;@z=)>SJ5i|NP>n@NRbPe+~314*Zxd-duI6CDp ztUWu!a~DRsQy)67-TCG+!gNhv`wIQG9(iJT{>hVu(j5`Q2S@842iylwu9mbeHue_! zHZ~T2(G)4$E&Yie{w=}yV#WvsnSWb9VvRLBUBX2dtKqz`oNDbAv@^i}T9@#h|Ba|c zLYdPo^(&*z##q|4;djUyq0{_n=#~s%aC1F|;zj7p12`2I-tmun)66Fi|N`htT{0Yhatrk3(OO3g6z~WR7 z0>&&x(Kx=##)lC540llfRVG-w?S0fkk70b@rm*+r`6f%EY0dt@z((8GuP}pGDBQii z0hgd{!2&-*@G3%QskEm&Rz=>G*_)~0LvTixs%Fbp%gpLQX#2)u*_r%V+P&P2>!b(C z{z>nK@fmmcN37ca2v#tE)9c{))zZk}FLK8d)ojxL^1-nE$G%b0aT5F!f_zacMRKg- zN>FHvd9WI(k%L(mOWi2TTI% zljUv<;RQJ*`5Y99D?c@llz|0m;MNqz19*UVsjIc-13!3;v6TD=Sr*CeIB_g7oa92% z2KtD^1u!wb!nk3Gn0U%HBpSnO#E|?0msM_M2bf^nd-@q6unhNs*m~jyB^IQY< zh%;TwZ4%muh8Fu^AEK5L*X{srACT~5m zU)uWTH#3tsM$w-m;C`P`ts3F;*}h-f%&>k$Zl? z*d3M+gwvh(LHME$n33(!iJt7k%X1b z?36xTK3!_GlT)EaDiac^j1aCf>m!_f`^2I)%T@EuS^s{)q}zgI`3KFBX>K#~E3W37 z*ewS!a(gK=Ft&G{kIbd)_z_C@6JqX04eQel;wu~c9UB^4^Zuy za{1R!Ogm&-61zWTSsVb14NC*P80t8yPA%+M8LM{BquQrBUlyUgWogY0)!rYzkl5_$Dag z4gl^h@gP!pORy+~?h2{Ta0TXqETUS--Dt!FuodC!I!(7C=@`LvVidbIx(NN5&4+7? z&5QT#EY?XlA-v8WmECwsCFu~A$Bpb8UjCgP*RR_O6NX2w)Zb6tbGtVohab;c;t7Ce z;$Svld$q@F3~Q-1MU-DNuWWBe;55nlEUIjVweiyvEuj!vv@9CcJ@uQV2Y1VkAKRJ(31n_jnPy5M#kspL+aY)`y zjD4XSbR532g}nPz4f{UO-aD6rIa4P;G0YNoqe=FfgCS?nmyilxJ{Qsd^P7_9sgKK#ZlLc& zv@yhJ9o8BchK28dlo>O=W3KBc<2T#@-R&t(_SNKq5GgYCH9jaWU%z<(H5(+T{is;( z1pH^<>^il>+WT<5whuSN{M!Zp&h`FXo&J^g@tOD1!3$Lq8taToi<6UxGZ#c##bNV` z8jSWO1{lu_G*;T0A_-u%T#3KZ9*hH-)w4Zj{OA(2x`Hgp1@_$lUVRqs*8BNz1?{Km zUfQ}P*X;wGc7KAyG5$3`6HCl6hz#T#TZgFFfL>)WID%(KvB1ff!(>d1dbShL{amUn z!xp2ic=Eml3Q-LW-z7MNpFnU<>zE!e2XlFcI?h9r(ckvq*#w--qfuTJi3js27*O`` zn8VquSSNSp4I`3nI{NITA?(?6*6l{%q*YSHJQok_l(BHx+vd@4AHCR~oK9)~$qfYq zM87cz06^Nuz4@=()8OOwbo@yB{yH)Kr7h>Gn*y)?Y}!W&-7^83&=O@Da7WQ`fj+9PYGmof8MFH#X3Y$wwWVnrZh8psx+HoDuP93 z!}h}VN>9mH9}n(L&M}}+B6jViq)p-!Y^L=KdBog^8*G(0#g$LJ@}cWC>&24W=d$#A z9xl{*d=Wg6=JyB#2qr`kGSGD)Xif~`WO*^!(lYLPw?v@ zLT-k94(Oe2_8?^6Jjmn0?-|NQsYc+8Q7gBdG>4naKFtG8*R{#1^9=@kX^Rbxj7HdS z_%xD~>6k7X1_)<5g&5mgFmW{Kn0M}X8ZNv}^iD}{ zDcTsbnavrV9M6mnjGuJxsF6DPl`{@gZIZOmKF)NY0XNxF#B6QGrN?!(uq&^+tUP2y zMD$b2(JpT-KCS_B+chZIusIjQ9pLzo!@N+FHv|b@fX1X!sBPzpR_@jHsjCxGXF!Z(_Jm4HsB2CEcC6hUks3IrN zF8M;Rt?1887Y7@a_JY#O9vha{%agY`P} zhf&l`CI-|@D2Bn^l>N%@>?ZSayy%dguSxrKjCd%4QDYi zjY_*u2o&i%;+~t)WzgEQ_)AtbWLG62^CQ&@Ko`($ATg$=BI5u!!ymiiRHHb)w>ZVI z4Gs-e7!|Da;iY@DJAX%<@X~4)5M00X?_cMFSQFvjUe3Whnamu|@=WV=37nd1R+j^y z6pgw-S`KgGAFxVPVF~M0f*ZEjBc-IOoY&-C`6j@UHK z&flbyocZUcf5zpln4{UhQYI9v{}`7Ue#K=qohYm?@ZKUj9LXpIH;thz0Y+; zAU@lOuMO$*6M#2>eDZGp>s`MtFOa<&@NS6hIWMuEsz2CV$N+^v_(Xjc_^7{~2LZes zG`#0XQKtG7G-=U-%(fs?G=HeCHc@xZ{0w?Vcw9VZ@>XtD;PF-%J^s{KRPL1Bc~!<*L8 zwjE`jjnP*txy;@J3~kpVUVG?_S}M6h=cwth+m3TO?EDg9q=jALY+}i3;o``KclY${ z!ALrnhh>H{_P8Zu$v!u8yg(j2#_cYjFAsih20P1&)7gIUx^aEzKT}|O0sk>LOoY$H zw6s#Ldj$daSk<>EQI=erv3-?szC5Yfb)^_lPh!}cO^vUlryK$V@*-U1T}R0;D$BXh zQ(F-$u0ue`KNP{9N$lGI?a`E%UVJM@YWYLcQemKM5`z}rL*#lr^`b7FXPu4USHwmE zTScaGshTnVjw3Tle=S)sy|`u3)rZhWZ4hmv$i{9M8r{h0NNl%uJqKn$#Rqf?Fa)2d zZXB1HNUklW%bK<5kVSOD8MP`-hnc#*6gn(CV=&XKAXB0o6iH-TkoN^ELEO#wTRNmB z7Ib=-8y~=sb23ruvd44*pgSREB51HfU1#*?gKV4RVWXZ9Qau7v{g04M+{6_9tol&1 z=6`LJ$__XHs|TJyT&NZZv82lP5IaQ=SDpRgOA*(6G|_E6!@lQ4;Jy^qQ%EDvSYO)1gJ zc={(DgGXun6g^rms-b$?1mCnd^p+(`T&t#Kb+9c$hjt~F@9p86}@hvsJZSRME!fW$HD z-WxcR#&P>#XNPKS!SYPsXJCMDfCsgEfB;;no@^rCz{I^2{T1Z{pze5GD4_5Ucs_t7 z1gRv{x2(;FbshFOc)a)MG*eOM`%lwn7QjNB77B}-E*)J$;5c>ET)cE2y98L?wgx?Gn> zBFnN^i+%GH@nQT4sZYU?(>Cs!%=wvSmo}(|M+TEehA71RHaIG;^K+UTbDCTDGVqp6 zoYeZsfN-8#ae55yx_O?qSwi?cL-qarGi2SpWZ6tfC9i~k`Kr0~!bm|)mD$4SynQj1 z6rL8GH5 zM0w07>IQoF8;v*yD->PO^#}`*&*(Or?$Q)Jaayi|?0q2JQ_RYN>s!N_qVBi{pAo!t zhA3l$vW4bqO|2(Pd0&l~dHXCyFq?zTCo$~`TJ|R zPPV|vG9dy zc4tjrCdxc|n>{kihtc1-`R-J1S1~Zn-9P!$yk)AaY0}}^ZN=jnS4Nf~U)J10zKoDO zC4bw(?~aRb7J#{y-(>9B5~_#76U8h=q1#Q!5%&B@^XywnAxAJYgJDke52$&_B8d^@ zU2LQ98!gVSD>d^!J1wbcHP{ZDU%2+4N}$Vs@*5RpsbNr^B2J40_|Z00@Wv6Ah*(u`Gbe4xUP}M0r*^1R(?86s9v;}t zb`As}rC`PSEmZik?HoSQi$j6Qt%j_(>Nw5CjtwWRIODY=PXdorSYNDtyG&h>#Q^Fl zLN`IoD!=KDU%4m%3@5RyTW~z3VUKZnv)U^Y7qP_AfyrKdWKb!S^VZaOnKQq~tUp#S zRZIG@NrTVz?o!}I==hKDpK0@NIR8{pU|UKgun!e|`PlaThusbRzf{yl;|uaH6)g=V zTS?28`WZk{G(KmRyI$gqg=jO;F0FrJvAHarb{1;Yg&UOI2Zcy0>fvWqW>9A75twGv zSM7NzWu3-EO^5C;DsgU*l@%4`efWd5^@kjfzG;@I5J;u_{!?r)IGmv9*Y6kWO&#=& zI|K#vaP&y&bM1g~8zPY|o6YERel&@0ECYai06j|7MebVVyQ!C@*%E|h2SSpp5%qx) zRY4VJKXUrO0C4F$_DW4fXaWKUbxLpQjfP9`%L>n=|yrc1*D0i zFEvtHAXFEnwoduA1A$?TLz?%;TBH_PeD0tCB6HxLZIQukUUtI(Qw(-?s-MMDD++V# zCsYxRJ>@9z+!Nd-iv=p$g?L=L9sH4kFu-dEkkVFP42x~uNh(fewk&qcM>3i$`ynQ# z`G_UqO>2M9^#LJGi%{DtYR}n-^Th@xZ~mDLdg{(8NwD?B2Eh|%bl8nM*-_T+i5Tl| z*2J5nl|fl#m9a^~;d=<;UbPwDhx7I@9Ai~XU3tE8x5Z(@T;}XSK)jt>j=?_Vij&T~8oG3HMHz{+M_;HCZ)r#dlkQtTC2Ff-jt+wB_y2 zL@>v(42AbYdaS!DOUs{03Jrm0C~qMX%RUF#*i@XDlcP+t9B5w3j!^Sv)Q0~dz0>+- zU5rhqg^^zr(&~(#0+#u+uC;!_xb$geBG*m|RbFMcN?It;7L@_Kg(4f9U`TW$mm|KN z=HpyBZeq6YR{;I&{6w|y#YSN)fyfhw;mwl>PML#WNYG)%tt|%y3C$Re*NR_^ID+p9 zZ42V4l_U!8#?o0cY|Gc3kx(I#crDY|YEC0jGej2*ER#iH4^6$PM927aSTZC65TtrO zk$s40DzPg?jJhgwZIk~4$%lxpz~%s{eTb+tgsKeRUhEXig#nu>Bq`)Fh$J_Y>cVsz zeO5(k!(E`#beC~e73{J{b!uVfz{+5Nq&{ zQJH~#BydCOS4-><({+KU(ppC%vRsn5aF>85>)RRI0>D!;8OK#i zXjA^X3>?_p=?y(Q#gra!-@FZ9<$x(!&06l2g3mea!4q+oEx7K7naT?^N7+y5o*?Qn z(RpC-BxlvQozOPb3VmAaBYAW{6{R=6!rd9%X=(GZ+GUi}oUR+NI2+!IEO zhlGKo>KMgbcR}BRxAg8U&xi)(6lI#NF3zEP-XPWbf-xkzT5u=Ih%#DQR3m{gpL(Rx z_Gg<}>Am+#YI?&>49i7Q91A65*((}@z*l4ADuGi$JowlFgHfj$pRwNOth_j#*Z#pe z8+oV5T0Vk;K*j!3=v%J(#0%t-8o6ud;W_gljcChn1yyA?sWtsx8oz|osyGU?m>F9{ zhX|R~EIRZpX6E#1{`)++37X6GVtQjiGV3PX&LKpMs(gh@=z{I|lHocDE3v%*xD@ts z*r%y3oKMA#0?qtE%(oJy{gbi5d&tdC-L78ECk&BRtd6s#*l8Un-I02z8JtId31|C~ z+~bn*>-EoC^Hnu|dmSQjpTly30D=Q<%%t9|; z&lG(E1!~*&(%9bWgnn8nhq#3ijjx4h>3=nrc2Pm7PtSj1<^Y%ZUmzNPYZ_c4TMiXPkXj+ zbtZ(|54euP$CIPU0WXFz-Q{!AUraF-tC2xQa8r~;141YUn2S`a3P)`Ui1edW#Wt4p zWA7#uboXGdqy_Kn5%%V8meVz8iscWq7BHwX(?6gVsbqPA1ucv>zFM}G2W&U`%y zQP?E*f-K;BtHRim*z-%ev0@A`_nXgRQLl@d_kD44Qy zT)i>@Kcd>}_#0KHns0~JS%c9SN2-kGU_kB>tVdrOMcavb^fdGtCC~Gy$5ll0fEarU z^g51k|0)Zz{#6z<_*Yr*VfJY7%*i>k9U~*>tnrNDh3f?=^Kf}}8ZPg0>Ih5KGwuyA z7s{Y0qnW;t(-KJx7S)no%~`vU90W@f%`1Js_Y4x0*D9{+NgLp2(sF@#YYahJ5;dgcWMw%P?Ed@Mg! zXSBF~J38HC=*&SrjLazay(Gr8%oYN@-6y_bbYg|FbZmLvAqBV$(O72A`&=1fRd`$< zbbaYj{h1ktK@Ho}Z@2UGho7Ct;#v@?V8_kQ`tmWY=#P))fHqI6ygn(iFRPc!4_}Uj zIs}r*?IA0Re-s3J>1)!Ym@}{<8K>!3SU(Da6i^=p!7p)I9|b`@a#DHHyM}y2J^TWC zE0jfj3F~l}Wl%J8=VE>UVIi$b zI1Z6v;zr!K9q%QQWkkSokV^H=R(Gt5g>Ro~95)Lhx(ynP#cnUr%;tXro6Wxnt&F@8 zTXpuvOB^AegrU|v1#Ss3jBMvi@E;KH_r<+ART z$l=PpNp>5b6r-3+TAp0qKO(sUv#AX~LmAmv9zH!&a=t+3cCWhCZI@@6ELkQS>DBB-*xgwLD1vc>*nu*VBtqWkc0kmae=^q zl0|l-OxgThzuY`$ztVcleA_JRYVVHq5GYD#7EdElhD^&)eOLgrle{5(lQBWlq$TR< z5mS$I)=o{DG_PUkYh3?i%}R8ww=9HofF6#k52Jz_ukcI=xoB=IDJb4 zWKcYzWTqsT@P0vH9u*>A`=bgiF)tt5IpyMPWn$84StQ^y5In@eIC<+e_CjAfu}}HP z^-&Rwj(@Q#wa>96*je=u^!#qMj(f*rt|m%x7DczqZKk0>SWcOibWO647=_RKa)W5C zQ6b-5ATPE;7qJh53y*g&py{gGoo6df|pke)|%-wg=ri;aN9bdtd{gbhuiyX>7mT@wZF+AoEMkZkE3J#P0VO=Pq^Uix)-xG8$9AUGp-LFb4N*NH_;qug~p zVni8`ZNPDwk_U1$I*6*HzBGX^C{zHpvh`CnUxI$n4AVrEJ%vhGA$@@%eBP>`Yl^Vb za*7dxGocn7t`DZUXx`_^a-Biq7Al5a6@0CiqrNT(eoqRxr%oXy86g3!;EW-N;v6D_ zJmc`{6HWN4B_8>y$AqO_AF9LfcYm`?h2gmHDUc?a)zdfD7QPiuJ(`99E z%8#!_Pl?Q*Tn(jiEvQ$yL~&Nlx(BLkokQ@VpofJ;h5{TXfG*OG5K{y1At4D9S7GqE zyFaGBw=fd|Aq*Fp-&%KKH`>Z;%BdO+c~!`h1@>7Lm$y*2Zd9q-Yi&&L4H_%_Z6CoY z81X&`<%HR3?M!!$5lQc%MKNz?Jp7sR3$1XDdwc%@2-kMMOB7F4Lp=zXPtTYXb7_H( zVfcwXeJ-AG@X7#^cM>miCQH#RsMALFMh<9w9Ywpb27`vIBW2oV%iU^Hb>kT%b791J zDLD~K{_+rUGV4k2*{~@S?hUndkS~-DOt^T8Dlhw|V1H5Ddvc|Vj&PuDy7|{)EmSg5j+-0e7?K(r=Jzro?A_XWJ?d+= zxC$EcX{(KwCakpN<=t=k6B!Q*pO>Afio_4X6jz#yI&-HxCnqHZeqAzTNDV5yXXJpm zokl?4C}O5E+|9O%+>Qm-X$RO7Ti2j>cx^DEjFF5RBdu$>MXH#*Hto6IFEeVko-}hI zu)@z@8JLL-=~WWDWZ>ylnitlx89sh4aa>WJQ%`uD4?7|!>KS&Gv`oO*uPzQaG9@kD zxD6%L-^9VmAxI11g5D?=IcCj8l=h#0^7j$f&N3=lR;!^@xIy!Y_=HN+M`e3mR@rcK zDkYdS5fb=5tTjaUWXQUmH+!RXPW@bwt(^68Vd=?Iiql6{FE@g~ycPy5EUFUR&>v{e zcGucf;H=XnL@_FC3*={B$mNs#POsS-giXqRsF{=E6R!)}$W||cL;Sf;Zy%E1d46oS zlB_{~oO3Cd#FCU)iD-6XiW`yvn~69$0LGEc<|MKvn!`rsc*J7MfuEV)Qh70F_UGn? z@M-CW@S@!ty<}14EvgD_OMm}2eJm5B^VF!@d6dTT71sV;51)kaJ3Ll7IXy=Gg0V%i z2f$7LHi2*zJn)iXk#aRV9cb8Yk@7kv^#;`Ijx}Eyeumy;qz;#N5HYF+`-+BRRgGYR z@9-9p5wfF0m-B>DQAYRSS8nXyr_F3wqHjsb+(0mwzCo*o5oD6XGnVmdDxX{qe-3^s zqpQ|kdPV!E+C>8a0JweV&0merA5DG#COLms&{XAYR_Ng0Ddjd6dHF@<6O@s| z9;(b{j_OR}SVJ`iLoI77etHeS_H{!{@sTNE(k>moTy$_`o%^S?Zh|y;@r}rekv?3R z>uN;z8TpAaS9^2Pa0fQ@v*JT^k@zCLpfJ2#Jb-H6VxvwWn)Xz5_f4=>R^SBp^FuEw zsqqmm%*3Mlgp-e_2l%1s)pvd4K#$1ygs;Eo>IT^%ses)36{8YLw26VA092FCgso(0 zLER~=K8&AqOw=(A5il_1Hto)s%R0Bt<(gZ!$!>z#4}I2%Do&Q@^9Zn4Z9FF&i%x`b zDMsM}tq<7)uUB79tw!{&I+_DgO*9^o{3+>V1t3PGh{5LR%?<@EsUf#_2(Gb~c0Nsr z0YbGHjjjK3U2j}rWl-UusU63?ryl0iAtCI^4kAcO2?03Rxq(AD~z8yq)NyA+$1%(fq)* zXO-NJLw*JrJCa75k=jpP?h)aP>IIv4N-=sTJV^=}rxdf15;D>NK2z{|ti^8Z6e{jv z%nf1D=Mc(*9)4Vj;zFICib5|jW~>2VLhus(*6sU5$1BCi59}&Uy}j5TOSHM!E`oYG zioT~AW`!`NqI^9bNB?e-LOd95{fCS*oRH_tFyYNY@@I{*V{e?GxOZce+g@zOimMWo*Keb-USaAwik5y>GMv*EHy1 zKY8M*UA~tdC@=5qyseORA?&$O}xqeA~|?(PlS96Dt}o z?Q(h*Y<59J=NGVl-oU7V%L%(59l7AJ008KJ-@u0UdMP}1dP?3`81*Y?8ySJM$x-Nqb|A&iy3yGOq>i( z)#dm|L{DQ^(>iGxJzi~D5$U#`F!cDd>BpVz2_2eXOuP3zBW7gFogJnghQKf6gJR6U(rwCSZakjwA#DN(~VSo15y>l$V*tDdJkl z5QF4a)bC#q*BE#(ejXk1)pu3=F?6d(GUSgX^Tw2`^BDMr!WQnBc>iqaZF5AgLj#uV zNlA5qr84wM4hgI{beU(qFUynA_{o|}lH{%=w}~}u2VcnUq0{s8Mmhsc)CjAnQF>=Q z!_W^bl{bKYI>tG~F}v%>X2JyHzZ~PQhByaPBcqS@uV1HMj**aJVYAAN9P~3xSGOOu z4)rp4EEZWc+!B!4Qq|?DY^jENu0c~QboTujXI(O=ZtP4ze{_!kFDCfV(@3Y&d&4U3 zds|7ky*Fc?1B1lPTdpSR%l-J-W#`4lv6?)~vR8`LsHYd>OX_0nW8>mr&9kP>O`8~< zm(J!Gvy?-V_^ey?u!|ZOE!-2XhO$xpC}vyPf|+O0jpZ`Pc>_6-U_ooy(&RHjMag1> zT!nH!;ZIc>T$iVgW3b{Is|9?|c5>Kz)|J~ErCsXMvk({d8`coKm&93DMd01@Fd?Od z{gM>gk#!%`jRLXp@Rv1eZJ>tHlF6uG7uG94n~R(!)bYh{(|{vAG1^h_)W*Zsc21oe zNlFh@{Tb)N>Fe4qI6uj649?qRPNcrRHd7>aqP}1^V$J4D`3Bd#t}$=YwnlX%>|e|h zT8QKY)EVrrdQ4kO$8L`*yc29%+ZeliiW~8w176fA@t9{RY+O7xGk<&waa^RH$5W~q zQ(4|^c&g=mk3~C`@<$qF_K>qaz3{GaElab1w5hgaUJ7B+I(u0>Yj)>)pf-n%M~5}I zdtznot5(2v*TTp9)XXU)e;{1QWtZiy7PqdgvQKYj6B5VfELP&IoSx%(i!`C*;&0#{ znZ>;xdwN%l1M-t@N_dt#K8yb=+DN*r8=GP}zYy9;E57h&!9pfyX-2^nF*QSZeG?L` zs-vDJrfN}hA~QPbDBx8R)UlLAOab7~vg)dEDp$JN5MYi`s`QisWQP%Og)Zb6T~o`( zd>j!_cm~8W%PM>PJH=#N1%;(?)Hh=Z6LqJr>Sm3S4;qE(x@pE*NpJ#awk=0VTHKk( z`h?)lyGEVYD_jJ9CPy#H+zDU6@N`+TtxzkiFE2X=sk~~fy@+k-nfk*UZ8|s;UEj2R zKKDAcoJe0|*GKNlBNs^e>KD8mJ zVj7wG5Y7IG2AbA`$TA0wl8ij^Din$Kn(Cg!rv#)3~8M$FkK%cs2!E zN3B4ug`!s_9TW%x<}6+J>8&-UQDB-QC#AHkH8HZ%p4ZGdx55ft>BptOWobx6iIQ^| za(|AD_&^%@JTYWzVq`OE+US77yX+YcNqsj0kSJ1wu3eLzQkSB*>asH84P@x@z>uwg z)@^>M_Qc>_K}aKFPU}Vf!f>Qyt;h`2Z%LY6E8q-`5{Vnij(1nm z9OVSxgZVLVW-yz&fse3nVH8B<;EGIHIr%cq_fI<8mO>H52JLxy+6^5G*)zclf(wD5 z=+d1V>@{?BVWb_Cakf>ZC*xfiCAZ~A!RPaNgs=ju>^Ok2aF&H{ zD^*(ju2});hcvn;S@vZBR7YHm^752CfUF-m3SVO&?!*u2O)%e6j_IA6XinQqI(8Y} zLkP5VvhKhGaiH&rS@WiSa;B7U?D4@}5N0a4@$h<)^S+M()9&VXnRMq|fFcHvc)@n< z5dNx>Q_47wMXMPWOQ(t z!jDs7U%%tNeHZ>&{Qd1aKtK43(ZIBiy|o8p47-jZZi)WptJhJ7zYO!&g?HyEZ=p7? z>%i;d6NQaBynOW3^4rZCb1mIHW}SMxNjo53|E^`ey3-&ExqF@SOe>2KfkndWuObpX zFqa(TvB5QFBkO_&qbVv@L=|r(RB6}x+57{80`^0&U+;^5BsPww$1BBLrd;QgJ({HsyvfYG`67#DtuArC;zYfLJj(Rpv1oVcVeMf)Na zh;v2;6y{29v9q=1)p{nKoljJm3>D`O2QjvxO>TgP7FryJ2^#Ld^oT0`A3j+^An2Q*Tq?tUivYU;fgG7R)ct)@R1?q zm_uC4k@i)JEAU<_G;N^65-Ag zc^@@k%No4dC*aPkXaf3YPRf*cVo~++=_x)oEdOHR-*VEwdH9`~{$e3=@)rvrQ#uf} zEM{6Eq8~IIDW8Br58wHY`xA3NKN{z$+HTt)Fqkwc-7+z@Dul$+k8yCCu>y96!1CKfh z0}8d0I}`lDtZT)vU=EQpPf}%leFt~(>?QB$cw#(Mh{qEE`(vn|AyhA$*!TAF0x6NR z7XL)NjD6u_{sQo?aj1_E`JX4tKmGvl@#+8d^&jTU{{;ARj`=UkzX4`HPJeUui>W^i z|D5>!ZMgHX!v8k^`=|MzW3j)@Uq9+a|7HHKA=y8z{~Q+mZB6{~-1(2u(Las<9EJRC z?EkT$`7r)H82P8^pYv$HP1zv+HvMxt?N5Y1$BBL;w0%rwe*E*lDgST7MStS_IePOO zX9@Zj&VL)k`4i#KCh^}0wjb5HkCps8!mn8UC&Hf%a=#H8K6ZtFApDA&e)rnc%Ha%SqRQNri!IAX zAaZ0Q8aDw*Y7m+~_i^WINBLbwEO|40COrH@=6gX^T z-m|VvxzoVo&jf>EZZu^c05>KKUAhBXpseUPo(oG?XlC!Z$mkZ%HGObQO7WqYX1XTo z(Y7_I#~<4#!y|a9y)!Myc)2d@m8YV+76`}vw(8ZI#C;fp5(P$);ZFmxX^c4zN_Txs zC@B0}PyOZMktO3p#ib!6`_(IZ2STCiczt;{s=lb5YBDTtnCQ|Da=cRmXKwzQx~yT@ z0rPW`d_2V8Gz$NjfrspUv45%HsgZwr8h#EWE&+bc7Am=hiRA-Gs|S==ePzGiCa^3p zyoS_T;B)!&t)PMDp66}7AfDaMfXmIk_1@=53#5U=)rtK-*9jxwPkQI;%1#n8+n|duZwHYA z&k(txYI{JzIQz-F7m$yX<+h74;^)`WwKcO~vCVm;7ZmEM8oakV_*~FU+zX+l2P$Tdse>a}r~H4y zk-AaEd;SAM3(+`OQB8DJ5Sp$^fzJ^|lI6FhgXBBq^hZ}jiw@&3%G z-dk_M#hfSui;uyQpxtNw1pfcTNle_NoBs!+%by4S2PY33dUty#Ya@Gm>wjR1Rp?jx zf$1}4a=W+~3QBl)pTp@OzzObBh`C9UJQAfw?-S}f!0{#@*iZO_xYd*juiNDL^0>RT zGkA_{W)&+oMa$8mRmh;sC`Y3C@P?tgvklNJMtjK6=m*76Cu=)eKb_XLFpvx+u~$MXxO9jpcE&C zI}&3uq;Suc3L5(F7#SG`T*aZHk>$)IRKt`^g-99>U1!rxi{K?(UBk3FlOts~#f7V% z^)p3U`N3@GuLu$&@)ZtLXE?%m)tiyZ?S@F1$ZWX3`kz_fci!Kp?vwbH=GX4YIKBEG z;P>EGcpu#T<{ciQIOHsfzP{og%}q|ZgbWL5iwp-vx*KeI^`rZdhN@+e>N$2UZ*w+$ zAAtXfH4T!TdGHT$-Tp8a?7y*gcJZ_^b^ZtGsnjvM4F-fT{m@0yKI_;1S1t6s`#2DW7}iLD~+hA_4bFjT+UM;5iK95~dty z)!`R6M*hyeQLYLnswN{wJ;vzT#LGw=dZe%kbuwiB)Rl;Ybcj6=FX5`Hcr8niq|cKf5crj z7W#f@t?wj$w$b%7x~`3ES9bbpj`oLY%;X`s<4S_uuQC=M8|3$NYb-I?qR_O#Exh3# zZ}kvZR>;CtdP{Kk3#%hRs&POtbX9$9oUYFRUEc=>^6v+kW{=*BxqWI6AnABI0(WY;4hAg0U1`;vw_qL8PZ%`RaJDdXGBr_lak8{C|5wnasP)?|2>j4P$_zqy5JE-bL%<+< zAGk)jB{8d9#1@oYWH3b;Dk3OkId}yc2N5S3o#i}9FT=Zd7iKABEc|mAsWm%9W>(9ky8Bkg0XmlK%E0)9SmhOnhwbI6U*i$i##hZb*dwoZp@xsmN=~ME zxs~w_^!Rcitn{UKv-}d|_i_|}Z?Krih%)+-oqA%~9RqXp&+#KYD@l+@x%W{P zFmk}DGxX_)qns+ZyOQI7k$)mOq~&97D|b|PF4CJQ$Rqm62>V9Z;)(=_W$^CY_<{rw zi-1o}zF{Wj?X&R1iv~p+?r5dzViA-p2*y}of@e~lF|!vT%%%9n=|_5L9CpYe9F12Y zsD*d9ry&g|ersWuTuF#ZfoV!DXvBRxDjX~{rbbqV#p z`tARBS}@b+P$M$UtV(_ztQE%+;i1%pL7t5KAfgDZO3;2TJSh|U7K90gy~7!Q;6ozUtyyU?8ds9(RG$H;;c zdFiigrX}X2OcS|H?yKJ)Fk^3lB^r9Qk4$ctSTbmDtmPFw?}e0hl4qC^jq0CEcr>m$XGSi=slcFS*Vk?ffO~Mh7FrFAp4KbS^Zmo5&Ko-XCxRLsx zKb``%Z03B&-*dG9r^>~KMJ>?mqgDq(i zMh^OmvqwU5*s!)70@1gpT=XZlvr$0RRqB|C=a`e~7~6rwaY& zVE#wlE;Xj?u-OrM&`-GQqVr4F7voH|D~kJ4_i(IMf^rV!E}e=)+YiHvY{tmhIZ-`> z^`d$L5lIBjho`Blw#$T_)aTcgE?5}OK$Z+e;mpGhN9@hQJ8wNOm|bLwqd@Gvj*b$; zDV{|UZuJ(tpIpo>w}hpT@es&3Y`uspx<;z)d)IET{qiJy(-HEB9R8>d*n9a_CxH!* zUoWJWnID53Z4c>%7#=Rz?!g<4 zH#-wi5@R7Kd{QX3x4y`|M@I5skx2JMAUn*(Y7~htTV4&**KXb*i}#>Ng?M3JG@u?~ zGY?yP;Hop(XaTqiu+XkZQ=g>Qm8jp=cCbS68Lvlp@}1#_(aTh^j)~zq9t@XoXb`w? zTBi-pb5FbLBOVhoD4;F4{eTTb1n(7UtXc;f(n0P`6yQM&Ov}^hT>gMeWfUS)c`A8k z%`NcDJw^MhDTO-Ak`rI+=~z)=LYn z%p56vJ6wEp5OOx25h725lQUj#R2e=;B9Vpn(MW(q1K}zdL!-oW+tNDYRoh`2?mh+b zn8Il^DGZ4QYSPYT1O(ld`E+-2pkc`{7$e`MVM(hzIVS_z9O~Wh1f>EL6k+3du<=}$ zJZGZU+9q8Z4xA--ubcCvw4_lMbBTq*fyhwEUP=lLi89iH8@||>NZhtx1n=u8Mtu>_ z5d{XiCKRTOMk44}Zs{tnOJ|H)>vc*MG~D8pq!0dl7`G~}W9;3gi67qAiy~$XF$hg4 zkJdYdceZ-TMEk@aPjn(M`PmLQtyjZ9wO1m6N*H{#o*MRiC?nuoBcvC3J@HN`VFG{HUV4bg$}b zNutHLQ~XnGistPS^ixhL`l$n26x}ohpKiHtp;K=RpS&LC=5*$ltGVUEW~%`n^{FmH zHq9&m@QVq#)`Ib=eC@IAcq~DYwhjQjz>=Giv^T3H-@}};opV=_%aOzp~#EFf%PaC1q zFa*J`l!aN~MUnwF+Y*WH4B~B~5rg!dihvn5e<$2`oFMCCk*qmT5w39kB6s%Jh=;W! zFR^kXOBqyFs@$tuDR>EkEi}f$VptMja-Y`#>D*DgLYur@EC%L6OKnm1W%uyBnH$yn ziFpZ^=xm|qV>3rm03VX{jBrVz{K@9)V&kKmIHcs4l_;P_Jl+;@1G-}9 z_#sgH7}SI{D|&p(URRdhQKr|Ha6yjC7s2!jP&7V?W)Qs{*op z5;?v!Bzsjysp`@-!5K5af8J=HKe@H3T~`vI>H!p|9VT#%PkXlfKAWxm7VrrQ+=vg2 z!9y6<9<;9n%F9kY=ka$D##HeP!JK*Ngo<`mAG!tdff4YOYL%##c!&pOLGpVE2}DAQ z&xbsh@AcwdJd)lA5SUFvA!HJO;70)?O{i#j(s&7xyaz0X{u+W1b%Y?XvI!|O`gz*Q z$w~P1lU|prYNS~tW0j!Sdb`#pzLdb$z{USL60@9I6K^_7)saW0H1d`1vpM?Il}7Oy z1;TM@GeB6x{F=45QwRkGR>Yk~S+$GE0SuqY*?37JMAT@}nN`2m)U%diEm@7CNTbq< zNTX%2Zbc~8J-j}RHBV<=KJ99Ccn1;o%8&TH3L`cQvk$+%qR==IeEaL>fq^Lwx1bkj zv$I-U&n{hNedL$Jp{@c>*D06oCCC6VO`O%p&S3a0{q5eNpwGpi|FC?{SZUJxji3J= zW(?oLG+*^Nx>jZzi`)_nm}h|38(=OJF#5fF7h!pJG!<{_X7 z4i?oF)<&obI|Dqfc$`*EUk?+qg}=6zYH4Az<_vR>CF^HFIJ_fp01+v|z=$T70A6%=-M<3)Wk=)kVG?~% zgFXbn)5#M0Tv8-=P(-%AJ*lsogv8)70&K!EOy1eHTnK^W3k(T4stUU?56=a5=IFE1jY5NQ$cV<5!urY( zBy>r*ESdT}l1SukIGd5)6tIXAQ(^MpNQ;Q!E)MyS4&X|8)R_QKR|A4T3UM-`0itn+ zh;*nNv7aBxN~7@upfZIgV)JVZ>f^SavMBcNs$bq;6hBZBuN{3(2Fc$5BO!v5#s*&8 z$-jWfz9ZsxAA59fhEt|fyks{vq+3o2AR=y~&jf~)B~zq)ig9LFi9lqmM|Oma_;WY2 zctQ^SFz_t}--mq@9`{x9*;$DuHvGA8p$V*I1$y9%=l0bQ8EC3|-wwRYgKu$OWz(l8 z-My~&_?jwxv!j2d{cz;7=;Q(S>%U@v4YPpB+jfE(Pw&#FO}mUd6CB;YU=;CW_!t^^7Zv2E zaL}Q&gJ>(5Tm|;&S91#zc$`Bb__38cK_rn!UXA>%5th^w(mJ7MgQ2e(7xHp5TR>*> zZh5Gp85?u!?x7i|kXEYHr9PBcC{ol)B)F^${h5E%E~N@~X~dx{9|^g$q&g)tr|Ic} z4ZB&wNiXzyDvx?VMs!s*=Uv?#wZrNAG2;5&w{vw-+Qh5Az4jGtk5$f{Qm5s7H7w}6 zy-mn{8*zV@NX|_CJ$ta8;PN$emqD(o>o1AzQCh`WNxe*Xd=)~ZoSc}r(WPx_>S_C= zJGl$Rp)Z;M-_WI!g~huGJ|D14+t+ns-$8m%0WW`6;E>-L_MHrJzxA*)1Bc!kK0fKx zpho2SU3hzAnomSt8pIW>QpkT8w3VZwyyzMTvk)yTIup$8jW^#?BxN z^mh&ME5c^0>?$5y!+>lA-|;@&?Xw+Gy}2mkv;&i*#_eIK9uC(u;BLECdB?BX>w7O0 zN{lc>3p&jmSA6&%1{?Z;)d+Cnbe2AC{rrAJuma zc{86XoT9PA^WY-eMlRXsD}V`eu2HMGn-Tz^BX6gt{>u1It`PZ2xo0z{gxvrNg}Dqb zyB+80-yvKFCae~`O1}=YEAkS%Pk%?Z_nkjYST0QHPj*+tzPO0-Zsh6mNJqwk7+RrI zgPKz;T!CYNYS=i|)P-v00#Ga93*TQMli|WB>(Fb4v;|-zhfUuwD^S_2M|Fg$p`j>`l z{=6*-gPYePoHYiW)Ud!0|So?XMH$RUc3VVxCQF&}s(y8)@cn}DUgWFyg za-XZK@f5Kf6Pg7jwXhS8d-vWSW3L3MF$^kQ4{{Jd2((#&+S-@7Zr=H#!bpZJB}PDo zxA(*&F5ggr`%&ET1&B}9s#3}B1bI*bd?5oMmhdE{p(mh!^1+V6BE}H?X$DRRF@!}_ z5XP#6q3ww0M@;Q3e32sfjX~g*tjJrRk13;2o%biwf*=&hw;RN%Tr|U2?4_c2e`S8v zg{ypVTtU2o_fHo=h30pw4uPt!q!QjCYhpPG0aG}mAJP+Hb9$YX#N)NNop zwDsI5`8c*o-o#XqR^A4+bDGty$+-;s1QjWnfVa+o)SbUD&-V;gC~}RbHO=q8gdQ#7 zG6G975xFt6*)13@bOx$(A;`7o*#}nnT8dtg6Tez8UqcPKPVuyn%HIt*L>7d3kwGSi zapSH?cF5=x^^^YIe2{YH^2xx>J=`BkI;HbS=aPw2yz+ViCZ7f$0+fl5B_u4v4Gv=HD~?yVU}6x$;q z5}JtF$|nkJKz6kjWS2K84%-~JYm~;Ul`-iNy!_hd&avaw8Qhd2`02ac2vNb$Q5e|k z=7$$rN{=EuN>WcYZcdo%;WNfCE+{H+aGwI>pLv_;9XFpAyAe|f0zCmtBzR~W(`r&F z^~UBq(^u}(iO-1Qw51rZu=%1SA5Yc{GBmnj@h)3&W^?yw^u z;P^`haW{MBVrb<%5jGkbICKktJL>e%9%DT_1Thv!Xih}tf)$ef;>e%gE$fmFV<+Dd z!QcV`Oo7@cb16O`7Ue=7sbh?nhFrH_q##T{4IvAK1qXdpC`?4pYCM&uav?Gp;4D&G zTee+HbB>9BhTprNt`3}nea*Y_n-EhVc83^LejpZ4nU0N-rUI?uz6Nz#e`-_VLLdLp zE9PSMUDT6#Y3NNDC#S?d9`JA++{DSsEL!5=p7ISY0XpHzC>3mIE^6bgO1CA`^jlx% zoJS6D`Km8|qsU&&*I7xZt{}<6n-NDyqK87FH5nPP0D z#q2xG2GAc)_1)vG53=j=>9I9yDb-Vt)$6^yfi4WDj$7P)FJ4C2opnnVOHi&83uvr& zHUIGa(BTa;-I?W+OZgjR5r0E?|MVeHvDG{$_L0Zx5oZw{z<}okYC0qMaP1)r^NpE6 z^Y3__wYhO{w>TZ&6Mg_-1tC_7+Z}^vOcf}9|9#_OzRcWRMwB1O+`wV!DSE&gz^^HB zi2OW`1;Mqn8!%`Ko@_p<1qFWP0e6HKVB|O=4MK^dWpp2ZbUN+={T|-^PCAHq z_J69U2&WmtT4pFcf=9H8Yz5N`MP8H%?WM4SP!!YVtg{#3U!rXSVl?AeoY)6ySP#hp zsWHrEsiF~ScEFB0NhaY9pdG`(I)e)8wu42b_)__e`p;BYO8r0uWpt zDr2<toB9T&E^+@S{z0YgWOpaM@c(F(p8*&a~74#_v$6U;W(EVMIu~(RayV@sD zTPe=)Xt!UWZxl6>Y~Lo-8elYzevIFZA9W>UaU4@42>`)Epy&o3M`f~XT-2fc%EU_~ zb-7n{KeZZA#o~52Ij(jK@?8o>9-z?WIW=zyxGh{QzJfIWc>U%(``?yY!8t&F>5ncp z5d5FI$oTKxcFqZz9mV%r=38*f@NLn=7MZ+0dWvK^#4uBU43KMq-BZ0~$)Z>^5jTq* z3vV4WcOBlM)IXl7095LPzUsS7eZJ;W)&`ocMNFChv_ z?>_1t6dn;TBL2>8s?*=z*KSQ%${5dxjHBEW_;**<;|zZ%qDnAasu%e%pkRJTrIo@x zm)3~tj=EsDh{jZOx`Tx^B&H#(>e`cV}V!L2jbp3VwwG8BsJMT8|$AR;|8 z(6;#7#?b60vG*cPX=ky2=|>keC~5NX%vfu8U&Tfl?70E=oS)sZ6{6_iC07v=2TJ4~ z;)2eg7DSvBmJoCX)~oC05E(ev$>2LxkW}yc^q9>Z3o0H05KDh+P+*dNSp?wz2&47B z!HNveoadtJ=9PR7Uo4^WtO~Ocv~MR2mdhEtLo?-{{?rFq#+E!<%de24W?L!0nsl~~ znN*Q8L=3p?2ZaTW{-=bRxEk_a68ps7#Fd**W=y+qlrDiW{xR%$ znCGP6y{{X{8~z!3}0JEOzdL-K^?~nbffx0heY}lc9VnfL{s|m(4-V zgo~RSD1-qB?#(w<+(q-P5fKPX#hK)i`L@7UwiM=PZON`|mpWC-!&Um2Gmt*yw_DkE z;@LBsdjDS>UF-~sr=+ZNQ+4+-+2-8$7L1JGjglDqP*mmMBoOWr!kuXRMw*gbIcpew<|wKx4@r^?Mjhr)1X70 z=5ji&@7Yxzap}ys0@Ty~V(DD>m@gOfq`@iy3wLhf2Lx-JdzLYcW%wm~bwLIslT2tf}`sxUm={o>P%9Qt|e2Wn^E{H%<)#Uv^4SKQo@c2L- zfS+Q2=ep`&baAMi#Gy0(x%7t}!6ZCS4G0EUogb<$sjG`goSM1c!HX&FV?P4RXw`O? zz?Q4S8@n`Wn==`|^o9Yf46X7v1&^yJsV06>>zpDZ=6+E0>$0>m@C6qqKf*48<#-8$ zk!!L+v|RQP>JdIvk%ecNuyxOE*d8WGfmy?cSWC$3gSiiPFLaK2A2!(>V7W$p9=cNk zT)hx!i+g-A-uQH3{epNL>DT80{Mru<^gq4W{kDDK@B}9Bc>S_K>4fe(A`hHLh15w9 zkOGoU3k8uPm&kW9B&qXJLrS-ky1T!Tbb@I8^aW|}?|%skNHnK-1y%}1kEg{Up%3R5 zJmu`rV^G5j)TF29_tg3JA3Y$dtMf6V$;Jf5CnlFuQo$bCnOAUE8bqU}jIzDMiA-*w3#cdH>q?5>2+>_p5OHZETU0zlr7O zFJ1I1xgbgO(H-AP0&9q(_!qF*y{|vdEI4Jeu>XoIwR2jJjzdzm#K)}=jPqj6BI6*{ z*%w&=!s%J6UFAu^K)c3)LN!V_a!MT1qVm`o$HlJ*KHd> z9JP^OeHU1K#QATumIuP=S!uEnvjn)XYR`n?Fxf1lgI^xAuSMlkZj7BTM+-CZM@(;i z-@jh@P_U&X&fO!zE_!U?-{JZR6V8P!_JwHa0}$I}cTen;YvLiZUWcT2)_OP`FeJ&@KQL?ez1Up{J+B&ljD1@ve53#8&{heRsZsC8RI~f( z_WqBCkLBN{n!No68%i(ys{3w;Q7LItHb-Rls^}R3H;raY(Pd65g*Jp}1lT~Av(ZUFwQWN!fqx-yVxleQbY2ZaD(Zb889x3FvHwSRDY-2_4k-+5xk~-6 z?2LZ3N5q{#2;((tH+kH%TFXznw?}9gv{1rcGVZvGtY_} zxrk|lGy9;h5@6t3v@lnFQF=kdo!2$0XKGJIPe!l!r0y0-wj-At{K207ir0U5P2iiQ zivilG#f?1-bYvJV;p7sUx7M_Q)ihM@;3y$BY?NP}e*y*z*bh-SFH6mVDYUf!j3@+= z7>Je&Dopi>iV7)IvhqLz+mu5v;Cs}7HII&nR9moXe7I;AkOd3{JLfktGRUiubA(4vQ2pKgMR2BIRc; zmrac$mY}RbO&PH2R+_qHaqL1#ioRNxj00!EgAR548$YX`&QxWgZZI+#vYVK)JyF6^ zW<%5kHWH^56j@a4##v9%d&rT4Dg%wFsDT8M+bhG!efE;6qs6<_qi%$2O-0GS#b}ulkLguX>GcVf~EU z^hu{om#;iZtu?xgu4d20;_U1AHu}c{CvT1^o?(gX4LeaM^;#Kd&4B;dh0uMq9j~aN z_Vi`G0xkutM*7Z}D$UDNN@L9HwcL42IA4$CFZ^VOG7Ru;T11f$??FK}d(+;awbtd@M`IY+OGYK$+H3T; z-ZrUYt}UyAcj86v8FGG^o{2Aw#o>GHA?ElS6t>mo*Ms20U$fTQ59{|QfsM~XGtbsv zvJtPUy>7@#`Hg;%d241jFksoh!KE{sakM6Xi7A*|_ZWj)Lvr?EixbZ$(MiAcRHMmk7-dl)6IerSSW;-y+w?AeV?wX#(72 zyV9vS2nwB&LD)k^DH2ohf#Bk7jD!z-STDRlnk9FO1PO;5MctM0T)m~KQZ3h%YgMi5 zum?&a5Mj4SU;{O~z-5ehuOwUxlR%9Q4OZ@eY{tRKcPh3j7#i_q><|^NpJDf(WPsiz zD9Gc=!zvog@6C6PuXzbsTve!{4M0!lfQh^r)kkN|TnqKSY&|6O2-!6aT^o;q=H0Sg znJehZR(Me~ODD)3>(N&~2&RyIUKu>Tm<`YE|C5iQU{kauei{ucod1)L+5SC%n{wJ< zL+EiYx$bjf;$12s(f(B}HokhtkyM`JaY2%E3QHsi$qK;$Kq1Z9JVqG4`398JC0LS# zvrcwOtzf@61W&1$iZoJw&wdmLgw_Yt`SLUn)ZylvtY9AzN|N3D`DQis%mD2vqS1S~ z)7{wGaO$l@h(hS^Ld_A+uMQG@&^#4xT7bPS8^*Sgg7Q5recxIe;#oKrjULV90a$o`Z~V`^YfWpri^ZkWy(E zkdvUCrit`#1G(TniL|;P_Ajp?+qxy|M|=VA-70ypU?!iaLY*iir%M zjo3QwU50k|kZW@hgS98aZm;P#FX;-#AvMwNl|)Mt{aj4f80ADWD9Xg^vbnnQD`!?|F7F0OJXE705X5XwVgP1bXg!b}T-D!lhUW4ES26 zanYjYxN;wOhbSEgjZ+2nNda+}y7sunxpw}Ata<3*$q4fXak(NcZz{IckA!*8*hE-e~_UKTTbF5U@eJxT0sH<%XH7nbB8;w@>+;BGFtW)3!*oKrEt7XY`BYHVm zXh6bUT^NGByXV|pOwpCA98~&6q}tcfFla%Q;3Mr2r4+VFry&VT)r9dQ2uVQ=Ls*g! zVmKONg-M2W7xaJzRwyohj& zIRo0G6jz$o91kYdjtH>L`Dh(O#@=GM-O*~yI15$dVDXcw<}Qs2E@w3b_+D{r2kBf! zK?&=NN9&6U2n2;aAA#SF8FvQZGUO7mA8vKPm#ZeMu`zGjDVzr)06nCl;*%by&lO!24&%c1NA`=VW*Ed@iM;r9r1-TW}9mLM)8>-VzsMu`IZ_jktA87 z)-m5^RcztHOl6>KPZM9w`Pld>9I^Ohv1Wlu1Z5dQ3J64&;hl7ug5VY)CU+n+GHSwt ziamD{-)T~4P73*!5se)r!T>cf5z*2rB2s4oE9Mj)LJsaQ)p%~|0PiMEX5(21#Cf4< zdE9iQgzPgDEaFqSX7Q$1c7KII*Ppn9G;!^lp))@GcMqa*%U0aFejhEq5W!h zuhV35RrH?l}a0G@Lgn1Eo9u%j^O%q3i-xMyW(S}|z_w!_t6}mkT z6D>kW;RXgS)%TB_gNogVxwsbkE7dJOvyX$BMOO-@%mSQRDMqKq#aa~fC{q zEhU+0R;ttqI?2Z>pzF7T_`NMV3q)udiAvRDU?jQ?O%|bKS?=pL|sp9?VmGGi!pRX^) z^k( zqiOhPwE$K`sd3q{oPOSOBs^R|uDgkWVjVbSULJat&DejTACmLGtsgr&>JH%_jvN*;UbzwKUKQ{PY{%U$RfRyT1n|8rO4h{cQ;#e^In@W;eg@rQEuj$d%wwd#>VL* z>Sx|CxXAeAciT#*0vp2p4IdHTQrj)O2YxF}395@Yh66rJZDpcr>a4U|(j%le0)h8C zBs=XIrT$_i$#sU9BTzg9{NrIA4~_mp2PxvfxPT?&VypH|8qf4Mw7YunqSj$!D`b}0 zjJkUxr9k-pq0IN(}yK5a%W3K{&NGfq^UGWo)j>u3@9w}pW1wKRiu zDhzWi<9j1iv>Z}kkO~aVF-&4B@cd-DF$9ZsR`ZbNZM&5Z=h*12N$V=Gwotp>dbJys zB*i0pt1bP7DLzqNy{e}qED`}|ETEY#6R}RbNo3Wsw0UNQ3#Tk>4Hj0EnO=Odm77)e zs*M(Bl$m0I_FURqcFfTw3BN6m7ar*CSk5z8rZ8eB%KYQye;2Z0T7ZE77*E%rHZ}zm zr$qQ67mK4=wqn-5SxKUKz2KqyYM4uyX(-~CTM7)Xg6W`p3k%*xJ~*KE*ONwaY9G&7 zHpe%C!m4b%k@P9($}RVJeJxb}m7lu}HXnia&? z@AZE@IVTms1pm6d|J(chw1gBAMXcv@e>h_<4DpHsbtQG@=^0D@?J=PNUxz zi2EJqm=U0;g|&+CY+hPr+#$((b2;2)1DXYW zwoVp81iFmWC_?G=(CW7$hPA6y7xf&6U}|;+gzw6R*x2N#AW6a);@yY|4G2EcGO$TC z#uWWS3C#l~xsZracql@42Ga-ewtlm&_2?)YqQ2~KZyI<4B?e6ss`Y-GlZKx#*wLRy zh_2yCk71~1Y_6LZ28+zdhEE+Th4WLxVg=saL&u=JdqeJV{BtSGVrFCXxI+@f!veJ6# znk~}hreLN-ILf-IU{S9pG}_miinAm_F#CE1H)1c>vQST1nc$j`nVA#~upl1ZJNP{t z>2!FAmPF1F?cN7*r?gSH?jfh=VU1*3WkHD7KT1mL^WxJ)PrG%Ofm-5ZdO2NYS z&bHWj<+j+0<0qp`S?xWVI(^5`&@UrwbJNSrxcep4*6MYRp#z_Ql;{V14n;*nW~1WC z74j#*o!~CvXmxyuiZStOO-FqgxPI~KCRME#wA-G|KzSjifpp{^_b*UMnq{Y&mQxMw zaKcgq>)05DiP7sNBH1|8$LJd`F8}j(PHc(Kv~)gT*z3Ts4U-shnX!4Bf8Zs@e>?ZkR*G$ zu`>~|Cen(|`zj^}GxyM19MY8x)(?2-PSzCh}J|qOQ zs;VhSv^<}P77$H2l^qg*2Z+FE#ls7#M@AWCz!S3;TB40fh!9MN!JM;V zby>?bsyRxCY*NA{3kfhZ;y&xajMwgWllv{7L7U?=TM)*ADNT|BF~vBDUt=;4JiC63 zStVx4GJOE~lYrk~L!);5ffl+mazi{mveG%(ObsArthn*c`Q1JhJ(&rge*~VHu3iyc zgfU{hB%MR>TGK#MNo`okh=n8m^s%qPRHb>M>)!=~b?`^5lhMiJ2LzWz0bgJ*{IJ5l z%iuRy7aM_r@ILHkuaq}Vu^->|RP3q>xNSjB`lB70v*&rlP`sEGK)h1VH0s8UcH%6p zStp=0kuD^t3g1yLVo0AlJxJqZ3P6lHDw)2$Z7xVaIYSAgPANbj7kjxIi}`iwPMzS+ zK8O7ahnJQ~Qq=yJQpjy$uhC1WWJ%Q^g(gHnw#2NRdxZ|n`P5oXSq9uVg~f0cTNYy_ zRYsfC1+bea)$-5^lj8hdUAt?tju4E z<~v`|wqQ`;Gh5I={}HAbIA+*@G6vVWT(q%O;1u*l9Ex`I5Ws-QWj8S@icoD5v(>T3 zpAAY!Zl!q;oLD+NX4)Vv#b?9|ns*$MS(W(x=rmar+)AugYN%Lagj|u^$qvWKbLga} zNiW2efWOezj0jVzR99MzG*pJE36m`V(<0Xx_g*_5MH%Zd#7U4r|?OYmX&jGl5nm4YmxjJJs`OCGh_(S}n!?~JN%GX21bb`z-1 zKp6Szw=P4h9_6IJkZ*l5f}yVLx~KVc9t_&X0~5XOsyM}Fnhx^4BEoVP20rP9Z|N|i zzWI}B-AgNv)z?H&9-rxn5;nF*jjt19e2qhpMJC$Nc=q5D5;TlD|+;on)DK4+K3fD)!Z zbmwa=A(dGmz)E|@V!7^B&lg}SQwPSz&*~iBuiE%qF<``Z4n5TQ@^4U1fJh zB(4poMS*GfJwFg3U4lf&j@a|<=v_Z3flY;+Nj*l~b%3=qSjiPwH*YQA*1lK(OPr0V z92R1cdK+{mt?FdiSRNFFh5aXtM1a~_=g{QX6Z*IGF3TL|U$ZUKy8A-$HdK{Szt89j zMN29Sed;F#2TLyGT~5{~3Kue|txnXDjy03zEERgjaugC$is5FzFVn4z4epo0`;S7C zj37BFLDa2?a-JvkBK)WIXO`G*@%G4dm@=xKt3$I@>)RjKAZ9t?**8z!jkr2jlkwk}$SUflH)o+V7#JC)$jq+C2YY!Dnf>|Ug+sPcqJ}_*C<@Z^HiR9WOmyT;ViIF2 znZ4+a`vEDAqn`tfI0YG{D1w~5>EwRJz$0T8k{I7=nKWtLuh4&i{%7d;bo{QB{xKdN z(EdAg{@HPIwlFpQ+35M#@vqQH(b%v%U_xq8jDs#QU#sY zr|RX3Zly>)ZtU3s7NEegt0L>^;htRgNciSug%Z#BT{D_2Kd0ip#sk;el|u8@+Q!Od z=ZCGT<2*I*$U(>pha}yX0oqGtrP7$()tf4%HL_NlRL^mv>++E|P$l%^-MZiGFYWHO zzh@ecJHr?`0a3FH@4{5$EaelOGw)&*`>$p0ZV&1IubOj@hI(D&_(Zugjta+Z%wfC5 zSw=lmOoFk*8DMR*7viX-#fFO_jxbR*Q_@sVc{UV!-!#ZDwRTZygz^6FQzZhMTH=U zx0%(A+i`;C)L&TgS4KTclt-H@VQDY+d-|ri!F^E@v_X~AGBI>n&zJL*I{Myc=$SF$ zice8uqrSFX7>(`(mx*6E3mFu*UH5lP$rxjrZ6Y`g3s$o)rtf_&fANuDtK;b(*&}6K zmNbse`0#}({vAO_ku6MUsTm0N~b>IZ-Hv_597!M z1-gF_GzX(iwcG} z4WYQ$3XQmdVs(9P2fH0bp5y9YvO6O}c8-!{>0!u5blxHFf&XZ(lRCt6KKHdkiGAh$ z55gL0xvI>Is0+UlSTxkjN9?2xS!7?YR7+Ms@y1QH1dKxE`?J@?`#P)fZIg8$wQ8{V z$$`7Vp-Z%xFka5wp;7t3#MYsiJeJl7O6WuNh< z+@L2ODIj0+()>6ds7 zwF{ga%ShXsx1UJKSWh}1^{cjVkq|qtrAhcPN6cMAF zsdb3Y;$1XDMt)GfW^b~#Ns_dP-rMqmR-LS_@iHH(4w0lOjP`Sq#SyWC)snnQ6Ib<& zhvs}oTW^?GgtMLL>4i8+g)95T>p0p&)T-KILH&vcKRJinTA1zBo>8mIM02b?N$!c+ zq}|DamiZUmoN&KFdRLpQ#ABMm7hv-s!Vx7HMKS7^ntsu`^R%X@BlKD<3KMSY`Xz&pXu2Q;ig; z4;fKmCR?&<`CH>cXlE3ZdrR+@(Y|i+>NT` z?5uq!H9xs_ImHliEJQ6Hx8-Kc&nCuO)3`5G0$PQp3+HeRp;nIZMVJ%OhQ3=IOA~Hk zM4EF0uaDn)tKvv559%FxnmkQi_-6thnXO5Wgy!tup*Ln}?*4Mscd6qPX{v<#O&yze zit%7YNCU;G_!2KXk2LkyvMCVt*7z+v!_rswqYja| z`HCuE8^7nJhx0P5+n)*Zz@lMIal_}<-(lSF`ObG3H+(VtJB%A{O8XAuhD)RWuejAp zj3Sv(9(f8a=#`f8$=9{OQbt+6B7kFm+}pO=Hra0F0Q+sS0Blwd3)ODoD3Q`6G@1cfyM};Eut!i`e z$GeJor={5mCrrkikNa%R6Rp9K-rp)*XKHvkG^e9MRGQtot@gUHC*gYIy#o~tz9_@) zC%>{jI*M_^%ctymI!;o2{5!lA<)iV~gNe90#fKNqucwm@OLx*e#p_O3rqS(_jEY9& z+I47}xt<2YnUs)bnw+<>YoW#|MIB+9cUmlAj_LC1G22bT^bUk&V>gg znekKzvccKFbQ3Hy^mU2b+a9><%}=BJB2820S}rJ?&CMLmKNK_&Jgj@H!tsN?UX?>! zdYOc^D@v(2=PE~Wpe@%R@`z4e=XMht3CRRzM`zYi+gasH=_#7B2G-IJll<80GEGN@ z=;m+@taqt+$HT~LGmI%xH`cyH+2ZfMXKDCp_GyuRU$1_D6etwrS$ zV9{V{Y0Th}0)?PM6(SslB3$8D1&A!5Wr_M z81QvoSUw|wVSpP12*qe8Oj(vpku(ZYz-kepJlq3Q{#VVrc380GDlnuFT{}!;?frU?11$uFr>HvVPK7c{F*{GFzo9;Yn6%v1cGxk0+h9d efy@46-<+}c+iZZc^rBgh42lObKM>is`02mGO(3fP literal 0 HcmV?d00001 diff --git a/products/ASC.CRM/Server/DocStore/ru-RU/ONLYOFFICE Summary for the period sample report.xlsx b/products/ASC.CRM/Server/DocStore/ru-RU/ONLYOFFICE Summary for the period sample report.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..0a8a248fc67f345ce270ec9a700b1fb213faf52a GIT binary patch literal 21559 zcmZs?V|10s`qzCJ#9rKcwkS12uMu{;!1~d`i z(2;qM+E%3wefRzedV`!O%3J_0Oc>g9d)5FMk#Rg{=FX6eo(tj8Eu0&=py-t1LsN}( z4b-D;D^mA<6X0 z-o_LZel2Hyvhm0g@gZVT5E6ZAl|2I?(6u~1JR4PisU53-o8L0hrX6H^r3TF0o|rhV zVc7!nagcmI#@{vw_0PaV_PpA?R&ZC#JwFe>1Q3@1zhw!Q+`z=}0;JUeim$%0-E0$B zTYA*0P_kYW)aikj<;-V6?w>$Wf-*7w6U47ka zT)b0igWze(1`yj3_v(^~P=@xCiucnW=babV+*v4xFet(+`?p+N2P=mw$xiVeSXTBT82ul*T5|r+` zJeWx_T15ajM`2yN#@SalOMNT}iBrN`4-nOv7M2;qn*7IospfR$v+%-iIqa{o${?^$~fNXfW@L-Jed5r9Jt)Dk+r4arL2SPR+CYw4CDqg`s!A*tBE`6 zqEhe0#t16aof@=ca>metiO5k3PaZ@cd_4~$Z6nA|;h0x> zB-cJe-aySNDbKJ)XWrR4eYskgxL=xocTy6!JcVgahaf4+Uq}<8wFODFv2`~a$B_E;!F>4xk7Hbn>v!)9J@vDlH3A^AL zP4n;wXrUR^3*r^c1eZ8vh=j*N${xCDyhdr(H!jpB`p_fb9chH;>QTV7_34Q!SRU`o zc<#CL5?IWR)HnYeED79w;Y;BAH%=W3%Hu3Q814Q%@IN@YThqDOIa(Ro*;)MqQ;htS zED!^NZ;I*lya_6b;GSXhCVO6%6jv>5$5qK6noV!ionDNX;h=6o58@6fRc_DUzwJ!B z?R-U(bP|$&X_iKt&R&u5%R>{V=rXlt?qulzI^I@KW{=kHRvSq!*3~mM@A3+ElvFp47Ed7fBrGsXyf^Mj4k#Fye-|34Qj^}Uhlc?* z@kOdnw#7|!NTKVI^(}T3AqloqW09c8hG`#aBe2OTI@7WWad# zv}q|{Ofq3;mm~~^sA*+AkOqP5Q@oq0I+n$V>@j#R zuDu?%yHOn=O%3=IS*IvX-~_DZM}l&tY?&%j)49`{rY=?!>OQ`o)fMu%eggj+;b*`m zpT3{tiU$?|;OFxX!cNW})+SE>;5(J3Ww$_&GSU-y^fG0mHm;fogAvILNmhgk33<0m zB5SlKb=X?CReG{2OShKZ-mE3yQR{R5@bHbJhpjVR%z4x z9AA?*Z&}7sJOG~xpv7>CIm#g;=glsO2LrEn8t;DRy{541MR8p(>5HB2OX$8nrc0%T zZu5Oluxfb*09**Euex@!3s-}dpJ?By+RG79W_W<&n6WMTcpws@C1bO~LW%T{orjM4G1$BHu z7No<4`_9C)0s~z_CWo7ND>2ahnre{QhI%fEFJZilroNqFn3uy`r#5Wu-qy|>_FOw! zlyVqAM^ztm{WP3m$TE0esbu|;_N)oA%KEL>>A7o$79sE1Lp`y+d$9gH7s$h$*A+6( zyNx-I!9#IvSi)Z>7hg5ol$T>jkDx-58$TqJ`=+3RLYve=$W;!|Y>B&@#_G__-;?PQ zUmG@mj#$VqYLj9vb6$7~w}~a^bycum3{F_JH4?l?hhB#v5wQ2`G0{^idp3i6X^tAWB0LgBrC^*$A;XqB0J*on@3ViC@BFs|HdS?ux__eAiNkc8 zS?K-T$Z~|kx$|eqiRxr&NPz{r?NlY()e-j7fn}xKdzC~ooja2EjxDESnHLz1E zaYVeov;>;09p1Zk!oy8b0+zh!Kk@1&_> zM%LMC2mwl@X(B95_zjR{P-rd8&xE39;*y@nstYmcQYjrQAs3S_6MBv8@QszLqaCJ> zDl_t}wj`Sy7IFhw*2sH|n4=HcblwxJ^Ua?oz9es|63P=ygzYfJnXSsQ z%&9#GKro@s!Kl{$Vw(<5hjN8FANuV+>}C25Rf7=a_c9osTDMBX7wI;a zh|giyk5f63wDy^!pUJMOj#CO|jF%m}mxuFbN|4EtQux zQgZ^|KXGBPpU(X0|3~273kU4OAL4fYkQnQ~1paS|`M*W+f6`3>%YWQM4Uwtdgsdbb zsU&N0yiF1gzqrxFU}~`G{BTQ+y*aWFcKfa5C*AQButgKcOZIE8u+1%0MFB{_Hps@i zXrICN^DRuEx>se#u0o$bNaoWyF4vStur{`YaVR-xEJwGv#IQk4IRv6lce&6x%Sk#G zW)sIb*iivZu5r6bZ!+cJGL^WNR=_Ge;x{n7%NCY5?D1mZiJt4|OnmGi0*8=`WjyMq zGRa6G6(i~)K5G<*4g1Xgl5up}efOZFETki6{+7cyysX-937?f?2UTo5&dw!_hZkRt zHi-wqMnA#r{F80|voZanXIJWdw%BY4UFfHLwNZJc>&eDa z3CdCdzXo^~t3kQOve%C!p`FHHCDsz+ zsB9-ar|DV0$@uXX@ydqFAyVvBoV9cYEK4989l@JRFSd(Qgf+>Jrkkga^TLsE03R_7 zq$rk${z0Ns;{O{Em@dqnmiCf>Zh-OTtoAyP?s%0fJ{}GRvPdAQT>Yy%jgKLLe86}L z-2sTo6EW&>m1=6~^=Jy)bAL2VFhag2NZVB5IvvqB`l2<_U;(TQxWJ-KVO_X1xT!NS z3^oCA+YMxVB?p(Q07VFIHjkJjOep&x?(3L!LD^A$2~j)fCUq4PVigB>4t+peap}HS zx53P#q5Lsjp|n7|0)y0@O5fxK!iZ--H$CPgy|k*qrPKL?CUlZtEJJ|{LxYXTZ+4q# zDhFa%Ct`}eF0Pu{4-htP5&}JRt-#BfRPjWgJ?|_(2e9v6e57#WjP6Y3-S(cUOPr3p zhK#T9k+VyX{+p>Qr<1j69TLNJJcu^o&^%;*t-b*`rwy9@B|M=H!%}KA%vXv3xUb5- z3Tl(T%*~YmXq1g{vA-cls<@|+NOUw>GpDG#8T!y!k3-3nvj!9?>oDK_o4Eu^H>z?2c@m7y`^HS$1ox}xjYE}t;AR=>*n z+V}ala(+Ccb*s`6;tEBL%<;+IM%?%yryxSHyjW$6XxzfMGl!Z6`;Fl6E~REvUJ5>% zd5RoR zegtz#Ik$vR0<2dB{&t@91Gm%H=SK$4pSm7BuHAO6N0#f5e>!!w@!)+I=zep=Vr6@+&|&q&ccpoO@I(!A|#atDK* z?(JW|J8_zLemjJg!S|iqg=)^$`v6!yziB~Q(Jsjc;heUDS7u*vQgd_|Abj6U-}Xwsb*f;aY;LRH#`V$U>GOD9Q|TK;l2T?-Ne4d_r4x zy=hEH&sbZjal;w|E>@#iAoP#4?n>S(U5=O%MktFT}*9jEU zRUvBYa^ZsxeCxL!7y%Ki`NFY{bCc0Gspyx%gXrAHxNVRJ^Qb1+Nh$zW`_lc}O|?r0 z^leWFerx1FBe2-ZmB-E#PwKH0tYn*srP1t3fS#AU1&uMEMl5&H_rfmgH#FJ2L-Cg4 zM3l=h`P*Q3UQ-)o+sA#U^6V9uXK_OLe?eLw@6A z>}E!jrI}aWeC3Y#dJX|>_*zSjk{O1EOnMBl-vH{VyNZ8iBZ>WT{hxqQq?%4be~I94 zR0NNL-_GTKf&fTRk|0II;Ox!}8EtSPQdq9urTLKPgBbFL1KKGX!~ddG^a4d>+oqH2 zv_nJ&R*vH!4Oma}mA44hQpOk=&#!bb=L0Fl(r8koDxPE7SKbpSH9~22gd$j;iZFR# z&UU6mI$uKdSC6Lr}CK(bP~B@QN#vz2#s*YnLY? zN=$*veKr!8!bzV7L@Gopiw9*E8B z)@SH-eR!eRzr#;NACpS49?ex-3f7f-ua}A=Hw;G}g>hd=ZC6 zv)~8pV9@yM`Dy&Q^t$$1c_@vEWgaIo?4T4h?Yxy#^flY2?yuMYdiWua3ad;S5MxrT z_O&{F^r|I(J(Nr)O?pt8J!6laZt3q7@R0Dio6zA@dAz)bJbC~H_y|Q@R?_ajv+{N- z!ch6!+s z`6_DDKM6nW$>q!ItIF-gk@=O2)gu@6NR>AI7oO)r3KtW%JS`rWo{i=lDAgq)E3SvK zUVBRQ_T_LV@1sK8j%(q=^;6mI0S2SVUXQE6Vp3G$mHGjOwp|q zfZ7i?cqNimr8?LB2jIZe~AS~Hl=wMis*Fkz)AV0PM)Ki zjdJ&ku5xuHW>Mn1clE>7zNdV$A-Jf(}w%qg^lR8NzLsR%S4=`i4|&q-o0e5!Db~Ik~P?k z)L%Dx4{SQsF@J4ZR6KIt$VK$PFKZ}YpXd95LOer%ULuD4PNHxo7f96PBW7>@#b#hOVhAyhy%(l z!{!;&+J508bh7i5aoKVrC8M=Q`Vy}CL-ukSXOFc(F3oWYIL%edR==jsyUQuj#?Z){O zc&m{G&`;IC&qI&6T~!b79reDADGDp3m`?oDe@-E`1{g`qjlyu`&K8P-eOXTK+v~ix zMi4-nb7W?XunRzbAa?e3H`3+Ns+>hqY@i}+zTTVoiK&hWw=u_WtEt0Q)bq`6Oh=6< zXQs^UgZHo_c~u;NEUq@$K6KuBXMm#DFxM#pcJUqvBcL5)v_neWnsU`z)#@#`!X^T! ztpX}@12rkW-Jq(H+)lR3bl|s;Onc|T*fLPmjTl(FQ>KGyPyOa6{=ZWN0^8*~2QUDD ze2o7yRbc#2s-U6ggw2BBXBK)xV9Uv!koC>Q(8LwNb>=L-EE?!g+ z$kw&**(VeXPE^#n@_4o0b;1HR+ zx|baWUQ}ku5mhgU$Z(e11x3{dl%GH4_l@N77r|I5fx$2u)___C3HR7;HO%^sijwa~7Zg<0aPqA_;|5&)Xd3n#ta3uwrib;$hMIUCfce&D(05s=SB~Pjk42mfw*up;OxQQlxC=Xf? zxSE%@Mj&V%?e!oSb>uwbdo$>HjX2 z*ucDbMStXtJWy;&sFka}ceYsdG<5fzw_tD>&pSSmS5b5X z$Aj?=jA{ld!jbF__mnTl)3{qMZS3sKGkg*e`oyWBKaJqb2BXi=$Ul zt%CN^sbz8Jc+FDGI+a)|TVye`Y$onX?%S|j*O46HjgIvFTh_(is}t6_?|MBdo6=^p zjo4+GRdIXa{@j&)WL^qrqh*C}_aJ|=O-!mpB>+ zPY&!mbG@RcvI7dlzlx(;iJ=4{iz+BNs6%~v&S2q%+2X`6_U0Qwn?$quMqoZk7`?^U zioU}AlvrA*FXr}*;5X1_1YzLn?c#6uL)11%h=FLf4Vo366!f@S=-V>%(T418`#h)1 z>Tw;zHYPE=D_+HjiZalTjYp1;G3UilEk1v>yRCF8Q8#CL3cR+wzcbYM0o_k4{wUy4 zDl$qat$>`N3r8}S8l+xGtB2VLs2A%{y0aAapP|kvEyYd`ZTnlaa~T7;IO*@r5F*K= z^D8}7-a4|*3Tlk6aL+XGEoxSj%E!-avSE`+Gc|!YKA%4x+~)>JRcvB@5u8renZoW`pf&~N`F{4* z%ZP6IXgJy^lBJC4F8cR%!!{8Jnc09hE*!0)}z)^10a^jdxXe9 z_5z~3Obn?iRYa2g(j{2BHnjM%Kz*NBKZjnKGDS7P1j!TZl?8(&{XR=KCrsCwlbJ}1 z=$t&*YD5?*ltrEY$-KhRcC77DqL%xzR4PGSQGc!^`aHoTqak9Py7ZNVIZ-eoRu_zu zPN6!TP*>=pY~N-9L}^4l$?;Dk5)8dna4`ZV!9eE)Krr1FuRTBIJ2#nwlsH@(XHc&2 z6KqMuVQ&R#E7;br+9hOr_gcB@=W>z?#K6wu$$LqiGeqK8kv3%p>Dl1kd0V65b#_i> z@EHO*`O**b>$~l+Nnxd_@NAerSj^`vHM^c#gM~a1lgv#6Im~{B^J{EO%IWViY?ovF zTflvN83wbgqP6Vvd#9$)^jNtbJ{9hdAFJ2QA@BWw6;H){(7UI{$#^|>QE zz?TxP+&?C&ch+iT=$3$cdjRQ%j@_dDDmaK?1^UR6ksHa!2Jnr!0vbY09rao>z*bv`*0A#n~=VQK?`DK zw-0q7&|^gZzNf}X^k2VtdO*`|th*WOJovMZ9CRQ>jS6FQ(!+^=k!5o{)ml5K^8qSx zu39!J-@6_6;_aE19w5-7BLG;JB2U}0@Hkg1<=lq0P4B_Pm0Zpqu(jmhDgwl6+*8Uk$j**s_PDfAg$ZL(dV#)B!kib=?qja&AY1w zKw~7k7u0d>Yieh5KoJmiaI2(T5y)wtq!Xs=sdX9zI2!hT{ld0Ig)WzX65kjF*ORW=9P`OTwOorGtbZvOL?}7JbTaFk5WOJ z0F1=SH(V~CYszQZ!_VLWvvi;UkaCnjNjP#)Q(p>pZqM7^=wadV2kt;~3}@-?Qwzg; zVYty&0Ptm5^Uk3f*q$P7i-0E6KE7N#u0d>#Nv#d0G9ZO#sR89EYoAb`XUZ4UV7jRM zkeSbfZWw-eM^Jz}Xx~xx4*1rOx7%*S4s9-9BV=x|-Q3V_cI$KR>oAweYa*kI#maT} zThg?qDy^cjcwVEqdXegANWIO4PHnj|s?IS=b^Pd@l9`#BGh-dnVWptQRp5vX47x%k1QSJUb-RN6 z7%w7@s^A+fo@Xpmc-@}`P~1CvxmToh*LV;=%0m_jqdcN>BFiJpCzz=uz)y3oxd5+? z#wvmp2yP-)%;LZqd}R2MkMY_4kEV*niXt3V)%N%9*liinaHTH!-a0R6ao$k!SyUU)$;x zlZ+b}jN+DbJwFpBWS*0v(oumT@&_MFn=A6JJtcC-r>@85m4 zHb_3g;c+9)TCe_D!B3e^gnSa*q8c;<$Ii=x2|zG%;SCLlFkgd@atQSx~);UpxbGt`%B$< z-IC!&iH<(}jiHQ2NiK1_>7zD;%nsA4AON7(Na9^O<0|@_rXEeIpMOFFv;o-k@X}T) zXctx^4s2CZkWZTss6siM|B{WH0PcO1J8dD4=dJlUGJga8TbTeL1F7PFl&O{Q|5PUC z|JGTzY&Td@y76n>W`hmYq)512k-VCs1_dGwC9p|sz%OG{%`>4zDoBo2yVhMBqPDL9 zSs!5|4TeI|u5<-F3ULz?t%qDQi|*DzoODuio~<4AXPk~4*driThOv6av>rPNOU3HQGz09^Mzw#<~F6}%coW�gptd77ZU>Jg7( z&!(}rOVp+e7eeL3#P=izYB+?1wW@DCHN_Dxv;a-1<6^7iZ-YbFFYWvE6-yrr^V&pE z(O{%q*p+rW5M9A=bgyyt$srNdo3$}&e9elNlP#s|SQPFm*TdDE>3!S~i*->fl^{1cgJf z;2-KW59gvdp5nrF&=IVN%s(y(G$YCVA&c#ajf3qxf~bAwz`+RT3c0!|q-Y_hRgDDc z>as2mzdKj>3BoT<86PH24L<60x9B1Z5~)?~ok#%4g8D^TNn<| zC_>i_y~6YfyM>dp+zi9BN{_(?PQ9)5Zk0Q>rns(2XYf9fboDYgWA+r2VjAA@00m8D zf3B;?mIbp?J}b+C4&73^1-7%y1+z0L8+&s>^bH7E7%yaSsA*jmRP^4Z_P{^@#e$(K zqFwzQx2KV(ZP-C4`%L<&aj&kAR``iUgfvt7%?m|~6K=3tD%$m(^l1^57TDJ@*ZC_& zZ{eKOkBbsG#TNx;>YV|f-Cj3$?gdBxkY^9kpSqg1R2oI~?iy*ovO|@S= zjH}gCy{rh8uCh-{+$^H1NB66 zfPxOE+O5H-M#k9UdD7FMq49EclGNI<*6E?f#_!fwyor^fBuF-l>CPhV*BfYd7@|qZ zvp~BAq;BHIh_Iv$RhXuZTJk6B?kkw8o~@`iuDohjrWh}NdQ2e3urfB|=f)=^9o+yvOZQs*0bgXbwObm-(;W4LCxKN?OQzZ)*p*u+F zAiq_WicJm-f3aqbEH0*#(F8}M>qm;WkUDSlcCyU*kndEN_<0N{&V5{MV1w_DH4qp^ zi29{tb!~{g1^|yd{y^e3xilx1Y~@AFz1fz_AW+*hS|zrNl(JIovdbS&(XPFIS>YaM z-@>#wP_W!Vw0X0vyOMAFxxfFv))spWp(2Q%_6?_>M&bYI&HCT%8?66PF!iZ_+Bbe~ z3c3E%zOhJ^>i5&W(GcoXrUR{-$Tjre_KmR=(%f|+co8^I&+{fbc@S95$Jy?{M^W6w zjzrZ|zj;=3dF8OJJ$v>6OkbvfrM)DH;kk6mY{@yu{wq=c^gKq{p<3ilci;LZd;**B zaLBYkmq5yezNG6BeB60fTtt(1j(nH^r2LIW{jyMY z)kCOcGaNST7@f;xkYb>FbQEI})FscS_$NjQ#qn6uUyNkYY6TeNU_^Oh7S+@?YeAo5 z;q5f{zo;5;lwlNeGRl=S%k%f9VRTNZ8lq*;1#yuF`h$ky zu#mSQu>hN;Wd~=O(pNp_UZhE(5gXVOC42L$N6i|224R(eltmOVZnqc;6F?451G}gc zhn&g%zce%VWVJFW&2&Xp%{58g>w5q25N5$cbTx*m1)~>Ccy!KrM-WP-FWMi6M>r7| z7hV%uz#DU4QCg2}@_3GS8>VWjL#>QD&hvRfoms823p4QpV}p=LLlqu~DlD%LJRV&EmY`7Ftu?(i;%$cLl>9!L)SSv4^M}n=KPgH?`^`Q> z;?&qZL4bnCu4TzQ+3a|&xYr}mJz#_dP@l^&e=ROmlx^P*78bj24>(56-VXk~4Ht)L z8YapreYA~PEHXhWAi0#LLeWBckvUOY^$b6?)$lre!Cg`5m&&Aa4D!n)S)Tv{hW+#F zYggb?D)194WU)N!XL*J)hVl~G2lVZhm`PnMLLSPw`GxGG`=8C=l<{?s6-F?+f+oDi z+W{!ehaea%(%}|3mp&vZ(q^+jj7>^T0l2I1at7%3+(hm388g1=?bUVek14c^r^qW4 zUXRB|1&r&aEvuajNl9qLfUb6B2E<44hWQE__`b2X3Lr@1%mFslv(JvVmb|}zRG3}4 zW~M5<)yKZ+zu&7--CdyF&lq$E0bGsr3P%67$qVzMDEvav-^&)9v)(-MUTxpIoQKeT z50;|4D?l461+Mn78P6BSDsRtyJF_%D5xqYzmn!u2oH~yHQ9@+UOS~lePDZ4#E-lx$ zGMSx%&8PC~D`8W8O0Pe24B9cXEKErYt}!2>rX_9Gd*;wiiLJ2GEKJt;wfwEyGGb*j zG-NFCWQ@tCvc>w{)AO1AG12FD|6VT~Gc-S;oD0qS=SVB-{FBnVLi@ZBNnR+C4*7KT zIEp8biLu-avWr}VEW+{CzlJ%18C??jE_Rp$&+v(TidY`?}ht}h4kZJ>H zN1eIkt`qVoO&p+xA%yt8(4K%xO#+L4a-VI=mUjU7%#IyT*+fUpFu3tzhfg>UjsyTc zs9O>*lf4LL`#Xo@(}%F+0QcfKjJiPRWptSV6?1*<+BQ$w_b#;dR)33%fmh8D@;st$ z2QJIXAUseqdtoNILlgR{cS0Iy_ce^}S546e`M-02TUzRNp`Y9zoE!iE>Ay{Z&gLdI zCUpN<|C{;C*ddEy{G~4JLifW4-^*LA%MamC#-NHlcyf0ey_~i*&Dzxh9g$3_n6C&U zdRi7*LW3;QJ*|uvVFVu6cZKgz6W& zBp9STeN!}}=n6a^nNBppVy)#oq*?23<>Li5dP~x}GOP{MZkKM&MkPt{$lhvmUtx-O zq-T%H840tvKN>S=hVw*>BTo|9ADLgdriBY<%&hh1mXsNuyfT%WRdy;3=I4|dq5*cC zT3fbEQ6&il7RL*ZbhgYFznP~nVkXM`;^hhoSuxGQKmd%Ut5F*o{fkq=eUXdB&@5Uo z>)tIT&^%x9(0$a+#7)%|@XIauhgZS0(Y=HO?jj!TQTyshBRI5tP3XUY!^?o>L#v>V`+t0R;mW<;25H5y8-)w8Mc);Zx)THTJ{=K^s2+Kz#MVE{Q@%_cUmJX z$`D+8#d6Sx?Jk?tGeQEVHtfzIUvo6JXEx&m;F%Gp|N&$SqPz>%=-lVWb0iM-Uvy3Y^d2cS8t873czt_gmT#!JAff_|H zy$)LKPS~JkmFlvN{SZvmHlOfA$p9Oh92F!<2t%w3F`*v8TS^)>soIF5Zz!Q@pd<$p zF%l0&&{lu?Al}Az)};;|WkbY=4enhXkH18}aYCiecXQI<3kEyt>j=>$4CyHp^_+DE7yBw+fBbs?)j{Se$7czcU<-t07r_dFq%h(&nUKri44l zxGG~&uO~Fv)tHDeCqgj!cm_3KFV`?rPgxq{8k3nC7Y#5Y9zNLnz8Gq^y9=8N=xR(= zrmVLY7C!9+5u1*PUR7PHizSc1me*K{yYgnarl+Nac&r*TW`veJF>ygY%pqcIm$A|q zALQA@>?MNebpaeoY-uq#eKwm=CrBqvk~OwJAXm@anfKovRhhKe&RDn++7J}256{Ph z52#4oF!BwkEQ#vajh($$IIpWNYNos_MV?X;_m8(b;w4SBQT6!&Tv zsWlmi3h~1BEH4xz4l_wuFsw6&-FZxXJeQr^*|^oNlOQXDwdzX#!uQU$=tbqW=!(M^ zgLGNV1DYCL`_NFVA-0*xRYu&y5^Bqzb@rhHZ~v62M|^e#1p_9-;>i{AXTY7HPN66@ ze29uMu|FCPdN6Q(Vt*P{G@H@xx;F#l1Q`d?k-Odgf=bXVJ61QJscVH1mLgciM9WW% z-YgNx#F;!r-FkBRU9@pvi+`o1^8&-(1cYuFN0UpB&08mLssXv3e2)NC(bws(exm;!dD=;oELH2xWsjn43Xc8#S zTIa`2%Nx=>#7+R&OB#Uufy(%C{S2o4fP*%RWZqxhH#p5vQ;i!oBnY#rq9H)EJfDc> zA4NHp6e(9|2tg%O<%L}0k$?g`Z`t%Ne*fms7B-pVLQ2&PSM#!<1ltmzWj6e&nH zDejz!1Q-(jkojoJV_VSZcE_vV>M+e3h_PTolO#_}F%II}kjxFwrWb8miCMBt=TH93 z?>kuEpcQ|hiSC44ACHf$ctJK(4Tu>dX0&s0zfVO+X3Xmsj%TW)TSOafgjgp*Yag`M zIFM9Q6IwE2?tnji>?1!_X_n}6vY@{X{)BZpI(htv;JnE11MG<(TG)FP^bYH6%|8&< zi~Zu6^3EZ8xb}D^dR+zFx*#j{*@n!~{W4-8R?Gq*R;gC474(byt!H4BFe9rz-477kU+9tLr`MHxs8&37OH~e#(;R{Z*n?Q9A!oXX%bro#+ zBrEk7`Of=y5Y)A8*EFy8qkijnK%(b;6^H0d<3XNhcxcYTz!#m+9W6%WH(&BEx6;aE z)wTWouXRc^O*-QRr80EK8ykqpmc1`5(U@glx+bv+HjAd5s!{j)ST?wm7ci{vTYA46 z48KC^)svg9ly6F(pke*X-!QQ*us4fnm$}GdAFxG=o!@EVZJtPGHnhIFe;CwoIE9g1 zKfwPT!0->&{-QraBxXNW`={ULp8z&?G;sT82H!M+yk+3UNA`}X`X3uy1-{~oAZ#0oRiF;`Qd`W?n zt|65=$FymExH^1`b|SjHmScnsEt{@w4<1owmVKFMpBZH_>4Do5j0KGw z_OA@sTB?aRo?696#I~<`bg$Z>hno#>ehbiZs|8m(|RL zZpyz>nLY<|z(~`3P?;#>&oB?&WfoR~GtKq1%O#=Eb!rAlWR@Y|kXo}jZKfgYPGr-Ql36;Aa4qSu&vZwF?H^LO_4-VJs!y41OYV;Swz6c`eBd6#z(Qxi8#+@nna5y>+ zm*_EIF+TW&H&(6o$Y_N8BpFBuKCZvvvEFfuigU<*PcYG|n!Iz}vtIv_-M_h)6WYX? z`BUks`61r_aPOb-B`0$elb>Oo|7`!^UW$g5-Oqi+7ji>Cqo{n-105efq%j2{gcXn~MU={fIr;&X6GdIF+&IPVZ`s1v!#Hok-n^n`xB| zi{_dzwmV#5hZMPrCv~KkB$MNyh!Hil;$2+6=gh`A zmixV&3aKSOY!=NxsNA!w#7M^2^ZVTDNW7c<{44dpPs z%Fr?U31&>i-G~ReptlEu&vUMmCnF6QYXtv*C>?bU5OS)+5$KOz+BBX2r(?iq1u)3`&x; zG-DOdb~5%Q4N4}VI{OY<3%k&&#|%REo=Q)c?L1kmzG1_?8)lD1Oyuuh;d2RmKRRVe z*_Vq&4|IvfStNuD7g0Wwg$qiG;thCCWa3-jOJ{70oJ*s*N{T$iS-E1O2cP27H>hT( zjE3uVkNCHGq?ed-I`|SCERyy|p>U#Gr&@$hm~l@H3iG6u7P4uF^qM>HXUo=RN>Cie z%>`|DQZ%R3GUsZd11AjRcD+4c*M7kB*HE12G1=3EK&p(i+>N>ZA-qe|SwD?@1}{D6 z*chHKg0rbqsa^$ZnO$zR zUNp0?T=hzx9D^40_JV%mHEgMLVm{G6wNy?`In4f7YIZPVUwMU(y96EmwzdteG5ygv zRv|CL_#fPVSUN}GM)@Qt7}q%`E~oz7I=}qi-cdc@hu|wVU-pw(Q{Tb9y1f~9+n}L? zk)eh$l(Cs7{k_dIaOc{YGupHpHTbRkNd*VWiH5)Ej%C~2GT)Of)6$EVm(Jl$DsZe= zm^#rfW;gzU=VFN-vxw3X9FWc5XLz7*!`Zo({^859JFfM=r1<4G{n_ai`0v|#wKC-k zUJ{g3Xa0=2-&v@~WZ|Fhl`r7CeYxkB6Dv$5i%GuH^v@)sT05bo&GALQY@qBhR+vRr zgH74YgfwLuB4PF%x!Bvk)~HFtwIhY#dbZ)g6BpB8T#m988+I39!@0TBwRjoXBf4Cn zcAw4_8{FH?i#4+@X*8TAneS`2dZ~kIco!ex!HjQxv5~DPU|d%<@a(pvM0xI`p14X8 zww_9xcI?EsY&Em)U)>qO`YOtO%EYm~cLWI`>byPZW?f6R5pKM^&?{AG*HPYi z)0R-z9+&W9eu3)ETrC5IsWVTi^50d~wy(|iw(2*D^L92m)uq*Fk?yG;sQrG7h)^V+o2>uckVx`Iss8Gw9W^^30Z%o}d;pJ?0 zB{N$1b1-$6@%FhXYH|DZqYHhct7CCt)LQmvC+W2a(ewaDTg-Q)!LCo-uMKtQVcNV` zDo#CXU4+8jmqVx_HCL3=bQ0?1zKv;PnVgF2BjZ61Dl~f`y@zC+0%r2=$OqCPMtiG& z4mo)OBs70|;`0~`K^t2xir;)DD#vcW{LGf!44FI){-*)~r|aj@1J@U< z=7Cwvs_KTf&VRzX;SH0Yux|LA_fJ?ie3k7dtQ)pk|6g@$UfUYOfclZg&j-qcMK;#QGpp4^#5xzw;*Thb?QO}#Cqd4Nu2+#v1hVQTDflfY_Zn0CH; z^{{u?h{JZIN7`cBj`5$orSEx3UhvYJ&>GY*4@)TKft>OTq;rvVCom2(9 zsoh*eYL#mp5%u4W*&vrisD>J1Gn9h!wLz9S=A|YYhJ6& za=d2Rr|X90f~KR38^1peNQ1sWK~Mkn^@F%H5CBGTEh?7)iMpd3tgLgXmkW%92%PoNsiJ3`c&(2NP1r7sV90L5UG4V?o148+{ z9i}YnOp$IBq=0S_q0nq$%K!4btA{1qtpG!e=;~n@`xRh_J6t{N!%8s3vaKF=-C>2w z5FfRA7~XLO7-A4W80ayOUsDka!@m8qR&X335FDcsppFv^T=pmX;fU>q<%4?Z#atgW NiW`bdP;y@U^dJ3eQKkR@ literal 0 HcmV?d00001 diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs new file mode 100644 index 00000000000..5a7c96fb190 --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs @@ -0,0 +1,126 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.MessagingSystem; +using ASC.Web.CRM.Configuration; +using ASC.Web.Core; +using ASC.Web.Core.Files; +using ASC.Web.Core.Utility; +using ASC.Web.CRM.Resources; +using ASC.Web.Studio.Controls.FileUploader; +using ASC.Web.Studio.Core; +using System; +using System.Web; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Core; +using Autofac; + + +namespace ASC.Web.CRM.Classes +{ + public class ContactPhotoHandler : IFileUploadHandler + { + public FileUploadResult ProcessUpload(HttpContext context) + { + if (!WebItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) + throw CRMSecurity.CreateSecurityException(); + + var contactId = Convert.ToInt32(context.Request["contactID"]); + Contact contact = null; + if (contactId != 0) + { + using (var scope = DIHelper.Resolve()) + { + contact = scope.Resolve().ContactDao.GetByID(contactId); + if (!CRMSecurity.CanEdit(contact)) + throw CRMSecurity.CreateSecurityException(); + } + } + + var fileUploadResult = new FileUploadResult(); + + if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; + + var file = new FileToUpload(context); + + if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) + throw new InvalidOperationException(CRMErrorsResource.InvalidFile); + + if (0 < SetupInfo.MaxImageUploadSize && SetupInfo.MaxImageUploadSize < file.ContentLength) + { + fileUploadResult.Success = false; + fileUploadResult.Message = FileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false).HtmlEncode(); + return fileUploadResult; + } + + if (FileUtility.GetFileTypeByFileName(file.FileName) != FileType.Image) + { + fileUploadResult.Success = false; + fileUploadResult.Message = CRMJSResource.ErrorMessage_NotImageSupportFormat.HtmlEncode(); + return fileUploadResult; + } + + var uploadOnly = Convert.ToBoolean(context.Request["uploadOnly"]); + var tmpDirName = Convert.ToString(context.Request["tmpDirName"]); + + try + { + ContactPhotoManager.PhotoData photoData; + if (contactId != 0) + { + photoData = ContactPhotoManager.UploadPhoto(file.InputStream, contactId, uploadOnly); + } + else + { + if (String.IsNullOrEmpty(tmpDirName) || tmpDirName == "null") + { + tmpDirName = Guid.NewGuid().ToString(); + } + photoData = ContactPhotoManager.UploadPhotoToTemp(file.InputStream, tmpDirName); + } + + fileUploadResult.Success = true; + fileUploadResult.Data = photoData; + } + catch (Exception e) + { + fileUploadResult.Success = false; + fileUploadResult.Message = e.Message.HtmlEncode(); + return fileUploadResult; + } + + if (contact != null) + { + var messageAction = contact is Company ? MessageAction.CompanyUpdatedPhoto : MessageAction.PersonUpdatedPhoto; + MessageService.Send(context.Request, messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + } + + return fileUploadResult; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs new file mode 100644 index 00000000000..314df286b83 --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs @@ -0,0 +1,149 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Net; +using System.Web; +using System.Linq; +using ASC.Collections; +using ASC.Common.Threading.Workers; +using ASC.Data.Storage; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Configuration; +using ASC.Web.Core.Utility; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.Studio.Controls.FileUploader; +using ASC.Web.Studio.Core; +using ASC.Web.Studio.Utility; +using System.Drawing.Imaging; +using System.Drawing.Drawing2D; +using ASC.Web.CRM.Resources; +using ASC.Common.Logging; + +#endregion + +namespace ASC.Web.CRM.HttpHandlers +{ + public class FileHandler : IHttpHandler + { + public void ProcessRequest(HttpContext context) + { + var action = context.Request["action"]; + + switch (action) + { + case "contactphotoulr": + ResponceContactPhotoUrl(context); + break; + case "mailmessage": + ResponceMailMessageContent(context); + break; + default: + throw new ArgumentException(String.Format("action='{0}' is not defined", action)); + } + } + + private void ResponceContactPhotoUrl(HttpContext context) + { + var contactId = Convert.ToInt32(context.Request["cid"]); + var isCompany = Convert.ToBoolean(context.Request["isc"]); + var photoSize = Convert.ToInt32(context.Request["ps"]); + + String photoUrl = String.Empty; + + switch (photoSize) + { + case 1: + photoUrl = ContactPhotoManager.GetSmallSizePhoto(contactId, isCompany); + break; + case 2: + photoUrl = ContactPhotoManager.GetMediumSizePhoto(contactId, isCompany); + break; + case 3: + photoUrl = ContactPhotoManager.GetBigSizePhoto(contactId, isCompany); + break; + default: + throw new Exception(CRMErrorsResource.ContactPhotoSizeUnknown); + } + + context.Response.Clear(); + context.Response.Write(photoUrl); + + try + { + context.Response.Flush(); + context.Response.SuppressContent = true; + context.ApplicationInstance.CompleteRequest(); + } + catch (HttpException ex) + { + LogManager.GetLogger("ASC").Error("ResponceContactPhotoUrl", ex); + } + } + + private void ResponceMailMessageContent(HttpContext context) + { + var messageId = Convert.ToInt32(context.Request["message_id"]); + + var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); + + String messageContent = String.Empty; + + using (var streamReader = new StreamReader(Global.GetStore().GetReadStream("mail_messages", filePath))) + { + messageContent = streamReader.ReadToEnd(); + } + + + context.Response.Clear(); + context.Response.Write(messageContent); + try + { + context.Response.Flush(); + context.Response.SuppressContent = true; + context.ApplicationInstance.CompleteRequest(); + } + catch (HttpException ex) + { + LogManager.GetLogger("ASC").Error("ResponceMailMessageContent", ex); + } + } + + + public bool IsReusable + { + get + { + return false; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs new file mode 100644 index 00000000000..0dc23385174 --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs @@ -0,0 +1,83 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Web; + +using ASC.Files.Core; +using ASC.Web.CRM.Resources; +using ASC.Web.Studio.Controls.FileUploader; +using ASC.Web.Studio.Controls.FileUploader.HttpModule; +using ASC.Web.Studio.Core; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Core; +using Autofac; + +namespace ASC.Web.CRM.Classes +{ + public class FileUploaderHandler : FileUploadHandler + { + public override FileUploadResult ProcessUpload(HttpContext context) + { + var fileUploadResult = new FileUploadResult(); + + if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; + + var file = new FileToUpload(context); + + if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) + throw new InvalidOperationException(CRMErrorsResource.InvalidFile); + + if (0 < SetupInfo.MaxUploadSize && SetupInfo.MaxUploadSize < file.ContentLength) + throw FileSizeComment.FileSizeException; + + var fileName = file.FileName.LastIndexOf('\\') != -1 + ? file.FileName.Substring(file.FileName.LastIndexOf('\\') + 1) + : file.FileName; + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var document = new File + { + Title = fileName, + FolderID = daoFactory.FileDao.GetRoot(), + ContentLength = file.ContentLength + }; + + document = daoFactory.FileDao.SaveFile(document, file.InputStream); + + fileUploadResult.Data = document.ID; + fileUploadResult.FileName = document.Title; + fileUploadResult.FileURL = document.DownloadUrl; + fileUploadResult.Success = true; + + + return fileUploadResult; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs new file mode 100644 index 00000000000..67088a571ce --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs @@ -0,0 +1,68 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Core; +using ASC.CRM.Core; +using ASC.Web.Core; +using ASC.Web.Core.Utility; +using ASC.Web.CRM.Configuration; +using ASC.Web.Studio.Controls.FileUploader; +using System; +using System.Web; + + +namespace ASC.Web.CRM.Classes +{ + public class ImportFileHandler : IFileUploadHandler + { + public FileUploadResult ProcessUpload(HttpContext context) + { + if (!WebItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) + throw CRMSecurity.CreateSecurityException(); + + var fileUploadResult = new FileUploadResult(); + + if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; + + var file = new FileToUpload(context); + + String assignedPath; + + Global.GetStore().SaveTemp("temp", out assignedPath, file.InputStream); + + file.InputStream.Position = 0; + + var jObject = ImportFromCSV.GetInfo(file.InputStream, context.Request["importSettings"]); + + jObject.Add("assignedPath", assignedPath); + + fileUploadResult.Success = true; + fileUploadResult.Data = Global.EncodeTo64(jObject.ToString()); + + return fileUploadResult; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs new file mode 100644 index 00000000000..1c55245f59e --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs @@ -0,0 +1,87 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core; +using ASC.Web.Core.Files; +using ASC.Web.Core.Utility; +using ASC.Web.CRM.Resources; +using ASC.Web.Studio.Controls.FileUploader; +using ASC.Web.Studio.Core; +using System; +using System.Web; + + +namespace ASC.Web.CRM.Classes +{ + public class OrganisationLogoHandler : IFileUploadHandler + { + public FileUploadResult ProcessUpload(HttpContext context) + { + if (!CRMSecurity.IsAdmin) + throw CRMSecurity.CreateSecurityException(); + + var fileUploadResult = new FileUploadResult(); + + if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; + + var file = new FileToUpload(context); + + if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) + throw new InvalidOperationException(CRMErrorsResource.InvalidFile); + + if (0 < SetupInfo.MaxImageUploadSize && SetupInfo.MaxImageUploadSize < file.ContentLength) + { + fileUploadResult.Success = false; + fileUploadResult.Message = FileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false).HtmlEncode(); + return fileUploadResult; + } + + if (FileUtility.GetFileTypeByFileName(file.FileName) != FileType.Image) + { + fileUploadResult.Success = false; + fileUploadResult.Message = CRMJSResource.ErrorMessage_NotImageSupportFormat.HtmlEncode(); + return fileUploadResult; + } + + try + { + var imageData = Global.ToByteArray(file.InputStream); + var imageFormat = ContactPhotoManager.CheckImgFormat(imageData); + var photoUri = OrganisationLogoManager.UploadLogo(imageData, imageFormat); + + fileUploadResult.Success = true; + fileUploadResult.Data = photoUri; + return fileUploadResult; + } + catch (Exception exception) + { + fileUploadResult.Success = false; + fileUploadResult.Message = exception.Message.HtmlEncode(); + return fileUploadResult; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs new file mode 100644 index 00000000000..d6d4217f73b --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs @@ -0,0 +1,392 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Specialized; +using System.Text; +using System.Web; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Core; +using ASC.MessagingSystem; +using ASC.Web.CRM.Classes; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using ASC.Common.Logging; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Services.NotifyService; +using Newtonsoft.Json.Linq; +using ASC.Web.CRM.Resources; +using ASC.Web.Core; +using ASC.Web.CRM.Configuration; +using ASC.Web.CRM.Core; +using ASC.Web.CRM.Core.Enums; +using Autofac; + +namespace ASC.Web.CRM.HttpHandlers +{ + public class WebToLeadFromHandler : IHttpHandler + { + private HttpContext _context; + + private String GetValue(String propertyName) + { + return _context.Request.Form[propertyName]; + } + + private bool CheckPermission() + { + try + { + var webFromKey = GetValue("web_form_key"); + + if (String.IsNullOrEmpty(webFromKey)) + return false; + + var webFromKeyAsGuid = new Guid(webFromKey); + + return Global.TenantSettings.WebFormKey == webFromKeyAsGuid; + } + catch(Exception) + { + return false; + } + } + + public void ProcessRequest(HttpContext context) + { + try + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + _context = context; + + SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); + + if (!CheckPermission()) + { + throw new Exception(CRMSettingResource.WebToLeadsForm_InvalidKeyException); + } + + var productInfo = WebItemSecurity.GetSecurityInfo(ProductEntryPoint.ID.ToString()); + if (!productInfo.Enabled) + { + throw new Exception(CRMCommonResource.CRMProductIsDisabled); + } + + Contact contact; + + var fieldCollector = new NameValueCollection(); + + var addressTemplate = new JObject(); + foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) + addressTemplate.Add(addressPartName.ToLower(), ""); + var addressTemplateStr = addressTemplate.ToString(); + + var isCompany = false; + + var isCompanyString = GetValue("is_company"); + var firstName = GetValue("firstName"); + var lastName = GetValue("lastName"); + var companyName = GetValue("companyName"); + + if (!String.IsNullOrEmpty(isCompanyString)) + { + if (!Boolean.TryParse(isCompanyString, out isCompany)) + { + throw new ArgumentException(); + } + } + else //old scheme + { + if (!String.IsNullOrEmpty(firstName)) + { + isCompany = false; + } + else if (!String.IsNullOrEmpty(companyName)) + { + isCompany = true; + } + else + { + throw new ArgumentException(); + } + } + + + if (isCompany) + { + contact = new Company(); + + ((Company) contact).CompanyName = companyName; + + fieldCollector.Add(CRMContactResource.CompanyName, companyName); + } + else + { + contact = new Person(); + + ((Person) contact).FirstName = firstName; + ((Person) contact).LastName = lastName; + ((Person) contact).JobTitle = GetValue("jobTitle"); + + fieldCollector.Add(CRMContactResource.FirstName, firstName); + fieldCollector.Add(CRMContactResource.LastName, lastName); + + if (!String.IsNullOrEmpty(GetValue("jobTitle"))) + fieldCollector.Add(CRMContactResource.JobTitle, ((Person) contact).JobTitle); + } + + contact.About = GetValue("about"); + + if (!String.IsNullOrEmpty(contact.About)) + fieldCollector.Add(CRMContactResource.About, contact.About); + + if (!String.IsNullOrEmpty(GetValue("is_shared"))) + { + contact.ShareType = Convert.ToBoolean(GetValue("is_shared")) + ? ShareType.ReadWrite + : ShareType.None; + } + else + { + contact.ShareType = (ShareType) (Convert.ToInt32(GetValue("share_type"))); + } + + contact.ID = daoFactory.ContactDao.SaveContact(contact); + + var messageAction = contact is Company + ? MessageAction.CompanyCreatedWithWebForm + : MessageAction.PersonCreatedWithWebForm; + MessageService.Send(HttpContext.Current.Request, MessageInitiator.System, messageAction, + MessageTarget.Create(contact.ID), contact.GetTitle()); + + var contactInfos = new List(); + + foreach (var key in _context.Request.Form.AllKeys) + { + if (key.StartsWith("customField_")) + { + var fieldID = Convert.ToInt32(key.Split(new[] {'_'})[1]); + String fieldValue = GetValue(key); + + if (String.IsNullOrEmpty(fieldValue)) continue; + + var customField = daoFactory.CustomFieldDao.GetFieldDescription(fieldID); + + if (customField == null || + !(customField.EntityType == EntityType.Contact || + customField.EntityType == EntityType.Company && isCompany || + customField.EntityType == EntityType.Person && !isCompany)) continue; + + if (customField.FieldType == CustomFieldType.CheckBox) + { + fieldValue = fieldValue == "on" || fieldValue == "true" ? "true" : "false"; + } + fieldCollector.Add(customField.Label, fieldValue); + + daoFactory.CustomFieldDao.SetFieldValue(isCompany ? EntityType.Company : EntityType.Person, contact.ID, fieldID, fieldValue); + } + else if (key.StartsWith("contactInfo_")) + { + var nameParts = key.Split(new[] {'_'}).Skip(1).ToList(); + var contactInfoType = (ContactInfoType) Enum.Parse(typeof(ContactInfoType), nameParts[0]); + var category = Convert.ToInt32(nameParts[1]); + + bool categoryIsExists = Enum.GetValues(ContactInfo.GetCategory(contactInfoType)) + .Cast() + .Any(categoryEnum => (int) categoryEnum == category); + if (!categoryIsExists) + throw new ArgumentException(String.Format("Category for {0} not found", nameParts[0])); + + if (contactInfoType == ContactInfoType.Address) + { + var addressPart = (AddressPart) Enum.Parse(typeof(AddressPart), nameParts[2]); + + var findedAddress = + contactInfos.Find( + item => + (category == item.Category) && (item.InfoType == ContactInfoType.Address)); + + if (findedAddress == null) + { + findedAddress = new ContactInfo + { + Category = category, + InfoType = contactInfoType, + Data = addressTemplateStr, + ContactID = contact.ID + }; + + contactInfos.Add(findedAddress); + } + + var addressParts = JObject.Parse(findedAddress.Data); + + addressParts[addressPart.ToString().ToLower()] = GetValue(key); + + findedAddress.Data = addressParts.ToString(); + + continue; + } + + var fieldValue = GetValue(key); + + if (String.IsNullOrEmpty(fieldValue)) continue; + + contactInfos.Add(new ContactInfo + { + Category = category, + InfoType = contactInfoType, + Data = fieldValue, + ContactID = contact.ID, + IsPrimary = true + }); + } + else if (String.Compare(key, "tag", true) == 0) + { + var tags = _context.Request.Form.GetValues("tag"); + + daoFactory.TagDao.SetTagToEntity(EntityType.Contact, contact.ID, tags); + } + } + + contactInfos.ForEach( + item => + fieldCollector[item.InfoType.ToLocalizedString()] = + PrepareteDataToView(item.InfoType, item.Data)); + + daoFactory.ContactInfoDao.SaveList(contactInfos, contact); + + var notifyList = GetValue("notify_list"); + + if (!String.IsNullOrEmpty(notifyList)) + NotifyClient.Instance.SendAboutCreateNewContact( + notifyList + .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) + .Select(item => new Guid(item)).ToList(), contact.ID, contact.GetTitle(), fieldCollector); + + var managersList = GetValue("managers_list"); + SetPermission(contact, managersList); + + if (contact is Person && !String.IsNullOrEmpty(companyName)) + AssignPersonToCompany((Person)contact, companyName, managersList, daoFactory); + + if (contact is Company && !String.IsNullOrEmpty(firstName) && !String.IsNullOrEmpty(lastName)) + AssignCompanyToPerson((Company)contact, firstName, lastName, managersList, daoFactory); + + SecurityContext.Logout(); + + var newURL = new UriBuilder(GetValue("return_url")).Uri.AbsoluteUri; + context.Response.Buffer = true; + context.Response.Status = "302 Object moved"; + context.Response.AddHeader("Location", newURL); + context.Response.Write(""); + context.Response.Write(String.Format("", newURL)); + context.Response.Write(String.Format("", newURL)); + context.Response.Write(""); + context.Response.Write(""); + } + } + catch(Exception error) + { + LogManager.GetLogger("ASC.CRM").Error(error); + context.Response.StatusCode = 400; + context.Response.Write(HttpUtility.HtmlEncode(error.Message)); + } + } + + private String PrepareteDataToView(ContactInfoType contactInfoType, String data) + { + if (contactInfoType != ContactInfoType.Address) return data; + + var addressParts = JObject.Parse(data); + + var address = new StringBuilder(); + + foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) + address.Append(addressParts[addressPartEnum.ToString().ToLower()] + " "); + + return address.ToString(); + } + + public bool IsReusable + { + get { return false; } + } + + protected void SetPermission(Contact contact, String privateList) + { + if (String.IsNullOrEmpty(privateList)) return; + + var selectedUsers = privateList + .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) + .Select(item => new Guid(item)).ToList(); + + CRMSecurity.SetAccessTo(contact, selectedUsers); + } + + protected void AssignCompanyToPerson(Company company, String firstName, String lastName, String privateList, DaoFactory daoFactory) + { + var person = new Person + { + FirstName = firstName, + LastName = lastName, + CompanyID = company.ID + }; + person.ID = daoFactory.ContactDao.SaveContact(person); + SetPermission(person, privateList); + } + + + protected void AssignPersonToCompany(Person person, String companyName, String privateList, DaoFactory daoFactory) + { + Company company; + + var findedCompanies = daoFactory.ContactDao.GetContactsByName(companyName, true).ToList(); + + if (findedCompanies.Count == 0) + { + company = new Company + { + CompanyName = companyName + }; + + company.ID = daoFactory.ContactDao.SaveContact(company); + + SetPermission(company, privateList); + } + else + { + company = (Company)findedCompanies[0]; + } + + daoFactory.ContactDao.AddMember(person.ID, company.ID); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/filehandler.ashx b/products/ASC.CRM/Server/HttpHandlers/filehandler.ashx new file mode 100644 index 00000000000..a98987a3f2a --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/filehandler.ashx @@ -0,0 +1,4 @@ +<%@ Assembly Name="ASC.Web.CRM" %> +<%@ Assembly Name="ASC.Web.Studio" %> +<%@ Assembly Name="ASC.Web.Core" %> +<%@ WebHandler Language="C#" CodeBehind="FileHandler.ashx.cs" Class="ASC.Web.CRM.HttpHandlers.FileHandler, ASC.Web.CRM" %> diff --git a/products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx b/products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx new file mode 100644 index 00000000000..bbfb15ae1c9 --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx @@ -0,0 +1,4 @@ +<%@ Assembly Name="ASC.Web.CRM" %> +<%@ Assembly Name="ASC.Web.Studio" %> +<%@ Assembly Name="ASC.Web.Core" %> +<%@ WebHandler Language="C#" CodeBehind="WebToLeadFromHandler.ashx.cs" Class="ASC.Web.CRM.HttpHandlers.WebToLeadFromHandler, ASC.Web.CRM" %> diff --git a/products/ASC.CRM/Server/InvoiceTemplates/template.docx b/products/ASC.CRM/Server/InvoiceTemplates/template.docx new file mode 100644 index 0000000000000000000000000000000000000000..d3a35668b76281b352956263b6e8bc466847454b GIT binary patch literal 12050 zcmZ`f1z223(!c=0-GaL%xVyW%2X}%?kO0BmCAhl>cXxMpcX#_?ckgaDcmMSFroWlj z<=xfYRV6C{07U@;0)had5%3mNW;@^e0t^J?1p)+w@b<5PmAuC+Dwx33n4 z@=`Kev@p#?=XixH3HGe%(*wvpMn0_gyk=@6D^rugNi-zD;~uSWhT`+X{qAAfPpN>} z(-}o8l;|5v6)P4gtw@EIS zA6d^s5DPV+`&xHYXL~iSx5Eh6ffuem-d?04K^;7pTaR>=+J8Nz?c-Y>Hx>yC&d~2a zVaeP)iq_@Dzsry)tr4Z+7Y~|hovv8U=82B?NQ{MG2lR+YR5)Y{T{o~s3Yvv#RKw@! zGqZMjaIU{nc;%(44Ky8$W7ozYgiYvoZdXp?t(=j;br>hY7|81e zTz<=(p0p(;zx9nxi6ckSqN6}|CkSO2+SWP5d-?L?26boM%9VwJJn@R4>jM z4d{e)C5+-|=@9%t#_5Fyg~nr;NBoN=CO6(m3jU3bS~VxnBed*4Y=KLKd9?Co1Nk?5 zApYGJ`c}4v@5WGy;FIa3h4FnAk9|Cd1Mn*?ig8#AYyk1#vwlI3BaJ+UeK_q`XKWuH z9evokeR#gbF8ow+hw@=^CbWQD&z4)-+u6f)g)2dPO4wK+i1DXym*QhZ?~<;b%XUoQ zbhIKEN=_%|&uFs~AW#`bjeG0Li(*9i;$6AYFle7rmMKYJL!hVb_-9uiSxiN6_dd zAO2b{Ns(BrN)bBR+4#8Fo65jYnk0$qcFUzN(;qZ!8v8XVp^QA}1}2p>mk9tm z(-#YEIlmCrlA4~RNGe73J~aWJ&q>w_Ce``^_5}sXA@P)$zXiQkGoxa090Rd{Fn-Lm z7eob`=CjxCTF&Ms_rqq^%lz}NO@u34 zmyW$vrJwIVinm_@OM6dNA}k2Td3{CrCdqZm)L-<4W^+72RpG#mtbSzh>Q{L&gwt;D z#Il=e>5^P%m?Z@uZMrJUEIF3L-8Lrpn&Tep?arjee_ z-$1EJcphVt9WEWwzJ4a{beT-Go2_qJwyOg$k*dO+gjgmiPkSL3<(oGns;u{9^j8qK z+7d2yUthb{PsNhp{s8t`l0WAQ6oiGW=eUrc`kc^||8;0QS z=<(hXBv_>@M*WtXGYbL`Xi8)bS&V+n4DNGZPyUCSLZn1hwcb+d$o0yC!CS z_lx^z)A?o6VL&&{WcldUyqEamLyoUo?uafgsNZ2%`!`;<^f390o1|$w=?-6Wo=yDc zICJReb52A_T{2YJc#0oqba#;UucCh4zx9K4rUhZ>+o)Fo7hr&4C| zidPzHCfu0|B8XB)eoAxe<0pw(P0vy-#vc|fEd?r-HQLzarebm1ag}+w(J$)3g5xQ8 zhy&BUOnekCjyjyK7WPumrQua@*W{b;DxB}d$RhWdr+vOjWZMT3kF8I*IeZLx1UDv3 zRcA1n3x3*DfJ|)CY}DjpZ0Us>U8}|Rzfcgaw za($L>^!3UO`T99K;1WaT8zmhn{0Vochdr%Q89erOM{i&WR(CY9z?tP!maq-%Lpv{3 zw%?cPy^~0aYcr~b%`+`_x93##{FAef9v-iB)<-vfJnlxm?SazPAi!p5sdeo^{ami- zQ07Le)4xj86J|*$KCtOaL`sY-olcFTNL7C1(x6TmnwC5=BXhn+YLV~P9z^0x$(H5d zTZ#ePJUBg?T~U*UH818EHe|iX<|Q3|SCwIASlm5IDzFreOg^Y5Eyjyo-0xRv0?41!d0=@^r1OF8dp|Lt*V0(u*n|oyBu9Q(<^x&W3WUsOCRC}< zu(f`rr{tQe>3Io;)svU8mGv_fQ>73ht7`Z>_&mfl(=Dtr!*e8Yna0 zuMVo48yFFp^wU*V2b5n=WT_Nc2w59Ka;3(w*gpZM9DfG0puyuOUHO3QeJV`IZNkh; zsGL&_ zQbl4^M1Y2HS5BIf7mU0wUqsV1xh13v)dlWJMAK%l+hiE~{lO^LN#0~eRVShCJsM$n zs-209@I_h^!gHPRfVYL2J*KhS61hsCK;q61d!SwGJ9E7 zio^}-XQqf+=z(x=&9XHvNKgfun=12=VEnxu&&o&cnYHH$*?%Wye`^iT>Xb-YRCiSY zmY#zCZ>?5aLMXEcEDddZSvXT5(;Rjj=Ug}`w*;%d0?kc*i**Tyt?;&S2m{&myH|`G z%FJT~=sn=px>BDAJ4D9a0*r|9ZmYNCrv~0|38LL$=!yOKlDefOMyrXvWWBDF|D!`K zzcYp|qk!{r<1$|oIs7E&R}PWHVz9J~=$&ecL1ak;_~@prEFH-U_4W_`XB?O_ZLWJ+ER`rqEpT$R4Uqzja98Mkm=q#)`v9CpP9n@_40z>9Rvjy>P zY;!L0QeAAYfCh~m9a-r3SQ{q;?NaaM+u*{FDliVMW&?uAjFGvZNmpxk? zd|_cv;E{d7=+)BJ^&I(HzJo}w%TlU6Fe2Q(0{`coAiW)( z|2QogSy|dE>grkiadr+JlauM7Mfh;$gxo4H>7@2UY^Vc2h~T{YgEwA!3>@ZSV~)yC zH`mdM`^+dqcyqh@)o0hsZR4{I10psb`7jZ2C}?mexSJfe)#6j!?DTBiJT5P)?fEE8 zYD=pfDLDdSq$PMoP=x^jafe7l12|?AOx>?Pf>C?Yk+nCuq1oNB4>`OuX8OOTIPE7( z#U%EJ1qz@PQyL#JBgPX=Kl=5PaHM(+H1dztioxry*xW zjw}}^a+i$H&#C)fyr6I<530~~1e~?vvVtQJr9viH%Q=pc4nW7vntYKr3$6wy=Gb`< zdz3E>bdhI>y=;B8P0-3d;(zWht#Vr2EA23MSdBJgM_H-U5o=lyZqgmIc4+g7mT?wc zflGwLDxdh_eQ18hGS^=D8g(n8?)Eoz8(Am_CN|}RCINte(7}L!-tUrssQas-fvGNy zg_W@twVAb{afza81tQSHABW@+B zRKkOQk%ehh^)@B!P=qpHNs-*Wdc_`rn1RtxJ)@r=MOT}Dy%Y>DG;rLybL?`oUUHNz zXC7xydG4=I537!CqH?YZN)CG_vp<|gFX7-tyVmuOs;zQpT2_4$As(Ao7Qtw13Pz2MgX+9GC%t%yLXrPeS*ZiXU+JsTd%@ACf)vuTgD?0KiU8mY3TMQ3%&4J6V7-` zFND_V>$Ip%zj(+x^=#(sHf(?G_PoEp9ejKtyRwc&3C?r<#?}rTRqexIU**gq-t^bd znhU{xlg*#vWOmxJ4#F8+dWlqVF1!4ZqEo%pB4k}pbba0uS`#<$3N2-V9EQQ#Y2{Tp zBRd?Z!5U!Ul=iO zHOqEX9P~5SKr;2jHJki&sfKsI6q}oqp2s)KvCvzqe92Iduw`20^m_%!Lu-=0*P-q1Fq`wsHOX#TaHJ%HFq~7jR4_EFR?qw5 zoFlV|8HB;Ig4KYk{|$!@ez{;&xl5%GGTVL=j60wEkh3ID7#;lA^A+tTD?6it*t0ch zfHsH!{3?|AGS1@71Ls@@xO9$i5rn~4W@Ec;AM3|qRbozF&{FZOLr;Auc`%*$Vq%1? z{c$s`pA?626_aVz2d(uiC`Bql_{guQFXUhVv|5=P->iC=Qtbbe3?_q~O7PFn9y}hZWvEBPkJ5*uNa*-C{3H8VBLR4%QEa)KL z8h&5Kuu%VpVhV9Wep^V}=YiSysjMKx^gXeq`IPx}&jrrpYVoiR=fGTpBEudeUDlb2 zDiT)@*Dp(zUC2K%Q849x1)qI(p0kwpMHkc^AmeMl+fe)!)`w<#;7rDNN20FFU&fdB zgMWYF%BQpjuKtW$wp#r1vqm0fwr*C)3*JWy%>HiV3vV<(Qp5vN#Lx5X33`gECjB@r z7AEa-=m6&@$&k%f43QGmCOVbUAixHTD%KNO9tbNuoH7X({1Hu@j4HQ23$i1Fel4;i zhrScCBa8kaq=tyas$YtD&2qWz>W==rmANbhXW+xOp0C1$Tg(v_%5Fpb>i6zVUo&gG zX2&M6&$e+r2xjALeB)S0pZKvJL}W=G6PDqRWdw2B@X?z6&|?h+yq(rOqpf4Xa61+= z2>i{E^3PFC{TCX}n1zM&Js*g=r_unM=vNiDD7t8;O7`S!lUebyzeX)9Tyf@F0H0F9 zE8QF0fiadJw^Re{%E`>c)_-WInX`)2-m_2inu4Koj!jz}b?ds8$O3$?i~6L>`Z8X2 zNc{S8z?HPF+{1L(FjOWKNGwEy$E2F^nlGLvzrOx0((-Qqn=sC%7dRjw`Z*vV_=_lZWnXK`Q`N5cokVH>(+`OYE03qSZ=t8;U6yOBj2vZ)!{8UkZ8pzkEWKD=VxL56Kr=OsmVAg|VPp;cEKG@JhX` z^@X-*pB5HW*K3z=VsR{Ll((q0Mnm0eLL3`c4b1ovsoKr97fjIR8euQ8R9jF9!%bk^ znjC9cr*H5xj|m`BzGBQl=ud2g#_uhvmZlZ#+p`H_&B6h&i!*1l>4q{@Q4vq8Hl47_ z=I7?DR=!_*kEy$49|mNS93e4ACbS*LOemR;I637IW8ydu-a2) zo~;kN9Bp>$W8q=rLyPDisr%11y4z3MBY7GHAJhP7Ao@jCsZMj}!(J0Z?~t3SEheDn zjr*?`ff}pqWTZEHuY7c~FTxduQm%@dg|}KCY-NVk8^TsUD1gg`ZlY1H$$s<^l^ zUo}?=%s8up^1p9=-E-H)6@LCM}h$0Vb1tE}0@Y^MlWmosWj8N408pRoG@;cc^d& zk&n^|vMo_s=JaFRi(m3%fLj}HUq8+12|o)2<;KFzdR;FP*{~%m;4f0_i-mKfXzB0+LnTc27#gq?6No z$X?_59i!Zbh17_GZ9TF8AfZ!0AM0Im6n{=D*%uY2+ z4k0&KPRb_VVM~r1_{g-d#RL5wm+6rhsuhN(9?4;z%J4&U6}=OzYRsVdu+%aS#esB8-D#SDg*G%i%ab_=b+|i4cE!B`{ecyJVazn{HVD&Y97m-J1>Rbq&pq zGx568jab~2P7z^CfOiAE@k{kStCG z9yeNrhpbSm=W{3JgOqA37YrfB#wMRT;;F{iEzhG_U241Y1?gg5IXjUW8VyT9-F(>rAOAU(K4exqV zlb>p1fK0pK@J4(uvRvWr#ycl>AGZ)pJrkpD(@nXS=rfz@E;3+6Du6hUl7uf3@9wUk zO~gUJ97vIRTntcQ95spO)Rxqb`*^P=3eQY@E2wnx!6XpXfs5Q5R}{!}GnP+Cyk>nG zK%%hD=B?q8K!wsPv;piFXl?QWD4_xyg=iX<6QwEA9$lB@zEJt=WQ%7KGPNzP_|zanCDbPEl|We z!v9JCmYV+!6zUCB=pB@T$O`!Le}n$P%XB{$xSYrei0WTLLBBC|`XclW3hWG>PW}#R z_$EfqKdAm&jC^+IPW*#+9$}r|LEm^ZwM=)Y!8L=3&vQgkVhWh;R4zG{!n}hlkqvOu zNRP@S)LGz%>f;6LHKmU3=JZPF`(sQi4Z^kv}F%JFc9^c$ZRR6Z0RI_KGI%` z8x{vGSAAY6YO8x?Cvo*Pyzu*;$ms?N@0EDaoQ_1IWu*{H#aD@7#yc9G=PB`#hdmK{ z+n@yG)>W*eFI{F=H07Dr37<1Gq-`#84SaQLOv*Wi)EN7uYv_ySFIuc1zOFWMca&W1 z0ro=$IW=l~(RR9RqDos2;TDG!Bo(Tzez8<6a)ZGm4?3MJ_YUC7%r#} zHD)5}pa^?r5P^h=MD?VX+xUJn`Q*r@m41JvX@%CX;ucxzG|!VDOZ&(+)h69?b+?Ds zBXTR$)f@Q=8{P8lb+?4fm`uCj)z$aqv>DHJ64Px54>*tU2f#23k+&nNXLvtb3i_YdF+1j|<`p z%`m*sxz0|vw=?Rw&Y4VnRJ9tVcRQaXYlY~xup(S>XTGzor>|Kykg+A_FpJ+qJ zy{=)JOyusfDb9(?bsMvkXerln%z-L$>!o6(eND4si`PsAT}g6S9W+A$iD{_~mQQ#E zfGFwOtw~Ac7uKwWp!RST&qeKtUfqqBU!UiI&a1Glz1mzX)siFC`iKlEZ)D5z) z>FgSmoiavP8+l$deP-@1(oa>iM$z+I8*lH?w({mprm!4nhGo=c3EU^Z3oCQvpSo7H z(#{mxYwMVJxX9cS!_iabkNz56KzA5kRjxOmKkWr|9?dM9LKV9~*79r5Ck?6);tjd- z(^L}G&g9@_G@NQg8fi}*L-XBp3Yua-TGfvOivkp$^KC1#Cq>z9`O8VWjlB79+}c0m zJzlZ_XznitlEw^F#i|dA!XGH_p2X1eN8-fKk+t2OJ7mC=RQ}*aeP}1^e!I1G5(N5U zQjb#&20eao7!>7e*L+(~|2b@ywvnCo$?z0wi^G~Hc)D-T! zvqxu7?ph91nS6|=Qhw3x2~TiP@!>AA*cb`voL#40P(k-Nva**Phk0_dM@d>#ib@Hq zObg1Pt4vsq%&kQg5<#o?vACSA+A3NRCJ4h1c6Rh!(W`vx7jp1H03zfV|2r*NKDt%_ zl$pEnGvi)3j9sB`A?0PG@M7V4qfzI`juVrk*f~e5iQn$+VPO#xZ05fGg0ymRO8aTL z^?m+_?jMnm0|HOf`RPAbfx(zsE8P#M8nW8&OfUX{qW{b_UfaIw^3h>B2a?C*bkyi_ z{aqBm=qiED-aQ8~JhunBg6zf9AL`gAS{x})QXJ#qde=wy?x_nb$LoC~Qe*aAigs1^ zJC^G}@Nqr*L+O!ccT^N=yz6vUT6#X`fK@P5luM5E^qt!)SEx#!uRP=T|KQ_Yls&4= zTMxCQ<5sNM+Vcr#CDkZUc&Ndc;eKRJa(Kk1bT2)x4=7C-US&>Qg-%@!IzrDRPF)8V zpO7x2M6?3bQbpJSm8(f92_n4f7n~qL0B6t`|BHZhuMJKR^1573TPcosSYu>6OHKB0 z6F%RIfIrs50MXOH_ywmtx?9JzMwBxsN*o0sW|SzMGe!gy6=fHZw;gpm(#4;>&tcn#e(ie4V%?eYj@_{kGr5KL}-V%AbPfbA?ZF0Gss_kpu_XU5aY8L8)Yk z?I6mk<`&CwhkIVg;vy=_CW`=p&Bllv;9xoIM!NJ0Q#ofFoZDLB7C;+b{yeKYkopsU z^nc?oE_lap{s;c-cl;4ay*|Cu4!^MUcsu9~6OAnbfcw3%^a3cz=Ml0r-$X!cK;5Uw zpPc~FIQ4wcbK?<_HKU=q$TOA(dyDi5&O_iyrNSU`y=fL{5Q|QmUu-LL1c|U|m!tG)*(i{opUUuL zL*>p5q7Rmc8e6HgOJSnZY?ZeK>N_H6jD>CG&By3uO6TM`ODej@wBd_BDHndfMWD%3 ztPcQYE%rKcxV)pp$oWG<LkpJlq^xHH0l=NQ<84uExXnwou0Gib;-kNV6HxB^$vPOI;_i{i*v;w!U$Z+I4#W zaZ9mnW$h_-_||-gtXxZ%r22NFe%sJ@_GXH(UMui>!slTFBU2JLqN5)h>2?^R6r)&5 zZK@m1f56AB ziq&+_XA3=M(}$6Z69%tfuuSV-c1dP3Qi4jsB7DIZq=nv2p#wSJ$lL6-Kw%snf@~+8 zM~%l{X8@CGS4J_!vv~qUxRAk}oGYA{=huIRN`TYUBm&>UBzbRf64ZZPmF-OozZ%l~ z@lE$fVS=iJ!dtlHJuC{VB%3D^)>Q}{jiOXh<(@1R)f8c2~WwuvvHa&jQqEn9? z6i1-1fOJ5R^jX1L=9rFmi<2N7Bhs~l)(j8I!+MZV3qUN;(Y2g^03b9i7yH8|7XVZF z`BlHzGcu0ttxRJI+BPbz7eCMMJ9y`#W6IZ(9`h>~P1|nU6AXVr@{=v z9F_TN_2l5pz2HyjT(ghO>s3G)3CNcDKH%(4rQWHWAWT_h@XgM4PusG6^a7`{pZHNK zV~p&9PAqw)j~wG@2-} zXHXXO1HW!Kgm1fgeZR)wa$6aQ&F9J0wj-$&c%z=j{wy0w0VaIYykYh8^!&N(apVR= z_zezVjpv4tOi4 zE6xSd;f7vb;e!@ASbJvAur_}bBsPd->!P>*Eobo_<{}3;HAla#+3L6F-#H5>Lp_DR zMLLy2CEz+}VFb&NoMjYL@fEL$D)zuU0X{QTk(eC6h(MB4%MI8PovjwuQJF6V-qli#~U6j~S4aii}{c_h!nOQ!SbdYB%jh zEU<@os+TSE)Gf7C`%zyDJ*DIwiSivYgHh2&IjB$JGij}Wv7%YT5@ z0lZ|ef$?0CQ&+zH&f0MBIZh#PARUlr@m^M2g=EGi_X%9 zBsMFyi32sK>vetbRP4@6L;;_}=ig-;Bmn}RX+7v{_MwU%l{8|MBRH|Ha)HH*W!`3a< z--zkQujJ^=5=Ek*ZfOb2ri*SnUNBeD;qaF21LS{t@WDVq5}!8()_?;6A-^e5L*Ok* z_*PM-t>|oRXs7k=zpG;hE#ESQLLMX+Xe55rg@uIWd;0T)vF@H?r0r8Q^L}lsPLkw> zl>Ygg%#rjAyDR4NHa(LiDE;8Yo9f#JF|cAFg<~Wt4$|DaW%~fJWaB~u{!e}VaM%gb zJ(nrK@%TlW(s3(EBH~&Vp#7S;u;fRI3*tNH(=$`$8^P1Or+%HT>L%NK_fsEW=|A!a zbkB5<(P(_GWkZ{Y*eXbYR%TnLKg*EL>Kd4m(=$vz5nRLGX$_FGiI)vWW-7}R%$kW@_$_E?`k455KqKQS+x5cgo!TK3PWPb$#*GkwVEi2gW$WU5sV{6E4 z^DMX8`19j#G^~9PG_wvD&-a6{F!Jx`5BN*qBr%9q4X>w?Eq|N!?@KpSqpEK6%~(=z z*Y!*=)aK z+aM}BI%3-ekMy!fz6XVBCoA*6`E$TcOK_wCJL7n#V=m~I_=@~MFQD`x`H1a zx&lFkDu&`Em!1va1Etge_MuEXal}mC)zALpd}Gb3W2yle@MQYo9*v05H1By_dhJeW zEf#in(Gw=?DF!NcLq&SAQL}ZfK#^A*OG>n}rr`~jq*k)-Hu2P$F_Lw)ICUy^cj_B* zMXgk`IyXa2q=x&^>$5LxE;sS9syi{#&2$#^iq$X+i_3?N zgIDIaOvwLAXaBCp-?L_aO8Nc`cq>5ouN>O%;J+tb{s#VL=|92$or3ut`1fPze}Jip z{sR8}Q2INH-*?0Rpg17?3&n4H<2#0bsqlYoMei7Z{!n2V* + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/products/ASC.CRM/Server/Properties/launchSettings.json b/products/ASC.CRM/Server/Properties/launchSettings.json new file mode 100644 index 00000000000..710e91144ba --- /dev/null +++ b/products/ASC.CRM/Server/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:64642", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Kestrel WebServer": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "weatherforecast", + "applicationUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/SalesByManagers.docbuilder b/products/ASC.CRM/Server/ReportTemplates/SalesByManagers.docbuilder new file mode 100644 index 00000000000..90713e0a8be --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/SalesByManagers.docbuilder @@ -0,0 +1,201 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); + + sRange = oWorksheet.GetRange("B39"); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + sRange.SetWrap(wrap || false) +} + +function writeCharts(startColIndex, startRowIndex, rowIndex) { + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + startRowIndex + ":$" + toColumnName(startColIndex + reportData.tbody[0].length - 1) + "$" + (startRowIndex + reportData.tbody.length); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (rowIndex - reportData.tbody.length - 1) + ":$" + toColumnName(startColIndex + 1) + "$" + (rowIndex - 1); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, true, "barStacked", 2, 240 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName2, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("none"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + var headerRow = [reportData.resource.manager].concat(reportData.thead); + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var j = 0; j < reportData.tbody.length; j++) { + if (j == reportData.tbody.length - 1) { + writeRow(colIndex, rowIndex, reportData.tbody[j], smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, reportData.tbody[j], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + rowIndex++; + } + + var startCell; + var endCell; + + var footerRow = [reportData.resource.total]; + for (var k = 1; k < reportData.tbody[0].length; k++) { + startCell = toColumnName(colIndex + k) + (startRowIndex + 1); + endCell = toColumnName(colIndex + k) + (startRowIndex + reportData.tbody.length); + footerRow[k] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + rowIndex = rowIndex + 3; + + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex = rowIndex + 2; + + headerRow = [reportData.resource.manager, reportData.resource.summary]; + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var l = 0; l <= reportData.tbody.length; l++) { + startCell = toColumnName(startColIndex + 1) + (startRowIndex + 1 + l); + endCell = toColumnName(startColIndex + reportData.tbody[0].length - 1) + (startRowIndex + 1 + l); + var row = ["=" + toColumnName(startColIndex) + (startRowIndex + 1 + l), "=SUM(" + startCell + ":" + endCell + ")"]; + + if(l == reportData.tbody.length) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, true, null, null, null); + } else { + if(l == reportData.tbody.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + rowIndex++; + } + } + + writeCharts(startColIndex, startRowIndex, rowIndex); +} + +customizeWorksheet(); +writeText(); + +if (reportData.tbody && reportData.tbody.length && reportData.thead && reportData.thead.length) { + writeTable(2, 41); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/SalesForecast.docbuilder b/products/ASC.CRM/Server/ReportTemplates/SalesForecast.docbuilder new file mode 100644 index 00000000000..bc87996e27d --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/SalesForecast.docbuilder @@ -0,0 +1,165 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); + + sRange = oWorksheet.GetRange("B25"); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, rowIndex) { + var chartRange = "$" + toColumnName(startColIndex) + "$" + startRowIndex + ":$" + toColumnName(startColIndex + reportData.tbody[0].length - 1) + "$" + (startRowIndex + reportData.tbody.length); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange, false, "lineNormal", 2, 240 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + writeRow(colIndex, rowIndex, reportData.thead, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.tbody.length; i++) { + if (i == reportData.tbody.length - 1) { + writeRow(colIndex, rowIndex, reportData.tbody[i], smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, reportData.tbody[i], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + var startCell; + var endCell; + + var footerRow = [reportData.resource.total]; + for (var k = 1; k < reportData.tbody[0].length; k++) { + startCell = toColumnName(colIndex + k) + (startRowIndex + 1); + endCell = toColumnName(colIndex + k) + (startRowIndex + reportData.tbody.length); + footerRow[k] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + writeCharts(startColIndex, startRowIndex, rowIndex); +} + +customizeWorksheet(); +writeText(); + +if (reportData.tbody && reportData.tbody.length && reportData.thead && reportData.thead.length) { + writeTable(2, 27); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/SalesFunnel.docbuilder b/products/ASC.CRM/Server/ReportTemplates/SalesFunnel.docbuilder new file mode 100644 index 00000000000..10ea1e7f8ce --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/SalesFunnel.docbuilder @@ -0,0 +1,329 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); + + sRange = oWorksheet.GetRange("B39"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.totalCountLabel); + + sRange = oWorksheet.GetRange("B40"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.totalCountValue.toString()); + + sRange = oWorksheet.GetRange("B41"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.totalBudgetLabel); + + sRange = oWorksheet.GetRange("B42"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetBold(true); + sRange.SetNumberFormat("0.00"); + sRange.SetValue(reportData.resource.totalBudgetValue.toString()); + + sRange = oWorksheet.GetRange("B43"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.averageBidLabel); + + sRange = oWorksheet.GetRange("B44"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetBold(true); + sRange.SetNumberFormat("0.00"); + sRange.SetValue(reportData.resource.averageBidValue.toString()); + + sRange = oWorksheet.GetRange("B45"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.averageDurationLabel); + + sRange = oWorksheet.GetRange("B46"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.averageDurationValue.toString()); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, length) { + var chartRange = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 8) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 7 + length); + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 18 + length) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 17 + 2 * length); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 3) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 5); + var chartRange3 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 13 + length) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 15 + length); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange, false, "horizontalBar", 2, 120 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("none"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetHorAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetVerAxisOrientation(false); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "horizontalBar", 2, 120 * 36000, 70 * 36000, 5, -0.5 * 36000, 7, 0); + oChart.SetTitle(reportData.resource.chartName1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("none"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetHorAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetVerAxisOrientation(false); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "pie", 2, 120 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName2, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange3, false, "pie", 2, 120 * 36000, 70 * 36000, 5, -0.5 * 36000, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName3, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); +} + +function getConversion(cell1, cell2){ + return "=IF(" + cell2 + ">0;" + cell1 + "/" + cell2 +";\"0%\")"; +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); + + rowIndex++; + rowIndex++; + + var row = []; + var typeBody = [ + [reportData.resource.status0, 0, 0], + [reportData.resource.status1, 0, 0], + [reportData.resource.status2, 0, 0], + ]; + var stageBody = []; + + for (var i = 0; i < reportData.data.length; i++) { + typeBody[reportData.data[i][1]][1]+=reportData.data[i][2]; + typeBody[reportData.data[i][1]][2]+=reportData.data[i][3]; + + if(reportData.data[i][1] != 2){ + stageBody.push([reportData.data[i][0], reportData.data[i][2], reportData.data[i][3]]); + } + } + + var head = [reportData.resource.deals, reportData.resource.count, "%"]; + + writeRow(colIndex, rowIndex, head, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < typeBody.length; i++) { + row = [typeBody[i][0], typeBody[i][1], {format: "0%", value: getConversion(toColumnName(colIndex + 1) + rowIndex, "B40")}]; + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + } + + rowIndex++; + + head = [reportData.resource.stage, reportData.resource.count, reportData.resource.conversion]; + + writeRow(colIndex, rowIndex, head, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var tmp = reportData.resource.totalCountValue - typeBody[2][1]; + + for (var i = 0; i < stageBody.length; i++) { + if (i == 0) { + row = [stageBody[i][0], tmp, {format: "0%", value: "1"}]; + } else { + row = [stageBody[i][0], tmp, {format: "0%", value: getConversion(toColumnName(colIndex + 1) + rowIndex, toColumnName(colIndex + 1) + (rowIndex - 1))}]; + } + + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + tmp-=stageBody[i][1]; + } + + rowIndex+=2; + + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex+=2; + + head = [reportData.resource.deals, reportData.resource.budget, "%"]; + + writeRow(colIndex, rowIndex, head, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < typeBody.length; i++) { + row = [typeBody[i][0], {format: "0.00", value: typeBody[i][2].toString()}, {format: "0%", value: getConversion(toColumnName(colIndex + 1) + rowIndex, "B42")}]; + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + } + + rowIndex++; + + head = [reportData.resource.stage, reportData.resource.budget, reportData.resource.conversion]; + + writeRow(colIndex, rowIndex, head, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + tmp = reportData.resource.totalBudgetValue - typeBody[2][2]; + + for (var i = 0; i < stageBody.length; i++) { + if (i == 0) { + row = [stageBody[i][0], {format: "0.00", value: tmp.toString()}, {format: "0%", value: "1"}]; + } else { + row = [stageBody[i][0], {format: "0.00", value: tmp.toString()}, {format: "0%", value: getConversion(toColumnName(colIndex + 1) + rowIndex, toColumnName(colIndex + 1) + (rowIndex - 1))}]; + } + + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + tmp-=stageBody[i][2]; + } + + writeCharts(startColIndex, startRowIndex, stageBody.length); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data && reportData.data.length) { + writeTable(2, 49); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/SummaryAtThisMoment.docbuilder b/products/ASC.CRM/Server/ReportTemplates/SummaryAtThisMoment.docbuilder new file mode 100644 index 00000000000..b37b977015a --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/SummaryAtThisMoment.docbuilder @@ -0,0 +1,327 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); + + sRange = oWorksheet.GetRange("B53"); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, rowIndex) { + var chartRange = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 1) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 3); + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 6) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 5 + reportData.data.DealsInfo.ByStage.length); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 11 + reportData.data.DealsInfo.ByStage.length) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 10 + reportData.data.DealsInfo.ByStage.length + reportData.data.ContactsInfo.ByType.length); + var chartRange3 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 13 + reportData.data.DealsInfo.ByStage.length + reportData.data.ContactsInfo.ByType.length) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 12 + reportData.data.DealsInfo.ByStage.length + reportData.data.ContactsInfo.ByType.length + reportData.data.ContactsInfo.ByStage.length); + var chartRange4 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 17 + reportData.data.DealsInfo.ByStage.length + reportData.data.ContactsInfo.ByType.length + reportData.data.ContactsInfo.ByStage.length) + ":$" + toColumnName(startColIndex + 2) + "$" + (startRowIndex + 17 + reportData.data.DealsInfo.ByStage.length + reportData.data.ContactsInfo.ByType.length + reportData.data.ContactsInfo.ByStage.length + reportData.data.TasksInfo.length); + var chartRange5 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 23 + reportData.data.DealsInfo.ByStage.length + reportData.data.ContactsInfo.ByType.length + reportData.data.ContactsInfo.ByStage.length + reportData.data.TasksInfo.length) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 24 + reportData.data.DealsInfo.ByStage.length + reportData.data.ContactsInfo.ByType.length + reportData.data.ContactsInfo.ByStage.length + reportData.data.TasksInfo.length); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange, true, "bar", 2, 120 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "horizontalBar", 2, 120 * 36000, 70 * 36000, 5, -0.5 * 36000, 7, 0); + oChart.SetTitle(reportData.resource.chartName1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("none"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetHorAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetVerAxisOrientation(false); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "pie", 2, 120 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName2, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange3, false, "pie", 2, 120 * 36000, 70 * 36000, 5, -0.5 * 36000, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName3, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange4, false, "bar", 2, 120 * 36000, 70 * 36000, 1, 0, 35, -1 * 36000); + oChart.SetTitle(reportData.resource.chartName4, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange5, true, "bar", 2, 120 * 36000, 70 * 36000, 5, -0.5 * 36000, 35, -1 * 36000); + oChart.SetTitle(reportData.resource.chartName5, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + //deals by status + writeRow(colIndex, rowIndex, [reportData.resource.status, reportData.resource.budget, reportData.resource.count], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.open, {format: "0.00", value: (reportData.data.DealsInfo.Open[0][1] || 0).toString()}, reportData.data.DealsInfo.Open[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.overdue, {format: "0.00", value: (reportData.data.DealsInfo.Overdue[0][1] || 0).toString()}, reportData.data.DealsInfo.Overdue[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.near, {format: "0.00", value: (reportData.data.DealsInfo.Near[0][1] || 0).toString()}, reportData.data.DealsInfo.Near[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + rowIndex++; + + //deals by count + writeRow(colIndex, rowIndex, [reportData.resource.stage, reportData.resource.budget, reportData.resource.count], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.DealsInfo.ByStage.length; i++) { + var row = [reportData.data.DealsInfo.ByStage[i][0] || reportData.resource.notSpecified, {format: "0.00", value: (reportData.data.DealsInfo.ByStage[i][2] || 0).toString()}, reportData.data.DealsInfo.ByStage[i][1] || 0]; + + if (i == reportData.data.DealsInfo.ByStage.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, null, null, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + rowIndex++; + rowIndex++; + + //contacts by type + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex++; + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.type, ""], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.ContactsInfo.ByType.length; i++) { + var row = reportData.data.ContactsInfo.ByType[i]; + + if(!row[0]) row[0] = reportData.resource.notSpecified; + + if (i == reportData.data.ContactsInfo.ByType.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, null, null, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + rowIndex++; + + //contacts by stage + writeRow(colIndex, rowIndex, [reportData.resource.temperature, ""], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.ContactsInfo.ByStage.length; i++) { + var row = reportData.data.ContactsInfo.ByStage[i]; + + if(!row[0]) row[0] = reportData.resource.notSpecified; + + if (i == reportData.data.ContactsInfo.ByStage.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, null, null, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + rowIndex++; + rowIndex++; + + //tasks by the period + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header3); + + rowIndex++; + rowIndex++; + + var headerRow = [reportData.resource.type, reportData.resource.open, reportData.resource.overdue]; + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.TasksInfo.length; i++) { + var row = reportData.data.TasksInfo[i]; + + if (i == reportData.data.TasksInfo.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, null, null, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + rowIndex++; + rowIndex++; + + //invoices by status + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header4); + + rowIndex++; + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.status, ""], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.billed, reportData.data.InvoicesInfo[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.overdue, reportData.data.InvoicesInfo[0][1] || 0], smallFontSize, blackFontColor, false, null, null, null); + + writeCharts(startColIndex, startRowIndex, rowIndex); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data) { + writeTable(2, 55); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/SummaryForThePeriod.docbuilder b/products/ASC.CRM/Server/ReportTemplates/SummaryForThePeriod.docbuilder new file mode 100644 index 00000000000..3913de0ae28 --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/SummaryForThePeriod.docbuilder @@ -0,0 +1,375 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); + + sRange = oWorksheet.GetRange("B67"); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function secondsToTimeFormat(seconds) { + var hours = Math.floor(seconds / 3600); + + if(hours < 10) hours="0"+hours; + + var minutes = Math.floor(seconds % 3600 / 60); + + if(minutes < 10) minutes="0"+minutes; + + var seconds = Math.floor(seconds % 3600 % 60); + + if(seconds < 10) seconds="0"+seconds; + + return {format: reportData.resource.timeFormat, value: hours + ":" + minutes + ":" + seconds}; +} + +function writeCharts(startColIndex, startRowIndex, rowIndex) { + var chartRange = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 1) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 4); + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 7) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 10); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 16) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 15 + reportData.data.ContactsInfo.length); + var chartRange3 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 20 + reportData.data.ContactsInfo.length) + ":$" + toColumnName(startColIndex + 3) + "$" + (startRowIndex + 20 + reportData.data.ContactsInfo.length + reportData.data.TasksInfo.length); + var chartRange4 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 26 + reportData.data.ContactsInfo.length + reportData.data.TasksInfo.length) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 29 + reportData.data.ContactsInfo.length + reportData.data.TasksInfo.length); + var chartRange5 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 35 + reportData.data.ContactsInfo.length + reportData.data.TasksInfo.length) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 36 + reportData.data.ContactsInfo.length + reportData.data.TasksInfo.length); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange, false, "bar", 2, 120 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("none"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "bar", 2, 120 * 36000, 70 * 36000, 5, -0.5 * 36000, 7, 0); + oChart.SetTitle(reportData.resource.chartName1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("none"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "pie", 2, 120 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName2, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange4, true, "bar", 2, 120 * 36000, 70 * 36000, 5, -0.5 * 36000, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName4, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange3, false, "bar", 2, 240 * 36000 - 0.5 * 36000, 70 * 36000, 1, 0, 35, -1 * 36000); + oChart.SetTitle(reportData.resource.chartName3, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange5, false, "pie", 2, 120 * 36000, 70 * 36000, 1, 0, 49, -1.5 * 36000); + oChart.SetTitle(reportData.resource.chartName5, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + //deals by budget + writeRow(colIndex, rowIndex, [reportData.resource.byBudget, reportData.resource.currency], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.created, {format: "0.00", value: (reportData.data.DealsInfo.Created[0][1] || 0).toString()}], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.won, {format: "0.00", value: (reportData.data.DealsInfo.Won[0][1] || 0).toString()}], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.lost, {format: "0.00", value: (reportData.data.DealsInfo.Lost[0][1] || 0).toString()}], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.overdue, {format: "0.00", value: (reportData.data.DealsInfo.Overdue[0][1] || 0).toString()}], smallFontSize, blackFontColor, false, null, null, null); + rowIndex++; + + rowIndex++; + + //deals by count + writeRow(colIndex, rowIndex, [reportData.resource.byCount, reportData.resource.item], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.created, reportData.data.DealsInfo.Created[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.won, reportData.data.DealsInfo.Won[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.lost, reportData.data.DealsInfo.Lost[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.overdue, reportData.data.DealsInfo.Overdue[0][0] || 0], smallFontSize, blackFontColor, false, null, null, null); + rowIndex++; + + rowIndex++; + rowIndex++; + + //contacts by type + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex++; + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.type, reportData.resource.item], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.ContactsInfo.length; i++) { + var row = reportData.data.ContactsInfo[i]; + + if(!row[0]) row[0] = reportData.resource.notSpecified; + + if (i == reportData.data.ContactsInfo.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, null, null, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + rowIndex++; + rowIndex++; + + //tasks by the period + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header3); + + rowIndex++; + rowIndex++; + + var headerRow = [reportData.resource.type, reportData.resource.closed, reportData.resource.overdue, reportData.resource.created]; + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.TasksInfo.length; i++) { + var row = reportData.data.TasksInfo[i]; + + if (i == reportData.data.TasksInfo.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, null, null, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + rowIndex++; + rowIndex++; + + //invoices by status + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header4); + + rowIndex++; + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.status, reportData.resource.item], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.billed, reportData.data.InvoicesInfo[0][0] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.paid, reportData.data.InvoicesInfo[0][1] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.rejected, reportData.data.InvoicesInfo[0][2] || 0], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.overdue, reportData.data.InvoicesInfo[0][3] || 0], smallFontSize, blackFontColor, false, null, null, null); + rowIndex++; + + rowIndex++; + rowIndex++; + + //calls by the period + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header5); + + rowIndex++; + rowIndex++; + + writeRow(colIndex, rowIndex, ["", reportData.resource.count, reportData.resource.duration], smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var incomingCount=0; + var incomingDuration=0; + var outcomingCount=0; + var outcomingDuration=0; + var missingCount=0; + + for (var i = 0; i < reportData.data.VoipInfo.length; i++) { + if (reportData.data.VoipInfo[i][0] == 1) { + outcomingCount+=reportData.data.VoipInfo[i][1]; + outcomingDuration+=reportData.data.VoipInfo[i][2]; + } else { + incomingCount+=reportData.data.VoipInfo[i][1]; + incomingDuration+=reportData.data.VoipInfo[i][2]; + + if(reportData.data.VoipInfo[i][0] == 3){ + missingCount+=reportData.data.VoipInfo[i][1]; + } + } + } + + writeRow(colIndex, rowIndex, [reportData.resource.incoming, incomingCount, secondsToTimeFormat(incomingDuration)], smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + sRange = oWorksheet.GetRange(toColumnName(colIndex+3) + rowIndex); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetValue(reportData.resource.missed.replace("{0}", missingCount)); + rowIndex++; + + writeRow(colIndex, rowIndex, [reportData.resource.outcoming, outcomingCount, secondsToTimeFormat(outcomingDuration)], smallFontSize, blackFontColor, false, null, null, null); + + writeCharts(startColIndex, startRowIndex, rowIndex); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data) { + writeTable(2, 69); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/WorkloadByContacts.docbuilder b/products/ASC.CRM/Server/ReportTemplates/WorkloadByContacts.docbuilder new file mode 100644 index 00000000000..1ebd5b93874 --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/WorkloadByContacts.docbuilder @@ -0,0 +1,289 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function prepareData(){ + reportData.header = [reportData.resource.manager]; + + var obj = {Name: "", Total: 0, WithDeals: 0}; + + for(var i=0; i 0 ? item.CategoryName : reportData.resource.noSet; + + if(!obj.hasOwnProperty(propName)){ + obj[propName] = { + Name: categoryName, + Count: 0 + }; + + reportData.header.push(categoryName); + } + } + + var data = {}; + var count = 0; + + for(var i=0; i= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, count, length) { + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 2) + ":$" + toColumnName(startColIndex + length - 1) + "$" + (startRowIndex + 2 + count); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 8 + count) + ":$" + toColumnName(startColIndex + 2) + "$" + (startRowIndex + 8 + 2 * count); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "barStacked", 2, 240 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.header1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "barStacked", 2, 240 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.header2, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); + + rowIndex = rowIndex + 2; + + writeRow(colIndex, rowIndex, reportData.header, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var index = 0; + + for(var propertyName in reportData.data) { + if(propertyName.indexOf("user") != 0) continue; + + var row = [reportData.data[propertyName].Name]; + + for(var propName in reportData.data[propertyName]) { + if(propName.indexOf("category") != 0) continue; + + row.push(reportData.data[propertyName][propName].Count) + } + + if (index == reportData.count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + var startCell; + var endCell; + + var footerRow = [reportData.resource.total]; + for (var i = 1; i < reportData.header.length; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 3); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + rowIndex = rowIndex + 3; + + + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex = rowIndex + 2; + + var headerRow = [reportData.resource.manager, reportData.resource.withouthDeals, reportData.resource.withDeals]; + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + index = 0; + + for(var propertyName in reportData.data) { + if(propertyName.indexOf("user") != 0) continue; + + var row = [reportData.data[propertyName].Name]; + row.push(reportData.data[propertyName].Total - reportData.data[propertyName].WithDeals); + row.push(reportData.data[propertyName].WithDeals); + + if (index == reportData.count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + startCell; + endCell; + + footerRow = [reportData.resource.total]; + for (var i = 1; i < headerRow.length; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count + 7); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count + 6 + reportData.count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + writeCharts(startColIndex, startRowIndex, reportData.count, reportData.header.length); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data && reportData.data.length) { + prepareData(); + writeTable(2, 39); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/WorkloadByDeals.docbuilder b/products/ASC.CRM/Server/ReportTemplates/WorkloadByDeals.docbuilder new file mode 100644 index 00000000000..3f85e3e8c34 --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/WorkloadByDeals.docbuilder @@ -0,0 +1,269 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, count) { + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 2) + ":$" + toColumnName(startColIndex + 3) + "$" + (startRowIndex + 2 + count); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 8 + count) + ":$" + toColumnName(startColIndex + 3) + "$" + (startRowIndex + 8 + 2 * count); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); + + rowIndex = rowIndex + 2; + + var headerRow = [reportData.resource.manager, reportData.resource.status0, reportData.resource.status1, reportData.resource.status2]; + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var data = {}; + var count = 0; + + for (var i = 0; i < reportData.data.length; i++) { + var propertyName = "usr_" + reportData.data[i][0]; + var status = reportData.data[i][2]; + + if(data[propertyName]){ + switch(status){ + case 0: + data[propertyName].count.open = reportData.data[i][3]; + data[propertyName].budget.open = reportData.data[i][4]; + break; + case 1: + data[propertyName].count.won = reportData.data[i][3]; + data[propertyName].budget.won = reportData.data[i][4]; + break; + case 2: + data[propertyName].count.lost = reportData.data[i][3]; + data[propertyName].budget.lost = reportData.data[i][4]; + break; + } + } else { + data[propertyName] = { + name: reportData.data[i][1], + count: { + open: status == 0 ? reportData.data[i][3] : 0, + won: status == 1 ? reportData.data[i][3] : 0, + lost: status == 2 ? reportData.data[i][3] : 0 + }, + budget: { + open: status == 0 ? reportData.data[i][4] : 0, + won: status == 1 ? reportData.data[i][4] : 0, + lost: status == 2 ? reportData.data[i][4] : 0 + } + }; + count++; + } + } + + var index = 0; + + for(var propertyName in data) { + if(propertyName.indexOf("usr_") != 0) continue; + + var row = [data[propertyName].name, data[propertyName].count.open, data[propertyName].count.won, data[propertyName].count.lost]; + + if (index == count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + var startCell; + var endCell; + + var footerRow = [reportData.resource.total]; + for (var i = 1; i < 4; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 3); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + rowIndex = rowIndex + 3; + + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex = rowIndex + 2; + + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var index = 0; + + for(var propertyName in data) { + if(propertyName.indexOf("usr_") != 0) continue; + + var row = [data[propertyName].name, {format: "0.00", value: data[propertyName].budget.open.toString()}, {format: "0.00", value: data[propertyName].budget.won.toString()}, {format: "0.00", value: data[propertyName].budget.lost.toString()}]; + + if (index == count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + footerRow = [reportData.resource.total]; + for (var i = 1; i < 4; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 9 + count); + endCell = toColumnName(colIndex + i) + (startRowIndex + 8 + 2 * count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + writeCharts(startColIndex, startRowIndex, count); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data && reportData.data.length) { + writeTable(2, 39); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/WorkloadByInvoices.docbuilder b/products/ASC.CRM/Server/ReportTemplates/WorkloadByInvoices.docbuilder new file mode 100644 index 00000000000..92816385493 --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/WorkloadByInvoices.docbuilder @@ -0,0 +1,211 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, count) { + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 2) + ":$" + toColumnName(startColIndex + 1) + "$" + (startRowIndex + 2 + count); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 6 + count) + ":$" + toColumnName(startColIndex + 3) + "$" + (startRowIndex + 6 + 2 * count); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("none"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetVertAxisTickLabelPosition("none"); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + oChart.SetMajorHorizontalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); + oChart.SetMajorVerticalGridlines(Api.CreateStroke(0, Api.CreateNoFill())); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); + + rowIndex = rowIndex + 2; + + var headerRow = [reportData.resource.manager, reportData.resource.billed]; + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.length; i++) { + var item = reportData.data[i]; + var row = [item.UserName, item.SentCount]; + + if (i == reportData.data.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + var startCell = toColumnName(colIndex + 1) + (startRowIndex + 3); + var endCell = toColumnName(colIndex + 1) + (startRowIndex + 2 + reportData.data.length); + var footerRow = [reportData.resource.total, "=SUM(" + startCell + ":" + endCell + ")"]; + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + rowIndex = rowIndex + 3; + + + headerRow = [reportData.resource.manager, reportData.resource.paid, reportData.resource.rejected, reportData.resource.overdue]; + + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + for (var i = 0; i < reportData.data.length; i++) { + var item = reportData.data[i]; + var row = [item.UserName, item.PaidCount, item.RejectedCount, item.OverdueCount]; + + if (i == reportData.data.length - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + } + + footerRow = [reportData.resource.total]; + for (var i = 1; i < 4; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.data.length + 5); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.data.length + 4 + reportData.data.length); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + writeCharts(startColIndex, startRowIndex, reportData.data.length); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data && reportData.data.length) { + writeTable(2, 39); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/WorkloadByTasks.docbuilder b/products/ASC.CRM/Server/ReportTemplates/WorkloadByTasks.docbuilder new file mode 100644 index 00000000000..613ee39e2e2 --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/WorkloadByTasks.docbuilder @@ -0,0 +1,348 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function prepareData(){ + reportData.header = [reportData.resource.manager]; + + var obj = {Name: ""}; + var groups = ["Closed", "Created", "Overdue"]; + + for(var i=0; i= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, count, length) { + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 2) + ":$" + toColumnName(startColIndex + length - 1) + "$" + (startRowIndex + 2 + count); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 8 + count) + ":$" + toColumnName(startColIndex + length - 1) + "$" + (startRowIndex + 8 + 2 * count); + var chartRange3 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 14 + 2 * count) + ":$" + toColumnName(startColIndex + length - 1) + "$" + (startRowIndex + 14 + 3 * count); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.header1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.header2, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange3, false, "bar", 2, 240 * 36000, 70 * 36000, 1, 0, 35, -1 * 36000); + oChart.SetTitle(reportData.resource.header3, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); + + rowIndex = rowIndex + 2; + + writeRow(colIndex, rowIndex, reportData.header, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var index = 0; + + for(var propertyName in reportData.data) { + if(propertyName.indexOf("user") != 0) continue; + + var row = [reportData.data[propertyName].Name]; + + for(var propName in reportData.data[propertyName]) { + if(propName.indexOf("category") != 0) continue; + + row.push(reportData.data[propertyName][propName].Closed) + } + + if (index == reportData.count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + var startCell; + var endCell; + + var footerRow = [reportData.resource.total]; + for (var i = 1; i < reportData.header.length; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 3); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + rowIndex = rowIndex + 3; + + + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex = rowIndex + 2; + + writeRow(colIndex, rowIndex, reportData.header, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + index = 0; + + for(var propertyName in reportData.data) { + if(propertyName.indexOf("user") != 0) continue; + + var row = [reportData.data[propertyName].Name]; + + for(var propName in reportData.data[propertyName]) { + if(propName.indexOf("category") != 0) continue; + + row.push(reportData.data[propertyName][propName].Created) + } + + if (index == reportData.count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + startCell; + endCell; + + footerRow = [reportData.resource.total]; + for (var i = 1; i < reportData.header.length; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count + 7); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count + 6 + reportData.count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + rowIndex = rowIndex + 3; + + + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header3); + + rowIndex = rowIndex + 2; + + writeRow(colIndex, rowIndex, reportData.header, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + index = 0; + + for(var propertyName in reportData.data) { + if(propertyName.indexOf("user") != 0) continue; + + var row = [reportData.data[propertyName].Name]; + + for(var propName in reportData.data[propertyName]) { + if(propName.indexOf("category") != 0) continue; + + row.push(reportData.data[propertyName][propName].Overdue) + } + + if (index == reportData.count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + startCell; + endCell; + + footerRow = [reportData.resource.total]; + for (var i = 1; i < reportData.header.length; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count + 6 + reportData.count + 7); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + reportData.count + 6 + reportData.count + 6 + reportData.count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + + writeCharts(startColIndex, startRowIndex, reportData.count, reportData.header.length); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data) { + prepareData(); + writeTable(2, 53); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/ReportTemplates/WorkloadByVoip.docbuilder b/products/ASC.CRM/Server/ReportTemplates/WorkloadByVoip.docbuilder new file mode 100644 index 00000000000..137b68c6dc0 --- /dev/null +++ b/products/ASC.CRM/Server/ReportTemplates/WorkloadByVoip.docbuilder @@ -0,0 +1,256 @@ + +builder.CreateFile("xlsx"); + +var mainHeaderFontSize = 24; +var headerFontSize = 14; +var chartHeaderFontSize = 12; +var smallFontSize = 10; +var legendFontSize = 9; + +var blackFontColor = Api.CreateColorFromRGB(63, 63, 63); +var grayFontColor = Api.CreateColorFromRGB(127, 127, 127); + +var lightGrayBgColor = Api.CreateColorFromRGB(242, 242, 242); +var darkGrayBgColor = Api.CreateColorFromRGB(216, 216, 216); + +var lightGrayBorderColor = Api.CreateColorFromRGB(216, 216, 216); +var darkGrayBorderColor = Api.CreateColorFromRGB(127, 127, 127); + +var reportData = ${reportData}; + +reportData.resource.sheetName = reportData.resource.sheetName.slice(0, 31); + +var oWorksheet = Api.GetActiveSheet(); + +function toColumnName(num) { + for (var res = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) { + res = String.fromCharCode(parseInt((num % b) / a) + 65) + res; + } + return res; +} + +function customizeWorksheet() { + Api.SetThemeColors("Origin"); + + oWorksheet.SetName(reportData.resource.sheetName); + oWorksheet.SetDisplayGridlines(false); + oWorksheet.SetColumnWidth(0, 6); + oWorksheet.SetColumnWidth(1, 30); + + for (var i = 2; i < 35; i++) { + oWorksheet.SetColumnWidth(i, 15); + } +} + +function writeText() { + var sRange = oWorksheet.GetRange("B2"); + sRange.SetFontSize(mainHeaderFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header); + + sRange = oWorksheet.GetRange("B3"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetBold(true); + sRange.SetValue(reportData.resource.dateRangeLabel); + + sRange = oWorksheet.GetRange("B4"); + sRange.SetFontSize(smallFontSize); + sRange.SetFontColor(grayFontColor); + sRange.SetAlignHorizontal("left"); + sRange.SetValue(reportData.resource.dateRangeValue); +} + +function writeRow(startColIndex, startRowIndex, dataArray, fontSize, fontColor, bold, borderType, borderColor, bgColor, wrap) { + var range = toColumnName(startColIndex) + startRowIndex + ":"; + + for (var i = 0; i < dataArray.length; i++) { + var cell = oWorksheet.GetRange(toColumnName(startColIndex) + startRowIndex); + + if (typeof(dataArray[i]) == "object") { + cell.SetNumberFormat(dataArray[i].format); + cell.SetValue(dataArray[i].value); + } else { + cell.SetValue(dataArray[i].toString()); + } + + if (i == 0) { + cell.SetAlignHorizontal("left"); + } else { + cell.SetAlignHorizontal("right"); + } + + startColIndex++; + } + + range += toColumnName(startColIndex - 1) + startRowIndex; + + var sRange = oWorksheet.GetRange(range); + + if (fontSize) + sRange.SetFontSize(fontSize); + + if (fontColor) + sRange.SetFontColor(fontColor); + + if (bold) + sRange.SetBold(true); + + if (borderType) + sRange.SetBorders(borderType, "Thin", borderColor); + + if (bgColor) + sRange.SetFillColor(bgColor); + + sRange.SetWrap(wrap || false); +} + +function writeCharts(startColIndex, startRowIndex, count) { + var chartRange1 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 2) + ":$" + toColumnName(startColIndex + 2) + "$" + (startRowIndex + 2 + count); + var chartRange2 = "$" + toColumnName(startColIndex) + "$" + (startRowIndex + 8 + count) + ":$" + toColumnName(startColIndex + 2) + "$" + (startRowIndex + 8 + 2 * count); + + var oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange1, false, "barStacked", 2, 240 * 36000, 70 * 36000, 1, 0, 7, 0); + oChart.SetTitle(reportData.resource.chartName, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); + + oChart = oWorksheet.AddChart("'" + reportData.resource.sheetName + "'!" + chartRange2, false, "barStacked", 2, 240 * 36000, 70 * 36000, 1, 0, 21, -0.5 * 36000); + oChart.SetTitle(reportData.resource.chartName1, chartHeaderFontSize, false); + oChart.ApplyChartStyle(0); + oChart.SetLegendPos("right"); + oChart.SetLegendFontSize(legendFontSize); + oChart.SetShowDataLabels(false, false, true, false); + oChart.SetHorAxisLablesFontSize(legendFontSize); + oChart.SetVertAxisLablesFontSize(legendFontSize); +} + +function writeTable(startColIndex, startRowIndex) { + + var colIndex = startColIndex; + var rowIndex = startRowIndex; + + var sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header1); + + rowIndex = rowIndex + 2; + + var headerRow = [reportData.resource.manager, reportData.resource.outcoming, reportData.resource.incoming, reportData.resource.total]; + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var data = {}; + var count = 0; + + for (var i = 0; i < reportData.data.length; i++) { + var propertyName = "usr_" + reportData.data[i][0]; + var status = reportData.data[i][2]; + + if(data[propertyName]) { + if(status == 1) { + data[propertyName].count.outcoming = reportData.data[i][3]; + data[propertyName].duration.outcoming = reportData.data[i][4]; + } else { + data[propertyName].count.incoming = reportData.data[i][3]; + data[propertyName].duration.incoming = reportData.data[i][4]; + } + } else { + data[propertyName] = { + name: reportData.data[i][1], + count: { + outcoming: status == 1 ? reportData.data[i][3] : 0, + incoming: status != 1 ? reportData.data[i][3] : 0 + }, + duration: { + outcoming: status == 1 ? reportData.data[i][4] : 0, + incoming: status != 1 ? reportData.data[i][4] : 0 + } + }; + count++; + } + } + + var index = 0; + + for(var propertyName in data) { + if(propertyName.indexOf("usr_") != 0) continue; + + var sum = "=SUM(" + toColumnName(colIndex + 1) + rowIndex + ":" + toColumnName(colIndex + 2) + rowIndex + ")"; + var row = [data[propertyName].name, data[propertyName].count.outcoming, data[propertyName].count.incoming, sum]; + + if (index == count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + var startCell; + var endCell; + + var footerRow = [reportData.resource.total]; + for (var i = 1; i < 4; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 3); + endCell = toColumnName(colIndex + i) + (startRowIndex + 2 + count); + footerRow[i] = "=SUM(" + startCell + ":" + endCell + ")"; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + rowIndex = rowIndex + 3; + + sRange = oWorksheet.GetRange(toColumnName(colIndex) + rowIndex); + sRange.SetFontSize(headerFontSize); + sRange.SetFontColor(blackFontColor); + sRange.SetValue(reportData.resource.header2); + + rowIndex = rowIndex + 2; + + writeRow(colIndex, rowIndex, headerRow, smallFontSize, grayFontColor, false, "Bottom", darkGrayBorderColor, null, true); + rowIndex++; + + var index = 0; + + for(var propertyName in data) { + if(propertyName.indexOf("usr_") != 0) continue; + + var sum = {format: reportData.resource.timeFormat, value: "=SUM(" + toColumnName(colIndex + 1) + rowIndex + ":" + toColumnName(colIndex + 2) + rowIndex + ")"}; + var row = [data[propertyName].name, data[propertyName].duration.outcoming, data[propertyName].duration.incoming, sum]; + + if (index == count - 1) { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", darkGrayBorderColor, null); + } else { + writeRow(colIndex, rowIndex, row, smallFontSize, blackFontColor, false, "Bottom", lightGrayBorderColor, null); + } + + rowIndex++; + index++; + } + + footerRow = [reportData.resource.total]; + for (var i = 1; i < 4; i++) { + startCell = toColumnName(colIndex + i) + (startRowIndex + 9 + count); + endCell = toColumnName(colIndex + i) + (startRowIndex + 8 + 2 * count); + footerRow[i] = {format: reportData.resource.timeFormat, value: "=SUM(" + startCell + ":" + endCell + ")"}; + } + writeRow(colIndex, rowIndex, footerRow, smallFontSize, blackFontColor, true, null, null, null); + + writeCharts(startColIndex, startRowIndex, count); +} + +customizeWorksheet(); +writeText(); + +if (reportData.data && reportData.data.length) { + writeTable(2, 39); +} + +builder.SaveFile("xlsx", "${outputFilePath}"); +builder.CloseFile(); \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMCasesResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMCasesResource.Designer.cs new file mode 100644 index 00000000000..89a46dd4bda --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMCasesResource.Designer.cs @@ -0,0 +1,468 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMCasesResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMCasesResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMCasesResource", typeof(CRMCasesResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Save and Create New Case. + /// + public static string AddThisAndCreateCaseButton { + get { + return ResourceManager.GetString("AddThisAndCreateCaseButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All Cases. + /// + public static string AllCases { + get { + return ResourceManager.GetString("AllCases", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case. + /// + public static string Case { + get { + return ResourceManager.GetString("Case", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The permissions will be set to the cases where you are the author. + /// + public static string CasesAccessRightsLimit { + get { + return ResourceManager.GetString("CasesAccessRightsLimit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status. + /// + public static string CasesByStatus { + get { + return ResourceManager.GetString("CasesByStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case Participant. + /// + public static string CasesParticipant { + get { + return ResourceManager.GetString("CasesParticipant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case Participants. + /// + public static string CasesParticipants { + get { + return ResourceManager.GetString("CasesParticipants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case Tag. + /// + public static string CasesTag { + get { + return ResourceManager.GetString("CasesTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case Tag List. + /// + public static string CasesTagList { + get { + return ResourceManager.GetString("CasesTagList", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status. + /// + public static string CaseStatus { + get { + return ResourceManager.GetString("CaseStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed. + /// + public static string CaseStatusClosed { + get { + return ResourceManager.GetString("CaseStatusClosed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open. + /// + public static string CaseStatusOpened { + get { + return ResourceManager.GetString("CaseStatusOpened", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case title. + /// + public static string CaseTitle { + get { + return ResourceManager.GetString("CaseTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close case. + /// + public static string CloseCase { + get { + return ResourceManager.GetString("CloseCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating case.... + /// + public static string CreateCaseProggress { + get { + return ResourceManager.GetString("CreateCaseProggress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create the first case. + /// + public static string CreateFirstCase { + get { + return ResourceManager.GetString("CreateFirstCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new case. + /// + public static string CreateNewCase { + get { + return ResourceManager.GetString("CreateNewCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string CreateThisCaseButton { + get { + return ResourceManager.GetString("CreateThisCaseButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete case. + /// + public static string DeleteThisCase { + get { + return ResourceManager.GetString("DeleteThisCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting cases. + /// + public static string DeletingCases { + get { + return ResourceManager.GetString("DeletingCases", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit case. + /// + public static string EditCase { + get { + return ResourceManager.GetString("EditCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit the «{0}» case. + /// + public static string EditCaseHeader { + get { + return ResourceManager.GetString("EditCaseHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cases allow you to keep in one and the same place all the correspondence history, assign tasks, upload documents for the contacts who take part in a common event. For instance, it can be a team training or exhibition organization.. + /// + public static string EmptyContentCasesDescribe { + get { + return ResourceManager.GetString("EmptyContentCasesDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No cases matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the cases in this section. Or you can create the case if it is absent from the list.. + /// + public static string EmptyContentCasesFilterDescribe { + get { + return ResourceManager.GetString("EmptyContentCasesFilterDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No cases to be displayed for this filter here. + /// + public static string EmptyContentCasesFilterHeader { + get { + return ResourceManager.GetString("EmptyContentCasesFilterHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The case list is empty. + /// + public static string EmptyContentCasesHeader { + get { + return ResourceManager.GetString("EmptyContentCasesHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The participant list is empty. + /// + public static string EmptyPeopleInCaseContent { + get { + return ResourceManager.GetString("EmptyPeopleInCaseContent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add participants to your case from the list of companies or persons. After this is done you will know who is going to take part in the upcoming events associated with this case.. + /// + public static string EmptyPeopleInCaseDescript { + get { + return ResourceManager.GetString("EmptyPeopleInCaseDescript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import cases. + /// + public static string ImportCases { + get { + return ResourceManager.GetString("ImportCases", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by the selected delimiter which will be used to import cases. The files containing more than {0} rows should be divided into smaller parts for proper importing. Make sure you selected the portal users who need to be granted access to the information to be imported, otherwise the data from the CSV file will be available to all portal users.. + /// + public static string ImportFromCSVStepOneDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepOneDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a CSV file and set access rights before you import cases. + /// + public static string ImportFromCSVStepOneHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepOneHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import cases correctly you need to have at least one column from your file matched with the 'Case Title' field of the ONLYOFFICE™ CRM. The fields containing the dates must have the following format: {0}.. + /// + public static string ImportFromCSVStepTwoDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please, verify the fields. + /// + public static string ImportFromCSVStepTwoHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to cases list. + /// + public static string ImportStartingPanelButton { + get { + return ResourceManager.GetString("ImportStartingPanelButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import of cases can take several minutes depending on the amount of your data.. + /// + public static string ImportStartingPanelDescription { + get { + return ResourceManager.GetString("ImportStartingPanelDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Importing started. + /// + public static string ImportStartingPanelHeader { + get { + return ResourceManager.GetString("ImportStartingPanelHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case participants. + /// + public static string MembersCase { + get { + return ResourceManager.GetString("MembersCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open case. + /// + public static string OpenCase { + get { + return ResourceManager.GetString("OpenCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Participants. + /// + public static string PeopleInCase { + get { + return ResourceManager.GetString("PeopleInCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Restrict access to the case. + /// + public static string PrivatePanelCheckBoxLabel { + get { + return ResourceManager.GetString("PrivatePanelCheckBoxLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save Changes. + /// + public static string SaveChanges { + get { + return ResourceManager.GetString("SaveChanges", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to profile. + /// + public static string ShowCaseProfile { + get { + return ResourceManager.GetString("ShowCaseProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open in a new tab. + /// + public static string ShowCaseProfileNewTab { + get { + return ResourceManager.GetString("ShowCaseProfileNewTab", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start Importing. + /// + public static string StartImport { + get { + return ResourceManager.GetString("StartImport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All cases. + /// + public static string TotalCases { + get { + return ResourceManager.GetString("TotalCases", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMCasesResource.resx b/products/ASC.CRM/Server/Resources/CRMCasesResource.resx new file mode 100644 index 00000000000..16fa8a52375 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMCasesResource.resx @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Save and Create New Case + + + All Cases + + + Case + + + The permissions will be set to the cases where you are the author + + + Status + + + Case Participant + + + Case Participants + + + Case Tag + + + Case Tag List + + + Status + + + Closed + + + Open + + + Case title + + + Close case + + + Creating case... + + + Create the first case + + + Create new case + + + Save + + + Delete case + + + Deleting cases + + + Edit case + + + Edit the «{0}» case + + + Cases allow you to keep in one and the same place all the correspondence history, assign tasks, upload documents for the contacts who take part in a common event. For instance, it can be a team training or exhibition organization. + + + No cases matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the cases in this section. Or you can create the case if it is absent from the list. + + + No cases to be displayed for this filter here + + + The case list is empty + + + The participant list is empty + + + Add participants to your case from the list of companies or persons. After this is done you will know who is going to take part in the upcoming events associated with this case. + + + Import cases + + + A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by the selected delimiter which will be used to import cases. The files containing more than {0} rows should be divided into smaller parts for proper importing. Make sure you selected the portal users who need to be granted access to the information to be imported, otherwise the data from the CSV file will be available to all portal users. + + + Select a CSV file and set access rights before you import cases + + + Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import cases correctly you need to have at least one column from your file matched with the 'Case Title' field of the ONLYOFFICE™ CRM. The fields containing the dates must have the following format: {0}. + + + Please, verify the fields + + + Go to cases list + + + Import of cases can take several minutes depending on the amount of your data. + + + Importing started + + + Case participants + + + Open case + + + Participants + + + Restrict access to the case + + + Save Changes + + + Go to profile + + + Open in a new tab + + + Start Importing + + + All cases + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMCommonResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMCommonResource.Designer.cs new file mode 100644 index 00000000000..072470aff78 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMCommonResource.Designer.cs @@ -0,0 +1,3079 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMCommonResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMCommonResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMCommonResource", typeof(CRMCommonResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to for reading. + /// + public static string AccessRightsForReading { + get { + return ResourceManager.GetString("AccessRightsForReading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to for reading/writing. + /// + public static string AccessRightsForReadWriting { + get { + return ResourceManager.GetString("AccessRightsForReadWriting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The access rights will be set only for the contacts which were created by you.. + /// + public static string AccessRightsLimit { + get { + return ResourceManager.GetString("AccessRightsLimit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Actions. + /// + public static string Actions { + get { + return ResourceManager.GetString("Actions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add. + /// + public static string Add { + get { + return ResourceManager.GetString("Add", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add {!group}. + /// + public static string AddGroup { + get { + return ResourceManager.GetString("AddGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Additional information. + /// + public static string AdditionalInformation { + get { + return ResourceManager.GetString("AdditionalInformation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add mail account. + /// + public static string AddMailAccount { + get { + return ResourceManager.GetString("AddMailAccount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add Tag. + /// + public static string AddNewTag { + get { + return ResourceManager.GetString("AddNewTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add participant. + /// + public static string AddParticipant { + get { + return ResourceManager.GetString("AddParticipant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add This Event. + /// + public static string AddThisNote { + get { + return ResourceManager.GetString("AddThisNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding the note.... + /// + public static string AddThisNoteProggress { + get { + return ResourceManager.GetString("AddThisNoteProggress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add {!user}. + /// + public static string AddUser { + get { + return ResourceManager.GetString("AddUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use the {0}?{1} and {0}*{1} symbols to perform a single/multiple-character search. For example, to search for all the words beginning with {0}O{1}, use the {0}O*{1} query. It's not recommended to use these symbols at the beginning of your query. To search for the exact phrase use the quotation marks.{2}Learn more...{3}. + /// + public static string AdvansedFilterInfoText { + get { + return ResourceManager.GetString("AdvansedFilterInfoText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Alert. + /// + public static string Alert { + get { + return ResourceManager.GetString("Alert", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Corresponding ONLYOFFICE™ CRM field. + /// + public static string AssignedField { + get { + return ResourceManager.GetString("AssignedField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Attachments. + /// + public static string Attachments { + get { + return ResourceManager.GetString("Attachments", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link with contact. + /// + public static string AttachThisNoteToContact { + get { + return ResourceManager.GetString("AttachThisNoteToContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Author. + /// + public static string Author { + get { + return ResourceManager.GetString("Author", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Back. + /// + public static string Back { + get { + return ResourceManager.GetString("Back", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Learn more.... + /// + public static string ButtonLearnMore { + get { + return ResourceManager.GetString("ButtonLearnMore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Category. + /// + public static string ByCategory { + get { + return ResourceManager.GetString("ByCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to By title. + /// + public static string ByTitle { + get { + return ResourceManager.GetString("ByTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cancel. + /// + public static string Cancel { + get { + return ResourceManager.GetString("Cancel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case. + /// + public static string Case { + get { + return ResourceManager.GetString("Case", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cases. + /// + public static string CasesModuleName { + get { + return ResourceManager.GetString("CasesModuleName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Category. + /// + public static string Category { + get { + return ResourceManager.GetString("Category", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change. + /// + public static string Change { + get { + return ResourceManager.GetString("Change", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choose. + /// + public static string Choose { + get { + return ResourceManager.GetString("Choose", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reset filter. + /// + public static string ClearFilter { + get { + return ResourceManager.GetString("ClearFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close. + /// + public static string Close { + get { + return ResourceManager.GetString("Close", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close this window. + /// + public static string CloseThisWindow { + get { + return ResourceManager.GetString("CloseThisWindow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close window. + /// + public static string CloseWindow { + get { + return ResourceManager.GetString("CloseWindow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Colon. + /// + public static string Colon { + get { + return ResourceManager.GetString("Colon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File column. + /// + public static string Column { + get { + return ResourceManager.GetString("Column", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Comma. + /// + public static string Comma { + get { + return ResourceManager.GetString("Comma", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Compose Mail. + /// + public static string ComposeMail { + get { + return ResourceManager.GetString("ComposeMail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Compose a letter to be sent to all the clients selected in the contact list. You can check the number of selected clients in the 'To' field, enter a common 'Subject' and use the 'Personal tags' to include all the necessary information to your letter. This is a beta version for those who want to try out new features of ONLYOFFICE™ CRM.. + /// + public static string ComposeMailDescription { + get { + return ResourceManager.GetString("ComposeMailDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Confirmation. + /// + public static string Confirmation { + get { + return ResourceManager.GetString("Confirmation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Confirmation of changes. + /// + public static string ConfirmationAccessRightsPanelHeader { + get { + return ResourceManager.GetString("ConfirmationAccessRightsPanelHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You deleted yourself from contact managers.. + /// + public static string ConfirmationAccessRightsPanelText1 { + get { + return ResourceManager.GetString("ConfirmationAccessRightsPanelText1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You will lose access to the contact for reading and writing, if the appropriate access is not allowed for all CRM users.. + /// + public static string ConfirmationAccessRightsPanelText2 { + get { + return ResourceManager.GetString("ConfirmationAccessRightsPanelText2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete these elements?. + /// + public static string ConfirmationDeleteText { + get { + return ResourceManager.GetString("ConfirmationDeleteText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to To change the list of the contact temperature levels, refer to the CRM {0}Settings{1} section. + /// + public static string ContactCategoriesHelpInfo { + get { + return ResourceManager.GetString("ContactCategoriesHelpInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact settings. + /// + public static string ContactSettings { + get { + return ResourceManager.GetString("ContactSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Content. + /// + public static string Content { + get { + return ResourceManager.GetString("Content", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Date. + /// + public static string ConversionDate { + get { + return ResourceManager.GetString("ConversionDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rate. + /// + public static string ConversionRate { + get { + return ResourceManager.GetString("ConversionRate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency convertor. + /// + public static string ConversionRates { + get { + return ResourceManager.GetString("ConversionRates", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Convert. + /// + public static string Convert { + get { + return ResourceManager.GetString("Convert", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Quantity. + /// + public static string Count { + get { + return ResourceManager.GetString("Count", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create. + /// + public static string Create { + get { + return ResourceManager.GetString("Create", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creation date. + /// + public static string CreateDate { + get { + return ResourceManager.GetString("CreateDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create Invoices. + /// + public static string CreateInvoices { + get { + return ResourceManager.GetString("CreateInvoices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create New. + /// + public static string CreateNew { + get { + return ResourceManager.GetString("CreateNew", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create New Contact. + /// + public static string CreateNewContact { + get { + return ResourceManager.GetString("CreateNewContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create project. + /// + public static string CreateNewProject { + get { + return ResourceManager.GetString("CreateNewProject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add new tag. + /// + public static string CreateNewTag { + get { + return ResourceManager.GetString("CreateNewTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creation date. + /// + public static string CreationDate { + get { + return ResourceManager.GetString("CreationDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The CRM module is not enabled. + /// + public static string CRMProductIsDisabled { + get { + return ResourceManager.GetString("CRMProductIsDisabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency. + /// + public static string Currency { + get { + return ResourceManager.GetString("Currency", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Algerian Dinar. + /// + public static string Currency_AlgerianDinar { + get { + return ResourceManager.GetString("Currency_AlgerianDinar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Argentinian Peso. + /// + public static string Currency_ArgentinianPeso { + get { + return ResourceManager.GetString("Currency_ArgentinianPeso", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Armenian Dram. + /// + public static string Currency_ArmenianDram { + get { + return ResourceManager.GetString("Currency_ArmenianDram", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Australian Dollar. + /// + public static string Currency_AustralianDollar { + get { + return ResourceManager.GetString("Currency_AustralianDollar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Azerbaijani Manat. + /// + public static string Currency_AzerbaijaniManat { + get { + return ResourceManager.GetString("Currency_AzerbaijaniManat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bangladeshi Taka. + /// + public static string Currency_BangladeshiTaka { + get { + return ResourceManager.GetString("Currency_BangladeshiTaka", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Basic currencies. + /// + public static string Currency_Basic { + get { + return ResourceManager.GetString("Currency_Basic", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Belarusian Ruble. + /// + public static string Currency_BelarusianRuble { + get { + return ResourceManager.GetString("Currency_BelarusianRuble", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Brazilian Real. + /// + public static string Currency_BrazilianReal { + get { + return ResourceManager.GetString("Currency_BrazilianReal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bulgarian Lev. + /// + public static string Currency_BulgarianLev { + get { + return ResourceManager.GetString("Currency_BulgarianLev", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Canadian Dollar. + /// + public static string Currency_CanadianDollar { + get { + return ResourceManager.GetString("Currency_CanadianDollar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Central African Franc. + /// + public static string Currency_CentralAfricanFranc { + get { + return ResourceManager.GetString("Currency_CentralAfricanFranc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Chilean Peso. + /// + public static string Currency_ChileanPeso { + get { + return ResourceManager.GetString("Currency_ChileanPeso", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Chinese Yuan. + /// + public static string Currency_ChineseYuan { + get { + return ResourceManager.GetString("Currency_ChineseYuan", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Colombian Peso. + /// + public static string Currency_ColombianPeso { + get { + return ResourceManager.GetString("Currency_ColombianPeso", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Costa Rican Colón. + /// + public static string Currency_CostaRicanColon { + get { + return ResourceManager.GetString("Currency_CostaRicanColon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Croatian Kuna. + /// + public static string Currency_CroatianKuna { + get { + return ResourceManager.GetString("Currency_CroatianKuna", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cuban Peso. + /// + public static string Currency_CubanPeso { + get { + return ResourceManager.GetString("Currency_CubanPeso", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Czech Koruna. + /// + public static string Currency_CzechKoruna { + get { + return ResourceManager.GetString("Currency_CzechKoruna", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Danish Krone. + /// + public static string Currency_DanishKrone { + get { + return ResourceManager.GetString("Currency_DanishKrone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dominican Peso. + /// + public static string Currency_DominicanPeso { + get { + return ResourceManager.GetString("Currency_DominicanPeso", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Euro. + /// + public static string Currency_Euro { + get { + return ResourceManager.GetString("Currency_Euro", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Georgian Lari. + /// + public static string Currency_GeorgianLari { + get { + return ResourceManager.GetString("Currency_GeorgianLari", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hong Kong Dollar. + /// + public static string Currency_HongKongDollar { + get { + return ResourceManager.GetString("Currency_HongKongDollar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hungarian Forint. + /// + public static string Currency_HungarianForint { + get { + return ResourceManager.GetString("Currency_HungarianForint", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Indian Rupee. + /// + public static string Currency_IndianRupee { + get { + return ResourceManager.GetString("Currency_IndianRupee", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Indonesian Rupiah. + /// + public static string Currency_IndonesianRupiah { + get { + return ResourceManager.GetString("Currency_IndonesianRupiah", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Israeli Shekel. + /// + public static string Currency_IsraeliSheqel { + get { + return ResourceManager.GetString("Currency_IsraeliSheqel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Japanese Yen. + /// + public static string Currency_JapaneseYen { + get { + return ResourceManager.GetString("Currency_JapaneseYen", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Kazakhstani Tenge. + /// + public static string Currency_KazakhstaniTenge { + get { + return ResourceManager.GetString("Currency_KazakhstaniTenge", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Kenyan Shilling. + /// + public static string Currency_KenyanShilling { + get { + return ResourceManager.GetString("Currency_KenyanShilling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Kuwaiti Dinar. + /// + public static string Currency_KuwaitiDinar { + get { + return ResourceManager.GetString("Currency_KuwaitiDinar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Latvian Lat. + /// + public static string Currency_LatvianLats { + get { + return ResourceManager.GetString("Currency_LatvianLats", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lithuanian Litas. + /// + public static string Currency_LithuanianLitas { + get { + return ResourceManager.GetString("Currency_LithuanianLitas", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Malagasy Ariary. + /// + public static string Currency_MalagasyAriary { + get { + return ResourceManager.GetString("Currency_MalagasyAriary", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Malaysian Ringgit. + /// + public static string Currency_MalaysianRinggit { + get { + return ResourceManager.GetString("Currency_MalaysianRinggit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mauritian Rupee. + /// + public static string Currency_MauritianRupee { + get { + return ResourceManager.GetString("Currency_MauritianRupee", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mexican Peso. + /// + public static string Currency_MexicanPeso { + get { + return ResourceManager.GetString("Currency_MexicanPeso", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moldovan Leu. + /// + public static string Currency_MoldovanLeu { + get { + return ResourceManager.GetString("Currency_MoldovanLeu", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moroccan Dirham. + /// + public static string Currency_MoroccanDirham { + get { + return ResourceManager.GetString("Currency_MoroccanDirham", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Belarusian Ruble. + /// + public static string Currency_NewBelarusianRuble { + get { + return ResourceManager.GetString("Currency_NewBelarusianRuble", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Zealand Dollar. + /// + public static string Currency_NewZealandDollar { + get { + return ResourceManager.GetString("Currency_NewZealandDollar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Nigerian Naira. + /// + public static string Currency_NigerianNaira { + get { + return ResourceManager.GetString("Currency_NigerianNaira", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Norwegian Krone. + /// + public static string Currency_NorwegianKrone { + get { + return ResourceManager.GetString("Currency_NorwegianKrone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Omani Rial. + /// + public static string Currency_OmaniRial { + get { + return ResourceManager.GetString("Currency_OmaniRial", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other currencies. + /// + public static string Currency_Other { + get { + return ResourceManager.GetString("Currency_Other", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pacific franc. + /// + public static string Currency_PacificFranc { + get { + return ResourceManager.GetString("Currency_PacificFranc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pakistani Rupee. + /// + public static string Currency_PakistaniRupee { + get { + return ResourceManager.GetString("Currency_PakistaniRupee", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Philippine Peso. + /// + public static string Currency_PhilippinePeso { + get { + return ResourceManager.GetString("Currency_PhilippinePeso", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Polish Zloty. + /// + public static string Currency_PolishZloty { + get { + return ResourceManager.GetString("Currency_PolishZloty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pound Sterling. + /// + public static string Currency_PoundSterling { + get { + return ResourceManager.GetString("Currency_PoundSterling", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Qatari Riyal. + /// + public static string Currency_QatariRiyal { + get { + return ResourceManager.GetString("Currency_QatariRiyal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Romanian Leu. + /// + public static string Currency_RomanianLeu { + get { + return ResourceManager.GetString("Currency_RomanianLeu", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rouble. + /// + public static string Currency_Rouble { + get { + return ResourceManager.GetString("Currency_Rouble", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saudi Riyal. + /// + public static string Currency_SaudiRiyal { + get { + return ResourceManager.GetString("Currency_SaudiRiyal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Serbian Dinar. + /// + public static string Currency_SerbianDinar { + get { + return ResourceManager.GetString("Currency_SerbianDinar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Singapore Dollar. + /// + public static string Currency_SingaporeDollar { + get { + return ResourceManager.GetString("Currency_SingaporeDollar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to South African Rand. + /// + public static string Currency_SouthAfricanRand { + get { + return ResourceManager.GetString("Currency_SouthAfricanRand", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to South Korean Won. + /// + public static string Currency_SouthKoreanWon { + get { + return ResourceManager.GetString("Currency_SouthKoreanWon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Swedish Krona. + /// + public static string Currency_SwedishKrona { + get { + return ResourceManager.GetString("Currency_SwedishKrona", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Swiss Franc. + /// + public static string Currency_SwissFranc { + get { + return ResourceManager.GetString("Currency_SwissFranc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Thai Baht. + /// + public static string Currency_ThaiBaht { + get { + return ResourceManager.GetString("Currency_ThaiBaht", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Trinidad and Tobago Dollar. + /// + public static string Currency_TrinidadAndTobagoDollar { + get { + return ResourceManager.GetString("Currency_TrinidadAndTobagoDollar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tunisian Dinar. + /// + public static string Currency_TunisianDinar { + get { + return ResourceManager.GetString("Currency_TunisianDinar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Turkish New Lira. + /// + public static string Currency_TurkishNewLira { + get { + return ResourceManager.GetString("Currency_TurkishNewLira", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ukraine Hryvnia. + /// + public static string Currency_UkraineHryvnia { + get { + return ResourceManager.GetString("Currency_UkraineHryvnia", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to United Arab Emirates Dirham. + /// + public static string Currency_UnitedArabEmiratesDirham { + get { + return ResourceManager.GetString("Currency_UnitedArabEmiratesDirham", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to United States Dollar. + /// + public static string Currency_UnitedStatesDollar { + get { + return ResourceManager.GetString("Currency_UnitedStatesDollar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Uzbekistani Som. + /// + public static string Currency_UzbekistaniSom { + get { + return ResourceManager.GetString("Currency_UzbekistaniSom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Venezuelan Bolivar. + /// + public static string Currency_VenezuelanBolivar { + get { + return ResourceManager.GetString("Currency_VenezuelanBolivar", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Vietnamese Dong. + /// + public static string Currency_VietnameseDong { + get { + return ResourceManager.GetString("Currency_VietnameseDong", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to West African Franc. + /// + public static string Currency_WestAfricanFranc { + get { + return ResourceManager.GetString("Currency_WestAfricanFranc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current {!user}. + /// + public static string CurrentUser { + get { + return ResourceManager.GetString("CurrentUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom. + /// + public static string Custom { + get { + return ResourceManager.GetString("Custom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom period. + /// + public static string CustomDateFilter { + get { + return ResourceManager.GetString("CustomDateFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other users. + /// + public static string CustomResponsibleFilter { + get { + return ResourceManager.GetString("CustomResponsibleFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manage Relations with Customers. + /// + public static string DashboardTitle { + get { + return ResourceManager.GetString("DashboardTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fill in various contact details, link persons with companies.. + /// + public static string DashContactsDetails { + get { + return ResourceManager.GetString("DashContactsDetails", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add contacts manually or import the list from file.. + /// + public static string DashContactsImport { + get { + return ResourceManager.GetString("DashContactsImport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use the mass mailing feature to address multiple contacts.. + /// + public static string DashContactsMail { + get { + return ResourceManager.GetString("DashContactsMail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change CRM module settings, adapting it maximally to your needs.. + /// + public static string DashCustomizeCRM { + get { + return ResourceManager.GetString("DashCustomizeCRM", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Customize user fields, task categories or opportunity stages.. + /// + public static string DashCustomizeFields { + get { + return ResourceManager.GetString("DashCustomizeFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use website contact form to add new contacts right from your site.. + /// + public static string DashCustomizeWebsite { + get { + return ResourceManager.GetString("DashCustomizeWebsite", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Simplify invoice creation adding products and services.. + /// + public static string DashInvoiceProductsAndServices { + get { + return ResourceManager.GetString("DashInvoiceProductsAndServices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add taxes specific to certain countries and use them in invoices.. + /// + public static string DashInvoiceTaxes { + get { + return ResourceManager.GetString("DashInvoiceTaxes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Issue invoices to your clients right from the portal interface.. + /// + public static string DashIssueInvoices { + get { + return ResourceManager.GetString("DashIssueInvoices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add opportunities, set budget and estimate success probability.. + /// + public static string DashSalesOpportunities { + get { + return ResourceManager.GetString("DashSalesOpportunities", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Organize cases and specify the list of their participants.. + /// + public static string DashSalesParticipants { + get { + return ResourceManager.GetString("DashSalesParticipants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Assign tasks to CRM managers linking them with the contacts.. + /// + public static string DashSalesTasks { + get { + return ResourceManager.GetString("DashSalesTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Date. + /// + public static string Date { + get { + return ResourceManager.GetString("Date", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due in {0} day(s). + /// + public static string DateDueInDays { + get { + return ResourceManager.GetString("DateDueInDays", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} day(s) overdue. + /// + public static string DateOverueByDays { + get { + return ResourceManager.GetString("DateOverueByDays", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities. + /// + public static string DealModuleName { + get { + return ResourceManager.GetString("DealModuleName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete. + /// + public static string Delete { + get { + return ResourceManager.GetString("Delete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete contact. + /// + public static string DeleteContact { + get { + return ResourceManager.GetString("DeleteContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete event. + /// + public static string DeleteHistoryEvent { + get { + return ResourceManager.GetString("DeleteHistoryEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete participant. + /// + public static string DeleteParticipant { + get { + return ResourceManager.GetString("DeleteParticipant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete tag. + /// + public static string DeleteTag { + get { + return ResourceManager.GetString("DeleteTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete user. + /// + public static string DeleteUser { + get { + return ResourceManager.GetString("DeleteUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description. + /// + public static string Description { + get { + return ResourceManager.GetString("Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deselect all. + /// + public static string DeselectAll { + get { + return ResourceManager.GetString("DeselectAll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Documents. + /// + public static string Documents { + get { + return ResourceManager.GetString("Documents", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do the same for all future occurrences. + /// + public static string DontAskAnymore { + get { + return ResourceManager.GetString("DontAskAnymore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Double quote. + /// + public static string DoubleQuote { + get { + return ResourceManager.GetString("DoubleQuote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate Records. + /// + public static string DuplicateRecords { + get { + return ResourceManager.GetString("DuplicateRecords", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {!Users}. + /// + public static string Employees { + get { + return ResourceManager.GetString("Employees", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Be aware of what your clients think about your produce and brand in the social network.. + /// + public static string EmptyContentTwitterAccountsDescribe { + get { + return ResourceManager.GetString("EmptyContentTwitterAccountsDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No linked twitter accounts. + /// + public static string EmptyContentTwitterAccountsHeader { + get { + return ResourceManager.GetString("EmptyContentTwitterAccountsHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Empty file. + /// + public static string EmptyFileErrorMsg { + get { + return ResourceManager.GetString("EmptyFileErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No records matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the records in this section. You can also look for the records you need in other contact history.. + /// + public static string EmptyHistoryDescription { + get { + return ResourceManager.GetString("EmptyHistoryDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No records for this filter can be found here. + /// + public static string EmptyHistoryHeader { + get { + return ResourceManager.GetString("EmptyHistoryHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The opportunity participant list is empty. + /// + public static string EmptyPeopleInDealContent { + get { + return ResourceManager.GetString("EmptyPeopleInDealContent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter amount. + /// + public static string EnterAmount { + get { + return ResourceManager.GetString("EnterAmount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error. + /// + public static string Error { + get { + return ResourceManager.GetString("Error", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File size exceeds {1}{0}{2}. + /// + public static string ErrorMessage_UploadFileSize { + get { + return ResourceManager.GetString("ErrorMessage_UploadFileSize", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Export current list to CSV-file. + /// + public static string ExportCurrentListToCsvFile { + get { + return ResourceManager.GetString("ExportCurrentListToCsvFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Export data. + /// + public static string ExportData { + get { + return ResourceManager.GetString("ExportData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All exported files you can always see, download, edit, or delete them in {0}Documents/My Documents{1}. + /// + public static string ExportDataInfo { + get { + return ResourceManager.GetString("ExportDataInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Export data ({0}% complete). + /// + public static string ExportDataProgress { + get { + return ResourceManager.GetString("ExportDataProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File. + /// + public static string File { + get { + return ResourceManager.GetString("File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Files. + /// + public static string Files { + get { + return ResourceManager.GetString("Files", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The maximum file size is exceeded. + /// + public static string FileSizeErrorMsg { + get { + return ResourceManager.GetString("FileSizeErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creation date. + /// + public static string FilterByCreationDate { + get { + return ResourceManager.GetString("FilterByCreationDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due date. + /// + public static string FilterByDate { + get { + return ResourceManager.GetString("FilterByDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Responsible. + /// + public static string FilterByResponsible { + get { + return ResourceManager.GetString("FilterByResponsible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to With tag. + /// + public static string FilterWithTag { + get { + return ResourceManager.GetString("FilterWithTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find a company or a person by name.... + /// + public static string FindContactByName { + get { + return ResourceManager.GetString("FindContactByName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to From. + /// + public static string From { + get { + return ResourceManager.GetString("From", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hide. + /// + public static string Hide { + get { + return ResourceManager.GetString("Hide", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hide file attachment panel. + /// + public static string HideAttachPanel { + get { + return ResourceManager.GetString("HideAttachPanel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History. + /// + public static string History { + get { + return ResourceManager.GetString("History", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can change the list for categories of history events {0}here{1}. + /// + public static string HistoryCategoriesHelpInfo { + get { + return ResourceManager.GetString("HistoryCategoriesHelpInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Phone call. + /// + public static string HistoryCategory_Call { + get { + return ResourceManager.GetString("HistoryCategory_Call", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Email. + /// + public static string HistoryCategory_Email { + get { + return ResourceManager.GetString("HistoryCategory_Email", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Appointment. + /// + public static string HistoryCategory_Meeting { + get { + return ResourceManager.GetString("HistoryCategory_Meeting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Note. + /// + public static string HistoryCategory_Note { + get { + return ResourceManager.GetString("HistoryCategory_Note", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to has been received. + /// + public static string HistoryEventInboxMail { + get { + return ResourceManager.GetString("HistoryEventInboxMail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to has been sent. + /// + public static string HistoryEventOutboxMail { + get { + return ResourceManager.GetString("HistoryEventOutboxMail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Max. number of characters exceeded: {0}. + /// + public static string HistoryLongDataMsg { + get { + return ResourceManager.GetString("HistoryLongDataMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ignore the first row when importing. + /// + public static string IgnoreFirstRow { + get { + return ResourceManager.GetString("IgnoreFirstRow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate. + /// + public static string ImportFromCSV_DublicateBehavior_Clone { + get { + return ResourceManager.GetString("ImportFromCSV_DublicateBehavior_Clone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use this option to import contacts duplicating the coinciding contacts. E.g. there are two records - 'A' and 'B' - in your ONLYOFFICE™ CRM. You want to import 'B' and 'C' records. In case you select the 'Duplicate' option, a duplicate record to 'B' will be created while importing.. + /// + public static string ImportFromCSV_DublicateBehavior_CloneDescription { + get { + return ResourceManager.GetString("ImportFromCSV_DublicateBehavior_CloneDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Check for duplicates will be performed based on the Email field.. + /// + public static string ImportFromCSV_DublicateBehavior_Description { + get { + return ResourceManager.GetString("ImportFromCSV_DublicateBehavior_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overwrite. + /// + public static string ImportFromCSV_DublicateBehavior_Overwrite { + get { + return ResourceManager.GetString("ImportFromCSV_DublicateBehavior_Overwrite", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use this option to import contacts overwriting the existing contacts. E.g. there are two records - 'A' and 'B' - in your ONLYOFFICE™ CRM. You want to import 'B' and 'C' records. In case you select the 'Overwrite' option, the existing 'B' will be overwritten by the imported one while importing.. + /// + public static string ImportFromCSV_DublicateBehavior_OverwriteDescription { + get { + return ResourceManager.GetString("ImportFromCSV_DublicateBehavior_OverwriteDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Skip. + /// + public static string ImportFromCSV_DublicateBehavior_Skip { + get { + return ResourceManager.GetString("ImportFromCSV_DublicateBehavior_Skip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use this option to import contacts keeping the existing contacts. E.g. there are two records - 'A' and 'B' - in your ONLYOFFICE™ CRM. You want to import 'B' and 'C' records. In case you select the 'Skip' option, the existing 'B' will be preserved while importing.. + /// + public static string ImportFromCSV_DublicateBehavior_SkipDescription { + get { + return ResourceManager.GetString("ImportFromCSV_DublicateBehavior_SkipDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delimiter. + /// + public static string ImportFromCSV_ReadFileSettings_DelimiterCharacter { + get { + return ResourceManager.GetString("ImportFromCSV_ReadFileSettings_DelimiterCharacter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Encoding. + /// + public static string ImportFromCSV_ReadFileSettings_Encoding { + get { + return ResourceManager.GetString("ImportFromCSV_ReadFileSettings_Encoding", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CSV File Settings. + /// + public static string ImportFromCSV_ReadFileSettings_Header { + get { + return ResourceManager.GetString("ImportFromCSV_ReadFileSettings_Header", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text Delimiter. + /// + public static string ImportFromCSV_ReadFileSettings_QuoteCharacter { + get { + return ResourceManager.GetString("ImportFromCSV_ReadFileSettings_QuoteCharacter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scanning the file.... + /// + public static string ImportFromCSVStepOneProgressLable { + get { + return ResourceManager.GetString("ImportFromCSVStepOneProgressLable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start importing data. + /// + public static string ImportFromCSVStepTwoProgressLable { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoProgressLable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to Contact List. + /// + public static string ImportStartingPanelButton { + get { + return ResourceManager.GetString("ImportStartingPanelButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import of contacts can take several minutes depending on the amount of your data. You will be informed when it is done.. + /// + public static string ImportStartingPanelDescription { + get { + return ResourceManager.GetString("ImportStartingPanelDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Importing started. + /// + public static string ImportStartingPanelHeader { + get { + return ResourceManager.GetString("ImportStartingPanelHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Information is submitted. + /// + public static string InformationProvidedBy { + get { + return ResourceManager.GetString("InformationProvidedBy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoices. + /// + public static string InvoiceModuleName { + get { + return ResourceManager.GetString("InvoiceModuleName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice settings. + /// + public static string InvoiceSettings { + get { + return ResourceManager.GetString("InvoiceSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Taxes. + /// + public static string InvoiceTaxes { + get { + return ResourceManager.GetString("InvoiceTaxes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Last month. + /// + public static string LastMonth { + get { + return ResourceManager.GetString("LastMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Learn more.... + /// + public static string LearnMore { + get { + return ResourceManager.GetString("LearnMore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Letter Body. + /// + public static string LetterBody { + get { + return ResourceManager.GetString("LetterBody", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link with. + /// + public static string LinkTo { + get { + return ResourceManager.GetString("LinkTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to . + /// + public static string LoadingProcessing { + get { + return ResourceManager.GetString("LoadingProcessing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please wait .... + /// + public static string LoadingWait { + get { + return ResourceManager.GetString("LoadingWait", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Email body. + /// + public static string MailBody { + get { + return ResourceManager.GetString("MailBody", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Copy. + /// + public static string MailCopyTo { + get { + return ResourceManager.GetString("MailCopyTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to From. + /// + public static string MailFrom { + get { + return ResourceManager.GetString("MailFrom", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ONLYOFFICE™ Mass Send Feature: "{0}". + /// + public static string MailHistoryEventTemplate { + get { + return ResourceManager.GetString("MailHistoryEventTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sending Mail. + /// + public static string MailSend { + get { + return ResourceManager.GetString("MailSend", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Failed to deliver message to {0}. + /// + public static string MailSender_FailedDeliverException { + get { + return ResourceManager.GetString("MailSender_FailedDeliverException", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid email address: {0}. + /// + public static string MailSender_InvalidEmail { + get { + return ResourceManager.GetString("MailSender_InvalidEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delivery failed - will retry in {0} seconds.. + /// + public static string MailSender_MailboxBusyException { + get { + return ResourceManager.GetString("MailSender_MailboxBusyException", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Email subject. + /// + public static string MailSubject { + get { + return ResourceManager.GetString("MailSubject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to To. + /// + public static string MailTo { + get { + return ResourceManager.GetString("MailTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manage Contacts. + /// + public static string ManageContacts { + get { + return ResourceManager.GetString("ManageContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Message. + /// + public static string Message { + get { + return ResourceManager.GetString("Message", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calculator. + /// + public static string MoneyCalculator { + get { + return ResourceManager.GetString("MoneyCalculator", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to My. + /// + public static string My { + get { + return ResourceManager.GetString("My", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to My opportunities. + /// + public static string MyDeals { + get { + return ResourceManager.GetString("MyDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to My events. + /// + public static string MyEventsFilter { + get { + return ResourceManager.GetString("MyEventsFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to My tasks. + /// + public static string MyTasks { + get { + return ResourceManager.GetString("MyTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next record. + /// + public static string NextSample { + get { + return ResourceManager.GetString("NextSample", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No. + /// + public static string No { + get { + return ResourceManager.GetString("No", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No records. + /// + public static string NoLoadedMessages { + get { + return ResourceManager.GetString("NoLoadedMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No mail accounts available. + /// + public static string NoMailAccountsAvailableError { + get { + return ResourceManager.GetString("NoMailAccountsAvailableError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No matches. + /// + public static string NoMatches { + get { + return ResourceManager.GetString("NoMatches", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not specified. + /// + public static string NoSet { + get { + return ResourceManager.GetString("NoSet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Notify. + /// + public static string Notify { + get { + return ResourceManager.GetString("Notify", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Not specified. + /// + public static string NotSpecified { + get { + return ResourceManager.GetString("NotSpecified", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to OK. + /// + public static string OK { + get { + return ResourceManager.GetString("OK", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to On top. + /// + public static string OnTop { + get { + return ResourceManager.GetString("OnTop", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Organization Profile. + /// + public static string OrganisationProfile { + get { + return ResourceManager.GetString("OrganisationProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other. + /// + public static string Other { + get { + return ResourceManager.GetString("Other", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other settings. + /// + public static string OtherSettings { + get { + return ResourceManager.GetString("OtherSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overview. + /// + public static string Overview { + get { + return ResourceManager.GetString("Overview", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Share. + /// + public static string Part { + get { + return ResourceManager.GetString("Part", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please wait. + /// + public static string PleaseWait { + get { + return ResourceManager.GetString("PleaseWait", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Portal name. + /// + public static string PortalName { + get { + return ResourceManager.GetString("PortalName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Preview Mail. + /// + public static string PreviewMail { + get { + return ResourceManager.GetString("PreviewMail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Here you can see the letter you are composing. Use the 'Back' button to make some changes or use the 'Send' button, if you like the result.. + /// + public static string PreviewMailDescription { + get { + return ResourceManager.GetString("PreviewMailDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous record. + /// + public static string PrevSample { + get { + return ResourceManager.GetString("PrevSample", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous Step. + /// + public static string PrevStep { + get { + return ResourceManager.GetString("PrevStep", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to private. + /// + public static string Private { + get { + return ResourceManager.GetString("Private", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Available to {!users}. + /// + public static string PrivatePanelAccessListLable { + get { + return ResourceManager.GetString("PrivatePanelAccessListLable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Restrict access. + /// + public static string PrivatePanelCheckBoxLabel { + get { + return ResourceManager.GetString("PrivatePanelCheckBoxLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The access is granted to all the portal {!users} by default. To restrict the access check the box below. + /// . + /// + public static string PrivatePanelDescription { + get { + return ResourceManager.GetString("PrivatePanelDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Access rights. + /// + public static string PrivatePanelHeader { + get { + return ResourceManager.GetString("PrivatePanelHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do the same as CRM user|Import, export data|Send emails to CRM contacts|Manage settings|Manage any contact, task, case, opportunity. + /// + public static string ProductAdminOpportunities { + get { + return ResourceManager.GetString("ProductAdminOpportunities", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manage your customer relations, identify priority contacts, track communication history and sales performance.. + /// + public static string ProductDescription { + get { + return ResourceManager.GetString("ProductDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manage your customer relations, identify priority contacts, track communication history and sales performance.. + /// + public static string ProductDescriptionEx { + get { + return ResourceManager.GetString("ProductDescriptionEx", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. + /// + public static string ProductName { + get { + return ResourceManager.GetString("ProductName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Products & Services. + /// + public static string ProductsAndServices { + get { + return ResourceManager.GetString("ProductsAndServices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create contact, task, case, opportunity with a possibility to limit access to them|Edit contact, task, case, opportunity with the access rights set up. + /// + public static string ProductUserOpportunities { + get { + return ResourceManager.GetString("ProductUserOpportunities", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Profile. + /// + public static string Profile { + get { + return ResourceManager.GetString("Profile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Projects. + /// + public static string Projects { + get { + return ResourceManager.GetString("Projects", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Linked with. + /// + public static string RelativeTo { + get { + return ResourceManager.GetString("RelativeTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reports. + /// + public static string ReportsModuleName { + get { + return ResourceManager.GetString("ReportsModuleName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Responsible. + /// + public static string Responsible { + get { + return ResourceManager.GetString("Responsible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Value. + /// + public static string SampleValues { + get { + return ResourceManager.GetString("SampleValues", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string Save { + get { + return ResourceManager.GetString("Save", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save changes. + /// + public static string SaveChanges { + get { + return ResourceManager.GetString("SaveChanges", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving changes.... + /// + public static string SaveChangesProggress { + get { + return ResourceManager.GetString("SaveChangesProggress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select. + /// + public static string Select { + get { + return ResourceManager.GetString("Select", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select All. + /// + public static string SelectAll { + get { + return ResourceManager.GetString("SelectAll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Notify users. + /// + public static string SelectUsersToNotify { + get { + return ResourceManager.GetString("SelectUsersToNotify", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Semicolon. + /// + public static string Semicolon { + get { + return ResourceManager.GetString("Semicolon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send. + /// + public static string Send { + get { + return ResourceManager.GetString("Send", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send Email. + /// + public static string SendEmail { + get { + return ResourceManager.GetString("SendEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set Permissions. + /// + public static string SetPermissions { + get { + return ResourceManager.GetString("SetPermissions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Settings. + /// + public static string SettingModuleName { + get { + return ResourceManager.GetString("SettingModuleName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set up & Customize. + /// + public static string SetUpCustomize { + get { + return ResourceManager.GetString("SetUpCustomize", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show. + /// + public static string Show { + get { + return ResourceManager.GetString("Show", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show file attachment panel. + /// + public static string ShowAttachPanel { + get { + return ResourceManager.GetString("ShowAttachPanel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show information. + /// + public static string ShowInformation { + get { + return ResourceManager.GetString("ShowInformation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show more. + /// + public static string ShowMore { + get { + return ResourceManager.GetString("ShowMore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show on page. + /// + public static string ShowOnPage { + get { + return ResourceManager.GetString("ShowOnPage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Single quote . + /// + public static string SingleQuote { + get { + return ResourceManager.GetString("SingleQuote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Space. + /// + public static string Space { + get { + return ResourceManager.GetString("Space", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Store this message in History. + /// + public static string StoreThisLetterInHistory { + get { + return ResourceManager.GetString("StoreThisLetterInHistory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Subject. + /// + public static string Subject { + get { + return ResourceManager.GetString("Subject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New events. + /// + public static string SubscriptionType_AddRelationshipEvent { + get { + return ResourceManager.GetString("SubscriptionType_AddRelationshipEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New contacts. + /// + public static string SubscriptionType_CreateNewContact { + get { + return ResourceManager.GetString("SubscriptionType_CreateNewContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Export completed. + /// + public static string SubscriptionType_ExportCompleted { + get { + return ResourceManager.GetString("SubscriptionType_ExportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import completed. + /// + public static string SubscriptionType_ImportCompleted { + get { + return ResourceManager.GetString("SubscriptionType_ImportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Responsible for opportunity. + /// + public static string SubscriptionType_ResponsibleForOpportunity { + get { + return ResourceManager.GetString("SubscriptionType_ResponsibleForOpportunity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks assigned to you. + /// + public static string SubscriptionType_ResponsibleForTask { + get { + return ResourceManager.GetString("SubscriptionType_ResponsibleForTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Access granted. + /// + public static string SubscriptionType_SetAccess { + get { + return ResourceManager.GetString("SubscriptionType_SetAccess", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Summary table. + /// + public static string SummaryTable { + get { + return ResourceManager.GetString("SummaryTable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tabulation. + /// + public static string Tabulation { + get { + return ResourceManager.GetString("Tabulation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tags. + /// + public static string Tags { + get { + return ResourceManager.GetString("Tags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks. + /// + public static string TaskModuleName { + get { + return ResourceManager.GetString("TaskModuleName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The email. + /// + public static string TheEmail { + get { + return ResourceManager.GetString("TheEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This month. + /// + public static string ThisMonth { + get { + return ResourceManager.GetString("ThisMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Title. + /// + public static string Title { + get { + return ResourceManager.GetString("Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to To. + /// + public static string To { + get { + return ResourceManager.GetString("To", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Today. + /// + public static string Today { + get { + return ResourceManager.GetString("Today", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total. + /// + public static string Total { + get { + return ResourceManager.GetString("Total", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Track Sales. + /// + public static string TrackSales { + get { + return ResourceManager.GetString("TrackSales", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type. + /// + public static string Type { + get { + return ResourceManager.GetString("Type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Company/Person. + /// + public static string TypeCompanyOrPerson { + get { + return ResourceManager.GetString("TypeCompanyOrPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unlink contact. + /// + public static string UnlinkContact { + get { + return ResourceManager.GetString("UnlinkContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Up. + /// + public static string Up { + get { + return ResourceManager.GetString("Up", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Attach file. + /// + public static string UploadFile { + get { + return ResourceManager.GetString("UploadFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show files. + /// + public static string ViewFiles { + get { + return ResourceManager.GetString("ViewFiles", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to View mailing history with this participant. + /// + public static string ViewMailingHistoryWithParticipant { + get { + return ResourceManager.GetString("ViewMailingHistoryWithParticipant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calls. + /// + public static string VoIPCallsSettings { + get { + return ResourceManager.GetString("VoIPCallsSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Common. + /// + public static string VoIPCommonSettings { + get { + return ResourceManager.GetString("VoIPCommonSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Numbers. + /// + public static string VoIPNumbersSettings { + get { + return ResourceManager.GetString("VoIPNumbersSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to VoIP Settings. + /// + public static string VoIPSettings { + get { + return ResourceManager.GetString("VoIPSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Whole CRM module. + /// + public static string WholeCRMModule { + get { + return ResourceManager.GetString("WholeCRMModule", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yes. + /// + public static string Yes { + get { + return ResourceManager.GetString("Yes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yesterday. + /// + public static string Yesterday { + get { + return ResourceManager.GetString("Yesterday", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMCommonResource.resx b/products/ASC.CRM/Server/Resources/CRMCommonResource.resx new file mode 100644 index 00000000000..f750289c13b --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMCommonResource.resx @@ -0,0 +1,1126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + for reading + + + for reading/writing + + + The access rights will be set only for the contacts which were created by you. + + + Actions + + + Add + + + Add {!group} + + + Additional information + + + Add mail account + + + Add Tag + + + Add participant + + + Add This Event + + + Adding the note... + + + Add {!user} + + + Use the {0}?{1} and {0}*{1} symbols to perform a single/multiple-character search. For example, to search for all the words beginning with {0}O{1}, use the {0}O*{1} query. It's not recommended to use these symbols at the beginning of your query. To search for the exact phrase use the quotation marks.{2}Learn more...{3} + + + Alert + + + Corresponding ONLYOFFICE™ CRM field + + + Attachments + + + Link with contact + + + Author + + + Back + + + Learn more... + + + Category + + + By title + + + Cancel + + + Case + + + Cases + + + Category + + + Change + + + Choose + + + Reset filter + + + Close + + + Close this window + + + Close window + + + Colon + + + File column + + + Comma + + + Compose Mail + + + Compose a letter to be sent to all the clients selected in the contact list. You can check the number of selected clients in the 'To' field, enter a common 'Subject' and use the 'Personal tags' to include all the necessary information to your letter. This is a beta version for those who want to try out new features of ONLYOFFICE™ CRM. + + + Confirmation + + + Are you sure you want to delete these elements? + + + To change the list of the contact temperature levels, refer to the CRM {0}Settings{1} section + + + Contact settings + + + Content + + + Date + + + Rate + + + Currency convertor + + + Convert + + + Quantity + + + Create + + + Creation date + + + Create Invoices + + + Create New + + + Create New Contact + + + Create project + + + Add new tag + + + The CRM module is not enabled + + + Currency + + + Algerian Dinar + + + Argentinian Peso + + + Armenian Dram + + + Australian Dollar + + + Azerbaijani Manat + + + Bangladeshi Taka + + + Basic currencies + + + Belarusian Ruble + + + Brazilian Real + + + Bulgarian Lev + + + Canadian Dollar + + + Central African Franc + + + Chilean Peso + + + Chinese Yuan + + + Colombian Peso + + + Costa Rican Colón + + + Croatian Kuna + + + Cuban Peso + + + Czech Koruna + + + Danish Krone + + + Dominican Peso + + + Euro + + + Georgian Lari + + + Hong Kong Dollar + + + Hungarian Forint + + + Indian Rupee + + + Indonesian Rupiah + + + Israeli Shekel + + + Japanese Yen + + + Kazakhstani Tenge + + + Kenyan Shilling + + + Kuwaiti Dinar + + + Latvian Lat + + + Lithuanian Litas + + + Malagasy Ariary + + + Malaysian Ringgit + + + Mauritian Rupee + + + Mexican Peso + + + Moldovan Leu + + + Moroccan Dirham + + + New Zealand Dollar + + + Nigerian Naira + + + Norwegian Krone + + + Omani Rial + + + Other currencies + + + Pakistani Rupee + + + Philippine Peso + + + Polish Zloty + + + Pound Sterling + + + Rouble + + + Saudi Riyal + + + Singapore Dollar + + + South African Rand + + + South Korean Won + + + Swedish Krona + + + Swiss Franc + + + Thai Baht + + + Trinidad and Tobago Dollar + + + Turkish New Lira + + + Ukraine Hryvnia + + + United Arab Emirates Dirham + + + United States Dollar + + + Uzbekistani Som + + + Venezuelan Bolivar + + + Vietnamese Dong + + + West African Franc + + + Current {!user} + + + Custom + + + Custom period + + + Other users + + + Manage Relations with Customers + + + Fill in various contact details, link persons with companies. + + + Add contacts manually or import the list from file. + + + Use the mass mailing feature to address multiple contacts. + + + Change CRM module settings, adapting it maximally to your needs. + + + Customize user fields, task categories or opportunity stages. + + + Use website contact form to add new contacts right from your site. + + + Simplify invoice creation adding products and services. + + + Add taxes specific to certain countries and use them in invoices. + + + Issue invoices to your clients right from the portal interface. + + + Add opportunities, set budget and estimate success probability. + + + Organize cases and specify the list of their participants. + + + Assign tasks to CRM managers linking them with the contacts. + + + Date + + + Due in {0} day(s) + + + {0} day(s) overdue + + + Opportunities + + + Delete + + + Delete contact + + + Delete event + + + Delete participant + + + Delete tag + + + Delete user + + + Description + + + Deselect all + + + Documents + + + Do the same for all future occurrences + + + Double quote + + + Duplicate Records + + + {!Users} + + + Be aware of what your clients think about your produce and brand in the social network. + + + No linked twitter accounts + + + Empty file + + + No records matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the records in this section. You can also look for the records you need in other contact history. + + + No records for this filter can be found here + + + The opportunity participant list is empty + + + Enter amount + + + Error + + + File size exceeds {1}{0}{2} + + + Export current list to CSV-file + + + File + + + Files + + + The maximum file size is exceeded + + + Creation date + + + Due date + + + Responsible + + + With tag + + + Find a company or a person by name... + + + From + + + Hide + + + Hide file attachment panel + + + History + + + You can change the list for categories of history events {0}here{1} + + + Phone call + + + Email + + + Appointment + + + Note + + + has been received + + + has been sent + + + Max. number of characters exceeded: {0} + + + Ignore the first row when importing + + + Duplicate + + + Use this option to import contacts duplicating the coinciding contacts. E.g. there are two records - 'A' and 'B' - in your ONLYOFFICE™ CRM. You want to import 'B' and 'C' records. In case you select the 'Duplicate' option, a duplicate record to 'B' will be created while importing. + + + Check for duplicates will be performed based on the Email field. + + + Overwrite + + + Use this option to import contacts overwriting the existing contacts. E.g. there are two records - 'A' and 'B' - in your ONLYOFFICE™ CRM. You want to import 'B' and 'C' records. In case you select the 'Overwrite' option, the existing 'B' will be overwritten by the imported one while importing. + + + Skip + + + Use this option to import contacts keeping the existing contacts. E.g. there are two records - 'A' and 'B' - in your ONLYOFFICE™ CRM. You want to import 'B' and 'C' records. In case you select the 'Skip' option, the existing 'B' will be preserved while importing. + + + Delimiter + + + Encoding + + + CSV File Settings + + + Text Delimiter + + + Scanning the file... + + + Start importing data + + + Go to Contact List + + + Import of contacts can take several minutes depending on the amount of your data. You will be informed when it is done. + + + Importing started + + + Information is submitted + + + Invoices + + + Invoice settings + + + Taxes + + + Last month + + + Learn more... + + + Letter Body + + + Link with + + + + + + Please wait ... + + + Email body + + + Copy + + + From + + + ONLYOFFICE™ Mass Send Feature: "{0}" + + + Sending Mail + + + Failed to deliver message to {0} + + + Invalid email address: {0} + + + Email subject + + + To + + + Manage Contacts + + + Message + + + Calculator + + + My + + + My opportunities + + + My events + + + My tasks + + + Next record + + + No + + + No records + + + No mail accounts available + + + No matches + + + Not specified + + + Notify + + + Not specified + + + OK + + + On top + + + Organization Profile + + + Other + + + Other settings + + + Overview + + + Share + + + Please wait + + + Portal name + + + Preview Mail + + + Here you can see the letter you are composing. Use the 'Back' button to make some changes or use the 'Send' button, if you like the result. + + + Previous record + + + Previous Step + + + private + + + Available to {!users} + + + Restrict access + + + The access is granted to all the portal {!users} by default. To restrict the access check the box below. + + + + Access rights + + + Do the same as CRM user|Import, export data|Send emails to CRM contacts|Manage settings|Manage any contact, task, case, opportunity + + + Manage your customer relations, identify priority contacts, track communication history and sales performance. + + + Manage your customer relations, identify priority contacts, track communication history and sales performance. + + + CRM + + + Products & Services + + + Create contact, task, case, opportunity with a possibility to limit access to them|Edit contact, task, case, opportunity with the access rights set up + + + Profile + + + Projects + + + Linked with + + + Responsible + + + Value + + + Save + + + Save changes + + + Saving changes... + + + Select + + + Select All + + + Notify users + + + Semicolon + + + Send + + + Send Email + + + Set Permissions + + + Settings + + + Set up & Customize + + + Show + + + Show file attachment panel + + + Show information + + + Show more + + + Show on page + + + Single quote + + + Space + + + Store this message in History + + + Subject + + + New events + + + New contacts + + + Export completed + + + Import completed + + + Responsible for opportunity + + + Tasks assigned to you + + + Access granted + + + Summary table + + + Tabulation + + + Tags + + + Tasks + + + The email + + + This month + + + Title + + + To + + + Today + + + Total + + + Track Sales + + + Type + + + Company/Person + + + Unlink contact + + + Up + + + Attach file + + + Show files + + + View mailing history with this participant + + + Calls + + + Common + + + Numbers + + + VoIP Settings + + + Yes + + + Yesterday + + + Romanian Leu + + + New Belarusian Ruble + + + Creation date + + + Reports + + + Confirmation of changes + + + You deleted yourself from contact managers. + + + You will lose access to the contact for reading and writing, if the appropriate access is not allowed for all CRM users. + + + Pacific franc + + + Export data + + + Export data ({0}% complete) + + + Delivery failed - will retry in {0} seconds. + + + All exported files you can always see, download, edit, or delete them in {0}Documents/My Documents{1} + + + Whole CRM module + + + Serbian Dinar + + + Tunisian Dinar + + + Qatari Riyal + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMContactResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMContactResource.Designer.cs new file mode 100644 index 00000000000..288307b658c --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMContactResource.Designer.cs @@ -0,0 +1,1867 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMContactResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMContactResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMContactResource", typeof(CRMContactResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Abort Blanket Mailing. + /// + public static string AbortMassSend { + get { + return ResourceManager.GetString("AbortMassSend", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Note. + /// + public static string About { + get { + return ResourceManager.GetString("About", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding company.... + /// + public static string AddingCompany { + get { + return ResourceManager.GetString("AddingCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding contact.... + /// + public static string AddingPersonProgress { + get { + return ResourceManager.GetString("AddingPersonProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Additional information. + /// + public static string AdditionalContactInformation { + get { + return ResourceManager.GetString("AdditionalContactInformation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add new address. + /// + public static string AddNewAddress { + get { + return ResourceManager.GetString("AddNewAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add new company. + /// + public static string AddNewCompany { + get { + return ResourceManager.GetString("AddNewCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add new person. + /// + public static string AddNewContact { + get { + return ResourceManager.GetString("AddNewContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add email. + /// + public static string AddNewEmail { + get { + return ResourceManager.GetString("AddNewEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add phone. + /// + public static string AddNewPhone { + get { + return ResourceManager.GetString("AddNewPhone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This default action can be changed {0}here{1}. + /// + public static string AddTagToContactGroupHelpForAdmin { + get { + return ResourceManager.GetString("AddTagToContactGroupHelpForAdmin", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only CRM administrator can reset this parameter afterwards. + /// + public static string AddTagToContactGroupHelpForUser { + get { + return ResourceManager.GetString("AddTagToContactGroupHelpForUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save and Create New Company. + /// + public static string AddThisAndCreateCompanyButton { + get { + return ResourceManager.GetString("AddThisAndCreateCompanyButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save and Create New Person. + /// + public static string AddThisAndCreatePeopleButton { + get { + return ResourceManager.GetString("AddThisAndCreatePeopleButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisCompanyButton { + get { + return ResourceManager.GetString("AddThisCompanyButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisPersonButton { + get { + return ResourceManager.GetString("AddThisPersonButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add to Letter Body. + /// + public static string AddToLetterBody { + get { + return ResourceManager.GetString("AddToLetterBody", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Temperature level. + /// + public static string AfterStage { + get { + return ResourceManager.GetString("AfterStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All Contacts. + /// + public static string AllContacts { + get { + return ResourceManager.GetString("AllContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All persons. + /// + public static string AllPersons { + get { + return ResourceManager.GetString("AllPersons", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link or add person. + /// + public static string AssignContact { + get { + return ResourceManager.GetString("AssignContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select from existing contacts. + /// + public static string AssignContactFromExisting { + get { + return ResourceManager.GetString("AssignContactFromExisting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Assign manager to this contact. + /// + public static string AssignContactManager { + get { + return ResourceManager.GetString("AssignContactManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select from existing persons or add a new one. + /// + public static string AssignPersonFromExisting { + get { + return ResourceManager.GetString("AssignPersonFromExisting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link or add project. + /// + public static string AssignProject { + get { + return ResourceManager.GetString("AssignProject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Batch size. + /// + public static string BatchSize { + get { + return ResourceManager.GetString("BatchSize", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to We suggest that you send your emails in batch quantities for the mailing software to work efficiently. You can change the number of recipients per batch if you wish.. + /// + public static string BatchSizeInfoText { + get { + return ResourceManager.GetString("BatchSizeInfoText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hide email addresses from recipients?. + /// + public static string BlindLinkInfoText { + get { + return ResourceManager.GetString("BlindLinkInfoText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new company. + /// + public static string BreadCrumbsAddCompany { + get { + return ResourceManager.GetString("BreadCrumbsAddCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new person. + /// + public static string BreadCrumbsAddPerson { + get { + return ResourceManager.GetString("BreadCrumbsAddPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manager. + /// + public static string ByContactManager { + get { + return ResourceManager.GetString("ByContactManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add to company only. + /// + public static string CancelAddContactTagToGroupForCompany { + get { + return ResourceManager.GetString("CancelAddContactTagToGroupForCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add to person only. + /// + public static string CancelAddContactTagToGroupForPerson { + get { + return ResourceManager.GetString("CancelAddContactTagToGroupForPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No, for current contact only. + /// + public static string CancelContactStatusGroupChange { + get { + return ResourceManager.GetString("CancelContactStatusGroupChange", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete from company only. + /// + public static string CancelDeleteContactTagFromGroupForCompany { + get { + return ResourceManager.GetString("CancelDeleteContactTagFromGroupForCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete from person only. + /// + public static string CancelDeleteContactTagFromGroupForPerson { + get { + return ResourceManager.GetString("CancelDeleteContactTagFromGroupForPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No category is specified. + /// + public static string CategoryNotSpecified { + get { + return ResourceManager.GetString("CategoryNotSpecified", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change photo. + /// + public static string ChangePhoto { + get { + return ResourceManager.GetString("ChangePhoto", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change photo to default. + /// + public static string ChangePhotoToDefault { + get { + return ResourceManager.GetString("ChangePhotoToDefault", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choose a profile photo. + /// + public static string ChooseProfilePhoto { + get { + return ResourceManager.GetString("ChooseProfilePhoto", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Companies. + /// + public static string Companies { + get { + return ResourceManager.GetString("Companies", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Company. + /// + public static string Company { + get { + return ResourceManager.GetString("Company", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Company Name. + /// + public static string CompanyName { + get { + return ResourceManager.GetString("CompanyName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Some persons are linked with this company. + ///Do you want to add this tag to all these persons as well?. + /// + public static string ConfirmationAddTagToCompanyGroup { + get { + return ResourceManager.GetString("ConfirmationAddTagToCompanyGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This person belongs to a company. + ///Do you want to add this tag also to the company and to all its persons?. + /// + public static string ConfirmationAddTagToPersonGroup { + get { + return ResourceManager.GetString("ConfirmationAddTagToPersonGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do you want to change the contact status of the company this person is linked with?. + /// + public static string ConfirmationChangeCompanyStatus { + get { + return ResourceManager.GetString("ConfirmationChangeCompanyStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do you want to change the contact status of all the persons linked with this company?. + /// + public static string ConfirmationChangePersonsStatus { + get { + return ResourceManager.GetString("ConfirmationChangePersonsStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This company has linked persons. + ///Do you want to delete this tag also from all persons linked with this company?. + /// + public static string ConfirmationDeleteTagFromCompanyGroup { + get { + return ResourceManager.GetString("ConfirmationDeleteTagFromCompanyGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This person belongs to a company. + ///Do you want to delete this tag also from the company and from all its persons?. + /// + public static string ConfirmationDeleteTagFromPersonGroup { + get { + return ResourceManager.GetString("ConfirmationDeleteTagFromPersonGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact. + /// + public static string Contact { + get { + return ResourceManager.GetString("Contact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact manager. + /// + public static string ContactManager { + get { + return ResourceManager.GetString("ContactManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can upload an image file in PNG or JPG format not larger than {1}200x300 pixels{2}, otherwise resizing will take place. The maximum image size cannot exceed {1}{0}{2}.. + /// + public static string ContactPhotoInfo { + get { + return ResourceManager.GetString("ContactPhotoInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contacts. + /// + public static string Contacts { + get { + return ResourceManager.GetString("Contacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Temperature Level. + /// + public static string ContactStage { + get { + return ResourceManager.GetString("ContactStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Temperature Levels. + /// + public static string ContactStages { + get { + return ResourceManager.GetString("ContactStages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cold. + /// + public static string ContactStatus_Cold { + get { + return ResourceManager.GetString("ContactStatus_Cold", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hot. + /// + public static string ContactStatus_Hot { + get { + return ResourceManager.GetString("ContactStatus_Hot", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warm. + /// + public static string ContactStatus_Warm { + get { + return ResourceManager.GetString("ContactStatus_Warm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This default action can be changed {0}here{1}. + /// + public static string ContactStatusGroupChangeHelpForAdmin { + get { + return ResourceManager.GetString("ContactStatusGroupChangeHelpForAdmin", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only CRM administrator can reset this parameter afterwards. + /// + public static string ContactStatusGroupChangeHelpForUser { + get { + return ResourceManager.GetString("ContactStatusGroupChangeHelpForUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Tag. + /// + public static string ContactTag { + get { + return ResourceManager.GetString("ContactTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Tag List. + /// + public static string ContactTagList { + get { + return ResourceManager.GetString("ContactTagList", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Tags. + /// + public static string ContactTags { + get { + return ResourceManager.GetString("ContactTags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Name. + /// + public static string ContactTitle { + get { + return ResourceManager.GetString("ContactTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter your Twitter account name. For example, teamlabdotcom. + /// + public static string ContactTwitterDescription { + get { + return ResourceManager.GetString("ContactTwitterDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Type. + /// + public static string ContactType { + get { + return ResourceManager.GetString("ContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Client. + /// + public static string ContactType_Client { + get { + return ResourceManager.GetString("ContactType_Client", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Competitor. + /// + public static string ContactType_Competitor { + get { + return ResourceManager.GetString("ContactType_Competitor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Partner. + /// + public static string ContactType_Partner { + get { + return ResourceManager.GetString("ContactType_Partner", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Supplier. + /// + public static string ContactType_Supplier { + get { + return ResourceManager.GetString("ContactType_Supplier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Web Site/Social Networks. + /// + public static string ContactWebSiteAndSocialProfiles { + get { + return ResourceManager.GetString("ContactWebSiteAndSocialProfiles", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Content. + /// + public static string Content { + get { + return ResourceManager.GetString("Content", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Continue. + /// + public static string Continue { + get { + return ResourceManager.GetString("Continue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create the first company. + /// + public static string CreateFirstCompany { + get { + return ResourceManager.GetString("CreateFirstCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create the first person. + /// + public static string CreateFirstPerson { + get { + return ResourceManager.GetString("CreateFirstPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create project. + /// + public static string CreateProject { + get { + return ResourceManager.GetString("CreateProject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create task. + /// + public static string CreateTask { + get { + return ResourceManager.GetString("CreateTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Customer. + /// + public static string Customer { + get { + return ResourceManager.GetString("Customer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Companies. + /// + public static string Dashboard { + get { + return ResourceManager.GetString("Dashboard", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete contact. + /// + public static string DeleteContact { + get { + return ResourceManager.GetString("DeleteContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This default action can be changed {0}here{1}. + /// + public static string DeleteTagFromContactGroupHelpForAdmin { + get { + return ResourceManager.GetString("DeleteTagFromContactGroupHelpForAdmin", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only CRM administrator will be able to reset this parameter in future. + /// + public static string DeleteTagFromContactGroupHelpForUser { + get { + return ResourceManager.GetString("DeleteTagFromContactGroupHelpForUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete company. + /// + public static string DeleteThisCompany { + get { + return ResourceManager.GetString("DeleteThisCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete person. + /// + public static string DeleteThisPerson { + get { + return ResourceManager.GetString("DeleteThisPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting contacts. + /// + public static string DeletingContacts { + get { + return ResourceManager.GetString("DeletingContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deselect all. + /// + public static string DeselectAll { + get { + return ResourceManager.GetString("DeselectAll", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do not import this field. + /// + public static string DoNotImportThisField { + get { + return ResourceManager.GetString("DoNotImportThisField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit. + /// + public static string Edit { + get { + return ResourceManager.GetString("Edit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit company «{0}». + /// + public static string EditCompany { + get { + return ResourceManager.GetString("EditCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit contact. + /// + public static string EditContact { + get { + return ResourceManager.GetString("EditContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit person «{0}». + /// + public static string EditPerson { + get { + return ResourceManager.GetString("EditPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit company. + /// + public static string EditProfileCompany { + get { + return ResourceManager.GetString("EditProfileCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit person. + /// + public static string EditProfilePerson { + get { + return ResourceManager.GetString("EditProfilePerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Email. + /// + public static string Email { + get { + return ResourceManager.GetString("Email", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keep all the contacts your company works with in one place. Add new companies and persons, divide them into {0}types{1}, link with each other, add personal information. Import multiple contacts that you already have from a {2}CSV file{3} at one go.. + /// + public static string EmptyContactListDescription { + get { + return ResourceManager.GetString("EmptyContactListDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No contacts matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the contacts in this section. Or you can create the contact in case it is absent from the list.. + /// + public static string EmptyContactListFilterDescribe { + get { + return ResourceManager.GetString("EmptyContactListFilterDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No contacts to be displayed for this filter here. + /// + public static string EmptyContactListFilterHeader { + get { + return ResourceManager.GetString("EmptyContactListFilterHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The contact list is empty. + /// + public static string EmptyContactListHeader { + get { + return ResourceManager.GetString("EmptyContactListHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select the existing projects from the list to link them with the CRM contacts, or go to the Projects module to create new projects. This will help you organize your workflow and make plans. A deeper integration with the projects will help you manage your work more efficiently.. + /// + public static string EmptyContactProjectListDescription { + get { + return ResourceManager.GetString("EmptyContactProjectListDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You haven't got the permission to link contacts with projects. You need to be project manager or portal administrator to be able to do that.. + /// + public static string EmptyContactProjectListDescriptionWithoutButton { + get { + return ResourceManager.GetString("EmptyContactProjectListDescriptionWithoutButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The project list is empty. + /// + public static string EmptyContactProjectListHeader { + get { + return ResourceManager.GetString("EmptyContactProjectListHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add persons here creating new people or linking the existing ones to the companies they work for. When a person is created, you can fill all the contact information for him/her and set the access rights level for other portal users.. + /// + public static string EmptyContentPeopleDescribe { + get { + return ResourceManager.GetString("EmptyContentPeopleDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The person list is empty. + /// + public static string EmptyContentPeopleHeader { + get { + return ResourceManager.GetString("EmptyContentPeopleHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter a company name. + /// + public static string ErrorEmptyCompanyName { + get { + return ResourceManager.GetString("ErrorEmptyCompanyName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter a first name. + /// + public static string ErrorEmptyContactFirstName { + get { + return ResourceManager.GetString("ErrorEmptyContactFirstName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The uploaded file could not be found. + /// + public static string ErrorEmptyUploadFileSelected { + get { + return ResourceManager.GetString("ErrorEmptyUploadFileSelected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid email. + /// + public static string ErrorInvalidEmail { + get { + return ResourceManager.GetString("ErrorInvalidEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid phone number. + /// + public static string ErrorInvalidPhone { + get { + return ResourceManager.GetString("ErrorInvalidPhone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to all users (including the deleted users). + /// + public static string Everyone { + get { + return ResourceManager.GetString("Everyone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Files. + /// + public static string Files { + get { + return ResourceManager.GetString("Files", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Accessibility. + /// + public static string FilterByAccessibility { + get { + return ResourceManager.GetString("FilterByAccessibility", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manager. + /// + public static string FilterByContactManager { + get { + return ResourceManager.GetString("FilterByContactManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find a company by name.... + /// + public static string FindCompanyByName { + get { + return ResourceManager.GetString("FindCompanyByName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find a person by name.... + /// + public static string FindContactByName { + get { + return ResourceManager.GetString("FindContactByName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find an employee by name.... + /// + public static string FindEmployeeByName { + get { + return ResourceManager.GetString("FindEmployeeByName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First Name. + /// + public static string FirstName { + get { + return ResourceManager.GetString("FirstName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to General information. + /// + public static string GeneralInformation { + get { + return ResourceManager.GetString("GeneralInformation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate. + /// + public static string Generate { + get { + return ResourceManager.GetString("Generate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate links. + /// + public static string GenerateLinks { + get { + return ResourceManager.GetString("GenerateLinks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generation. + /// + public static string Generation { + get { + return ResourceManager.GetString("Generation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Incoming call. Duration: {0}. + /// + public static string HistoryVoipIncomingNote { + get { + return ResourceManager.GetString("HistoryVoipIncomingNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Outgoing call. Duration: {0}. + /// + public static string HistoryVoipOutcomingNote { + get { + return ResourceManager.GetString("HistoryVoipOutcomingNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import contacts. + /// + public static string ImportContacts { + get { + return ResourceManager.GetString("ImportContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by a delimiter which will be used to import persons or companies - 'First Name' and 'Last Name' for persons, 'Company Name' for companies. The files containing more than {0} rows should be divided into smaller parts for proper importing. Make sure you selected the portal users who need to be granted access to the contact details, otherwise the data from the CSV file will be available to you on [rest of string was truncated]";. + /// + public static string ImportFromCSVStepOneDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepOneDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a CSV file and set access rights before you import contacts. + /// + public static string ImportFromCSVStepOneHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepOneHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import persons correctly you need to have at least one column from your file matched with the 'First Name' field of the ONLYOFFICE™ CRM. The same is for the company import, you will need to match the 'Company Name' field to be able to import a company. The fields containing the dates must have the following format: {0}.. + /// + public static string ImportFromCSVStepTwoDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please, verify the fields. + /// + public static string ImportFromCSVStepTwoHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to Contact List. + /// + public static string ImportStartingPanelButton { + get { + return ResourceManager.GetString("ImportStartingPanelButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import of contacts can take several minutes depending on the amount of your data.. + /// + public static string ImportStartingPanelDescription { + get { + return ResourceManager.GetString("ImportStartingPanelDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Importing started. + /// + public static string ImportStartingPanelHeader { + get { + return ResourceManager.GetString("ImportStartingPanelHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Industry. + /// + public static string Industry { + get { + return ResourceManager.GetString("Industry", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Position. + /// + public static string JobTitle { + get { + return ResourceManager.GetString("JobTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Last Name. + /// + public static string LastName { + get { + return ResourceManager.GetString("LastName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lead. + /// + public static string Lead { + get { + return ResourceManager.GetString("Lead", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Upload photo. + /// + public static string LoadPhoto { + get { + return ResourceManager.GetString("LoadPhoto", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Upload photo from PC. + /// + public static string LoadPhotoFromPC { + get { + return ResourceManager.GetString("LoadPhotoFromPC", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select from social networks. + /// + public static string LoadPhotoFromSocialMedia { + get { + return ResourceManager.GetString("LoadPhotoFromSocialMedia", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allow access to the company for all CRM users. + /// + public static string MakePublicPanelCheckBoxLabelForCompany { + get { + return ResourceManager.GetString("MakePublicPanelCheckBoxLabelForCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allow all CRM users access this contact. + /// + public static string MakePublicPanelCheckBoxLabelForImportContacts { + get { + return ResourceManager.GetString("MakePublicPanelCheckBoxLabelForImportContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allow access to the person for all CRM users. + /// + public static string MakePublicPanelCheckBoxLabelForPerson { + get { + return ResourceManager.GetString("MakePublicPanelCheckBoxLabelForPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The access is granted to contact managers only. To allow access to this contact for all users check the box below. + /// + public static string MakePublicPanelDescrForContact { + get { + return ResourceManager.GetString("MakePublicPanelDescrForContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Make this company public. + /// + public static string MakePublicPanelTitleForCompany { + get { + return ResourceManager.GetString("MakePublicPanelTitleForCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Make contact public. + /// + public static string MakePublicPanelTitleForImportContacts { + get { + return ResourceManager.GetString("MakePublicPanelTitleForImportContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Make this person public. + /// + public static string MakePublicPanelTitleForPerson { + get { + return ResourceManager.GetString("MakePublicPanelTitleForPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Already sent. + /// + public static string MassSendAlreadySent { + get { + return ResourceManager.GetString("MassSendAlreadySent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total emails. + /// + public static string MassSendEmailsTotal { + get { + return ResourceManager.GetString("MassSendEmailsTotal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Errors. + /// + public static string MassSendErrors { + get { + return ResourceManager.GetString("MassSendErrors", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Estimated end time. + /// + public static string MassSendEstimatedTime { + get { + return ResourceManager.GetString("MassSendEstimatedTime", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your last mailing is in progress. Thank you for using our blanket mailing feature!. + /// + public static string MassSendInfo { + get { + return ResourceManager.GetString("MassSendInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This is a duplicate. + /// + public static string MergeButtonText { + get { + return ResourceManager.GetString("MergeButtonText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start Merging Contacts. + /// + public static string MergePanelButtonStartText { + get { + return ResourceManager.GetString("MergePanelButtonStartText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please select the contact which is duplicated by the current contact. The two contact data will be combined and the current contact will be deleted.. + /// + public static string MergePanelDescriptionText { + get { + return ResourceManager.GetString("MergePanelDescriptionText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Merge contacts. + /// + public static string MergePanelHeaderText { + get { + return ResourceManager.GetString("MergePanelHeaderText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Merging contacts.... + /// + public static string MergePanelProgress { + get { + return ResourceManager.GetString("MergePanelProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No matches in ONLYOFFICE™ CRM, select from list. + /// + public static string NoMatchSelect { + get { + return ResourceManager.GetString("NoMatchSelect", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no available photos corresponding to the profile. + /// + public static string NoPhotoFromSocialMedia { + get { + return ResourceManager.GetString("NoPhotoFromSocialMedia", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Notify contact manager by email. + /// + public static string NotifyContactManager { + get { + return ResourceManager.GetString("NotifyContactManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add to linked contacts. + /// + public static string OKAddContactTagToGroup { + get { + return ResourceManager.GetString("OKAddContactTagToGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yes, change for the persons. + /// + public static string OKCompanyStatusGroupChange { + get { + return ResourceManager.GetString("OKCompanyStatusGroupChange", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete from linked contact. + /// + public static string OKDeleteContactTagFromGroup { + get { + return ResourceManager.GetString("OKDeleteContactTagFromGroup", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yes, change for the company. + /// + public static string OKPersonStatusGroupChange { + get { + return ResourceManager.GetString("OKPersonStatusGroupChange", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description. + /// + public static string Overview { + get { + return ResourceManager.GetString("Overview", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to People. + /// + public static string People { + get { + return ResourceManager.GetString("People", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Person. + /// + public static string Person { + get { + return ResourceManager.GetString("Person", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Personal tags. + /// + public static string PersonalTags { + get { + return ResourceManager.GetString("PersonalTags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Position. + /// + public static string PersonPosition { + get { + return ResourceManager.GetString("PersonPosition", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Persons. + /// + public static string Persons { + get { + return ResourceManager.GetString("Persons", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Public. + /// + public static string PublicContacts { + get { + return ResourceManager.GetString("PublicContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Associated identity. + /// + public static string RelativeEntity { + get { + return ResourceManager.GetString("RelativeEntity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Restricted. + /// + public static string RestrictedContacts { + get { + return ResourceManager.GetString("RestrictedContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save Changes. + /// + public static string SaveChanges { + get { + return ResourceManager.GetString("SaveChanges", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save and Create company. + /// + public static string SaveThisAndCreateCompanyButton { + get { + return ResourceManager.GetString("SaveThisAndCreateCompanyButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save and Create person. + /// + public static string SaveThisAndCreatePeopleButton { + get { + return ResourceManager.GetString("SaveThisAndCreatePeopleButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving changes.... + /// + public static string SavingChangesProgress { + get { + return ResourceManager.GetString("SavingChangesProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Search. + /// + public static string Search { + get { + return ResourceManager.GetString("Search", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter a text to search. + /// + public static string SearchText { + get { + return ResourceManager.GetString("SearchText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a CSV file. + /// + public static string SelectCSVFileButton { + get { + return ResourceManager.GetString("SelectCSVFileButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show. + /// + public static string Show { + get { + return ResourceManager.GetString("Show", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show all the results. + /// + public static string ShowAllSearchResult { + get { + return ResourceManager.GetString("ShowAllSearchResult", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to profile. + /// + public static string ShowContactProfile { + get { + return ResourceManager.GetString("ShowContactProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open in a new tab. + /// + public static string ShowContactProfileNewTab { + get { + return ResourceManager.GetString("ShowContactProfileNewTab", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show on the map. + /// + public static string ShowOnMap { + get { + return ResourceManager.GetString("ShowOnMap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show on page. + /// + public static string ShowOnPage { + get { + return ResourceManager.GetString("ShowOnPage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Staff. + /// + public static string Staff { + get { + return ResourceManager.GetString("Staff", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact type. + /// + public static string Stage { + get { + return ResourceManager.GetString("Stage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start importing contacts. + /// + public static string StartImport { + get { + return ResourceManager.GetString("StartImport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Supplier. + /// + public static string Supplier { + get { + return ResourceManager.GetString("Supplier", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tag. + /// + public static string Tag { + get { + return ResourceManager.GetString("Tag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tags. + /// + public static string Tags { + get { + return ResourceManager.GetString("Tags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to We will add the text watermark to your letter like "Powered by ONLYOFFICE.com". You can see it in the next (message preview) step.. + /// + public static string TeamlabWatermarkInfo { + get { + return ResourceManager.GetString("TeamlabWatermarkInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Position. + /// + public static string Title { + get { + return ResourceManager.GetString("Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CSV (comma-separated values) files store tabular data in the plain-text form. You can create such files from any spreadsheets using ONLYOFFICE™ Documents.. + /// + public static string TooltipCsv { + get { + return ResourceManager.GetString("TooltipCsv", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact types let you characterize your potential customers in a certain way. The default contact types are cold, warm and hot which mean the contact's willingness to purchase your product. To be able to edit them, the administrator rights are needed.. + /// + public static string TooltipTypes { + get { + return ResourceManager.GetString("TooltipTypes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All contacts. + /// + public static string TotalContacts { + get { + return ResourceManager.GetString("TotalContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total found. + /// + public static string TotalFinded { + get { + return ResourceManager.GetString("TotalFinded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show info. + /// + public static string ViewInfo { + get { + return ResourceManager.GetString("ViewInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to View mailing history. + /// + public static string ViewMailingHistory { + get { + return ResourceManager.GetString("ViewMailingHistory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No contact manager. + /// + public static string WithoutContactManager { + get { + return ResourceManager.GetString("WithoutContactManager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Write message. + /// + public static string WriteEmail { + get { + return ResourceManager.GetString("WriteEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Starting with this message its conversation thread will be displayed in the contact history.. + /// + public static string WriteEmailByMailProductDscr { + get { + return ResourceManager.GetString("WriteEmailByMailProductDscr", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMContactResource.resx b/products/ASC.CRM/Server/Resources/CRMContactResource.resx new file mode 100644 index 00000000000..e670a07bb8c --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMContactResource.resx @@ -0,0 +1,724 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Abort Blanket Mailing + + + Note + + + Adding company... + + + Adding contact... + + + Additional information + + + Add new address + + + Add new company + + + Add new person + + + Add email + + + Add phone + + + This default action can be changed {0}here{1} + + + Only CRM administrator can reset this parameter afterwards + + + Save and Create New Company + + + Save and Create New Person + + + Save + + + Save + + + Add to Letter Body + + + Temperature level + + + All Contacts + + + All persons + + + Link or add person + + + Select from existing contacts + + + Assign manager to this contact + + + Select from existing persons or add a new one + + + Link or add project + + + Batch size + + + We suggest that you send your emails in batch quantities for the mailing software to work efficiently. You can change the number of recipients per batch if you wish. + + + Hide email addresses from recipients? + + + Create new company + + + Create new person + + + Manager + + + Add to company only + + + Add to person only + + + No, for current contact only + + + Delete from company only + + + Delete from person only + + + No category is specified + + + Change photo + + + Change photo to default + + + Choose a profile photo + + + Companies + + + Company + + + Company Name + + + Some persons are linked with this company. +Do you want to add this tag to all these persons as well? + + + This person belongs to a company. +Do you want to add this tag also to the company and to all its persons? + + + Do you want to change the contact status of the company this person is linked with? + + + Do you want to change the contact status of all the persons linked with this company? + + + This company has linked persons. +Do you want to delete this tag also from all persons linked with this company? + + + This person belongs to a company. +Do you want to delete this tag also from the company and from all its persons? + + + Contact + + + Contact manager + + + You can upload an image file in PNG or JPG format not larger than {1}200x300 pixels{2}, otherwise resizing will take place. The maximum image size cannot exceed {1}{0}{2}. + + + Contacts + + + Contact Temperature Level + + + Contact Temperature Levels + + + Cold + + + Hot + + + Warm + + + This default action can be changed {0}here{1} + + + Only CRM administrator can reset this parameter afterwards + + + Contact Tag + + + Contact Tag List + + + Contact Tags + + + Contact Name + + + Enter your Twitter account name. For example, teamlabdotcom + + + Contact Type + + + Client + + + Competitor + + + Partner + + + Supplier + + + Web Site/Social Networks + + + Content + + + Continue + + + Create the first company + + + Create the first person + + + Create project + + + Create task + + + Customer + + + Companies + + + Delete contact + + + This default action can be changed {0}here{1} + + + Only CRM administrator will be able to reset this parameter in future + + + Delete company + + + Delete person + + + Deleting contacts + + + Deselect all + + + Do not import this field + + + Edit + + + Edit company «{0}» + + + Edit contact + + + Edit person «{0}» + + + Edit company + + + Edit person + + + Email + + + Keep all the contacts your company works with in one place. Add new companies and persons, divide them into {0}types{1}, link with each other, add personal information. Import multiple contacts that you already have from a {2}CSV file{3} at one go. + + + No contacts matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the contacts in this section. Or you can create the contact in case it is absent from the list. + + + No contacts to be displayed for this filter here + + + The contact list is empty + + + Select the existing projects from the list to link them with the CRM contacts, or go to the Projects module to create new projects. This will help you organize your workflow and make plans. A deeper integration with the projects will help you manage your work more efficiently. + + + You haven't got the permission to link contacts with projects. You need to be project manager or portal administrator to be able to do that. + + + The project list is empty + + + Add persons here creating new people or linking the existing ones to the companies they work for. When a person is created, you can fill all the contact information for him/her and set the access rights level for other portal users. + + + The person list is empty + + + Enter a company name + + + Enter a first name + + + The uploaded file could not be found + + + Invalid email + + + Invalid phone number + + + all users (including the deleted users) + + + Files + + + Accessibility + + + Manager + + + Find a company by name... + + + Find a person by name... + + + Find an employee by name... + + + First Name + + + General information + + + Generate + + + Generate links + + + Generation + + + Incoming call. Duration: {0} + + + Outgoing call. Duration: {0} + + + Import contacts + + + A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by a delimiter which will be used to import persons or companies - 'First Name' and 'Last Name' for persons, 'Company Name' for companies. The files containing more than {0} rows should be divided into smaller parts for proper importing. Make sure you selected the portal users who need to be granted access to the contact details, otherwise the data from the CSV file will be available to you only. + + + Select a CSV file and set access rights before you import contacts + + + Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import persons correctly you need to have at least one column from your file matched with the 'First Name' field of the ONLYOFFICE™ CRM. The same is for the company import, you will need to match the 'Company Name' field to be able to import a company. The fields containing the dates must have the following format: {0}. + + + Please, verify the fields + + + Go to Contact List + + + Import of contacts can take several minutes depending on the amount of your data. + + + Importing started + + + Industry + + + Position + + + Last Name + + + Lead + + + Upload photo + + + Upload photo from PC + + + Select from social networks + + + Allow access to the company for all CRM users + + + Allow all CRM users access this contact + + + Allow access to the person for all CRM users + + + The access is granted to contact managers only. To allow access to this contact for all users check the box below + + + Make this company public + + + Make contact public + + + Make this person public + + + Already sent + + + Total emails + + + Errors + + + Estimated end time + + + Your last mailing is in progress. Thank you for using our blanket mailing feature! + + + This is a duplicate + + + Start Merging Contacts + + + Please select the contact which is duplicated by the current contact. The two contact data will be combined and the current contact will be deleted. + + + Merge contacts + + + Merging contacts... + + + No matches in ONLYOFFICE™ CRM, select from list + + + There are no available photos corresponding to the profile + + + Notify contact manager by email + + + Add to linked contacts + + + Yes, change for the persons + + + Delete from linked contact + + + Yes, change for the company + + + Description + + + People + + + Person + + + Personal tags + + + Position + + + Persons + + + Public + + + Associated identity + + + Restricted + + + Save Changes + + + Save and Create company + + + Save and Create person + + + Saving changes... + + + Search + + + Enter a text to search + + + Select a CSV file + + + Show + + + Show all the results + + + Go to profile + + + Open in a new tab + + + Show on the map + + + Show on page + + + Staff + + + Contact type + + + Start importing contacts + + + Supplier + + + Tag + + + Tags + + + We will add the text watermark to your letter like "Powered by ONLYOFFICE.com". You can see it in the next (message preview) step. + + + Position + + + CSV (comma-separated values) files store tabular data in the plain-text form. You can create such files from any spreadsheets using ONLYOFFICE™ Documents. + + + Contact types let you characterize your potential customers in a certain way. The default contact types are cold, warm and hot which mean the contact's willingness to purchase your product. To be able to edit them, the administrator rights are needed. + + + All contacts + + + Total found + + + Show info + + + View mailing history + + + No contact manager + + + Write message + + + Starting with this message its conversation thread will be displayed in the contact history. + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMDealResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMDealResource.Designer.cs new file mode 100644 index 00000000000..205863726a0 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMDealResource.Designer.cs @@ -0,0 +1,954 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMDealResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMDealResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMDealResource", typeof(CRMDealResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Add new opportunity. + /// + public static string AddNewDeal { + get { + return ResourceManager.GetString("AddNewDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save and Create New Opportunity. + /// + public static string AddThisAndCreateDealButton { + get { + return ResourceManager.GetString("AddThisAndCreateDealButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisDealButton { + get { + return ResourceManager.GetString("AddThisDealButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All Opportunities. + /// + public static string AllDeals { + get { + return ResourceManager.GetString("AllDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stake. + /// + public static string BidType { + get { + return ResourceManager.GetString("BidType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to fix. + /// + public static string BidType_FixedBid { + get { + return ResourceManager.GetString("BidType_FixedBid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per day. + /// + public static string BidType_PerDay { + get { + return ResourceManager.GetString("BidType_PerDay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per hour. + /// + public static string BidType_PerHour { + get { + return ResourceManager.GetString("BidType_PerHour", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per month. + /// + public static string BidType_PerMonth { + get { + return ResourceManager.GetString("BidType_PerMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per week. + /// + public static string BidType_PerWeek { + get { + return ResourceManager.GetString("BidType_PerWeek", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per year. + /// + public static string BidType_PerYear { + get { + return ResourceManager.GetString("BidType_PerYear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Payment recurrence. + /// + public static string BidTypePeriod { + get { + return ResourceManager.GetString("BidTypePeriod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stage. + /// + public static string ByStage { + get { + return ResourceManager.GetString("ByStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stage type. + /// + public static string ByStageType { + get { + return ResourceManager.GetString("ByStageType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity contact. + /// + public static string ClientDeal { + get { + return ResourceManager.GetString("ClientDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add the first opportunity. + /// + public static string CreateFirstDeal { + get { + return ResourceManager.GetString("CreateFirstDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new opportunity. + /// + public static string CreateNewDeal { + get { + return ResourceManager.GetString("CreateNewDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current opportunity. + /// + public static string CurrentDeal { + get { + return ResourceManager.GetString("CurrentDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity at stage. + /// + public static string CurrentDealMilestone { + get { + return ResourceManager.GetString("CurrentDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom period. + /// + public static string CustomDateFilter { + get { + return ResourceManager.GetString("CustomDateFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other users. + /// + public static string CustomResponsibleFilter { + get { + return ResourceManager.GetString("CustomResponsibleFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity. + /// + public static string Deal { + get { + return ResourceManager.GetString("Deal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The permissions will be set to the opportunities where you are the author. + /// + public static string DealAccessRightsLimit { + get { + return ResourceManager.GetString("DealAccessRightsLimit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sum. + /// + public static string DealAmount { + get { + return ResourceManager.GetString("DealAmount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Qty. + /// + public static string DealCount { + get { + return ResourceManager.GetString("DealCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity Stages. + /// + public static string DealMilestone { + get { + return ResourceManager.GetString("DealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The salesperson takes a series of question and answer sessions in order to identify the requirements of the prospect. + /// + public static string DealMilestone_Champion_Description { + get { + return ResourceManager.GetString("DealMilestone_Champion_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Need assessment. + /// + public static string DealMilestone_Champion_Title { + get { + return ResourceManager.GetString("DealMilestone_Champion_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A contact with the potential buyer is needed to understand the future sales prospective. + /// + public static string DealMilestone_InitialContact_Description { + get { + return ResourceManager.GetString("DealMilestone_InitialContact_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Initial contact. + /// + public static string DealMilestone_InitialContact_Title { + get { + return ResourceManager.GetString("DealMilestone_InitialContact_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A failure. The opportunity is closed due to the lack of perspective. + /// + public static string DealMilestone_Lost_Description { + get { + return ResourceManager.GetString("DealMilestone_Lost_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unsuccessfully closed. + /// + public static string DealMilestone_Lost_Title { + get { + return ResourceManager.GetString("DealMilestone_Lost_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The potential buyer has expressed his interest in the salesperson's goods or services. + /// + public static string DealMilestone_Opportunity_Description { + get { + return ResourceManager.GetString("DealMilestone_Opportunity_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Qualified prospect. + /// + public static string DealMilestone_Opportunity_Title { + get { + return ResourceManager.GetString("DealMilestone_Opportunity_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The salesperson tries to identify whether the customer can be his/her potential buyer. + /// + public static string DealMilestone_Preapproach_Description { + get { + return ResourceManager.GetString("DealMilestone_Preapproach_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Application of initial fit criteria. + /// + public static string DealMilestone_Preapproach_Title { + get { + return ResourceManager.GetString("DealMilestone_Preapproach_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The potential buyer has received a written offering from the salesperson. + /// + public static string DealMilestone_Prospect_Description { + get { + return ResourceManager.GetString("DealMilestone_Prospect_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Proposal. + /// + public static string DealMilestone_Prospect_Title { + get { + return ResourceManager.GetString("DealMilestone_Prospect_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The potential buyer is identified as a person or entity that has the interest and authority to purchase a product or service. + /// + public static string DealMilestone_Suspect_Description { + get { + return ResourceManager.GetString("DealMilestone_Suspect_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Suspect. + /// + public static string DealMilestone_Suspect_Title { + get { + return ResourceManager.GetString("DealMilestone_Suspect_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The potential buyer has already discussed your offering in details. + /// + public static string DealMilestone_Verbal_Description { + get { + return ResourceManager.GetString("DealMilestone_Verbal_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Negotiations. + /// + public static string DealMilestone_Verbal_Title { + get { + return ResourceManager.GetString("DealMilestone_Verbal_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A deal. The opportunity is closed successfully. + /// + public static string DealMilestone_Won_Description { + get { + return ResourceManager.GetString("DealMilestone_Won_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closure/Transaction. + /// + public static string DealMilestone_Won_Title { + get { + return ResourceManager.GetString("DealMilestone_Won_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stage type. + /// + public static string DealMilestoneType { + get { + return ResourceManager.GetString("DealMilestoneType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity Participant. + /// + public static string DealParticipant { + get { + return ResourceManager.GetString("DealParticipant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity Participants. + /// + public static string DealParticipants { + get { + return ResourceManager.GetString("DealParticipants", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities. + /// + public static string Deals { + get { + return ResourceManager.GetString("Deals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity Tag. + /// + public static string DealTag { + get { + return ResourceManager.GetString("DealTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity Tag List. + /// + public static string DealTagList { + get { + return ResourceManager.GetString("DealTagList", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity Tags. + /// + public static string DealTags { + get { + return ResourceManager.GetString("DealTags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete opportunity. + /// + public static string DeleteDeal { + get { + return ResourceManager.GetString("DeleteDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting opportunities. + /// + public static string DeletingDeals { + get { + return ResourceManager.GetString("DeletingDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description. + /// + public static string DescriptionDeal { + get { + return ResourceManager.GetString("DescriptionDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit «{0}» opportunity. + /// + public static string EditDealLabel { + get { + return ResourceManager.GetString("EditDealLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit opportunity. + /// + public static string EditThisDealButton { + get { + return ResourceManager.GetString("EditThisDealButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities let you track potential sales to your clients. Determine the {0}opportunity stages{1} in accordance with your business process, keep history, assign tasks, upload documents, calculate profit with every client.. + /// + public static string EmptyContentDealsDescribe { + get { + return ResourceManager.GetString("EmptyContentDealsDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No opportunities matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the opportunities in this section. Or you can create the opportunity in case it is absent from the list.. + /// + public static string EmptyContentDealsFilterDescribe { + get { + return ResourceManager.GetString("EmptyContentDealsFilterDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No opportunities to be displayed for this filter here. + /// + public static string EmptyContentDealsFilterHeader { + get { + return ResourceManager.GetString("EmptyContentDealsFilterHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The opportunity list is empty. + /// + public static string EmptyContentDealsHeader { + get { + return ResourceManager.GetString("EmptyContentDealsHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter the opportunity title. + /// + public static string EmptyDealName { + get { + return ResourceManager.GetString("EmptyDealName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every opportunity must have a responsible one. + /// + public static string EmptyDealResponsible { + get { + return ResourceManager.GetString("EmptyDealResponsible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The participant list is empty. + /// + public static string EmptyPeopleInDealContent { + get { + return ResourceManager.GetString("EmptyPeopleInDealContent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add participants to your opportunity from the list of companies or persons. After this is done you will know what contacts are associated with this opportunity and who you can deal with.. + /// + public static string EmptyPeopleInDealDescript { + get { + return ResourceManager.GetString("EmptyPeopleInDealDescript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Estimated/Actual due date. + /// + public static string Estimated { + get { + return ResourceManager.GetString("Estimated", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Budget. + /// + public static string ExpectedValue { + get { + return ResourceManager.GetString("ExpectedValue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact. + /// + public static string FilterByContact { + get { + return ResourceManager.GetString("FilterByContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Participant. + /// + public static string FilterByParticipant { + get { + return ResourceManager.GetString("FilterByParticipant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stage/stage type. + /// + public static string FilterByStageOrStageType { + get { + return ResourceManager.GetString("FilterByStageOrStageType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find opportunity by title. + /// + public static string FindDealByName { + get { + return ResourceManager.GetString("FindDealByName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import opportunities. + /// + public static string ImportDeals { + get { + return ResourceManager.GetString("ImportDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by the selected delimiter which will be used to import opportunities. The files containing more than {0} rows should be divided into smaller parts for proper importing. Make sure you selected the portal users who need to be granted access to the information to be imported, otherwise the data from the CSV file will be available to all portal users.. + /// + public static string ImportFromCSVStepOneDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepOneDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a CSV file and set access rights before you import opportunities. + /// + public static string ImportFromCSVStepOneHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepOneHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import opportunities correctly you need to have at least the following columns from your file matched with the fields of the ONLYOFFICE™ CRM: 'Opportunity Title', 'Opportunity Responsible'. The fields containing the dates must have the following format: {0}. The currency field must be set in accordance with the international three letter code (e.g. USD, JPY, AUD).. + /// + public static string ImportFromCSVStepTwoDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please, verify the fields. + /// + public static string ImportFromCSVStepTwoHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to oppotunity list. + /// + public static string ImportStartingPanelButton { + get { + return ResourceManager.GetString("ImportStartingPanelButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import of opportunities can take several minutes depending on the amount of your data.. + /// + public static string ImportStartingPanelDescription { + get { + return ResourceManager.GetString("ImportStartingPanelDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Importing started. + /// + public static string ImportStartingPanelHeader { + get { + return ResourceManager.GetString("ImportStartingPanelHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select from existing opportunities or add a new one. + /// + public static string LinkDealsFromExisting { + get { + return ResourceManager.GetString("LinkDealsFromExisting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link or create opportunity. + /// + public static string LinkOrCreateDeal { + get { + return ResourceManager.GetString("LinkOrCreateDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to My opportunities. + /// + public static string MyDeals { + get { + return ResourceManager.GetString("MyDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity title. + /// + public static string NameDeal { + get { + return ResourceManager.GetString("NameDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Budget is not set. + /// + public static string NoExpectedValue { + get { + return ResourceManager.GetString("NoExpectedValue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other opportunity participants. + /// + public static string OtherMembersDeal { + get { + return ResourceManager.GetString("OtherMembersDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overdue. + /// + public static string Overdue { + get { + return ResourceManager.GetString("Overdue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Participants. + /// + public static string PeopleInDeal { + get { + return ResourceManager.GetString("PeopleInDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Restrict access to the opportunity. + /// + public static string PrivatePanelCheckBoxLabel { + get { + return ResourceManager.GetString("PrivatePanelCheckBoxLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Success probability. + /// + public static string ProbabilityOfWinning { + get { + return ResourceManager.GetString("ProbabilityOfWinning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Responsible for the opportunity. + /// + public static string ResponsibleDeal { + get { + return ResourceManager.GetString("ResponsibleDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Customize user fields. + /// + public static string SettingCustomFields { + get { + return ResourceManager.GetString("SettingCustomFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to profile. + /// + public static string ShowDealProfile { + get { + return ResourceManager.GetString("ShowDealProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open in a new tab. + /// + public static string ShowDealProfileNewTab { + get { + return ResourceManager.GetString("ShowDealProfileNewTab", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show total amount. + /// + public static string ShowTotalAmount { + get { + return ResourceManager.GetString("ShowTotalAmount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start Importing. + /// + public static string StartImport { + get { + return ResourceManager.GetString("StartImport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity stages let you determine steps necessary to complete the deal. The default opportunity stages are approach, discussion, evaluation, negotiation, commitment, success, zero-point. To be able to edit them the portal administrator rights are needed.. + /// + public static string TooltipStages { + get { + return ResourceManager.GetString("TooltipStages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total. + /// + public static string Total { + get { + return ResourceManager.GetString("Total", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total amount. + /// + public static string TotalAmount { + get { + return ResourceManager.GetString("TotalAmount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All opportunities. + /// + public static string TotalDeals { + get { + return ResourceManager.GetString("TotalDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Page total. + /// + public static string TotalOnPage { + get { + return ResourceManager.GetString("TotalOnPage", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMDealResource.resx b/products/ASC.CRM/Server/Resources/CRMDealResource.resx new file mode 100644 index 00000000000..4b66f9ebc74 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMDealResource.resx @@ -0,0 +1,417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Save and Create New Opportunity + + + Save + + + All Opportunities + + + Stake + + + fix + + + per day + + + per hour + + + per month + + + per week + + + per year + + + Payment recurrence + + + Stage + + + Stage type + + + Opportunity contact + + + Add the first opportunity + + + Create new opportunity + + + Current opportunity + + + Opportunity at stage + + + Custom period + + + Other users + + + Opportunity + + + The permissions will be set to the opportunities where you are the author + + + Sum + + + Qty + + + Opportunity Stages + + + The salesperson takes a series of question and answer sessions in order to identify the requirements of the prospect + + + Need assessment + + + A contact with the potential buyer is needed to understand the future sales prospective + + + Initial contact + + + A failure. The opportunity is closed due to the lack of perspective + + + Unsuccessfully closed + + + The potential buyer has expressed his interest in the salesperson's goods or services + + + Qualified prospect + + + The salesperson tries to identify whether the customer can be his/her potential buyer + + + Application of initial fit criteria + + + The potential buyer has received a written offering from the salesperson + + + Proposal + + + The potential buyer is identified as a person or entity that has the interest and authority to purchase a product or service + + + Suspect + + + The potential buyer has already discussed your offering in details + + + Negotiations + + + A deal. The opportunity is closed successfully + + + Closure/Transaction + + + Stage type + + + Opportunity Participant + + + Opportunity Participants + + + Opportunities + + + Opportunity Tag + + + Opportunity Tag List + + + Opportunity Tags + + + Delete opportunity + + + Deleting opportunities + + + Description + + + Edit «{0}» opportunity + + + Edit opportunity + + + Opportunities let you track potential sales to your clients. Determine the {0}opportunity stages{1} in accordance with your business process, keep history, assign tasks, upload documents, calculate profit with every client. + + + No opportunities matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the opportunities in this section. Or you can create the opportunity in case it is absent from the list. + + + No opportunities to be displayed for this filter here + + + The opportunity list is empty + + + Enter the opportunity title + + + Every opportunity must have a responsible one + + + The participant list is empty + + + Add participants to your opportunity from the list of companies or persons. After this is done you will know what contacts are associated with this opportunity and who you can deal with. + + + Estimated/Actual due date + + + Budget + + + Contact + + + Participant + + + Stage/stage type + + + Import opportunities + + + A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by the selected delimiter which will be used to import opportunities. The files containing more than {0} rows should be divided into smaller parts for proper importing. Make sure you selected the portal users who need to be granted access to the information to be imported, otherwise the data from the CSV file will be available to all portal users. + + + Select a CSV file and set access rights before you import opportunities + + + Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import opportunities correctly you need to have at least the following columns from your file matched with the fields of the ONLYOFFICE™ CRM: 'Opportunity Title', 'Opportunity Responsible'. The fields containing the dates must have the following format: {0}. The currency field must be set in accordance with the international three letter code (e.g. USD, JPY, AUD). + + + Please, verify the fields + + + Go to oppotunity list + + + Import of opportunities can take several minutes depending on the amount of your data. + + + Importing started + + + Link or create opportunity + + + My opportunities + + + Opportunity title + + + Budget is not set + + + Other opportunity participants + + + Overdue + + + Participants + + + Restrict access to the opportunity + + + Success probability + + + Responsible for the opportunity + + + Customize user fields + + + Go to profile + + + Open in a new tab + + + Show total amount + + + Start Importing + + + Opportunity stages let you determine steps necessary to complete the deal. The default opportunity stages are approach, discussion, evaluation, negotiation, commitment, success, zero-point. To be able to edit them the portal administrator rights are needed. + + + Total + + + Total amount + + + All opportunities + + + Page total + + + Add new opportunity + + + Select from existing opportunities or add a new one + + + Find opportunity by title + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMEnumResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMEnumResource.Designer.cs new file mode 100644 index 00000000000..7510ddd31a2 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMEnumResource.Designer.cs @@ -0,0 +1,684 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMEnumResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMEnumResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMEnumResource", typeof(CRMEnumResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Billing. + /// + public static string AddressCategory_Billing { + get { + return ResourceManager.GetString("AddressCategory_Billing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Home. + /// + public static string AddressCategory_Home { + get { + return ResourceManager.GetString("AddressCategory_Home", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Office. + /// + public static string AddressCategory_Office { + get { + return ResourceManager.GetString("AddressCategory_Office", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other. + /// + public static string AddressCategory_Other { + get { + return ResourceManager.GetString("AddressCategory_Other", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delivery. + /// + public static string AddressCategory_Postal { + get { + return ResourceManager.GetString("AddressCategory_Postal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Work. + /// + public static string AddressCategory_Work { + get { + return ResourceManager.GetString("AddressCategory_Work", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to City. + /// + public static string AddressPart_City { + get { + return ResourceManager.GetString("AddressPart_City", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Country. + /// + public static string AddressPart_Country { + get { + return ResourceManager.GetString("AddressPart_Country", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to State. + /// + public static string AddressPart_State { + get { + return ResourceManager.GetString("AddressPart_State", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Street. + /// + public static string AddressPart_Street { + get { + return ResourceManager.GetString("AddressPart_Street", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Zip. + /// + public static string AddressPart_Zip { + get { + return ResourceManager.GetString("AddressPart_Zip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Home. + /// + public static string ContactInfoBaseCategory_Home { + get { + return ResourceManager.GetString("ContactInfoBaseCategory_Home", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other. + /// + public static string ContactInfoBaseCategory_Other { + get { + return ResourceManager.GetString("ContactInfoBaseCategory_Other", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Work. + /// + public static string ContactInfoBaseCategory_Work { + get { + return ResourceManager.GetString("ContactInfoBaseCategory_Work", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Address. + /// + public static string ContactInfoType_Address { + get { + return ResourceManager.GetString("ContactInfoType_Address", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to AIM. + /// + public static string ContactInfoType_AIM { + get { + return ResourceManager.GetString("ContactInfoType_AIM", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Blogger. + /// + public static string ContactInfoType_Blogger { + get { + return ResourceManager.GetString("ContactInfoType_Blogger", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Email. + /// + public static string ContactInfoType_Email { + get { + return ResourceManager.GetString("ContactInfoType_Email", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Facebook. + /// + public static string ContactInfoType_Facebook { + get { + return ResourceManager.GetString("ContactInfoType_Facebook", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to GMail. + /// + public static string ContactInfoType_GMail { + get { + return ResourceManager.GetString("ContactInfoType_GMail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ICQ. + /// + public static string ContactInfoType_ICQ { + get { + return ResourceManager.GetString("ContactInfoType_ICQ", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Jabber. + /// + public static string ContactInfoType_Jabber { + get { + return ResourceManager.GetString("ContactInfoType_Jabber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LinkedIn. + /// + public static string ContactInfoType_LinkedIn { + get { + return ResourceManager.GetString("ContactInfoType_LinkedIn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to LiveJournal. + /// + public static string ContactInfoType_LiveJournal { + get { + return ResourceManager.GetString("ContactInfoType_LiveJournal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to MSN. + /// + public static string ContactInfoType_MSN { + get { + return ResourceManager.GetString("ContactInfoType_MSN", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to MySpace. + /// + public static string ContactInfoType_MySpace { + get { + return ResourceManager.GetString("ContactInfoType_MySpace", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Phone. + /// + public static string ContactInfoType_Phone { + get { + return ResourceManager.GetString("ContactInfoType_Phone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Skype. + /// + public static string ContactInfoType_Skype { + get { + return ResourceManager.GetString("ContactInfoType_Skype", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Twitter. + /// + public static string ContactInfoType_Twitter { + get { + return ResourceManager.GetString("ContactInfoType_Twitter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to VK. + /// + public static string ContactInfoType_VK { + get { + return ResourceManager.GetString("ContactInfoType_VK", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Web site. + /// + public static string ContactInfoType_Website { + get { + return ResourceManager.GetString("ContactInfoType_Website", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yahoo. + /// + public static string ContactInfoType_Yahoo { + get { + return ResourceManager.GetString("ContactInfoType_Yahoo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All companies and persons. + /// + public static string ContactListViewType_All { + get { + return ResourceManager.GetString("ContactListViewType_All", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Companies. + /// + public static string ContactListViewType_Company { + get { + return ResourceManager.GetString("ContactListViewType_Company", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Persons. + /// + public static string ContactListViewType_Person { + get { + return ResourceManager.GetString("ContactListViewType_Person", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to With opportunities. + /// + public static string ContactListViewType_WithOpportunity { + get { + return ResourceManager.GetString("ContactListViewType_WithOpportunity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Flag. + /// + public static string CustomFieldType_CheckBox { + get { + return ResourceManager.GetString("CustomFieldType_CheckBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Date. + /// + public static string CustomFieldType_Date { + get { + return ResourceManager.GetString("CustomFieldType_Date", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Title. + /// + public static string CustomFieldType_Heading { + get { + return ResourceManager.GetString("CustomFieldType_Heading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Drop-down list. + /// + public static string CustomFieldType_SelectBox { + get { + return ResourceManager.GetString("CustomFieldType_SelectBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text area. + /// + public static string CustomFieldType_TextArea { + get { + return ResourceManager.GetString("CustomFieldType_TextArea", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text area. + /// + public static string CustomFieldType_TextField { + get { + return ResourceManager.GetString("CustomFieldType_TextField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unsuccessfully closed. + /// + public static string DealMilestoneStatus_ClosedAndLost { + get { + return ResourceManager.GetString("DealMilestoneStatus_ClosedAndLost", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Successfully closed. + /// + public static string DealMilestoneStatus_ClosedAndWon { + get { + return ResourceManager.GetString("DealMilestoneStatus_ClosedAndWon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open. + /// + public static string DealMilestoneStatus_Open { + get { + return ResourceManager.GetString("DealMilestoneStatus_Open", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case. + /// + public static string EntityType_Case { + get { + return ResourceManager.GetString("EntityType_Case", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Company. + /// + public static string EntityType_Company { + get { + return ResourceManager.GetString("EntityType_Company", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact. + /// + public static string EntityType_Contact { + get { + return ResourceManager.GetString("EntityType_Contact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File. + /// + public static string EntityType_File { + get { + return ResourceManager.GetString("EntityType_File", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice. + /// + public static string EntityType_Invoice { + get { + return ResourceManager.GetString("EntityType_Invoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity. + /// + public static string EntityType_Opportunity { + get { + return ResourceManager.GetString("EntityType_Opportunity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Person. + /// + public static string EntityType_Person { + get { + return ResourceManager.GetString("EntityType_Person", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History. + /// + public static string EntityType_RelationshipEvent { + get { + return ResourceManager.GetString("EntityType_RelationshipEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task. + /// + public static string EntityType_Task { + get { + return ResourceManager.GetString("EntityType_Task", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Files are uploaded. + /// + public static string HistoryCategorySystem_FilesUpload { + get { + return ResourceManager.GetString("HistoryCategorySystem_FilesUpload", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mail Message. + /// + public static string HistoryCategorySystem_MailMessage { + get { + return ResourceManager.GetString("HistoryCategorySystem_MailMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task is closed. + /// + public static string HistoryCategorySystem_TaskClosed { + get { + return ResourceManager.GetString("HistoryCategorySystem_TaskClosed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Archive. + /// + public static string InvoiceStatus_Archived { + get { + return ResourceManager.GetString("InvoiceStatus_Archived", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Draft. + /// + public static string InvoiceStatus_Draft { + get { + return ResourceManager.GetString("InvoiceStatus_Draft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overdue. + /// + public static string InvoiceStatus_Overdue { + get { + return ResourceManager.GetString("InvoiceStatus_Overdue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Paid. + /// + public static string InvoiceStatus_Paid { + get { + return ResourceManager.GetString("InvoiceStatus_Paid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rejected. + /// + public static string InvoiceStatus_Rejected { + get { + return ResourceManager.GetString("InvoiceStatus_Rejected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Billed. + /// + public static string InvoiceStatus_Sent { + get { + return ResourceManager.GetString("InvoiceStatus_Sent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Direct. + /// + public static string PhoneCategory_Direct { + get { + return ResourceManager.GetString("PhoneCategory_Direct", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fax. + /// + public static string PhoneCategory_Fax { + get { + return ResourceManager.GetString("PhoneCategory_Fax", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Home. + /// + public static string PhoneCategory_Home { + get { + return ResourceManager.GetString("PhoneCategory_Home", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mobile. + /// + public static string PhoneCategory_Mobile { + get { + return ResourceManager.GetString("PhoneCategory_Mobile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other. + /// + public static string PhoneCategory_Other { + get { + return ResourceManager.GetString("PhoneCategory_Other", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Work. + /// + public static string PhoneCategory_Work { + get { + return ResourceManager.GetString("PhoneCategory_Work", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMEnumResource.resx b/products/ASC.CRM/Server/Resources/CRMEnumResource.resx new file mode 100644 index 00000000000..13a28c8f0be --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMEnumResource.resx @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Billing + + + Home + + + Office + + + Other + + + Delivery + + + Work + + + City + + + Country + + + State + + + Street + + + Zip + + + Home + + + Other + + + Work + + + Address + + + AIM + + + Blogger + + + Email + + + Facebook + + + GMail + + + ICQ + + + Jabber + + + LinkedIn + + + LiveJournal + + + MSN + + + MySpace + + + Phone + + + Skype + + + Twitter + + + Web site + + + Yahoo + + + All companies and persons + + + Companies + + + Persons + + + With opportunities + + + Flag + + + Date + + + Title + + + Drop-down list + + + Text area + + + Text area + + + Unsuccessfully closed + + + Successfully closed + + + Open + + + Case + + + Company + + + Contact + + + File + + + Invoice + + + Opportunity + + + Person + + + History + + + Task + + + Files are uploaded + + + Mail Message + + + Task is closed + + + Archive + + + Draft + + + Overdue + + + Paid + + + Rejected + + + Billed + + + Direct + + + Fax + + + Home + + + Mobile + + + Other + + + Work + + + VK + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMErrorsResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMErrorsResource.Designer.cs new file mode 100644 index 00000000000..681c736a9f6 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMErrorsResource.Designer.cs @@ -0,0 +1,423 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMErrorsResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMErrorsResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMErrorsResource", typeof(CRMErrorsResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Access Denied. + /// + public static string AccessDenied { + get { + return ResourceManager.GetString("AccessDenied", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can't be deleted. + /// + public static string BasicCannotBeDeleted { + get { + return ResourceManager.GetString("BasicCannotBeDeleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Can't be edited. + /// + public static string BasicCannotBeEdited { + get { + return ResourceManager.GetString("BasicCannotBeEdited", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact is not a company. + /// + public static string ContactIsNotCompany { + get { + return ResourceManager.GetString("ContactIsNotCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact is not a person. + /// + public static string ContactIsNotPerson { + get { + return ResourceManager.GetString("ContactIsNotPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact is not found. + /// + public static string ContactNotFound { + get { + return ResourceManager.GetString("ContactNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown photo size. + /// + public static string ContactPhotoSizeUnknown { + get { + return ResourceManager.GetString("ContactPhotoSizeUnknown", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact type is not found. + /// + public static string ContactTypeNotFound { + get { + return ResourceManager.GetString("ContactTypeNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency is not found. + /// + public static string CurrencyNotFound { + get { + return ResourceManager.GetString("CurrencyNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mask is not valid. + /// + public static string CustomFieldMaskNotValid { + get { + return ResourceManager.GetString("CustomFieldMaskNotValid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to invalid date time format. + /// + public static string DateTimeFormatInvalid { + get { + return ResourceManager.GetString("DateTimeFormatInvalid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are some opportunities at this stage. + /// + public static string DealMilestoneHasRelatedDeals { + get { + return ResourceManager.GetString("DealMilestoneHasRelatedDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deal milestone is not found. + /// + public static string DealMilestoneNotFound { + get { + return ResourceManager.GetString("DealMilestoneNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to opportunity is not found. + /// + public static string DealNotFound { + get { + return ResourceManager.GetString("DealNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Entity type is unknown. + /// + public static string EntityTypeUnknown { + get { + return ResourceManager.GetString("EntityTypeUnknown", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to empty exchange rate. + /// + public static string ExchangeRateNotSet { + get { + return ResourceManager.GetString("ExchangeRateNotSet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Export data is null. + /// + public static string ExportToCSVDataEmpty { + get { + return ResourceManager.GetString("ExportToCSVDataEmpty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File was not created. + /// + public static string FileCreateError { + get { + return ResourceManager.GetString("FileCreateError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are some related contacts. + /// + public static string HasRelatedContacts { + get { + return ResourceManager.GetString("HasRelatedContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are some history events with this category. + /// + public static string HistoryCategoryHasRelatedEvents { + get { + return ResourceManager.GetString("HistoryCategoryHasRelatedEvents", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Data too long for column 'content'. + /// + public static string HistoryEventDataTooLong { + get { + return ResourceManager.GetString("HistoryEventDataTooLong", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid currency rate: {0}. + /// + public static string InvalidCurrencyRate { + get { + return ResourceManager.GetString("InvalidCurrencyRate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid file. + /// + public static string InvalidFile { + get { + return ResourceManager.GetString("InvalidFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to consignee is null. + /// + public static string InvoiceConsigneeNotFound { + get { + return ResourceManager.GetString("InvoiceConsigneeNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to conctact is null. + /// + public static string InvoiceContactNotFound { + get { + return ResourceManager.GetString("InvoiceContactNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to invalid dueDate. + /// + public static string InvoiceDueDateInvalid { + get { + return ResourceManager.GetString("InvoiceDueDateInvalid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Issue date more than due date. + /// + public static string InvoiceIssueMoreThanDue { + get { + return ResourceManager.GetString("InvoiceIssueMoreThanDue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to invoiceItem is not found. + /// + public static string InvoiceItemNotFound { + get { + return ResourceManager.GetString("InvoiceItemNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to invoiceItems list is empty. + /// + public static string InvoiceItemsListEmpty { + get { + return ResourceManager.GetString("InvoiceItemsListEmpty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice is not found. + /// + public static string InvoiceNotFound { + get { + return ResourceManager.GetString("InvoiceNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to invoice with same number is already exist. + /// + public static string InvoiceNumberBusy { + get { + return ResourceManager.GetString("InvoiceNumberBusy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to invoiceTax is not found. + /// + public static string InvoiceTaxNotFound { + get { + return ResourceManager.GetString("InvoiceTaxNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to terms is null. + /// + public static string InvoiceTermsNotFound { + get { + return ResourceManager.GetString("InvoiceTermsNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to language is null. + /// + public static string LanguageNotFound { + get { + return ResourceManager.GetString("LanguageNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to responsible user cannot be visitor. + /// + public static string ResponsibleCannotBeVisitor { + get { + return ResourceManager.GetString("ResponsibleCannotBeVisitor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tag with this name already exists. + /// + public static string TagNameBusy { + get { + return ResourceManager.GetString("TagNameBusy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tag name is empty. + /// + public static string TagNameNotSet { + get { + return ResourceManager.GetString("TagNameNotSet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are some tasks with this category. + /// + public static string TaskCategoryHasRelatedTasks { + get { + return ResourceManager.GetString("TaskCategoryHasRelatedTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Category is not found. + /// + public static string TaskCategoryNotFound { + get { + return ResourceManager.GetString("TaskCategoryNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown currency: {0}. + /// + public static string UnknownCurrency { + get { + return ResourceManager.GetString("UnknownCurrency", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMErrorsResource.resx b/products/ASC.CRM/Server/Resources/CRMErrorsResource.resx new file mode 100644 index 00000000000..313b82fd78f --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMErrorsResource.resx @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Access Denied + + + Can't be deleted + + + Can't be edited + + + Contact is not a company + + + Contact is not a person + + + Contact is not found + + + Unknown photo size + + + Contact type is not found + + + Currency is not found + + + Mask is not valid + + + invalid date time format + + + There are some opportunities at this stage + + + Deal milestone is not found + + + opportunity is not found + + + Entity type is unknown + + + empty exchange rate + + + Export data is null + + + File was not created + + + There are some related contacts + + + There are some history events with this category + + + Data too long for column 'content' + + + Invalid currency rate: {0} + + + Invalid file + + + consignee is null + + + conctact is null + + + invalid dueDate + + + Issue date more than due date + + + invoiceItem is not found + + + invoiceItems list is empty + + + Invoice is not found + + + invoice with same number is already exist + + + invoiceTax is not found + + + terms is null + + + language is null + + + responsible user cannot be visitor + + + Tag with this name already exists + + + Tag name is empty + + + There are some tasks with this category + + + Category is not found + + + Unknown currency: {0} + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMInvoiceResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMInvoiceResource.Designer.cs new file mode 100644 index 00000000000..759a34846d6 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMInvoiceResource.Designer.cs @@ -0,0 +1,1575 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMInvoiceResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMInvoiceResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMInvoiceResource", typeof(CRMInvoiceResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Add and Create New Invoice. + /// + public static string AddAndCreateNewInvoiceButton { + get { + return ResourceManager.GetString("AddAndCreateNewInvoiceButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add billing address. + /// + public static string AddBillingAddress { + get { + return ResourceManager.GetString("AddBillingAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add delivery address. + /// + public static string AddDeliveryAddress { + get { + return ResourceManager.GetString("AddDeliveryAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add Line. + /// + public static string AddLineButton { + get { + return ResourceManager.GetString("AddLineButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Address has been successfully updated. + /// + public static string AddressesUpdated { + get { + return ResourceManager.GetString("AddressesUpdated", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new tax. + /// + public static string AddTaxHeaderText { + get { + return ResourceManager.GetString("AddTaxHeaderText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating a tax. + /// + public static string AddTaxProcessText { + get { + return ResourceManager.GetString("AddTaxProcessText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save and Create New Item. + /// + public static string AddThisAndCreateInvoiceItemButton { + get { + return ResourceManager.GetString("AddThisAndCreateInvoiceItemButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add This Invoice. + /// + public static string AddThisInvoiceButton { + get { + return ResourceManager.GetString("AddThisInvoiceButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All invoices. + /// + public static string AllInvoices { + get { + return ResourceManager.GetString("AllInvoices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Amount. + /// + public static string AmountCol { + get { + return ResourceManager.GetString("AmountCol", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Attach document. + /// + public static string AttachDocumentButton { + get { + return ResourceManager.GetString("AttachDocumentButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to automatically generated. + /// + public static string AutomaticallyGenerated { + get { + return ResourceManager.GetString("AutomaticallyGenerated", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Bill To. + /// + public static string BillTo { + get { + return ResourceManager.GetString("BillTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency. + /// + public static string ByCurrency { + get { + return ResourceManager.GetString("ByCurrency", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due date. + /// + public static string ByDueDate { + get { + return ResourceManager.GetString("ByDueDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change format. + /// + public static string ChangeFormat { + get { + return ResourceManager.GetString("ChangeFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All the future invoices will have the prefix/number format set using the fields below. Check the appropriate box to generate numbers automatically.. + /// + public static string ChangeFormatInfo { + get { + return ResourceManager.GetString("ChangeFormatInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change status. + /// + public static string ChangeInvoiceStatus { + get { + return ResourceManager.GetString("ChangeInvoiceStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Client notes. + /// + public static string ClientNotes { + get { + return ResourceManager.GetString("ClientNotes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Will be displayed on the invoice and in the letter body if you send the invoice per ONLYOFFICE™ Mail.. + /// + public static string ClientNotessHelpInfoText { + get { + return ResourceManager.GetString("ClientNotessHelpInfoText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Consignee. + /// + public static string Consignee { + get { + return ResourceManager.GetString("Consignee", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to coincides with the client. + /// + public static string ConsigneeEqualClient { + get { + return ResourceManager.GetString("ConsigneeEqualClient", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create first invoice. + /// + public static string CreateFirstInvoice { + get { + return ResourceManager.GetString("CreateFirstInvoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create first item. + /// + public static string CreateFirstInvoiceItem { + get { + return ResourceManager.GetString("CreateFirstInvoiceItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create first tax. + /// + public static string CreateFirstInvoiceTax { + get { + return ResourceManager.GetString("CreateFirstInvoiceTax", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create item. + /// + public static string CreateInvoiceItem { + get { + return ResourceManager.GetString("CreateInvoiceItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating invoice item. + /// + public static string CreateInvoiceItemProggress { + get { + return ResourceManager.GetString("CreateInvoiceItemProggress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create tax. + /// + public static string CreateInvoiceTax { + get { + return ResourceManager.GetString("CreateInvoiceTax", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new invoice. + /// + public static string CreateNewInvoice { + get { + return ResourceManager.GetString("CreateNewInvoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new item. + /// + public static string CreateNewInvoiceItem { + get { + return ResourceManager.GetString("CreateNewInvoiceItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new tax. + /// + public static string CreateNewInvoiceTax { + get { + return ResourceManager.GetString("CreateNewInvoiceTax", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency. + /// + public static string Currency { + get { + return ResourceManager.GetString("Currency", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have a currency. + /// + public static string CurrencyRequiredErrorMsg { + get { + return ResourceManager.GetString("CurrencyRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} days. + /// + public static string DaysCount { + get { + return ResourceManager.GetString("DaysCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to These default terms will be used on future invoices.. + /// + public static string DefaultTermsInfo { + get { + return ResourceManager.GetString("DefaultTermsInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the '{0}' invoice?. + /// + public static string DeleteInvoiceConfirmMessage { + get { + return ResourceManager.GetString("DeleteInvoiceConfirmMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting invoice.... + /// + public static string DeleteInvoiceInProgress { + get { + return ResourceManager.GetString("DeleteInvoiceInProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting item.... + /// + public static string DeleteInvoiceItemInProgress { + get { + return ResourceManager.GetString("DeleteInvoiceItemInProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the «{0}» item?. + /// + public static string DeleteItemConfirmMessage { + get { + return ResourceManager.GetString("DeleteItemConfirmMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the «{0}» tax?. + /// + public static string DeleteTaxConfirmMessage { + get { + return ResourceManager.GetString("DeleteTaxConfirmMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting tax.... + /// + public static string DeleteTaxInProgress { + get { + return ResourceManager.GetString("DeleteTaxInProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete this invoice. + /// + public static string DeleteThisInvoice { + get { + return ResourceManager.GetString("DeleteThisInvoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting invoices. + /// + public static string DeletingInvoices { + get { + return ResourceManager.GetString("DeletingInvoices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description. + /// + public static string DescriptionCol { + get { + return ResourceManager.GetString("DescriptionCol", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Discount. + /// + public static string DiscountCol { + get { + return ResourceManager.GetString("DiscountCol", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Download. + /// + public static string Download { + get { + return ResourceManager.GetString("Download", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due date. + /// + public static string DueDate { + get { + return ResourceManager.GetString("DueDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please, set custom Due date or choose one of the presets on the right to link this date with the Date of issue.. + /// + public static string DueDateHelpInfoText { + get { + return ResourceManager.GetString("DueDateHelpInfoText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Issue date more than due date. + /// + public static string DueDateInvalidErrorMsg { + get { + return ResourceManager.GetString("DueDateInvalidErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due on receipt. + /// + public static string DueDatePresetInfoText { + get { + return ResourceManager.GetString("DueDatePresetInfoText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have a due date. + /// + public static string DueDateRequiredErrorMsg { + get { + return ResourceManager.GetString("DueDateRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate and Create New Invoice. + /// + public static string DuplicateAndCreateNewInvoiceButton { + get { + return ResourceManager.GetString("DuplicateAndCreateNewInvoiceButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate invoice. + /// + public static string DuplicateInvoice { + get { + return ResourceManager.GetString("DuplicateInvoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate Invoice. + /// + public static string DuplicateInvoiceButton { + get { + return ResourceManager.GetString("DuplicateInvoiceButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duplicate invoice «{0}». + /// + public static string DuplicateInvoiceHeader { + get { + return ResourceManager.GetString("DuplicateInvoiceHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit billing address. + /// + public static string EditBillingAddress { + get { + return ResourceManager.GetString("EditBillingAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit delivery address. + /// + public static string EditDeliveryAddress { + get { + return ResourceManager.GetString("EditDeliveryAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit invoice. + /// + public static string EditInvoice { + get { + return ResourceManager.GetString("EditInvoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit invoice «{0}». + /// + public static string EditInvoiceHeader { + get { + return ResourceManager.GetString("EditInvoiceHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit. + /// + public static string EditInvoiceItem { + get { + return ResourceManager.GetString("EditInvoiceItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit tax. + /// + public static string EditInvoiceTax { + get { + return ResourceManager.GetString("EditInvoiceTax", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This section allows you to set the list of items which can be included into invoices. After the list is created you can select the necessary item from it to add to your payment document. You can also add new items whenever needed.. + /// + public static string EmptyContentInvoiceItemsDescribe { + get { + return ResourceManager.GetString("EmptyContentInvoiceItemsDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No invoice items matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the invoice items in this section. Or you can create the invoice item if it is absent from the list.. + /// + public static string EmptyContentInvoiceItemsFilterDescribe { + get { + return ResourceManager.GetString("EmptyContentInvoiceItemsFilterDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No invoice items to be displayed for this filter here. + /// + public static string EmptyContentInvoiceItemsFilterHeader { + get { + return ResourceManager.GetString("EmptyContentInvoiceItemsFilterHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Products & Services list is empty. + /// + public static string EmptyContentInvoiceItemsHeader { + get { + return ResourceManager.GetString("EmptyContentInvoiceItemsHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The 'Invoices' section allows you to create payment documents that you can provide your clients with. After the invoices are added the list of the available ones will be displayed here.. + /// + public static string EmptyContentInvoicesDescribe { + get { + return ResourceManager.GetString("EmptyContentInvoicesDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No invoices matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the invoices in this section. Or you can create the invoice if it is absent from the list.. + /// + public static string EmptyContentInvoicesFilterDescribe { + get { + return ResourceManager.GetString("EmptyContentInvoicesFilterDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No invoices to be displayed for this filter here. + /// + public static string EmptyContentInvoicesFilterHeader { + get { + return ResourceManager.GetString("EmptyContentInvoicesFilterHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The invoice list is empty. + /// + public static string EmptyContentInvoicesHeader { + get { + return ResourceManager.GetString("EmptyContentInvoicesHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice taxes allow you to create additional taxes specific for the countries or areas you or your clients live in. You can add the tax name, interest rate and description. You can also add new taxes whenever needed.. + /// + public static string EmptyContentInvoiceTaxesDescribe { + get { + return ResourceManager.GetString("EmptyContentInvoiceTaxesDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The invoice taxes list is empty. + /// + public static string EmptyContentInvoiceTaxesHeader { + get { + return ResourceManager.GetString("EmptyContentInvoiceTaxesHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No opportunities found. + /// + public static string EmptyOpportunitiesText { + get { + return ResourceManager.GetString("EmptyOpportunitiesText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select Item. + /// + public static string EmptyProductText { + get { + return ResourceManager.GetString("EmptyProductText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The tax name field cannot be empty. + /// + public static string EmptyTaxNameError { + get { + return ResourceManager.GetString("EmptyTaxNameError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The rate field cannot be empty. + /// + public static string EmptyTaxRateError { + get { + return ResourceManager.GetString("EmptyTaxRateError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to None. + /// + public static string EmptyTaxText { + get { + return ResourceManager.GetString("EmptyTaxText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Price is empty. + /// + public static string ErrorEmptyPrice { + get { + return ResourceManager.GetString("ErrorEmptyPrice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Price is incorect. + /// + public static string ErrorIncorrectPrice { + get { + return ResourceManager.GetString("ErrorIncorrectPrice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Quantity is incorrect. + /// + public static string ErrorIncorrectQuantity { + get { + return ResourceManager.GetString("ErrorIncorrectQuantity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to the rate value is incorect. + /// + public static string ErrorIncorrectRate { + get { + return ResourceManager.GetString("ErrorIncorrectRate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Exchange rate. + /// + public static string ExchangeRate { + get { + return ResourceManager.GetString("ExchangeRate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You must fill this field. + /// + public static string ExchangeRateRequiredErrorMsg { + get { + return ResourceManager.GetString("ExchangeRateRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The tax name already exist. + /// + public static string ExistTaxNameError { + get { + return ResourceManager.GetString("ExistTaxNameError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Inventory stock. + /// + public static string FormInvoiceItemInventoryStock { + get { + return ResourceManager.GetString("FormInvoiceItemInventoryStock", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Item name. + /// + public static string FormInvoiceItemName { + get { + return ResourceManager.GetString("FormInvoiceItemName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Price. + /// + public static string FormInvoiceItemPrice { + get { + return ResourceManager.GetString("FormInvoiceItemPrice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stock quantity. + /// + public static string FormInvoiceItemStockQuantity { + get { + return ResourceManager.GetString("FormInvoiceItemStockQuantity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Taxes. + /// + public static string FormInvoiceItemTaxes { + get { + return ResourceManager.GetString("FormInvoiceItemTaxes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find by title, SKU or description. + /// + public static string InfoiceItemsFilterWatermarkText { + get { + return ResourceManager.GetString("InfoiceItemsFilterWatermarkText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice. + /// + public static string Invoice { + get { + return ResourceManager.GetString("Invoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Client. + /// + public static string InvoiceClient { + get { + return ResourceManager.GetString("InvoiceClient", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have a client. + /// + public static string InvoiceClientReqiuredErrorMsg { + get { + return ResourceManager.GetString("InvoiceClientReqiuredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Consignee. + /// + public static string InvoiceConsignee { + get { + return ResourceManager.GetString("InvoiceConsignee", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your default CRM currency is used to set prices in Products & Services Catalog.<br/>To change it, please go to <a href="settings.aspx?type=common" target="_blank">Common Settings</a>. + /// + public static string InvoiceCurrencyHelpInfo { + get { + return ResourceManager.GetString("InvoiceCurrencyHelpInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Active. + /// + public static string InvoiceItemActiveStatus { + get { + return ResourceManager.GetString("InvoiceItemActiveStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Archived. + /// + public static string InvoiceItemArchivedStatus { + get { + return ResourceManager.GetString("InvoiceItemArchivedStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Name. + /// + public static string InvoiceItemName { + get { + return ResourceManager.GetString("InvoiceItemName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to One or more invoice items have negative stock quantities. + /// + public static string InvoiceItemNegativeQuantityErrorText { + get { + return ResourceManager.GetString("InvoiceItemNegativeQuantityErrorText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Price. + /// + public static string InvoiceItemPrice { + get { + return ResourceManager.GetString("InvoiceItemPrice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to With inventory stock. + /// + public static string InvoiceItemWithIventoryStock { + get { + return ResourceManager.GetString("InvoiceItemWithIventoryStock", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Without inventory stock. + /// + public static string InvoiceItemWithoutIventoryStock { + get { + return ResourceManager.GetString("InvoiceItemWithoutIventoryStock", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice language. + /// + public static string InvoiceLanguage { + get { + return ResourceManager.GetString("InvoiceLanguage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have a language. + /// + public static string InvoiceLanguageRequiredErrorMsgs { + get { + return ResourceManager.GetString("InvoiceLanguageRequiredErrorMsgs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice number. + /// + public static string InvoiceNumber { + get { + return ResourceManager.GetString("InvoiceNumber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The invoice number is already taken. + /// + public static string InvoiceNumberBusyError { + get { + return ResourceManager.GetString("InvoiceNumberBusyError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoices. + /// + public static string Invoices { + get { + return ResourceManager.GetString("Invoices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status. + /// + public static string InvoicesByStatus { + get { + return ResourceManager.GetString("InvoicesByStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax 1 name. + /// + public static string InvoiceTax1Name { + get { + return ResourceManager.GetString("InvoiceTax1Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax 1 rate. + /// + public static string InvoiceTax1Rate { + get { + return ResourceManager.GetString("InvoiceTax1Rate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax 2 name. + /// + public static string InvoiceTax2Name { + get { + return ResourceManager.GetString("InvoiceTax2Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax 2 rate. + /// + public static string InvoiceTax2Rate { + get { + return ResourceManager.GetString("InvoiceTax2Rate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax with such a name has already been registered. + /// + public static string InvoiceTaxAlreadyRegisteredError { + get { + return ResourceManager.GetString("InvoiceTaxAlreadyRegisteredError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax categories let you create additional taxes specific for the countries or areas you or your clients live in. You can add the tax name, interest rate and description.. + /// + public static string InvoiceTaxesDescriptionText { + get { + return ResourceManager.GetString("InvoiceTaxesDescriptionText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can delete the tax category only in case it is not used in the Products&Services section.. + /// + public static string InvoiceTaxesDescriptionTextEditDelete { + get { + return ResourceManager.GetString("InvoiceTaxesDescriptionTextEditDelete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax name. + /// + public static string InvoiceTaxName { + get { + return ResourceManager.GetString("InvoiceTaxName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rate. + /// + public static string InvoiceTaxRate { + get { + return ResourceManager.GetString("InvoiceTaxRate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice Date. + /// + public static string IssueDate { + get { + return ResourceManager.GetString("IssueDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have a date. + /// + public static string IssueDateRequiredErrorMsg { + get { + return ResourceManager.GetString("IssueDateRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Item. + /// + public static string ItemCol { + get { + return ResourceManager.GetString("ItemCol", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your default CRM currency.<br/>To change it, please go to <a href="?type=common" target="_blank">Common Settings</a>. + /// + public static string ItemCurrencyHelpInfo { + get { + return ResourceManager.GetString("ItemCurrencyHelpInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add the quantity of items you currently have in stock. This number will decrease every time the item is added to an invoice. When you receive more inventory, simply add it to your current inventory here.. + /// + public static string IventoryStockHelpInfo { + get { + return ResourceManager.GetString("IventoryStockHelpInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link with opportunity. + /// + public static string LinkOpportunityButton { + get { + return ResourceManager.GetString("LinkOpportunityButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Make out an invoice. + /// + public static string MakeOutAnInvoice { + get { + return ResourceManager.GetString("MakeOutAnInvoice", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mark as draft. + /// + public static string MarkAsDraft { + get { + return ResourceManager.GetString("MarkAsDraft", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mark as paid. + /// + public static string MarkAsPaid { + get { + return ResourceManager.GetString("MarkAsPaid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mark as rejected. + /// + public static string MarkAsRejected { + get { + return ResourceManager.GetString("MarkAsRejected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mark as billed. + /// + public static string MarkAsSend { + get { + return ResourceManager.GetString("MarkAsSend", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Number. + /// + public static string Number { + get { + return ResourceManager.GetString("Number", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Format is incorrect or invoice with the same number already exists. + /// + public static string NumberFormatErrorMsg { + get { + return ResourceManager.GetString("NumberFormatErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start number is empty. + /// + public static string NumberFormatRequiredErrorMsg { + get { + return ResourceManager.GetString("NumberFormatRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have a number. + /// + public static string NumberRequiredErrorMsg { + get { + return ResourceManager.GetString("NumberRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overdue. + /// + public static string OverdueInvoicesFilter { + get { + return ResourceManager.GetString("OverdueInvoicesFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PO Number. + /// + public static string PONumber { + get { + return ResourceManager.GetString("PONumber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Prefix. + /// + public static string Prefix { + get { + return ResourceManager.GetString("Prefix", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Price. + /// + public static string PriceCol { + get { + return ResourceManager.GetString("PriceCol", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Print. + /// + public static string Print { + get { + return ResourceManager.GetString("Print", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Products & Services. + /// + public static string ProductsAndServices { + get { + return ResourceManager.GetString("ProductsAndServices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select product or service from list or add new. + /// + public static string ProductsAndServicesEmptyItemErrorMsgs { + get { + return ResourceManager.GetString("ProductsAndServicesEmptyItemErrorMsgs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have items. + /// + public static string ProductsAndServicesRequiredErrorMsg { + get { + return ResourceManager.GetString("ProductsAndServicesRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Quantity. + /// + public static string QuantityCol { + get { + return ResourceManager.GetString("QuantityCol", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Quantity. + /// + public static string QuantityItem { + get { + return ResourceManager.GetString("QuantityItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving number settings.... + /// + public static string SaveNumberSettingsProgress { + get { + return ResourceManager.GetString("SaveNumberSettingsProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving terms settings.... + /// + public static string SaveTermsSettingsProgress { + get { + return ResourceManager.GetString("SaveTermsSettingsProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An error "{0}" occurred while saving the invoice. Please try again later.. + /// + public static string SavingInvoiceServerError { + get { + return ResourceManager.GetString("SavingInvoiceServerError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Seller. + /// + public static string Seller { + get { + return ResourceManager.GetString("Seller", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send by email. + /// + public static string SendByEmail { + get { + return ResourceManager.GetString("SendByEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set default. + /// + public static string SetDefault { + get { + return ResourceManager.GetString("SetDefault", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set default terms. + /// + public static string SetDefaultTerms { + get { + return ResourceManager.GetString("SetDefaultTerms", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set empty. + /// + public static string SetEmpty { + get { + return ResourceManager.GetString("SetEmpty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ship To. + /// + public static string ShipTo { + get { + return ResourceManager.GetString("ShipTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show invoice profile. + /// + public static string ShowInvoiceProfile { + get { + return ResourceManager.GetString("ShowInvoiceProfile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open in a new tab. + /// + public static string ShowInvoiceProfileNewTab { + get { + return ResourceManager.GetString("ShowInvoiceProfileNewTab", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start number. + /// + public static string StartNumber { + get { + return ResourceManager.GetString("StartNumber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status. + /// + public static string Status { + get { + return ResourceManager.GetString("Status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stock keeping unit (SKU). + /// + public static string StockKeepingUnit { + get { + return ResourceManager.GetString("StockKeepingUnit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Subtotal. + /// + public static string Subtotal { + get { + return ResourceManager.GetString("Subtotal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax. + /// + public static string Tax { + get { + return ResourceManager.GetString("Tax", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tax. + /// + public static string TaxCol { + get { + return ResourceManager.GetString("TaxCol", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Terms. + /// + public static string Terms { + get { + return ResourceManager.GetString("Terms", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every invoice must have terms. + /// + public static string TermsRequiredErrorMsg { + get { + return ResourceManager.GetString("TermsRequiredErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice Total. + /// + public static string Total { + get { + return ResourceManager.GetString("Total", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total invoices. + /// + public static string TotalInvoices { + get { + return ResourceManager.GetString("TotalInvoices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Track inventory. + /// + public static string TrackInventory { + get { + return ResourceManager.GetString("TrackInventory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Update item «{0}». + /// + public static string UpdateInvoiceItem { + get { + return ResourceManager.GetString("UpdateInvoiceItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Update «{0}» tax. + /// + public static string UpdateTaxHeaderText { + get { + return ResourceManager.GetString("UpdateTaxHeaderText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving changes.... + /// + public static string UpdateTaxProcessText { + get { + return ResourceManager.GetString("UpdateTaxProcessText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warning. + /// + public static string Warning { + get { + return ResourceManager.GetString("Warning", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMInvoiceResource.resx b/products/ASC.CRM/Server/Resources/CRMInvoiceResource.resx new file mode 100644 index 00000000000..2a53624d952 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMInvoiceResource.resx @@ -0,0 +1,624 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Add and Create New Invoice + + + Add billing address + + + Add delivery address + + + Add Line + + + Address has been successfully updated + + + Create new tax + + + Creating a tax + + + Save and Create New Item + + + Add This Invoice + + + All invoices + + + Amount + + + Attach document + + + automatically generated + + + Bill To + + + Currency + + + Due date + + + Change format + + + All the future invoices will have the prefix/number format set using the fields below. Check the appropriate box to generate numbers automatically. + + + Change status + + + Client notes + + + Will be displayed on the invoice and in the letter body if you send the invoice per ONLYOFFICE™ Mail. + + + Consignee + + + coincides with the client + + + Create first invoice + + + Create first item + + + Create first tax + + + Create item + + + Creating invoice item + + + Create tax + + + Create new invoice + + + Create new item + + + Create new tax + + + Currency + + + Every invoice must have a currency + + + {0} days + + + These default terms will be used on future invoices. + + + Are you sure you want to delete the '{0}' invoice? + + + Deleting invoice... + + + Deleting item... + + + Are you sure you want to delete the «{0}» item? + + + Are you sure you want to delete the «{0}» tax? + + + Deleting tax... + + + Delete this invoice + + + Deleting invoices + + + Description + + + Discount + + + Download + + + Due date + + + Please, set custom Due date or choose one of the presets on the right to link this date with the Date of issue. + + + Issue date more than due date + + + Due on receipt + + + Every invoice must have a due date + + + Duplicate and Create New Invoice + + + Duplicate invoice + + + Duplicate Invoice + + + Duplicate invoice «{0}» + + + Edit billing address + + + Edit delivery address + + + Edit invoice + + + Edit invoice «{0}» + + + Edit + + + Edit tax + + + This section allows you to set the list of items which can be included into invoices. After the list is created you can select the necessary item from it to add to your payment document. You can also add new items whenever needed. + + + No invoice items matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the invoice items in this section. Or you can create the invoice item if it is absent from the list. + + + No invoice items to be displayed for this filter here + + + Products & Services list is empty + + + The 'Invoices' section allows you to create payment documents that you can provide your clients with. After the invoices are added the list of the available ones will be displayed here. + + + No invoices matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the invoices in this section. Or you can create the invoice if it is absent from the list. + + + No invoices to be displayed for this filter here + + + The invoice list is empty + + + Invoice taxes allow you to create additional taxes specific for the countries or areas you or your clients live in. You can add the tax name, interest rate and description. You can also add new taxes whenever needed. + + + The invoice taxes list is empty + + + No opportunities found + + + Select Item + + + The tax name field cannot be empty + + + The rate field cannot be empty + + + None + + + Price is empty + + + Price is incorect + + + Quantity is incorrect + + + the rate value is incorect + + + Exchange rate + + + You must fill this field + + + Inventory stock + + + Item name + + + Price + + + Stock quantity + + + Taxes + + + Find by title, SKU or description + + + Invoice + + + Client + + + Every invoice must have a client + + + Consignee + + + Your default CRM currency is used to set prices in Products & Services Catalog.<br/>To change it, please go to <a href="settings.aspx?type=common" target="_blank">Common Settings</a> + + + Active + + + Archived + + + Name + + + One or more invoice items have negative stock quantities + + + Price + + + With inventory stock + + + Without inventory stock + + + Invoice language + + + Every invoice must have a language + + + Invoice number + + + The invoice number is already taken + + + Invoices + + + Status + + + Tax 1 name + + + Tax 1 rate + + + Tax 2 name + + + Tax 2 rate + + + Tax with such a name has already been registered + + + Tax categories let you create additional taxes specific for the countries or areas you or your clients live in. You can add the tax name, interest rate and description. + + + You can delete the tax category only in case it is not used in the Products&Services section. + + + Tax name + + + Rate + + + Invoice Date + + + Every invoice must have a date + + + Item + + + Your default CRM currency.<br/>To change it, please go to <a href="?type=common" target="_blank">Common Settings</a> + + + Add the quantity of items you currently have in stock. This number will decrease every time the item is added to an invoice. When you receive more inventory, simply add it to your current inventory here. + + + Link with opportunity + + + Make out an invoice + + + Mark as draft + + + Mark as paid + + + Mark as rejected + + + Mark as billed + + + Number + + + Format is incorrect or invoice with the same number already exists + + + Start number is empty + + + Every invoice must have a number + + + Overdue + + + PO Number + + + Prefix + + + Price + + + Print + + + Products & Services + + + Select product or service from list or add new + + + Every invoice must have items + + + Quantity + + + Quantity + + + Saving number settings... + + + Saving terms settings... + + + An error "{0}" occurred while saving the invoice. Please try again later. + + + Seller + + + Send by email + + + Set default + + + Set default terms + + + Set empty + + + Ship To + + + Show invoice profile + + + Open in a new tab + + + Start number + + + Status + + + Stock keeping unit (SKU) + + + Subtotal + + + Tax + + + Tax + + + Terms + + + Every invoice must have terms + + + Invoice Total + + + Total invoices + + + Track inventory + + + Update item «{0}» + + + Update «{0}» tax + + + Saving changes... + + + Warning + + + The tax name already exist + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMJSResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMJSResource.Designer.cs new file mode 100644 index 00000000000..83d3931eaf6 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMJSResource.Designer.cs @@ -0,0 +1,1558 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMJSResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMJSResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMJSResource", typeof(CRMJSResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Actual date of the deal. + /// + public static string ActualCloseDate { + get { + return ResourceManager.GetString("ActualCloseDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding an opportunity.... + /// + public static string AddNewDealProgress { + get { + return ResourceManager.GetString("AddNewDealProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add email. + /// + public static string AddNewEmail { + get { + return ResourceManager.GetString("AddNewEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding an invoice.... + /// + public static string AddNewInvoiceProgress { + get { + return ResourceManager.GetString("AddNewInvoiceProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add phone. + /// + public static string AddNewPhone { + get { + return ResourceManager.GetString("AddNewPhone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create New Task. + /// + public static string AddNewTask { + get { + return ResourceManager.GetString("AddNewTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to addresses. + /// + public static string AddressGenitivePlural { + get { + return ResourceManager.GetString("AddressGenitivePlural", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to addresses. + /// + public static string AddressGenitiveSingular { + get { + return ResourceManager.GetString("AddressGenitiveSingular", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Address. + /// + public static string AddressWatermark { + get { + return ResourceManager.GetString("AddressWatermark", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisTask { + get { + return ResourceManager.GetString("AddThisTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to batch. + /// + public static string Batch { + get { + return ResourceManager.GetString("Batch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per day. + /// + public static string BidType_PerDay { + get { + return ResourceManager.GetString("BidType_PerDay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per hour. + /// + public static string BidType_PerHour { + get { + return ResourceManager.GetString("BidType_PerHour", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per month. + /// + public static string BidType_PerMonth { + get { + return ResourceManager.GetString("BidType_PerMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per week. + /// + public static string BidType_PerWeek { + get { + return ResourceManager.GetString("BidType_PerWeek", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to per year. + /// + public static string BidType_PerYear { + get { + return ResourceManager.GetString("BidType_PerYear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Billing address. + /// + public static string BillingAddress { + get { + return ResourceManager.GetString("BillingAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Browse. + /// + public static string Browse { + get { + return ResourceManager.GetString("Browse", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Case. + /// + public static string Case { + get { + return ResourceManager.GetString("Case", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed. + /// + public static string CaseStatusClosed { + get { + return ResourceManager.GetString("CaseStatusClosed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open. + /// + public static string CaseStatusOpened { + get { + return ResourceManager.GetString("CaseStatusOpened", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit. + /// + public static string Change { + get { + return ResourceManager.GetString("Change", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Mark as primary. + /// + public static string CheckAsPrimary { + get { + return ResourceManager.GetString("CheckAsPrimary", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choose. + /// + public static string Choose { + get { + return ResourceManager.GetString("Choose", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to City. + /// + public static string CityWatermark { + get { + return ResourceManager.GetString("CityWatermark", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close case. + /// + public static string CloseCase { + get { + return ResourceManager.GetString("CloseCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Company. + /// + public static string Company { + get { + return ResourceManager.GetString("Company", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to change this key?. + /// + public static string ConfirmChangeKey { + get { + return ResourceManager.GetString("ConfirmChangeKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Note: all previously created forms will no longer work. + /// + public static string ConfirmChangeKeyNote { + get { + return ResourceManager.GetString("ConfirmChangeKeyNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete this task?. + /// + public static string ConfirmDeleteTask { + get { + return ResourceManager.GetString("ConfirmDeleteTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All the entered information will be lost. + ///Are you sure you want to continue anyway?. + /// + public static string ConfirmGoToCustomFieldPage { + get { + return ResourceManager.GetString("ConfirmGoToCustomFieldPage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please enter the name of your Twitter account. For example, teamlabdotcom. + /// + public static string ContactTwitterDescription { + get { + return ResourceManager.GetString("ContactTwitterDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Country. + /// + public static string CountryWatermark { + get { + return ResourceManager.GetString("CountryWatermark", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current month. + /// + public static string CurrentMonth { + get { + return ResourceManager.GetString("CurrentMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current user. + /// + public static string CurrentUser { + get { + return ResourceManager.GetString("CurrentUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current week. + /// + public static string CurrentWeek { + get { + return ResourceManager.GetString("CurrentWeek", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom period. + /// + public static string CustomPeriod { + get { + return ResourceManager.GetString("CustomPeriod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity. + /// + public static string Deal { + get { + return ResourceManager.GetString("Deal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the '{0}' case?. + /// + public static string DeleteCaseConfirmMessage { + get { + return ResourceManager.GetString("DeleteCaseConfirmMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting case.... + /// + public static string DeleteCaseInProgress { + get { + return ResourceManager.GetString("DeleteCaseInProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete company. + /// + public static string DeleteCompany { + get { + return ResourceManager.GetString("DeleteCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the '{0}' company?. + /// + public static string DeleteCompanyConfirmMessage { + get { + return ResourceManager.GetString("DeleteCompanyConfirmMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Note: this action cannot be undone. + /// + public static string DeleteConfirmNote { + get { + return ResourceManager.GetString("DeleteConfirmNote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting contact.... + /// + public static string DeleteContactInProgress { + get { + return ResourceManager.GetString("DeleteContactInProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the '{0}' opportunity?. + /// + public static string DeleteDealConfirmMessage { + get { + return ResourceManager.GetString("DeleteDealConfirmMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deleting opportunity.... + /// + public static string DeleteDealInProgress { + get { + return ResourceManager.GetString("DeleteDealInProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the '{0}' person?. + /// + public static string DeletePersonConfirmMessage { + get { + return ResourceManager.GetString("DeletePersonConfirmMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delivery address. + /// + public static string DeliveryAddress { + get { + return ResourceManager.GetString("DeliveryAddress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit email. + /// + public static string EditEmail { + get { + return ResourceManager.GetString("EditEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving changes.... + /// + public static string EditingDealProgress { + get { + return ResourceManager.GetString("EditingDealProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving changes.... + /// + public static string EditingInvoiceProgress { + get { + return ResourceManager.GetString("EditingInvoiceProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit phone. + /// + public static string EditPhone { + get { + return ResourceManager.GetString("EditPhone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit «{0}» field. + /// + public static string EditSelectedCustomField { + get { + return ResourceManager.GetString("EditSelectedCustomField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit task. + /// + public static string EditTask { + get { + return ResourceManager.GetString("EditTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} selected. + /// + public static string ElementsSelectedCount { + get { + return ResourceManager.GetString("ElementsSelectedCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Empty. + /// + public static string Empty { + get { + return ResourceManager.GetString("Empty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The settings fields cannot be empty. + /// + public static string EmptyFieldsOfSettings { + get { + return ResourceManager.GetString("EmptyFieldsOfSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The element list cannot be empty. + /// + public static string EmptyItemList { + get { + return ResourceManager.GetString("EmptyItemList", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every field must have a title. + /// + public static string EmptyLabelError { + get { + return ResourceManager.GetString("EmptyLabelError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every letter must have a body. + /// + public static string EmptyLetterBodyContent { + get { + return ResourceManager.GetString("EmptyLetterBodyContent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every task must have a due date. + /// + public static string EmptyTaskDeadline { + get { + return ResourceManager.GetString("EmptyTaskDeadline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every task must have a responsible one. + /// + public static string EmptyTaskResponsible { + get { + return ResourceManager.GetString("EmptyTaskResponsible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every task must have a title. + /// + public static string EmptyTaskTitle { + get { + return ResourceManager.GetString("EmptyTaskTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The title field cannot be empty. + /// + public static string EmptyTitleError { + get { + return ResourceManager.GetString("EmptyTitleError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No fields corresponding to the 'Case Title' could be found. + /// + public static string ErrorCasesNotMappingBasicColumn { + get { + return ResourceManager.GetString("ErrorCasesNotMappingBasicColumn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No person is selected. + /// + public static string ErrorContactIsNotSelected { + get { + return ResourceManager.GetString("ErrorContactIsNotSelected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No fields corresponding to the 'First Name' or 'Company Name' could be found. + /// + public static string ErrorContactNotMappingBasicColumn { + get { + return ResourceManager.GetString("ErrorContactNotMappingBasicColumn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} email recipients maximum. + /// + public static string ErrorEmailRecipientsCount { + get { + return ResourceManager.GetString("ErrorEmailRecipientsCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter the case title. + /// + public static string ErrorEmptyCaseTitle { + get { + return ResourceManager.GetString("ErrorEmptyCaseTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Obligatory fields must not be duplicated. + /// + public static string ErrorMappingMoreBasicColumn { + get { + return ResourceManager.GetString("ErrorMappingMoreBasicColumn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Image format is not supported. + /// + public static string ErrorMessage_NotImageSupportFormat { + get { + return ResourceManager.GetString("ErrorMessage_NotImageSupportFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to File format is not supported. + /// + public static string ErrorMessage_NotSupportedFileFormat { + get { + return ResourceManager.GetString("ErrorMessage_NotSupportedFileFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An error occurred while uploading the image to the server. + /// + public static string ErrorMessage_SaveImageError { + get { + return ResourceManager.GetString("ErrorMessage_SaveImageError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Incorrect email. + /// + public static string ErrorNotCorrectEmail { + get { + return ResourceManager.GetString("ErrorNotCorrectEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No fields corresponding to the 'Opportunity Title', 'Opportunity Responsible' could be found. + /// + public static string ErrorOpportunityNotMappingBasicColumn { + get { + return ResourceManager.GetString("ErrorOpportunityNotMappingBasicColumn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No fields corresponding to the 'Task Title', 'Responsible', 'Due Date' could be found. + /// + public static string ErrorTaskNotMappingBasicColumn { + get { + return ResourceManager.GetString("ErrorTaskNotMappingBasicColumn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The "{0}" type is the last one. It cannot be deleted.. + /// + public static string ErrorTheLastContactStage { + get { + return ResourceManager.GetString("ErrorTheLastContactStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The "{0}" type is the last one. It cannot be deleted.. + /// + public static string ErrorTheLastContactType { + get { + return ResourceManager.GetString("ErrorTheLastContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This is the only opportunity stage. It cannot be deleted.. + /// + public static string ErrorTheLastDealMilestone { + get { + return ResourceManager.GetString("ErrorTheLastDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The "{0}" category is the last one. It cannot be deleted.. + /// + public static string ErrorTheLastHistoryCategory { + get { + return ResourceManager.GetString("ErrorTheLastHistoryCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The "{0}" category is the last one. It cannot be deleted.. + /// + public static string ErrorTheLastTaskCategory { + get { + return ResourceManager.GetString("ErrorTheLastTaskCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Estimated deal due date. + /// + public static string ExpectedCloseDate { + get { + return ResourceManager.GetString("ExpectedCloseDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find account in Twitter. + /// + public static string FindTwitter { + get { + return ResourceManager.GetString("FindTwitter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your recipient list has been generated. {0} Click the links below to pass your email addresses over to the email program.. + /// + public static string GenerateLinkInfo { + get { + return ResourceManager.GetString("GenerateLinkInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to Settings. + /// + public static string GoToSettings { + get { + return ResourceManager.GetString("GoToSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open the portal Settings page if you need to restrict the access to the CRM module and give some users administrator privileges.. + /// + public static string HelpContentAccessRights { + get { + return ResourceManager.GetString("HelpContentAccessRights", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Click this button and select the Import contacts option if you need to transfer your contacts from a CSV file, all at once.. + /// + public static string HelpContentAddContacts { + get { + return ResourceManager.GetString("HelpContentAddContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use this button to start creating your customer database adding persons and companies and linking them.. + /// + public static string HelpContentCreateNew { + get { + return ResourceManager.GetString("HelpContentCreateNew", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use this link to build a form that you can publish on your site and capture new contacts automatically.. + /// + public static string HelpContentCreateWebsite { + get { + return ResourceManager.GetString("HelpContentCreateWebsite", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manage Access Rights. + /// + public static string HelpTitleAccessRights { + get { + return ResourceManager.GetString("HelpTitleAccessRights", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add Contacts in Bulk. + /// + public static string HelpTitleAddContacts { + get { + return ResourceManager.GetString("HelpTitleAddContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create New Contact. + /// + public static string HelpTitleCreateNew { + get { + return ResourceManager.GetString("HelpTitleCreateNew", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create a Website Contact Form. + /// + public static string HelpTitleCreateWebsite { + get { + return ResourceManager.GetString("HelpTitleCreateWebsite", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link with project. + /// + public static string LinkWithProject { + get { + return ResourceManager.GetString("LinkWithProject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Uploading. + /// + public static string Loading { + get { + return ResourceManager.GetString("Loading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Loading.... + /// + public static string LoadingProcessing { + get { + return ResourceManager.GetString("LoadingProcessing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to cases. + /// + public static string ManyCases { + get { + return ResourceManager.GetString("ManyCases", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to companies. + /// + public static string ManyCompanies { + get { + return ResourceManager.GetString("ManyCompanies", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to contacts. + /// + public static string ManyContacts { + get { + return ResourceManager.GetString("ManyContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to opportunities. + /// + public static string ManyDeals { + get { + return ResourceManager.GetString("ManyDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to events. + /// + public static string ManyEvents { + get { + return ResourceManager.GetString("ManyEvents", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to persons. + /// + public static string ManyPersons { + get { + return ResourceManager.GetString("ManyPersons", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to tasks. + /// + public static string ManyTasks { + get { + return ResourceManager.GetString("ManyTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New document. + /// + public static string NewDocument { + get { + return ResourceManager.GetString("NewDocument", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next. + /// + public static string Next { + get { + return ResourceManager.GetString("Next", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next (to preview). + /// + public static string NextPreview { + get { + return ResourceManager.GetString("NextPreview", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no cases. + /// + public static string NoCases { + get { + return ResourceManager.GetString("NoCases", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No close date. + /// + public static string NoCloseDate { + get { + return ResourceManager.GetString("NoCloseDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no companies. + /// + public static string NoCompanies { + get { + return ResourceManager.GetString("NoCompanies", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no contacts. + /// + public static string NoContacts { + get { + return ResourceManager.GetString("NoContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no opportunities. + /// + public static string NoDeals { + get { + return ResourceManager.GetString("NoDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no events. + /// + public static string NoEvents { + get { + return ResourceManager.GetString("NoEvents", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No file has been selected. + /// + public static string NoFileSelected { + get { + return ResourceManager.GetString("NoFileSelected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no persons. + /// + public static string NoPersons { + get { + return ResourceManager.GetString("NoPersons", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to no subject. + /// + public static string NoSubject { + get { + return ResourceManager.GetString("NoSubject", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to There are no tasks. + /// + public static string NoTasks { + get { + return ResourceManager.GetString("NoTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to case. + /// + public static string OneCase { + get { + return ResourceManager.GetString("OneCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to company. + /// + public static string OneCompany { + get { + return ResourceManager.GetString("OneCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to contact. + /// + public static string OneContact { + get { + return ResourceManager.GetString("OneContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to opportunity. + /// + public static string OneDeal { + get { + return ResourceManager.GetString("OneDeal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to event. + /// + public static string OneEvent { + get { + return ResourceManager.GetString("OneEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to person. + /// + public static string OnePerson { + get { + return ResourceManager.GetString("OnePerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to task. + /// + public static string OneTask { + get { + return ResourceManager.GetString("OneTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open a case. + /// + public static string OpenCase { + get { + return ResourceManager.GetString("OpenCase", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overall progress. + /// + public static string OverallProgress { + get { + return ResourceManager.GetString("OverallProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to during {0} days. + /// + public static string PerPeriodDays { + get { + return ResourceManager.GetString("PerPeriodDays", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to during {0} hours. + /// + public static string PerPeriodHours { + get { + return ResourceManager.GetString("PerPeriodHours", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to during {0} months. + /// + public static string PerPeriodMonths { + get { + return ResourceManager.GetString("PerPeriodMonths", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to during {0} weeks. + /// + public static string PerPeriodWeeks { + get { + return ResourceManager.GetString("PerPeriodWeeks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to during {0} years. + /// + public static string PerPeriodYears { + get { + return ResourceManager.GetString("PerPeriodYears", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please reload the page. + /// + public static string PleaseRefreshThePage { + get { + return ResourceManager.GetString("PleaseRefreshThePage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please wait.... + /// + public static string PleaseWait { + get { + return ResourceManager.GetString("PleaseWait", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Possible profiles for {0}. + /// + public static string PossibleSocialMediaAccounts { + get { + return ResourceManager.GetString("PossibleSocialMediaAccounts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous. + /// + public static string Previous { + get { + return ResourceManager.GetString("Previous", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Primary. + /// + public static string Primary { + get { + return ResourceManager.GetString("Primary", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} recipients didn't have email addresses.. + /// + public static string RecipientsWithoutEmail { + get { + return ResourceManager.GetString("RecipientsWithoutEmail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save changes. + /// + public static string SaveChanges { + get { + return ResourceManager.GetString("SaveChanges", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a CSV file. + /// + public static string SelectCSVFileButton { + get { + return ResourceManager.GetString("SelectCSVFileButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Selected CSV file: {0}. + /// + public static string SelectedCSVFileLabel { + get { + return ResourceManager.GetString("SelectedCSVFileLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choices. + /// + public static string SelectOptions { + get { + return ResourceManager.GetString("SelectOptions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send. + /// + public static string Send { + get { + return ResourceManager.GetString("Send", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Settings have been successfully updated. + /// + public static string SettingsUpdated { + get { + return ResourceManager.GetString("SettingsUpdated", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show {0} more from {1}. + /// + public static string ShowMore { + get { + return ResourceManager.GetString("ShowMore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show more. + /// + public static string ShowMoreButtonText { + get { + return ResourceManager.GetString("ShowMoreButtonText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Temperature level. + /// + public static string Stage { + get { + return ResourceManager.GetString("Stage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to State. + /// + public static string StateWatermark { + get { + return ResourceManager.GetString("StateWatermark", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Successfully closed. + /// + public static string SuccessfullyClosed { + get { + return ResourceManager.GetString("SuccessfullyClosed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The «{0}» task is closed. + /// + public static string TaskIsOver { + get { + return ResourceManager.GetString("TaskIsOver", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Powered by {0}. + /// + public static string TeamlabWatermark { + get { + return ResourceManager.GetString("TeamlabWatermark", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0} days {1} hours {2} minutes from the container start. + /// + public static string TemplateFixedDeadline { + get { + return ResourceManager.GetString("TemplateFixedDeadline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to From the previous task {0} days {1} hours {2} minutes. + /// + public static string TemplateNotFixedDeadline { + get { + return ResourceManager.GetString("TemplateNotFixedDeadline", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Today. + /// + public static string Today { + get { + return ResourceManager.GetString("Today", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unsuccessfully closed. + /// + public static string UnsuccessfullyClosed { + get { + return ResourceManager.GetString("UnsuccessfullyClosed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Attach file. + /// + public static string UploadFile { + get { + return ResourceManager.GetString("UploadFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The file «{0}» is being uploaded.... + /// + public static string UploadingProgress { + get { + return ResourceManager.GetString("UploadingProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Agent. + /// + public static string VoipCallAgent { + get { + return ResourceManager.GetString("VoipCallAgent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Answered. + /// + public static string VoipCallAnsweredType { + get { + return ResourceManager.GetString("VoipCallAnsweredType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Caller. + /// + public static string VoipCallCaller { + get { + return ResourceManager.GetString("VoipCallCaller", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to contact removed. + /// + public static string VoipCallContactRemoved { + get { + return ResourceManager.GetString("VoipCallContactRemoved", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cost. + /// + public static string VoipCallCost { + get { + return ResourceManager.GetString("VoipCallCost", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Date. + /// + public static string VoipCallDate { + get { + return ResourceManager.GetString("VoipCallDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duration. + /// + public static string VoipCallDuration { + get { + return ResourceManager.GetString("VoipCallDuration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Missed. + /// + public static string VoipCallMissedType { + get { + return ResourceManager.GetString("VoipCallMissedType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Outgoing. + /// + public static string VoipCallOutgoingType { + get { + return ResourceManager.GetString("VoipCallOutgoingType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type. + /// + public static string VoipCallType { + get { + return ResourceManager.GetString("VoipCallType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Zip code. + /// + public static string ZipCodeWatermark { + get { + return ResourceManager.GetString("ZipCodeWatermark", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMJSResource.resx b/products/ASC.CRM/Server/Resources/CRMJSResource.resx new file mode 100644 index 00000000000..158d14700db --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMJSResource.resx @@ -0,0 +1,619 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Actual date of the deal + + + Adding an opportunity... + + + Add email + + + Adding an invoice... + + + Add phone + + + Create New Task + + + addresses + + + addresses + + + Address + + + Save + + + batch + + + per day + + + per hour + + + per month + + + per week + + + per year + + + Billing address + + + Browse + + + Case + + + Closed + + + Open + + + Edit + + + Mark as primary + + + Choose + + + City + + + Close case + + + Company + + + Are you sure you want to change this key? + + + Note: all previously created forms will no longer work + + + Are you sure you want to delete this task? + + + All the entered information will be lost. +Are you sure you want to continue anyway? + + + Please enter the name of your Twitter account. For example, teamlabdotcom + + + Current month + + + Current user + + + Current week + + + Custom period + + + Opportunity + + + Are you sure you want to delete the '{0}' case? + + + Deleting case... + + + Delete company + + + Are you sure you want to delete the '{0}' company? + + + Note: this action cannot be undone + + + Deleting contact... + + + Are you sure you want to delete the '{0}' opportunity? + + + Deleting opportunity... + + + Are you sure you want to delete the '{0}' person? + + + Delivery address + + + Edit email + + + Saving changes... + + + Saving changes... + + + Edit phone + + + Edit «{0}» field + + + Edit task + + + {0} selected + + + Empty + + + The settings fields cannot be empty + + + The element list cannot be empty + + + Every field must have a title + + + Every letter must have a body + + + Every task must have a due date + + + Every task must have a responsible one + + + Every task must have a title + + + The title field cannot be empty + + + No fields corresponding to the 'Case Title' could be found + + + No person is selected + + + No fields corresponding to the 'First Name' or 'Company Name' could be found + + + {0} email recipients maximum + + + Enter the case title + + + Obligatory fields must not be duplicated + + + Image format is not supported + + + File format is not supported + + + An error occurred while uploading the image to the server + + + Incorrect email + + + No fields corresponding to the 'Opportunity Title', 'Opportunity Responsible' could be found + + + No fields corresponding to the 'Task Title', 'Responsible', 'Due Date' could be found + + + The "{0}" type is the last one. It cannot be deleted. + + + The "{0}" type is the last one. It cannot be deleted. + + + This is the only opportunity stage. It cannot be deleted. + + + The "{0}" category is the last one. It cannot be deleted. + + + The "{0}" category is the last one. It cannot be deleted. + + + Estimated deal due date + + + Find account in Twitter + + + Your recipient list has been generated. {0} Click the links below to pass your email addresses over to the email program. + + + Go to Settings + + + Open the portal Settings page if you need to restrict the access to the CRM module and give some users administrator privileges. + + + Click this button and select the Import contacts option if you need to transfer your contacts from a CSV file, all at once. + + + Use this button to start creating your customer database adding persons and companies and linking them. + + + Use this link to build a form that you can publish on your site and capture new contacts automatically. + + + Manage Access Rights + + + Add Contacts in Bulk + + + Create New Contact + + + Create a Website Contact Form + + + Link with project + + + Uploading + + + Loading... + + + cases + + + companies + + + contacts + + + opportunities + + + events + + + persons + + + tasks + + + New document + + + Next + + + Next (to preview) + + + There are no cases + + + No close date + + + There are no companies + + + There are no contacts + + + There are no opportunities + + + There are no events + + + No file has been selected + + + There are no persons + + + no subject + + + There are no tasks + + + case + + + company + + + contact + + + opportunity + + + event + + + person + + + task + + + Open a case + + + Overall progress + + + during {0} days + + + during {0} hours + + + during {0} months + + + during {0} weeks + + + during {0} years + + + Please reload the page + + + Please wait... + + + Possible profiles for {0} + + + Previous + + + Primary + + + {0} recipients didn't have email addresses. + + + Save changes + + + Select a CSV file + + + Selected CSV file: {0} + + + Choices + + + Send + + + Settings have been successfully updated + + + Show {0} more from {1} + + + Show more + + + Temperature level + + + State + + + Successfully closed + + + The «{0}» task is closed + + + Powered by {0} + + + {0} days {1} hours {2} minutes from the container start + + + From the previous task {0} days {1} hours {2} minutes + + + Today + + + Unsuccessfully closed + + + Attach file + + + The file «{0}» is being uploaded... + + + Agent + + + Answered + + + Caller + + + contact removed + + + Cost + + + Date + + + Duration + + + Missed + + + Outgoing + + + Type + + + Zip code + + + Country + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMReportResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMReportResource.Designer.cs new file mode 100644 index 00000000000..17ad6e6df75 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMReportResource.Designer.cs @@ -0,0 +1,1181 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMReportResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMReportResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMReportResource", typeof(CRMReportResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The average budget of opportunities. + /// + public static string AverageDealsBudget { + get { + return ResourceManager.GetString("AverageDealsBudget", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The average duration of a successful opportunity, days. + /// + public static string AverageDealsDuration { + get { + return ResourceManager.GetString("AverageDealsDuration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Billed. + /// + public static string Billed { + get { + return ResourceManager.GetString("Billed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Billed invoices . + /// + public static string BilledInvoices { + get { + return ResourceManager.GetString("BilledInvoices", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Budget. + /// + public static string Budget { + get { + return ResourceManager.GetString("Budget", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Empty docbuilder path. + /// + public static string BuildErrorEmptyDocbuilderPath { + get { + return ResourceManager.GetString("BuildErrorEmptyDocbuilderPath", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Empty docbuilder template. + /// + public static string BuildErrorEmptyDocbuilderTemplate { + get { + return ResourceManager.GetString("BuildErrorEmptyDocbuilderTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An error has occurred. Empty output file. + /// + public static string BuildErrorEmptyOutputFile { + get { + return ResourceManager.GetString("BuildErrorEmptyOutputFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Maximum number of process is exceeded. Try later. + /// + public static string BuildErrorMaxProcessExceeded { + get { + return ResourceManager.GetString("BuildErrorMaxProcessExceeded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to By the budget. + /// + public static string ByBudget { + get { + return ResourceManager.GetString("ByBudget", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to By number. + /// + public static string ByCount { + get { + return ResourceManager.GetString("ByCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calls. + /// + public static string Calls { + get { + return ResourceManager.GetString("Calls", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calls count. + /// + public static string CallsCount { + get { + return ResourceManager.GetString("CallsCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calls duration. + /// + public static string CallsDuration { + get { + return ResourceManager.GetString("CallsDuration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Calls for the period. + /// + public static string CallsForThePeriod { + get { + return ResourceManager.GetString("CallsForThePeriod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed. + /// + public static string Closed { + get { + return ResourceManager.GetString("Closed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed tasks. + /// + public static string ClosedTasks { + get { + return ResourceManager.GetString("ClosedTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Complete. + /// + public static string Complete { + get { + return ResourceManager.GetString("Complete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contacts by temperature level. + /// + public static string ContactsByStage { + get { + return ResourceManager.GetString("ContactsByStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contacts by type. + /// + public static string ContactsByType { + get { + return ResourceManager.GetString("ContactsByType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to With opportunities. + /// + public static string ContactsWithDeals { + get { + return ResourceManager.GetString("ContactsWithDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Without opportunities. + /// + public static string ContactsWithoutDeals { + get { + return ResourceManager.GetString("ContactsWithoutDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Conversion. + /// + public static string Conversion { + get { + return ResourceManager.GetString("Conversion", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Count. + /// + public static string Count { + get { + return ResourceManager.GetString("Count", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Created. + /// + public static string Created { + get { + return ResourceManager.GetString("Created", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to To generate the report the opportunity budget must be brought to the base currency. Setup the used currency exchange rates to do that.. + /// + public static string CurrencySettingsDialogBody { + get { + return ResourceManager.GetString("CurrencySettingsDialogBody", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency Settings. + /// + public static string CurrencySettingsDialogHdr { + get { + return ResourceManager.GetString("CurrencySettingsDialogHdr", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current month. + /// + public static string CurrentMonth { + get { + return ResourceManager.GetString("CurrentMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current quarter. + /// + public static string CurrentQuarter { + get { + return ResourceManager.GetString("CurrentQuarter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current week. + /// + public static string CurrentWeek { + get { + return ResourceManager.GetString("CurrentWeek", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Current year. + /// + public static string CurrentYear { + get { + return ResourceManager.GetString("CurrentYear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Day. + /// + public static string Day { + get { + return ResourceManager.GetString("Day", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Budget of opportunities. + /// + public static string DealsBudget { + get { + return ResourceManager.GetString("DealsBudget", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities by budget. + /// + public static string DealsByBudget { + get { + return ResourceManager.GetString("DealsByBudget", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities by number. + /// + public static string DealsByCount { + get { + return ResourceManager.GetString("DealsByCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities by stage. + /// + public static string DealsByStage { + get { + return ResourceManager.GetString("DealsByStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities by status. + /// + public static string DealsByStatus { + get { + return ResourceManager.GetString("DealsByStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Number of opportunities. + /// + public static string DealsCount { + get { + return ResourceManager.GetString("DealsCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duration. + /// + public static string Duration { + get { + return ResourceManager.GetString("Duration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to During all time. + /// + public static string DuringAllTime { + get { + return ResourceManager.GetString("DuringAllTime", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error. + /// + public static string Error { + get { + return ResourceManager.GetString("Error", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not get docbuilder response. + /// + public static string ErrorNullDocbuilderResponse { + get { + return ResourceManager.GetString("ErrorNullDocbuilderResponse", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not get report data. + /// + public static string ErrorNullReportData { + get { + return ResourceManager.GetString("ErrorNullReportData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not get report script. + /// + public static string ErrorNullReportScript { + get { + return ResourceManager.GetString("ErrorNullReportScript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generated reports. + /// + public static string GeneratedReports { + get { + return ResourceManager.GetString("GeneratedReports", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All your generated reports are displayed here. You can edit, delete or download the report files. To create a report, select a template from the list to the left, set the filters and click the 'Generate' button.. + /// + public static string GeneratedReportsDescription { + get { + return ResourceManager.GetString("GeneratedReportsDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate report. + /// + public static string GenerateReport { + get { + return ResourceManager.GetString("GenerateReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If all opportunities won. + /// + public static string IfAllOpportunitiesWon { + get { + return ResourceManager.GetString("IfAllOpportunitiesWon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Incoming. + /// + public static string Incoming { + get { + return ResourceManager.GetString("Incoming", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoices by status. + /// + public static string InvoicesByStatus { + get { + return ResourceManager.GetString("InvoicesByStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoices for the period. + /// + public static string InvoicesForThePeriod { + get { + return ResourceManager.GetString("InvoicesForThePeriod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Item. + /// + public static string Item { + get { + return ResourceManager.GetString("Item", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lost. + /// + public static string Lost { + get { + return ResourceManager.GetString("Lost", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Manager. + /// + public static string Manager { + get { + return ResourceManager.GetString("Manager", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Managers. + /// + public static string Managers { + get { + return ResourceManager.GetString("Managers", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to of which {0} are unanswered. + /// + public static string MissedCount { + get { + return ResourceManager.GetString("MissedCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Month. + /// + public static string Month { + get { + return ResourceManager.GetString("Month", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Will close in the next 30 days. + /// + public static string Near { + get { + return ResourceManager.GetString("Near", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New. + /// + public static string New { + get { + return ResourceManager.GetString("New", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New contacts. + /// + public static string NewContacts { + get { + return ResourceManager.GetString("NewContacts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New contacts with and without opportunities. + /// + public static string NewContactsWithAndWithoutDeals { + get { + return ResourceManager.GetString("NewContactsWithAndWithoutDeals", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New tasks. + /// + public static string NewTasks { + get { + return ResourceManager.GetString("NewTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next month. + /// + public static string NextMonth { + get { + return ResourceManager.GetString("NextMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next quarter. + /// + public static string NextQuarter { + get { + return ResourceManager.GetString("NextQuarter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next week. + /// + public static string NextWeek { + get { + return ResourceManager.GetString("NextWeek", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next year. + /// + public static string NextYear { + get { + return ResourceManager.GetString("NextYear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No data for the report. Select another filter.. + /// + public static string NoData { + get { + return ResourceManager.GetString("NoData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open. + /// + public static string Open { + get { + return ResourceManager.GetString("Open", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opened. + /// + public static string Opened { + get { + return ResourceManager.GetString("Opened", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Outcoming. + /// + public static string Outcoming { + get { + return ResourceManager.GetString("Outcoming", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overdue. + /// + public static string Overdue { + get { + return ResourceManager.GetString("Overdue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overdue tasks. + /// + public static string OverdueTasks { + get { + return ResourceManager.GetString("OverdueTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Paid. + /// + public static string Paid { + get { + return ResourceManager.GetString("Paid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous month. + /// + public static string PreviousMonth { + get { + return ResourceManager.GetString("PreviousMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous quarter. + /// + public static string PreviousQuarter { + get { + return ResourceManager.GetString("PreviousQuarter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous week. + /// + public static string PreviousWeek { + get { + return ResourceManager.GetString("PreviousWeek", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous year. + /// + public static string PreviousYear { + get { + return ResourceManager.GetString("PreviousYear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rejected. + /// + public static string Rejected { + get { + return ResourceManager.GetString("Rejected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Report building. + /// + public static string ReportBuilding { + get { + return ResourceManager.GetString("ReportBuilding", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All generated reports you can always see, download, edit, or delete them in {0}CRM/Reports/Generated reports{1}. + /// + public static string ReportBuildingInfo { + get { + return ResourceManager.GetString("ReportBuildingInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Report building ({0}% complete). + /// + public static string ReportBuildingProgress { + get { + return ResourceManager.GetString("ReportBuildingProgress", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reports. + /// + public static string Reports { + get { + return ResourceManager.GetString("Reports", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales by the day, by the managers. + /// + public static string SalesByDay { + get { + return ResourceManager.GetString("SalesByDay", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales by the hour, by the managers. + /// + public static string SalesByHour { + get { + return ResourceManager.GetString("SalesByHour", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales By Managers. + /// + public static string SalesByManagersReport { + get { + return ResourceManager.GetString("SalesByManagersReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the successfully closed opportunities for the selected {1}Time period{2} for all the managers or only the selected ones.{0} When the week or month period is selected, the report shows the results grouped by days, the quarter and year periods will group the data by months.. + /// + public static string SalesByManagersReportDescription { + get { + return ResourceManager.GetString("SalesByManagersReportDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales by the month, by the managers. + /// + public static string SalesByMonth { + get { + return ResourceManager.GetString("SalesByMonth", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales Forecast. + /// + public static string SalesForecastReport { + get { + return ResourceManager.GetString("SalesForecastReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the sales forecast for a particular period of time, taking into account the opportunity probability. It shows the number of opportunities for the selected {1}Time period{2} for all the managers or only the selected ones.{0} The data includes the total budget for the opportunities, which estimated closing date falls into the selected period of time.. + /// + public static string SalesForecastReportDescription { + get { + return ResourceManager.GetString("SalesForecastReportDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales funnel by budget of opportunities. + /// + public static string SalesFunnelByBudget { + get { + return ResourceManager.GetString("SalesFunnelByBudget", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales funnel by number of opportunities. + /// + public static string SalesFunnelByCount { + get { + return ResourceManager.GetString("SalesFunnelByCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sales Funnel. + /// + public static string SalesFunnelReport { + get { + return ResourceManager.GetString("SalesFunnelReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended for building sales funnel for a particular period of time. It shows the number of opportunities for the selected {1}Time period{2} for all the managers or only the selected ones. + ///{0} The main data includes the number of opportunities in the funnel, average opportunity budget, average duration of successfully closed opportunities, the ratio of open to closed opportunities. + ///{0} The data is sorted by the opportunity number and budget.. + /// + public static string SalesFunnelReportDescription { + get { + return ResourceManager.GetString("SalesFunnelReportDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Stage. + /// + public static string Stage { + get { + return ResourceManager.GetString("Stage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status. + /// + public static string Status { + get { + return ResourceManager.GetString("Status", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Sum. + /// + public static string Sum { + get { + return ResourceManager.GetString("Sum", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the summary data for the opportunities, contacts, tasks and invoices by the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the opportunities specified by the status and by their stage, contacts by type and stage, tasks and invoices by their status.. + /// + public static string SummaryAtThisMomentDescription { + get { + return ResourceManager.GetString("SummaryAtThisMomentDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Summary for the Moment. + /// + public static string SummaryAtThisMomentReport { + get { + return ResourceManager.GetString("SummaryAtThisMomentReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Summary for the Period. + /// + public static string SummaryForThePeriodReport { + get { + return ResourceManager.GetString("SummaryForThePeriodReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the summary data for the opportunities, contacts, tasks and invoices for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the opportunities specified by the budget and by their number, contacts by type, tasks and invoices by the time period.. + /// + public static string SummaryForThePeriodReportDescription { + get { + return ResourceManager.GetString("SummaryForThePeriodReportDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks by status. + /// + public static string TasksByStatus { + get { + return ResourceManager.GetString("TasksByStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks for the period. + /// + public static string TasksForThePeriod { + get { + return ResourceManager.GetString("TasksForThePeriod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time period. + /// + public static string TimePeriod { + get { + return ResourceManager.GetString("TimePeriod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Today. + /// + public static string Today { + get { + return ResourceManager.GetString("Today", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tomorrow. + /// + public static string Tomorrow { + get { + return ResourceManager.GetString("Tomorrow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total. + /// + public static string Total { + get { + return ResourceManager.GetString("Total", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The total budget of opportunities. + /// + public static string TotalDealsBudget { + get { + return ResourceManager.GetString("TotalDealsBudget", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The total number of opportunities. + /// + public static string TotalDealsCount { + get { + return ResourceManager.GetString("TotalDealsCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Total sales for the period by managers. + /// + public static string TotalSalesByManagers { + get { + return ResourceManager.GetString("TotalSalesByManagers", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type. + /// + public static string Type { + get { + return ResourceManager.GetString("Type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to With respect to probability. + /// + public static string WithRespectToProbability { + get { + return ResourceManager.GetString("WithRespectToProbability", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Won. + /// + public static string Won { + get { + return ResourceManager.GetString("Won", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the total number of contacts for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the new contacts specified by type and by the presence and absence of opportunities. The data is grouped by managers only.. + /// + public static string WorkloadByContactsDescription { + get { + return ResourceManager.GetString("WorkloadByContactsDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contacts by Managers. + /// + public static string WorkloadByContactsReport { + get { + return ResourceManager.GetString("WorkloadByContactsReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the total workload of won and lost opportunities for the selected {1}Time period{2} for all the managers or only the selected ones. The data is grouped by managers only.. + /// + public static string WorkloadByDealsDescription { + get { + return ResourceManager.GetString("WorkloadByDealsDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunities by Managers. + /// + public static string WorkloadByDealsReport { + get { + return ResourceManager.GetString("WorkloadByDealsReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the total number of invoices for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the total number of sent invoices as well as number of paid, rejected and overdue invoices. The data is grouped by managers only.. + /// + public static string WorkloadByInvoicesDescription { + get { + return ResourceManager.GetString("WorkloadByInvoicesDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoices by Managers. + /// + public static string WorkloadByInvoicesReport { + get { + return ResourceManager.GetString("WorkloadByInvoicesReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the total number of tasks for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the closed, new and overdue tasks specified by type. The data is grouped by managers only.. + /// + public static string WorkloadByTasksDescription { + get { + return ResourceManager.GetString("WorkloadByTasksDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks by Managers. + /// + public static string WorkloadByTasksReport { + get { + return ResourceManager.GetString("WorkloadByTasksReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This report is intended to show the total number of calls for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the total number of incoming, outcoming calls and theirs duration. The data is grouped by managers only.. + /// + public static string WorkloadByVoipDescription { + get { + return ResourceManager.GetString("WorkloadByVoipDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please note that this report will only be available if you connect Twillio. To connect, follow the {0}link{1}. + /// + public static string WorkloadByVoipNotAllowed { + get { + return ResourceManager.GetString("WorkloadByVoipNotAllowed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Voip by Managers. + /// + public static string WorkloadByVoipReport { + get { + return ResourceManager.GetString("WorkloadByVoipReport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yesterday. + /// + public static string Yesterday { + get { + return ResourceManager.GetString("Yesterday", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMReportResource.resx b/products/ASC.CRM/Server/Resources/CRMReportResource.resx new file mode 100644 index 00000000000..f65f4a2a4a1 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMReportResource.resx @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Generate report + + + Managers + + + Reports + + + Sales By Managers + + + To generate the report the opportunity budget must be brought to the base currency. Setup the used currency exchange rates to do that. + + + Currency Settings + + + Manager + + + Sales by the day, by the managers + + + Sales by the hour, by the managers + + + Sales by the month, by the managers + + + Sum + + + Time period + + + Total + + + Total sales for the period by managers + + + Current month + + + Current quarter + + + Current week + + + Current year + + + Next month + + + Next quarter + + + Next week + + + Next year + + + No data for the report. Select another filter. + + + Previous month + + + Previous quarter + + + Previous week + + + Previous year + + + This report is intended to show the successfully closed opportunities for the selected {1}Time period{2} for all the managers or only the selected ones.{0} When the week or month period is selected, the report shows the results grouped by days, the quarter and year periods will group the data by months. + + + Sales Forecast + + + This report is intended to show the sales forecast for a particular period of time, taking into account the opportunity probability. It shows the number of opportunities for the selected {1}Time period{2} for all the managers or only the selected ones.{0} The data includes the total budget for the opportunities, which estimated closing date falls into the selected period of time. + + + Today + + + Tomorrow + + + Yesterday + + + Day + + + Month + + + Sales Funnel + + + This report is intended for building sales funnel for a particular period of time. It shows the number of opportunities for the selected {1}Time period{2} for all the managers or only the selected ones. +{0} The main data includes the number of opportunities in the funnel, average opportunity budget, average duration of successfully closed opportunities, the ratio of open to closed opportunities. +{0} The data is sorted by the opportunity number and budget. + + + The average budget of opportunities + + + The average duration of a successful opportunity, days + + + Budget + + + By the budget + + + By number + + + Conversion + + + Count + + + Budget of opportunities + + + Number of opportunities + + + Sales funnel by budget of opportunities + + + Sales funnel by number of opportunities + + + The total budget of opportunities + + + The total number of opportunities + + + Contacts by Managers + + + Opportunities by Managers + + + Invoices by Managers + + + Tasks by Managers + + + This report is intended to show the total number of contacts for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the new contacts specified by type and by the presence and absence of opportunities. The data is grouped by managers only. + + + Lost + + + New + + + Won + + + This report is intended to show the total workload of won and lost opportunities for the selected {1}Time period{2} for all the managers or only the selected ones. The data is grouped by managers only. + + + This report is intended to show the total number of invoices for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the total number of sent invoices as well as number of paid, rejected and overdue invoices. The data is grouped by managers only. + + + This report is intended to show the total number of tasks for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the closed, new and overdue tasks specified by type. The data is grouped by managers only. + + + Empty docbuilder path + + + Empty docbuilder template + + + An error has occurred. Empty output file + + + Maximum number of process is exceeded. Try later + + + Report building + + + Generated reports + + + All your generated reports are displayed here. You can edit, delete or download the report files. To create a report, select a template from the list to the left, set the filters and click the 'Generate' button. + + + Complete + + + Error + + + Open + + + All generated reports you can always see, download, edit, or delete them in {0}CRM/Reports/Generated reports{1} + + + Report building ({0}% complete) + + + Closed tasks + + + New tasks + + + Overdue tasks + + + Billed invoices + + + Paid + + + Rejected + + + With opportunities + + + Without opportunities + + + New contacts + + + New contacts with and without opportunities + + + During all time + + + Summary for the Period + + + This report is intended to show the summary data for the opportunities, contacts, tasks and invoices for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the opportunities specified by the budget and by their number, contacts by type, tasks and invoices by the time period. + + + Closed + + + Contacts by type + + + Created + + + Opportunities by budget + + + Opportunities by number + + + Invoices for the period + + + Item + + + Overdue + + + Status + + + Tasks for the period + + + Type + + + Contacts by temperature level + + + Opportunities by stage + + + Opportunities by status + + + Invoices by status + + + Will close in the next 30 days + + + Stage + + + This report is intended to show the summary data for the opportunities, contacts, tasks and invoices by the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the opportunities specified by the status and by their stage, contacts by type and stage, tasks and invoices by their status. + + + Summary for the Moment + + + Tasks by status + + + Billed + + + Opened + + + Calls count + + + Calls duration + + + Incoming + + + Outcoming + + + This report is intended to show the total number of calls for the selected {1}Time period{2} for all the managers or only the selected ones. The report will show the total number of incoming, outcoming calls and theirs duration. The data is grouped by managers only. + + + Voip by Managers + + + Calls + + + Calls for the period + + + Duration + + + of which {0} are unanswered + + + Please note that this report will only be available if you connect Twillio. To connect, follow the {0}link{1} + + + Could not get docbuilder response + + + Could not get report data + + + Could not get report script + + + If all opportunities won + + + With respect to probability + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMSettingResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMSettingResource.Designer.cs new file mode 100644 index 00000000000..3aaa2361f2f --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMSettingResource.Designer.cs @@ -0,0 +1,1580 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMSettingResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMSettingResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMSettingResource", typeof(CRMSettingResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Cancel. + /// + public static string AbortExport { + get { + return ResourceManager.GetString("AbortExport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Access rights & Tags. + /// + public static string AccessRightsAndTags { + get { + return ResourceManager.GetString("AccessRightsAndTags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set up the access rights for the users added via the "Website Contact Form", otherwise all CRM users will see new contacts. Create tags the new clients in the list will be marked with.. + /// + public static string AccessRightsAndTagsDescription { + get { + return ResourceManager.GetString("AccessRightsAndTagsDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Portal Access Rights. + /// + public static string AccessRightsSettings { + get { + return ResourceManager.GetString("AccessRightsSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add rate. + /// + public static string AddCurrencyRate { + get { + return ResourceManager.GetString("AddCurrencyRate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add new tag. + /// + public static string AddNewTag { + get { + return ResourceManager.GetString("AddNewTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add new task template. + /// + public static string AddNewTaskTemplate { + get { + return ResourceManager.GetString("AddNewTaskTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add new task template container. + /// + public static string AddNewTaskTemplateContainer { + get { + return ResourceManager.GetString("AddNewTaskTemplateContainer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add an Option. + /// + public static string AddOption { + get { + return ResourceManager.GetString("AddOption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Address. + /// + public static string Address { + get { + return ResourceManager.GetString("Address", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add tag. + /// + public static string AddTag { + get { + return ResourceManager.GetString("AddTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding tag. + /// + public static string AddTagInProgressing { + get { + return ResourceManager.GetString("AddTagInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do not show the Linking Contacts dialog again. + /// + public static string AddTagWithoutAskingSettingsLabel { + get { + return ResourceManager.GetString("AddTagWithoutAskingSettingsLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add task template. + /// + public static string AddTaskTemplate { + get { + return ResourceManager.GetString("AddTaskTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add task template container. + /// + public static string AddTaskTemplateContainer { + get { + return ResourceManager.GetString("AddTaskTemplateContainer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding task template container. + /// + public static string AddTaskTemplateContainerInProgressing { + get { + return ResourceManager.GetString("AddTaskTemplateContainerInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Adding task template. + /// + public static string AddTaskTemplateInProgressing { + get { + return ResourceManager.GetString("AddTaskTemplateInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisCategory { + get { + return ResourceManager.GetString("AddThisCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisContactType { + get { + return ResourceManager.GetString("AddThisContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisDealMilestone { + get { + return ResourceManager.GetString("AddThisDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisField { + get { + return ResourceManager.GetString("AddThisField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisStage { + get { + return ResourceManager.GetString("AddThisStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Save. + /// + public static string AddThisTag { + get { + return ResourceManager.GetString("AddThisTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add this task template. + /// + public static string AddThisTaskTemplate { + get { + return ResourceManager.GetString("AddThisTaskTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add this task template container. + /// + public static string AddThisTaskTemplateContainer { + get { + return ResourceManager.GetString("AddThisTaskTemplateContainer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Basic Information. + /// + public static string BasicInformation { + get { + return ResourceManager.GetString("BasicInformation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Both Person & Company. + /// + public static string BothPersonAndCompany { + get { + return ResourceManager.GetString("BothPersonAndCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change color. + /// + public static string ChangeColor { + get { + return ResourceManager.GetString("ChangeColor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do not show the Linking Contacts dialog again. + /// + public static string ChangeContactStatusWithoutAskingSettingsLabel { + get { + return ResourceManager.GetString("ChangeContactStatusWithoutAskingSettingsLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to change the default currency?. + /// + public static string ChangeDefaultCurrencyConfText { + get { + return ResourceManager.GetString("ChangeDefaultCurrencyConfText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change icon. + /// + public static string ChangeIcon { + get { + return ResourceManager.GetString("ChangeIcon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Change Logo. + /// + public static string ChangeLogo { + get { + return ResourceManager.GetString("ChangeLogo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Checkbox. + /// + public static string CheckBox { + get { + return ResourceManager.GetString("CheckBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Columns. + /// + public static string Cols { + get { + return ResourceManager.GetString("Cols", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Common Settings. + /// + public static string CommonSettings { + get { + return ResourceManager.GetString("CommonSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Configure the SMTP. + /// + public static string ConfigureTheSMTP { + get { + return ResourceManager.GetString("ConfigureTheSMTP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to SMTP server is not configured. Fill in the fields and click Save. You can set up the necessary parameters in the 'Settings' section.. + /// + public static string ConfigureTheSMTPInfo { + get { + return ResourceManager.GetString("ConfigureTheSMTPInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact Types. + /// + public static string ContactTypes { + get { + return ResourceManager.GetString("ContactTypes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating category. + /// + public static string CreateCategoryInProgressing { + get { + return ResourceManager.GetString("CreateCategoryInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating temperature level. + /// + public static string CreateContactStageInProgressing { + get { + return ResourceManager.GetString("CreateContactStageInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating contact type. + /// + public static string CreateContactTypeInProgressing { + get { + return ResourceManager.GetString("CreateContactTypeInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create user field. + /// + public static string CreateCustomField { + get { + return ResourceManager.GetString("CreateCustomField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating stage. + /// + public static string CreateDealMilestoneInProgressing { + get { + return ResourceManager.GetString("CreateDealMilestoneInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create field. + /// + public static string CreateField { + get { + return ResourceManager.GetString("CreateField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating field. + /// + public static string CreateFieldInProgressing { + get { + return ResourceManager.GetString("CreateFieldInProgressing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new category. + /// + public static string CreateNewCategory { + get { + return ResourceManager.GetString("CreateNewCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Category. + /// + public static string CreateNewCategoryListButton { + get { + return ResourceManager.GetString("CreateNewCategoryListButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new contact type. + /// + public static string CreateNewContactType { + get { + return ResourceManager.GetString("CreateNewContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Contact Type. + /// + public static string CreateNewContactTypeListButton { + get { + return ResourceManager.GetString("CreateNewContactTypeListButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new stage. + /// + public static string CreateNewDealMilestone { + get { + return ResourceManager.GetString("CreateNewDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Stage. + /// + public static string CreateNewDealMilestoneListButton { + get { + return ResourceManager.GetString("CreateNewDealMilestoneListButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new field. + /// + public static string CreateNewField { + get { + return ResourceManager.GetString("CreateNewField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Field. + /// + public static string CreateNewFieldListButton { + get { + return ResourceManager.GetString("CreateNewFieldListButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new temperature level. + /// + public static string CreateNewStage { + get { + return ResourceManager.GetString("CreateNewStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Temperature Level. + /// + public static string CreateNewStageListButton { + get { + return ResourceManager.GetString("CreateNewStageListButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create new tag. + /// + public static string CreateNewTag { + get { + return ResourceManager.GetString("CreateNewTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Tag. + /// + public static string CreateNewTagListButton { + get { + return ResourceManager.GetString("CreateNewTagListButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency rate. + /// + public static string CurrencyRate { + get { + return ResourceManager.GetString("CurrencyRate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Currency Settings. + /// + public static string CurrencySettings { + get { + return ResourceManager.GetString("CurrencySettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set up the default currency which will be used to calculate the 'Sum total' for all the opportunities present in the CRM module of your portal. The conversion rates are available for currencies from the list only and are taken from the 'The Money Converter.com' web site.{0}This currency will be the currency for your Products & Services catalog which is used to invoice.. + /// + public static string CurrencySettingsHelp { + get { + return ResourceManager.GetString("CurrencySettingsHelp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to User Fields. + /// + public static string CustomFields { + get { + return ResourceManager.GetString("CustomFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Date. + /// + public static string Date { + get { + return ResourceManager.GetString("Date", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closes opportunity unsuccessfully.. + /// + public static string DealMilestoneStatusDescription_ClosedAndLost { + get { + return ResourceManager.GetString("DealMilestoneStatusDescription_ClosedAndLost", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closes opportunity successfully.. + /// + public static string DealMilestoneStatusDescription_ClosedAndWon { + get { + return ResourceManager.GetString("DealMilestoneStatusDescription_ClosedAndWon", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Default currency. + /// + public static string DefaultCurrency { + get { + return ResourceManager.GetString("DefaultCurrency", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete category. + /// + public static string DeleteCategory { + get { + return ResourceManager.GetString("DeleteCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete temperature level. + /// + public static string DeleteContactStage { + get { + return ResourceManager.GetString("DeleteContactStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete contact type. + /// + public static string DeleteContactType { + get { + return ResourceManager.GetString("DeleteContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete field. + /// + public static string DeleteCustomField { + get { + return ResourceManager.GetString("DeleteCustomField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The selected field with all the data will be deleted from all contacts where it is present. Are you sure you want to continue?. + /// + public static string DeleteCustomFieldConfirmationText { + get { + return ResourceManager.GetString("DeleteCustomFieldConfirmationText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete stage. + /// + public static string DeleteDealMilestone { + get { + return ResourceManager.GetString("DeleteDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete tag. + /// + public static string DeleteTag { + get { + return ResourceManager.GetString("DeleteTag", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Category deletion confirmation. + /// + public static string DeleteTaskCategoryConfirmation { + get { + return ResourceManager.GetString("DeleteTaskCategoryConfirmation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete task template. + /// + public static string DeleteTaskTemplate { + get { + return ResourceManager.GetString("DeleteTaskTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete task template container. + /// + public static string DeleteTaskTemplateContainer { + get { + return ResourceManager.GetString("DeleteTaskTemplateContainer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete unused tags. + /// + public static string DeleteUnusedTags { + get { + return ResourceManager.GetString("DeleteUnusedTags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description. + /// + public static string Description { + get { + return ResourceManager.GetString("Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact temperature levels let you characterize your potential buyers in a certain way. For instance, the temperature levels can be "Cold", "Hot", "Warm", which will mean the contact's willingness to buy your product.. + /// + public static string DescriptionTextContactStage { + get { + return ResourceManager.GetString("DescriptionTextContactStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can edit or delete the contact temperature levels only in case there are no contacts of this level.. + /// + public static string DescriptionTextContactStageEditDelete { + get { + return ResourceManager.GetString("DescriptionTextContactStageEditDelete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contact types let you characterize your contacts in a certain way. The default contact types are "Client", "Competitor", "Partner", "Supplier" which classify the contacts based on their role in relation to the organization.. + /// + public static string DescriptionTextContactType { + get { + return ResourceManager.GetString("DescriptionTextContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can edit or delete the contact type only in case there are no contacts of this type.. + /// + public static string DescriptionTextContactTypeEditDelete { + get { + return ResourceManager.GetString("DescriptionTextContactTypeEditDelete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity stages let you determine steps necessary to complete the deal. For instance, you can add opportunity stages "Commercial offer", "Prepayment", "Execution". Set + /// + ///the necessary order for the opportunity stages dragging them.. + /// + public static string DescriptionTextDealMilestone { + get { + return ResourceManager.GetString("DescriptionTextDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can edit or delete the opportunity stage only in case there are no opportunities at this stage.. + /// + public static string DescriptionTextDealMilestoneEditDelete { + get { + return ResourceManager.GetString("DescriptionTextDealMilestoneEditDelete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History event categories allow you to split your history events into groups. Standard history event categories are mail, note, phone call, meeting. You need to have administrator rights to be able to edit them.. + /// + public static string DescriptionTextHistoryCategory { + get { + return ResourceManager.GetString("DescriptionTextHistoryCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can edit or delete the history event category only in case there are no history events in this category.. + /// + public static string DescriptionTextHistoryCategoryEditDelete { + get { + return ResourceManager.GetString("DescriptionTextHistoryCategoryEditDelete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task categories let you divide your tasks into groups depending on the goals you intend to achieve. For instance, a task category can be "Appointment", "Phone + /// + ///call" or "Expression of gratitude".. + /// + public static string DescriptionTextTaskCategory { + get { + return ResourceManager.GetString("DescriptionTextTaskCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You can edit or delete the task category stage only in case there are no tasks with this category.. + /// + public static string DescriptionTextTaskCategoryEditDelete { + get { + return ResourceManager.GetString("DescriptionTextTaskCategoryEditDelete", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Offset in days. + /// + public static string DisplacementInDays { + get { + return ResourceManager.GetString("DisplacementInDays", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Download all data in one ZIP-archive. + /// + public static string DownloadAllDataInZipArchive { + get { + return ResourceManager.GetString("DownloadAllDataInZipArchive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ZIP archive generation started. + /// + public static string DownloadingAllDataInZipArchive { + get { + return ResourceManager.GetString("DownloadingAllDataInZipArchive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link to download the ZIP archive. + /// + public static string DownloadLinkText { + get { + return ResourceManager.GetString("DownloadLinkText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit category. + /// + public static string EditCategory { + get { + return ResourceManager.GetString("EditCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit temperature level. + /// + public static string EditContactStage { + get { + return ResourceManager.GetString("EditContactStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit contact type. + /// + public static string EditContactType { + get { + return ResourceManager.GetString("EditContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit field. + /// + public static string EditCustomField { + get { + return ResourceManager.GetString("EditCustomField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit stage. + /// + public static string EditDealMilestone { + get { + return ResourceManager.GetString("EditDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit «{0}» task category. + /// + public static string EditSelectedCategory { + get { + return ResourceManager.GetString("EditSelectedCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit the «{0}» temperature level. + /// + public static string EditSelectedContactStage { + get { + return ResourceManager.GetString("EditSelectedContactStage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit the "{0}" contact type. + /// + public static string EditSelectedContactType { + get { + return ResourceManager.GetString("EditSelectedContactType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit «{0}» opportunity stage. + /// + public static string EditSelectedDealMilestone { + get { + return ResourceManager.GetString("EditSelectedDealMilestone", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit the «{0}» task template. + /// + public static string EditSelectedTaskTemplate { + get { + return ResourceManager.GetString("EditSelectedTaskTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit the «{0}» task template container. + /// + public static string EditSelectedTaskTemplateContainer { + get { + return ResourceManager.GetString("EditSelectedTaskTemplateContainer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit task template. + /// + public static string EditTaskTemplate { + get { + return ResourceManager.GetString("EditTaskTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit task template container. + /// + public static string EditTaskTemplateContainer { + get { + return ResourceManager.GetString("EditTaskTemplateContainer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The user field list is empty. + /// + public static string EmptyContentCustomFields { + get { + return ResourceManager.GetString("EmptyContentCustomFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to User fields let you determine additional information about the client, opportunity or case. For instance, you can add the 'Source' field to specify where the user came from: advertisement, direct sale, etc. You can edit or delete the user field only in case there are no contacts or opportunities with this field value.. + /// + public static string EmptyContentCustomFieldsDescript { + get { + return ResourceManager.GetString("EmptyContentCustomFieldsDescript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The tag list is empty. + /// + public static string EmptyContentTags { + get { + return ResourceManager.GetString("EmptyContentTags", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The tags can be used to describe and group contacts (both companies and persons), opportunities and cases which have something similar in them. For instance, you can tag all the persons from different companies but from the same sphere of business with a common tag for a better sorting. You can edit or delete the tag only in case there are no contacts, opportunities or cases with this tag.. + /// + public static string EmptyContentTagsDescript { + get { + return ResourceManager.GetString("EmptyContentTagsDescript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The list of task templates is empty. + /// + public static string EmptyContentTaskTemplates { + get { + return ResourceManager.GetString("EmptyContentTaskTemplates", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task templates allow you to create similar tasks inside the CRM module. You can add the tasks to contacts, opportunities or cases with a single mouse click. Select the container to create a task for every container task template.. + /// + public static string EmptyContentTaskTemplatesDescript { + get { + return ResourceManager.GetString("EmptyContentTaskTemplatesDescript", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This field must be filled correctly. + /// + public static string EmptyField { + get { + return ResourceManager.GetString("EmptyField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Every field must have a title. + /// + public static string EmptyLabelError { + get { + return ResourceManager.GetString("EmptyLabelError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The field title cannot be empty. + /// + public static string EmptyTitleError { + get { + return ResourceManager.GetString("EmptyTitleError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Export. + /// + public static string Export { + get { + return ResourceManager.GetString("Export", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Export of All Data. + /// + public static string ExportData { + get { + return ResourceManager.GetString("ExportData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The export function generates a ZIP-archive containing CSV files with all your CRM data (contacts, opportunities, cases, history, etc.) The email with the link to the created archive will be sent to your email address.. + /// + public static string ExportDataSettingsInfo { + get { + return ResourceManager.GetString("ExportDataSettingsInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate list for external program. + /// + public static string ExternalClient { + get { + return ResourceManager.GetString("ExternalClient", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Field list. + /// + public static string FieldList { + get { + return ResourceManager.GetString("FieldList", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fields selection. + /// + public static string FieldsSelection { + get { + return ResourceManager.GetString("FieldsSelection", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select the fields which will be displayed on the form. + /// + public static string FieldsSelectionDescription { + get { + return ResourceManager.GetString("FieldsSelectionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Form source code. + /// + public static string FormCode { + get { + return ResourceManager.GetString("FormCode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use this form on your site. + /// + public static string FormCodeDescription { + get { + return ResourceManager.GetString("FormCodeDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Preview. + /// + public static string FormPreview { + get { + return ResourceManager.GetString("FormPreview", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This is how the form on your site will look like. + /// + public static string FormPreviewDescription { + get { + return ResourceManager.GetString("FormPreviewDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Form properties. + /// + public static string FormProperties { + get { + return ResourceManager.GetString("FormProperties", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Website Contact Form main settings. + /// + public static string FormPropertiesDescription { + get { + return ResourceManager.GetString("FormPropertiesDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate Form. + /// + public static string GenerateForm { + get { + return ResourceManager.GetString("GenerateForm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Title. + /// + public static string Heading { + get { + return ResourceManager.GetString("Heading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to History Event Categories. + /// + public static string HistoryCategories { + get { + return ResourceManager.GetString("HistoryCategories", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Internal SMTP ({0} email recipients maximum). + /// + public static string InternalSMTP { + get { + return ResourceManager.GetString("InternalSMTP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Just for company. + /// + public static string JustForCompany { + get { + return ResourceManager.GetString("JustForCompany", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Just for person. + /// + public static string JustForPerson { + get { + return ResourceManager.GetString("JustForPerson", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Title. + /// + public static string Label { + get { + return ResourceManager.GetString("Label", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Learn more.... + /// + public static string LearnMore { + get { + return ResourceManager.GetString("LearnMore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Success probability. + /// + public static string Likelihood { + get { + return ResourceManager.GetString("Likelihood", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Notify {!users}. + /// + public static string NotifyUsers { + get { + return ResourceManager.GetString("NotifyUsers", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select the {!users} who will receive notification when a new contact is added via the "Website Contact Form". + /// + public static string NotifyUsersDescription { + get { + return ResourceManager.GetString("NotifyUsersDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Count from the previous task. + /// + public static string OffsetFromThePreviousTask { + get { + return ResourceManager.GetString("OffsetFromThePreviousTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Count from the container start. + /// + public static string OffsetFromTheStartOfContainer { + get { + return ResourceManager.GetString("OffsetFromTheStartOfContainer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invoice logo. + /// + public static string OrganisationLogo { + get { + return ResourceManager.GetString("OrganisationLogo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other fields. + /// + public static string OtherFields { + get { + return ResourceManager.GetString("OtherFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to This is a test mail message created by the ONLYOFFICE™ portal automatically to check the mass mailing feature.\nPlease do not reply to this message.\n\nWe are sorry for any inconveniences caused.\nBest regards,\nPortal {0} administration. + /// + public static string pattern_TestMailSMTPMainBody { + get { + return ResourceManager.GetString("pattern_TestMailSMTPMainBody", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete option. + /// + public static string RemoveOption { + get { + return ResourceManager.GetString("RemoveOption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Restore to Default. + /// + public static string RestoreLogoToDeafult { + get { + return ResourceManager.GetString("RestoreLogoToDeafult", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Redirection URL. + /// + public static string ReturnURL { + get { + return ResourceManager.GetString("ReturnURL", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The address of your web site where the user will be redirected after the form is filled.. + /// + public static string ReturnURLDescription { + get { + return ResourceManager.GetString("ReturnURLDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lines. + /// + public static string Rows { + get { + return ResourceManager.GetString("Rows", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saved. + /// + public static string SaveCompleted { + get { + return ResourceManager.GetString("SaveCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select box. + /// + public static string SelectBox { + get { + return ResourceManager.GetString("SelectBox", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Choices. + /// + public static string SelectOptions { + get { + return ResourceManager.GetString("SelectOptions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please select a category stage to be replaced with the current category in tasks. + /// + public static string SelectTaskCategoryForReplace { + get { + return ResourceManager.GetString("SelectTaskCategoryForReplace", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Customize user fields. + /// + public static string SettingCustomFields { + get { + return ResourceManager.GetString("SettingCustomFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Settings. + /// + public static string Settings { + get { + return ResourceManager.GetString("Settings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Set your organization billing address which will be placed to all your invoices. Fill the fields with the {0}Address{1}, {0}City{1}, {0}State{1}, {0}Country{1} and {0}Zip Code{1}.. + /// + public static string SettingsCompanyAddressHelp { + get { + return ResourceManager.GetString("SettingsCompanyAddressHelp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The default {0}logo{1} of your organization will be displayed on your {0}Invoices{1}.{3} + ///To replace the logo click the 'Change Logo' link and select the image stored on your computer to load it to your portal. Please, keep in mind that you can upload an image file in PNG or JPG format not larger than {0}{4}x{5} pixels{1}, otherwise resizing will take place. The maximum image size cannot exceed {0}{2}{1}.. + /// + public static string SettingsCompanyLogoHelp { + get { + return ResourceManager.GetString("SettingsCompanyLogoHelp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Size. + /// + public static string Size { + get { + return ResourceManager.GetString("Size", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Send data. + /// + public static string SubmitFormData { + get { + return ResourceManager.GetString("SubmitFormData", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tag with this title already exists. + /// + public static string TagAlreadyExistsError { + get { + return ResourceManager.GetString("TagAlreadyExistsError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task templates. + /// + public static string TaskTemplates { + get { + return ResourceManager.GetString("TaskTemplates", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text area. + /// + public static string TextArea { + get { + return ResourceManager.GetString("TextArea", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Text. + /// + public static string TextField { + get { + return ResourceManager.GetString("TextField", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Title. + /// + public static string TitleItem { + get { + return ResourceManager.GetString("TitleItem", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type. + /// + public static string Type { + get { + return ResourceManager.GetString("Type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Web Form Key. + /// + public static string WebFormKey { + get { + return ResourceManager.GetString("WebFormKey", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A unique web form key which serves for the authentication of the form used to send the data and necessary for the form correct work. This is done for the security reasons to prevent spam, fraud and protect your web form from unauthorized use. When you generate a new key the existing forms with the old key will stop working.. + /// + public static string WebFormKeyDescription { + get { + return ResourceManager.GetString("WebFormKeyDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Website Contact Form. + /// + public static string WebToLeadsForm { + get { + return ResourceManager.GetString("WebToLeadsForm", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Invalid form key. + /// + public static string WebToLeadsForm_InvalidKeyException { + get { + return ResourceManager.GetString("WebToLeadsForm_InvalidKeyException", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use the Website Contact Form functionality to build a form that you can publish on your site. It will allow you to capture new contacts automatically. Define the form properties, select the necessary fields and generate the code to create your own web form.. + /// + public static string WebToLeadsFormHeader { + get { + return ResourceManager.GetString("WebToLeadsFormHeader", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMSettingResource.resx b/products/ASC.CRM/Server/Resources/CRMSettingResource.resx new file mode 100644 index 00000000000..f6163503e30 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMSettingResource.resx @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cancel + + + Access rights & Tags + + + Set up the access rights for the users added via the "Website Contact Form", otherwise all CRM users will see new contacts. Create tags the new clients in the list will be marked with. + + + Portal Access Rights + + + Add new tag + + + Add new task template + + + Add new task template container + + + Add an Option + + + Address + + + Add tag + + + Adding tag + + + Do not show the Linking Contacts dialog again + + + Add task template + + + Add task template container + + + Adding task template container + + + Adding task template + + + Save + + + Save + + + Save + + + Save + + + Save + + + Save + + + Add this task template + + + Add this task template container + + + Basic Information + + + Both Person & Company + + + Change color + + + Do not show the Linking Contacts dialog again + + + Are you sure you want to change the default currency? + + + Change icon + + + Change Logo + + + Checkbox + + + Columns + + + Common Settings + + + Configure the SMTP + + + SMTP server is not configured. Fill in the fields and click Save. You can set up the necessary parameters in the 'Settings' section. + + + Contact Types + + + Creating category + + + Creating temperature level + + + Creating contact type + + + Create user field + + + Creating stage + + + Create field + + + Creating field + + + Create new category + + + New Category + + + Create new contact type + + + New Contact Type + + + Create new stage + + + New Stage + + + Create new field + + + New Field + + + Create new temperature level + + + New Temperature Level + + + Create new tag + + + New Tag + + + Currency Settings + + + User Fields + + + Date + + + Closes opportunity unsuccessfully. + + + Closes opportunity successfully. + + + Default currency + + + Delete category + + + Delete temperature level + + + Delete contact type + + + Delete field + + + The selected field with all the data will be deleted from all contacts where it is present. Are you sure you want to continue? + + + Delete stage + + + Delete tag + + + Category deletion confirmation + + + Delete task template + + + Delete task template container + + + Delete unused tags + + + Description + + + Contact temperature levels let you characterize your potential buyers in a certain way. For instance, the temperature levels can be "Cold", "Hot", "Warm", which will mean the contact's willingness to buy your product. + + + You can edit or delete the contact temperature levels only in case there are no contacts of this level. + + + Contact types let you characterize your contacts in a certain way. The default contact types are "Client", "Competitor", "Partner", "Supplier" which classify the contacts based on their role in relation to the organization. + + + You can edit or delete the contact type only in case there are no contacts of this type. + + + Opportunity stages let you determine steps necessary to complete the deal. For instance, you can add opportunity stages "Commercial offer", "Prepayment", "Execution". Set + +the necessary order for the opportunity stages dragging them. + + + You can edit or delete the opportunity stage only in case there are no opportunities at this stage. + + + History event categories allow you to split your history events into groups. Standard history event categories are mail, note, phone call, meeting. You need to have administrator rights to be able to edit them. + + + You can edit or delete the history event category only in case there are no history events in this category. + + + Task categories let you divide your tasks into groups depending on the goals you intend to achieve. For instance, a task category can be "Appointment", "Phone + +call" or "Expression of gratitude". + + + You can edit or delete the task category stage only in case there are no tasks with this category. + + + Offset in days + + + Download all data in one ZIP-archive + + + ZIP archive generation started + + + Link to download the ZIP archive + + + Edit category + + + Edit temperature level + + + Edit contact type + + + Edit field + + + Edit stage + + + Edit «{0}» task category + + + Edit the «{0}» temperature level + + + Edit the "{0}" contact type + + + Edit «{0}» opportunity stage + + + Edit the «{0}» task template + + + Edit the «{0}» task template container + + + Edit task template + + + Edit task template container + + + The user field list is empty + + + User fields let you determine additional information about the client, opportunity or case. For instance, you can add the 'Source' field to specify where the user came from: advertisement, direct sale, etc. You can edit or delete the user field only in case there are no contacts or opportunities with this field value. + + + The tag list is empty + + + The tags can be used to describe and group contacts (both companies and persons), opportunities and cases which have something similar in them. For instance, you can tag all the persons from different companies but from the same sphere of business with a common tag for a better sorting. You can edit or delete the tag only in case there are no contacts, opportunities or cases with this tag. + + + The list of task templates is empty + + + Task templates allow you to create similar tasks inside the CRM module. You can add the tasks to contacts, opportunities or cases with a single mouse click. Select the container to create a task for every container task template. + + + This field must be filled correctly + + + Every field must have a title + + + The field title cannot be empty + + + Export + + + Export of All Data + + + The export function generates a ZIP-archive containing CSV files with all your CRM data (contacts, opportunities, cases, history, etc.) The email with the link to the created archive will be sent to your email address. + + + Generate list for external program + + + Field list + + + Fields selection + + + Select the fields which will be displayed on the form + + + Form source code + + + Use this form on your site + + + Preview + + + This is how the form on your site will look like + + + Form properties + + + Website Contact Form main settings + + + Generate Form + + + Title + + + History Event Categories + + + Internal SMTP ({0} email recipients maximum) + + + Just for company + + + Just for person + + + Title + + + Learn more... + + + Success probability + + + Notify {!users} + + + Select the {!users} who will receive notification when a new contact is added via the "Website Contact Form" + + + Count from the previous task + + + Count from the container start + + + Invoice logo + + + Other fields + + + This is a test mail message created by the ONLYOFFICE™ portal automatically to check the mass mailing feature.\nPlease do not reply to this message.\n\nWe are sorry for any inconveniences caused.\nBest regards,\nPortal {0} administration + + + Delete option + + + Restore to Default + + + Redirection URL + + + The address of your web site where the user will be redirected after the form is filled. + + + Lines + + + Saved + + + Select box + + + Choices + + + Please select a category stage to be replaced with the current category in tasks + + + Customize user fields + + + Settings + + + Set your organization billing address which will be placed to all your invoices. Fill the fields with the {0}Address{1}, {0}City{1}, {0}State{1}, {0}Country{1} and {0}Zip Code{1}. + + + The default {0}logo{1} of your organization will be displayed on your {0}Invoices{1}.{3} +To replace the logo click the 'Change Logo' link and select the image stored on your computer to load it to your portal. Please, keep in mind that you can upload an image file in PNG or JPG format not larger than {0}{4}x{5} pixels{1}, otherwise resizing will take place. The maximum image size cannot exceed {0}{2}{1}. + + + Size + + + Send data + + + Tag with this title already exists + + + Task templates + + + Text area + + + Text + + + Title + + + Type + + + Web Form Key + + + A unique web form key which serves for the authentication of the form used to send the data and necessary for the form correct work. This is done for the security reasons to prevent spam, fraud and protect your web form from unauthorized use. When you generate a new key the existing forms with the old key will stop working. + + + Website Contact Form + + + Invalid form key + + + Use the Website Contact Form functionality to build a form that you can publish on your site. It will allow you to capture new contacts automatically. Define the form properties, select the necessary fields and generate the code to create your own web form. + + + Add rate + + + Currency rate + + + Set up the default currency which will be used to calculate the 'Sum total' for all the opportunities present in the CRM module of your portal. The conversion rates are available for currencies from the list only and are taken from the 'The Money Converter.com' web site.{0}This currency will be the currency for your Products & Services catalog which is used to invoice. + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMSocialMediaResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMSocialMediaResource.Designer.cs new file mode 100644 index 00000000000..e75ceb4aa6a --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMSocialMediaResource.Designer.cs @@ -0,0 +1,216 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMSocialMediaResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMSocialMediaResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMSocialMediaResource", typeof(CRMSocialMediaResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Return. + /// + public static string Back { + get { + return ResourceManager.GetString("Back", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Be aware of what your clients think about your produce and brand in the social network. Simply link the twitter account with the contact and follow the tweet news feed right on your portal.. + /// + public static string EmptyContentTwitterAccountsDescribe { + get { + return ResourceManager.GetString("EmptyContentTwitterAccountsDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No linked Twitter accounts. + /// + public static string EmptyContentTwitterAccountsHeader { + get { + return ResourceManager.GetString("EmptyContentTwitterAccountsHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Internal error. + /// + public static string ErrorInternalServer { + get { + return ResourceManager.GetString("ErrorInternalServer", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Twitter account could not be found. + /// + public static string ErrorTwitterAccountNotFound { + get { + return ResourceManager.GetString("ErrorTwitterAccountNotFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Could not connect to Twitter. + /// + public static string ErrorTwitterConnectionFailure { + get { + return ResourceManager.GetString("ErrorTwitterConnectionFailure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Twitter is overloaded. + /// + public static string ErrorTwitterIsDown { + get { + return ResourceManager.GetString("ErrorTwitterIsDown", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Maximal allowed number of requests to Twitter is exceeded. Try again later.. + /// + public static string ErrorTwitterRateLimit { + get { + return ResourceManager.GetString("ErrorTwitterRateLimit", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The application has no Twitter access. Please reconnect the Twitter account.. + /// + public static string ErrorTwitterUnauthorized { + get { + return ResourceManager.GetString("ErrorTwitterUnauthorized", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unknown Twitter account. + /// + public static string ErrorUnknownTwitterAccount { + get { + return ResourceManager.GetString("ErrorUnknownTwitterAccount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The information is taken from the following source. + /// + public static string InformationProvidedBy { + get { + return ResourceManager.GetString("InformationProvidedBy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link Twitter account. + /// + public static string LinkTwitterAccount { + get { + return ResourceManager.GetString("LinkTwitterAccount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No accounts could be found. + /// + public static string NoAccountsHasBeenFound { + get { + return ResourceManager.GetString("NoAccountsHasBeenFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No companies could be found. + /// + public static string NoCompaniesHasBeenFound { + get { + return ResourceManager.GetString("NoCompaniesHasBeenFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please wait.... + /// + public static string PleaseWait { + get { + return ResourceManager.GetString("PleaseWait", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter a text to search. + /// + public static string SearchText { + get { + return ResourceManager.GetString("SearchText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Twitter account is not connected. + /// + public static string SocialMediaAccountNotFoundTwitter { + get { + return ResourceManager.GetString("SocialMediaAccountNotFoundTwitter", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMSocialMediaResource.resx b/products/ASC.CRM/Server/Resources/CRMSocialMediaResource.resx new file mode 100644 index 00000000000..dbeda7f9f5c --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMSocialMediaResource.resx @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Return + + + Be aware of what your clients think about your produce and brand in the social network. Simply link the twitter account with the contact and follow the tweet news feed right on your portal. + + + No linked Twitter accounts + + + The information is taken from the following source + + + Link Twitter account + + + No accounts could be found + + + No companies could be found + + + Please wait... + + + Enter a text to search + + + Internal error + + + Twitter account could not be found + + + Could not connect to Twitter + + + Twitter is overloaded + + + Maximal allowed number of requests to Twitter is exceeded. Try again later. + + + The application has no Twitter access. Please reconnect the Twitter account. + + + Unknown Twitter account + + + Twitter account is not connected + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMTaskResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMTaskResource.Designer.cs new file mode 100644 index 00000000000..1dd0713c0f4 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMTaskResource.Designer.cs @@ -0,0 +1,765 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMTaskResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMTaskResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMTaskResource", typeof(CRMTaskResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Create new task. + /// + public static string AddNewTask { + get { + return ResourceManager.GetString("AddNewTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create New Task. + /// + public static string AddNewTaskButtonText { + get { + return ResourceManager.GetString("AddNewTaskButtonText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due date. + /// + public static string ByDueDate { + get { + return ResourceManager.GetString("ByDueDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cancel. + /// + public static string Cancel { + get { + return ResourceManager.GetString("Cancel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed task. + /// + public static string ClosedTask { + get { + return ResourceManager.GetString("ClosedTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed tasks. + /// + public static string ClosedTasks { + get { + return ResourceManager.GetString("ClosedTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Link with contact. + /// + public static string ConnectWithAContact { + get { + return ResourceManager.GetString("ConnectWithAContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create the first task. + /// + public static string CreateFirstTask { + get { + return ResourceManager.GetString("CreateFirstTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create task. + /// + public static string CreateTask { + get { + return ResourceManager.GetString("CreateTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Custom period. + /// + public static string CustomDateFilter { + get { + return ResourceManager.GetString("CustomDateFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Other users. + /// + public static string CustomResponsibleFilter { + get { + return ResourceManager.GetString("CustomResponsibleFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Deadline. + /// + public static string DeadLine { + get { + return ResourceManager.GetString("DeadLine", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete task. + /// + public static string DeleteTask { + get { + return ResourceManager.GetString("DeleteTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description. + /// + public static string Description { + get { + return ResourceManager.GetString("Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Due date. + /// + public static string DueDate { + get { + return ResourceManager.GetString("DueDate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Edit task. + /// + public static string EditTask { + get { + return ResourceManager.GetString("EditTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks are easy way to create a reminder of what is to be done. For example, a task can be used to remind of an appointment, or a phone call. You can create tasks of {0}different categories{1}, link them with a contact, opportunity or case, or create a simple reminder for yourself.. + /// + public static string EmptyContentTasksDescribe { + get { + return ResourceManager.GetString("EmptyContentTasksDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No tasks matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the tasks in this section. You can also look for the tasks you need in contacts, opportunities or cases tabs.. + /// + public static string EmptyContentTasksFilterDescribe { + get { + return ResourceManager.GetString("EmptyContentTasksFilterDescribe", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No tasks to be displayed for this filter here. + /// + public static string EmptyContentTasksFilterHeader { + get { + return ResourceManager.GetString("EmptyContentTasksFilterHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The task list is empty. + /// + public static string EmptyContentTasksHeader { + get { + return ResourceManager.GetString("EmptyContentTasksHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Find a company or a person by name. + /// + public static string FindContactByName { + get { + return ResourceManager.GetString("FindContactByName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by the selected delimiter which will be used to import tasks. The files containing more than {0} rows should be divided into smaller parts for proper importing.. + /// + public static string ImportFromCSVStepOneDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepOneDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select a CSV file. + /// + public static string ImportFromCSVStepOneHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepOneHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import tasks correctly you need to have at least the following columns from your file matched with the fields of the ONLYOFFICE™ CRM: 'Task Title', 'Responsible', 'Due Date'. The fields containing the dates must have the following format: {0}.. + /// + public static string ImportFromCSVStepTwoDescription { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please, verify the fields. + /// + public static string ImportFromCSVStepTwoHeader { + get { + return ResourceManager.GetString("ImportFromCSVStepTwoHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Go to task list. + /// + public static string ImportStartingPanelButton { + get { + return ResourceManager.GetString("ImportStartingPanelButton", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import of tasks can take several minutes depending on the amount of your data.. + /// + public static string ImportStartingPanelDescription { + get { + return ResourceManager.GetString("ImportStartingPanelDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Importing started. + /// + public static string ImportStartingPanelHeader { + get { + return ResourceManager.GetString("ImportStartingPanelHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Import tasks. + /// + public static string ImportTasks { + get { + return ResourceManager.GetString("ImportTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to My Tasks. + /// + public static string MyTasks { + get { + return ResourceManager.GetString("MyTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to My tasks. + /// + public static string MyTasksFilter { + get { + return ResourceManager.GetString("MyTasksFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to never. + /// + public static string Never { + get { + return ResourceManager.GetString("Never", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed. + /// + public static string OnlyClosedTasks { + get { + return ResourceManager.GetString("OnlyClosedTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open. + /// + public static string OnlyOpenTasks { + get { + return ResourceManager.GetString("OnlyOpenTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Overdue. + /// + public static string OverdueTasksFilter { + get { + return ResourceManager.GetString("OverdueTasksFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 15 minutes. + /// + public static string PerFifteenMinutes { + get { + return ResourceManager.GetString("PerFifteenMinutes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 5 minutes. + /// + public static string PerFiveMinutes { + get { + return ResourceManager.GetString("PerFiveMinutes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to half an hour. + /// + public static string PerHalfHour { + get { + return ResourceManager.GetString("PerHalfHour", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to an hour. + /// + public static string PerHour { + get { + return ResourceManager.GetString("PerHour", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to a day. + /// + public static string PerNight { + get { + return ResourceManager.GetString("PerNight", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 2 hours. + /// + public static string PerTwoHours { + get { + return ResourceManager.GetString("PerTwoHours", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Responsible. + /// + public static string Responsible { + get { + return ResourceManager.GetString("Responsible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Saving task. + /// + public static string SavingTask { + get { + return ResourceManager.GetString("SavingTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Show. + /// + public static string Show { + get { + return ResourceManager.GetString("Show", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Start Importing. + /// + public static string StartImport { + get { + return ResourceManager.GetString("StartImport", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task. + /// + public static string Task { + get { + return ResourceManager.GetString("Task", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks Categories. + /// + public static string TaskCategories { + get { + return ResourceManager.GetString("TaskCategories", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task category. + /// + public static string TaskCategory { + get { + return ResourceManager.GetString("TaskCategory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Phone call. + /// + public static string TaskCategory_Call { + get { + return ResourceManager.GetString("TaskCategory_Call", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Opportunity. + /// + public static string TaskCategory_Deal { + get { + return ResourceManager.GetString("TaskCategory_Deal", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Demo. + /// + public static string TaskCategory_Demo { + get { + return ResourceManager.GetString("TaskCategory_Demo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Email. + /// + public static string TaskCategory_Email { + get { + return ResourceManager.GetString("TaskCategory_Email", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fax. + /// + public static string TaskCategory_Fax { + get { + return ResourceManager.GetString("TaskCategory_Fax", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Execution control. + /// + public static string TaskCategory_FollowUP { + get { + return ResourceManager.GetString("TaskCategory_FollowUP", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lunch. + /// + public static string TaskCategory_Lunch { + get { + return ResourceManager.GetString("TaskCategory_Lunch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Appointment. + /// + public static string TaskCategory_Meeting { + get { + return ResourceManager.GetString("TaskCategory_Meeting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Note. + /// + public static string TaskCategory_Note { + get { + return ResourceManager.GetString("TaskCategory_Note", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delivery. + /// + public static string TaskCategory_Ship { + get { + return ResourceManager.GetString("TaskCategory_Ship", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Social networks. + /// + public static string TaskCategory_SocialNetworks { + get { + return ResourceManager.GetString("TaskCategory_SocialNetworks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Expression of gratitude. + /// + public static string TaskCategory_ThankYou { + get { + return ResourceManager.GetString("TaskCategory_ThankYou", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task description. + /// + public static string TaskDescription { + get { + return ResourceManager.GetString("TaskDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task «{0}» is closed. + /// + public static string TaskIsOver { + get { + return ResourceManager.GetString("TaskIsOver", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Assign to. + /// + public static string TaskResponsible { + get { + return ResourceManager.GetString("TaskResponsible", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tasks. + /// + public static string Tasks { + get { + return ResourceManager.GetString("Tasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status. + /// + public static string TasksByStatus { + get { + return ResourceManager.GetString("TasksByStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task status. + /// + public static string TaskStatus { + get { + return ResourceManager.GetString("TaskStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Closed. + /// + public static string TaskStatus_Closed { + get { + return ResourceManager.GetString("TaskStatus_Closed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Open. + /// + public static string TaskStatus_Open { + get { + return ResourceManager.GetString("TaskStatus_Open", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task title. + /// + public static string TaskTitle { + get { + return ResourceManager.GetString("TaskTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Upcoming. + /// + public static string TheNextTasksFilter { + get { + return ResourceManager.GetString("TheNextTasksFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 3 days. + /// + public static string ThreeDays { + get { + return ResourceManager.GetString("ThreeDays", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Time. + /// + public static string Time { + get { + return ResourceManager.GetString("Time", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Today. + /// + public static string Today { + get { + return ResourceManager.GetString("Today", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Today. + /// + public static string TodayTasksFilter { + get { + return ResourceManager.GetString("TodayTasksFilter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Task categories let you divide your tasks into groups depending on the goals you intend to achieve. The default task categories are phone call, opportunity, demo, email, fax, execution control, lunch, appointment, note, delivery, social networks, expression of gratitude. To be able to edit them, the administrator rights are needed.. + /// + public static string TooltipCategories { + get { + return ResourceManager.GetString("TooltipCategories", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All tasks. + /// + public static string TotalTasks { + get { + return ResourceManager.GetString("TotalTasks", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Week. + /// + public static string Week { + get { + return ResourceManager.GetString("Week", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Nobody. + /// + public static string WithoutResponsible { + get { + return ResourceManager.GetString("WithoutResponsible", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMTaskResource.resx b/products/ASC.CRM/Server/Resources/CRMTaskResource.resx new file mode 100644 index 00000000000..b8d30270543 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMTaskResource.resx @@ -0,0 +1,354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Create new task + + + Create New Task + + + Due date + + + Cancel + + + Closed task + + + Closed tasks + + + Link with contact + + + Create the first task + + + Create task + + + Custom period + + + Other users + + + Deadline + + + Delete task + + + Description + + + Due date + + + Edit task + + + Tasks are easy way to create a reminder of what is to be done. For example, a task can be used to remind of an appointment, or a phone call. You can create tasks of {0}different categories{1}, link them with a contact, opportunity or case, or create a simple reminder for yourself. + + + No tasks matching your filter can be displayed in this section. Please select other filter options or clear filter to view all the tasks in this section. You can also look for the tasks you need in contacts, opportunities or cases tabs. + + + No tasks to be displayed for this filter here + + + The task list is empty + + + Find a company or a person by name + + + A properly formed CSV file should be selected on your computer HDD. It must contain the fields or columns separated by the selected delimiter which will be used to import tasks. The files containing more than {0} rows should be divided into smaller parts for proper importing. + + + Select a CSV file + + + Match your file columns with the corresponding ONLYOFFICE™ CRM fields. Please pay your attention to the fact that to import tasks correctly you need to have at least the following columns from your file matched with the fields of the ONLYOFFICE™ CRM: 'Task Title', 'Responsible', 'Due Date'. The fields containing the dates must have the following format: {0}. + + + Please, verify the fields + + + Go to task list + + + Import of tasks can take several minutes depending on the amount of your data. + + + Importing started + + + Import tasks + + + My Tasks + + + My tasks + + + never + + + Closed + + + Open + + + Overdue + + + 15 minutes + + + 5 minutes + + + half an hour + + + an hour + + + a day + + + 2 hours + + + Responsible + + + Saving task + + + Show + + + Start Importing + + + Task + + + Tasks Categories + + + Task category + + + Phone call + + + Opportunity + + + Demo + + + Email + + + Fax + + + Execution control + + + Lunch + + + Appointment + + + Note + + + Delivery + + + Social networks + + + Expression of gratitude + + + Task description + + + Task «{0}» is closed + + + Assign to + + + Tasks + + + Status + + + Task status + + + Closed + + + Open + + + Task title + + + Upcoming + + + 3 days + + + Time + + + Today + + + Today + + + Task categories let you divide your tasks into groups depending on the goals you intend to achieve. The default task categories are phone call, opportunity, demo, email, fax, execution control, lunch, appointment, note, delivery, social networks, expression of gratitude. To be able to edit them, the administrator rights are needed. + + + All tasks + + + Week + + + Nobody + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Resources/CRMVoipResource.Designer.cs b/products/ASC.CRM/Server/Resources/CRMVoipResource.Designer.cs new file mode 100644 index 00000000000..e65a65f20a3 --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMVoipResource.Designer.cs @@ -0,0 +1,847 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMVoipResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMVoipResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Resources.CRMVoipResource", typeof(CRMVoipResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Добавить оператора. + /// + public static string AddOperatorBtn { + get { + return ResourceManager.GetString("AddOperatorBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Добавить операторов. + /// + public static string AddOperatorsBtn { + get { + return ResourceManager.GetString("AddOperatorsBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Добавить мелодию. + /// + public static string AddRingtoneBtn { + get { + return ResourceManager.GetString("AddRingtoneBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Псевдоним. + /// + public static string Alias { + get { + return ResourceManager.GetString("Alias", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Псевдоним{1} "дальше идет объяснительный текст". + /// + public static string AliasDscrMsg { + get { + return ResourceManager.GetString("AliasDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Введите название для номера. + /// + public static string AliasPlaceholder { + get { + return ResourceManager.GetString("AliasPlaceholder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Buy phone number. + /// + public static string BuyNumberBtn { + get { + return ResourceManager.GetString("BuyNumberBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Покупка номера. + /// + public static string BuyNumberHeader { + get { + return ResourceManager.GetString("BuyNumberHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Call. + /// + public static string Call { + get { + return ResourceManager.GetString("Call", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Agent. + /// + public static string CallAgent { + get { + return ResourceManager.GetString("CallAgent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Client. + /// + public static string CallClient { + get { + return ResourceManager.GetString("CallClient", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cost. + /// + public static string CallCost { + get { + return ResourceManager.GetString("CallCost", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Date/Time. + /// + public static string CallDatetime { + get { + return ResourceManager.GetString("CallDatetime", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Duration. + /// + public static string CallDuration { + get { + return ResourceManager.GetString("CallDuration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type. + /// + public static string CallType { + get { + return ResourceManager.GetString("CallType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Waiting Time. + /// + public static string CallWaitingTime { + get { + return ResourceManager.GetString("CallWaitingTime", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Отмена. + /// + public static string CancelBtn { + get { + return ResourceManager.GetString("CancelBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Удалить. + /// + public static string DeleteBtn { + get { + return ResourceManager.GetString("DeleteBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Номер сохранится в twilio, но будет недоступен в рамках текущего портала. + /// + public static string DeleteNumberBody { + get { + return ResourceManager.GetString("DeleteNumberBody", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Удалить номер. + /// + public static string DeleteNumberBtn { + get { + return ResourceManager.GetString("DeleteNumberBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Удалить номер. + /// + public static string DeleteNumberHeader { + get { + return ResourceManager.GetString("DeleteNumberHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Удалить мелодию. + /// + public static string DeleteRingtoneBtn { + get { + return ResourceManager.GetString("DeleteRingtoneBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Редактировать. + /// + public static string EditBtn { + get { + return ResourceManager.GetString("EditBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter Credentials. + /// + public static string EmptyScreenEnter { + get { + return ResourceManager.GetString("EmptyScreenEnter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to IP Telephony Setup. + /// + public static string EmptyScreenHeader { + get { + return ResourceManager.GetString("EmptyScreenHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Buy a new IP phone number to add it to the ONLYOFFICE portal. Once added you can use this phone number with portal CRM. + ///. + /// + public static string EmptyScreenNumberDescription1 { + get { + return ResourceManager.GetString("EmptyScreenNumberDescription1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Note: the phone numbers you already have at Twilio website cannot be transferred to the portal.. + /// + public static string EmptyScreenNumberDescription2 { + get { + return ResourceManager.GetString("EmptyScreenNumberDescription2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No IP telephony numbers have been added yet. + /// + public static string EmptyScreenNumberHeader { + get { + return ResourceManager.GetString("EmptyScreenNumberHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Register Account. + /// + public static string EmptyScreenRegister { + get { + return ResourceManager.GetString("EmptyScreenRegister", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Click the 'Register Account' button to go to Twilio website for registration to be able to use the IP telephony feature.. + /// + public static string EmptyScreenText1 { + get { + return ResourceManager.GetString("EmptyScreenText1", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If you already have a Twilio account, enter the API credentials: Account SID and Auth token, which can be found at the {0}settings{1} page.. + /// + public static string EmptyScreenText2 { + get { + return ResourceManager.GetString("EmptyScreenText2", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enter Credentials. + /// + public static string EnterCredentialsHeader { + get { + return ResourceManager.GetString("EnterCredentialsHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Общие настройки. + /// + public static string GeneralSettings { + get { + return ResourceManager.GetString("GeneralSettings", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Мелодии приветствия. + /// + public static string GreetingRingtones { + get { + return ResourceManager.GetString("GreetingRingtones", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Incoming Call. + /// + public static string IncomingCall { + get { + return ResourceManager.GetString("IncomingCall", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Очередь входящих звонков{1} "дальше идет объяснительный текст". + /// + public static string IncomingCallsQueueDscrMsg { + get { + return ResourceManager.GetString("IncomingCallsQueueDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Размер очереди входящих звонков. + /// + public static string IncomingCallsQueueSize { + get { + return ResourceManager.GetString("IncomingCallsQueueSize", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to После привязки все вызовы будут обрабатываться текущим порталом.. + /// + public static string LinkNumberBody { + get { + return ResourceManager.GetString("LinkNumberBody", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Привязать купленный номер. + /// + public static string LinkNumberBtn { + get { + return ResourceManager.GetString("LinkNumberBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Привязка номера. + /// + public static string LinkNumberHeader { + get { + return ResourceManager.GetString("LinkNumberHeader", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Номер успешно привязан. + /// + public static string LinkNumberSuccessMsg { + get { + return ResourceManager.GetString("LinkNumberSuccessMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Идет загрузка, пожалуйста подождите. + /// + public static string LoadingMsg { + get { + return ResourceManager.GetString("LoadingMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to К сожалению доступных номеров нет, попробуйте позже.. + /// + public static string NoAvailableNumbersMsg { + get { + return ResourceManager.GetString("NoAvailableNumbersMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to У вас пока нет номеров. Срочно купите!. + /// + public static string NoExistingNumbersMsg { + get { + return ResourceManager.GetString("NoExistingNumbersMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to У вас нет номеров. Приобрести номер можно {0}здесь{1}.. + /// + public static string NoNumbersMsg { + get { + return ResourceManager.GetString("NoNumbersMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Нет номеров с такими крутыми циферками. + /// + public static string NoSearchingNumbersMsg { + get { + return ResourceManager.GetString("NoSearchingNumbersMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Операторы номера. + /// + public static string NumberOperators { + get { + return ResourceManager.GetString("NumberOperators", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Здесь{1} можно их настроить.. + /// + public static string NumbersCountDscrMsg { + get { + return ResourceManager.GetString("NumbersCountDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Количество ваших номеров. + /// + public static string NumbersCountMsg { + get { + return ResourceManager.GetString("NumbersCountMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Оператор. + /// + public static string Operator { + get { + return ResourceManager.GetString("Operator", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Пауза оператора. + /// + public static string OperatorPause { + get { + return ResourceManager.GetString("OperatorPause", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Выключена. + /// + public static string OperatorPauseDisabled { + get { + return ResourceManager.GetString("OperatorPauseDisabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Пауза оператора{1} "дальше идет объяснительный текст". + /// + public static string OperatorPauseDscrMsg { + get { + return ResourceManager.GetString("OperatorPauseDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Включена. + /// + public static string OperatorPauseEnabled { + get { + return ResourceManager.GetString("OperatorPauseEnabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Исходящие звонки. + /// + public static string OutgoingCalls { + get { + return ResourceManager.GetString("OutgoingCalls", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Мелодии очереди. + /// + public static string QueueRingtones { + get { + return ResourceManager.GetString("QueueRingtones", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Быстрая настройка. + /// + public static string QuickTuning { + get { + return ResourceManager.GetString("QuickTuning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Быстрая настройка{1} "дальше идет объяснительный текст". + /// + public static string QuickTuningDscrMsg { + get { + return ResourceManager.GetString("QuickTuningDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Запись звонков. + /// + public static string RecordingCalls { + get { + return ResourceManager.GetString("RecordingCalls", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Записи разговоров хранятся в формате WAV. Ваш браузер не поддерживает воспроизведение аудиофайлов в этом формате, поэтому Вы не сможете прослушать свои записи.. + /// + public static string RecordingsCallsPlayNotSupportedMsg { + get { + return ResourceManager.GetString("RecordingsCallsPlayNotSupportedMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Список браузеров, поддерживающих данную функцию можно найти {0}здесь{1}. + /// + public static string RecordingsCallsPlayNotSupportedTipMsg { + get { + return ResourceManager.GetString("RecordingsCallsPlayNotSupportedTipMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Список мелодий. + /// + public static string RingtonesList { + get { + return ResourceManager.GetString("RingtonesList", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Настройка мелодий. + /// + public static string RingtonesTuning { + get { + return ResourceManager.GetString("RingtonesTuning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Настройка мелодий{1} "дальше идет объяснительный текст". + /// + public static string RingtonesTuningDscrMsg { + get { + return ResourceManager.GetString("RingtonesTuningDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Рекомендации к загружаемой мелодии{1} Размер файла не должен превышать 5 Mb. Поддерживаемые форматы: mp3.. + /// + public static string RingtonesUploadingRecomendationsMsg { + get { + return ResourceManager.GetString("RingtonesUploadingRecomendationsMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Поиск. + /// + public static string SearchLabel { + get { + return ResourceManager.GetString("SearchLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Настройка номера. + /// + public static string TuningNumber { + get { + return ResourceManager.GetString("TuningNumber", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Account Sid. + /// + public static string TwilioAccountSid { + get { + return ResourceManager.GetString("TwilioAccountSid", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Auth Token. + /// + public static string TwilioAuthToken { + get { + return ResourceManager.GetString("TwilioAuthToken", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Не выбрано. + /// + public static string UnspecifiedOption { + get { + return ResourceManager.GetString("UnspecifiedOption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Обновить настройки. + /// + public static string UpdateSettingsBtn { + get { + return ResourceManager.GetString("UpdateSettingsBtn", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Виртуальные номера. + /// + public static string VirtualNumbers { + get { + return ResourceManager.GetString("VirtualNumbers", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Виртуальные номера и операторы. + /// + public static string VirtualNumbersAndOperators { + get { + return ResourceManager.GetString("VirtualNumbersAndOperators", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Виртуальные номера{1} "дальше идет объяснительный текст". + /// + public static string VirtualNumbersDscrMsg { + get { + return ResourceManager.GetString("VirtualNumbersDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Голосовая почта. + /// + public static string Voicemail { + get { + return ResourceManager.GetString("Voicemail", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Мелодии голосового письма. + /// + public static string VoicemailRingtones { + get { + return ResourceManager.GetString("VoicemailRingtones", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to VoIP. + /// + public static string VoipModuleDescription { + get { + return ResourceManager.GetString("VoipModuleDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to VoIP. + /// + public static string VoipModuleTitle { + get { + return ResourceManager.GetString("VoipModuleTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Мелодии ожидания. + /// + public static string WaitingRingtones { + get { + return ResourceManager.GetString("WaitingRingtones", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Таймаут ожидания. + /// + public static string WaitingTimeout { + get { + return ResourceManager.GetString("WaitingTimeout", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 10 минут. + /// + public static string WaitingTimeout10Minutes { + get { + return ResourceManager.GetString("WaitingTimeout10Minutes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 15 минут. + /// + public static string WaitingTimeout15Minutes { + get { + return ResourceManager.GetString("WaitingTimeout15Minutes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to 5 минут. + /// + public static string WaitingTimeout5Minutes { + get { + return ResourceManager.GetString("WaitingTimeout5Minutes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to {0}Таймаут ожидания{1} "дальше идет объяснительный текст". + /// + public static string WaitingTimeoutDscrMsg { + get { + return ResourceManager.GetString("WaitingTimeoutDscrMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Рабочие часы. + /// + public static string WorkingHours { + get { + return ResourceManager.GetString("WorkingHours", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Некорректный интервал. + /// + public static string WorkingHoursFormatErrorMsg { + get { + return ResourceManager.GetString("WorkingHoursFormatErrorMsg", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Введите время в формате ##:##. + /// + public static string WorkingHoursFormatTip { + get { + return ResourceManager.GetString("WorkingHoursFormatTip", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Resources/CRMVoipResource.resx b/products/ASC.CRM/Server/Resources/CRMVoipResource.resx new file mode 100644 index 00000000000..19abbf66dbc --- /dev/null +++ b/products/ASC.CRM/Server/Resources/CRMVoipResource.resx @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Добавить оператора + + + Добавить операторов + + + Добавить мелодию + + + Псевдоним + + + {0}Псевдоним{1} "дальше идет объяснительный текст" + + + Введите название для номера + + + Buy phone number + + + Покупка номера + + + Call + + + Agent + + + Client + + + Cost + + + Date/Time + + + Duration + + + Type + + + Waiting Time + + + Отмена + + + Удалить + + + Номер сохранится в twilio, но будет недоступен в рамках текущего портала + + + Удалить номер + + + Удалить номер + + + Удалить мелодию + + + Редактировать + + + Enter Credentials + + + IP Telephony Setup + + + Buy a new IP phone number to add it to the ONLYOFFICE portal. Once added you can use this phone number with portal CRM. + + + + Note: the phone numbers you already have at Twilio website cannot be transferred to the portal. + + + No IP telephony numbers have been added yet + + + Register Account + + + Click the 'Register Account' button to go to Twilio website for registration to be able to use the IP telephony feature. + + + If you already have a Twilio account, enter the API credentials: Account SID and Auth token, which can be found at the {0}settings{1} page. + + + Enter Credentials + + + Общие настройки + + + Мелодии приветствия + + + Incoming Call + + + {0}Очередь входящих звонков{1} "дальше идет объяснительный текст" + + + Размер очереди входящих звонков + + + После привязки все вызовы будут обрабатываться текущим порталом. + + + Привязать купленный номер + + + Привязка номера + + + Номер успешно привязан + + + Идет загрузка, пожалуйста подождите + + + К сожалению доступных номеров нет, попробуйте позже. + + + У вас пока нет номеров. Срочно купите! + + + У вас нет номеров. Приобрести номер можно {0}здесь{1}. + + + Нет номеров с такими крутыми циферками + + + Операторы номера + + + {0}Здесь{1} можно их настроить. + + + Количество ваших номеров + + + Оператор + + + Пауза оператора + + + Выключена + + + {0}Пауза оператора{1} "дальше идет объяснительный текст" + + + Включена + + + Исходящие звонки + + + Мелодии очереди + + + Быстрая настройка + + + {0}Быстрая настройка{1} "дальше идет объяснительный текст" + + + Запись звонков + + + Записи разговоров хранятся в формате WAV. Ваш браузер не поддерживает воспроизведение аудиофайлов в этом формате, поэтому Вы не сможете прослушать свои записи. + + + Список браузеров, поддерживающих данную функцию можно найти {0}здесь{1} + + + Список мелодий + + + Настройка мелодий + + + {0}Настройка мелодий{1} "дальше идет объяснительный текст" + + + {0}Рекомендации к загружаемой мелодии{1} Размер файла не должен превышать 5 Mb. Поддерживаемые форматы: mp3. + + + Поиск + + + Настройка номера + + + Account Sid + + + Auth Token + + + Не выбрано + + + Обновить настройки + + + Виртуальные номера + + + Виртуальные номера и операторы + + + {0}Виртуальные номера{1} "дальше идет объяснительный текст" + + + Голосовая почта + + + Мелодии голосового письма + + + VoIP + + + VoIP + + + Мелодии ожидания + + + Таймаут ожидания + + + 10 минут + + + 15 минут + + + 5 минут + + + {0}Таймаут ожидания{1} "дальше идет объяснительный текст" + + + Рабочие часы + + + Некорректный интервал + + + Введите время в формате ##:## + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs b/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs new file mode 100644 index 00000000000..d5f1a6f8626 --- /dev/null +++ b/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs @@ -0,0 +1,325 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Services.NotifyService { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMPatternResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMPatternResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Services.NotifyService.CRMPatternResource", typeof(CRMPatternResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to h1. New event added to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has added a new event to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}": + /// $AdditionalData.get_item("EventContent") + /// + /// #foreach($fileInfo in $AdditionalData.get_item("Files").Keys) + /// + /// #beforeall + /// + /// ---------------------------------------- + /// + /// #each + /// + /// " [rest of string was truncated]";. + /// + public static string pattern_AddRelationshipEvent { + get { + return ResourceManager.GetString("pattern_AddRelationshipEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. New contact created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" + /// + ///$__DateTime A new contact has been created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" + /// + ///Contact information: + /// + ///#foreach($contactInfo in $AdditionalData.Keys) + ///#each + /// + ///$contactInfo: $AdditionalData.get_item($contactInfo) + /// + ///#end. + /// + public static string pattern_CreateNewContact { + get { + return ResourceManager.GetString("pattern_CreateNewContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data export successfully completed + /// + ///Please, follow this link to download the archive: "exportdata.zip":"${EntityRelativeURL}" + /// + ///*Note*: this link is valid for 24 hours only. + /// + ///If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" + /// + ///Best regards, + ///ONLYOFFICE™ Support Team + ///"www.onlyoffice.com":"http://onlyoffice.com/". + /// + public static string pattern_ExportCompleted { + get { + return ResourceManager.GetString("pattern_ExportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data export successfully completed + /// + ///Please, follow this link to download the archive: "${EntityTitle}":"${EntityRelativeURL}" + /// + ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. + /// + public static string pattern_ExportCompletedCustomMode { + get { + return ResourceManager.GetString("pattern_ExportCompletedCustomMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data import successfully completed + /// + ///Go to the "Contacts":"$__VirtualRootPath/products/crm/" list. + /// + ///If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" + /// + ///Best regards, + ///ONLYOFFICE™ Support Team + ///"www.onlyoffice.com":"http://onlyoffice.com/". + /// + public static string pattern_ImportCompleted { + get { + return ResourceManager.GetString("pattern_ImportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data import successfully completed + /// + ///Go to the "${Tag_EntityListTitle}":"$__VirtualRootPath/${Tag_EntityListRelativeURL}" list. + /// + ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. + /// + public static string pattern_ImportCompletedCustomMode { + get { + return ResourceManager.GetString("pattern_ImportCompletedCustomMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1.You were appointed responsible for the opportunity: "$EntityTitle":"${__VirtualRootPath}/products/crm/deals.aspx?id=$EntityID" + /// + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the opportunity: $EntityTitle . + /// + ///#if($AdditionalData.get_item("OpportunityDescription")&&$AdditionalData.get_item("OpportunityDescription")!="") + /// + ///Opportunity description: + ///$AdditionalData.get_item("OpportunityDescription") + ///#end. + /// + public static string pattern_ResponsibleForOpportunity { + get { + return ResourceManager.GetString("pattern_ResponsibleForOpportunity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1.Task assigned to you: $EntityTitle + /// + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the task: $EntityTitle. + ///#if($AdditionalData.get_item("TaskCategory")) + /// + ///Task category: $AdditionalData.get_item("TaskCategory") + ///#end + ///#if($AdditionalData.get_item("ContactRelativeUrl")) + /// + ///Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" + ///#end + ///#if($AdditionalData.get_item("CaseRelativeUrl")) + /// + ///Link with case: "$Addit [rest of string was truncated]";. + /// + public static string pattern_ResponsibleForTask { + get { + return ResourceManager.GetString("pattern_ResponsibleForTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1.Access granted to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" + /// + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has granted you the access to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}".. + /// + public static string pattern_SetAccess { + get { + return ResourceManager.GetString("pattern_SetAccess", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. Reminder about the task: $EntityTitle + ///#if($AdditionalData.get_item("TaskCategory")) + /// + ///Task category: $AdditionalData.get_item("TaskCategory") + ///#end + ///#if($AdditionalData.get_item("ContactRelativeUrl")) + /// + ///Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" + ///#end + ///#if($AdditionalData.get_item("CaseRelativeUrl")) + /// + ///Link with case: "$AdditionalData.get_item("CaseTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("CaseRelativeUrl") [rest of string was truncated]";. + /// + public static string pattern_TaskReminder { + get { + return ResourceManager.GetString("pattern_TaskReminder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <patterns> + /// <formatter type="ASC.Notify.Patterns.NVelocityPatternFormatter, ASC.Common" /> + /// + /// <!--Export is completed--> + /// <pattern id="ExportCompleted" sender="email.sender"> + /// <subject resource="|subject_ExportCompleted|ASC.Web.CRM.Services.NotifyService.CRMPatternResource,ASC.Web.CRM" /> + /// <body styler="ASC.Notify.Textile.TextileStyler,ASC.Notify.Textile" resource="|pattern_ExportCompleted|ASC.Web.CRM.Services.NotifyService.CRMPatternResource,ASC.Web.CRM" /> + /// </pattern> + /// <pattern id="Expor [rest of string was truncated]";. + /// + public static string patterns { + get { + return ResourceManager.GetString("patterns", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. New event added to $EntityTitle. + /// + public static string subject_AddRelationshipEvent { + get { + return ResourceManager.GetString("subject_AddRelationshipEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. New contact created using 'Website Contact Form'. + /// + public static string subject_CreateNewContact { + get { + return ResourceManager.GetString("subject_CreateNewContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Data export successfully completed. + /// + public static string subject_ExportCompleted { + get { + return ResourceManager.GetString("subject_ExportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Data import successfully completed. + /// + public static string subject_ImportCompleted { + get { + return ResourceManager.GetString("subject_ImportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. You were appointed as a responsible person for the opportunity: $EntityTitle. + /// + public static string subject_ResponsibleForOpportunity { + get { + return ResourceManager.GetString("subject_ResponsibleForOpportunity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Task assigned to you: $EntityTitle. + /// + public static string subject_ResponsibleForTask { + get { + return ResourceManager.GetString("subject_ResponsibleForTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Access granted to $EntityTitle. + /// + public static string subject_SetAccess { + get { + return ResourceManager.GetString("subject_SetAccess", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Reminder about the task: $EntityTitle. + /// + public static string subject_TaskReminder { + get { + return ResourceManager.GetString("subject_TaskReminder", resourceCulture); + } + } + } +} diff --git a/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.resx b/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.resx new file mode 100644 index 00000000000..a2fc39aa22d --- /dev/null +++ b/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.resx @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + h1. New event added to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" +$__DateTime "$__AuthorName":"$__AuthorUrl" has added a new event to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}": + $AdditionalData.get_item("EventContent") + + #foreach($fileInfo in $AdditionalData.get_item("Files").Keys) + + #beforeall + + ---------------------------------------- + + #each + + "$fileInfo":"$AdditionalData.get_item("Files").get_item($fileInfo)" + + #end + + + h1. CRM. New contact created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" + +$__DateTime A new contact has been created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" + +Contact information: + +#foreach($contactInfo in $AdditionalData.Keys) +#each + +$contactInfo: $AdditionalData.get_item($contactInfo) + +#end + + + h1. CRM. Data export successfully completed + +Please, follow this link to download the archive: "exportdata.zip":"${EntityRelativeURL}" + +*Note*: this link is valid for 24 hours only. + +If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" + +Best regards, +ONLYOFFICE™ Support Team +"www.onlyoffice.com":"http://onlyoffice.com/" + + + h1. CRM. Data import successfully completed + +Go to the "Contacts":"$__VirtualRootPath/products/crm/" list. + +If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" + +Best regards, +ONLYOFFICE™ Support Team +"www.onlyoffice.com":"http://onlyoffice.com/" + + + h1.You were appointed responsible for the opportunity: "$EntityTitle":"${__VirtualRootPath}/products/crm/deals.aspx?id=$EntityID" + +$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the opportunity: $EntityTitle . + +#if($AdditionalData.get_item("OpportunityDescription")&&$AdditionalData.get_item("OpportunityDescription")!="") + +Opportunity description: +$AdditionalData.get_item("OpportunityDescription") +#end + + + h1.Task assigned to you: $EntityTitle + +$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the task: $EntityTitle. +#if($AdditionalData.get_item("TaskCategory")) + +Task category: $AdditionalData.get_item("TaskCategory") +#end +#if($AdditionalData.get_item("ContactRelativeUrl")) + +Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" +#end +#if($AdditionalData.get_item("CaseRelativeUrl")) + +Link with case: "$AdditionalData.get_item("CaseTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("CaseRelativeUrl")" +#end +#if($AdditionalData.get_item("DealRelativeUrl")) + +Link with opportunity: "$AdditionalData.get_item("DealTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("DealRelativeUrl")" +#end +#if($AdditionalData.get_item("TaskDescription")&&$AdditionalData.get_item("TaskDescription")!="") + +Task description: +$AdditionalData.get_item("TaskDescription") +#end + +Due date: $AdditionalData.get_item("DueDate") + + +#foreach($fileInfo in $AdditionalData.get_item("Files").Keys) + +#beforeall + +---------------------------------------- + +#each + +"$fileInfo":"$AdditionalData.get_item("Files").get_item($fileInfo)" + +#end + +Go to the "Tasks":"${__VirtualRootPath}/products/crm/tasks.aspx" list. + + + h1.Access granted to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" + +$__DateTime "$__AuthorName":"$__AuthorUrl" has granted you the access to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}". + + + + patterns.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + + h1. Reminder about the task: $EntityTitle +#if($AdditionalData.get_item("TaskCategory")) + +Task category: $AdditionalData.get_item("TaskCategory") +#end +#if($AdditionalData.get_item("ContactRelativeUrl")) + +Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" +#end +#if($AdditionalData.get_item("CaseRelativeUrl")) + +Link with case: "$AdditionalData.get_item("CaseTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("CaseRelativeUrl")" +#end +#if($AdditionalData.get_item("DealRelativeUrl")) + +Link with opportunity: "$AdditionalData.get_item("DealTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("DealRelativeUrl")" +#end +#if($AdditionalData.get_item("TaskDescription")&&$AdditionalData.get_item("TaskDescription")!="") + +Task description: +$AdditionalData.get_item("TaskDescription") +#end + +Due date: $AdditionalData.get_item("DueDate") + +Go to the "Tasks":"${__VirtualRootPath}/products/crm/tasks.aspx" list. + +^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal.^ + + + CRM. New event added to $EntityTitle + + + CRM. New contact created using 'Website Contact Form' + + + CRM. Data export successfully completed + + + CRM. Data import successfully completed + + + CRM. You were appointed as a responsible person for the opportunity: $EntityTitle + + + CRM. Task assigned to you: $EntityTitle + + + CRM. Access granted to $EntityTitle + + + CRM. Reminder about the task: $EntityTitle + + + h1. CRM. Data export successfully completed + +Please, follow this link to download the archive: "${EntityTitle}":"${EntityRelativeURL}" + +^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^ + + + h1. CRM. Data import successfully completed + +Go to the "${Tag_EntityListTitle}":"$__VirtualRootPath/${Tag_EntityListRelativeURL}" list. + +^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^ + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs new file mode 100644 index 00000000000..3ac9418312b --- /dev/null +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -0,0 +1,553 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Billing; +using ASC.Core.Tenants; +using ASC.Core.Users; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Notify; +using ASC.Notify.Model; +using ASC.Notify.Patterns; +using ASC.Notify.Recipients; +using ASC.Web.CRM.Core; +using Autofac; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Web; + +#endregion + +namespace ASC.Web.CRM.Services.NotifyService +{ + public class NotifyClient + { + public NotifyClient(PathProvider pathProvider, + SecurityContext securityContext, + PaymentManager paymentManager, + TenantManager tenantManager, + TenantUtil tenantUtil, + UserManager userManager, + DaoFactory daoFactory) + { + PathProvider = pathProvider; + SecurityContext = securityContext; + PaymentManager = paymentManager; + TenantManager = tenantManager; + TenantUtil = tenantUtil; + UserManager = userManager; + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public UserManager UserManager { get; } + public TenantUtil TenantUtil { get; } + public TenantManager TenantManager { get;} + public PaymentManager PaymentManager { get; } + public SecurityContext SecurityContext { get; } + public PathProvider PathProvider { get; } + + private static NotifyClient instance; + private readonly INotifyClient client; + private readonly INotifySource source; + + public static NotifyClient Instance + { + get + { + if (instance == null) + { + lock (typeof(NotifyClient)) + { + if (instance == null) instance = new NotifyClient(WorkContext.NotifyContext.NotifyService.RegisterClient(NotifySource.Instance), NotifySource.Instance); + } + } + return instance; + } + } + + public void SendAboutCreateNewContact(List recipientID, int contactID, String contactTitle, NameValueCollection fields) + { + if ((recipientID.Count == 0) || String.IsNullOrEmpty(contactTitle)) return; + + client.SendNoticeToAsync( + NotifyConstants.Event_CreateNewContact, + null, + recipientID.ConvertAll(item => ToRecipient(item)).ToArray(), + true, + new TagValue(NotifyConstants.Tag_AdditionalData, fields), + new TagValue(NotifyConstants.Tag_EntityTitle, contactTitle), + new TagValue(NotifyConstants.Tag_EntityID, contactID) + ); + + } + + public void SendAboutSetAccess(EntityType entityType, int entityID, DaoFactory daoFactory, params Guid[] userID) + { + if (userID.Length == 0) return; + + var baseData = ExtractBaseDataFrom(entityType, entityID, daoFactory); + + client.SendNoticeToAsync( + NotifyConstants.Event_SetAccess, + null, + userID.Select(item => ToRecipient(item)).ToArray(), + true, + new TagValue(NotifyConstants.Tag_EntityID, baseData["id"]), + new TagValue(NotifyConstants.Tag_EntityTitle, baseData["title"]), + new TagValue(NotifyConstants.Tag_EntityRelativeURL, baseData["entityRelativeURL"]) + ); + } + + private NameValueCollection ExtractBaseDataFrom(EntityType entityType, int entityID, DaoFactory daoFactory) + { + var result = new NameValueCollection(); + + String title; + String relativeURL; + + switch (entityType) + { + case EntityType.Person: + case EntityType.Company: + case EntityType.Contact: + { + var contact = daoFactory.ContactDao.GetByID(entityID); + title = contact != null ? contact.GetTitle() : string.Empty; + relativeURL = "default.aspx?id=" + entityID; + break; + } + case EntityType.Opportunity: + { + var deal = daoFactory.DealDao.GetByID(entityID); + title = deal != null ? deal.Title : string.Empty; + relativeURL = "deals.aspx?id=" + entityID; + break; + } + case EntityType.Case: + { + var cases = daoFactory.CasesDao.GetByID(entityID); + title = cases != null ? cases.Title : string.Empty; + relativeURL = "cases.aspx?id=" + entityID; + break; + } + + default: + throw new ArgumentException(); + } + + result.Add("title", title); + result.Add("id", entityID.ToString()); + result.Add("entityRelativeURL", String.Concat(PathProvider.BaseAbsolutePath, relativeURL)); + + return result; + } + + public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable fileListInfoHashtable, DaoFactory daoFactory, params Guid[] userID) + { + if (userID.Length == 0) return; + + NameValueCollection baseEntityData; + + if (entity.EntityID != 0) + { + baseEntityData = ExtractBaseDataFrom(entity.EntityType, entity.EntityID, daoFactory); + } + else + { + var contact = daoFactory.ContactDao.GetByID(entity.ContactID); + + baseEntityData = new NameValueCollection(); + baseEntityData["title"] = contact.GetTitle(); + baseEntityData["id"] = contact.ID.ToString(); + baseEntityData["entityRelativeURL"] = "default.aspx?id=" + contact.ID; + + if (contact is Person) + baseEntityData["entityRelativeURL"] += "&type=people"; + + baseEntityData["entityRelativeURL"] = String.Concat(PathProvider.BaseAbsolutePath, + baseEntityData["entityRelativeURL"]); + } + + client.BeginSingleRecipientEvent("send about add relationship event add"); + + var interceptor = new InitiatorInterceptor(new DirectRecipient(SecurityContext.CurrentAccount.ID.ToString(), "")); + + client.AddInterceptor(interceptor); + + try + { + + client.SendNoticeToAsync( + NotifyConstants.Event_AddRelationshipEvent, + null, + userID.Select(item => ToRecipient(item)).ToArray(), + true, + new TagValue(NotifyConstants.Tag_EntityTitle, baseEntityData["title"]), + new TagValue(NotifyConstants.Tag_EntityID, baseEntityData["id"]), + new TagValue(NotifyConstants.Tag_EntityRelativeURL, baseEntityData["entityRelativeURL"]), + new TagValue(NotifyConstants.Tag_AdditionalData, + new Hashtable { + { "Files", fileListInfoHashtable }, + {"EventContent", entity.Content}})); + + } + finally + { + client.RemoveInterceptor(interceptor.Name); + client.EndSingleRecipientEvent("send about add relationship event add"); + } + + + } + + public void SendAboutExportCompleted(Guid recipientID, String fileName, String filePath) + { + if (recipientID == Guid.Empty) return; + + var recipient = ToRecipient(recipientID); + + client.SendNoticeToAsync(CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, + null, + new[] { recipient }, + true, + new TagValue(NotifyConstants.Tag_EntityTitle, fileName), + new TagValue(NotifyConstants.Tag_EntityRelativeURL, filePath)); + + } + + public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) + { + if (recipientID == Guid.Empty) return; + + var recipient = ToRecipient(recipientID); + + var entitiyListTitle = ""; + var entitiyListRelativeURL = ""; + switch (entityType) + { + case EntityType.Contact: + entitiyListTitle = CRMContactResource.Contacts; + entitiyListRelativeURL = "products/crm/"; + break; + case EntityType.Opportunity: + entitiyListTitle = CRMCommonResource.DealModuleName; + entitiyListRelativeURL = "products/crm/deals.aspx"; + break; + case EntityType.Case: + entitiyListTitle = CRMCommonResource.CasesModuleName; + entitiyListRelativeURL = "products/crm/cases.aspx"; + break; + case EntityType.Task: + entitiyListTitle = CRMCommonResource.TaskModuleName; + entitiyListRelativeURL = "products/crm/tasks.aspx"; + break; + default: + throw new ArgumentException(CRMErrorsResource.EntityTypeUnknown); + } + + client.SendNoticeToAsync( + CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, + null, + new[] { recipient }, + true, + new TagValue(NotifyConstants.Tag_EntityListRelativeURL, entitiyListRelativeURL), + new TagValue(NotifyConstants.Tag_EntityListTitle, entitiyListTitle)); + } + + public void SendAutoReminderAboutTask(DateTime scheduleDate) + { + using (var scope = DIHelper.Resolve(-1)) + { + var defaultDao = scope.Resolve(); + + var execAlert = new List(); + + foreach (var row in defaultDao.TaskDao + .GetInfoForReminder(scheduleDate)) + { + + var tenantId = Convert.ToInt32(row[0]); + var taskId = Convert.ToInt32(row[1]); + var deadline = Convert.ToDateTime(row[2]); + var alertValue = Convert.ToInt32(row[3]); + var responsibleID = !string.IsNullOrEmpty(Convert.ToString(row[4])) + ? new Guid(Convert.ToString(row[4])) + : Guid.Empty; + + var deadlineReminderDate = deadline.AddMinutes(-alertValue); + + if (deadlineReminderDate.Subtract(scheduleDate).Minutes > 1) continue; + + execAlert.Add(taskId); + + var tenant = TenantManager.GetTenant(tenantId); + if (tenant == null || + tenant.Status != TenantStatus.Active || + TariffState.NotPaid <= PaymentManager.GetTariff(tenant.TenantId).State) + { + continue; + } + + try + { + TenantManager.SetCurrentTenant(tenant); + SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); + + var user = UserManager.GetUsers(responsibleID); + + if (!(!Constants.LostUser.Equals(user) && user.Status == EmployeeStatus.Active)) continue; + + SecurityContext.AuthenticateMe(user.ID); + + Thread.CurrentThread.CurrentCulture = user.GetCulture(); + Thread.CurrentThread.CurrentUICulture = user.GetCulture(); + + using (var innerScope = DIHelper.Resolve(tenantId)) + { + var dao = innerScope.Resolve(); + var task = dao.TaskDao.GetByID(taskId); + + if (task == null) continue; + + ASC.CRM.Core.Entities.Contact taskContact = null; + ASC.CRM.Core.Entities.Cases taskCase = null; + ASC.CRM.Core.Entities.Deal taskDeal = null; + + if (task.ContactID > 0) + { + taskContact = dao.ContactDao.GetByID(task.ContactID); + } + + if (task.EntityID > 0) + { + switch (task.EntityType) + { + case EntityType.Case: + taskCase = dao.CasesDao.GetByID(task.EntityID); + break; + case EntityType.Opportunity: + taskDeal = dao.DealDao.GetByID(task.EntityID); + break; + } + } + + var listItem = dao.ListItemDao.GetByID(task.CategoryID); + + NotifyClient.Instance.SendTaskReminder(task, + listItem != null ? listItem.Title : string.Empty, + taskContact, taskCase, taskDeal); + } + } + catch (Exception ex) + { + LogManager.GetLogger("ASC.CRM.Tasks") + .Error("SendAutoReminderAboutTask, tenant: " + tenant.TenantDomain, ex); + } + } + + defaultDao.TaskDao.ExecAlert(execAlert); + } + } + + public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal) + { + var recipient = ToRecipient(task.ResponsibleID); + + if (recipient == null) return; + + var deadLineString = task.DeadLine.Hour == 0 && task.DeadLine.Minute == 0 + ? task.DeadLine.ToShortDateString() + : task.DeadLine.ToString(CultureInfo.InvariantCulture); + + string taskContactRelativeUrl = null; + string taskContactTitle = null; + + string taskCaseRelativeUrl = null; + string taskCaseTitle = null; + + string taskDealRelativeUrl = null; + string taskDealTitle = null; + + if (taskContact != null) + { + taskContactRelativeUrl = String.Format("products/crm/default.aspx?id={0}{1}", taskContact.ID, taskContact is Person ? "&type=people" : ""); + taskContactTitle = taskContact.GetTitle(); + } + + if (taskCase != null) + { + taskCaseRelativeUrl = String.Format("products/crm/cases.aspx?id={0}", taskCase.ID); + taskCaseTitle = taskCase.Title.HtmlEncode(); + } + + if (taskDeal != null) + { + taskDealRelativeUrl = String.Format("products/crm/deals.aspx?id={0}", taskDeal.ID); + taskDealTitle = taskDeal.Title.HtmlEncode(); + } + + + client.SendNoticeToAsync( + NotifyConstants.Event_TaskReminder, + null, + new[] { recipient }, + true, + new TagValue(NotifyConstants.Tag_EntityTitle, task.Title), + new TagValue(NotifyConstants.Tag_AdditionalData, + new Hashtable { + { "TaskDescription", HttpUtility.HtmlEncode(task.Description) }, + { "TaskCategory", taskCategoryTitle }, + + { "ContactRelativeUrl", taskContactRelativeUrl }, + { "ContactTitle", taskContactTitle }, + + { "CaseRelativeUrl", taskCaseRelativeUrl }, + { "CaseTitle", taskCaseTitle }, + + { "DealRelativeUrl", taskDealRelativeUrl }, + { "DealTitle", taskDealTitle }, + + { "DueDate", deadLineString } + }) + ); + } + + public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal, Hashtable fileListInfoHashtable) + { + var recipient = ToRecipient(task.ResponsibleID); + + if (recipient == null) return; + + task.DeadLine = TenantUtil.DateTimeFromUtc(task.DeadLine); + var deadLineString = task.DeadLine.Hour == 0 && task.DeadLine.Minute == 0 + ? task.DeadLine.ToShortDateString() + : task.DeadLine.ToString(); + + + string taskContactRelativeUrl = null; + string taskContactTitle = null; + + string taskCaseRelativeUrl = null; + string taskCaseTitle = null; + + string taskDealRelativeUrl = null; + string taskDealTitle = null; + + if (taskContact != null) + { + taskContactRelativeUrl = String.Format("products/crm/default.aspx?id={0}{1}", taskContact.ID, taskContact is Person ? "&type=people" : ""); + taskContactTitle = taskContact.GetTitle(); + } + + if (taskCase != null) + { + taskCaseRelativeUrl = String.Format("products/crm/cases.aspx?id={0}", taskCase.ID); + taskCaseTitle = taskCase.Title.HtmlEncode(); + } + + if (taskDeal != null) + { + taskDealRelativeUrl = String.Format("products/crm/deals.aspx?id={0}", taskDeal.ID); + taskDealTitle = taskDeal.Title.HtmlEncode(); + } + + client.SendNoticeToAsync( + NotifyConstants.Event_ResponsibleForTask, + null, + new[] { recipient }, + true, + new TagValue(NotifyConstants.Tag_EntityTitle, task.Title), + new TagValue(NotifyConstants.Tag_AdditionalData, + new Hashtable { + { "TaskDescription", HttpUtility.HtmlEncode(task.Description) }, + { "Files", fileListInfoHashtable }, + { "TaskCategory", taskCategoryTitle }, + + { "ContactRelativeUrl", taskContactRelativeUrl }, + { "ContactTitle", taskContactTitle }, + + { "CaseRelativeUrl", taskCaseRelativeUrl }, + { "CaseTitle", taskCaseTitle }, + + { "DealRelativeUrl", taskDealRelativeUrl }, + { "DealTitle", taskDealTitle }, + + { "DueDate", deadLineString } + }) + ); + } + + public void SendAboutResponsibleForOpportunity(Deal deal) + { + var recipient = ToRecipient(deal.ResponsibleID); + + if (recipient == null) return; + + client.SendNoticeToAsync( + NotifyConstants.Event_ResponsibleForOpportunity, + null, + new[] { recipient }, + true, + new TagValue(NotifyConstants.Tag_EntityTitle, deal.Title), + new TagValue(NotifyConstants.Tag_EntityID, deal.ID), + new TagValue(NotifyConstants.Tag_AdditionalData, + new Hashtable { + { "OpportunityDescription", HttpUtility.HtmlEncode(deal.Description) } + }) + ); + } + + private IRecipient ToRecipient(Guid userID) + { + return source.GetRecipientsProvider().GetRecipient(userID.ToString()); + } + + public INotifyClient Client + { + get { return client; } + } + + private NotifyClient(INotifyClient client, INotifySource source) + { + this.client = client; + this.source = source; + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs new file mode 100644 index 00000000000..a9243cc7208 --- /dev/null +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs @@ -0,0 +1,71 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.Notify.Model; + +#endregion + +namespace ASC.Web.CRM.Services.NotifyService +{ + public static class NotifyConstants + { + + public static readonly INotifyAction Event_SetAccess = new NotifyAction("SetAccess", "set access for users"); + + public static readonly INotifyAction Event_ResponsibleForTask = new NotifyAction("ResponsibleForTask", "responsible for task"); + + public static readonly INotifyAction Event_TaskReminder = new NotifyAction("TaskReminder", "auto reminder about task"); + + public static readonly INotifyAction Event_ResponsibleForOpportunity = new NotifyAction("ResponsibleForOpportunity", "responsible for opportunity"); + + public static readonly INotifyAction Event_AddRelationshipEvent = new NotifyAction("AddRelationshipEvent", "add relationship event"); + + public static readonly INotifyAction Event_ExportCompleted = new NotifyAction("ExportCompleted", "export is completed"); + + public static readonly INotifyAction Event_ExportCompletedCustomMode = new NotifyAction("ExportCompletedCustomMode", "export is completed"); + + public static readonly INotifyAction Event_ImportCompleted = new NotifyAction("ImportCompleted", "import is completed"); + + public static readonly INotifyAction Event_ImportCompletedCustomMode = new NotifyAction("ImportCompletedCustomMode", "import is completed"); + + public static readonly INotifyAction Event_CreateNewContact = new NotifyAction("CreateNewContact", "create new contact"); + + public static readonly string Tag_AdditionalData = "AdditionalData"; + + public static readonly string Tag_EntityID = "EntityID"; + + public static readonly string Tag_EntityTitle = "EntityTitle"; + + public static readonly string Tag_EntityRelativeURL = "EntityRelativeURL"; + + public static readonly string Tag_EntityListRelativeURL = "EntityListRelativeURL"; + + public static readonly string Tag_EntityListTitle = "EntityListTitle"; + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs new file mode 100644 index 00000000000..1db7761ccda --- /dev/null +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs @@ -0,0 +1,79 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.CRM.Services.NotifyService; +using ASC.Notify.Model; +using ASC.Notify.Patterns; +using System; +using NotifySourceBase = ASC.Core.Notify.NotifySource; + +#endregion + +namespace ASC.Web.CRM.Services.NotifyService +{ + + public class NotifySource : NotifySourceBase + { + public static NotifySource Instance + { + get; + private set; + } + + static NotifySource() + { + Instance = new NotifySource(); + } + + public NotifySource() + : base(new Guid("{13FF36FB-0272-4887-B416-74F52B0D0B02}")) + { + + } + + protected override IActionProvider CreateActionProvider() + { + return new ConstActionProvider( + NotifyConstants.Event_ResponsibleForTask, + NotifyConstants.Event_ResponsibleForOpportunity, + NotifyConstants.Event_AddRelationshipEvent, + NotifyConstants.Event_TaskReminder, + NotifyConstants.Event_SetAccess, + NotifyConstants.Event_ExportCompleted, + NotifyConstants.Event_ExportCompletedCustomMode, + NotifyConstants.Event_ImportCompleted, + NotifyConstants.Event_ImportCompletedCustomMode, + NotifyConstants.Event_CreateNewContact); + } + + protected override IPatternProvider CreatePatternsProvider() + { + return new XmlPatternProvider2(CRMPatternResource.patterns); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/patterns.xml b/products/ASC.CRM/Server/Services/NotifyService/patterns.xml new file mode 100644 index 00000000000..7b1bc1025c9 --- /dev/null +++ b/products/ASC.CRM/Server/Services/NotifyService/patterns.xml @@ -0,0 +1,148 @@ + + + + + + + + + + + + ${EntityRelativeURL} + + + + + + + + + + ${EntityRelativeURL} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #if($AdditionalData.get_item("TaskDescription")&&$AdditionalData.get_item("TaskDescription")!="") + + $AdditionalData.get_item("TaskDescription") + #end + + ${__VirtualRootPath}/products/crm/tasks.aspx + + + + + + + + + + + + #if($AdditionalData.get_item("TaskDescription")&&$AdditionalData.get_item("TaskDescription")!="") + + $AdditionalData.get_item("TaskDescription") + #end + + ${__VirtualRootPath}/products/crm/tasks.aspx + + + + + + + + + + + + + #if($AdditionalData.get_item("OpportunityDescription")&&$AdditionalData.get_item("OpportunityDescription")!="") + + $AdditionalData.get_item("OpportunityDescription") + #end + + ${__VirtualRootPath}/products/crm/deals.aspx?id=$EntityID + + + + + + + + + + + + + $AdditionalData.get_item("EventContent") + + #foreach($fileInfo in $AdditionalData.get_item("Files").Keys) + + #beforeall + + ---------------------------------------- + + #each + + "$fileInfo":"$AdditionalData.get_item("Files").get_item($fileInfo)" + + #end + + ${__VirtualRootPath}/${EntityRelativeURL} + + + + + + + + + + + + ${__VirtualRootPath}/${EntityRelativeURL} + + + + + + + + + + + + ${__VirtualRootPath}/products/crm/default.aspx?id=$EntityID + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs new file mode 100644 index 00000000000..8841e44c060 --- /dev/null +++ b/products/ASC.CRM/Server/Startup.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace ASC.CRM +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddHttpContextAccessor(); + services.AddControllers(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + }); + } + } +} diff --git a/products/ASC.CRM/Server/Templates/CasesTemplates.html b/products/ASC.CRM/Server/Templates/CasesTemplates.html new file mode 100644 index 00000000000..7cb8e4efb41 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/CasesTemplates.html @@ -0,0 +1,129 @@ + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/CommonCustomFieldsTemplates.html b/products/ASC.CRM/Server/Templates/CommonCustomFieldsTemplates.html new file mode 100644 index 00000000000..288d8d7b7aa --- /dev/null +++ b/products/ASC.CRM/Server/Templates/CommonCustomFieldsTemplates.html @@ -0,0 +1,144 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/CommonTemplates.html b/products/ASC.CRM/Server/Templates/CommonTemplates.html new file mode 100644 index 00000000000..a1c94124bc4 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/CommonTemplates.html @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/ContactInfoCardTemplate.html b/products/ASC.CRM/Server/Templates/ContactInfoCardTemplate.html new file mode 100644 index 00000000000..94f44f28064 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/ContactInfoCardTemplate.html @@ -0,0 +1,87 @@ + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/ContactSelectorTemplates.html b/products/ASC.CRM/Server/Templates/ContactSelectorTemplates.html new file mode 100644 index 00000000000..0608eea6e22 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/ContactSelectorTemplates.html @@ -0,0 +1,161 @@ + + + + + + + + + + + diff --git a/products/ASC.CRM/Server/Templates/ContactsTemplates.html b/products/ASC.CRM/Server/Templates/ContactsTemplates.html new file mode 100644 index 00000000000..89f979a995a --- /dev/null +++ b/products/ASC.CRM/Server/Templates/ContactsTemplates.html @@ -0,0 +1,366 @@ + + + + + + + + + + +F + + + + + + + + + + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/DealsSelectorTemplates.html b/products/ASC.CRM/Server/Templates/DealsSelectorTemplates.html new file mode 100644 index 00000000000..63964f8ba46 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/DealsSelectorTemplates.html @@ -0,0 +1,26 @@ + diff --git a/products/ASC.CRM/Server/Templates/DealsTemplates.html b/products/ASC.CRM/Server/Templates/DealsTemplates.html new file mode 100644 index 00000000000..67f44948975 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/DealsTemplates.html @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/InvoicesTemplates.html b/products/ASC.CRM/Server/Templates/InvoicesTemplates.html new file mode 100644 index 00000000000..61d942f169f --- /dev/null +++ b/products/ASC.CRM/Server/Templates/InvoicesTemplates.html @@ -0,0 +1,624 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/SettingsTemplates.html b/products/ASC.CRM/Server/Templates/SettingsTemplates.html new file mode 100644 index 00000000000..835e01fe11f --- /dev/null +++ b/products/ASC.CRM/Server/Templates/SettingsTemplates.html @@ -0,0 +1,806 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/SimpleContactListTemplate.html b/products/ASC.CRM/Server/Templates/SimpleContactListTemplate.html new file mode 100644 index 00000000000..08ef3719a42 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/SimpleContactListTemplate.html @@ -0,0 +1,73 @@ + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/TasksTemplates.html b/products/ASC.CRM/Server/Templates/TasksTemplates.html new file mode 100644 index 00000000000..e9020fdc503 --- /dev/null +++ b/products/ASC.CRM/Server/Templates/TasksTemplates.html @@ -0,0 +1,283 @@ + + + + + + + + + \ No newline at end of file diff --git a/products/ASC.CRM/Server/Templates/VoipTemplates.html b/products/ASC.CRM/Server/Templates/VoipTemplates.html new file mode 100644 index 00000000000..b54ec35b53f --- /dev/null +++ b/products/ASC.CRM/Server/Templates/VoipTemplates.html @@ -0,0 +1,364 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs new file mode 100644 index 00000000000..a690c3e11c3 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -0,0 +1,356 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Text.RegularExpressions; +using System.Web.Configuration; +using ASC.CRM.Core; +using ASC.Common.Logging; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Core; +using Autofac; + +namespace ASC.Web.CRM.Classes +{ + + public static class CurrencyProvider + { + + #region Members + + private static readonly ILog _log = LogManager.GetLogger("ASC"); + private static readonly object _syncRoot = new object(); + private static readonly Dictionary _currencies; + private static Dictionary _exchangeRates; + private static DateTime _publisherDate; + private const String _formatDate = "yyyy-MM-ddTHH:mm:ss.fffffffK"; + + #endregion + + #region Constructor + + static CurrencyProvider() + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var currencies = daoFactory.CurrencyInfoDao.GetAll(); + + if (currencies == null || currencies.Count == 0) + { + currencies = new List + { + new CurrencyInfo("Currency_UnitedStatesDollar", "USD", "$", "US", true, true) + }; + } + + _currencies = currencies.ToDictionary(c => c.Abbreviation); + } + } + + #endregion + + #region Property + + public static DateTime GetPublisherDate + { + get { + TryToReadPublisherDate(GetExchangesTempPath()); + return _publisherDate; } + } + + #endregion + + #region Public Methods + + public static CurrencyInfo Get(string currencyAbbreviation) + { + if (!_currencies.ContainsKey(currencyAbbreviation)) + return null; + + return _currencies[currencyAbbreviation]; + } + + public static List GetAll() + { + return _currencies.Values.OrderBy(v => v.Abbreviation).ToList(); + } + + public static List GetBasic() + { + return _currencies.Values.Where(c => c.IsBasic).OrderBy(v => v.Abbreviation).ToList(); + } + + public static List GetOther() + { + return _currencies.Values.Where(c => !c.IsBasic).OrderBy(v => v.Abbreviation).ToList(); + } + + public static Dictionary MoneyConvert(CurrencyInfo baseCurrency) + { + if (baseCurrency == null) throw new ArgumentNullException("baseCurrency"); + if (!_currencies.ContainsKey(baseCurrency.Abbreviation)) throw new ArgumentOutOfRangeException("baseCurrency", "Not found."); + + var result = new Dictionary(); + var rates = GetExchangeRates(); + foreach (var ci in GetAll()) + { + + if (baseCurrency.Title == ci.Title) + { + result.Add(ci, 1); + + continue; + } + + var key = String.Format("{1}/{0}", baseCurrency.Abbreviation, ci.Abbreviation); + + if (!rates.ContainsKey(key)) + continue; + + result.Add(ci, rates[key]); + } + return result; + } + + + public static bool IsConvertable(String abbreviation) + { + var findedItem = _currencies.Keys.ToList().Find(item => String.Compare(abbreviation, item) == 0); + + if (findedItem == null) + throw new ArgumentException(abbreviation); + + return _currencies[findedItem].IsConvertable; + } + + public static Decimal MoneyConvert(decimal amount, string from, string to) + { + if (string.IsNullOrEmpty(from) || string.IsNullOrEmpty(to) || string.Compare(from, to, true) == 0) return amount; + + var rates = GetExchangeRates(); + + if (from.Contains('-')) from = new RegionInfo(from).ISOCurrencySymbol; + if (to.Contains('-')) to = new RegionInfo(to).ISOCurrencySymbol; + var key = string.Format("{0}/{1}", to, from); + + return Math.Round(rates[key] * amount, 4, MidpointRounding.AwayFromZero); + } + + public static Decimal MoneyConvertToDefaultCurrency(decimal amount, string from) + { + return MoneyConvert(amount, from, Global.TenantSettings.DefaultCurrency.Abbreviation); + } + + #endregion + + #region Private Methods + + private static bool ObsoleteData() + { + return _exchangeRates == null || (DateTime.UtcNow.Date.Subtract(_publisherDate.Date).Days > 0); + } + + private static string GetExchangesTempPath() { + return Path.Combine(Path.GetTempPath(), Path.Combine("onlyoffice", "exchanges")); + } + + private static Regex CurRateRegex = new Regex("[a-zA-Z]{3})\">(?[\\d\\.]+)"); + + private static Dictionary GetExchangeRates() + { + if (ObsoleteData()) + { + lock (_syncRoot) + { + if (ObsoleteData()) + { + try + { + _exchangeRates = new Dictionary(); + + var tmppath = GetExchangesTempPath(); + + TryToReadPublisherDate(tmppath); + + + var updateEnable = WebConfigurationManager.AppSettings["crm.update.currency.info.enable"] != "false"; + var ratesUpdatedFlag = false; + + foreach (var ci in _currencies.Values.Where(c => c.IsConvertable)) + { + var filepath = Path.Combine(tmppath, ci.Abbreviation + ".html"); + + if (updateEnable && 0 < (DateTime.UtcNow.Date - _publisherDate.Date).TotalDays || !File.Exists(filepath)) + { + var filepath_temp = Path.Combine(tmppath, ci.Abbreviation + "_temp.html"); + + DownloadCurrencyPage(ci.Abbreviation, filepath_temp); + + if (File.Exists(filepath_temp)) + { + if (TryGetRatesFromFile(filepath_temp, ci)) + { + ratesUpdatedFlag = true; + File.Copy(filepath_temp, filepath, true); + } + File.Delete(filepath_temp); + continue; + } + } + + if (File.Exists(filepath) && TryGetRatesFromFile(filepath, ci)) + { + ratesUpdatedFlag = true; + } + } + + if (ratesUpdatedFlag) + { + _publisherDate = DateTime.UtcNow; + WritePublisherDate(tmppath); + } + + } + catch (Exception error) + { + LogManager.GetLogger("ASC.CRM").Error(error); + _publisherDate = DateTime.UtcNow; + } + } + } + } + + return _exchangeRates; + } + + private static bool TryGetRatesFromFile(string filepath, CurrencyInfo curCI) + { + var success = false; + var currencyLines = File.ReadAllLines(filepath); + for (var i = 0; i < currencyLines.Length; i++) + { + var line = currencyLines[i]; + + if (line.Contains("id=\"major-currency-table\"") || line.Contains("id=\"minor-currency-table\"") || line.Contains("id=\"exotic-currency-table\"")) + { + var currencyInfos = CurRateRegex.Matches(line); + + if (currencyInfos.Count > 0) + { + foreach (var curInfo in currencyInfos) + { + _exchangeRates.Add( + String.Format("{0}/{1}", (curInfo as Match).Groups["Currency"].Value.Trim(), curCI.Abbreviation), + Convert.ToDecimal((curInfo as Match).Groups["Rate"].Value.Trim(), CultureInfo.InvariantCulture.NumberFormat)); + + success = true; + } + } + } + } + + return success; + } + + + private static void TryToReadPublisherDate(string tmppath) + { + if (_publisherDate == default(DateTime)) + { + try + { + var timefile = Path.Combine(tmppath, "last.time"); + if (File.Exists(timefile)) + { + var dateFromFile = File.ReadAllText(timefile); + _publisherDate = DateTime.ParseExact(dateFromFile, _formatDate, null); + } + } + catch (Exception err) + { + LogManager.GetLogger("ASC.CRM").Error(err); + } + } + } + + private static void WritePublisherDate(string tmppath) + { + try + { + var timefile = Path.Combine(tmppath, "last.time"); + File.WriteAllText(timefile, _publisherDate.ToString(_formatDate)); + } + catch (Exception err) + { + LogManager.GetLogger("ASC.CRM").Error(err); + } + } + + private static void DownloadCurrencyPage(string currency, string filepath) + { + + try + { + var dir = Path.GetDirectoryName(filepath); + + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(dir); + } + + var destinationURI = new Uri(String.Format("https://themoneyconverter.com/{0}/{0}.aspx", currency)); + + var request = (HttpWebRequest)WebRequest.Create(destinationURI); + request.Method = "GET"; + request.AllowAutoRedirect = true; + request.MaximumAutomaticRedirections = 2; + request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:8.0) Gecko/20100101 Firefox/8.0"; + request.UseDefaultCredentials = true; + + using (var response = (HttpWebResponse)request.GetResponse()) + using (var responseStream = new StreamReader(response.GetResponseStream())) + { + var data = responseStream.ReadToEnd(); + + File.WriteAllText(filepath, data); + + } + } + catch (Exception error) + { + _log.Error(error); + } + } + + #endregion + } +} diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs new file mode 100644 index 00000000000..9b64e5b811b --- /dev/null +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -0,0 +1,1426 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.Globalization; +using ASC.Common.Caching; +using ASC.Common.Security.Authentication; +using ASC.Common.Threading.Progress; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Data.Storage; +using ASC.Web.Core.Files; +using ASC.Web.CRM.Resources; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Utils; +using ASC.Web.Studio.Utility; +using Ionic.Zip; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using ASC.Common.Logging; +using ASC.Web.CRM.Core; +using Autofac; +using ASC.CRM.Resources; + +namespace ASC.Web.CRM.Classes +{ + class ExportDataCache + { + public static readonly ICache Cache = AscCache.Default; + + public static String GetStateCacheKey(string key) + { + return String.Format("{0}:crm:queue:exporttocsv", key); + } + + public static String GetCancelCacheKey(string key) + { + return String.Format("{0}:crm:queue:exporttocsv:cancel", key); + } + + public static ExportDataOperation Get(string key) + { + return Cache.Get(GetStateCacheKey(key)); + } + + public static void Insert(string key, ExportDataOperation data) + { + Cache.Insert(GetStateCacheKey(key), data, TimeSpan.FromMinutes(1)); + } + + public static bool CheckCancelFlag(string key) + { + var fromCache = Cache.Get(GetCancelCacheKey(key)); + + return !String.IsNullOrEmpty(fromCache); + } + + public static void SetCancelFlag(string key) + { + Cache.Insert(GetCancelCacheKey(key), "true", TimeSpan.FromMinutes(1)); + } + + public static void ResetAll(string key) + { + Cache.Remove(GetStateCacheKey(key)); + Cache.Remove(GetCancelCacheKey(key)); + } + } + + class ExportDataOperation : IProgressItem + { + #region Constructor + + public ExportDataOperation(FilterObject filterObject, string fileName) + { + _tenantId = TenantProvider.CurrentTenantID; + _author = SecurityContext.CurrentAccount; + _dataStore = Global.GetStore(); + _notifyClient = NotifyClient.Instance; + _filterObject = filterObject; + _log = LogManager.GetLogger("ASC.CRM"); + + Id = ExportToCsv.GetKey(filterObject != null); + Status = ProgressStatus.Queued; + Error = null; + Percentage = 0; + IsCompleted = false; + FileName = fileName ?? CRMSettingResource.Export + (filterObject == null ? ".zip" : ".csv"); + FileUrl = null; + } + + public ExportDataOperation() + : this(null, null) + { + } + + #endregion + + #region Members + + private readonly int _tenantId; + + private readonly IAccount _author; + + private readonly IDataStore _dataStore; + + private readonly NotifyClient _notifyClient; + + private readonly FilterObject _filterObject; + + private readonly ILog _log; + + private int _totalCount; + + #endregion + + public override bool Equals(object obj) + { + if (obj == null) return false; + + var exportDataOperation = obj as ExportDataOperation; + + if (exportDataOperation == null) return false; + + return Id == exportDataOperation.Id; + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public object Clone() + { + var cloneObj = new ExportDataOperation + { + Id = Id, + Status = Status, + Error = Error, + Percentage = Percentage, + IsCompleted = IsCompleted, + FileName = FileName, + FileUrl = FileUrl + }; + + return cloneObj; + } + + #region Property + + public object Id { get; set; } + + public object Status { get; set; } + + public object Error { get; set; } + + public double Percentage { get; set; } + + public bool IsCompleted { get; set; } + + public string FileName { get; set; } + + public string FileUrl { get; set; } + + #endregion + + #region Private Methods + + private static String WrapDoubleQuote(String value) + { + return "\"" + value.Trim().Replace("\"", "\"\"") + "\""; + } + + private static String DataTableToCsv(DataTable dataTable) + { + var result = new StringBuilder(); + + var columnsCount = dataTable.Columns.Count; + + for (var index = 0; index < columnsCount; index++) + { + if (index != columnsCount - 1) + result.Append(dataTable.Columns[index].Caption + ","); + else + result.Append(dataTable.Columns[index].Caption); + } + + result.Append(Environment.NewLine); + + foreach (DataRow row in dataTable.Rows) + { + for (var i = 0; i < columnsCount; i++) + { + var itemValue = WrapDoubleQuote(row[i].ToString()); + + if (i != columnsCount - 1) + result.Append(itemValue + ","); + else + result.Append(itemValue); + } + + result.Append(Environment.NewLine); + } + + return result.ToString(); + } + + #endregion + + public void RunJob() + { + try + { + Status = ProgressStatus.Started; + + CoreContext.TenantManager.SetCurrentTenant(_tenantId); + SecurityContext.AuthenticateMe(_author); + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var userCulture = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + + System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; + System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; + + _log.Debug("Start Export Data"); + + ExportDataCache.Insert((string) Id, (ExportDataOperation) Clone()); + + if (_filterObject == null) + ExportAllData(daoFactory); + else + ExportPartData(daoFactory); + } + + Complete(100, ProgressStatus.Done, null); + + _log.Debug("Export is completed"); + } + catch (OperationCanceledException) + { + Complete(0, ProgressStatus.Done, null); + + _log.Debug("Export is cancel"); + } + catch (Exception ex) + { + Complete(0, ProgressStatus.Failed, ex.Message); + + _log.Error(ex); + } + finally + { + ExportDataCache.ResetAll((string) Id); + } + } + + private void Complete(double percentage, ProgressStatus status, object error) + { + IsCompleted = true; + Percentage = percentage; + Status = status; + Error = error; + + ExportDataCache.Insert((string) Id, (ExportDataOperation)Clone()); + } + + private void ExportAllData(DaoFactory daoFactory) + { + using (var stream = TempStream.Create()) + { + var contactDao = daoFactory.ContactDao; + var contactInfoDao = daoFactory.ContactInfoDao; + var dealDao = daoFactory.DealDao; + var casesDao = daoFactory.CasesDao; + var taskDao = daoFactory.TaskDao; + var historyDao = daoFactory.RelationshipEventDao; + var invoiceItemDao = daoFactory.InvoiceItemDao; + + _totalCount += contactDao.GetAllContactsCount(); + _totalCount += dealDao.GetDealsCount(); + _totalCount += casesDao.GetCasesCount(); + _totalCount += taskDao.GetAllTasksCount(); + _totalCount += historyDao.GetAllItemsCount(); + _totalCount += invoiceItemDao.GetInvoiceItemsCount(); + + using (var zipStream = new ZipOutputStream(stream, true)) + { + zipStream.AlternateEncoding = Encoding.UTF8; + zipStream.AlternateEncodingUsage = ZipOption.Always; + + zipStream.PutNextEntry(CRMContactResource.Contacts + ".csv"); + var contactData = contactDao.GetAllContacts(); + var contactInfos = new StringDictionary(); + contactInfoDao.GetAll() + .ForEach(item => + { + var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, (int)item.InfoType, item.Category); + if (contactInfos.ContainsKey(contactInfoKey)) + { + contactInfos[contactInfoKey] += "," + item.Data; + } + else + { + contactInfos.Add(contactInfoKey, item.Data); + } + }); + + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportContactsToCsv(contactData, contactInfos, daoFactory)))) + { + zipEntryData.StreamCopyTo(zipStream); + } + + zipStream.PutNextEntry(CRMCommonResource.DealModuleName + ".csv"); + var dealData = dealDao.GetAllDeals(); + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportDealsToCsv(dealData, daoFactory)))) + { + zipEntryData.StreamCopyTo(zipStream); + } + + zipStream.PutNextEntry(CRMCommonResource.CasesModuleName + ".csv"); + var casesData = casesDao.GetAllCases(); + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportCasesToCsv(casesData, daoFactory)))) + { + zipEntryData.StreamCopyTo(zipStream); + } + + zipStream.PutNextEntry(CRMCommonResource.TaskModuleName + ".csv"); + var taskData = taskDao.GetAllTasks(); + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportTasksToCsv(taskData, daoFactory)))) + { + zipEntryData.StreamCopyTo(zipStream); + } + + zipStream.PutNextEntry(CRMCommonResource.History + ".csv"); + var historyData = historyDao.GetAllItems(); + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportHistoryToCsv(historyData, daoFactory)))) + { + zipEntryData.StreamCopyTo(zipStream); + } + + zipStream.PutNextEntry(CRMCommonResource.ProductsAndServices + ".csv"); + var invoiceItemData = invoiceItemDao.GetAll(); + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportInvoiceItemsToCsv(invoiceItemData, daoFactory)))) + { + zipEntryData.StreamCopyTo(zipStream); + } + + zipStream.Flush(); + zipStream.Close(); + + stream.Position = 0; + } + + FileUrl = CommonLinkUtility.GetFullAbsolutePath(_dataStore.SavePrivate(String.Empty, FileName, stream, DateTime.Now.AddDays(1))); + + _notifyClient.SendAboutExportCompleted(_author.ID, FileName, FileUrl); + } + } + + private void ExportPartData(DaoFactory daoFactory) + { + var items = _filterObject.GetItemsByFilter(daoFactory); + + string fileContent; + + _totalCount = items.Count; + + if (_totalCount == 0) + throw new ArgumentException(CRMErrorsResource.ExportToCSVDataEmpty); + + if (items is List) + { + var contactInfoDao = daoFactory.ContactInfoDao; + + var contacts = (List) items; + + var contactInfos = new StringDictionary(); + + contactInfoDao.GetAll(contacts.Select(item => item.ID).ToArray()) + .ForEach(item => + { + var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, + (int) item.InfoType, + item.Category); + + if (contactInfos.ContainsKey(contactInfoKey)) + contactInfos[contactInfoKey] += "," + item.Data; + else + contactInfos.Add(contactInfoKey, item.Data); + }); + + fileContent = ExportContactsToCsv(contacts, contactInfos, daoFactory); + } + else if (items is List) + { + fileContent = ExportDealsToCsv((List) items, daoFactory); + } + else if (items is List) + { + fileContent = ExportCasesToCsv((List) items, daoFactory); + } + else if (items is List) + { + fileContent = ExportHistoryToCsv((List) items, daoFactory); + } + else if (items is List) + { + fileContent = ExportTasksToCsv((List) items, daoFactory); + } + else if (items is List) + { + fileContent = ExportInvoiceItemsToCsv((List) items, daoFactory); + } + else + throw new ArgumentException(); + + FileUrl = SaveCsvFileInMyDocument(FileName, fileContent); + } + + private String ExportContactsToCsv(IReadOnlyCollection contacts, StringDictionary contactInfos, DaoFactory daoFactory) + { + var key = (string) Id; + var listItemDao = daoFactory.ListItemDao; + var tagDao = daoFactory.TagDao; + var customFieldDao = daoFactory.CustomFieldDao; + var contactDao = daoFactory.ContactDao; + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = CRMCommonResource.TypeCompanyOrPerson, + ColumnName = "company/person" + }, + new DataColumn + { + Caption = CRMContactResource.FirstName, + ColumnName = "firstname" + }, + new DataColumn + { + Caption = CRMContactResource.LastName, + ColumnName = "lastname" + }, + new DataColumn + { + Caption = CRMContactResource.CompanyName, + ColumnName = "companyname" + }, + new DataColumn + { + Caption = CRMContactResource.JobTitle, + ColumnName = "jobtitle" + }, + new DataColumn + { + Caption = CRMContactResource.About, + ColumnName = "about" + }, + new DataColumn + { + Caption = CRMContactResource.ContactStage, + ColumnName = "contact_stage" + }, + new DataColumn + { + Caption = CRMContactResource.ContactType, + ColumnName = "contact_type" + }, + new DataColumn + { + Caption = CRMContactResource.ContactTagList, + ColumnName = "contact_tag_list" + } + }); + + foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) + foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) + { + var localTitle = String.Format("{1} ({0})", categoryEnum.ToLocalizedString().ToLower(), infoTypeEnum.ToLocalizedString()); + + if (infoTypeEnum == ContactInfoType.Address) + dataTable.Columns.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) + select new DataColumn + { + Caption = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString().ToLower()), + ColumnName = String.Format("contactInfo_{0}_{1}_{2}", (int)infoTypeEnum, categoryEnum, (int)addressPartEnum) + }).ToArray()); + + else + dataTable.Columns.Add(new DataColumn + { + Caption = localTitle, + ColumnName = String.Format("contactInfo_{0}_{1}", (int)infoTypeEnum, categoryEnum) + }); + } + + var fieldsDescription = customFieldDao.GetFieldsDescription(EntityType.Company); + + customFieldDao.GetFieldsDescription(EntityType.Person).ForEach(item => + { + var alreadyContains = fieldsDescription.Any(field => field.ID == item.ID); + + if (!alreadyContains) + fieldsDescription.Add(item); + }); + + fieldsDescription.ForEach( + item => + { + if (item.FieldType == CustomFieldType.Heading) return; + + dataTable.Columns.Add( + new DataColumn + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + } + ); + }); + + var customFieldEntity = new Dictionary>(); + + var entityFields = customFieldDao.GetEnityFields(EntityType.Company, 0, false); + + customFieldDao.GetEnityFields(EntityType.Person, 0, false).ForEach(item => + { + var alreadyContains = entityFields.Any(field => field.ID == item.ID && field.EntityID == item.EntityID); + + if (!alreadyContains) + entityFields.Add(item); + }); + + entityFields.ForEach( + item => + { + if (!customFieldEntity.ContainsKey(item.EntityID)) + customFieldEntity.Add(item.EntityID, new List { item }); + else + customFieldEntity[item.EntityID].Add(item); + }); + + var tags = tagDao.GetEntitiesTags(EntityType.Contact); + + foreach (var contact in contacts) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var isCompany = contact is Company; + + var compPersType = (isCompany) ? CRMContactResource.Company : CRMContactResource.Person; + + var contactTags = String.Empty; + + if (tags.ContainsKey(contact.ID)) + contactTags = String.Join(",", tags[contact.ID].OrderBy(x => x)); + + String firstName; + String lastName; + + String companyName; + String title; + + if (contact is Company) + { + firstName = String.Empty; + lastName = String.Empty; + title = String.Empty; + companyName = ((Company)contact).CompanyName; + } + else + { + var people = (Person)contact; + + firstName = people.FirstName; + lastName = people.LastName; + title = people.JobTitle; + + companyName = String.Empty; + + if (people.CompanyID > 0) + { + var personCompany = contacts.SingleOrDefault(item => item.ID == people.CompanyID) ?? + contactDao.GetByID(people.CompanyID); + + if (personCompany != null) + companyName = personCompany.GetTitle(); + } + } + + var contactStatus = String.Empty; + + if (contact.StatusID > 0) + { + + var listItem = listItemDao.GetByID(contact.StatusID); + + if (listItem != null) + contactStatus = listItem.Title; + } + + var contactType = String.Empty; + + if (contact.ContactTypeID > 0) + { + + var listItem = listItemDao.GetByID(contact.ContactTypeID); + + if (listItem != null) + contactType = listItem.Title; + } + + var dataRowItems = new List + { + compPersType, + firstName, + lastName, + companyName, + title, + contact.About, + contactStatus, + contactType, + contactTags + }; + + foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) + foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) + { + var contactInfoKey = String.Format("{0}_{1}_{2}", contact.ID, + (int)infoTypeEnum, + Convert.ToInt32(categoryEnum)); + + var columnValue = ""; + + if (contactInfos.ContainsKey(contactInfoKey)) + columnValue = contactInfos[contactInfoKey]; + + if (infoTypeEnum == ContactInfoType.Address) + { + if (!String.IsNullOrEmpty(columnValue)) + { + var addresses = JArray.Parse(String.Concat("[", columnValue, "]")); + + dataRowItems.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) + select String.Join(",", addresses.Select(item => (String)item.SelectToken(addressPartEnum.ToString().ToLower())).ToArray())).ToArray()); + } + else + { + dataRowItems.AddRange(new[] { "", "", "", "", "" }); + } + } + else + { + dataRowItems.Add(columnValue); + } + } + + var dataRow = dataTable.Rows.Add(dataRowItems.ToArray()); + + if (customFieldEntity.ContainsKey(contact.ID)) + customFieldEntity[contact.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); + } + + return DataTableToCsv(dataTable); + } + + private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) + { + var key = (string) Id; + var tagDao = daoFactory.TagDao; + var customFieldDao = daoFactory.CustomFieldDao; + var dealMilestoneDao = daoFactory.DealMilestoneDao; + var contactDao = daoFactory.ContactDao; + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = CRMDealResource.NameDeal, + ColumnName = "title" + }, + new DataColumn + { + Caption = CRMDealResource.ClientDeal, + ColumnName = "client_deal" + }, + new DataColumn + { + Caption = CRMDealResource.DescriptionDeal, + ColumnName = "description" + }, + new DataColumn + { + Caption = CRMCommonResource.Currency, + ColumnName = "currency" + }, + new DataColumn + { + Caption = CRMDealResource.DealAmount, + ColumnName = "amount" + }, + new DataColumn + { + Caption = CRMDealResource.BidType, + ColumnName = "bid_type" + }, + new DataColumn + { + Caption = CRMDealResource.BidTypePeriod, + ColumnName = "bid_type_period" + }, + new DataColumn + { + Caption = CRMJSResource.ExpectedCloseDate, + ColumnName = "expected_close_date" + }, + new DataColumn + { + Caption = CRMJSResource.ActualCloseDate, + ColumnName = "actual_close_date" + }, + new DataColumn + { + Caption = CRMDealResource.ResponsibleDeal, + ColumnName = "responsible_deal" + }, + new DataColumn + { + Caption = CRMDealResource.CurrentDealMilestone, + ColumnName = "current_deal_milestone" + }, + new DataColumn + { + Caption = CRMDealResource.DealMilestoneType, + ColumnName = "deal_milestone_type" + }, + new DataColumn + { + Caption = (CRMDealResource.ProbabilityOfWinning + " %"), + ColumnName = "probability_of_winning" + }, + new DataColumn + { + Caption = (CRMDealResource.DealTagList), + ColumnName = "tag_list" + } + }); + + customFieldDao.GetFieldsDescription(EntityType.Opportunity).ForEach( + item => + { + if (item.FieldType == CustomFieldType.Heading) return; + + dataTable.Columns.Add(new DataColumn + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + }); + }); + + var customFieldEntity = new Dictionary>(); + + customFieldDao.GetEnityFields(EntityType.Opportunity, 0, false).ForEach( + item => + { + if (!customFieldEntity.ContainsKey(item.EntityID)) + customFieldEntity.Add(item.EntityID, new List { item }); + else + customFieldEntity[item.EntityID].Add(item); + }); + + var tags = tagDao.GetEntitiesTags(EntityType.Opportunity); + + foreach (var deal in deals) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var contactTags = String.Empty; + + if (tags.ContainsKey(deal.ID)) + contactTags = String.Join(",", tags[deal.ID].OrderBy(x => x)); + + String bidType; + + switch (deal.BidType) + { + case BidType.FixedBid: + bidType = CRMDealResource.BidType_FixedBid; + break; + case BidType.PerDay: + bidType = CRMDealResource.BidType_PerDay; + break; + case BidType.PerHour: + bidType = CRMDealResource.BidType_PerHour; + break; + case BidType.PerMonth: + bidType = CRMDealResource.BidType_PerMonth; + break; + case BidType.PerWeek: + bidType = CRMDealResource.BidType_PerWeek; + break; + case BidType.PerYear: + bidType = CRMDealResource.BidType_PerYear; + break; + default: + throw new ArgumentException(); + } + + var currentDealMilestone = dealMilestoneDao.GetByID(deal.DealMilestoneID); + var currentDealMilestoneStatus = currentDealMilestone.Status.ToLocalizedString(); + var contactTitle = String.Empty; + + if (deal.ContactID != 0) + contactTitle = contactDao.GetByID(deal.ContactID).GetTitle(); + + var dataRow = dataTable.Rows.Add(new object[] + { + deal.Title, + contactTitle, + deal.Description, + deal.BidCurrency, + deal.BidValue.ToString(CultureInfo.InvariantCulture), + bidType, + deal.PerPeriodValue == 0 ? "" : deal.PerPeriodValue.ToString(CultureInfo.InvariantCulture), + deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern), + deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern), + CoreContext.UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(false), + currentDealMilestone.Title, + currentDealMilestoneStatus, + deal.DealMilestoneProbability.ToString(CultureInfo.InvariantCulture), + contactTags + }); + + if (customFieldEntity.ContainsKey(deal.ID)) + customFieldEntity[deal.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); + } + + return DataTableToCsv(dataTable); + } + + private String ExportCasesToCsv(IEnumerable cases, DaoFactory daoFactory) + { + var key = (string) Id; + var tagDao = daoFactory.TagDao; + var customFieldDao = daoFactory.CustomFieldDao; + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = CRMCasesResource.CaseTitle, + ColumnName = "title" + }, + new DataColumn(CRMCasesResource.CasesTagList) + { + Caption = CRMCasesResource.CasesTagList, + ColumnName = "tag_list" + } + }); + + customFieldDao.GetFieldsDescription(EntityType.Case).ForEach( + item => + { + if (item.FieldType == CustomFieldType.Heading) return; + + dataTable.Columns.Add(new DataColumn + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + }); + }); + + var customFieldEntity = new Dictionary>(); + + customFieldDao.GetEnityFields(EntityType.Case, 0, false).ForEach( + item => + { + if (!customFieldEntity.ContainsKey(item.EntityID)) + customFieldEntity.Add(item.EntityID, new List { item }); + else + customFieldEntity[item.EntityID].Add(item); + }); + + var tags = tagDao.GetEntitiesTags(EntityType.Case); + + foreach (var item in cases) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var contactTags = String.Empty; + + if (tags.ContainsKey(item.ID)) + contactTags = String.Join(",", tags[item.ID].OrderBy(x => x)); + + var dataRow = dataTable.Rows.Add(new object[] + { + item.Title, + contactTags + }); + + if (customFieldEntity.ContainsKey(item.ID)) + customFieldEntity[item.ID].ForEach(row => dataRow["customField_" + row.ID] = row.Value); + } + + return DataTableToCsv(dataTable); + } + + private String ExportHistoryToCsv(IEnumerable events, DaoFactory daoFactory) + { + var key = (string) Id; + var listItemDao = daoFactory.ListItemDao; + var dealDao = daoFactory.DealDao; + var casesDao = daoFactory.CasesDao; + var contactDao = daoFactory.ContactDao; + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = (CRMContactResource.Content), + ColumnName = "content" + }, + new DataColumn + { + Caption = (CRMCommonResource.Category), + ColumnName = "category" + }, + new DataColumn + { + Caption = (CRMContactResource.ContactTitle), + ColumnName = "contact_title" + }, + new DataColumn + { + Caption = (CRMContactResource.RelativeEntity), + ColumnName = "relative_entity" + }, + new DataColumn + { + Caption = (CRMCommonResource.Author), + ColumnName = "author" + }, + new DataColumn + { + Caption = (CRMCommonResource.CreateDate), + ColumnName = "create_date" + } + }); + + foreach (var item in events) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var entityTitle = String.Empty; + + if (item.EntityID > 0) + switch (item.EntityType) + { + case EntityType.Case: + var casesObj = casesDao.GetByID(item.EntityID); + + if (casesObj != null) + entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, + casesObj.Title); + break; + case EntityType.Opportunity: + var dealObj = dealDao.GetByID(item.EntityID); + + if (dealObj != null) + entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, + dealObj.Title); + break; + } + + var contactTitle = String.Empty; + + if (item.ContactID > 0) + { + var contactObj = contactDao.GetByID(item.ContactID); + + if (contactObj != null) + contactTitle = contactObj.GetTitle(); + } + + var categoryTitle = String.Empty; + + if (item.CategoryID > 0) + { + var categoryObj = listItemDao.GetByID(item.CategoryID); + + if (categoryObj != null) + categoryTitle = categoryObj.Title; + + } + else if (item.CategoryID == (int)HistoryCategorySystem.TaskClosed) + categoryTitle = HistoryCategorySystem.TaskClosed.ToLocalizedString(); + else if (item.CategoryID == (int)HistoryCategorySystem.FilesUpload) + categoryTitle = HistoryCategorySystem.FilesUpload.ToLocalizedString(); + else if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) + categoryTitle = HistoryCategorySystem.MailMessage.ToLocalizedString(); + + dataTable.Rows.Add(new object[] + { + item.Content, + categoryTitle, + contactTitle, + entityTitle, + CoreContext.UserManager.GetUsers(item.CreateBy).DisplayUserName(false), + item.CreateOn.ToShortString() + }); + } + + return DataTableToCsv(dataTable); + } + + private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) + { + var key = (string) Id; + var listItemDao = daoFactory.ListItemDao; + var dealDao = daoFactory.DealDao; + var casesDao = daoFactory.CasesDao; + var contactDao = daoFactory.ContactDao; + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = (CRMTaskResource.TaskTitle), + ColumnName = "title" + }, + new DataColumn + { + Caption = (CRMTaskResource.Description), + ColumnName = "description" + }, + new DataColumn + { + Caption = (CRMTaskResource.DueDate), + ColumnName = "due_date" + }, + new DataColumn + { + Caption = (CRMTaskResource.Responsible), + ColumnName = "responsible" + }, + new DataColumn + { + Caption = (CRMContactResource.ContactTitle), + ColumnName = "contact_title" + }, + new DataColumn + { + Caption = (CRMTaskResource.TaskStatus), + ColumnName = "task_status" + }, + new DataColumn + { + Caption = (CRMTaskResource.TaskCategory), + ColumnName = "task_category" + }, + new DataColumn + { + Caption = (CRMContactResource.RelativeEntity), + ColumnName = "relative_entity" + }, + new DataColumn + { + Caption = (CRMCommonResource.Alert), + ColumnName = "alert_value" + } + }); + + foreach (var item in tasks) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var entityTitle = String.Empty; + + if (item.EntityID > 0) + switch (item.EntityType) + { + case EntityType.Case: + var caseObj = casesDao.GetByID(item.EntityID); + + if (caseObj != null) + entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, caseObj.Title); + break; + case EntityType.Opportunity: + var dealObj = dealDao.GetByID(item.EntityID); + + if (dealObj != null) + entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, dealObj.Title); + break; + } + + var contactTitle = String.Empty; + + if (item.ContactID > 0) + { + var contact = contactDao.GetByID(item.ContactID); + + if (contact != null) + contactTitle = contact.GetTitle(); + } + + dataTable.Rows.Add(new object[] + { + item.Title, + item.Description, + item.DeadLine == DateTime.MinValue + ? "" + : item.DeadLine.ToShortString(), + CoreContext.UserManager.GetUsers(item.ResponsibleID).DisplayUserName(false), + contactTitle, + item.IsClosed + ? CRMTaskResource.TaskStatus_Closed + : CRMTaskResource.TaskStatus_Open, + listItemDao.GetByID(item.CategoryID).Title, + entityTitle, + item.AlertValue.ToString(CultureInfo.InvariantCulture) + }); + } + + return DataTableToCsv(dataTable); + } + + private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, DaoFactory daoFactory) + { + var key = (string) Id; + var taxes = daoFactory.InvoiceTaxDao.GetAll(); + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceItemName), + ColumnName = "title" + }, + new DataColumn + { + Caption = (CRMSettingResource.Description), + ColumnName = "description" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.StockKeepingUnit), + ColumnName = "sku" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceItemPrice), + ColumnName = "price" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.FormInvoiceItemStockQuantity), + ColumnName = "stock_quantity" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.TrackInventory), + ColumnName = "track_inventory" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.Currency), + ColumnName = "currency" + }, + + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax1Name), + ColumnName = "tax1_name" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax1Rate), + ColumnName = "tax1_rate" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax2Name), + ColumnName = "tax2_name" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax2Rate), + ColumnName = "tax2_rate" + } + + }); + + + foreach (var item in invoiceItems) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var tax1 = item.InvoiceTax1ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax1ID) : null; + var tax2 = item.InvoiceTax2ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax2ID) : null; + + dataTable.Rows.Add(new object[] + { + item.Title, + item.Description, + item.StockKeepingUnit, + item.Price.ToString(CultureInfo.InvariantCulture), + item.StockQuantity.ToString(CultureInfo.InvariantCulture), + item.TrackInventory.ToString(), + item.Currency, + tax1 != null ? tax1.Name : "", + tax1 != null ? tax1.Rate.ToString(CultureInfo.InvariantCulture) : "", + tax2 != null ? tax2.Name : "", + tax2 != null ? tax2.Rate.ToString(CultureInfo.InvariantCulture) : "" + }); + } + + return DataTableToCsv(dataTable); + } + + private static String SaveCsvFileInMyDocument(String title, String data) + { + string fileUrl; + + using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(data))) + { + var file = FileUploader.Exec(Files.Classes.Global.FolderMy.ToString(), title, memStream.Length, memStream, true); + + if (FileUtility.CanWebView(title) || FileUtility.CanWebEdit(title)) + { + fileUrl = FilesLinkUtility.GetFileWebEditorUrl((int)file.ID); + fileUrl += string.Format("&options={{\"delimiter\":{0},\"codePage\":{1}}}", + (int)FileUtility.CsvDelimiter.Comma, + Encoding.UTF8.CodePage); + } + else + { + fileUrl = FilesLinkUtility.GetFileDownloadUrl((int)file.ID); + } + } + + return fileUrl; + } + } + + public class ExportToCsv + { + #region Members + + private static readonly object Locker = new object(); + + private static readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromSeconds(60), true); + + #endregion + + #region Public Methods + + public static IProgressItem GetStatus(bool partialDataExport) + { + var key = GetKey(partialDataExport); + + return Queue.GetStatus(key) ?? ExportDataCache.Get(key); + } + + public static IProgressItem Start(FilterObject filterObject, string fileName) + { + lock (Locker) + { + var key = GetKey(filterObject != null); + + var operation = Queue.GetStatus(key); + + if (operation == null ) + { + var fromCache = ExportDataCache.Get(key); + + if (fromCache != null) + return fromCache; + } + + if (operation == null) + { + operation = new ExportDataOperation(filterObject, fileName); + + Queue.Add(operation); + } + + if (!Queue.IsStarted) + Queue.Start(x => x.RunJob()); + + return operation; + } + } + + public static void Cancel(bool partialDataExport) + { + lock (Locker) + { + var key = GetKey(partialDataExport); + + var findedItem = Queue.GetItems().FirstOrDefault(elem => (string)elem.Id == key); + + if (findedItem != null) + { + Queue.Remove(findedItem); + } + + ExportDataCache.SetCancelFlag(key); + } + } + + public static string GetKey(bool partialDataExport) + { + return string.Format("{0}_{1}", TenantProvider.CurrentTenantID, + partialDataExport ? SecurityContext.CurrentAccount.ID : Guid.Empty); + } + + public static String ExportItems(FilterObject filterObject, string fileName) + { + var operation = new ExportDataOperation(filterObject, fileName); + + operation.RunJob(); + + return operation.FileUrl; + } + + #endregion + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/FileHelper.cs b/products/ASC.CRM/Server/Utils/FileHelper.cs new file mode 100644 index 00000000000..6db9cbcd5f9 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/FileHelper.cs @@ -0,0 +1,94 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.IO; +using System.Reflection; + +namespace ASC.Web.CRM.Classes +{ + public class FileHelper + { + public static void WriteTextToFile(string path, string text) + { + File.WriteAllText(path, text); + } + + public static string ReadTextFromFile(string path) + { + return File.Exists(path) ? File.ReadAllText(path) : null; + } + + public static string ReadTextFromEmbeddedResource(string resourceName) + { + var result = string.Empty; + var assembly = Assembly.GetExecutingAssembly(); + + using (var stream = assembly.GetManifestResourceStream(resourceName)) + { + if (stream != null) + { + using (var sr = new StreamReader(stream)) + { + result = sr.ReadToEnd(); + } + } + } + + return result; + } + + public static byte[] ReadBytesFromFile(string path) + { + return File.Exists(path) ? File.ReadAllBytes(path) : null; + } + + public static byte[] ReadBytesFromEmbeddedResource(string resourceName) + { + byte[] result = null; + var assembly = Assembly.GetExecutingAssembly(); + + using (var stream = assembly.GetManifestResourceStream(resourceName)) + { + if (stream != null) + { + using (var memoryStream = new MemoryStream()) + { + stream.CopyTo(memoryStream); + result = memoryStream.ToArray(); + } + } + } + + return result; + } + + public static void DeleteFile(string path) + { + if (File.Exists(path)) + File.Delete(path); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs b/products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs new file mode 100644 index 00000000000..a599d274ca1 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs @@ -0,0 +1,32 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.Web.CRM.Classes +{ + internal class CsvReader + { + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs new file mode 100644 index 00000000000..6469ce2b4ac --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs @@ -0,0 +1,49 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; + +namespace LumenWorks.Framework.IO.Csv +{ + public static class CsvReaderExtension + { + public static String[] GetCurrentRowFields(this CsvReader csvReader, bool htmlEncodeColumn) + { + var fieldCount = csvReader.FieldCount; + var result = new String[fieldCount]; + + for (int index = 0; index < fieldCount; index++) + { + if (htmlEncodeColumn) + result[index] = csvReader[index].HtmlEncode().ReplaceSingleQuote(); + else + result[index] = csvReader[index]; + } + + return result; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs new file mode 100644 index 00000000000..50ce6761560 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs @@ -0,0 +1,103 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Web.CRM.Core.Enums; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace ASC.Web.CRM.Classes +{ + public class ImportCSVSettings + { + public ImportCSVSettings(String jsonStr) + { + var json = JObject.Parse(jsonStr); + + if (json == null) return; + + HasHeader = json["has_header"].Value(); + DelimiterCharacter = Convert.ToChar(json["delimiter_character"].Value()); + Encoding = Encoding.GetEncoding(json["encoding"].Value()); + QuoteType = Convert.ToChar(json["quote_character"].Value()); + + JToken columnMappingToken; + + if (json.TryGetValue("column_mapping", out columnMappingToken)) + ColumnMapping = (JObject)columnMappingToken; + + JToken duplicateRecordRuleToken; + + if (json.TryGetValue("removing_duplicates_behavior", out duplicateRecordRuleToken)) + DuplicateRecordRule = duplicateRecordRuleToken.Value(); + + JToken isPrivateToken; + if (json.TryGetValue("is_private", out isPrivateToken)) + { + IsPrivate = isPrivateToken.Value(); + AccessList = json["access_list"].Values().Select(item => new Guid(item)).ToList(); + } + + JToken shareTypeToken; + if (json.TryGetValue("share_type", out shareTypeToken)) + { + ShareType = (ShareType)(shareTypeToken.Value()); + ContactManagers = json["contact_managers"].Values().Select(item => new Guid(item)).ToList(); + } + + if (json["tags"] != null) + { + Tags = json["tags"].Values().ToList(); + } + } + + public bool IsPrivate { get; set; } + + public ShareType ShareType { get; set; } + + public int DuplicateRecordRule { get; set; } + + public bool HasHeader { get; set; } + + public char DelimiterCharacter { get; set; } + + public char QuoteType { get; set; } + + public Encoding Encoding { get; set; } + + public List AccessList { get; set; } + + public List ContactManagers { get; set; } + + public JObject ColumnMapping { get; set; } + + public List Tags { get; set; } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs new file mode 100644 index 00000000000..f037e3b99b6 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -0,0 +1,224 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Web.CRM.Resources; +using LumenWorks.Framework.IO.Csv; +using Newtonsoft.Json.Linq; +using ASC.Common.Threading.Progress; +using ASC.CRM.Core.Dao; + +#endregion + +namespace ASC.Web.CRM.Classes +{ + public partial class ImportDataOperation + { + private void ImportCaseData(DaoFactory _daoFactory) + { + using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) + { + int currentIndex = 0; + + var casesDao = _daoFactory.CasesDao; + var customFieldDao = _daoFactory.CustomFieldDao; + var tagDao = _daoFactory.TagDao; + + var findedTags = new Dictionary>(); + var findedCustomField = new List(); + var findedCases = new List(); + var findedCasesMembers = new Dictionary>(); + + while (csv.ReadNextRecord()) + { + _columns = csv.GetCurrentRowFields(false); + + var objCases = new ASC.CRM.Core.Entities.Cases(); + + objCases.ID = currentIndex; + + objCases.Title = GetPropertyValue("title"); + + if (String.IsNullOrEmpty(objCases.Title)) continue; + + foreach (JProperty jToken in _importSettings.ColumnMapping.Children()) + { + var propertyValue = GetPropertyValue(jToken.Name); + + if (String.IsNullOrEmpty(propertyValue)) continue; + + if (!jToken.Name.StartsWith("customField_")) continue; + + var fieldID = Convert.ToInt32(jToken.Name.Split(new[] { '_' })[1]); + + var field = customFieldDao.GetFieldDescription(fieldID); + + if (field != null) + { + findedCustomField.Add(new CustomField + { + EntityID = objCases.ID, + EntityType = EntityType.Case, + ID = fieldID, + Value = field.FieldType == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue + }); + } + + } + + var tag = GetPropertyValue("tag"); + + if (!String.IsNullOrEmpty(tag)) + { + var tagList = tag.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); + tagList.AddRange(_importSettings.Tags); + tagList = tagList.Distinct().ToList(); + findedTags.Add(objCases.ID, tagList); + } + else if (_importSettings.Tags.Count != 0) + { + findedTags.Add(objCases.ID, _importSettings.Tags); + } + + var localMembersCases = new List(); + + var members = GetPropertyValue("member"); + + if (!String.IsNullOrEmpty(members)) + { + var membersList = members.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var item in membersList) + { + var findedMember = _daoFactory.ContactDao.GetContactsByName(item, true); + + if (findedMember.Count > 0) + { + localMembersCases.Add(findedMember[0].ID); + } + else + { + findedMember = _daoFactory.ContactDao.GetContactsByName(item, false); + if (findedMember.Count > 0) + { + localMembersCases.Add(findedMember[0].ID); + } + } + + } + } + + if (localMembersCases.Count > 0) + findedCasesMembers.Add(objCases.ID, localMembersCases); + + objCases.ID = currentIndex; + + findedCases.Add(objCases); + + if (currentIndex + 1 > ImportFromCSV.MaxRoxCount) break; + + currentIndex++; + } + + Percentage = 62.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Case)) + { + ImportDataCache.ResetAll(EntityType.Case); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + + var newIDs = casesDao.SaveCasesList(findedCases); + findedCases.ForEach(d => d.ID = newIDs[d.ID]); + + findedCustomField.ForEach(item => item.EntityID = newIDs[item.EntityID]); + + customFieldDao.SaveList(findedCustomField); + + Percentage += 12.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Case)) + { + ImportDataCache.ResetAll(EntityType.Case); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + + foreach (var findedCasesMemberKey in findedCasesMembers.Keys) + { + _daoFactory.DealDao.SetMembers(newIDs[findedCasesMemberKey], findedCasesMembers[findedCasesMemberKey].ToArray()); + } + + Percentage += 12.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Case)) + { + ImportDataCache.ResetAll(EntityType.Case); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + + + foreach (var findedTagKey in findedTags.Keys) + { + tagDao.SetTagToEntity(EntityType.Case, newIDs[findedTagKey], findedTags[findedTagKey].ToArray()); + } + + if (_importSettings.IsPrivate) + findedCases.ForEach(dealItem => CRMSecurity.SetAccessTo(dealItem, _importSettings.AccessList)); + + + Percentage += 12.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Case)) + { + ImportDataCache.ResetAll(EntityType.Case); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Case,(ImportDataOperation)Clone()); + + } + + Complete(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs new file mode 100644 index 00000000000..a06d2c6c73c --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -0,0 +1,698 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Web.CRM.Core.Enums; +using LumenWorks.Framework.IO.Csv; +using Newtonsoft.Json.Linq; +using ASC.CRM.Core.Dao; +using ASC.Common.Threading.Progress; + +#endregion + +namespace ASC.Web.CRM.Classes +{ + public partial class ImportDataOperation + { + private Int32 DaoIterationStep = 200; + + private void ImportContactsData(DaoFactory _daoFactory) + { + var index = 0; + + var personFakeIdCompanyNameHash = new Dictionary(); + + var contactDao = _daoFactory.ContactDao; + var contactInfoDao = _daoFactory.ContactInfoDao; + var customFieldDao = _daoFactory.CustomFieldDao; + var tagDao = _daoFactory.TagDao; + + var findedContacts = new Dictionary(); + var findedTags = new Dictionary>(); + var findedCustomField = new List(); + var findedContactInfos = new List(); + + #region Read csv + using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) + { + int currentIndex = 0; + + while (csv.ReadNextRecord()) + { + _columns = csv.GetCurrentRowFields(false); + Contact contact = null; + + #region Common data + + if (!_CommonData(currentIndex, _daoFactory, ref contact, ref personFakeIdCompanyNameHash)) + continue; + + findedContacts.Add(contact.ID, contact); + + #endregion + + #region Read tags + + _ReadTags(ref findedTags, contact); + + #endregion + + #region Custom fields Y contact infos + + var primaryFields = new List(); + + foreach (JProperty jToken in _importSettings.ColumnMapping.Children()) + { + var propertyValue = GetPropertyValue(jToken.Name); + if (String.IsNullOrEmpty(propertyValue)) continue; + + if (jToken.Name.StartsWith("customField_")) + { + _ReadCustomField(jToken, propertyValue, contact, ref findedCustomField, customFieldDao); + } + else if (jToken.Name.StartsWith("contactInfo_")) + { + var addressTemplate = new JObject(); + foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) + addressTemplate.Add(addressPartName.ToLower(), ""); + + var addressTemplateStr = addressTemplate.ToString(); + + _ReadContactInfo(jToken, propertyValue, contact, ref findedContactInfos, ref primaryFields, addressTemplateStr); + } + } + #endregion + + if (currentIndex + 1 > ImportFromCSV.MaxRoxCount) break; + currentIndex++; + } + } + _log.InfoFormat("ImportContactsData. Reading {0} findedContacts complete", findedContacts.Count); + + #endregion + + Percentage = 37.5; + + #region Check Cancel flag | Insert Operation InCache + if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) + { + ImportDataCache.ResetAll(EntityType.Contact); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + #endregion + + #region Processing duplicate rule + + _DuplicateRecordRuleProcess(_daoFactory, ref findedContacts, ref personFakeIdCompanyNameHash, ref findedContactInfos, ref findedCustomField, ref findedTags); + + _log.Info("ImportContactsData. _DuplicateRecordRuleProcess. End"); + + if (IsCompleted) { + return; + } + + #endregion + + Percentage += 12.5; + + #region Check Cancel flag | Insert Operation InCache + if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) + { + ImportDataCache.ResetAll(EntityType.Contact); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Contact,(ImportDataOperation)Clone()); + #endregion + + #region Manipulation for saving Companies for persons + CRMSecurity + + var findedCompanies = findedContacts.Where(x => x.Value is Company).ToDictionary(x => x.Key, y => y.Value); + var findedPeoples = findedContacts.Where(x => x.Value is Person).ToDictionary(x => x.Key, y => y.Value); + + var fakeRealContactIdHash = new Dictionary(); + var companyNameRealIdHash = new Dictionary(); + + + var findedCompaniesList = findedCompanies.Values.ToList(); + if (findedCompaniesList.Count != 0) + { + index = 0; + while (index < findedCompaniesList.Count) + { + var portion = findedCompaniesList.Skip(index).Take(DaoIterationStep).ToList();// Get next step + + fakeRealContactIdHash = fakeRealContactIdHash.Union( + contactDao.SaveContactList(portion)) + .ToDictionary(item => item.Key, item => item.Value); + + + #region CRMSecurity set -by every item- + + portion.ForEach(ct => CRMSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); + + #endregion + + + index += DaoIterationStep; + if (index > findedCompaniesList.Count) + { + index = findedCompaniesList.Count; + } + } + } + + + foreach (Company item in findedCompanies.Values) + { + if (companyNameRealIdHash.ContainsKey(item.CompanyName)) continue; + + companyNameRealIdHash.Add(item.CompanyName, item.ID); + } + + foreach (var item in personFakeIdCompanyNameHash) + { + var person = (Person)findedPeoples[item.Key]; + + if (companyNameRealIdHash.ContainsKey(item.Value)) + { + person.CompanyID = companyNameRealIdHash[item.Value]; + } + else + { + var findedCompany = contactDao.GetContactsByName(item.Value, true).FirstOrDefault(); + + // Why ??? + if (findedCompany == null) + { + #region create COMPANY for person in csv + + findedCompany = new Company + { + CompanyName = item.Value, + ShareType = _importSettings.ShareType + }; + findedCompany.ID = contactDao.SaveContact(findedCompany); + + person.CompanyID = findedCompany.ID; + CRMSecurity.SetAccessTo(findedCompany, _importSettings.ContactManagers); + + if (_importSettings.Tags.Count != 0) + { + tagDao.SetTagToEntity(EntityType.Contact, person.CompanyID, _importSettings.Tags.ToArray()); + } + + #endregion + } + else + { + person.CompanyID = findedCompany.ID; + } + + companyNameRealIdHash.Add(item.Value, person.CompanyID); + } + } + #endregion + + #region Saving People common data -by portions- + CRMSecurity + + var findedPeopleList = findedPeoples.Values.ToList(); + if (findedPeopleList.Count != 0) + { + index = 0; + while (index < findedPeopleList.Count) + { + var portion = findedPeopleList.Skip(index).Take(DaoIterationStep).ToList();// Get next step + + fakeRealContactIdHash = fakeRealContactIdHash.Union( + contactDao.SaveContactList(portion)) + .ToDictionary(item => item.Key, item => item.Value); + + #region CRMSecurity set -by every item- + + portion.ForEach(ct => CRMSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); + + #endregion + + + index += DaoIterationStep; + if (index > findedPeopleList.Count) + { + index = findedPeopleList.Count; + } + } + } + _log.Info("ImportContactsData. Contacts common data saved"); + #endregion + + Percentage += 12.5; + + #region Check Cancel flag | Insert Operation InCache + if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) + { + ImportDataCache.ResetAll(EntityType.Contact); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + #endregion + + #region Save contact infos -by portions- + + if (findedContactInfos.Count != 0) + { + findedContactInfos.ForEach(item => item.ContactID = fakeRealContactIdHash[item.ContactID]); + + index = 0; + while (index < findedContactInfos.Count) + { + var portion = findedContactInfos.Skip(index).Take(DaoIterationStep).ToList();// Get next step + + contactInfoDao.SaveList(portion); + + index += DaoIterationStep; + if (index > findedContactInfos.Count) + { + index = findedContactInfos.Count; + } + } + } + _log.Info("ImportContactsData. Contacts infos saved"); + #endregion + + Percentage += 12.5; + + #region Check Cancel flag | Insert Operation InCache + if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) + { + ImportDataCache.ResetAll(EntityType.Contact); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + #endregion + + #region Save custom fields -by portions- + + if (findedCustomField.Count != 0) + { + findedCustomField.ForEach(item => item.EntityID = fakeRealContactIdHash[item.EntityID]); + + index = 0; + while (index < findedCustomField.Count) + { + var portion = findedCustomField.Skip(index).Take(DaoIterationStep).ToList();// Get next step + + customFieldDao.SaveList(portion); + + index += DaoIterationStep; + if (index > findedCustomField.Count) + { + index = findedCustomField.Count; + } + } + } + _log.Info("ImportContactsData. Custom fields saved"); + #endregion + + Percentage += 12.5; + + #region Check Cancel flag | Insert Operation InCache + if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) + { + ImportDataCache.ResetAll(EntityType.Contact); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + #endregion + + #region Save tags + + var findedTagsValues = new List(); + + findedTags.Values.ToList().ForEach(t => { findedTagsValues.AddRange(t); }); + findedTagsValues = findedTagsValues.Distinct().ToList(); + + var allTagsForImport = tagDao.GetAndAddTags(EntityType.Contact, findedTagsValues.Distinct().ToArray()); + + foreach (var findedTagKey in findedTags.Keys) + { + var curTagNames = findedTags[findedTagKey]; + var curTagIds = curTagNames.ConvertAll(n => allTagsForImport.ContainsKey(n) ? allTagsForImport[n] : 0).Where(id => id != 0).ToArray(); + + tagDao.AddTagToEntity(EntityType.Contact, fakeRealContactIdHash[findedTagKey], curTagIds); + } + _log.Info("ImportContactsData. Tags saved"); + #endregion + + Percentage += 12.5; + + #region Check Cancel flag | Insert Operation InCache + if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) + { + ImportDataCache.ResetAll(EntityType.Contact); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + #endregion + + Complete(); + } + + private bool _CommonData(int currentIndex, DaoFactory _daoFactory, ref Contact contact, ref Dictionary personFakeIdCompanyNameHash) + { + var firstName = GetPropertyValue("firstName"); + var lastName = GetPropertyValue("lastName"); + var companyName = GetPropertyValue("companyName"); + + if (String.IsNullOrEmpty(firstName) && String.IsNullOrEmpty(lastName) && String.IsNullOrEmpty(companyName)) + return false; + + Percentage += 1.0 * 100 / (ImportFromCSV.MaxRoxCount * 3); + + var listItemDao = _daoFactory.ListItemDao; + + + if (!String.IsNullOrEmpty(firstName) || !String.IsNullOrEmpty(lastName)) + { + var person = new Person + { + ID = currentIndex, + FirstName = !String.IsNullOrEmpty(firstName) ? firstName : lastName, + LastName = !String.IsNullOrEmpty(firstName) ? lastName : String.Empty, + JobTitle = GetPropertyValue("title") + }; + + if (!(String.IsNullOrEmpty(companyName))) + personFakeIdCompanyNameHash.Add(person.ID, companyName); + + contact = person; + } + else + { + contact = new Company + { + ID = currentIndex + }; + + ((Company)contact).CompanyName = companyName; + } + + contact.About = GetPropertyValue("notes"); + contact.ShareType = _importSettings.ShareType; + + var contactStageName = GetPropertyValue("contactStage"); + var contactTypeName = GetPropertyValue("contactType"); + if (!String.IsNullOrEmpty(contactStageName)) + { + var contactStage = listItemDao.GetByTitle(ListType.ContactStatus, contactStageName); + if (contactStage != null) + { + contact.StatusID = contactStage.ID; + } + else + { + contact.StatusID = listItemDao.CreateItem(ListType.ContactStatus, new ListItem(){ + Title = contactStageName, + Color = "#77cf9a", + Description = "" + }); + } + } + + if (!String.IsNullOrEmpty(contactTypeName)) + { + var contactType = listItemDao.GetByTitle(ListType.ContactType, contactTypeName); + if (contactType != null) + { + contact.ContactTypeID = contactType.ID; + } + else + { + contact.ContactTypeID = listItemDao.CreateItem(ListType.ContactType, new ListItem(){ + Title = contactTypeName, + Description = "" + }); + } + } + + return true; + } + + #region Read methods + + private void _ReadTags(ref Dictionary> findedTags, Contact contact) + { + var tag = GetPropertyValue("tag"); + + if (!String.IsNullOrEmpty(tag)) + { + var tagList = tag.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); + tagList.AddRange(_importSettings.Tags); + tagList = tagList.Distinct().ToList(); + findedTags.Add(contact.ID, tagList); + } + else if (_importSettings.Tags.Count != 0) + { + findedTags.Add(contact.ID, _importSettings.Tags); + } + } + + private void _ReadCustomField(JProperty jToken, String propertyValue, Contact contact, ref List findedCustomField, CustomFieldDao customFieldDao) + { + var fieldID = Convert.ToInt32(jToken.Name.Split(new[] { '_' })[1]); + var field = customFieldDao.GetFieldDescription(fieldID); + + if (field != null) + { + findedCustomField.Add(new CustomField + { + EntityID = contact.ID, + EntityType = contact is Person ? EntityType.Person : EntityType.Company, + ID = fieldID, + Value = field.FieldType == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue + }); + } + } + + private void _ReadContactInfo(JProperty jToken, String propertyValue, Contact contact, ref List findedContactInfos, ref List primaryFields, String addressTemplateStr) + { + var nameParts = jToken.Name.Split(new[] { '_' }).Skip(1).ToList(); + var contactInfoType = + (ContactInfoType)Enum.Parse(typeof(ContactInfoType), nameParts[0]); + + if (contactInfoType == ContactInfoType.Email) + { + var validEmails = propertyValue + .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) + .Where(email => email.TestEmailRegex()).ToArray(); + + if(!validEmails.Any()) + return; + + propertyValue = string.Join(",", validEmails); + } + + var category = Convert.ToInt32(nameParts[1]); + + var isPrimary = false; + + if ((contactInfoType == ContactInfoType.Email || + contactInfoType == ContactInfoType.Phone || + contactInfoType == ContactInfoType.Address) && + (!primaryFields.Contains((int)contactInfoType))) + { + isPrimary = true; + + primaryFields.Add((int)contactInfoType); + } + + if (contactInfoType == ContactInfoType.Address) + { + var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), nameParts[2]); + + var findedAddress = + findedContactInfos.Find( + item => + (category == item.Category) && (item.InfoType == ContactInfoType.Address) && + (item.ContactID == contact.ID)); + + if (findedAddress == null) + { + findedAddress = new ContactInfo + { + Category = category, + InfoType = contactInfoType, + Data = addressTemplateStr, + ContactID = contact.ID, + IsPrimary = isPrimary + }; + + findedContactInfos.Add(findedAddress); + } + + var addressParts = JObject.Parse(findedAddress.Data); + + addressParts[addressPart.ToString().ToLower()] = propertyValue; + + findedAddress.Data = addressParts.ToString(); + + return; + } + + var items = propertyValue.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); + + foreach (var item in items) + { + findedContactInfos.Add(new ContactInfo + { + Category = category, + InfoType = contactInfoType, + Data = item, + ContactID = contact.ID, + IsPrimary = isPrimary + }); + + isPrimary = false; + } + } + + #endregion + + private void _DuplicateRecordRuleProcess(DaoFactory _daoFactory, + ref Dictionary findedContacts, + ref Dictionary personFakeIdCompanyNameHash, + ref List findedContactInfos, + ref List findedCustomField, + ref Dictionary> findedTags) + { + var contactDao = _daoFactory.ContactDao; + + _log.Info("_DuplicateRecordRuleProcess. Start"); + + switch (_importSettings.DuplicateRecordRule) + { + case 1: // Skip + { + var emails = findedContactInfos.Where(item => item.InfoType == ContactInfoType.Email).ToList(); + + if (emails.Count == 0) break; + + var index = 0; + while (index < emails.Count) + { + var emailsIteration = emails.Skip(index).Take(DaoIterationStep).ToList();// Get next step + + var duplicateContactsID = contactDao.FindDuplicateByEmail(emailsIteration, false) + .Distinct() + .ToList(); + + if (duplicateContactsID.Count != 0) + { + findedContacts = findedContacts.Where(item => !duplicateContactsID.Contains(item.Key)).ToDictionary(x => x.Key, y => y.Value); + + personFakeIdCompanyNameHash = personFakeIdCompanyNameHash.Where(item => !duplicateContactsID.Contains(item.Key)).ToDictionary(x => x.Key, y => y.Value); + + if (findedContacts.Count == 0) + { + Complete(); + return; + } + + findedContactInfos = findedContactInfos.Where(item => !duplicateContactsID.Contains(item.ContactID)).ToList(); + findedCustomField = findedCustomField.Where(item => !duplicateContactsID.Contains(item.EntityID)).ToList(); + + foreach (var exceptID in duplicateContactsID) + { + if (findedTags.ContainsKey(exceptID)) findedTags.Remove(exceptID); + } + } + + index += DaoIterationStep; + if (index > emails.Count) + { + index = emails.Count; + } + } + } + break; + case 2: // Overwrite + { + var emailContactInfos = findedContactInfos.Where(item => item.InfoType == ContactInfoType.Email).ToList(); + if (emailContactInfos.Count == 0) break; + + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. Start. All emeails count = {0}", emailContactInfos.Count); + + var index = 0; + while (index < emailContactInfos.Count) + { + var emailsIteration = emailContactInfos.Skip(index).Take(DaoIterationStep).ToList();// Get next step + + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. Portion from index = {0}. count = {1}", index, emailsIteration.Count); + var duplicateContactsID = contactDao.FindDuplicateByEmail(emailsIteration, true) + .Distinct() + .ToArray(); + + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. FindDuplicateByEmail result count = {0}", duplicateContactsID.Length); + var deleted = contactDao.DeleteBatchContact(duplicateContactsID); + + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. DeleteBatchContact. Was deleted {0} contacts", deleted != null ? deleted.Count : 0); + + index += DaoIterationStep; + if (index > emailContactInfos.Count) + { + index = emailContactInfos.Count; + } + } + + break; + } + case 3: // Clone + break; + default: + break; + } + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs new file mode 100644 index 00000000000..8f9651a2e24 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -0,0 +1,272 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Linq; +using System.Globalization; + +using ASC.Common.Caching; +using ASC.Common.Security.Authentication; +using ASC.Common.Threading.Progress; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.Data.Storage; +using ASC.Web.CRM.Resources; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Studio.Utility; +using ASC.Common.Logging; +using ASC.Web.CRM.Core; +using Autofac; + +namespace ASC.Web.CRM.Classes +{ + class ImportDataCache + { + public static readonly ICache Cache = AscCache.Default; + + public static String GetStateCacheKey(EntityType entityType, int tenantId = -1) + { + if (tenantId == -1) + { + tenantId = TenantProvider.CurrentTenantID; + } + + return String.Format("{0}:crm:queue:importtocsv:{1}", tenantId.ToString(CultureInfo.InvariantCulture), entityType.ToString()); + } + + public static String GetCancelCacheKey(EntityType entityType, int tenantId = -1) + { + if (tenantId == -1) + { + tenantId = TenantProvider.CurrentTenantID; + } + + return String.Format("{0}:crm:queue:importtocsv:{1}:cancel", tenantId.ToString(CultureInfo.InvariantCulture), entityType.ToString()); + } + + public static ImportDataOperation Get(EntityType entityType) + { + return Cache.Get(GetStateCacheKey(entityType)); + } + + public static void Insert(EntityType entityType,ImportDataOperation data) + { + Cache.Insert(GetStateCacheKey(entityType), data, TimeSpan.FromMinutes(1)); + } + + public static bool CheckCancelFlag(EntityType entityType) + { + var fromCache = Cache.Get(GetCancelCacheKey(entityType)); + + if (!String.IsNullOrEmpty(fromCache)) + return true; + + return false; + + } + + public static void SetCancelFlag(EntityType entityType) + { + Cache.Insert(GetCancelCacheKey(entityType), true, TimeSpan.FromMinutes(1)); + } + + public static void ResetAll(EntityType entityType, int tenantId = -1) + { + Cache.Remove(GetStateCacheKey(entityType, tenantId)); + Cache.Remove(GetCancelCacheKey(entityType, tenantId)); + } + } + + public partial class ImportDataOperation : IProgressItem + { + #region Constructor + + public ImportDataOperation() + : this(EntityType.Contact, String.Empty, String.Empty) + { + } + + public ImportDataOperation(EntityType entityType, String CSVFileURI, String importSettingsJSON) + { + _CSVFileURI = CSVFileURI; + _dataStore = Global.GetStore(); + _tenantID = TenantProvider.CurrentTenantID; + _entityType = entityType; + _author = SecurityContext.CurrentAccount; + + _notifyClient = NotifyClient.Instance; + + Id = String.Format("{0}_{1}", TenantProvider.CurrentTenantID, (int)_entityType); + + _log = LogManager.GetLogger("ASC.CRM"); + + if (!String.IsNullOrEmpty(importSettingsJSON)) + _importSettings = new ImportCSVSettings(importSettingsJSON); + } + + #endregion + + #region Members + + private readonly ILog _log; + + private readonly IDataStore _dataStore; + + private readonly IAccount _author; + + private readonly NotifyClient _notifyClient; + + private readonly int _tenantID; + + private readonly String _CSVFileURI; + + private readonly ImportCSVSettings _importSettings; + + private readonly EntityType _entityType; + + private String[] _columns; + + #endregion + + public override bool Equals(object obj) + { + if (obj == null) return false; + if (!(obj is ImportDataOperation)) return false; + + var dataOperation = (ImportDataOperation)obj; + + if (_tenantID == dataOperation._tenantID && _entityType == dataOperation._entityType) return true; + + return base.Equals(obj); + } + + public override int GetHashCode() + { + return _tenantID.GetHashCode() + _entityType.GetHashCode(); + } + + public object Clone() + { + var cloneObj = new ImportDataOperation + { + Error = Error, + Id = Id, + IsCompleted = IsCompleted, + Percentage = Percentage, + Status = Status + }; + + return cloneObj; + } + + #region Property + + public object Id { get; set; } + + public object Status { get; set; } + + public object Error { get; set; } + + public double Percentage { get; set; } + + public bool IsCompleted { get; set; } + + #endregion + + private String GetPropertyValue(String propertyName) + { + if (_importSettings.ColumnMapping[propertyName] == null) return String.Empty; + + var values = + _importSettings.ColumnMapping[propertyName].Values().ToList().ConvertAll(columnIndex => _columns[columnIndex]); + + values.RemoveAll(item => item == String.Empty); + + return String.Join(",", values.ToArray()); + } + + private void Complete() + { + IsCompleted = true; + + Percentage = 100; + + _log.Debug("Import is completed"); + + _notifyClient.SendAboutImportCompleted(_author.ID, _entityType); + + ImportDataCache.Insert(_entityType, (ImportDataOperation)Clone()); + } + + public void RunJob() + { + try + { + CoreContext.TenantManager.SetCurrentTenant(_tenantID); + SecurityContext.AuthenticateMe(_author); + + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var userCulture = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + + System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; + System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; + + ImportDataCache.Insert(_entityType, (ImportDataOperation) Clone()); + + switch (_entityType) + { + case EntityType.Contact: + ImportContactsData(daoFactory); + break; + case EntityType.Opportunity: + ImportOpportunityData(daoFactory); + break; + case EntityType.Case: + ImportCaseData(daoFactory); + break; + case EntityType.Task: + ImportTaskData(daoFactory); + break; + default: + throw new ArgumentException(CRMErrorsResource.EntityTypeUnknown); + } + } + } + catch (OperationCanceledException) + { + _log.Debug("Queue canceled"); + } + finally + { + ImportDataCache.ResetAll(_entityType, _tenantID); + } + } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs new file mode 100644 index 00000000000..3fc310469d5 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -0,0 +1,367 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Core.Users; +using ASC.Web.CRM.Resources; +using ASC.Web.Studio.Core.Users; +using LumenWorks.Framework.IO.Csv; +using Newtonsoft.Json.Linq; +using ASC.Common.Threading.Progress; +using ASC.CRM.Core.Dao; + +#endregion + +namespace ASC.Web.CRM.Classes +{ + public partial class ImportDataOperation + { + + private void ImportOpportunityData(DaoFactory _daoFactory) + { + var allUsers = ASC.Core.CoreContext.UserManager.GetUsers(EmployeeStatus.All).ToList(); + + using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) + { + int currentIndex = 0; + + var customFieldDao = _daoFactory.CustomFieldDao; + var contactDao = _daoFactory.ContactDao; + var tagDao = _daoFactory.TagDao; + var dealDao = _daoFactory.DealDao; + var dealMilestoneDao = _daoFactory.DealMilestoneDao; + + var findedTags = new Dictionary>(); + var findedCustomField = new List(); + var findedDeals = new List(); + var findedDealMembers = new Dictionary>(); + + var dealMilestones = dealMilestoneDao.GetAll(); + + while (csv.ReadNextRecord()) + { + _columns = csv.GetCurrentRowFields(false); + + var obj = new Deal(); + + obj.ID = currentIndex; + + obj.Title = GetPropertyValue("title"); + + if (String.IsNullOrEmpty(obj.Title)) continue; + + obj.Description = GetPropertyValue("description"); + + var csvResponsibleValue = GetPropertyValue("responsible"); + var responsible = allUsers.Where(n => n.DisplayUserName().Equals(csvResponsibleValue)).FirstOrDefault(); + + if (responsible != null) + obj.ResponsibleID = responsible.ID; + else + obj.ResponsibleID = Constants.LostUser.ID; + + DateTime actualCloseDate; + + DateTime expectedCloseDate; + + if (DateTime.TryParse(GetPropertyValue("actual_close_date"), out actualCloseDate)) + obj.ActualCloseDate = actualCloseDate; + + if (DateTime.TryParse(GetPropertyValue("expected_close_date"), out expectedCloseDate)) + obj.ExpectedCloseDate = expectedCloseDate; + + var currency = CurrencyProvider.Get(GetPropertyValue("bid_currency")); + + if (currency != null) + obj.BidCurrency = currency.Abbreviation; + else + obj.BidCurrency = Global.TenantSettings.DefaultCurrency.Abbreviation; + + decimal bidValue; + + var bidValueStr = GetPropertyValue("bid_amount"); + + if (Decimal.TryParse(bidValueStr, out bidValue)) + obj.BidValue = bidValue; + else + obj.BidValue = 0; + + + var bidTypeStr = GetPropertyValue("bid_type"); + + BidType bidType = BidType.FixedBid; + + if (!String.IsNullOrEmpty(bidTypeStr)) + { + if (String.Compare(CRMDealResource.BidType_FixedBid, bidTypeStr, true) == 0) + bidType = BidType.FixedBid; + else if (String.Compare(CRMDealResource.BidType_PerDay, bidTypeStr, true) == 0) + bidType = BidType.PerDay; + else if (String.Compare(CRMDealResource.BidType_PerHour, bidTypeStr, true) == 0) + bidType = BidType.PerHour; + else if (String.Compare(CRMDealResource.BidType_PerMonth, bidTypeStr, true) == 0) + bidType = BidType.PerMonth; + else if (String.Compare(CRMDealResource.BidType_PerWeek, bidTypeStr, true) == 0) + bidType = BidType.PerWeek; + else if (String.Compare(CRMDealResource.BidType_PerYear, bidTypeStr, true) == 0) + bidType = BidType.PerYear; + } + + obj.BidType = bidType; + + if (obj.BidType != BidType.FixedBid) + { + int perPeriodValue; + + if (int.TryParse(GetPropertyValue("per_period_value"), out perPeriodValue)) + obj.PerPeriodValue = perPeriodValue; + } + + int probabilityOfWinning; + + if (int.TryParse(GetPropertyValue("probability_of_winning"), out probabilityOfWinning)) + obj.DealMilestoneProbability = probabilityOfWinning; + + var dealMilestoneTitle = GetPropertyValue("deal_milestone"); + + var tag = GetPropertyValue("tag"); + + + if (!String.IsNullOrEmpty(tag)) + { + var tagList = tag.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); + tagList.AddRange(_importSettings.Tags); + tagList = tagList.Distinct().ToList(); + findedTags.Add(obj.ID, tagList); + } + else if (_importSettings.Tags.Count != 0) + { + findedTags.Add(obj.ID, _importSettings.Tags); + } + + + if (String.IsNullOrEmpty(dealMilestoneTitle)) + obj.DealMilestoneID = dealMilestones[0].ID; + else + { + var dealMilestone = dealMilestones.Find(item => String.Compare(item.Title, dealMilestoneTitle, true) == 0); + + if (dealMilestone == null) + obj.DealMilestoneID = dealMilestones[0].ID; + else + obj.DealMilestoneID = dealMilestone.ID; + } + + var contactName = GetPropertyValue("client"); + + var localMembersDeal = new List(); + + if (!String.IsNullOrEmpty(contactName)) + { + var contacts = contactDao.GetContactsByName(contactName, true); + + if (contacts.Count > 0) + { + obj.ContactID = contacts[0].ID; + localMembersDeal.Add(obj.ContactID); + } + else + { + contacts = contactDao.GetContactsByName(contactName, false); + if (contacts.Count > 0) + { + obj.ContactID = contacts[0].ID; + localMembersDeal.Add(obj.ContactID); + } + } + + + } + + var members = GetPropertyValue("member"); + + if (!String.IsNullOrEmpty(members)) + { + var membersList = members.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + foreach (var item in membersList) + { + var findedMember = contactDao.GetContactsByName(item, true); + + if (findedMember.Count > 0) + { + localMembersDeal.Add(findedMember[0].ID); + } + else + { + findedMember = _daoFactory.ContactDao.GetContactsByName(item, false); + if (findedMember.Count > 0) + { + localMembersDeal.Add(findedMember[0].ID); + } + } + } + } + + if (localMembersDeal.Count > 0) + findedDealMembers.Add(obj.ID, localMembersDeal); + + + foreach (JProperty jToken in _importSettings.ColumnMapping.Children()) + { + var propertyValue = GetPropertyValue(jToken.Name); + + if (String.IsNullOrEmpty(propertyValue)) continue; + + if (!jToken.Name.StartsWith("customField_")) continue; + + var fieldID = Convert.ToInt32(jToken.Name.Split(new[] { '_' })[1]); + var field = customFieldDao.GetFieldDescription(fieldID); + + if (field != null) + { + findedCustomField.Add(new CustomField + { + EntityID = obj.ID, + EntityType = EntityType.Opportunity, + ID = fieldID, + Value = field.FieldType == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue + }); + } + } + + Percentage += 1.0 * 100 / (ImportFromCSV.MaxRoxCount * 2); + + if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) + { + ImportDataCache.ResetAll(EntityType.Opportunity); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + + + + findedDeals.Add(obj); + + if (currentIndex + 1 > ImportFromCSV.MaxRoxCount) break; + + currentIndex++; + + } + + + Percentage = 50; + + if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) + { + ImportDataCache.ResetAll(EntityType.Opportunity); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + + var newDealIDs = dealDao.SaveDealList(findedDeals); + findedDeals.ForEach(d => d.ID = newDealIDs[d.ID]); + + Percentage += 12.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) + { + ImportDataCache.ResetAll(EntityType.Opportunity); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + + findedCustomField.ForEach(item => item.EntityID = newDealIDs[item.EntityID]); + + customFieldDao.SaveList(findedCustomField); + + Percentage += 12.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) + { + ImportDataCache.ResetAll(EntityType.Opportunity); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + + foreach (var findedDealMemberKey in findedDealMembers.Keys) + { + dealDao.SetMembers(newDealIDs[findedDealMemberKey], findedDealMembers[findedDealMemberKey].ToArray()); + } + + Percentage += 12.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) + { + ImportDataCache.ResetAll(EntityType.Opportunity); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + + foreach (var findedTagKey in findedTags.Keys) + { + tagDao.SetTagToEntity(EntityType.Opportunity, newDealIDs[findedTagKey], findedTags[findedTagKey].ToArray()); + } + + if (_importSettings.IsPrivate) + findedDeals.ForEach(dealItem => CRMSecurity.SetAccessTo(dealItem, _importSettings.AccessList)); + + Percentage += 12.5; + + if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) + { + ImportDataCache.ResetAll(EntityType.Opportunity); + + throw new OperationCanceledException(); + } + + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + + } + + Complete(); + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs new file mode 100644 index 00000000000..4e2b301aa9f --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -0,0 +1,141 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Threading.Progress; +using ASC.CRM.Core.Enums; +using LumenWorks.Framework.IO.Csv; +using Newtonsoft.Json.Linq; +using System; +using System.IO; +using System.Linq; + +namespace ASC.Web.CRM.Classes +{ + + public class ImportFromCSV + { + #region Members + + private static readonly Object _syncObj = new Object(); + + private static readonly ProgressQueue _importQueue = new ProgressQueue(3, TimeSpan.FromSeconds(15), true); + + public static readonly int MaxRoxCount = 10000; + + #endregion + + public static int GetQuotas() + { + return MaxRoxCount; + } + + public static CsvReader CreateCsvReaderInstance(Stream CSVFileStream, ImportCSVSettings importCsvSettings) + { + var result = new CsvReader( + new StreamReader(CSVFileStream, importCsvSettings.Encoding, true), + importCsvSettings.HasHeader, importCsvSettings.DelimiterCharacter, importCsvSettings.QuoteType, '"', '#', ValueTrimmingOptions.UnquotedOnly) { SkipEmptyLines = true, SupportsMultiline = true, DefaultParseErrorAction = ParseErrorAction.AdvanceToNextLine, MissingFieldAction = MissingFieldAction.ReplaceByEmpty }; + + return result; + } + + public static String GetRow(Stream CSVFileStream, int index, String jsonSettings) + { + var importCSVSettings = new ImportCSVSettings(jsonSettings); + + using (CsvReader csv = CreateCsvReaderInstance(CSVFileStream, importCSVSettings)) + { + int countRows = 0; + + index++; + + while (countRows++ != index && csv.ReadNextRecord()) ; + + return new JObject(new JProperty("data", new JArray(csv.GetCurrentRowFields(false).ToArray())), + new JProperty("isMaxIndex", csv.EndOfStream)).ToString(); + } + } + + public static JObject GetInfo(Stream CSVFileStream, String jsonSettings) + { + var importCSVSettings = new ImportCSVSettings(jsonSettings); + + using (CsvReader csv = CreateCsvReaderInstance(CSVFileStream, importCSVSettings)) + { + csv.ReadNextRecord(); + + var firstRowFields = csv.GetCurrentRowFields(false); + + String[] headerRowFields = csv.GetFieldHeaders().ToArray(); + + if (!importCSVSettings.HasHeader) + headerRowFields = firstRowFields; + + return new JObject( + new JProperty("headerColumns", new JArray(headerRowFields)), + new JProperty("firstContactFields", new JArray(firstRowFields)), + new JProperty("isMaxIndex", csv.EndOfStream) + ); + } + } + + public static IProgressItem GetStatus(EntityType entityType) + { + var result = _importQueue.GetStatus(String.Format("{0}_{1}", TenantProvider.CurrentTenantID, (int)entityType)); + + if (result == null) + { + return ImportDataCache.Get(entityType); + } + + return result; + } + + public static IProgressItem Start(EntityType entityType, String CSVFileURI, String importSettingsJSON) + { + lock (_syncObj) + { + var operation = GetStatus(entityType); + + if (operation == null) + { + var fromCache = ImportDataCache.Get(entityType); + + if (fromCache != null) + return fromCache; + + operation = new ImportDataOperation(entityType, CSVFileURI, importSettingsJSON); + + _importQueue.Add(operation); + } + + if (!_importQueue.IsStarted) + _importQueue.Start(x => x.RunJob()); + + return operation; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs new file mode 100644 index 00000000000..60629d2dfc7 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs @@ -0,0 +1,168 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Core.Tenants; +using ASC.Core.Users; +using ASC.CRM.Core.Dao; +using LumenWorks.Framework.IO.Csv; +using ASC.Web.CRM.Resources; + +#endregion + +namespace ASC.Web.CRM.Classes +{ + public partial class ImportDataOperation + { + private void ImportTaskData(DaoFactory _daoFactory) + { + using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) + { + int currentIndex = 0; + + var contactDao = _daoFactory.ContactDao; + var listItemDao = _daoFactory.ListItemDao; + var taskDao = _daoFactory.TaskDao; + + var findedTasks = new List(); + var taskCategories = listItemDao.GetItems(ListType.TaskCategory); + + var allUsers = ASC.Core.CoreContext.UserManager.GetUsers(EmployeeStatus.All).ToList(); + + while (csv.ReadNextRecord()) + { + _columns = csv.GetCurrentRowFields(false); + + var obj = new Task(); + + obj.ID = currentIndex; + + obj.Title = GetPropertyValue("title"); + + if (String.IsNullOrEmpty(obj.Title)) continue; + + obj.Description = GetPropertyValue("description"); + + DateTime deadline; + + if (DateTime.TryParse(GetPropertyValue("due_date"), out deadline)) + obj.DeadLine = deadline; + else + obj.DeadLine = TenantUtil.DateTimeNow(); + + var csvResponsibleValue = GetPropertyValue("responsible"); + var responsible = allUsers.Where(n => n.DisplayUserName().Equals(csvResponsibleValue)).FirstOrDefault(); + + if (responsible != null) + obj.ResponsibleID = responsible.ID; + else + obj.ResponsibleID = Constants.LostUser.ID; + + var categoryTitle = GetPropertyValue("taskCategory"); + + if (!String.IsNullOrEmpty(categoryTitle)) + { + var findedCategory = taskCategories.Find(item => String.Compare(item.Title, categoryTitle) == 0); + + if (findedCategory == null) + { + obj.CategoryID = taskCategories[0].ID; + } + else + obj.CategoryID = findedCategory.ID; + } + else + obj.CategoryID = taskCategories[0].ID; + + var contactName = GetPropertyValue("contact"); + + if (!String.IsNullOrEmpty(contactName)) + { + var contacts = contactDao.GetContactsByName(contactName, true); + + if (contacts.Count > 0) + { + obj.ContactID = contacts[0].ID; + } + else + { + contacts = contactDao.GetContactsByName(contactName, false); + if (contacts.Count > 0) + { + obj.ContactID = contacts[0].ID; + } + } + } + + obj.IsClosed = false; + + var taskStatus = GetPropertyValue("status"); + + if (!String.IsNullOrEmpty(taskStatus)) + { + if (String.Compare(taskStatus, CRMTaskResource.TaskStatus_Closed, true) == 0) + obj.IsClosed = true; + + } + + var alertValue = GetPropertyValue("alertValue"); + int alertIntVal = 0; + + if (Int32.TryParse(alertValue, out alertIntVal)) + obj.AlertValue = alertIntVal; + else + obj.AlertValue = 0; + + + findedTasks.Add(obj); + + if ((currentIndex + 1) > ImportFromCSV.MaxRoxCount) break; + + currentIndex++; + + } + + Percentage = 50; + + taskDao.SaveTaskList(findedTasks); + + Percentage += 12.5; + + Complete(); + + } + + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs new file mode 100644 index 00000000000..ef721b11030 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -0,0 +1,1009 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.Common.Caching; +using ASC.Common.Threading.Progress; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.CRM.Resources; +using ASC.Web.Studio.Utility; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Web.Configuration; +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Tenants; +using ASC.Web.CRM.Core; +using ASC.Web.Files.Api; +using Autofac; +using MailKit; +using MailKit.Net.Smtp; +using MailKit.Security; +using MimeKit; +using File = System.IO.File; +using SmtpClient = MailKit.Net.Smtp.SmtpClient; + +#endregion + +namespace ASC.Web.CRM.Classes +{ + + class SendBatchEmailsOperation : IProgressItem, IDisposable + { + private readonly bool _storeInHistory; + private readonly ILog _log; + private readonly SMTPServerSetting _smtpSetting; + private readonly Guid _currUser; + private readonly int _tenantID; + private readonly List _contactID; + private readonly String _subject; + private readonly String _bodyTempate; + private readonly List _fileID; + private int historyCategory; + private double _exactPercentageValue = 0; + + + public object Id { get; set; } + public object Status { get; set; } + public object Error { get; set; } + public double Percentage { get; set; } + public bool IsCompleted { get; set; } + + + private SendBatchEmailsOperation() + : this(new List(), new List(), String.Empty, String.Empty, false) + { + } + + public SendBatchEmailsOperation( + List fileID, + List contactID, + String subject, + String bodyTempate, + bool storeInHistory) + { + Id = TenantProvider.CurrentTenantID; + Percentage = 0; + _fileID = fileID; + _contactID = contactID; + _subject = subject; + _bodyTempate = bodyTempate; + + _log = LogManager.GetLogger("ASC.CRM.MailSender"); + _tenantID = TenantProvider.CurrentTenantID; + _smtpSetting = Global.TenantSettings.SMTPServerSetting; + _currUser = SecurityContext.CurrentAccount.ID; + _storeInHistory = storeInHistory; + + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = 0, + DeliveryCount = 0 + }; + } + + private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) + { + if (contactID == 0 || String.IsNullOrEmpty(content)) return; + + var historyEvent = new RelationshipEvent() + { + ContactID = contactID, + Content = content, + CreateBy = _currUser, + CreateOn = TenantUtil.DateTimeNow(), + }; + if (historyCategory == 0) + { + var listItemDao = _daoFactory.ListItemDao; + + // HACK + var listItem = listItemDao.GetItems(ListType.HistoryCategory).Find(item => item.AdditionalParams == "event_category_email.png"); + if (listItem == null) + { + listItemDao.CreateItem( + ListType.HistoryCategory, + new ListItem { AdditionalParams = "event_category_email.png", Title = CRMCommonResource.HistoryCategory_Note }); + } + historyCategory = listItem.ID; + } + + historyEvent.CategoryID = historyCategory; + var relationshipEventDao = _daoFactory.RelationshipEventDao; + historyEvent = relationshipEventDao.CreateItem(historyEvent); + + if (historyEvent.ID > 0 && _fileID != null && _fileID.Count > 0) + { + relationshipEventDao.AttachFiles(historyEvent.ID, _fileID.ToArray()); + } + } + + public void RunJob() + { + SmtpClient smtpClient = null; + try + { + CoreContext.TenantManager.SetCurrentTenant(_tenantID); + SecurityContext.AuthenticateMe(CoreContext.Authentication.GetAccountByID(_currUser)); + + smtpClient = GetSmtpClient(); + + using (var scope = DIHelper.Resolve()) + { + var _daoFactory = scope.Resolve(); + var userCulture = CoreContext.UserManager.GetUsers(_currUser).GetCulture(); + + Thread.CurrentThread.CurrentCulture = userCulture; + Thread.CurrentThread.CurrentUICulture = userCulture; + + var contactCount = _contactID.Count; + + if (contactCount == 0) + { + Complete(); + return; + } + + MailSenderDataCache.Insert((SendBatchEmailsOperation) Clone()); + + var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); + var filePaths = new List(); + using (var fileDao = FilesIntegration.GetFileDao()) + { + foreach (var fileID in _fileID) + { + var fileObj = fileDao.GetFile(fileID); + if (fileObj == null) continue; + using (var fileStream = fileDao.GetFileStream(fileObj)) + { + var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), + "crm/files/mailsender/"); + if (!Directory.Exists(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + var filePath = Path.Combine(directoryPath, fileObj.Title); + using (var newFileStream = File.Create(filePath)) + { + fileStream.StreamCopyTo(newFileStream); + } + filePaths.Add(filePath); + } + } + } + + var templateManager = new MailTemplateManager(_daoFactory); + var deliveryCount = 0; + + try + { + Error = string.Empty; + foreach (var contactID in _contactID) + { + _exactPercentageValue += 100.0 / contactCount; + Percentage = Math.Round(_exactPercentageValue); + + if (IsCompleted) break; // User selected cancel + + var contactInfoDao = _daoFactory.ContactInfoDao; + var startDate = DateTime.Now; + + var contactEmails = contactInfoDao.GetList(contactID, ContactInfoType.Email, null, true); + if (contactEmails.Count == 0) + { + continue; + } + + var recipientEmail = contactEmails[0].Data; + + if (!recipientEmail.TestEmailRegex()) + { + Error += string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail) + + "
    "; + continue; + } + + var to = new MailboxAddress(recipientEmail); + + var mimeMessage = new MimeMessage + { + Subject = _subject + }; + + mimeMessage.From.Add(from); + mimeMessage.To.Add(to); + + var bodyBuilder = new BodyBuilder + { + HtmlBody = templateManager.Apply(_bodyTempate, contactID) + }; + + foreach (var filePath in filePaths) + { + bodyBuilder.Attachments.Add(filePath); + } + + mimeMessage.Body = bodyBuilder.ToMessageBody(); + + mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); + + _log.Debug(GetLoggerRow(mimeMessage)); + + var success = false; + + try + { + smtpClient.Send(mimeMessage); + + success = true; + } + catch (SmtpCommandException ex) + { + _log.Error(Error, ex); + + Error += string.Format(CRMCommonResource.MailSender_FailedDeliverException, recipientEmail) + "
    "; + } + + if (success) + { + if (_storeInHistory) + { + AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), _daoFactory); + } + + var endDate = DateTime.Now; + var waitInterval = endDate.Subtract(startDate); + + deliveryCount++; + + var estimatedTime = + TimeSpan.FromTicks(waitInterval.Ticks*(_contactID.Count - deliveryCount)); + + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = estimatedTime.ToString(), + DeliveryCount = deliveryCount + }; + } + + if (MailSenderDataCache.CheckCancelFlag()) + { + MailSenderDataCache.ResetAll(); + + throw new OperationCanceledException(); + } + + MailSenderDataCache.Insert((SendBatchEmailsOperation) Clone()); + + if (Percentage > 100) + { + Percentage = 100; + + if (MailSenderDataCache.CheckCancelFlag()) + { + MailSenderDataCache.ResetAll(); + + throw new OperationCanceledException(); + } + + MailSenderDataCache.Insert((SendBatchEmailsOperation) Clone()); + + } + } + } + catch (OperationCanceledException) + { + _log.Debug("cancel mail sender"); + } + finally + { + foreach (var filePath in filePaths) + { + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + } + } + + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = TimeSpan.Zero.ToString(), + DeliveryCount = deliveryCount + }; + } + } + catch (SocketException e) + { + Error = e.Message; + _log.Error(Error); + } + finally + { + if (smtpClient != null) + { + smtpClient.Dispose(); + } + Complete(); + } + } + + public static string GetLoggerRow(MimeMessage mailMessage) + { + if (mailMessage == null) + return String.Empty; + + var result = new StringBuilder(); + + result.AppendLine("From:" + mailMessage.From); + result.AppendLine("To:" + mailMessage.To[0]); + result.AppendLine("Subject:" + mailMessage.Subject); + result.AppendLine("Body:" + mailMessage.Body); + result.AppendLine("TenantID:" + TenantProvider.CurrentTenantID); + + foreach (var attachment in mailMessage.Attachments) + { + result.AppendLine("Attachment: " + attachment.ContentDisposition.FileName); + } + + return result.ToString(); + } + + public object Clone() + { + var cloneObj = new SendBatchEmailsOperation(); + + cloneObj.Error = Error; + cloneObj.Id = Id; + cloneObj.IsCompleted = IsCompleted; + cloneObj.Percentage = Percentage; + cloneObj.Status = Status; + + return cloneObj; + } + + private void DeleteFiles() + { + if (_fileID == null || _fileID.Count == 0) return; + + using (var fileDao = FilesIntegration.GetFileDao()) + { + foreach (var fileID in _fileID) + { + var fileObj = fileDao.GetFile(fileID); + if (fileObj == null) continue; + + fileDao.DeleteFile(fileObj.ID); + } + } + } + + private SmtpClient GetSmtpClient() + { + var client = new SmtpClient + { + ServerCertificateValidationCallback = (sender, certificate, chain, errors) => + WorkContext.IsMono || MailKit.MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), + Timeout = (int) TimeSpan.FromSeconds(30).TotalMilliseconds + }; + + client.Connect(_smtpSetting.Host, _smtpSetting.Port, + _smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); + + if (_smtpSetting.RequiredHostAuthentication) + { + client.Authenticate(_smtpSetting.HostLogin, _smtpSetting.HostPassword); + } + + return client; + } + + private void Complete() + { + IsCompleted = true; + Percentage = 100; + _log.Debug("Completed"); + + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); + + Thread.Sleep(10000); + MailSenderDataCache.ResetAll(); + } + + public override bool Equals(object obj) + { + if (obj == null || !(obj is SendBatchEmailsOperation)) return false; + + var curOperation = (SendBatchEmailsOperation)obj; + return (curOperation.Id == Id) && (curOperation._tenantID == _tenantID); + } + + public override int GetHashCode() + { + return Id.GetHashCode() ^ _tenantID.GetHashCode(); + } + + public void Dispose() + { + DeleteFiles(); + } + } + + class MailSenderDataCache + { + public static readonly ICache Cache = AscCache.Default; + + public static String GetStateCacheKey() + { + return String.Format("{0}:crm:queue:sendbatchemails", TenantProvider.CurrentTenantID.ToString()); + } + + public static String GetCancelCacheKey() + { + return String.Format("{0}:crm:queue:sendbatchemails:cancel", TenantProvider.CurrentTenantID.ToString()); + } + + public static SendBatchEmailsOperation Get() + { + return Cache.Get(GetStateCacheKey()); + } + + public static void Insert(SendBatchEmailsOperation data) + { + Cache.Insert(GetStateCacheKey(), data, TimeSpan.FromMinutes(1)); + } + + public static bool CheckCancelFlag() + { + var fromCache = Cache.Get(GetCancelCacheKey()); + + if (!String.IsNullOrEmpty(fromCache)) + return true; + + return false; + + } + + public static void SetCancelFlag() + { + Cache.Insert(GetCancelCacheKey(), "true", TimeSpan.FromMinutes(1)); + } + + public static void ResetAll() + { + Cache.Remove(GetStateCacheKey()); + Cache.Remove(GetCancelCacheKey()); + } + } + + public class MailSender + { + private static readonly Object _syncObj = new Object(); + private static readonly ProgressQueue _mailQueue = new ProgressQueue(2, TimeSpan.FromSeconds(60), true); + private static readonly int quotas = 50; + + + static MailSender() + { + int parsed; + if (int.TryParse(WebConfigurationManager.AppSettings["crm.mailsender.quotas"], out parsed)) + { + quotas = parsed; + } + } + + public static int GetQuotas() + { + return quotas; + } + + public static IProgressItem Start(List fileID, List contactID, String subject, String bodyTemplate, bool storeInHistory) + { + lock (_syncObj) + { + var operation = _mailQueue.GetStatus(TenantProvider.CurrentTenantID); + + if (operation == null) + { + var mailSender = MailSenderDataCache.Get(); + + if (mailSender != null) + return mailSender; + } + + if (operation == null) + { + if (fileID == null) + { + fileID = new List(); + } + if (contactID == null || contactID.Count == 0 || + String.IsNullOrEmpty(subject) || String.IsNullOrEmpty(bodyTemplate)) + { + return null; + } + + if (contactID.Count > GetQuotas()) + { + contactID = contactID.Take(GetQuotas()).ToList(); + } + + operation = new SendBatchEmailsOperation(fileID, contactID, subject, bodyTemplate, storeInHistory); + _mailQueue.Add(operation); + } + + if (!_mailQueue.IsStarted) + { + _mailQueue.Start(x => x.RunJob()); + } + return operation; + } + } + + private static SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) + { + var client = new SmtpClient + { + ServerCertificateValidationCallback = (sender, certificate, chain, errors) => MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), + Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds + }; + + client.Connect(smtpSetting.Host, smtpSetting.Port, + smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); + + if (smtpSetting.RequiredHostAuthentication) + { + client.Authenticate(smtpSetting.HostLogin, smtpSetting.HostPassword); + } + + return client; + } + + public static void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) + { + var log = LogManager.GetLogger("ASC.CRM.MailSender"); + + if (!recipientEmail.TestEmailRegex()) + { + throw new Exception(string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail)); + } + + CoreContext.TenantManager.SetCurrentTenant(TenantProvider.CurrentTenantID); + + var smtpSetting = Global.TenantSettings.SMTPServerSetting; + + ThreadPool.QueueUserWorkItem(_ => + { + try + { + var toAddress = new MailboxAddress(recipientEmail); + var fromAddress = new MailboxAddress(smtpSetting.SenderDisplayName, smtpSetting.SenderEmailAddress); + + var mimeMessage = new MimeMessage + { + Subject = mailSubj + }; + + mimeMessage.From.Add(fromAddress); + + mimeMessage.To.Add(toAddress); + + var bodyBuilder = new BodyBuilder + { + TextBody = mailBody + }; + + mimeMessage.Body = bodyBuilder.ToMessageBody(); + + mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); + + using (var smtpClient = GetSmtpClient(smtpSetting)) + { + smtpClient.Send(FormatOptions.Default, mimeMessage, CancellationToken.None); + } + } + catch (Exception ex) + { + log.Error(ex); + } + }); + } + + public static IProgressItem GetStatus() + { + var result = _mailQueue.GetStatus(TenantProvider.CurrentTenantID); + + if (result == null) + return MailSenderDataCache.Get(); + + return result; + } + + public static void Cancel() + { + lock (_syncObj) + { + var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantProvider.CurrentTenantID); + + if (findedItem.Any()) + { + _mailQueue.Remove(findedItem.ElementAt(0)); + + MailSenderDataCache.ResetAll(); + } + else + { + MailSenderDataCache.SetCancelFlag(); + } + } + } + } + + [Serializable] + [DataContract] + public class MailTemplateTag + { + [DataMember(Name = "sysname")] + public String SysName { get; set; } + + [DataMember(Name = "display_name")] + public String DisplayName { get; set; } + + [DataMember(Name = "category")] + public String Category { get; set; } + + [DataMember(Name = "is_company")] + public bool isCompany { get; set; } + + [DataMember(Name = "name")] + public String Name { get; set; } + + + } + + public class MailTemplateManager + { + + #region Members + + private readonly Dictionary> _templateTagsCache = new Dictionary>(); + + private readonly DaoFactory _daoFactory; + + #endregion + + #region Constructor + + public MailTemplateManager(DaoFactory daoFactory) + { + _daoFactory = daoFactory; + } + + #endregion + + private IEnumerable GetTagsFrom(String template) + { + if (_templateTagsCache.ContainsKey(template)) return _templateTagsCache[template]; + + var tags = GetAllTags(); + + var result = new List(); + + var _regex = new Regex("\\$\\((Person|Company)\\.[^<>\\)]*\\)"); + + + if (!_regex.IsMatch(template)) + return new List(); + + foreach (Match match in _regex.Matches(template)) + { + var findedTag = tags.Find(item => String.Compare(item.Name, match.Value) == 0); + + if (findedTag == null) continue; + + if (!result.Contains(findedTag)) + result.Add(findedTag); + } + + _templateTagsCache.Add(template, result); + + return result; + } + + private String Apply(String template, IEnumerable templateTags, int contactID) + { + var result = template; + + + var contactDao = _daoFactory.ContactDao; + var contactInfoDao = _daoFactory.ContactInfoDao; + var customFieldDao = _daoFactory.CustomFieldDao; + + var contact = contactDao.GetByID(contactID); + + if (contact == null) + throw new ArgumentException(CRMErrorsResource.ContactNotFound); + + foreach (var tag in templateTags) + { + var tagParts = tag.SysName.Split(new[] { '_' }); + + var source = tagParts[0]; + + var tagValue = String.Empty; + + switch (source) + { + case "common": + + if (contact is Person) + { + + var person = (Person)contact; + + switch (tagParts[1]) + { + + case "firstName": + tagValue = person.FirstName; + + break; + case "lastName": + tagValue = person.LastName; + + break; + case "jobTitle": + tagValue = person.JobTitle; + break; + case "companyName": + var relativeCompany = contactDao.GetByID(((Person)contact).CompanyID); + + if (relativeCompany != null) + tagValue = relativeCompany.GetTitle(); + + + break; + default: + tagValue = String.Empty; + break; + + } + + } + else + { + + var company = (Company)contact; + + switch (tagParts[1]) + { + case "companyName": + tagValue = company.CompanyName; + break; + default: + tagValue = String.Empty; + break; + } + } + + break; + case "customField": + var tagID = Convert.ToInt32(tagParts[tagParts.Length - 1]); + + var entityType = contact is Company ? EntityType.Company : EntityType.Person; + + tagValue = customFieldDao.GetValue(entityType, contactID, tagID); + + break; + case "contactInfo": + var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), tagParts[1]); + var category = Convert.ToInt32(tagParts[2]); + var contactInfos = contactInfoDao.GetList(contactID, contactInfoType, category, true); + + if (contactInfos == null || contactInfos.Count == 0) break; + + var contactInfo = contactInfos[0]; + + if (contactInfoType == ContactInfoType.Address) + { + var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), tagParts[3]); + + tagValue = JObject.Parse(contactInfo.Data)[addressPart.ToString().ToLower()].Value(); + + } + else + tagValue = contactInfo.Data; + + break; + default: + throw new ArgumentException(tag.SysName); + } + + result = result.Replace(tag.Name, tagValue); + } + + return result; + } + + public String Apply(String template, int contactID) + { + return Apply(template, GetTagsFrom(template), contactID); + } + + private String ToTagName(String value, bool isCompany) + { + return String.Format("$({0}.{1})", isCompany ? "Company" : "Person", value); + } + + private List GetAllTags() + { + return GetTags(true).Union(GetTags(false)).ToList(); + } + + public List GetTags(bool isCompany) + { + + var result = new List(); + + if (isCompany) + { + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.CompanyName, + SysName = "common_companyName", + Category = CRMContactResource.GeneralInformation, + isCompany = isCompany, + Name = ToTagName("Company Name", isCompany) + }); + + } + else + { + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.FirstName, + SysName = "common_firstName", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("First Name", isCompany) + }); + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.LastName, + SysName = "common_lastName", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("Last Name", isCompany) + }); + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.JobTitle, + SysName = "common_jobTitle", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("Job Title", isCompany) + }); + + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.CompanyName, + SysName = "common_companyName", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("Company Name", isCompany) + }); + + } + + #region Contact Infos + + foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) + { + + var localName = String.Format("contactInfo_{0}_{1}", infoTypeEnum, ContactInfo.GetDefaultCategory(infoTypeEnum)); + var localTitle = infoTypeEnum.ToLocalizedString(); + + if (infoTypeEnum == ContactInfoType.Address) + foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) + result.Add(new MailTemplateTag + { + SysName = String.Format(localName + "_{0}_{1}", addressPartEnum, (int)AddressCategory.Work), + DisplayName = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString()), + Category = CRMContactResource.GeneralInformation, + isCompany = isCompany, + Name = ToTagName(String.Format("{0} {1}", infoTypeEnum.ToString(), addressPartEnum.ToString()), isCompany) + }); + else + result.Add(new MailTemplateTag + { + SysName = localName, + DisplayName = localTitle, + Category = CRMContactResource.GeneralInformation, + isCompany = isCompany, + Name = ToTagName(infoTypeEnum.ToString(), isCompany) + }); + } + + #endregion + + #region Custom Fields + + var entityType = isCompany ? EntityType.Company : EntityType.Person; + + var customFieldsDao = _daoFactory.CustomFieldDao; + + var customFields = customFieldsDao.GetFieldsDescription(entityType); + + var category = CRMContactResource.GeneralInformation; + + foreach (var customField in customFields) + { + if (customField.FieldType == CustomFieldType.SelectBox) continue; + if (customField.FieldType == CustomFieldType.CheckBox) continue; + + if (customField.FieldType == CustomFieldType.Heading) + { + if (!String.IsNullOrEmpty(customField.Label)) + category = customField.Label; + + continue; + } + + result.Add(new MailTemplateTag + { + SysName = "customField_" + customField.ID, + DisplayName = customField.Label.HtmlEncode(), + Category = category, + isCompany = isCompany, + Name = ToTagName(customField.Label, isCompany) + }); + } + + #endregion + + return result; + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs new file mode 100644 index 00000000000..d78d58ebf98 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -0,0 +1,720 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Web; +using System.Xml; +using ASC.Common.Logging; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Resources; +using ASC.Web.CRM.Core; +using ASC.Web.CRM.Resources; +using ASC.Web.Files.Services.DocumentService; +using Autofac; +using Ionic.Zip; +using File = ASC.Files.Core.File; + +namespace ASC.Web.CRM.Classes +{ + public class PdfCreator + { + private static Stream Template + { + get + { + var bytes = FileHelper.ReadBytesFromEmbeddedResource("ASC.Web.CRM.InvoiceTemplates.template.docx"); + return new MemoryStream(bytes); + } + } + private const string FormatPdf = ".pdf"; + private const string FormatDocx = ".docx"; + private const string DocumentXml = "word/document.xml"; + private const string DocumentLogoImage = "word/media/logo.jpeg"; + + + public static void CreateAndSaveFile(int invoiceId) + { + var log = LogManager.GetLogger("ASC.CRM"); + log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}", invoiceId); + try + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + + var invoice = daoFactory.InvoiceDao.GetByID(invoiceId); + if (invoice == null) + { + log.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); + return; + } + + log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. Convertation", invoiceId); + + string urlToFile; + using (var docxStream = GetStreamDocx(invoice)) + { + urlToFile = GetUrlToFile(docxStream); + } + + log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, + urlToFile); + + var file = new File + { + Title = string.Format("{0}{1}", invoice.Number, FormatPdf), + FolderID = daoFactory.FileDao.GetRoot() + }; + + var request = WebRequest.Create(urlToFile); + using (var response = request.GetResponse()) + using (var stream = response.GetResponseStream()) + { + file.ContentLength = response.ContentLength; + + log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); + file = daoFactory.FileDao.SaveFile(file, stream); + } + + if (file == null) + { + throw new Exception(CRMErrorsResource.FileCreateError); + } + + invoice.FileID = Int32.Parse(file.ID.ToString()); + + log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); + daoFactory.InvoiceDao.UpdateInvoiceFileID(invoice.ID, invoice.FileID); + + log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); + daoFactory.RelationshipEventDao.AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] {invoice.FileID}); + } + } + catch (Exception e) + { + log.Error(e); + } + } + + public static File CreateFile(Invoice data, DaoFactory daoFactory) + { + var log = LogManager.GetLogger("ASC.CRM"); + try + { + using (var docxStream = GetStreamDocx(data)) + { + var urlToFile = GetUrlToFile(docxStream); + return SaveFile(data, urlToFile, daoFactory); + } + } + catch (Exception e) + { + log.Error(e); + throw; + } + } + + private static string GetUrlToFile(Stream docxStream) + { + var externalUri = Files.Classes.PathProvider.GetTempUrl(docxStream, FormatDocx); + externalUri = DocumentServiceConnector.ReplaceCommunityAdress(externalUri); + LogManager.GetLogger("ASC.CRM").DebugFormat("PdfCreator. GetUrlToFile. externalUri = {0}", externalUri); + + var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); + string urlToFile; + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, false, out urlToFile); + + LogManager.GetLogger("ASC.CRM").DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); + return urlToFile; + } + + public static ConverterData StartCreationFileAsync(Invoice data) + { + using (var docxStream = GetStreamDocx(data)) + { + var externalUri = Files.Classes.PathProvider.GetTempUrl(docxStream, FormatDocx); + externalUri = DocumentServiceConnector.ReplaceCommunityAdress(externalUri); + + var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); + string urlToFile; + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, true, out urlToFile); + + return new ConverterData + { + StorageUrl = externalUri, + RevisionId = revisionId, + InvoiceId = data.ID, + }; + } + } + + public static File GetConvertedFile(ConverterData data, DaoFactory daoFactory) + { + if (string.IsNullOrEmpty(data.StorageUrl) || string.IsNullOrEmpty(data.RevisionId)) + { + return null; + } + + string urlToFile; + DocumentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, true, out urlToFile); + + if (string.IsNullOrEmpty(urlToFile)) + { + return null; + } + + var invoice = daoFactory.InvoiceDao.GetByID(data.InvoiceId); + + return SaveFile(invoice, urlToFile, daoFactory); + } + + private static File SaveFile(Invoice data, string url, DaoFactory daoFactory) + { + File file = null; + + var request = (HttpWebRequest)WebRequest.Create(url); + + using (var response = request.GetResponse()) + { + using (var stream = response.GetResponseStream()) + { + if (stream != null) + { + var document = new File + { + Title = string.Format("{0}{1}", data.Number, FormatPdf), + FolderID = daoFactory.FileDao.GetRoot(), + ContentLength = response.ContentLength + }; + + if (data.GetInvoiceFile(daoFactory) != null) + { + document.ID = data.FileID; + } + + file = daoFactory.FileDao.SaveFile(document, stream); + } + } + } + + return file; + } + + private static Stream GetStreamDocx(Invoice data) + { + var invoiceData = InvoiceFormattedData.GetData(data, 0, 0); + var logo = new byte[] {}; + + if (!string.IsNullOrEmpty(invoiceData.LogoBase64)) + { + logo = Convert.FromBase64String(invoiceData.LogoBase64); + } + else if (invoiceData.LogoBase64Id != 0) + { + logo = Convert.FromBase64String(OrganisationLogoManager.GetOrganisationLogoBase64(invoiceData.LogoBase64Id)); + } + + using (var zip = ZipFile.Read(Template)) + { + var documentXmlStream = new MemoryStream(); + foreach (var entry in zip.Entries.Where(entry => entry.FileName == DocumentXml)) + { + entry.Extract(documentXmlStream); + } + documentXmlStream.Position = 0; + zip.RemoveEntry(DocumentXml); + var document = new XmlDocument(); + document.Load(documentXmlStream); + var documentStr = GenerateDocumentXml(document, invoiceData, logo); + zip.AddEntry(DocumentXml, documentStr, Encoding.UTF8); + + if (logo.Length > 0) + { + zip.UpdateEntry(DocumentLogoImage, logo); + } + + var streamZip = new MemoryStream(); + zip.Save(streamZip); + streamZip.Seek(0, SeekOrigin.Begin); + streamZip.Flush(); + return streamZip; + } + + } + + private static string GenerateDocumentXml(XmlDocument xDocument, InvoiceFormattedData data, byte[] logo) + { + XmlNodeList nodeList; + XmlNode parent; + XmlNode child; + + + #region Seller + + nodeList = xDocument.SelectNodes("//*[@ascid='seller']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + if (data.Seller == null) + { + parent.RemoveAll(); + } + else + { + var newText = parent.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(data.Seller.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(data.Seller.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (parent.ParentNode != null) + { + if (newEl.DocumentElement != null) + { + parent.ParentNode.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), parent); + } + parent.ParentNode.RemoveChild(parent); + } + } + } + + #endregion + + + #region Logo + + nodeList = xDocument.SelectNodes("//*[@ascid='logo']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + if (logo.Length <= 0) + { + parent.RemoveAll(); + } + else + { + using (var stream = new MemoryStream(logo)) + using (var img = System.Drawing.Image.FromStream(stream)) + { + var cx = img.Width*9525; //1px = 9525emu + var cy = img.Height*9525; //1px = 9525emu + + var newText = parent.CloneNode(true).OuterXml; + newText = newText + .Replace("${width}", cx.ToString(CultureInfo.InvariantCulture)) + .Replace("${height}", cy.ToString(CultureInfo.InvariantCulture)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (parent.ParentNode != null) + { + if (newEl.DocumentElement != null) + { + parent.ParentNode.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), + parent); + } + parent.ParentNode.RemoveChild(parent); + } + } + } + } + + #endregion + + + #region Number + + nodeList = xDocument.SelectNodes("//*[@ascid='number']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + if (data.Number == null) + { + parent.RemoveAll(); + } + else + { + var newText = parent.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(data.Number.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(data.Number.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (parent.ParentNode != null) + { + if (newEl.DocumentElement != null) + { + parent.ParentNode.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), parent); + } + parent.ParentNode.RemoveChild(parent); + } + } + } + + #endregion + + + #region Invoice + + nodeList = xDocument.SelectNodes("//*[@ascid='invoice']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + nodeList = xDocument.SelectNodes("//*[@ascid='invoice']//*[@ascid='row']"); + child = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (child != null) + { + if (data.Invoice == null || data.Invoice.Count <= 0) + { + if (parent.ParentNode != null) + { + parent.ParentNode.RemoveChild(parent); + } + } + else + { + foreach (var line in data.Invoice) + { + var newText = child.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(line.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(line.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (newEl.DocumentElement != null) + { + parent.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), child); + } + } + parent.RemoveChild(child); + } + } + } + + #endregion + + + #region Customer + + nodeList = xDocument.SelectNodes("//*[@ascid='customer']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + if (data.Customer == null) + { + if (parent.ParentNode != null) + { + parent.ParentNode.RemoveChild(parent); + } + } + else + { + var newText = parent.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(data.Customer.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(data.Customer.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (parent.ParentNode != null) + { + if (newEl.DocumentElement != null) + { + parent.ParentNode.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), parent); + } + parent.ParentNode.RemoveChild(parent); + } + } + } + + #endregion + + + nodeList = xDocument.SelectNodes("//*[@ascid='table']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + #region TableHeaderRow + + nodeList = xDocument.SelectNodes("//*[@ascid='table']//*[@ascid='headerRow']"); + child = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (child != null) + { + if (data.TableHeaderRow == null || data.TableHeaderRow.Count <= 0) + { + if (parent.ParentNode != null) + parent.ParentNode.RemoveChild(parent); + } + else + { + var newText = child.CloneNode(true).OuterXml; + for (var i = 0; i < data.TableHeaderRow.Count; i++) + { + newText = newText + .Replace("${label" + i + "}", EncodeAndReplaceLineBreaks(data.TableHeaderRow[i])); + } + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (newEl.DocumentElement != null) + { + parent.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), child); + } + parent.RemoveChild(child); + } + } + + #endregion + + + #region TableBodyRows + + nodeList = xDocument.SelectNodes("//*[@ascid='table']//*[@ascid='bodyRow']"); + child = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (child != null) + { + if (data.TableBodyRows == null || data.TableBodyRows.Count <= 0) + { + if (parent.ParentNode != null) + parent.ParentNode.RemoveChild(parent); + } + else + { + foreach (var line in data.TableBodyRows) + { + var newText = child.CloneNode(true).OuterXml; + for (var i = 0; i < line.Count; i++) + { + newText = newText + .Replace("${value" + i + "}", EncodeAndReplaceLineBreaks(line[i])); + } + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (newEl.DocumentElement != null) + { + parent.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), child); + } + } + parent.RemoveChild(child); + } + } + + #endregion + + + #region TableFooterRows + + nodeList = xDocument.SelectNodes("//*[@ascid='table']//*[@ascid='footerRow']"); + child = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (child != null) + { + if (data.TableFooterRows == null || data.TableFooterRows.Count <= 0) + { + if (parent.ParentNode != null) + parent.ParentNode.RemoveChild(parent); + } + else + { + foreach (var line in data.TableFooterRows) + { + var newText = child.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(line.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(line.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (newEl.DocumentElement != null) + { + parent.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), child); + } + } + parent.RemoveChild(child); + } + } + + #endregion + + + #region TableTotalRow + + nodeList = xDocument.SelectNodes("//*[@ascid='table']//*[@ascid='totalRow']"); + child = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (child != null) + { + if (data.TableTotalRow == null) + { + if (parent.ParentNode != null) + parent.ParentNode.RemoveChild(parent); + } + else + { + var newText = child.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(data.TableTotalRow.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(data.TableTotalRow.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (newEl.DocumentElement != null) + { + parent.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), child); + } + parent.RemoveChild(child); + } + } + + #endregion + } + + + #region Terms + + nodeList = xDocument.SelectNodes("//*[@ascid='terms']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + if (data.Terms == null) + { + if (parent.ParentNode != null) + parent.ParentNode.RemoveChild(parent); + } + else + { + var newText = parent.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(data.Terms.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(data.Terms.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (parent.ParentNode != null) + { + if (newEl.DocumentElement != null) + { + parent.ParentNode.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), parent); + } + parent.ParentNode.RemoveChild(parent); + } + } + } + + #endregion + + + #region Notes + + nodeList = xDocument.SelectNodes("//*[@ascid='notes']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + if (data.Notes == null) + { + if (parent.ParentNode != null) + parent.ParentNode.RemoveChild(parent); + } + else + { + var newText = parent.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(data.Notes.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(data.Notes.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (parent.ParentNode != null) + { + if (newEl.DocumentElement != null) + { + parent.ParentNode.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), parent); + } + parent.ParentNode.RemoveChild(parent); + } + } + } + + #endregion + + + #region Consignee + + nodeList = xDocument.SelectNodes("//*[@ascid='consignee']"); + parent = nodeList != null && nodeList.Count > 0 ? nodeList[0] : null; + if (parent != null) + { + if (data.Consignee == null) + { + if (parent.ParentNode != null) + { + parent.ParentNode.RemoveChild(parent); + } + } + else + { + var newText = parent.CloneNode(true).OuterXml; + newText = newText + .Replace("${label}", EncodeAndReplaceLineBreaks(data.Consignee.Item1)) + .Replace("${value}", EncodeAndReplaceLineBreaks(data.Consignee.Item2)); + var newEl = new XmlDocument(); + newEl.LoadXml(newText); + if (parent.ParentNode != null) + { + if (newEl.DocumentElement != null) + { + parent.ParentNode.InsertBefore(xDocument.ImportNode(newEl.DocumentElement, true), parent); + } + parent.ParentNode.RemoveChild(parent); + } + } + } + + #endregion + + + return xDocument.InnerXml; + } + + private static string EncodeAndReplaceLineBreaks(string str) + { + return str + .Replace("&", "&") + .Replace("'", "'") + .Replace("<", "<") + .Replace(">", ">") + .Replace("\"", """) + .Replace("\r\n", "") + .Replace("\n", "") + .Replace("\r", ""); + } + } + + public class ConverterData + { + public string StorageUrl { get; set; } + public string RevisionId { get; set; } + public int InvoiceId { get; set; } + public int FileId { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs new file mode 100644 index 00000000000..b389e9eece1 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -0,0 +1,164 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Web; +using ASC.Common.Logging; +using ASC.CRM.Core; +using ASC.Common.Threading.Progress; +using ASC.Common.Web; +using ASC.Core; + +namespace ASC.Web.CRM.Classes +{ + public class PdfQueueWorker + { + private static readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromMinutes(5), true); + + public static string GetTaskId(int tenantId, int invoiceId) + { + return string.Format("{0}_{1}", tenantId, invoiceId); + } + + public static PdfProgressItem GetTaskStatus(int tenantId, int invoiceId) + { + var id = GetTaskId(tenantId, invoiceId); + return Queue.GetStatus(id) as PdfProgressItem; + } + + public static void TerminateTask(int tenantId, int invoiceId) + { + var item = GetTaskStatus(tenantId, invoiceId); + + if (item != null) + Queue.Remove(item); + } + + public static PdfProgressItem StartTask(HttpContext context, int tenantId, Guid userId, int invoiceId) + { + lock (Queue.SynchRoot) + { + var task = GetTaskStatus(tenantId, invoiceId); + + if (task != null && task.IsCompleted) + { + Queue.Remove(task); + task = null; + } + + if (task == null) + { + task = new PdfProgressItem(context, tenantId, userId, invoiceId); + Queue.Add(task); + } + + if (!Queue.IsStarted) + Queue.Start(x => x.RunJob()); + + return task; + } + } + } + + public class PdfProgressItem : IProgressItem + { + private readonly string _contextUrl; + private readonly int _tenantId; + private readonly int _invoiceId; + private readonly Guid _userId; + + public object Id { get; set; } + public object Status { get; set; } + public object Error { get; set; } + public double Percentage { get; set; } + public bool IsCompleted { get; set; } + + public PdfProgressItem(HttpContext context, int tenantId, Guid userId, int invoiceId) + { + _contextUrl = context != null ? context.Request.GetUrlRewriter().ToString() : null; + _tenantId = tenantId; + _invoiceId = invoiceId; + _userId = userId; + + Id = PdfQueueWorker.GetTaskId(tenantId, invoiceId); + Status = ProgressStatus.Queued; + Error = null; + Percentage = 0; + IsCompleted = false; + } + + public void RunJob() + { + try + { + Percentage = 0; + Status = ProgressStatus.Started; + + CoreContext.TenantManager.SetCurrentTenant(_tenantId); + + SecurityContext.AuthenticateMe(_userId); + + if (HttpContext.Current == null && !WorkContext.IsMono) + { + HttpContext.Current = new HttpContext( + new HttpRequest("hack", _contextUrl, string.Empty), + new HttpResponse(new System.IO.StringWriter())); + } + + PdfCreator.CreateAndSaveFile(_invoiceId); + + Percentage = 100; + Status = ProgressStatus.Done; + } + catch (Exception ex) + { + LogManager.GetLogger("ASC.Web").Error(ex); + Percentage = 0; + Status = ProgressStatus.Failed; + Error = ex.Message; + } + finally + { + // fake httpcontext break configuration manager for mono + if (!WorkContext.IsMono) + { + if (HttpContext.Current != null) + { + new DisposableHttpContext(HttpContext.Current).Dispose(); + HttpContext.Current = null; + } + } + + IsCompleted = true; + } + } + + public object Clone() + { + return MemberwiseClone(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs new file mode 100644 index 00000000000..52753c7fc80 --- /dev/null +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -0,0 +1,227 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Core.Tenants; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.CRM.Core; +using Autofac; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; + +namespace ASC.Web.CRM.Classes +{ + public class ReportHelper + { + private static string GetFileName(ReportType reportType) + { + string reportName; + + switch (reportType) + { + case ReportType.SalesByManagers: + reportName = CRMReportResource.SalesByManagersReport; + break; + case ReportType.SalesForecast: + reportName = CRMReportResource.SalesForecastReport; + break; + case ReportType.SalesFunnel: + reportName = CRMReportResource.SalesFunnelReport; + break; + case ReportType.WorkloadByContacts: + reportName = CRMReportResource.WorkloadByContactsReport; + break; + case ReportType.WorkloadByTasks: + reportName = CRMReportResource.WorkloadByTasksReport; + break; + case ReportType.WorkloadByDeals: + reportName = CRMReportResource.WorkloadByDealsReport; + break; + case ReportType.WorkloadByInvoices: + reportName = CRMReportResource.WorkloadByInvoicesReport; + break; + case ReportType.WorkloadByVoip: + reportName = CRMReportResource.WorkloadByVoipReport; + break; + case ReportType.SummaryForThePeriod: + reportName = CRMReportResource.SummaryForThePeriodReport; + break; + case ReportType.SummaryAtThisMoment: + reportName = CRMReportResource.SummaryAtThisMomentReport; + break; + default: + reportName = string.Empty; + break; + } + + return string.Format("{0} ({1} {2}).xlsx", + reportName, + TenantUtil.DateTimeNow().ToShortDateString(), + TenantUtil.DateTimeNow().ToShortTimeString()); + } + + public static bool CheckReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) + { + using (var scope = DIHelper.Resolve()) + { + var reportDao = scope.Resolve().ReportDao; + + switch (reportType) + { + case ReportType.SalesByManagers: + return reportDao.CheckSalesByManagersReportData(timePeriod, managers); + case ReportType.SalesForecast: + return reportDao.CheckSalesForecastReportData(timePeriod, managers); + case ReportType.SalesFunnel: + return reportDao.CheckSalesFunnelReportData(timePeriod, managers); + case ReportType.WorkloadByContacts: + return reportDao.CheckWorkloadByContactsReportData(timePeriod, managers); + case ReportType.WorkloadByTasks: + return reportDao.CheckWorkloadByTasksReportData(timePeriod, managers); + case ReportType.WorkloadByDeals: + return reportDao.CheckWorkloadByDealsReportData(timePeriod, managers); + case ReportType.WorkloadByInvoices: + return reportDao.CheckWorkloadByInvoicesReportData(timePeriod, managers); + case ReportType.WorkloadByVoip: + return reportDao.CheckWorkloadByViopReportData(timePeriod, managers); + case ReportType.SummaryForThePeriod: + return reportDao.CheckSummaryForThePeriodReportData(timePeriod, managers); + case ReportType.SummaryAtThisMoment: + return reportDao.CheckSummaryAtThisMomentReportData(timePeriod, managers); + default: + return false; + } + } + } + + public static List GetMissingRates(ReportType reportType) + { + using (var scope = DIHelper.Resolve()) + { + var reportDao = scope.Resolve().ReportDao; + if (reportType == ReportType.WorkloadByTasks || reportType == ReportType.WorkloadByInvoices || + reportType == ReportType.WorkloadByContacts || reportType == ReportType.WorkloadByVoip) return null; + + return reportDao.GetMissingRates(Global.TenantSettings.DefaultCurrency.Abbreviation); + } + } + + private static object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) + { + using (var scope = DIHelper.Resolve()) + { + var reportDao = scope.Resolve().ReportDao; + + var defaultCurrency = Global.TenantSettings.DefaultCurrency.Abbreviation; + + switch (reportType) + { + case ReportType.SalesByManagers: + return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); + case ReportType.SalesForecast: + return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); + case ReportType.SalesFunnel: + return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); + case ReportType.WorkloadByContacts: + return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); + case ReportType.WorkloadByTasks: + return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); + case ReportType.WorkloadByDeals: + return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); + case ReportType.WorkloadByInvoices: + return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); + case ReportType.WorkloadByVoip: + return reportDao.GetWorkloadByViopReportData(timePeriod, managers); + case ReportType.SummaryForThePeriod: + return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); + case ReportType.SummaryAtThisMoment: + return reportDao.GetSummaryAtThisMomentReportData(timePeriod, managers, defaultCurrency); + default: + return null; + } + } + } + + private static string GetReportScript(object data, ReportType type, string fileName) + { + var script = + FileHelper.ReadTextFromEmbeddedResource(string.Format("ASC.Web.CRM.ReportTemplates.{0}.docbuilder", type)); + + if (string.IsNullOrEmpty(script)) + throw new Exception(CRMReportResource.BuildErrorEmptyDocbuilderTemplate); + + return script.Replace("${outputFilePath}", fileName) + .Replace("${reportData}", JsonConvert.SerializeObject(data)); + } + + private static void SaveReportFile(ReportState state, string url) + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + var data = new WebClient().DownloadData(url); + + using (var stream = new MemoryStream(data)) + { + var document = new ASC.Files.Core.File + { + Title = state.FileName, + FolderID = daoFactory.FileDao.GetRoot(), + ContentLength = stream.Length + }; + + var file = daoFactory.FileDao.SaveFile(document, stream); + + daoFactory.ReportDao.SaveFile((int)file.ID, state.ReportType); + state.FileId = (int)file.ID; + } + } + } + + public static ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = GetReportData(reportType, timePeriod, managers); + if (reportData == null) + throw new Exception(CRMReportResource.ErrorNullReportData); + + var tmpFileName = DocbuilderReportsUtility.TmpFileName; + + var script = GetReportScript(reportData, reportType, tmpFileName); + if (string.IsNullOrEmpty(script)) + throw new Exception(CRMReportResource.ErrorNullReportScript); + + var state = new ReportState(GetFileName(reportType), tmpFileName, script, (int)reportType, ReportOrigin.CRM, SaveReportFile, null); + + DocbuilderReportsUtility.Enqueue(state); + + return state; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/appsettings.Development.json b/products/ASC.CRM/Server/appsettings.Development.json new file mode 100644 index 00000000000..8983e0fc1c5 --- /dev/null +++ b/products/ASC.CRM/Server/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/products/ASC.CRM/Server/appsettings.json b/products/ASC.CRM/Server/appsettings.json new file mode 100644 index 00000000000..d9d9a9bff6f --- /dev/null +++ b/products/ASC.CRM/Server/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} From cc2824a660b9da5fcba509d129e464e9d6268b09 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 11 Mar 2020 18:10:53 +0300 Subject: [PATCH 02/61] migrate DAO to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 1 + products/ASC.CRM/Server/Classes/Global.cs | 2 +- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 67 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 220 +++--- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 28 +- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 4 +- .../Server/Core/Dao/CurrencyInfoDao.cs | 15 +- .../Server/Core/Dao/CurrencyRateDao.cs | 172 ++--- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 43 +- .../Server/Core/Dao/DealMilestoneDao.cs | 166 +++-- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 48 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 37 +- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 127 ++-- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 146 ++-- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 207 +++--- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 239 +++---- .../Server/Core/Dao/ListItemHistoryDao.cs | 1 + .../ASC.CRM/Server/Core/Dao/ManagerDao.cs | 11 +- .../Server/Core/Dao/RelationshipEventDao.cs | 4 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 26 +- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 412 ++++++----- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 427 ++++++------ .../Core/Dao/TaskTemplateContainerDao.cs | 367 +++++----- .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 117 ++-- .../Server/Core/EF/{CrmCase.cs => DbCase.cs} | 17 +- .../Core/EF/{CrmContact.cs => DbContact.cs} | 6 +- .../{CrmContactInfo.cs => DbContactInfo.cs} | 15 +- .../{CrmCurrencyInfo.cs => DbCurrencyInfo.cs} | 2 +- .../{CrmCurrencyRate.cs => DbCurrencyRate.cs} | 11 +- .../Server/Core/EF/{CrmDeal.cs => DbDeal.cs} | 54 +- ...CrmDealMilestone.cs => DbDealMilestone.cs} | 2 +- ...CrmEntityContact.cs => DbEntityContact.cs} | 8 +- .../EF/{CrmEntityTag.cs => DbEntityTag.cs} | 9 +- ...ldDescription.cs => DbFieldDescription.cs} | 2 +- .../EF/{CrmFieldValue.cs => DbFieldValue.cs} | 6 +- .../Core/EF/{CrmInvoice.cs => DbInvoice.cs} | 2 +- .../{CrmInvoiceItem.cs => DbInvoiceItem.cs} | 12 +- .../{CrmInvoiceLine.cs => DbInvoiceLine.cs} | 2 +- .../EF/{CrmInvoiceTax.cs => DbInvoiceTax.cs} | 14 +- .../Core/EF/{CrmListItem.cs => DbListItem.cs} | 15 +- ...anisationLogo.cs => DbOrganisationLogo.cs} | 2 +- .../Core/EF/{CrmProjects.cs => DbProjects.cs} | 8 +- ...ionshipEvent.cs => DbRelationshipEvent.cs} | 2 +- .../EF/{CrmReportFile.cs => DbReportFile.cs} | 2 +- .../Server/Core/EF/{CrmTag.cs => DbTag.cs} | 11 +- .../Server/Core/EF/{CrmTask.cs => DbTask.cs} | 33 +- .../{CrmTaskTemplate.cs => DbTaskTemplate.cs} | 26 +- ...ontainer.cs => DbTaskTemplateContainer.cs} | 16 +- ...kTemplateTask.cs => DbTaskTemplateTask.cs} | 9 +- .../EF/{CrmVoipCalls.cs => DbVoipCalls.cs} | 2 +- .../EF/{CrmVoipNumber.cs => DbVoipNumber.cs} | 2 +- .../CRMPatternResource.Designer.cs | 649 +++++++++--------- 53 files changed, 2010 insertions(+), 1818 deletions(-) rename products/ASC.CRM/Server/Core/EF/{CrmCase.cs => DbCase.cs} (76%) rename products/ASC.CRM/Server/Core/EF/{CrmContact.cs => DbContact.cs} (91%) rename products/ASC.CRM/Server/Core/EF/{CrmContactInfo.cs => DbContactInfo.cs} (85%) rename products/ASC.CRM/Server/Core/EF/{CrmCurrencyInfo.cs => DbCurrencyInfo.cs} (96%) rename products/ASC.CRM/Server/Core/EF/{CrmCurrencyRate.cs => DbCurrencyRate.cs} (78%) rename products/ASC.CRM/Server/Core/EF/{CrmDeal.cs => DbDeal.cs} (51%) rename products/ASC.CRM/Server/Core/EF/{CrmDealMilestone.cs => DbDealMilestone.cs} (95%) rename products/ASC.CRM/Server/Core/EF/{CrmEntityContact.cs => DbEntityContact.cs} (79%) rename products/ASC.CRM/Server/Core/EF/{CrmEntityTag.cs => DbEntityTag.cs} (77%) rename products/ASC.CRM/Server/Core/EF/{CrmFieldDescription.cs => DbFieldDescription.cs} (95%) rename products/ASC.CRM/Server/Core/EF/{CrmFieldValue.cs => DbFieldValue.cs} (83%) rename products/ASC.CRM/Server/Core/EF/{CrmInvoice.cs => DbInvoice.cs} (98%) rename products/ASC.CRM/Server/Core/EF/{CrmInvoiceItem.cs => DbInvoiceItem.cs} (89%) rename products/ASC.CRM/Server/Core/EF/{CrmInvoiceLine.cs => DbInvoiceLine.cs} (96%) rename products/ASC.CRM/Server/Core/EF/{CrmInvoiceTax.cs => DbInvoiceTax.cs} (85%) rename products/ASC.CRM/Server/Core/EF/{CrmListItem.cs => DbListItem.cs} (80%) rename products/ASC.CRM/Server/Core/EF/{CrmOrganisationLogo.cs => DbOrganisationLogo.cs} (94%) rename products/ASC.CRM/Server/Core/EF/{CrmProjects.cs => DbProjects.cs} (72%) rename products/ASC.CRM/Server/Core/EF/{CrmRelationshipEvent.cs => DbRelationshipEvent.cs} (97%) rename products/ASC.CRM/Server/Core/EF/{CrmReportFile.cs => DbReportFile.cs} (95%) rename products/ASC.CRM/Server/Core/EF/{CrmTag.cs => DbTag.cs} (69%) rename products/ASC.CRM/Server/Core/EF/{CrmTask.cs => DbTask.cs} (78%) rename products/ASC.CRM/Server/Core/EF/{CrmTaskTemplate.cs => DbTaskTemplate.cs} (80%) rename products/ASC.CRM/Server/Core/EF/{CrmTaskTemplateContainer.cs => DbTaskTemplateContainer.cs} (78%) rename products/ASC.CRM/Server/Core/EF/{CrmTaskTemplateTask.cs => DbTaskTemplateTask.cs} (66%) rename products/ASC.CRM/Server/Core/EF/{CrmVoipCalls.cs => DbVoipCalls.cs} (98%) rename products/ASC.CRM/Server/Core/EF/{CrmVoipNumber.cs => DbVoipNumber.cs} (95%) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 54e2b507b6d..6308fa3b1e7 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -17,6 +17,7 @@ + diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 42fdd1547e9..d94a7324609 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -85,7 +85,7 @@ public static bool CanCreateProjects() { var apiUrl = String.Format("{0}project/securityinfo.json", SetupInfo.WebApiBaseUrl); - var cacheKey = String.Format("{0}-{1}", ASC.Core.SecurityContext.CurrentAccount.ID, apiUrl); + var cacheKey = String.Format("{0}-{1}", SecurityContext.CurrentAccount.ID, apiUrl); bool canCreateProject; diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index 812b11763db..af85343c9b3 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -57,17 +57,7 @@ SecurityContext securityContext _cache = AscCache.Memory; CRMDbContext = dbContextManager.Get(CRMConstants.DatabaseId); TenantID = tenantManager.GetCurrentTenant().TenantId; - SecurityContext = securityContext; - } - - /* - protected readonly String _invoiceItemCacheKey; - protected readonly String _invoiceTaxCacheKey; - protected readonly String _invoiceLineCacheKey; - */ - protected AbstractDao(int tenantID) - { - TenantID = tenantID; + SecurityContext = securityContext; _supportedEntityType.Add(EntityType.Company); _supportedEntityType.Add(EntityType.Person); @@ -93,8 +83,16 @@ protected AbstractDao(int tenantID) _cache.Insert(_invoiceLineCacheKey, String.Empty); } */ + + } + /* + protected readonly String _invoiceItemCacheKey; + protected readonly String _invoiceTaxCacheKey; + protected readonly String _invoiceLineCacheKey; + */ + protected int TenantID { get; private set; } protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumerable tags) @@ -106,22 +104,22 @@ protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumer foreach (var tag in tags) { tagIDs.Add(CRMDbContext - .CrmTag - .Where(x => x.EntityType == (int)entityType && String.Compare(x.Title, tag.Trim(), true) == 0) + .Tags + .Where(x => x.EntityType == entityType && String.Compare(x.Title, tag.Trim(), true) == 0) .Select(x => x.Id).Single()); } - Expression> exp = null; + Expression> exp = null; if (exceptIDs != null && exceptIDs.Length > 0) - exp = x => exceptIDs.Contains(x.EntityId) && x.EntityType == (int)entityType; + exp = x => exceptIDs.Contains(x.EntityId) && x.EntityType == entityType; else - exp = x => x.EntityType == (int)entityType; - + exp = x => x.EntityType == entityType; + throw new NotImplementedException(); - // exp.Update() Exp.In("tag_id", tagIDs) + // exp.Update() Exp.In("tag_id", tagIDs) // return CRMDbContext.CrmEntityTag.Where(exp).GroupBy(x => x.EntityId).Select(x=>) // .Where(x => true).Select(x=>x); @@ -143,14 +141,14 @@ protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumer protected Dictionary GetRelativeToEntity(int[] contactID, EntityType entityType, int[] entityID) { - Expression> exp = null; + Expression> exp = null; if (contactID != null && contactID.Length > 0 && (entityID == null || entityID.Length == 0)) exp = x => x.EntityType == (int)entityType && contactID.Contains(x.ContactId); else if (entityID != null && entityID.Length > 0 && (contactID == null || contactID.Length == 0)) exp = x => x.EntityType == (int)entityType && entityID.Contains(x.EntityId); - return CRMDbContext.CrmEntityContact.Where(exp).GroupBy(x => x.EntityId).ToDictionary( + return CRMDbContext.EntityContact.Where(exp).GroupBy(x => x.EntityId).ToDictionary( x => x.Key, x => x.Select(x => Convert.ToInt32(x.ContactId)).ToArray()); } @@ -163,13 +161,13 @@ protected int[] GetRelativeToEntity(int? contactID, EntityType entityType, int? protected int[] GetRelativeToEntityInDb(int? contactID, EntityType entityType, int? entityID) { if (contactID.HasValue && !entityID.HasValue) - return CRMDbContext.CrmEntityContact + return CRMDbContext.EntityContact .Where(x => x.EntityType == (int)entityType && x.ContactId == contactID.Value) .Select(x => x.EntityId) .ToArray(); if (!contactID.HasValue && entityID.HasValue) - return CRMDbContext.CrmEntityContact + return CRMDbContext.EntityContact .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID.Value) .Select(x => x.ContactId) .ToArray(); @@ -184,17 +182,17 @@ protected void SetRelative(int[] contactID, EntityType entityType, int entityID) using var tx = CRMDbContext.Database.BeginTransaction(); - var exists = CRMDbContext.CrmEntityContact + var exists = CRMDbContext.EntityContact .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID) .Select(x => x.ContactId) .ToArray(); foreach (var existContact in exists) { - var items = CRMDbContext.CrmEntityContact + var items = CRMDbContext.EntityContact .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID && x.ContactId == existContact); - CRMDbContext.CrmEntityContact.RemoveRange(items); + CRMDbContext.EntityContact.RemoveRange(items); } if (!(contactID == null || contactID.Length == 0)) @@ -206,7 +204,7 @@ protected void SetRelative(int[] contactID, EntityType entityType, int entityID) protected void SetRelative(int contactID, EntityType entityType, int entityID) { - CRMDbContext.CrmEntityContact.Add(new CrmEntityContact + CRMDbContext.EntityContact.Add(new DbEntityContact { ContactId = contactID, EntityType = (int)entityType, @@ -221,7 +219,7 @@ protected void RemoveRelativeInDb(int[] contactID, EntityType entityType, int[] if ((contactID == null || contactID.Length == 0) && (entityID == null || entityID.Length == 0)) throw new ArgumentException(); - Expression> expr = null; + Expression> expr = null; if (contactID != null && contactID.Length > 0) expr = x => contactID.Contains(x.ContactId); @@ -229,7 +227,7 @@ protected void RemoveRelativeInDb(int[] contactID, EntityType entityType, int[] if (entityID != null && entityID.Length > 0) expr = x => entityID.Contains(x.EntityId) && x.EntityType == (int)entityType; - var dbCrmEntity = CRMDbContext.CrmEntityContact; + var dbCrmEntity = CRMDbContext.EntityContact; dbCrmEntity.RemoveRange(dbCrmEntity.Where(expr)); @@ -255,14 +253,14 @@ protected void RemoveRelative(int contactID, EntityType entityType, int entityID public int SaveOrganisationLogo(byte[] bytes) { - var entity = new CrmOrganisationLogo + var entity = new DbOrganisationLogo { Content = Convert.ToBase64String(bytes), CreateOn = DateTime.UtcNow, CreateBy = SecurityContext.CurrentAccount.ID.ToString() }; - CRMDbContext.CrmOrganisationLogo.Add(entity); + CRMDbContext.OrganisationLogo.Add(entity); CRMDbContext.SaveChanges(); @@ -275,7 +273,7 @@ public string GetOrganisationLogoBase64(int logo_id) if (logo_id <= 0) throw new ArgumentException(); - return CRMDbContext.CrmOrganisationLogo + return CRMDbContext.OrganisationLogo .Where(x => x.Id == logo_id) .Select(x => x.Content) .FirstOrDefault(); @@ -297,19 +295,24 @@ protected IQueryable Query(DbSet set) where T : class, IDbCrm { return set.Where(r => r.TenantId == TenantID); } - + protected string GetTenantColumnName(string table) { var tenant = "tenant_id"; + if (!table.Contains(" ")) return tenant; + return table.Substring(table.IndexOf(" ")).Trim() + "." + tenant; + } protected static Guid ToGuid(object guid) { var str = guid as string; + return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty; + } } diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 1656604a113..50ee9cda3d6 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -26,10 +26,13 @@ using ASC.Collections; using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.CRM.Core.Search; +using ASC.Web.Files.Api; using System; using System.Collections.Generic; using System.Globalization; @@ -81,22 +84,30 @@ private void ResetCache(int taskID) public class CasesDao : AbstractDao { - public CasesDao(int tenantID) - : base(tenantID) + public CasesDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + FilesIntegration filesIntegration + ) : + base(dbContextManager, + tenantManager, + securityContext) { - + CRMSecurity = cRMSecurity; + TenantUtil = tenantUtil; + FilesIntegration = filesIntegration; } - #region Property + public CoreContext CoreContext { get; } - public CRMSecurity CRMSecurity { get; } + public FilesIntegration FilesIntegration { get; } - #endregion + public TenantUtil TenantUtil { get; } - public CasesDao(CRMSecurity cRMSecurity) - { - CRMSecurity = cRMSecurity; - } + public CRMSecurity CRMSecurity { get; } public void AddMember(int caseID, int memberID) { @@ -125,16 +136,17 @@ public void RemoveMember(int caseID, int memberID) public virtual int[] SaveCasesList(List items) { - using (var tx = Db.BeginTransaction()) - { - var result = items.Select(item => CreateCasesInDb(item.Title)).ToArray(); - tx.Commit(); - // Delete relative keys - _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "cases.*")); - return result; - } - } + using var tx = CRMDbContext.Database.BeginTransaction(); + + var result = items.Select(item => CreateCasesInDb(item.Title)).ToArray(); + tx.Commit(); + + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "cases.*")); + + return result; + } public Cases CloseCases(int caseID) { @@ -146,12 +158,22 @@ public Cases CloseCases(int caseID) CRMSecurity.DemandAccessTo(cases); - Db.ExecuteNonQuery( - Update("crm_case") - .Set("is_closed", true) - .Where("id", caseID) - ); + CRMDbContext.Cases.Update(new DbCase + { + Id = cases.ID, + CreateBy = cases.CreateBy, + CreateOn = cases.CreateOn, + IsClosed = true, + LastModifedBy = cases.LastModifedBy, + LastModifedOn = cases.LastModifedOn, + TenantId = TenantID, + Title = cases.Title + }); + + CRMDbContext.SaveChanges(); + cases.IsClosed = true; + return cases; } @@ -165,12 +187,22 @@ public Cases ReOpenCases(int caseID) CRMSecurity.DemandAccessTo(cases); - Db.ExecuteNonQuery( - Update("crm_case") - .Set("is_closed", false) - .Where("id", caseID) - ); + CRMDbContext.Cases.Update(new DbCase + { + Id = cases.ID, + CreateBy = cases.CreateBy, + CreateOn = cases.CreateOn, + IsClosed = false, + LastModifedBy = cases.LastModifedBy, + LastModifedOn = cases.LastModifedOn, + TenantId = TenantID, + Title = cases.Title + }); + + CRMDbContext.SaveChanges(); + cases.IsClosed = false; + return cases; } @@ -185,16 +217,23 @@ public int CreateCases(String title) private int CreateCasesInDb(String title) { - return Db.ExecuteScalar( - Insert("crm_case") - .InColumnValue("id", 0) - .InColumnValue("title", title) - .InColumnValue("is_closed", false) - .InColumnValue("create_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); + var dbCase = new DbCase + { + Title = title, + IsClosed = false, + CreateOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + CreateBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.Cases.Add(dbCase); + + CRMDbContext.SaveChanges(); + + return dbCase.Id; + } public virtual void UpdateCases(Cases cases) @@ -204,14 +243,19 @@ public virtual void UpdateCases(Cases cases) // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); - Db.ExecuteNonQuery( - Update("crm_case") - .Set("title", cases.Title) - .Set("is_closed", cases.IsClosed) - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where("id", cases.ID) - ); + CRMDbContext.Cases.Update(new DbCase + { + Id = cases.ID, + Title = cases.Title, + IsClosed = cases.IsClosed, + LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID, + CreateBy = cases.CreateBy, + CreateOn = cases.CreateOn + }); + + CRMDbContext.SaveChanges(); } public virtual Cases DeleteCases(int casesID) @@ -262,37 +306,36 @@ private void DeleteBatchCasesExecute(List caseses) { var casesID = caseses.Select(x => x.ID).ToArray(); - using (var tagdao = FilesIntegration.GetTagDao()) - { - var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id") - .Where(Exp.Eq("have_files", true) & Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))) - .Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); - var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + var tagdao = FilesIntegration.GetTagDao(); - using (var tx = Db.BeginTransaction(true)) - { - Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(Delete("crm_case").Where(Exp.In("id", casesID))); + var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id") + .Where(Exp.Eq("have_files", true) & Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))) + .Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); - tx.Commit(); - } + var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + + using var tx = CRMDbContext.Database.BeginTransaction(); + + Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); + Db.ExecuteNonQuery(Delete("crm_case").Where(Exp.In("id", casesID))); + + tx.Commit(); - caseses.ForEach(item => CoreContext.AuthorizationManager.RemoveAllAces(item)); + caseses.ForEach(item => CoreContext.AuthorizationManager.RemoveAllAces(item)); - if (0 < tagNames.Length) + if (0 < tagNames.Length) + { + var filedao = FilesIntegration.GetFileDao(); + + foreach (var filesID in filesIDs) { - using (var filedao = FilesIntegration.GetFileDao()) - { - foreach (var filesID in filesIDs) - { - filedao.DeleteFile(filesID); - } - } + filedao.DeleteFile(filesID); } } + //todo: remove indexes } @@ -394,9 +437,9 @@ private Exp WhereConditional( { if (!BundleSearch.TrySelectCase(searchText, out ids)) { - conditions.Add(BuildLike(new[] {"title"}, keywords)); + conditions.Add(BuildLike(new[] { "title" }, keywords)); } - else if(!ids.Any()) + else if (!ids.Any()) { return null; @@ -413,7 +456,7 @@ private Exp WhereConditional( if (ids.Count > 0) sqlQuery.Where(Exp.In("entity_id", ids)); - + ids = Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList(); if (ids.Count == 0) return null; } @@ -540,7 +583,10 @@ public List GetCasesByPrefix(String prefix, int from, int count) public virtual List GetByID(int[] ids) { - return Db.ExecuteList(GetCasesSqlQuery(Exp.In("id", ids))).ConvertAll(ToCases); + return CRMDbContext.Cases + .Where(x => ids.Contains(x.Id)) + .ToList() + .ConvertAll(ToCases); } public virtual Cases GetByID(int id) @@ -552,22 +598,23 @@ public virtual Cases GetByID(int id) return cases.Count == 0 ? null : cases[0]; } - #region Private Methods - - private static Cases ToCases(object[] row) + private Cases ToCases(DbCase dbCase) { return new Cases - { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - CreateBy = ToGuid(row[2]), - CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[3].ToString())), - IsClosed = Convert.ToBoolean(row[4]) - }; + { + ID = dbCase.Id, + Title = dbCase.Title, + CreateBy = dbCase.CreateBy, + CreateOn = dbCase.CreateOn, + IsClosed = dbCase.IsClosed, + LastModifedBy = dbCase.LastModifedBy, + LastModifedOn = dbCase.LastModifedOn + }; } private SqlQuery GetCasesSqlQuery(Exp where) { + var sqlQuery = Query("crm_case") .Select("id", "title", "create_by", "create_on", "is_closed"); @@ -579,9 +626,6 @@ private SqlQuery GetCasesSqlQuery(Exp where) return sqlQuery; } - #endregion - - public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) { var cases = GetAllCases(); diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 08389edd0c9..73679165be0 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -26,9 +26,13 @@ using ASC.Collections; using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; +using ASC.Web.CRM.Core.Search; using System; using System.Collections.Generic; using System.Globalization; @@ -91,23 +95,27 @@ private void ResetCache(int contactID) _contactCache.Reset(contactID.ToString()); } } - - - - + public class ContactDao : AbstractDao { #region Constructor - public ContactDao(int tenantID) - : base(tenantID) + public ContactDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity) : + base(dbContextManager, + tenantManager, + securityContext) { + CRMSecurity = cRMSecurity; } #endregion #region Members - + public CRMSecurity CRMSecurity { get; } private readonly String _displayNameSeparator = "!=!"; #endregion @@ -1139,7 +1147,7 @@ private void UpdateContactFromDb(Contact contact) .Set("status_id", contact.StatusID) .Set("company_id", companyID) .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) .Set("display_name", displayName) .Set("is_shared", (int)contact.ShareType) .Set("contact_type_id", contact.ContactTypeID) @@ -1327,10 +1335,10 @@ private int SaveContactToDb(Contact contact) .InColumnValue("industry", contact.Industry) .InColumnValue("status_id", contact.StatusID) .InColumnValue("company_id", companyID) - .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) .InColumnValue("create_on", TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn)) .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn)) - .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) .InColumnValue("display_name", displayName) .InColumnValue("is_shared", (int)contact.ShareType) .InColumnValue("contact_type_id", contact.ContactTypeID) diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 6abb2440164..509482d5609 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -157,7 +157,7 @@ private int UpdateInDb(ContactInfo contactInfo) .Set("contact_id", contactInfo.ContactID) .Set("type", (int)contactInfo.InfoType) .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) ); return contactInfo.ID; } @@ -197,7 +197,7 @@ private int SaveInDb(ContactInfo contactInfo) .InColumnValue("contact_id", contactInfo.ContactID) .InColumnValue("type", (int)contactInfo.InfoType) .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) .Identity(1, 0, true)); } diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 92b66e9c583..349f7c59625 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -30,6 +30,9 @@ using System.Collections.Generic; using ASC.Common.Data.Sql; using ASC.Common.Data.Sql.Expressions; +using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; #endregion @@ -37,9 +40,17 @@ namespace ASC.CRM.Core.Dao { public class CurrencyInfoDao : AbstractDao { - public CurrencyInfoDao(int tenantID) - : base(tenantID) + + + public CurrencyInfoDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext): + base(dbContextManager, + tenantManager, + securityContext) { + + } public virtual List GetAll() diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index 3d95fcdc38b..f9c8b2cc1b7 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -23,44 +23,42 @@ * */ - -#region Import - using System; using System.Collections.Generic; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; +using System.Linq; using ASC.Core; - -#endregion +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; namespace ASC.CRM.Core.Dao { public class CurrencyRateDao : AbstractDao { - public CurrencyRateDao(int tenantID) - : base(tenantID) + public CurrencyRateDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) : + base(dbContextManager, + tenantManager, + securityContext) { + } public virtual List GetAll() { - return Db.ExecuteList(GetSqlQuery(null)).ConvertAll(ToCurrencyRate); + return CRMDbContext.CurrencyRate.Where(x => x.TenantId == TenantID).ToList().ConvertAll(ToCurrencyRate); } public virtual CurrencyRate GetByID(int id) { - var rates = Db.ExecuteList(GetSqlQuery(Exp.Eq("id", id))).ConvertAll(ToCurrencyRate); - - return rates.Count > 0 ? rates[0] : null; + return ToCurrencyRate(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.Id == id)); } public CurrencyRate GetByCurrencies(string fromCurrency, string toCurrency) { - var rates = Db.ExecuteList(GetSqlQuery(Exp.Eq("from_currency", fromCurrency.ToUpper()) & Exp.Eq("to_currency", toCurrency.ToUpper()))) - .ConvertAll(ToCurrencyRate); - - return rates.Count > 0 ? rates[0] : null; + return ToCurrencyRate(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && + String.Compare(x.ToCurrency, toCurrency, true) == 0)); } public int SaveOrUpdate(CurrencyRate currencyRate) @@ -70,32 +68,39 @@ public int SaveOrUpdate(CurrencyRate currencyRate) if (currencyRate.ID > 0 && currencyRate.Rate == 0) return Delete(currencyRate.ID); - - if (Db.ExecuteScalar(Query("crm_currency_rate").SelectCount().Where(Exp.Eq("id", currencyRate.ID))) == 0) + + if (CRMDbContext.CurrencyRate.Where(x => x.Id == currencyRate.ID).Any()) { - var query = Insert("crm_currency_rate") - .InColumnValue("id", 0) - .InColumnValue("from_currency", currencyRate.FromCurrency.ToUpper()) - .InColumnValue("to_currency", currencyRate.ToCurrency.ToUpper()) - .InColumnValue("rate", currencyRate.Rate) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("create_on", DateTime.UtcNow) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", DateTime.UtcNow) - .Identity(1, 0, true); - - currencyRate.ID = Db.ExecuteScalar(query); + var itemToInsert = new DbCurrencyRate + { + FromCurrency = currencyRate.FromCurrency.ToUpper(), + ToCurrency = currencyRate.ToCurrency.ToUpper(), + Rate = currencyRate.Rate, + CreateBy = SecurityContext.CurrentAccount.ID, + CreateOn = DateTime.UtcNow, + LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = DateTime.UtcNow, + TenantId = TenantID + }; + + CRMDbContext.CurrencyRate.Add(itemToInsert); + CRMDbContext.SaveChanges(); + + currencyRate.ID = itemToInsert.Id; } else { - Db.ExecuteNonQuery( - Update("crm_currency_rate") - .Set("from_currency", currencyRate.FromCurrency.ToUpper()) - .Set("to_currency", currencyRate.ToCurrency.ToUpper()) - .Set("rate", currencyRate.Rate) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", currencyRate.ID))); + var itemToUpdate = CRMDbContext.CurrencyRate.FirstOrDefault(x => x.Id == currencyRate.ID); + + itemToUpdate.FromCurrency = currencyRate.FromCurrency.ToUpper(); + itemToUpdate.ToCurrency = currencyRate.ToCurrency.ToUpper(); + itemToUpdate.Rate = currencyRate.Rate; + itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedOn = DateTime.UtcNow; + itemToUpdate.TenantId = TenantID; + + CRMDbContext.Update(itemToUpdate); + CRMDbContext.SaveChanges(); } return currencyRate.ID; @@ -105,64 +110,63 @@ public int Delete(int id) { if (id <= 0) throw new ArgumentException(); - var sqlQuery = Delete("crm_currency_rate") - .Where(Exp.Eq("id", id)); + var itemToDelete = new DbCurrencyRate { Id = id }; - Db.ExecuteNonQuery(sqlQuery); + CRMDbContext.CurrencyRate.Attach(itemToDelete); + CRMDbContext.CurrencyRate.Remove(itemToDelete); + CRMDbContext.SaveChanges(); return id; } public List SetCurrencyRates(List rates) { - using (var tx = Db.BeginTransaction()) + using var tx = CRMDbContext.Database.BeginTransaction(); + + var items = CRMDbContext.CurrencyRate.Where(x => x.TenantId == TenantID); + + CRMDbContext.RemoveRange(items); + + foreach (var rate in rates) { - Db.ExecuteNonQuery(Delete("crm_currency_rate")); - - foreach (var rate in rates) - { - var query = Insert("crm_currency_rate") - .InColumnValue("id", 0) - .InColumnValue("from_currency", rate.FromCurrency.ToUpper()) - .InColumnValue("to_currency", rate.ToCurrency.ToUpper()) - .InColumnValue("rate", rate.Rate) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("create_on", DateTime.UtcNow) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", DateTime.UtcNow) - .Identity(1, 0, true); - - rate.ID = Db.ExecuteScalar(query); - } - - tx.Commit(); - - return rates; - } - } + var itemToInsert = new DbCurrencyRate { + FromCurrency = rate.FromCurrency.ToUpper(), + ToCurrency = rate.ToCurrency.ToUpper(), + Rate = rate.Rate, + CreateBy = SecurityContext.CurrentAccount.ID, + CreateOn = DateTime.UtcNow, + LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = DateTime.UtcNow, + TenantId = TenantID + }; - private SqlQuery GetSqlQuery(Exp where) - { - var sqlQuery = Query("crm_currency_rate") - .Select("id", - "from_currency", - "to_currency", - "rate"); + CRMDbContext.CurrencyRate.Add(itemToInsert); - if (where != null) - sqlQuery.Where(where); + CRMDbContext.SaveChanges(); - return sqlQuery; - } + rate.ID = itemToInsert.Id; + } + + tx.Commit(); - private static CurrencyRate ToCurrencyRate(object[] row) + return rates; + } + + private static CurrencyRate ToCurrencyRate(DbCurrencyRate dbCurrencyRate) { - return new CurrencyRate{ - ID = Convert.ToInt32(row[0]), - FromCurrency = Convert.ToString(row[1]), - ToCurrency = Convert.ToString(row[2]), - Rate = Convert.ToDecimal(row[3]) - }; + if (dbCurrencyRate == null) return null; + + return new CurrencyRate + { + ID = dbCurrencyRate.Id, + FromCurrency = dbCurrencyRate.FromCurrency, + ToCurrency = dbCurrencyRate.ToCurrency, + Rate = dbCurrencyRate.Rate, + CreateBy = dbCurrencyRate.CreateBy, + CreateOn = dbCurrencyRate.CreateOn, + LastModifedBy = dbCurrencyRate.LastModifedBy, + LastModifedOn = dbCurrencyRate.LastModifedOn + }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 21b1e4864fd..f28d6f1f42c 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -100,7 +100,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, .InColumnValue("field_id", fieldID) .InColumnValue("entity_type", (int)entityType) .InColumnValue("last_modifed_on", lastModifiedOn) - .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) .Identity(1, 0, true) ); diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index f3a91467a1f..8e0a990483f 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -24,24 +24,23 @@ */ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using System.Globalization; - using ASC.Collections; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Files.Core; -using ASC.Web.Files.Api; using ASC.Web.CRM.Core.Search; +using ASC.Web.Files.Api; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; using OrderBy = ASC.CRM.Core.Entities.OrderBy; -using ASC.CRM.Core.Enums; namespace ASC.CRM.Core.Dao { @@ -93,11 +92,21 @@ public class DealDao : AbstractDao { #region Constructor - public DealDao(int tenantID) - : base(tenantID) + public DealDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity) : + base(dbContextManager, + tenantManager, + securityContext) { + } + + public TenantUtil TenantUtil { get; } + public CRMSecurity CRMSecurity { get; } + #endregion #region Methods @@ -180,9 +189,9 @@ private int CreateNewDealInDb(Deal deal) .InColumnValue("actual_close_date", TenantUtil.DateTimeToUtc(deal.ActualCloseDate)) .InColumnValue("per_period_value", deal.PerPeriodValue) .InColumnValue("create_on", TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn)) - .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn)) - .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) .Identity(1, 0, true)); // if (deal.ContactID > 0) @@ -231,7 +240,7 @@ public virtual void EditDeal(Deal deal) .Set("per_period_value", deal.PerPeriodValue) .Set("actual_close_date", TenantUtil.DateTimeToUtc(deal.ActualCloseDate)) .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) + .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) .Where(Exp.Eq("id", deal.ID)) ); @@ -885,12 +894,16 @@ public void SetDealCreationDate(int opportunityid, DateTime creationDate) /// public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) { + + Db.ExecuteNonQuery( Update("crm_deal") .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) .Where(Exp.Eq("id", opportunityid))); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index ddc6eb84f5f..1850c69e23b 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -27,7 +27,12 @@ #region Import using ASC.Collections; +using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using System; using System.Collections.Generic; using System.Linq; @@ -99,31 +104,48 @@ public class DealMilestoneDao : AbstractDao #region Constructor - public DealMilestoneDao(int tenantID) - : base(tenantID) + public DealMilestoneDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) : + base(dbContextManager, + tenantManager, + securityContext) { + + } + #endregion public virtual void Reorder(int[] ids) { - using (var tx = Db.BeginTransaction()) - { - for (int index = 0; index < ids.Length; index++) - Db.ExecuteNonQuery(Update("crm_deal_milestone") - .Set("sort_order", index) - .Where(Exp.Eq("id", ids[index]))); + using var tx = CRMDbContext.Database.BeginTransaction(); - tx.Commit(); + for (int index = 0; index < ids.Length; index++) + { + Query(CRMDbContext.DealMilestones) } + + + tx.Commit(); + + + throw new NotImplementedException(); + + // .Where(x => ids.Contains(x.Id)); + + Db.ExecuteNonQuery(Update("crm_deal_milestone") + .Set("sort_order", index) + .Where(Exp.Eq("id", ids[index]))); + } public int GetCount() { - return Db.ExecuteScalar(Query("crm_deal_milestone").SelectCount()); + return Query(CRMDbContext.DealMilestones).Count(); } @@ -144,12 +166,8 @@ public Dictionary GetRelativeItemsCount() public int GetRelativeItemsCount(int id) { - - var sqlQuery = Query("crm_deal") - .Select("count(*)") - .Where(Exp.Eq("deal_milestone_id", id)); - - return Db.ExecuteScalar(sqlQuery); + return Query(CRMDbContext.Deals) + .Count(x => x.DealMilestoneId == id); } public virtual int Create(DealMilestone item) @@ -186,34 +204,37 @@ public virtual int Create(DealMilestone item) public virtual void ChangeColor(int id, String newColor) { - Db.ExecuteNonQuery(Update("crm_deal_milestone") - .Set("color", newColor) - .Where(Exp.Eq("id", id))); + var item = CRMDbContext.DealMilestones.First(x => x.Id == id); + + item.Color = newColor; + + CRMDbContext.SaveChanges(); } public virtual void Edit(DealMilestone item) { - if (HaveContactLink(item.ID)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.DealMilestoneHasRelatedDeals)); - Db.ExecuteNonQuery(Update("crm_deal_milestone") - .Set("title", item.Title) - .Set("description", item.Description) - .Set("color", item.Color) - .Set("probability", item.Probability) - .Set("status", (int)item.Status) - .Where(Exp.Eq("id", item.ID))); + Query(CRMDbContext.DealMilestones) + .First(x => x.Id == item.ID); + + + //CRMDbContext.DealMilestones.Update(); + + //Db.ExecuteNonQuery(Update("crm_deal_milestone") + // .Set("title", item.Title) + // .Set("description", item.Description) + // .Set("color", item.Color) + // .Set("probability", item.Probability) + // .Set("status", (int)item.Status) + // .Where(Exp.Eq("id", item.ID))); } public bool HaveContactLink(int dealMilestoneID) { - SqlQuery sqlQuery = Query("crm_deal") - .Where(Exp.Eq("deal_milestone_id", dealMilestoneID)) - .SelectCount() - .SetMaxResults(1); - - return Db.ExecuteScalar(sqlQuery) >= 1; + return Query(CRMDbContext.Deals) + .Any(x => x.DealMilestoneId == dealMilestoneID); } public virtual void Delete(int id) @@ -221,69 +242,78 @@ public virtual void Delete(int id) if (HaveContactLink(id)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.DealMilestoneHasRelatedDeals)); - Db.ExecuteNonQuery(Delete("crm_deal_milestone").Where(Exp.Eq("id", id))); + var item = CRMDbContext.DealMilestones.First(x => x.Id == id); + + CRMDbContext.DealMilestones.Remove(item); + + CRMDbContext.SaveChanges(); + } public virtual DealMilestone GetByID(int id) { - var dealMilestones = Db.ExecuteList(GetDealMilestoneQuery(Exp.Eq("id", id))).ConvertAll(row => ToDealMilestone(row)); + + //var dealMilestones = Db.ExecuteList(GetDealMilestoneQuery(Exp.Eq("id", id))).ConvertAll(row => ToDealMilestone(row)); - if (dealMilestones.Count == 0) - return null; + //if (dealMilestones.Count == 0) + // return null; - return dealMilestones[0]; + //return dealMilestones[0]; } public Boolean IsExist(int id) { - return Db.ExecuteScalar("select exists(select 1 from crm_deal_milestone where tenant_id = @tid and id = @id)", - new { tid = TenantID, id = id }); + return Query(CRMDbContext.DealMilestones).Any(x => x.Id == id); } public List GetAll(int[] id) { - return Db.ExecuteList(GetDealMilestoneQuery(Exp.In("id", id))).ConvertAll(row => ToDealMilestone(row)); + + + + + + // return Db.ExecuteList(GetDealMilestoneQuery(Exp.In("id", id))).ConvertAll(row => ToDealMilestone(row)); } public List GetAll() { - return Db.ExecuteList(GetDealMilestoneQuery(null)).ConvertAll(row => ToDealMilestone(row)); + + +// return Db.ExecuteList(GetDealMilestoneQuery(null)).ConvertAll(row => ToDealMilestone(row)); } - private SqlQuery GetDealMilestoneQuery(Exp where) - { - SqlQuery sqlQuery = Query("crm_deal_milestone") - .Select("id", - "title", - "description", - "color", - "probability", - "status", - "sort_order") - .OrderBy("sort_order", true); + //private SqlQuery GetDealMilestoneQuery(Exp where) + //{ + // SqlQuery sqlQuery = Query("crm_deal_milestone") + // .Select("id", + // "title", + // "description", + // "color", + // "probability", + // "status", + // "sort_order") + // .OrderBy("sort_order", true); - if (where != null) - sqlQuery.Where(where); + // if (where != null) + // sqlQuery.Where(where); - return sqlQuery; + // return sqlQuery; - } + //} - private static DealMilestone ToDealMilestone(object[] row) + private static DealMilestone ToDealMilestone(DbDealMilestone dbDealMilestone) { return new DealMilestone { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - Description = Convert.ToString(row[2]), - Color = Convert.ToString(row[3]), - Probability = Convert.ToInt32(row[4]), - Status = (DealMilestoneStatus)Convert.ToInt32(row[5]), - SortOrder = Convert.ToInt32(row[6]) + ID = dbDealMilestone.Id, + Title = dbDealMilestone.Title, + Color = dbDealMilestone.Color, + Status = dbDealMilestone.Status, + Description = dbDealMilestone.Description, + Probability = dbDealMilestone.Probability, + SortOrder = dbDealMilestone.SortOrder }; } - - - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index bfadba290fd..74bc411c02d 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -28,6 +28,8 @@ using System.Collections.Generic; using System.Linq; using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; using ASC.Files.Core; using ASC.Web.Files.Api; @@ -35,28 +37,33 @@ namespace ASC.CRM.Core.Dao { public class FileDao : AbstractDao { - public FileDao(int tenantID) - : base(tenantID) + public FileDao(FilesIntegration filesIntegration, + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext): + base(dbContextManager, + tenantManager, + securityContext) { + FilesIntegration = filesIntegration; } - #region Public Methods + public FilesIntegration FilesIntegration { get; } public File GetFile(int id, int version) { - using (var dao = FilesIntegration.GetFileDao()) - { - var file = 0 < version ? dao.GetFile(id, version) : dao.GetFile(id); - return file; - } + var dao = FilesIntegration.GetFileDao(); + + var file = 0 < version ? dao.GetFile(id, version) : dao.GetFile(id); + + return file; } public void DeleteFile(int id) { - using (var dao = FilesIntegration.GetFileDao()) - { - dao.DeleteFile(id); - } + var dao = FilesIntegration.GetFileDao(); + + dao.DeleteFile(id); } public object GetRoot() @@ -71,21 +78,18 @@ public object GetMy() public File SaveFile(File file, System.IO.Stream stream) { - using (var dao = FilesIntegration.GetFileDao()) - { - return dao.SaveFile(file, stream); - } + var dao = FilesIntegration.GetFileDao(); + + return dao.SaveFile(file, stream); } public List GetEventsByFile(int id) { - using (var tagdao = FilesIntegration.GetTagDao()) - { - var tags = tagdao.GetTags(id, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); - return tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); - } + var tagdao = FilesIntegration.GetTagDao(); + var tags = tagdao.GetTags(id, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); + + return tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); } - #endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 7891531ed03..7ea80f7f4e6 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -32,8 +32,12 @@ using ASC.Collections; using ASC.Common.Data.Sql; using ASC.Common.Data.Sql.Expressions; +using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; @@ -93,11 +97,18 @@ public class InvoiceDao : AbstractDao new KeyValuePair(InvoiceStatus.Paid, InvoiceStatus.Sent)//Bug 23450 }; - public InvoiceDao(int tenantID) - : base(tenantID) + public InvoiceDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { + } + public CRMSecurity CRMSecurity { get; } + public Boolean IsExist(int invoiceID) { return IsExistFromDb(invoiceID); @@ -106,6 +117,7 @@ public Boolean IsExist(int invoiceID) public Boolean IsExistFromDb(int invoiceID) { + return Db.ExecuteScalar(@"select exists(select 1 from crm_invoice where tenant_id = @tid and id = @id)", new { tid = TenantID, id = invoiceID }); } @@ -123,9 +135,7 @@ public Boolean IsExistFromDb(string number) .Where("number", number); return Db.ExecuteScalar(q) > 0; } - - #region Get - + public virtual List GetAll() { return Db.ExecuteList(GetInvoiceSqlQuery(null, null)).ConvertAll(ToInvoice); @@ -453,11 +463,7 @@ public InvoiceSetting GetSettings() { return Global.TenantSettings.InvoiceSetting ?? InvoiceSetting.DefaultSettings; } - - #endregion - - #region SaveOrUpdate - + public virtual int SaveOrUpdateInvoice(Invoice invoice) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -663,12 +669,7 @@ public InvoiceSetting SaveInvoiceSettings(InvoiceSetting invoiceSetting) return tenantSettings.InvoiceSetting; } - - #endregion - - #region Delete - - + public virtual Invoice DeleteInvoice(int invoiceID) { if (invoiceID <= 0) return null; @@ -714,10 +715,6 @@ private void DeleteBatchInvoicesExecute(List invoices) invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(invoice)); } - #endregion - - #region Private Methods - private static Invoice ToInvoice(object[] row) { return new Invoice diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index a80a8f7796d..a9192ee03c9 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -24,19 +24,18 @@ */ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Web.Caching; using ASC.Collections; -using ASC.Common.Data; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.Web.CRM.Classes; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; namespace ASC.CRM.Core.Dao { @@ -44,8 +43,17 @@ public class CachedInvoiceItemDao : InvoiceItemDao { private readonly HttpRequestDictionary _invoiceItemCache = new HttpRequestDictionary("crm_invoice_item"); - public CachedInvoiceItemDao(int tenantID) - : base(tenantID) + public CachedInvoiceItemDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + TenantUtil tenantUtil, + CRMSecurity cRMSecurity + ) : base(dbContextManager, + tenantManager, + securityContext, + tenantUtil, + cRMSecurity) + { } @@ -82,11 +90,23 @@ private void ResetCache(int invoiceItemID) public class InvoiceItemDao : AbstractDao { - public InvoiceItemDao(int tenantID) - : base(tenantID) + public InvoiceItemDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + TenantUtil tenantUtil, + CRMSecurity cRMSecurity + ) : base(dbContextManager, + tenantManager, + securityContext) { + TenantUtil = tenantUtil; + CRMSecurity = cRMSecurity; } + public CRMSecurity CRMSecurity { get; } + + public TenantUtil TenantUtil { get; } public Boolean IsExist(int invoiceItemID) { @@ -95,18 +115,14 @@ public Boolean IsExist(int invoiceItemID) public Boolean IsExistInDb(int invoiceItemID) { - return Db.ExecuteScalar(@"select exists(select 1 from crm_invoice_item where tenant_id = @tid and id = @id)", - new { tid = TenantID, id = invoiceItemID }); + return Query(CRMDbContext.InvoiceItem).Any(x => x.Id == invoiceItemID); } public Boolean CanDelete(int invoiceItemID) { - return Db.ExecuteScalar(@"select count(*) from crm_invoice_line where tenant_id = @tid and invoice_item_id = @id", - new { tid = TenantID, id = invoiceItemID }) == 0; + return Query(CRMDbContext.InvoiceLine).Any(x => x.InvoiceItemId == invoiceItemID); } - #region Get - public virtual List GetAll() { return GetAllInDb(); @@ -249,11 +265,6 @@ public int GetInvoiceItemsCount( return result; } - #endregion - - - #region SaveOrUpdate - public virtual InvoiceItem SaveOrUpdateInvoiceItem(InvoiceItem invoiceItem) { /*_cache.Remove(_invoiceItemCacheKey); @@ -336,11 +347,6 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) return invoiceItem; } - #endregion - - - #region Delete - public virtual InvoiceItem DeleteInvoiceItem(int invoiceItemID) { var invoiceItem = GetByID(invoiceItemID); @@ -348,7 +354,10 @@ public virtual InvoiceItem DeleteInvoiceItem(int invoiceItemID) CRMSecurity.DemandDelete(invoiceItem); - Db.ExecuteNonQuery(Delete("crm_invoice_item").Where("id", invoiceItemID)); + + + +// Db.ExecuteNonQuery(Delete("crm_invoice_item").Where("id", invoiceItemID)); /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ @@ -372,11 +381,6 @@ public virtual List DeleteBatchInvoiceItems(int[] invoiceItemIDs) return items; } - #endregion - - - #region Private Methods - private void DeleteBatchItemsExecute(List items) { var ids = items.Select(x => x.ID).ToArray(); @@ -388,25 +392,45 @@ private void DeleteBatchItemsExecute(List items) //} } - private static InvoiceItem ToInvoiceItem(object[] row) + private InvoiceItem ToInvoiceItem(DbInvoiceItem dbInvoiceItem) { return new InvoiceItem - { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - Description = Convert.ToString(row[2]), - StockKeepingUnit = Convert.ToString(row[3]), - Price = Convert.ToDecimal(row[4]), - StockQuantity = Convert.ToDecimal(row[5]), - TrackInventory = Convert.ToBoolean(row[6]), - InvoiceTax1ID = Convert.ToInt32(row[7]), - InvoiceTax2ID = Convert.ToInt32(row[8]), - Currency = Convert.ToString(row[9]), - CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[10].ToString())), - CreateBy = ToGuid(row[11]), - LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[12].ToString())), - LastModifedBy = ToGuid(row[13]) - }; + { + ID = dbInvoiceItem.Id, + Title = dbInvoiceItem.Title, + Description = dbInvoiceItem.Description, + StockKeepingUnit = dbInvoiceItem.StockKeepingUnit, + Price = dbInvoiceItem.Price, + StockQuantity = dbInvoiceItem.StockQuantity, + TrackInventory = dbInvoiceItem.TrackInventory, + InvoiceTax1ID = dbInvoiceItem.InvoiceTax1Id, + InvoiceTax2ID = dbInvoiceItem.InvoiceTax2Id, + Currency = dbInvoiceItem.Currency, + CreateOn = TenantUtil.DateTimeFromUtc(dbInvoiceItem.CreateOn), + CreateBy = dbInvoiceItem.CreateBy, + LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoiceItem.LastModifedOn), + LastModifedBy = dbInvoiceItem.LastModifedBy + }; + + + + //return new InvoiceItem + // { + // ID = Convert.ToInt32(row[0]), + // Title = Convert.ToString(row[1]), + // Description = Convert.ToString(row[2]), + // StockKeepingUnit = Convert.ToString(row[3]), + // Price = Convert.ToDecimal(row[4]), + // StockQuantity = Convert.ToDecimal(row[5]), + // TrackInventory = Convert.ToBoolean(row[6]), + // InvoiceTax1ID = Convert.ToInt32(row[7]), + // InvoiceTax2ID = Convert.ToInt32(row[8]), + // Currency = Convert.ToString(row[9]), + // CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[10].ToString())), + // CreateBy = ToGuid(row[11]), + // LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[12].ToString())), + // LastModifedBy = ToGuid(row[13]) + // }; } private SqlQuery GetInvoiceItemSqlQuery(Exp where) @@ -485,6 +509,5 @@ private Exp WhereConditional( return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); } - #endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 8fac8e076ab..55b2b92fbaf 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -24,17 +24,16 @@ */ +using ASC.Collections; +using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using ASC.Collections; -using ASC.Common.Data; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; -using ASC.CRM.Core.Entities; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using System.Text.RegularExpressions; namespace ASC.CRM.Core.Dao @@ -43,8 +42,12 @@ public class CachedInvoiceLineDao : InvoiceLineDao { private readonly HttpRequestDictionary _invoiceLineCache = new HttpRequestDictionary("crm_invoice_line"); - public CachedInvoiceLineDao(int tenantID) - : base(tenantID) + public CachedInvoiceLineDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { } @@ -81,9 +84,14 @@ private void ResetCache(int invoiceLineID) public class InvoiceLineDao : AbstractDao { - public InvoiceLineDao(int tenantID) - : base(tenantID) + public InvoiceLineDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { + } @@ -108,24 +116,23 @@ public static string GetJson(InvoiceTax invoiceTax) { description = invoiceTax.Description }); } - - #region Get - + public virtual List GetAll() { - return Db.ExecuteList(GetInvoiceLineSqlQuery(null)).ConvertAll(ToInvoiceLine); + return Query(CRMDbContext.InvoiceLine) + .ToList() + .ConvertAll(ToInvoiceLine); } public virtual List GetByID(int[] ids) { - return Db.ExecuteList(GetInvoiceLineSqlQuery(Exp.In("id", ids))).ConvertAll(ToInvoiceLine); + return Query(CRMDbContext.InvoiceLine).Where(x => ids.Contains(x.Id)).ToList() + .ConvertAll(ToInvoiceLine); } public virtual InvoiceLine GetByID(int id) { - var invoiceLines = Db.ExecuteList(GetInvoiceLineSqlQuery(Exp.Eq("id", id))).ConvertAll(ToInvoiceLine); - - return invoiceLines.Count > 0 ? invoiceLines[0] : null; + return ToInvoiceLine(Query(CRMDbContext.InvoiceLine).FirstOrDefault(x => x.Id == id)); } public List GetInvoiceLines(int invoiceID) @@ -135,14 +142,13 @@ public List GetInvoiceLines(int invoiceID) public List GetInvoiceLinesInDb(int invoiceID) { - return Db.ExecuteList(GetInvoiceLineSqlQuery(Exp.Eq("invoice_id", invoiceID)).OrderBy("sort_order", true)).ConvertAll(ToInvoiceLine); + return Query(CRMDbContext.InvoiceLine) + .Where(x => x.InvoiceId == invoiceID) + .OrderBy(x => x.SortOrder) + .ToList() + .ConvertAll(ToInvoiceLine); } - - #endregion - - - #region SaveOrUpdate - + public virtual int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -159,6 +165,7 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) { invoiceLine.Description = String.Empty; } + if (Db.ExecuteScalar(Query("crm_invoice_line").SelectCount().Where(Exp.Eq("id", invoiceLine.ID))) == 0) { @@ -194,28 +201,30 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) } return invoiceLine.ID; } - - #endregion - - - #region Delete - + public virtual void DeleteInvoiceLine(int invoiceLineID) { var invoiceLine = GetByID(invoiceLineID); if (invoiceLine == null) return; - Db.ExecuteNonQuery(Delete("crm_invoice_line").Where("id", invoiceLineID)); + var itemToDelete = new DbInvoiceLine { Id = invoiceLineID }; + CRMDbContext.Attach(itemToDelete); + CRMDbContext.Remove(itemToDelete); + CRMDbContext.SaveChanges(); + /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ } public void DeleteInvoiceLines(int invoiceID) { - Db.ExecuteNonQuery(Delete("crm_invoice_line").Where(Exp.Eq("invoice_id", invoiceID))); + var itemToDelete = Query(CRMDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceID); + CRMDbContext.RemoveRange(itemToDelete); + CRMDbContext.SaveChanges(); + /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ } @@ -227,63 +236,32 @@ public Boolean CanDelete(int invoiceLineID) public Boolean CanDeleteInDb(int invoiceLineID) { + var invoiceID = Query(CRMDbContext.InvoiceLine) + .Where(x => x.Id == invoiceLineID) + .Select(x => x.InvoiceId); - var invoiceID = Db.ExecuteScalar(Query("crm_invoice_line").Select("invoice_id") - .Where(Exp.Eq("id", invoiceLineID))); - - if (invoiceID == 0) return false; + if (!invoiceID.Any()) return false; - var count = Db.ExecuteScalar(Query("crm_invoice_line").SelectCount() - .Where(Exp.Eq("invoice_id", invoiceID))); - - return count > 1; + return Query(CRMDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceLineID).Any(); } - #endregion - - - #region Private Methods - - private static InvoiceLine ToInvoiceLine(object[] row) + private InvoiceLine ToInvoiceLine(DbInvoiceLine dbInvoiceLine) { - return new InvoiceLine - { - ID = Convert.ToInt32(row[0]), - InvoiceID = Convert.ToInt32(row[1]), - InvoiceItemID = Convert.ToInt32(row[2]), - InvoiceTax1ID = Convert.ToInt32(row[3]), - InvoiceTax2ID = Convert.ToInt32(row[4]), - SortOrder = Convert.ToInt32(row[5]), - Description = Convert.ToString(row[6]), - Quantity = Convert.ToDecimal(row[7]), - Price = Convert.ToDecimal(row[8]), - Discount = Convert.ToDecimal(row[9]) - }; - } + if (dbInvoiceLine == null) return null; - private SqlQuery GetInvoiceLineSqlQuery(Exp where) - { - var sqlQuery = Query("crm_invoice_line") - .Select( - "id", - "invoice_id", - "invoice_item_id", - "invoice_tax1_id", - "invoice_tax2_id", - "sort_order", - "description", - "quantity", - "price", - "discount"); - - if (where != null) + return new InvoiceLine { - sqlQuery.Where(where); - } - - return sqlQuery; + ID = dbInvoiceLine.Id, + InvoiceID = dbInvoiceLine.InvoiceId, + InvoiceItemID = dbInvoiceLine.InvoiceItemId, + InvoiceTax1ID = dbInvoiceLine.InvoiceTax1Id, + InvoiceTax2ID = dbInvoiceLine.InvoiceTax2Id, + SortOrder = dbInvoiceLine.SortOrder, + Description = dbInvoiceLine.Description, + Quantity = dbInvoiceLine.Quantity, + Price = dbInvoiceLine.Price, + Discount = dbInvoiceLine.Discount + }; } - - #endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index b179c0cad82..36da62eb929 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -24,17 +24,16 @@ */ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; using ASC.Collections; -using ASC.Common.Data; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; namespace ASC.CRM.Core.Dao { @@ -80,68 +79,67 @@ private void ResetCache(int invoiceTaxID) public class InvoiceTaxDao : AbstractDao { - public InvoiceTaxDao(int tenantID) - : base(tenantID) + public InvoiceTaxDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext + ) + : base(dbContextManager, + tenantManager, + securityContext) { + } + public TenantUtil TenantUtil { get; } + public CRMSecurity CRMSecurity { get; } public Boolean IsExist(int invoiceTaxID) { - return Db.ExecuteScalar( - @"select exists(select 1 from crm_invoice_tax where tenant_id = @tid and id = @id)", - new {tid = TenantID, id = invoiceTaxID}); + return CRMDbContext.InvoiceTax.Where(x => x.Id == invoiceTaxID).Any(); } public Boolean IsExist(String invoiceName) { - var q = new SqlQuery("crm_invoice_tax") - .Select("1") - .Where("tenant_id", TenantID) - .Where("name", invoiceName) - .SetMaxResults(1); - - return Db.ExecuteScalar(q); + return Query(CRMDbContext.InvoiceTax).Where(x => String.Compare(x.Name, invoiceName, true) == 0).Any(); } public Boolean CanDelete(int invoiceTaxID) { - var count1 = Db.ExecuteScalar(@"select count(*) from crm_invoice_item where tenant_id = @tid and (invoice_tax1_id = @id or invoice_tax2_id = @id)", - new { tid = TenantID, id = invoiceTaxID }); - var count2 = Db.ExecuteScalar(@"select count(*) from crm_invoice_line where tenant_id = @tid and (invoice_tax1_id = @id or invoice_tax2_id = @id)", - new { tid = TenantID, id = invoiceTaxID }); - - return count1 == 0 && count2 == 0; + return !Query(CRMDbContext.InvoiceItem) + .Where(x => x.InvoiceTax1Id == invoiceTaxID || x.InvoiceTax2Id == invoiceTaxID).Any() && + !Query(CRMDbContext.InvoiceLine) + .Where(x => x.InvoiceTax1Id == invoiceTaxID || x.InvoiceTax2Id == invoiceTaxID).Any(); } - #region Get - public virtual List GetAll() { - return Db.ExecuteList(GetInvoiceTaxSqlQuery(null)).ConvertAll(ToInvoiceTax); + return Query(CRMDbContext.InvoiceTax) + .ToList() + .ConvertAll(ToInvoiceTax); } public DateTime GetMaxLastModified() { - return Db.ExecuteScalar(Query("crm_invoice_tax").Select("last_modifed_on")); + throw new NotImplementedException(); + +// return Query(CRMDbContext.InvoiceItem).Select(x => x.la) +// return Db.ExecuteScalar(Query("crm_invoice_tax").Select("last_modifed_on")); } public virtual List GetByID(int[] ids) { - return Db.ExecuteList(GetInvoiceTaxSqlQuery(Exp.In("id", ids))).ConvertAll(ToInvoiceTax); + return Query(CRMDbContext.InvoiceTax) + .Where(x => ids.Contains(x.Id)) + .ToList() + .ConvertAll(ToInvoiceTax); } public virtual InvoiceTax GetByID(int id) { - var invoiceTaxes = Db.ExecuteList(GetInvoiceTaxSqlQuery(Exp.Eq("id", id))).ConvertAll(ToInvoiceTax); - - return invoiceTaxes.Count > 0 ? invoiceTaxes[0] : null; + return ToInvoiceTax(CRMDbContext.InvoiceTax.FirstOrDefault(x => x.Id == id)); } - #endregion - - #region SaveOrUpdate - public virtual InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) { /*_cache.Remove(_invoiceItemCacheKey); @@ -158,31 +156,55 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) invoiceTax.LastModifedBy = SecurityContext.CurrentAccount.ID; invoiceTax.LastModifedOn = DateTime.UtcNow; - if (Db.ExecuteScalar(Query("crm_invoice_tax").SelectCount().Where(Exp.Eq("id", invoiceTax.ID))) == 0) + if (!Query(CRMDbContext.InvoiceTax).Where(x => x.Id == invoiceTax.ID).Any()) { invoiceTax.CreateOn = DateTime.UtcNow; invoiceTax.CreateBy = SecurityContext.CurrentAccount.ID; - invoiceTax.ID = Db.ExecuteScalar( - Insert("crm_invoice_tax") - .InColumnValue("id", 0) - .InColumnValue("name", invoiceTax.Name) - .InColumnValue("description", invoiceTax.Description) - .InColumnValue("rate", invoiceTax.Rate) - .InColumnValue("create_on", invoiceTax.CreateOn) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", invoiceTax.LastModifedOn) - .InColumnValue("last_modifed_by", invoiceTax.LastModifedBy) - .Identity(1, 0, true)); + var itemToInsert = new DbInvoiceTax + { + Id = 0, + Name = invoiceTax.Name, + Description = invoiceTax.Description, + Rate = invoiceTax.Rate, + CreateOn = invoiceTax.CreateOn, + CreateBy = invoiceTax.CreateBy, + LastModifedBy = invoiceTax.LastModifedBy, + LastModifedOn = invoiceTax.LastModifedOn, + TenantId = TenantID + }; + + CRMDbContext.InvoiceTax.Add(itemToInsert); + + CRMDbContext.SaveChanges(); + + //invoiceTax.ID = Db.ExecuteScalar( + // Insert("crm_invoice_tax") + // .InColumnValue("id", 0) + // .InColumnValue("name", invoiceTax.Name) + // .InColumnValue("description", invoiceTax.Description) + // .InColumnValue("rate", invoiceTax.Rate) + // .InColumnValue("create_on", invoiceTax.CreateOn) + // .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + // .InColumnValue("last_modifed_on", invoiceTax.LastModifedOn) + // .InColumnValue("last_modifed_by", invoiceTax.LastModifedBy) + // .Identity(1, 0, true)); + + + } else { - var oldInvoiceTax = Db.ExecuteList(GetInvoiceTaxSqlQuery(Exp.Eq("id", invoiceTax.ID))) - .ConvertAll(ToInvoiceTax) - .FirstOrDefault(); - + var oldInvoiceTax = GetByID(invoiceTax.ID); + CRMSecurity.DemandEdit(oldInvoiceTax); +// throw new NotImplementedException(); + + CRMDbContext.InvoiceTax.Add(itemToInsert); + + CRMDbContext.SaveChanges(); + Db.ExecuteNonQuery( Update("crm_invoice_tax") .Set("name", invoiceTax.Name) @@ -195,12 +217,7 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) return invoiceTax; } - - #endregion - - - #region Delete - + public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) { var invoiceTax = GetByID(invoiceTaxID); @@ -209,54 +226,48 @@ public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) CRMSecurity.DemandDelete(invoiceTax); - Db.ExecuteNonQuery(Delete("crm_invoice_tax").Where("id", invoiceTaxID)); + var itemToDelete = new DbInvoiceTax + { + Id = invoiceTaxID + }; + + CRMDbContext.Attach(invoiceTax); + CRMDbContext.Remove(itemToDelete); + + CRMDbContext.SaveChanges(); /* _cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ return invoiceTax; } - #endregion - - - #region Private Methods - - private static InvoiceTax ToInvoiceTax(object[] row) + private InvoiceTax ToInvoiceTax(DbInvoiceTax dbInvoiceTax) { - return new InvoiceTax - { - ID = Convert.ToInt32(row[0]), - Name = Convert.ToString(row[1]), - Description = Convert.ToString(row[2]), - Rate = Convert.ToDecimal(row[3]), - CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[4].ToString())), - CreateBy = ToGuid(row[5]), - LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[6].ToString())), - LastModifedBy = ToGuid(row[7]) - }; - } + if (dbInvoiceTax == null) return null; - private SqlQuery GetInvoiceTaxSqlQuery(Exp where) - { - var sqlQuery = Query("crm_invoice_tax") - .Select( - "id", - "name", - "description", - "rate", - "create_on", - "create_by", - "last_modifed_on", - "last_modifed_by"); - - if (where != null) + return new InvoiceTax { - sqlQuery.Where(where); - } - - return sqlQuery; + ID = dbInvoiceTax.Id, + Name = dbInvoiceTax.Name, + Description = dbInvoiceTax.Description, + Rate = dbInvoiceTax.Rate, + CreateOn = dbInvoiceTax.CreateOn, + CreateBy = dbInvoiceTax.CreateBy, + LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoiceTax.LastModifedOn), + LastModifedBy = dbInvoiceTax.LastModifedBy + }; + + //return new InvoiceTax + // { + // ID = Convert.ToInt32(row[0]), + // Name = Convert.ToString(row[1]), + // Description = Convert.ToString(row[2]), + // Rate = Convert.ToDecimal(row[3]), + // CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[4].ToString())), + // CreateBy = ToGuid(row[5]), + // LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[6].ToString())), + // LastModifedBy = ToGuid(row[7]) + // }; } - - #endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 13ae3b83e1b..0b8e9a1fdce 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -23,36 +23,26 @@ * */ - -#region Import - +using ASC.Collections; +using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Classes; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; -using ASC.Collections; -using ASC.Web.CRM.Classes; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; -using ASC.CRM.Core.Entities; -using ASC.Web.CRM.Resources; - -#endregion namespace ASC.CRM.Core.Dao { public class CachedListItem : ListItemDao { - - #region Members - private readonly HttpRequestDictionary _listItemCache = new HttpRequestDictionary("crm_list_item"); - #endregion - - #region Constructor - public CachedListItem(int tenantID) : base(tenantID) { @@ -60,10 +50,6 @@ public CachedListItem(int tenantID) } - #endregion - - #region Members - public override void ChangeColor(int id, string newColor) { ResetCache(id); @@ -113,66 +99,56 @@ private void ResetCache(int id) { _listItemCache.Reset(id.ToString()); } - - #endregion - - } public class ListItemDao : AbstractDao { - #region Constructor - - public ListItemDao(int tenantID) - : base(tenantID) + public ListItemDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { } - #endregion - - - public bool IsExist(ListType listType, String title) { - var q = new SqlQuery("crm_list_item") - .Select("1") - .Where("tenant_id", TenantID) - .Where("list_type", (int)listType) - .Where("title", title) - .SetMaxResults(1); - - return Db.ExecuteScalar(q); + return CRMDbContext.ListItem + .Where(x => x.TenantId == TenantID && x.ListType == listType && String.Compare(x.Title, title, true) == 0) + .Any(); } public bool IsExist(int id) { - return Db.ExecuteScalar("select exists(select 1 from crm_list_item where tenant_id = @tid and id = @id)", - new { tid = TenantID, id = id }); + return CRMDbContext.ListItem.Where(x => x.Id == id).Any(); } public List GetItems() { - var sqlQuery = GetListItemSqlQuery(null).OrderBy("sort_order", true); - - return Db.ExecuteList(sqlQuery).ConvertAll(ToListItem); + return Query(CRMDbContext.ListItem) + .OrderBy(x => x.SortOrder) + .ToList() + .ConvertAll(ToListItem); } public List GetItems(ListType listType) { - var sqlQuery = GetListItemSqlQuery(Exp.Eq("list_type", (int)listType)) - .OrderBy("sort_order", true); - - return Db.ExecuteList(sqlQuery).ConvertAll(ToListItem); + return Query(CRMDbContext.ListItem) + .Where(x => x.ListType == listType) + .OrderBy(x => x.SortOrder) + .ToList() + .ConvertAll(ToListItem); } public int GetItemsCount(ListType listType) { - SqlQuery sqlQuery = Query("crm_list_item").SelectCount().Where(Exp.Eq("list_type", (int)listType)) - .OrderBy("sort_order", true); - - return Db.ExecuteScalar(sqlQuery); + return Query(CRMDbContext.ListItem) + .Where(x => x.ListType == listType) + .OrderBy(x => x.SortOrder).Count(); } public ListItem GetSystemListItem(int id) @@ -181,25 +157,25 @@ public ListItem GetSystemListItem(int id) { case (int)HistoryCategorySystem.TaskClosed: return new ListItem - { - ID = -1, - Title = HistoryCategorySystem.TaskClosed.ToLocalizedString(), - AdditionalParams = "event_category_close.png" - }; + { + ID = -1, + Title = HistoryCategorySystem.TaskClosed.ToLocalizedString(), + AdditionalParams = "event_category_close.png" + }; case (int)HistoryCategorySystem.FilesUpload: return new ListItem - { - ID = -2, - Title = HistoryCategorySystem.FilesUpload.ToLocalizedString(), - AdditionalParams = "event_category_attach_file.png" - }; + { + ID = -2, + Title = HistoryCategorySystem.FilesUpload.ToLocalizedString(), + AdditionalParams = "event_category_attach_file.png" + }; case (int)HistoryCategorySystem.MailMessage: - return new ListItem - { - ID = -3, - Title = HistoryCategorySystem.MailMessage.ToLocalizedString(), - AdditionalParams = "event_category_email.png" - }; + return new ListItem + { + ID = -3, + Title = HistoryCategorySystem.MailMessage.ToLocalizedString(), + AdditionalParams = "event_category_email.png" + }; default: return null; } @@ -234,10 +210,8 @@ public List GetSystemItems() public virtual ListItem GetByID(int id) { if (id < 0) return GetSystemListItem(id); - - var result = Db.ExecuteList(GetListItemSqlQuery(Exp.Eq("id", id))).ConvertAll(ToListItem); - - return result.Count > 0 ? result[0] : null; + + return ToListItem(Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == id)); } public virtual List GetItems(int[] id) @@ -251,7 +225,10 @@ public virtual List GetItems(int[] id) public virtual List GetAll() { - return Db.ExecuteList(GetListItemSqlQuery(null)).ConvertAll(ToListItem); + return CRMDbContext + .ListItem + .ToList() + .ConvertAll(ToListItem); } public virtual void ChangeColor(int id, string newColor) @@ -277,9 +254,8 @@ public NameValueCollection GetColors(ListType listType) public ListItem GetByTitle(ListType listType, string title) { - var result = Db.ExecuteList(GetListItemSqlQuery(Exp.Eq("title", title) & Exp.Eq("list_type", (int)listType))).ConvertAll(ToListItem); - - return result.Count > 0 ? result[0] : null; + return ToListItem(Query(CRMDbContext.ListItem) + .FirstOrDefault(x => String.Compare(x.Title, title, true) == 0 && x.ListType == listType)); } public int GetRelativeItemsCount(ListType listType, int id) @@ -313,7 +289,7 @@ public int GetRelativeItemsCount(ListType listType, int id) break; default: throw new ArgumentException(); - + } return Db.ExecuteScalar(sqlQuery); @@ -376,8 +352,8 @@ public virtual int CreateItem(ListType listType, ListItem enumItem) if (string.IsNullOrEmpty(enumItem.AdditionalParams)) throw new ArgumentException(); else - enumItem.AdditionalParams = System.IO.Path.GetFileName(enumItem.AdditionalParams); - + enumItem.AdditionalParams = System.IO.Path.GetFileName(enumItem.AdditionalParams); + if (listType == ListType.ContactStatus) if (string.IsNullOrEmpty(enumItem.Color)) throw new ArgumentException(); @@ -405,18 +381,18 @@ public virtual void EditItem(ListType listType, ListItem enumItem) { if (HaveRelativeItemsLink(listType, enumItem.ID)) - switch (listType) - { - case ListType.ContactStatus: - case ListType.ContactType: - throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.HasRelatedContacts)); - case ListType.TaskCategory: - throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.TaskCategoryHasRelatedTasks)); - case ListType.HistoryCategory: - throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.HistoryCategoryHasRelatedEvents)); - default: - throw new ArgumentException(string.Format("{0}.", CRMErrorsResource.BasicCannotBeEdited)); - } + switch (listType) + { + case ListType.ContactStatus: + case ListType.ContactType: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.HasRelatedContacts)); + case ListType.TaskCategory: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.TaskCategoryHasRelatedTasks)); + case ListType.HistoryCategory: + throw new ArgumentException(string.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.HistoryCategoryHasRelatedEvents)); + default: + throw new ArgumentException(string.Format("{0}.", CRMErrorsResource.BasicCannotBeEdited)); + } Db.ExecuteNonQuery(Update("crm_list_item") .Set("description", enumItem.Description) @@ -428,6 +404,7 @@ public virtual void EditItem(ListType listType, ListItem enumItem) public virtual void ChangePicture(int id, String newPicture) { + Db.ExecuteNonQuery(Update("crm_list_item") .Set("additional_params", newPicture) .Where(Exp.Eq("id", id))); @@ -468,14 +445,12 @@ public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toIte { if (!IsExist(fromItemID)) throw new ArgumentException("", "toItemID"); - + if (!HaveRelativeItemsLink(listType, fromItemID)) return; if (!IsExist(toItemID)) throw new ArgumentException("", "toItemID"); - - SqlUpdate sqlUpdate; - + switch (listType) { case ListType.ContactStatus: @@ -495,7 +470,7 @@ public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toIte break; case ListType.HistoryCategory: sqlUpdate = Update("crm_relationship_event") - .Set("category_id", toItemID) + .Set("category_id", toItemID) .Where(Exp.Eq("category_id", fromItemID)); break; default: @@ -526,61 +501,45 @@ public virtual void DeleteItem(ListType listType, int itemID, int toItemID) } } - Db.ExecuteNonQuery(Delete("crm_list_item").Where(Exp.Eq("id", itemID) & Exp.Eq("list_type", (int)listType))); - } + var itemToRemove = Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == itemID); - public virtual void ReorderItems(ListType listType, String[] titles) - { - using (var tx = Db.BeginTransaction()) - { - for (int index = 0; index < titles.Length; index++) - Db.ExecuteNonQuery(Update("crm_list_item") - .Set("sort_order", index) - .Where(Exp.Eq("title", titles[index]) & Exp.Eq("list_type", (int)listType))); + CRMDbContext.ListItem.Remove(itemToRemove); + CRMDbContext.SaveChanges(); - tx.Commit(); - } } - private SqlQuery GetListItemSqlQuery(Exp where) + public virtual void ReorderItems(ListType listType, String[] titles) { - var result = Query("crm_list_item") - .Select( - "id", - "title", - "description", - "color", - "sort_order", - "additional_params", - "list_type" - ); + using var tx = CRMDbContext.Database.BeginTransaction(); - if (where != null) - result.Where(where); + for (int index = 0; index < titles.Length; index++) + { + Db.ExecuteNonQuery(Update("crm_list_item") + .Set("sort_order", index) + .Where(Exp.Eq("title", titles[index]) & Exp.Eq("list_type", (int)listType))); - return result; + } + + tx.Commit(); } - public static ListItem ToListItem(object[] row) + public static ListItem ToListItem(DbListItem dbListItem) { + if (dbListItem == null) return null; + var result = new ListItem - { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - Description = Convert.ToString(row[2]), - Color = Convert.ToString(row[3]), - SortOrder = Convert.ToInt32(row[4]), - AdditionalParams = Convert.ToString(row[5]) - }; - - ListType listType; - if (Enum.TryParse(Convert.ToString(row[6]), out listType)) { - result.ListType = listType; - } + ID = dbListItem.Id, + Title = dbListItem.Title, + Description = dbListItem.Description, + Color = dbListItem.Color, + SortOrder = dbListItem.SortOrder, + AdditionalParams = dbListItem.AdditionalParams, + ListType = dbListItem.ListType + }; return result; } } -} +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs index 3a64e6e717e..20dd03ba0eb 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs @@ -36,6 +36,7 @@ using ASC.Common.Data.Sql; using ASC.Common.Data.Sql.Expressions; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; #endregion diff --git a/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs b/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs index cbba83fa91a..688bb1a58b1 100644 --- a/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs @@ -48,9 +48,6 @@ namespace ASC.CRM.Core.Dao public class ManagerDao : AbstractDao { - - #region Constructor - public ManagerDao(int tenantID, String storageKey) : base(tenantID, storageKey) { @@ -58,10 +55,6 @@ public ManagerDao(int tenantID, String storageKey) } - #endregion - - #region Methods - public void Add(Guid managerID) { DbManager.ExecuteNonQuery(Insert("crm_manager").InColumnValue("id", managerID)); @@ -70,7 +63,7 @@ public void Add(Guid managerID) public void Remove(Guid managerID) { - + DbManager.ExecuteNonQuery(Delete("crm_manager").Where(Exp.Eq("id", managerID))); } @@ -86,8 +79,6 @@ public List GetAll(bool includeAdmins) return managers; } - #endregion - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 8812af3e59d..a0c57eef6b9 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -321,8 +321,8 @@ public RelationshipEvent CreateItem(RelationshipEvent item) if (item.CreateOn == DateTime.MinValue) item.CreateOn = TenantUtil.DateTimeNow(); - item.CreateBy = ASC.Core.SecurityContext.CurrentAccount.ID; - item.LastModifedBy = ASC.Core.SecurityContext.CurrentAccount.ID; + item.CreateBy = SecurityContext.CurrentAccount.ID; + item.LastModifedBy = SecurityContext.CurrentAccount.ID; if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) { diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index 4e374c81b94..f48258654cd 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -45,29 +45,17 @@ namespace ASC.CRM.Core.Dao { public class SearchDao : AbstractDao - { - #region Members - + { private Dictionary> _findedIDs; private bool _fullTextSearchEnable; private DaoFactory DaoFactory { get; set; } - - #endregion - - #region Constructor - + public SearchDao(int tenantID, DaoFactory daoFactory) : base(tenantID) { DaoFactory = daoFactory; } - #endregion - - #region Methods - - #region Public - public SearchResultItem[] Search(String searchText) { var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) @@ -131,11 +119,7 @@ public SearchResultItem[] Search(String searchText) return ToSearchResultItem(Db.ExecuteList(searchQuery)); } - - #endregion - - #region Private - + private Dictionary> SearchByRelationshipEvent(String[] keywords) { var historyQuery = Query("crm_relationship_event") @@ -434,9 +418,5 @@ private String GetPath(int contactID, int entityID, EntityType entityType) throw new ArgumentException(); } } - - #endregion - - #endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 081b1833851..eb2a7523a94 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -24,34 +24,31 @@ */ +using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using Microsoft.EntityFrameworkCore.Internal; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; -using ASC.Common.Data; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; -using ASC.CRM.Core.Entities; -using Newtonsoft.Json; -using ASC.Web.CRM.Resources; -using ASC.CRM.Core.Enums; namespace ASC.CRM.Core.Dao { public class TagDao : AbstractDao { - #region Constructor - - public TagDao(int tenantID) - : base(tenantID) + public TagDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) : + base(dbContextManager, + tenantManager, + securityContext) { - } - #endregion - - #region Methods - public bool IsExist(EntityType entityType, String tagName) { if (String.IsNullOrEmpty(tagName)) @@ -62,46 +59,32 @@ public bool IsExist(EntityType entityType, String tagName) private bool IsExistInDb(EntityType entityType, String tagName) { - var q = new SqlQuery("crm_tag") - .Select("1") - .Where("tenant_id", TenantID) - .Where("entity_type", (int)entityType) - .Where("trim(lower(title))", tagName.Trim().ToLower()) - .SetMaxResults(1); - - return Db.ExecuteScalar(q); + return Query(CRMDbContext.Tags) + .Where(x => x.EntityType == entityType && String.Compare(x.Title, tagName, true) == 0).Any(); } private int GetTagId(EntityType entityType, String tagName) { - var q = new SqlQuery("crm_tag") - .Select("id") - .Where("tenant_id", TenantID) - .Where("entity_type", (int)entityType) - .Where("trim(lower(title))", tagName.Trim().ToLower()) - .SetMaxResults(1); - - return Db.ExecuteScalar(q); + return Query(CRMDbContext.Tags) + .Where(x => x.EntityType == entityType && String.Compare(x.Title, tagName, true) == 0) + .Select(x => x.Id) + .SingleOrDefault(); } public String[] GetAllTags(EntityType entityType) { - return Db.ExecuteList( - Query("crm_tag") - .Select("title") - .Where(Exp.Eq("entity_type", (int)entityType)) - .OrderBy("title", true)).ConvertAll(row => row[0].ToString()).ToArray(); + return CRMDbContext.Tags + .Where(x => x.EntityType == entityType) + .OrderBy(x => x.Title) + .Select(x => x.Title) + .ToArray(); } public List> GetAllTags() { - return Db.ExecuteList( - Query("crm_tag") - .Select("title", "entity_type") - .OrderBy("title", true)) - .ConvertAll(row => new KeyValuePair( - (EntityType)Enum.Parse(typeof(EntityType), row[1].ToString(), true), - row[0].ToString())); + return Query(CRMDbContext.Tags) + .OrderBy(x => x.Title) + .Select(x => new KeyValuePair (x.EntityType, x.Title)).ToList(); } public String GetTagsLinkCountJSON(EntityType entityType) @@ -112,21 +95,42 @@ public String GetTagsLinkCountJSON(EntityType entityType) public IEnumerable GetTagsLinkCount(EntityType entityType) { - var sqlQuery = new SqlQuery("crm_tag tbl_tag") - .SelectCount("tag_id") - .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) - .Where(Exp.Eq("tbl_tag.entity_type", (int)entityType) & Exp.Eq("tbl_tag.tenant_id", TenantID)) - .OrderBy("title", true) - .GroupBy("tbl_tag.id"); - - var queryResult = Db.ExecuteList(sqlQuery); - return queryResult.ConvertAll(row => Convert.ToInt32(row[0])); + + //var temp = Query(CRMDbContext.Tags) + // .Join(CRMDbContext.CrmEntityTag, + // x => x.Id, + // y => y.TagId, + // (x, y) => new + // { + // x, + // y + + // }) + // .Where(x => x.y.EntityType == entityType) + // .GroupBy(x=> x.x.Id) + // .OrderBy(x => x.x.Title) + + // .Count(); + + + + //var sqlQuery = new SqlQuery("crm_tag tbl_tag") + // .SelectCount("tag_id") + // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) + // .Where(Exp.Eq("tbl_tag.entity_type", (int)entityType) & Exp.Eq("tbl_tag.tenant_id", TenantID)) + // .OrderBy("title", true) + // .GroupBy("tbl_tag.id"); + + //var queryResult = Db.ExecuteList(sqlQuery); + + // return queryResult.ConvertAll(row => Convert.ToInt32(row[0])); + + throw new NotImplementedException(); } public Dictionary> GetEntitiesTags(EntityType entityType) { - var result = new Dictionary>(); var sqlQuery = @@ -154,31 +158,47 @@ public Dictionary> GetEntitiesTags(EntityType entityType) public String[] GetEntityTags(EntityType entityType, int entityID) { - - SqlQuery sqlQuery = Query("crm_tag") - .Select("title") - .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) - .Where(Exp.Eq("entity_id", entityID) & Exp.Eq("crm_tag.entity_type", (int)entityType)); - - return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToString(row[0])).ToArray(); + //SqlQuery sqlQuery = Query("crm_tag") + // .Select("title") + // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) + // .Where(Exp.Eq("entity_id", entityID) & Exp.Eq("crm_tag.entity_type", (int)entityType)); + + //return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToString(row[0])).ToArray(); + + return Query(CRMDbContext.Tags) + .Join(CRMDbContext.EntityTags, + x => x.Id, + y => y.TagId, + (x, y) => new + { + x, y + + }) + .Where(x => x.y.EntityId == entityID && x.y.EntityType == entityType) + .Select(x => x.x.Title).ToArray(); } - - - - public String[] GetUnusedTags(EntityType entityType) + + public string[] GetUnusedTags(EntityType entityType) { - return Db.ExecuteList(Query("crm_tag") - .Select("title") - .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) - .Where(Exp.Eq("tag_id", Exp.Empty) & Exp.Eq("crm_tag.entity_type", (int)entityType))).ConvertAll(row => Convert.ToString(row[0])).ToArray(); + return Query(CRMDbContext.Tags) + .GroupJoin(CRMDbContext.EntityTags.DefaultIfEmpty(), + x => x.Id, + y => y.TagId, + (x, y) => new { x, y }) + .Where(x => x.y == null && x.x.EntityType == entityType) + .Select(x => x.x.Title).ToArray(); + + //return Db.ExecuteList(Query("crm_tag") + // .Select("title") + // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) + // .Where(Exp.Eq("tag_id", Exp.Empty) & Exp.Eq("crm_tag.entity_type", (int)entityType))).ConvertAll(row => Convert.ToString(row[0])).ToArray(); } public bool CanDeleteTag(EntityType entityType, String tagName) { - var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") - .Where(Exp.Eq("trim(lower(title))", tagName.Trim().ToLower()) & Exp.Eq("entity_type", (int)entityType))); - - return tagID != 0; + return Query(CRMDbContext.Tags) + .Where(x => string.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) + .Select(x => x.Id).SingleOrDefault() != 0; } public void DeleteTag(EntityType entityType, String tagName) @@ -190,57 +210,70 @@ public void DeleteTag(EntityType entityType, String tagName) public void DeleteTagFromEntity(EntityType entityType, int entityID, String tagName) { - var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") - .Where(Exp.Eq("trim(lower(title))", tagName.Trim().ToLower()) & Exp.Eq("entity_type", (int)entityType))); - + var tagID = Query(CRMDbContext.Tags) + .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) + .Select(x => x.Id).SingleOrDefault(); + if (tagID == 0) return; - var sqlQuery = new SqlDelete("crm_entity_tag") - .Where(Exp.Eq("entity_type", (int)entityType) & Exp.Eq("tag_id", tagID)); + var itemsToRemove = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && x.TagId == tagID); if (entityID > 0) - sqlQuery.Where(Exp.Eq("entity_id", entityID)); + itemsToRemove = itemsToRemove.Where(x => x.EntityId == entityID); - Db.ExecuteNonQuery(sqlQuery); + CRMDbContext.RemoveRange(itemsToRemove); if (entityID == 0) - Db.ExecuteNonQuery(Delete("crm_tag") - .Where(Exp.Eq("id", tagID) & Exp.Eq("entity_type", (int)entityType))); + CRMDbContext.Tags.RemoveRange(Query(CRMDbContext.Tags).Where(x => x.Id == tagID && x.EntityType == entityType)); + + CRMDbContext.SaveChanges(); } public void DeleteAllTagsFromEntity(EntityType entityType, int entityID) { if (entityID <= 0) return; - var sqlQuery = new SqlDelete("crm_entity_tag") - .Where(Exp.Eq("entity_type", (int)entityType) & Exp.Eq("entity_id", entityID)); + var itemsToRemove = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && x.EntityId == entityID); + + CRMDbContext.EntityTags.RemoveRange(itemsToRemove); - Db.ExecuteNonQuery(sqlQuery); + CRMDbContext.SaveChanges(); } public void DeleteUnusedTags(EntityType entityType) { - if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - using (var tx = Db.BeginTransaction()) - { + using var tx = CRMDbContext.Database.BeginTransaction(); - var sqlSubQuery = Query("crm_tag") - .Select("id") - .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) - .Where(Exp.Eq("crm_tag.entity_type", (int)entityType) & Exp.Eq("tag_id", Exp.Empty)); - var tagIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => Convert.ToInt32(row[0])); + //var temp = from e in CRMDbContext.Tags + // select new { }; - if (tagIDs.Count > 0) - Db.ExecuteNonQuery(Delete("crm_tag").Where(Exp.In("id", tagIDs) & Exp.Eq("entity_type", (int)entityType))); +// Query(CRMDbContext.Tags).Join() +// .Select(x => x.Id); + //var sqlSubQuery = Query("crm_tag") + // .Select("id") + // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) + // .Where(Exp.Eq("crm_tag.entity_type", (int)entityType) & Exp.Eq("tag_id", Exp.Empty)); - tx.Commit(); - } + //List tagIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => Convert.ToInt32(row[0])); + + // Query(CRMDbContext.Tags).Join() + + //if (tagIDs.Count > 0) + //{ + // var itemToDelete = Query(CRMDbContext.Tags).Where(x => x.EntityType == entityType && tagIDs.Contains(x.Id)); + + // CRMDbContext.RemoveRange(itemToDelete); + //} + + CRMDbContext.SaveChanges(); + + tx.Commit(); } public int AddTag(EntityType entityType, String tagName, bool returnExisted = false) @@ -264,42 +297,43 @@ public int AddTag(EntityType entityType, String tagName, bool returnExisted = fa private int AddTagInDb(EntityType entityType, String tagName) { - return Db.ExecuteScalar( - Insert("crm_tag") - .InColumnValue("id", 0) - .InColumnValue("title", tagName) - .InColumnValue("entity_type", (int)entityType) - .Identity(1, 0, true)); + var dbTag = new DbTag + { + Title = tagName, + EntityType = entityType + }; + + CRMDbContext.Tags.Add(dbTag); + + CRMDbContext.SaveChanges(); + + return dbTag.Id; } public Dictionary GetAndAddTags(EntityType entityType, String[] tags) { tags = tags.Select(CorrectTag).Where(t => !string.IsNullOrWhiteSpace(t)).ToArray(); + + using var tx = CRMDbContext.Database.BeginTransaction(); - var tagNamesAndIds = new Dictionary(); + var tagNamesAndIds = Query(CRMDbContext.Tags) + .Where(x => tags.Contains(x.Title) && x.EntityType == entityType) + .Select(x => new { x.Id, x.Title }) + .ToDictionary(x => x.Title, x => x.Id); + + var tagsForCreate = tags.Where(t => !tagNamesAndIds.ContainsKey(t)); - using (var tx = Db.BeginTransaction()) + foreach (var tagName in tagsForCreate) { - - Db.ExecuteList(Query("crm_tag").Select("id", "title") - .Where(Exp.In("trim(lower(title))", tags.ToList().ConvertAll(t => t.ToLower())) & Exp.Eq("entity_type", (int)entityType))) - .ForEach(row => - { tagNamesAndIds[row[1].ToString()] = (int)row[0]; }); - - var tagsForCreate = tags.Where(t => !tagNamesAndIds.ContainsKey(t)); - - foreach (var tagName in tagsForCreate) - { - tagNamesAndIds.Add(tagName, AddTagInDb(entityType, tagName)); - } - - tx.Commit(); - return tagNamesAndIds; + tagNamesAndIds.Add(tagName, AddTagInDb(entityType, tagName)); } - } + tx.Commit(); + return tagNamesAndIds; + } + private int AddTagToEntityInDb(EntityType entityType, int entityID, String tagName) { tagName = CorrectTag(tagName); @@ -307,16 +341,21 @@ private int AddTagToEntityInDb(EntityType entityType, int entityID, String tagNa if (String.IsNullOrEmpty(tagName) || entityID == 0) throw new ArgumentException(); - var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") - .Where(Exp.Eq("trim(lower(title))", tagName.ToLower()) & Exp.Eq("entity_type", (int)entityType))); + var tagID = Query(CRMDbContext.Tags) + .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) + .Select(x => x.Id).SingleOrDefault(); if (tagID == 0) tagID = AddTagInDb(entityType, tagName); - Db.ExecuteNonQuery(new SqlInsert("crm_entity_tag", true) - .InColumnValue("entity_id", entityID) - .InColumnValue("entity_type", (int)entityType) - .InColumnValue("tag_id", tagID)); + CRMDbContext.EntityTags.Add(new DbEntityTag + { + EntityId = entityID, + EntityType = entityType, + TagId = tagID + }); + + CRMDbContext.SaveChanges(); return tagID; } @@ -333,24 +372,30 @@ public int AddTagToContacts(int[] contactID, String tagName) if (String.IsNullOrEmpty(tagName) || contactID == null || contactID.Length == 0) throw new ArgumentException(); - using (var tx = Db.BeginTransaction()) - { - var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") - .Where(Exp.Eq("trim(lower(title))", tagName.ToLower()) & Exp.Eq("entity_type", (int)EntityType.Contact))); + using var tx = CRMDbContext.Database.BeginTransaction(); + + var tagID = Query(CRMDbContext.Tags) + .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == EntityType.Contact) + .Select(x => x.Id).SingleOrDefault(); - if (tagID == 0) - tagID = AddTagInDb(EntityType.Contact, tagName); + if (tagID == 0) + tagID = AddTagInDb(EntityType.Contact, tagName); - foreach (var id in contactID) + foreach (var id in contactID) + { + CRMDbContext.EntityTags.Add(new DbEntityTag { - Db.ExecuteNonQuery(new SqlInsert("crm_entity_tag", true) - .InColumnValue("entity_id", id) - .InColumnValue("entity_type", (int)EntityType.Contact) - .InColumnValue("tag_id", tagID)); - } - tx.Commit(); - return tagID; + EntityId = id, + EntityType = EntityType.Contact, + TagId = tagID + }); } + + CRMDbContext.SaveChanges(); + + tx.Commit(); + + return tagID; } public int DeleteTagFromContacts(int[] contactID, String tagName) @@ -358,61 +403,73 @@ public int DeleteTagFromContacts(int[] contactID, String tagName) if (String.IsNullOrEmpty(tagName) || contactID == null || contactID.Length == 0) throw new ArgumentException(); - using (var tx = Db.BeginTransaction()) - { - var tagID = Db.ExecuteScalar(Query("crm_tag").Select("id") - .Where(Exp.Eq("trim(lower(title))", tagName.Trim().ToLower()) & Exp.Eq("entity_type", (int)EntityType.Contact))); + using var tx = CRMDbContext.Database.BeginTransaction(); - if (tagID == 0) - throw new ArgumentException(); + var tagID = Query(CRMDbContext.Tags) + .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == EntityType.Contact) + .Select(x => x.Id) + .SingleOrDefault(); + if (tagID == 0) + throw new ArgumentException(); - foreach (var id in contactID) - { - Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag") - .Where(Exp.Eq("entity_id", id) & - Exp.Eq("entity_type", (int)EntityType.Contact) & - Exp.Eq("tag_id", tagID))); - - } - tx.Commit(); - return tagID; - } + var itemsToRemove = CRMDbContext + .EntityTags + .Where(x => x.EntityType == EntityType.Contact && + x.TagId == tagID && + contactID.Contains(x.EntityId)); + + CRMDbContext.EntityTags.RemoveRange(itemsToRemove); + + CRMDbContext.SaveChanges(); + + tx.Commit(); + + return tagID; } public void SetTagToEntity(EntityType entityType, int entityID, String[] tags) { - using (var tx = Db.BeginTransaction()) - { - Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag") - .Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType))); + using var tx = CRMDbContext.Database.BeginTransaction(); + + var itemsToDelete = CRMDbContext.EntityTags.Where(x => x.EntityId == entityID && x.EntityType == entityType); - foreach (var tagName in tags.Where(t => !string.IsNullOrWhiteSpace(t))) - { - AddTagToEntityInDb(entityType, entityID, tagName); - } - tx.Commit(); + CRMDbContext.EntityTags.RemoveRange(itemsToDelete); + + foreach (var tagName in tags.Where(t => !string.IsNullOrWhiteSpace(t))) + { + AddTagToEntityInDb(entityType, entityID, tagName); } + + CRMDbContext.SaveChanges(); + + tx.Commit(); } private void AddTagToEntityInDb(EntityType entityType, int entityID, int tagID) { - Db.ExecuteNonQuery(new SqlInsert("crm_entity_tag", true) - .InColumnValue("entity_id", entityID) - .InColumnValue("entity_type", (int)entityType) - .InColumnValue("tag_id", tagID)); + CRMDbContext.EntityTags.Add(new DbEntityTag + { + EntityId = entityID, + EntityType = entityType, + TagId = tagID + }); + + CRMDbContext.SaveChanges(); } public void AddTagToEntity(EntityType entityType, int entityID, int[] tagIDs) { - using (var tx = Db.BeginTransaction()) + using var tx = CRMDbContext.Database.BeginTransaction(); + + foreach (var tagID in tagIDs) { - foreach (var tagID in tagIDs) - { - AddTagToEntityInDb(entityType, entityID, tagID); - } - tx.Commit(); + AddTagToEntityInDb(entityType, entityID, tagID); } + + CRMDbContext.SaveChanges(); + + tx.Commit(); } private static string CorrectTag(string tag) @@ -425,6 +482,5 @@ private static string CorrectTag(string tag) .Replace("\r", string.Empty); } - #endregion } } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index b38db2f2b63..e90f706a08c 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -24,22 +24,21 @@ */ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; - using ASC.Collections; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; using ASC.Common.Logging; using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; namespace ASC.CRM.Core.Dao { @@ -92,57 +91,75 @@ private void ResetCache(int taskID) public class TaskDao : AbstractDao { - #region Constructor - - public TaskDao(int tenantID) - : base(tenantID) + public TaskDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + FactoryIndexer factoryIndexer + ) : + base(dbContextManager, + tenantManager, + securityContext) { - - + CRMSecurity = cRMSecurity; + TenantUtil = tenantUtil; + FactoryIndexer = factoryIndexer; } - #endregion + public FactoryIndexer FactoryIndexer { get; } - #region Methods + public TenantUtil TenantUtil { get; } + public CRMSecurity CRMSecurity { get; } - public void OpenTask(int taskID) + public void OpenTask(int taskId) { - var task = GetByID(taskID); + var task = GetByID(taskId); if (task == null) throw new ArgumentException(); CRMSecurity.DemandEdit(task); - Db.ExecuteNonQuery( - Update("crm_task") - .Set("is_closed", false) - .Where(Exp.Eq("id", taskID)) - ); + DbTask entity = new DbTask() + { + Id = taskId, + IsClosed = false + }; + + CRMDbContext.Tasks.Update(entity); + + CRMDbContext.SaveChanges(); + } - public void CloseTask(int taskID) + public void CloseTask(int taskId) { - var task = GetByID(taskID); + var task = GetByID(taskId); if (task == null) throw new ArgumentException(); CRMSecurity.DemandEdit(task); - Db.ExecuteNonQuery( - Update("crm_task") - .Set("is_closed", true) - .Where(Exp.Eq("id", taskID)) - ); + DbTask entity = new DbTask() + { + Id = taskId, + IsClosed = true + }; + + CRMDbContext.Tasks.Update(entity); + + CRMDbContext.SaveChanges(); } public virtual Task GetByID(int taskID) { - var tasks = Db.ExecuteList(GetTaskQuery(Exp.Eq("id", taskID))) - .ConvertAll(row => ToTask(row)); + var crmTask = CRMDbContext.Tasks.Where(x => x.Id == taskID).SingleOrDefault(); + + if (crmTask == default(DbTask)) return null; - return tasks.Count > 0 ? tasks[0] : null; + return ToTask(crmTask); } public List GetTasks(EntityType entityType, int entityID, bool? onlyActiveTask) @@ -152,11 +169,13 @@ public List GetTasks(EntityType entityType, int entityID, bool? onlyActive } public int GetAllTasksCount() { - return Db.ExecuteScalar(Query("crm_task").SelectCount()); + return CRMDbContext.Tasks.Count(); } public List GetAllTasks() { + + return Db.ExecuteList( GetTaskQuery(null) .OrderBy("deadline", true) @@ -168,27 +187,19 @@ public void ExecAlert(IEnumerable ids) { if (!ids.Any()) return; - Db.ExecuteNonQuery(new SqlUpdate("crm_task").Set("exec_alert", true).Where(Exp.In("id", ids.ToArray()))); + CRMDbContext.Tasks.UpdateRange(ids.Select(x => new DbTask { ExecAlert = true, Id = x })); ; + + CRMDbContext.SaveChanges(); } public List GetInfoForReminder(DateTime scheduleDate) { - var sqlQuery = new SqlQuery("crm_task") - .Select( - "tenant_id", - "id", - "deadline", - "alert_value", - "responsible_id" - ) - .Where( - Exp.Eq("is_closed", false) & - !Exp.Eq("alert_value", 0) & - Exp.Eq("exec_alert", false) & - Exp.Between("DATE_ADD(deadline, interval -alert_value minute)", scheduleDate.AddHours(-1), scheduleDate.AddHours(1)) - ); - - return Db.ExecuteList(sqlQuery); + return CRMDbContext.Tasks.Where(x => + x.IsClosed == false && + x.AlertValue != 0 && + x.ExecAlert == false && + ( x.Deadline.AddMinutes(-x.AlertValue) >= scheduleDate.AddHours(-1) && x.Deadline.AddMinutes(-x.AlertValue) <= scheduleDate.AddHours(-1)) + ).Select(x => new object[]{ x.TenantId, x.Id, x.Deadline, x.AlertValue, x.ResponsibleId }).ToList(); } public List GetTasks( @@ -302,9 +313,9 @@ private List GetCrudeTasks( if (keywords.Length > 0) { List tasksIds; - if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out tasksIds)) + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out tasksIds)) { - sqlQuery.Where(BuildLike(new[] {taskTableAlias + ".title", taskTableAlias + ".description"}, keywords)); + sqlQuery.Where(BuildLike(new[] { taskTableAlias + ".title", taskTableAlias + ".description" }, keywords)); } else { @@ -427,7 +438,7 @@ public int GetTasksCount( .Select("tbl_tsk.id") .InnerJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_ctc.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Company|', tbl_ctc.id)")) .Where(Exp.Eq("tbl_ctc.is_shared", 0)) @@ -454,7 +465,7 @@ public int GetTasksCount( .Select("tbl_tsk.id") .InnerJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_ctc.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Person|', tbl_ctc.id)")) .Where(Exp.Eq("tbl_ctc.is_shared", 0)) @@ -481,7 +492,7 @@ public int GetTasksCount( sqlQuery = Query("crm_task tbl_tsk") .Select("tbl_tsk.id") .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Deal|', tbl_tsk.entity_id)")) .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Opportunity) & Exp.Eq("tbl_tsk.contact_id", 0)); @@ -506,7 +517,7 @@ public int GetTasksCount( sqlQuery = Query("crm_task tbl_tsk") .Select("tbl_tsk.id") .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", ASC.Core.SecurityContext.CurrentAccount.ID.ToString()) & + Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Cases|', tbl_tsk.entity_id)")) .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Case) & Exp.Eq("tbl_tsk.contact_id", 0)); @@ -680,7 +691,7 @@ public Dictionary GetNearestTask(int[] contactID) if (taskIDs.Count == 0) return new Dictionary(); - var tasks = Db.ExecuteList(GetTaskQuery(Exp.In("id", taskIDs))).ConvertAll(row=>ToTask(row)).Where(CRMSecurity.CanAccessTo); + var tasks = Db.ExecuteList(GetTaskQuery(Exp.In("id", taskIDs))).ConvertAll(row => ToTask(row)).Where(CRMSecurity.CanAccessTo); var result = new Dictionary(); @@ -694,6 +705,10 @@ public Dictionary GetNearestTask(int[] contactID) public IEnumerable GetResponsibles(int categoryID) { + + + // CRMDbContext.Tasks.Select(x=>x.ResponsibleId) + var q = Query("crm_task") .Select("responsible_id") .GroupBy(1); @@ -710,15 +725,10 @@ public IEnumerable GetResponsibles(int categoryID) public Dictionary GetTasksCount(int[] contactID) { - var sqlQuery = Query("crm_task") - .Select("contact_id") - .SelectCount() - .Where(Exp.In("contact_id", contactID)) - .GroupBy("contact_id"); - - var sqlResult = Db.ExecuteList(sqlQuery); - - return sqlResult.ToDictionary(item => Convert.ToInt32(item[0]), item => Convert.ToInt32(item[1])); + return CRMDbContext.Tasks + .Where(x => contactID.Contains(x.ContactId)) + .GroupBy(x => x.ContactId) + .ToDictionary(x => x.Key, x => x.Count()); } public int GetTasksCount(int contactID) @@ -777,14 +787,34 @@ private Task SaveOrUpdateTaskInDb(Task newTask) if (String.IsNullOrEmpty(newTask.Title) || newTask.DeadLine == DateTime.MinValue || newTask.CategoryID <= 0) throw new ArgumentException(); - + if (newTask.ID == 0 || Db.ExecuteScalar(Query("crm_task").SelectCount().Where(Exp.Eq("id", newTask.ID))) == 0) { newTask.CreateOn = DateTime.UtcNow; - newTask.CreateBy = ASC.Core.SecurityContext.CurrentAccount.ID; + newTask.CreateBy = SecurityContext.CurrentAccount.ID; newTask.LastModifedOn = DateTime.UtcNow; - newTask.LastModifedBy = ASC.Core.SecurityContext.CurrentAccount.ID; + newTask.LastModifedBy = SecurityContext.CurrentAccount.ID; + + new DbTask + { + Title = newTask.Title, + Description = newTask.Description, + Deadline = TenantUtil.DateTimeToUtc(newTask.DeadLine), + ResponsibleId = newTask.ResponsibleID, + ContactId = newTask.ContactID, + EntityType = newTask.EntityType, + EntityId = newTask.EntityID, + IsClosed = newTask.IsClosed, + CategoryId = newTask.CategoryID, + CreateOn = newTask.CreateOn, + CreateBy = newTask.CreateBy, + LastModifedOn = newTask.LastModifedOn, + LastModifedBy = newTask.LastModifedBy, + AlertValue = newTask.AlertValue, + TenantId = TenantID + }; + newTask.ID = Db.ExecuteScalar( Insert("crm_task") @@ -817,7 +847,7 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.CreateBy = oldTask.CreateBy; newTask.LastModifedOn = DateTime.UtcNow; - newTask.LastModifedBy = ASC.Core.SecurityContext.CurrentAccount.ID; + newTask.LastModifedBy = SecurityContext.CurrentAccount.ID; newTask.IsClosed = oldTask.IsClosed; @@ -838,7 +868,8 @@ private Task SaveOrUpdateTaskInDb(Task newTask) .Where(Exp.Eq("id", newTask.ID))); } - FactoryIndexer.IndexAsync(newTask); + FactoryIndexer.IndexAsync(newTask); + return newTask; } @@ -854,46 +885,53 @@ private int SaveTaskInDb(Task newTask) newTask.CategoryID == 0) throw new ArgumentException(); - var result = Db.ExecuteScalar( - Insert("crm_task") - .InColumnValue("id", 0) - .InColumnValue("title", newTask.Title) - .InColumnValue("description", newTask.Description) - .InColumnValue("deadline", TenantUtil.DateTimeToUtc(newTask.DeadLine)) - .InColumnValue("responsible_id", newTask.ResponsibleID) - .InColumnValue("contact_id", newTask.ContactID) - .InColumnValue("entity_type", (int)newTask.EntityType) - .InColumnValue("entity_id", newTask.EntityID) - .InColumnValue("is_closed", newTask.IsClosed) - .InColumnValue("category_id", newTask.CategoryID) - .InColumnValue("create_on", newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn) - .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn) - .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .InColumnValue("alert_value", (int)newTask.AlertValue) - .Identity(1, 0, true)); - - newTask.ID = result; - FactoryIndexer.IndexAsync(newTask); - - return result; + var dbTask = new DbTask + { + Title = newTask.Title, + Description = newTask.Description, + Deadline = TenantUtil.DateTimeToUtc(newTask.DeadLine), + ResponsibleId = newTask.ResponsibleID, + ContactId = newTask.ContactID, + EntityType = newTask.EntityType, + EntityId = newTask.EntityID, + IsClosed = newTask.IsClosed, + CategoryId = newTask.CategoryID, + CreateOn = newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn, + CreateBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn, + LastModifedBy = SecurityContext.CurrentAccount.ID, + AlertValue = newTask.AlertValue, + TenantId = TenantID + }; + + CRMDbContext.Tasks.Add(dbTask); + + CRMDbContext.SaveChanges(); + + newTask.ID = dbTask.Id; + + FactoryIndexer.IndexAsync(newTask); + + return newTask.ID; } public virtual int[] SaveTaskList(List items) { - using (var tx = Db.BeginTransaction()) - { - var result = new List(); - foreach (var item in items) - { - result.Add(SaveTaskInDb(item)); - } + using var tx = CRMDbContext.Database.BeginTransaction(); - tx.Commit(); + var result = new List(); - return result.ToArray(); + foreach (var item in items) + { + result.Add(SaveTaskInDb(item)); } + + CRMDbContext.SaveChanges(); + + tx.Commit(); + + return result.ToArray(); } @@ -905,10 +943,11 @@ public virtual void DeleteTask(int taskID) CRMSecurity.DemandEdit(task); - Db.ExecuteNonQuery(Delete("crm_task").Where("id", taskID)); + CRMDbContext.Tasks.Remove(new DbTask { Id = taskID }); _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); - FactoryIndexer.DeleteAsync(task); + + FactoryIndexer.DeleteAsync(task); } public List CreateByTemplate(List templateItems, EntityType entityType, int entityID) @@ -917,79 +956,61 @@ public List CreateByTemplate(List templateItems, EntityType var result = new List(); - using (var tx = Db.BeginTransaction()) + using var tx = CRMDbContext.Database.BeginTransaction(); + + foreach (var templateItem in templateItems) { - foreach (var templateItem in templateItems) + var task = new Task { - var task = new Task - { - ResponsibleID = templateItem.ResponsibleID, - Description = templateItem.Description, - DeadLine = TenantUtil.DateTimeNow().AddTicks(templateItem.Offset.Ticks), - CategoryID = templateItem.CategoryID, - Title = templateItem.Title, - CreateOn = TenantUtil.DateTimeNow(), - CreateBy = templateItem.CreateBy - }; - - switch (entityType) - { - case EntityType.Contact: - case EntityType.Person: - case EntityType.Company: - task.ContactID = entityID; - break; - case EntityType.Opportunity: - task.EntityType = EntityType.Opportunity; - task.EntityID = entityID; - break; - case EntityType.Case: - task.EntityType = EntityType.Case; - task.EntityID = entityID; - break; - default: - throw new NotImplementedException(); - } - - task = SaveOrUpdateTask(task); + ResponsibleID = templateItem.ResponsibleID, + Description = templateItem.Description, + DeadLine = TenantUtil.DateTimeNow().AddTicks(templateItem.Offset.Ticks), + CategoryID = templateItem.CategoryID, + Title = templateItem.Title, + CreateOn = TenantUtil.DateTimeNow(), + CreateBy = templateItem.CreateBy + }; - result.Add(task); + switch (entityType) + { + case EntityType.Contact: + case EntityType.Person: + case EntityType.Company: + task.ContactID = entityID; + break; + case EntityType.Opportunity: + task.EntityType = EntityType.Opportunity; + task.EntityID = entityID; + break; + case EntityType.Case: + task.EntityType = EntityType.Case; + task.EntityID = entityID; + break; + default: + throw new NotImplementedException(); + } - Db.ExecuteNonQuery(Insert("crm_task_template_task") - .InColumnValue("task_id", task.ID) - .InColumnValue("task_template_id", templateItem.ID)); + task = SaveOrUpdateTask(task); - } + result.Add(task); - tx.Commit(); + CRMDbContext.TaskTemplateTask.Add(new DbTaskTemplateTask + { + TaskId = task.ID, + TaskTemplateId = templateItem.ID, + TenantId = TenantID + }); } + tx.Commit(); + + CRMDbContext.SaveChanges(); + return result; } #region Private Methods - private static Task ToTask(object[] row) - { - return new Task - { - ID = Convert.ToInt32(row[0]), - ContactID = Convert.ToInt32(row[1]), - Title = Convert.ToString(row[2]), - Description = Convert.ToString(row[3]), - DeadLine = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[4])), - ResponsibleID = ToGuid(row[5]), - IsClosed = Convert.ToBoolean(row[6]), - CategoryID = Convert.ToInt32(row[7]), - EntityID = Convert.ToInt32(row[8]), - EntityType = (EntityType)Convert.ToInt32(row[9]), - CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[10])), - CreateBy = ToGuid(row[11]), - AlertValue = Convert.ToInt32(row[12]) - }; - } - - private String[] GetTaskColumnsTable(String alias) { if (!String.IsNullOrEmpty(alias)) @@ -1017,34 +1038,34 @@ private String[] GetTaskColumnsTable(String alias) return result.ConvertAll(item => String.Concat(alias, item)).ToArray(); } - private SqlQuery GetTaskQuery(Exp where, String alias) - { + //private SqlQuery GetTaskQuery(Exp where, String alias) + //{ - var sqlQuery = Query("crm_task"); + // var sqlQuery = Query("crm_task"); - if (!String.IsNullOrEmpty(alias)) - { - sqlQuery = new SqlQuery(String.Concat("crm_task ", alias)) - .Where(Exp.Eq(alias + ".tenant_id", TenantID)); - sqlQuery.Select(GetTaskColumnsTable(alias)); + // if (!String.IsNullOrEmpty(alias)) + // { + // sqlQuery = new SqlQuery(String.Concat("crm_task ", alias)) + // .Where(Exp.Eq(alias + ".tenant_id", TenantID)); + // sqlQuery.Select(GetTaskColumnsTable(alias)); - } - else - sqlQuery.Select(GetTaskColumnsTable(String.Empty)); + // } + // else + // sqlQuery.Select(GetTaskColumnsTable(String.Empty)); - if (where != null) - sqlQuery.Where(where); + // if (where != null) + // sqlQuery.Where(where); - return sqlQuery; + // return sqlQuery; - } + //} - private SqlQuery GetTaskQuery(Exp where) - { - return GetTaskQuery(where, String.Empty); + //private SqlQuery GetTaskQuery(Exp where) + //{ + // return GetTaskQuery(where, String.Empty); - } + //} #endregion @@ -1063,9 +1084,6 @@ public void ReassignTasksResponsible(Guid fromUserId, Guid toUserId) } } - #endregion - - /// /// Test method /// @@ -1073,10 +1091,16 @@ public void ReassignTasksResponsible(Guid fromUserId, Guid toUserId) /// public void SetTaskCreationDate(int taskId, DateTime creationDate) { - Db.ExecuteNonQuery( - Update("crm_task") - .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) - .Where(Exp.Eq("id", taskId))); + DbTask entity = new DbTask() + { + Id = taskId, + CreateOn = TenantUtil.DateTimeToUtc(creationDate) + }; + + CRMDbContext.Tasks.Update(entity); + + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); } @@ -1088,12 +1112,23 @@ public void SetTaskCreationDate(int taskId, DateTime creationDate) /// public void SetTaskLastModifedDate(int taskId, DateTime lastModifedDate) { - Db.ExecuteNonQuery( - Update("crm_task") - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) - .Where(Exp.Eq("id", taskId))); + DbTask entity = new DbTask() + { + Id = taskId, + LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate) + }; + + CRMDbContext.Tasks.Update(entity); + + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); } + + public Task ToTask(DbTask dbTask) + { + throw new NotImplementedException(); + } } } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 42f5d33e33b..986d5f68fc1 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -23,95 +23,59 @@ * */ - -#region Import - +using ASC.Core; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; -using ASC.Core.Tenants; -using ASC.CRM.Core.Entities; - -#endregion +using System.Linq; namespace ASC.CRM.Core.Dao { - public class CachedTaskTemplateContainerDao : TaskTemplateContainerDao - { - #region Constructor - - public CachedTaskTemplateContainerDao(int tenantID) - : base(tenantID) - { - - - } - - #endregion - - } - - public class CachedTaskTemplateDao : TaskTemplateDao - { - - #region Constructor - - public CachedTaskTemplateDao(int tenantID) - : base(tenantID) - { - - - } - - #endregion - } - public class TaskTemplateContainerDao : AbstractDao { - #region Constructor - - public TaskTemplateContainerDao(int tenantID) - : base(tenantID) + public TaskTemplateContainerDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { - } - #endregion - - #region Methods - public virtual int SaveOrUpdate(TaskTemplateContainer item) { - if (item.ID == 0 && Db.ExecuteScalar(Query("crm_task_template_container").SelectCount().Where(Exp.Eq("id", item.ID))) == 0) + var dbTaskTemplateContainer = new DbTaskTemplateContainer { + Id = item.ID, + Title = item.Title, + EntityType = item.EntityType, + CreateOn = DateTime.UtcNow, + CreateBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + if (item.ID == 0 && Query(CRMDbContext.TaskTemplateContainer).Where(x => x.Id == item.ID).Any()) + { + CRMDbContext.TaskTemplateContainer.Add(dbTaskTemplateContainer); + + item.ID = dbTaskTemplateContainer.Id; - item.ID = Db.ExecuteScalar( - Insert("crm_task_template_container") - .InColumnValue("id", 0) - .InColumnValue("title", item.Title) - .InColumnValue("entity_type", (int)item.EntityType) - .InColumnValue("create_on", DateTime.UtcNow) - .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", DateTime.UtcNow) - .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); + CRMDbContext.SaveChanges(); } else { + CRMDbContext.TaskTemplateContainer.Attach(dbTaskTemplateContainer); - Db.ExecuteScalar( - Update("crm_task_template_container") - .Set("title", item.Title) - .Set("entity_type", (int)item.EntityType) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", item.ID))); - - - + CRMDbContext.SaveChanges(); } @@ -120,24 +84,23 @@ public virtual int SaveOrUpdate(TaskTemplateContainer item) public virtual void Delete(int id) { - if (id <= 0) throw new ArgumentException(); - Db.ExecuteNonQuery(Delete("crm_task_template_container").Where("id", id)); + var itemToDelete = new DbTaskTemplateContainer { Id = id }; + + CRMDbContext.TaskTemplateContainer.Attach(itemToDelete); + CRMDbContext.TaskTemplateContainer.Remove(itemToDelete); + + CRMDbContext.SaveChanges(); } public virtual TaskTemplateContainer GetByID(int id) { - if (id <= 0) throw new ArgumentException(); - var result = Db.ExecuteList(GetQuery(null).Where(Exp.Eq("id", id))).ConvertAll(row => ToObject(row)); - - if (result.Count == 0) return null; - - return result[0]; + return ToObject(Query(CRMDbContext.TaskTemplateContainer).FirstOrDefault(x => x.Id == id)); } public virtual List GetItems(EntityType entityType) @@ -145,91 +108,81 @@ public virtual List GetItems(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException("", entityType.ToString()); - return Db.ExecuteList(GetQuery(Exp.Eq("entity_type", (int)entityType))) - .ConvertAll(row => ToObject(row)); + return Query(CRMDbContext.TaskTemplateContainer) + .Where(x => x.EntityType == entityType) + .ToList() + .ConvertAll(ToObject); } - - #endregion - - protected SqlQuery GetQuery(Exp where) + + protected TaskTemplateContainer ToObject(DbTaskTemplateContainer dbTaskTemplateContainer) { + if (dbTaskTemplateContainer == null) return null; - var sqlQuery = Query("crm_task_template_container") - .Select("id", - "title", - "entity_type"); - - if (where != null) - sqlQuery.Where(where); - - return sqlQuery; - } - - protected TaskTemplateContainer ToObject(object[] row) - { return new TaskTemplateContainer - { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - EntityType = (EntityType)Convert.ToInt32(row[2]) - }; + { + ID = dbTaskTemplateContainer.Id, + Title = dbTaskTemplateContainer.Title, + EntityType = dbTaskTemplateContainer.EntityType + }; } } public class TaskTemplateDao : AbstractDao { - #region Constructor - - public TaskTemplateDao(int tenantID) - : base(tenantID) + public TaskTemplateDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { } - #endregion - - #region Methods - public int SaveOrUpdate(TaskTemplate item) { - if (item.ID == 0 && Db.ExecuteScalar(Query("crm_task_template").SelectCount().Where(Exp.Eq("id", item.ID))) == 0) + if (item.ID == 0) { - - item.ID = Db.ExecuteScalar( - Insert("crm_task_template") - .InColumnValue("id", 0) - .InColumnValue("title", item.Title) - .InColumnValue("category_id", item.CategoryID) - .InColumnValue("description", item.Description) - .InColumnValue("responsible_id", item.ResponsibleID) - .InColumnValue("is_notify", item.isNotify) - .InColumnValue("offset", item.Offset.Ticks) - .InColumnValue("deadLine_is_fixed", item.DeadLineIsFixed) - .InColumnValue("container_id", item.ContainerID) - .InColumnValue("create_on", DateTime.UtcNow) - .InColumnValue("create_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", DateTime.UtcNow) - .InColumnValue("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); - + var itemToInsert = new DbTaskTemplate + { + Id = item.ID, + Title = item.Title, + CategoryId = item.CategoryID, + Description = item.Description, + ResponsibleId = item.ResponsibleID, + IsNotify = item.isNotify, + Offset = item.Offset.Ticks, + DeadLineIsFixed = item.DeadLineIsFixed, + ContainerId = item.ContainerID, + CreateOn = DateTime.UtcNow, + CreateBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.TaskTemplates.Add(itemToInsert); + CRMDbContext.SaveChanges(); } else { - Db.ExecuteNonQuery( - Update("crm_task_template") - .Set("title", item.Title) - .Set("category_id", item.CategoryID) - .Set("description", item.Description) - .Set("responsible_id", item.ResponsibleID) - .Set("is_notify", item.isNotify) - .Set("offset", item.Offset.Ticks) - .Set("deadLine_is_fixed", item.DeadLineIsFixed) - .Set("container_id", item.ContainerID) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", ASC.Core.SecurityContext.CurrentAccount.ID) - .Where("id", item.ID)); - + //Db.ExecuteNonQuery( + // Update("crm_task_template") + // .Set("title", item.Title) + // .Set("category_id", item.CategoryID) + // .Set("description", item.Description) + // .Set("responsible_id", item.ResponsibleID) + // .Set("is_notify", item.isNotify) + // .Set("offset", item.Offset.Ticks) + // .Set("deadLine_is_fixed", item.DeadLineIsFixed) + // .Set("container_id", item.ContainerID) + // .Set("last_modifed_on", DateTime.UtcNow) + // .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) + // .Where("id", item.ID)); + + //CRMDbContext.TaskTemplates.Add(itemToInsert); + //CRMDbContext.SaveChanges(); } return item.ID; @@ -237,36 +190,47 @@ public int SaveOrUpdate(TaskTemplate item) public TaskTemplate GetNext(int taskID) { - using (var tx = Db.BeginTransaction()) - { - var sqlResult = Db.ExecuteList( - Query("crm_task_template_task tblTTT") - .Select("tblTT.container_id") - .Select("tblTT.sort_order") - .LeftOuterJoin("crm_task_template tblTT", Exp.EqColumns("tblTT.tenant_id", "tblTTT.tenant_id") & Exp.EqColumns("tblTT.id", "tblTTT.task_template_id")) - .Where(Exp.Eq("tblTTT.task_id", taskID) & Exp.Eq("tblTT.tenant_id", TenantID))); + using var tx = CRMDbContext.Database.BeginTransaction(); - if (sqlResult.Count == 0) return null; + var temp = Query(CRMDbContext.TaskTemplateTask) + .Join(CRMDbContext.TaskTemplates, + x => new { x.TenantId, x.TaskTemplateId }, + y => new { y.TenantId, y.Id }, + (x, y) => new + { + x, y + }); - var result = Db.ExecuteList(GetQuery(Exp.Eq("container_id", sqlResult[0][0]) & - Exp.Gt("sort_order", sqlResult[0][1]) & - Exp.Eq("deadLine_is_fixed", false)).SetMaxResults(1)).ConvertAll( - row => ToObject(row)); + //var sqlResult = Db.ExecuteList( + // Query("crm_task_template_task tblTTT") + // .Select("tblTT.container_id") + // .Select("tblTT.sort_order") + // .LeftOuterJoin("crm_task_template tblTT", Exp.EqColumns("tblTT.tenant_id", "tblTTT.tenant_id") & Exp.EqColumns("tblTT.id", "tblTTT.task_template_id")) + // .Where(Exp.Eq("tblTTT.task_id", taskID) & Exp.Eq("tblTT.tenant_id", TenantID))); - Db.ExecuteNonQuery(Delete("crm_task_template_task").Where(Exp.Eq("task_id", taskID))); + //if (sqlResult.Count == 0) return null; - tx.Commit(); + //var result = Db.ExecuteList(GetQuery(Exp.Eq("container_id", sqlResult[0][0]) & + // Exp.Gt("sort_order", sqlResult[0][1]) & + // Exp.Eq("deadLine_is_fixed", false)).SetMaxResults(1)).ConvertAll( + // row => ToObject(row)); - if (result.Count == 0) return null; + //Db.ExecuteNonQuery(Delete("crm_task_template_task").Where(Exp.Eq("task_id", taskID))); + + tx.Commit(); + +// if (result.Count == 0) return null; + + // return result[0]; - return result[0]; - } } public List GetAll() { - return Db.ExecuteList(GetQuery(null)) - .ConvertAll(row => ToObject(row)); + return Query(CRMDbContext.TaskTemplates) + .OrderBy(x => x.SortOrder) + .ToList() + .ConvertAll(ToObject); } public List GetList(int containerID) @@ -274,8 +238,11 @@ public List GetList(int containerID) if (containerID <= 0) throw new NotImplementedException(); - return Db.ExecuteList(GetQuery(Exp.Eq("container_id", containerID))) - .ConvertAll(row => ToObject(row)); + return Query(CRMDbContext.TaskTemplates) + .Where(x => x.ContainerId == containerID) + .OrderBy(x=> x.SortOrder) + .ToList() + .ConvertAll(ToObject); } public virtual TaskTemplate GetByID(int id) @@ -283,12 +250,7 @@ public virtual TaskTemplate GetByID(int id) if (id <= 0) throw new NotImplementedException(); - var items = Db.ExecuteList(GetQuery(Exp.Eq("id", id))).ConvertAll(row => ToObject(row)); - - if (items.Count == 0) - return null; - - return items[0]; + return ToObject(CRMDbContext.TaskTemplates.FirstOrDefault(x => x.Id == id)); } public virtual void Delete(int id) @@ -296,53 +258,34 @@ public virtual void Delete(int id) if (id <= 0) throw new NotImplementedException(); - Db.ExecuteNonQuery(Delete("crm_task_template").Where("id", id)); - } + var itemToRemove = new DbTaskTemplate + { + Id = id + }; - protected TaskTemplate ToObject(object[] row) - { - return new TaskTemplate - { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - CategoryID = Convert.ToInt32(row[2]), - Description = Convert.ToString(row[3]), - ResponsibleID = ToGuid(row[4]), - isNotify = Convert.ToBoolean(row[5]), - Offset = TimeSpan.FromTicks((long)row[6]), - DeadLineIsFixed = Convert.ToBoolean(row[7]), - ContainerID = Convert.ToInt32(row[8]), - CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[9])), - CreateBy = ToGuid(row[10]) - }; + CRMDbContext.Entry(itemToRemove).State = EntityState.Deleted; + CRMDbContext.SaveChanges(); } - protected SqlQuery GetQuery(Exp where) + protected TaskTemplate ToObject(DbTaskTemplate dbTaskTemplate) { - var sqlQuery = Query("crm_task_template") - .Select("id", - "title", - "category_id", - "description", - "responsible_id", - "is_notify", - "offset", - "deadLine_is_fixed", - "container_id", - "create_on", - "create_by" - ); - - if (where != null) - sqlQuery.Where(where); - - sqlQuery.OrderBy("sort_order", true); - - return sqlQuery; - } - - #endregion + if (dbTaskTemplate == null) return null; + return new TaskTemplate + { + ID = dbTaskTemplate.Id, + Title = dbTaskTemplate.Title, + CategoryID = dbTaskTemplate.CategoryId, + Description = dbTaskTemplate.Description, + ResponsibleID = dbTaskTemplate.ResponsibleId, + isNotify = dbTaskTemplate.IsNotify, + Offset = TimeSpan.FromTicks(dbTaskTemplate.Offset), + DeadLineIsFixed = dbTaskTemplate.DeadLineIsFixed, + ContainerID = dbTaskTemplate.ContainerId, + CreateOn = dbTaskTemplate.CreateOn, + CreateBy = dbTaskTemplate.CreateBy + }; + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index fbd77613b57..55752ccea50 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -7,42 +7,33 @@ namespace ASC.CRM.Core.EF { public partial class CRMDbContext : BaseDbContext { - //public CRMDbContext() - //{ - //} - - //public CRMDbContext(DbContextOptions options) - // : base(options) - //{ - //} - - public virtual DbSet CrmCase { get; set; } - public virtual DbSet CrmContact { get; set; } - public virtual DbSet CrmContactInfo { get; set; } - public virtual DbSet CrmCurrencyInfo { get; set; } - public virtual DbSet CrmCurrencyRate { get; set; } - public virtual DbSet CrmDeal { get; set; } - public virtual DbSet CrmDealMilestone { get; set; } - public virtual DbSet CrmEntityContact { get; set; } - public virtual DbSet CrmEntityTag { get; set; } - public virtual DbSet CrmFieldDescription { get; set; } - public virtual DbSet CrmFieldValue { get; set; } - public virtual DbSet CrmInvoice { get; set; } - public virtual DbSet CrmInvoiceItem { get; set; } - public virtual DbSet CrmInvoiceLine { get; set; } - public virtual DbSet CrmInvoiceTax { get; set; } - public virtual DbSet CrmListItem { get; set; } - public virtual DbSet CrmOrganisationLogo { get; set; } - public virtual DbSet CrmProjects { get; set; } - public virtual DbSet CrmRelationshipEvent { get; set; } - public virtual DbSet CrmReportFile { get; set; } - public virtual DbSet CrmTag { get; set; } - public virtual DbSet CrmTask { get; set; } - public virtual DbSet CrmTaskTemplate { get; set; } - public virtual DbSet CrmTaskTemplateContainer { get; set; } - public virtual DbSet CrmTaskTemplateTask { get; set; } - public virtual DbSet CrmVoipCalls { get; set; } - public virtual DbSet CrmVoipNumber { get; set; } + public virtual DbSet Cases { get; set; } + public virtual DbSet Contacts { get; set; } + public virtual DbSet ContactsInfo { get; set; } + public virtual DbSet CurrencyInfo { get; set; } + public virtual DbSet CurrencyRate { get; set; } + public virtual DbSet Deals { get; set; } + public virtual DbSet DealMilestones { get; set; } + public virtual DbSet EntityContact { get; set; } + public virtual DbSet EntityTags { get; set; } + public virtual DbSet FieldDescription { get; set; } + public virtual DbSet FieldValue { get; set; } + public virtual DbSet Invoices { get; set; } + public virtual DbSet InvoiceItem { get; set; } + public virtual DbSet InvoiceLine { get; set; } + public virtual DbSet InvoiceTax { get; set; } + public virtual DbSet ListItem { get; set; } + public virtual DbSet OrganisationLogo { get; set; } + public virtual DbSet Projects { get; set; } + public virtual DbSet RelationshipEvent { get; set; } + public virtual DbSet ReportFile { get; set; } + public virtual DbSet Tags { get; set; } + public virtual DbSet Tasks { get; set; } + public virtual DbSet TaskTemplates { get; set; } + public virtual DbSet TaskTemplateContainer { get; set; } + public virtual DbSet TaskTemplateTask { get; set; } + public virtual DbSet VoipCalls { get; set; } + public virtual DbSet VoipNumber { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { @@ -53,7 +44,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.CreateOn) .HasName("create_on"); @@ -77,7 +68,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.CreateOn) .HasName("create_on"); @@ -132,7 +123,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.LastModifedOn) .HasName("last_modifed_on"); @@ -149,7 +140,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => e.Abbreviation) .HasName("PRIMARY"); @@ -171,7 +162,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.FromCurrency) .HasName("from_currency"); @@ -196,7 +187,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.CreateOn) .HasName("create_on"); @@ -235,7 +226,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -254,7 +245,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => new { e.EntityId, e.EntityType, e.ContactId }) .HasName("PRIMARY"); @@ -263,7 +254,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("IX_Contact"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => new { e.EntityId, e.EntityType, e.TagId }) .HasName("PRIMARY"); @@ -272,7 +263,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("tag_id"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.EntityType, e.SortOrder }) .HasName("entity_type"); @@ -286,7 +277,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.FieldId) .HasName("field_id"); @@ -306,7 +297,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -358,7 +349,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -388,7 +379,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -398,7 +389,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -420,7 +411,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.ListType }) .HasName("list_type"); @@ -442,7 +433,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -456,7 +447,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => new { e.TenantId, e.ContactId, e.ProjectId }) .HasName("PRIMARY"); @@ -468,7 +459,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("project_id"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.ContactId) .HasName("IX_Contact"); @@ -495,7 +486,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => e.FileId) .HasName("PRIMARY"); @@ -514,7 +505,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -524,7 +515,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_bin"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.CreateOn) .HasName("create_on"); @@ -568,7 +559,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.ContainerId }) .HasName("template_id"); @@ -597,7 +588,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.EntityType }) .HasName("entity_type"); @@ -617,13 +608,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasKey(e => new { e.TenantId, e.TaskId, e.TaskTemplateId }) .HasName("PRIMARY"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); @@ -661,7 +652,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) .HasName("tenant_id"); diff --git a/products/ASC.CRM/Server/Core/EF/CrmCase.cs b/products/ASC.CRM/Server/Core/EF/DbCase.cs similarity index 76% rename from products/ASC.CRM/Server/Core/EF/CrmCase.cs rename to products/ASC.CRM/Server/Core/EF/DbCase.cs index 61a865d503a..8fbc3c754dd 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmCase.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCase.cs @@ -1,32 +1,37 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_case")] - public partial class CrmCase + public partial class DbCase { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } + [Column("is_closed")] public bool IsClosed { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid? LastModifedBy { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmContact.cs b/products/ASC.CRM/Server/Core/EF/DbContact.cs similarity index 91% rename from products/ASC.CRM/Server/Core/EF/CrmContact.cs rename to products/ASC.CRM/Server/Core/EF/DbContact.cs index ffd1609b019..65687ddd2d2 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContact.cs @@ -1,13 +1,11 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_contact")] - public partial class CrmContact + public partial class DbContact { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmContactInfo.cs b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs similarity index 85% rename from products/ASC.CRM/Server/Core/EF/CrmContactInfo.cs rename to products/ASC.CRM/Server/Core/EF/DbContactInfo.cs index 772723612b8..40c9cbbedd8 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmContactInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs @@ -1,33 +1,40 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_contact_info")] - public partial class CrmContactInfo + public partial class DbContactInfo { [Key] [Column("id", TypeName = "int(10)")] public int Id { get; set; } + [Required] [Column("data", TypeName = "text")] public string Data { get; set; } + [Column("category", TypeName = "int(255)")] public int Category { get; set; } + [Column("tenant_id", TypeName = "int(255)")] public int TenantId { get; set; } + [Column("is_primary", TypeName = "tinyint(4)")] public sbyte IsPrimary { get; set; } + [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } + [Column("type", TypeName = "int(255)")] public int Type { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] public string LastModifedBy { get; set; } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs b/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs similarity index 96% rename from products/ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs rename to products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs index 8368513e568..30962ac3905 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmCurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_currency_info")] - public partial class CrmCurrencyInfo + public partial class DbCurrencyInfo { [Required] [Column("resource_key", TypeName = "varchar(255)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs similarity index 78% rename from products/ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs rename to products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs index fc63ba28d09..9bea9922d9b 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmCurrencyRate.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs @@ -1,13 +1,11 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_currency_rate")] - public partial class CrmCurrencyRate + public partial class DbCurrencyRate { [Key] [Column("id", TypeName = "int(11)")] @@ -22,13 +20,14 @@ public partial class CrmCurrencyRate public decimal Rate { get; set; } [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid? LastModifedBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/CrmDeal.cs b/products/ASC.CRM/Server/Core/EF/DbDeal.cs similarity index 51% rename from products/ASC.CRM/Server/Core/EF/CrmDeal.cs rename to products/ASC.CRM/Server/Core/EF/DbDeal.cs index dd14d6353b8..6b911630961 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmDeal.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDeal.cs @@ -1,52 +1,92 @@ -// This file has been auto generated by EF Core Power Tools. +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_deal")] - public partial class CrmDeal + public partial class DbDeal : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } + [Column("description", TypeName = "text")] public string Description { get; set; } + [Required] [Column("responsible_id", TypeName = "char(38)")] - public string ResponsibleId { get; set; } + public Guid ResponsibleId { get; set; } + [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } - [Required] + + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("bid_currency", TypeName = "varchar(255)")] public string BidCurrency { get; set; } + [Column("bid_value", TypeName = "decimal(50,9)")] public decimal BidValue { get; set; } + [Column("bid_type", TypeName = "int(11)")] public int BidType { get; set; } + [Column("deal_milestone_id", TypeName = "int(11)")] public int DealMilestoneId { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Column("expected_close_date", TypeName = "datetime")] public DateTime ExpectedCloseDate { get; set; } + [Column("per_period_value", TypeName = "int(11)")] public int PerPeriodValue { get; set; } + [Column("deal_milestone_probability", TypeName = "int(11)")] public int? DealMilestoneProbability { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } + [Column("actual_close_date", TypeName = "datetime")] public DateTime? ActualCloseDate { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/CrmDealMilestone.cs b/products/ASC.CRM/Server/Core/EF/DbDealMilestone.cs similarity index 95% rename from products/ASC.CRM/Server/Core/EF/CrmDealMilestone.cs rename to products/ASC.CRM/Server/Core/EF/DbDealMilestone.cs index cf07306ae1a..80014bcac36 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmDealMilestone.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDealMilestone.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_deal_milestone")] - public partial class CrmDealMilestone + public partial class DbDealMilestone : IDbCrm { [Key] [Column("id", TypeName = "int(10)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmEntityContact.cs b/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs similarity index 79% rename from products/ASC.CRM/Server/Core/EF/CrmEntityContact.cs rename to products/ASC.CRM/Server/Core/EF/DbEntityContact.cs index 580f94ba475..37d26ba4b2a 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmEntityContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs @@ -1,4 +1,5 @@ // This file has been auto generated by EF Core Power Tools. +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -7,16 +8,19 @@ namespace ASC.CRM.Core.EF { [Table("crm_entity_contact")] - public partial class CrmEntityContact + public partial class DbEntityContact { [Key] [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } + [Key] [Column("entity_type", TypeName = "int(11)")] public int EntityType { get; set; } + [Key] [Column("contact_id", TypeName = "int(11)")] - public int ContactId { get; set; } + public int ContactId { get; set; } } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmEntityTag.cs b/products/ASC.CRM/Server/Core/EF/DbEntityTag.cs similarity index 77% rename from products/ASC.CRM/Server/Core/EF/CrmEntityTag.cs rename to products/ASC.CRM/Server/Core/EF/DbEntityTag.cs index aeb57f1b898..b797098a23b 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmEntityTag.cs +++ b/products/ASC.CRM/Server/Core/EF/DbEntityTag.cs @@ -1,4 +1,6 @@ // This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -7,16 +9,19 @@ namespace ASC.CRM.Core.EF { [Table("crm_entity_tag")] - public partial class CrmEntityTag + public partial class DbEntityTag { [Key] [Column("tag_id", TypeName = "int(11)")] public int TagId { get; set; } + [Key] [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } + [Key] [Column("entity_type", TypeName = "int(10)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmFieldDescription.cs b/products/ASC.CRM/Server/Core/EF/DbFieldDescription.cs similarity index 95% rename from products/ASC.CRM/Server/Core/EF/CrmFieldDescription.cs rename to products/ASC.CRM/Server/Core/EF/DbFieldDescription.cs index 02f6fb15db8..9bed51f3ddf 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmFieldDescription.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldDescription.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_field_description")] - public partial class CrmFieldDescription + public partial class DbFieldDescription { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmFieldValue.cs b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs similarity index 83% rename from products/ASC.CRM/Server/Core/EF/CrmFieldValue.cs rename to products/ASC.CRM/Server/Core/EF/DbFieldValue.cs index 7eaf7c0066b..f630b0e1aea 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmFieldValue.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs @@ -1,13 +1,11 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_field_value")] - public partial class CrmFieldValue + public partial class DbFieldValue { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoice.cs b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs similarity index 98% rename from products/ASC.CRM/Server/Core/EF/CrmInvoice.cs rename to products/ASC.CRM/Server/Core/EF/DbInvoice.cs index 6ba2358ced3..c5733d08ef6 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmInvoice.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_invoice")] - public partial class CrmInvoice + public partial class DbInvoice { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs b/products/ASC.CRM/Server/Core/EF/DbInvoiceItem.cs similarity index 89% rename from products/ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs rename to products/ASC.CRM/Server/Core/EF/DbInvoiceItem.cs index d6ec6d9961c..254fad4a5fd 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmInvoiceItem.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoiceItem.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_invoice_item")] - public partial class CrmInvoiceItem + public partial class DbInvoiceItem : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] @@ -26,7 +26,7 @@ public partial class CrmInvoiceItem [Column("stock_quantity", TypeName = "decimal(10,2)")] public decimal StockQuantity { get; set; } [Column("track_inventory", TypeName = "tinyint(4)")] - public sbyte TrackInventory { get; set; } + public bool TrackInventory { get; set; } [Column("invoice_tax1_id", TypeName = "int(11)")] public int InvoiceTax1Id { get; set; } [Column("invoice_tax2_id", TypeName = "int(11)")] @@ -34,15 +34,19 @@ public partial class CrmInvoiceItem [Required] [Column("currency", TypeName = "varchar(255)")] public string Currency { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs b/products/ASC.CRM/Server/Core/EF/DbInvoiceLine.cs similarity index 96% rename from products/ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs rename to products/ASC.CRM/Server/Core/EF/DbInvoiceLine.cs index fc0082da34e..00684fd352b 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmInvoiceLine.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoiceLine.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_invoice_line")] - public partial class CrmInvoiceLine + public partial class DbInvoiceLine : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs b/products/ASC.CRM/Server/Core/EF/DbInvoiceTax.cs similarity index 85% rename from products/ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs rename to products/ASC.CRM/Server/Core/EF/DbInvoiceTax.cs index dea1fe96d21..5d489e7bd22 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmInvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoiceTax.cs @@ -7,28 +7,36 @@ namespace ASC.CRM.Core.EF { [Table("crm_invoice_tax")] - public partial class CrmInvoiceTax + public partial class DbInvoiceTax : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Required] [Column("name", TypeName = "varchar(255)")] public string Name { get; set; } + [Required] [Column("description", TypeName = "text")] public string Description { get; set; } + [Column("rate", TypeName = "decimal(10,2)")] public decimal Rate { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/CrmListItem.cs b/products/ASC.CRM/Server/Core/EF/DbListItem.cs similarity index 80% rename from products/ASC.CRM/Server/Core/EF/CrmListItem.cs rename to products/ASC.CRM/Server/Core/EF/DbListItem.cs index 30e2d845801..ad5f8155804 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmListItem.cs +++ b/products/ASC.CRM/Server/Core/EF/DbListItem.cs @@ -1,30 +1,35 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using ASC.CRM.Core.Enums; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_list_item")] - public partial class CrmListItem + public partial class DbListItem : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } + [Column("sort_order", TypeName = "int(11)")] public int SortOrder { get; set; } + [Column("color", TypeName = "varchar(255)")] public string Color { get; set; } + [Column("additional_params", TypeName = "varchar(255)")] public string AdditionalParams { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Column("list_type", TypeName = "int(255)")] - public int? ListType { get; set; } + public ListType ListType { get; set; } + [Column("description", TypeName = "varchar(255)")] public string Description { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/CrmOrganisationLogo.cs b/products/ASC.CRM/Server/Core/EF/DbOrganisationLogo.cs similarity index 94% rename from products/ASC.CRM/Server/Core/EF/CrmOrganisationLogo.cs rename to products/ASC.CRM/Server/Core/EF/DbOrganisationLogo.cs index 778fa075fdc..f34acd47a47 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmOrganisationLogo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbOrganisationLogo.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_organisation_logo")] - public partial class CrmOrganisationLogo + public partial class DbOrganisationLogo { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmProjects.cs b/products/ASC.CRM/Server/Core/EF/DbProjects.cs similarity index 72% rename from products/ASC.CRM/Server/Core/EF/CrmProjects.cs rename to products/ASC.CRM/Server/Core/EF/DbProjects.cs index ce04722c982..63a2dc86107 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmProjects.cs +++ b/products/ASC.CRM/Server/Core/EF/DbProjects.cs @@ -1,20 +1,20 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_projects")] - public partial class CrmProjects + public partial class DbProjects { [Key] [Column("project_id", TypeName = "int(10)")] public int ProjectId { get; set; } + [Key] [Column("contact_id", TypeName = "int(10)")] public int ContactId { get; set; } + [Key] [Column("tenant_id", TypeName = "int(10)")] public int TenantId { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/CrmRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs similarity index 97% rename from products/ASC.CRM/Server/Core/EF/CrmRelationshipEvent.cs rename to products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index 8ef51ce22fb..0d60c6b3558 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_relationship_event")] - public partial class CrmRelationshipEvent + public partial class DbRelationshipEvent { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmReportFile.cs b/products/ASC.CRM/Server/Core/EF/DbReportFile.cs similarity index 95% rename from products/ASC.CRM/Server/Core/EF/CrmReportFile.cs rename to products/ASC.CRM/Server/Core/EF/DbReportFile.cs index 011241dc107..c239b0355ce 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmReportFile.cs +++ b/products/ASC.CRM/Server/Core/EF/DbReportFile.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_report_file")] - public partial class CrmReportFile + public partial class DbReportFile { [Key] [Column("file_id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmTag.cs b/products/ASC.CRM/Server/Core/EF/DbTag.cs similarity index 69% rename from products/ASC.CRM/Server/Core/EF/CrmTag.cs rename to products/ASC.CRM/Server/Core/EF/DbTag.cs index 810441e4c31..b1abf57b411 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmTag.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTag.cs @@ -1,23 +1,24 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; +using ASC.CRM.Core.Enums; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_tag")] - public partial class CrmTag + public partial class DbTag : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Column("entity_type", TypeName = "int(11)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs similarity index 78% rename from products/ASC.CRM/Server/Core/EF/CrmTask.cs rename to products/ASC.CRM/Server/Core/EF/DbTask.cs index b339f9fdd10..a5aa91477cc 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -1,51 +1,66 @@ -// This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_task")] - public partial class CrmTask + public partial class DbTask { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } + [Column("description", TypeName = "text")] public string Description { get; set; } + [Column("deadline", TypeName = "datetime")] public DateTime Deadline { get; set; } + [Required] [Column("responsible_id", TypeName = "char(38)")] - public string ResponsibleId { get; set; } + public Guid ResponsibleId { get; set; } + [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } + [Column("is_closed", TypeName = "int(1)")] - public int IsClosed { get; set; } + public bool IsClosed { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Column("entity_type", TypeName = "int(11)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } + [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } + [Column("category_id", TypeName = "int(11)")] public int CategoryId { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid? LastModifedBy { get; set; } + [Column("alert_value", TypeName = "int(10)")] public int AlertValue { get; set; } + [Column("exec_alert", TypeName = "int(10)")] - public int ExecAlert { get; set; } + public bool ExecAlert { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs b/products/ASC.CRM/Server/Core/EF/DbTaskTemplate.cs similarity index 80% rename from products/ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs rename to products/ASC.CRM/Server/Core/EF/DbTaskTemplate.cs index 3b694981a7d..b92bcbac057 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplate.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTaskTemplate.cs @@ -7,41 +7,55 @@ namespace ASC.CRM.Core.EF { [Table("crm_task_template")] - public partial class CrmTaskTemplate + public partial class DbTaskTemplate : IDbCrm { [Key] [Column("id", TypeName = "int(10)")] public int Id { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime LastModifedOn { get; set; } + [Required] [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } + [Column("category_id", TypeName = "int(10)")] public int CategoryId { get; set; } + [Column("description", TypeName = "tinytext")] public string Description { get; set; } + [Required] [Column("responsible_id", TypeName = "char(38)")] - public string ResponsibleId { get; set; } + public Guid ResponsibleId { get; set; } + [Column("is_notify", TypeName = "tinyint(4)")] - public sbyte IsNotify { get; set; } + public bool IsNotify { get; set; } + [Column("offset", TypeName = "bigint(20)")] public long Offset { get; set; } + [Column("sort_order", TypeName = "int(11)")] public int SortOrder { get; set; } + [Column("deadLine_is_fixed", TypeName = "tinyint(4)")] - public sbyte DeadLineIsFixed { get; set; } + public bool DeadLineIsFixed { get; set; } + [Column("tenant_id", TypeName = "int(10)")] public int TenantId { get; set; } + [Column("container_id", TypeName = "int(10)")] public int ContainerId { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/EF/DbTaskTemplateContainer.cs similarity index 78% rename from products/ASC.CRM/Server/Core/EF/CrmTaskTemplateContainer.cs rename to products/ASC.CRM/Server/Core/EF/DbTaskTemplateContainer.cs index 5105b10bf5c..dcec0776eeb 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateContainer.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTaskTemplateContainer.cs @@ -1,4 +1,5 @@ // This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -7,27 +8,34 @@ namespace ASC.CRM.Core.EF { [Table("crm_task_template_container")] - public partial class CrmTaskTemplateContainer + public partial class DbTaskTemplateContainer : IDbCrm { [Key] [Column("id", TypeName = "int(10)")] public int Id { get; set; } + [Required] [Column("title", TypeName = "varchar(256)")] public string Title { get; set; } + [Column("entity_type", TypeName = "int(10)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } + [Column("tenant_id", TypeName = "int(10)")] public int TenantId { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime LastModifedOn { get; set; } + [Required] [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateTask.cs b/products/ASC.CRM/Server/Core/EF/DbTaskTemplateTask.cs similarity index 66% rename from products/ASC.CRM/Server/Core/EF/CrmTaskTemplateTask.cs rename to products/ASC.CRM/Server/Core/EF/DbTaskTemplateTask.cs index cc51f2c0249..310fe1b0ba9 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmTaskTemplateTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTaskTemplateTask.cs @@ -1,20 +1,19 @@ -// This file has been auto generated by EF Core Power Tools. -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_task_template_task")] - public partial class CrmTaskTemplateTask + public partial class DbTaskTemplateTask : IDbCrm { [Key] [Column("task_id", TypeName = "int(10)")] public int TaskId { get; set; } + [Key] [Column("task_template_id", TypeName = "int(10)")] public int TaskTemplateId { get; set; } + [Key] [Column("tenant_id", TypeName = "int(10)")] public int TenantId { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/CrmVoipCalls.cs b/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs similarity index 98% rename from products/ASC.CRM/Server/Core/EF/CrmVoipCalls.cs rename to products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs index b493c90d0f1..5d787568a3b 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmVoipCalls.cs +++ b/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_voip_calls")] - public partial class CrmVoipCalls + public partial class DbVoipCalls { [Key] [Column("id", TypeName = "varchar(50)")] diff --git a/products/ASC.CRM/Server/Core/EF/CrmVoipNumber.cs b/products/ASC.CRM/Server/Core/EF/DbVoipNumber.cs similarity index 95% rename from products/ASC.CRM/Server/Core/EF/CrmVoipNumber.cs rename to products/ASC.CRM/Server/Core/EF/DbVoipNumber.cs index 41d8e66a3a1..d0df468511c 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmVoipNumber.cs +++ b/products/ASC.CRM/Server/Core/EF/DbVoipNumber.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_voip_number")] - public partial class CrmVoipNumber + public partial class DbVoipNumber { [Key] [Column("id", TypeName = "varchar(50)")] diff --git a/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs b/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs index d5f1a6f8626..116999c9a93 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/CRMPatternResource.Designer.cs @@ -1,325 +1,324 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ASC.CRM.Services.NotifyService { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class CRMPatternResource { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal CRMPatternResource() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Services.NotifyService.CRMPatternResource", typeof(CRMPatternResource).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to h1. New event added to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" - ///$__DateTime "$__AuthorName":"$__AuthorUrl" has added a new event to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}": - /// $AdditionalData.get_item("EventContent") - /// - /// #foreach($fileInfo in $AdditionalData.get_item("Files").Keys) - /// - /// #beforeall - /// - /// ---------------------------------------- - /// - /// #each - /// - /// " [rest of string was truncated]";. - /// - public static string pattern_AddRelationshipEvent { - get { - return ResourceManager.GetString("pattern_AddRelationshipEvent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1. CRM. New contact created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" - /// - ///$__DateTime A new contact has been created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" - /// - ///Contact information: - /// - ///#foreach($contactInfo in $AdditionalData.Keys) - ///#each - /// - ///$contactInfo: $AdditionalData.get_item($contactInfo) - /// - ///#end. - /// - public static string pattern_CreateNewContact { - get { - return ResourceManager.GetString("pattern_CreateNewContact", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1. CRM. Data export successfully completed - /// - ///Please, follow this link to download the archive: "exportdata.zip":"${EntityRelativeURL}" - /// - ///*Note*: this link is valid for 24 hours only. - /// - ///If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" - /// - ///Best regards, - ///ONLYOFFICE™ Support Team - ///"www.onlyoffice.com":"http://onlyoffice.com/". - /// - public static string pattern_ExportCompleted { - get { - return ResourceManager.GetString("pattern_ExportCompleted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1. CRM. Data export successfully completed - /// - ///Please, follow this link to download the archive: "${EntityTitle}":"${EntityRelativeURL}" - /// - ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. - /// - public static string pattern_ExportCompletedCustomMode { - get { - return ResourceManager.GetString("pattern_ExportCompletedCustomMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1. CRM. Data import successfully completed - /// - ///Go to the "Contacts":"$__VirtualRootPath/products/crm/" list. - /// - ///If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" - /// - ///Best regards, - ///ONLYOFFICE™ Support Team - ///"www.onlyoffice.com":"http://onlyoffice.com/". - /// - public static string pattern_ImportCompleted { - get { - return ResourceManager.GetString("pattern_ImportCompleted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1. CRM. Data import successfully completed - /// - ///Go to the "${Tag_EntityListTitle}":"$__VirtualRootPath/${Tag_EntityListRelativeURL}" list. - /// - ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. - /// - public static string pattern_ImportCompletedCustomMode { - get { - return ResourceManager.GetString("pattern_ImportCompletedCustomMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1.You were appointed responsible for the opportunity: "$EntityTitle":"${__VirtualRootPath}/products/crm/deals.aspx?id=$EntityID" - /// - ///$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the opportunity: $EntityTitle . - /// - ///#if($AdditionalData.get_item("OpportunityDescription")&&$AdditionalData.get_item("OpportunityDescription")!="") - /// - ///Opportunity description: - ///$AdditionalData.get_item("OpportunityDescription") - ///#end. - /// - public static string pattern_ResponsibleForOpportunity { - get { - return ResourceManager.GetString("pattern_ResponsibleForOpportunity", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1.Task assigned to you: $EntityTitle - /// - ///$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the task: $EntityTitle. - ///#if($AdditionalData.get_item("TaskCategory")) - /// - ///Task category: $AdditionalData.get_item("TaskCategory") - ///#end - ///#if($AdditionalData.get_item("ContactRelativeUrl")) - /// - ///Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" - ///#end - ///#if($AdditionalData.get_item("CaseRelativeUrl")) - /// - ///Link with case: "$Addit [rest of string was truncated]";. - /// - public static string pattern_ResponsibleForTask { - get { - return ResourceManager.GetString("pattern_ResponsibleForTask", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1.Access granted to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" - /// - ///$__DateTime "$__AuthorName":"$__AuthorUrl" has granted you the access to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}".. - /// - public static string pattern_SetAccess { - get { - return ResourceManager.GetString("pattern_SetAccess", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to h1. Reminder about the task: $EntityTitle - ///#if($AdditionalData.get_item("TaskCategory")) - /// - ///Task category: $AdditionalData.get_item("TaskCategory") - ///#end - ///#if($AdditionalData.get_item("ContactRelativeUrl")) - /// - ///Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" - ///#end - ///#if($AdditionalData.get_item("CaseRelativeUrl")) - /// - ///Link with case: "$AdditionalData.get_item("CaseTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("CaseRelativeUrl") [rest of string was truncated]";. - /// - public static string pattern_TaskReminder { - get { - return ResourceManager.GetString("pattern_TaskReminder", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to <patterns> - /// <formatter type="ASC.Notify.Patterns.NVelocityPatternFormatter, ASC.Common" /> - /// - /// <!--Export is completed--> - /// <pattern id="ExportCompleted" sender="email.sender"> - /// <subject resource="|subject_ExportCompleted|ASC.Web.CRM.Services.NotifyService.CRMPatternResource,ASC.Web.CRM" /> - /// <body styler="ASC.Notify.Textile.TextileStyler,ASC.Notify.Textile" resource="|pattern_ExportCompleted|ASC.Web.CRM.Services.NotifyService.CRMPatternResource,ASC.Web.CRM" /> - /// </pattern> - /// <pattern id="Expor [rest of string was truncated]";. - /// - public static string patterns { - get { - return ResourceManager.GetString("patterns", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. New event added to $EntityTitle. - /// - public static string subject_AddRelationshipEvent { - get { - return ResourceManager.GetString("subject_AddRelationshipEvent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. New contact created using 'Website Contact Form'. - /// - public static string subject_CreateNewContact { - get { - return ResourceManager.GetString("subject_CreateNewContact", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. Data export successfully completed. - /// - public static string subject_ExportCompleted { - get { - return ResourceManager.GetString("subject_ExportCompleted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. Data import successfully completed. - /// - public static string subject_ImportCompleted { - get { - return ResourceManager.GetString("subject_ImportCompleted", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. You were appointed as a responsible person for the opportunity: $EntityTitle. - /// - public static string subject_ResponsibleForOpportunity { - get { - return ResourceManager.GetString("subject_ResponsibleForOpportunity", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. Task assigned to you: $EntityTitle. - /// - public static string subject_ResponsibleForTask { - get { - return ResourceManager.GetString("subject_ResponsibleForTask", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. Access granted to $EntityTitle. - /// - public static string subject_SetAccess { - get { - return ResourceManager.GetString("subject_SetAccess", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CRM. Reminder about the task: $EntityTitle. - /// - public static string subject_TaskReminder { - get { - return ResourceManager.GetString("subject_TaskReminder", resourceCulture); - } - } - } -} +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ASC.CRM.Services.NotifyService { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CRMPatternResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CRMPatternResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.CRM.Services.NotifyService.CRMPatternResource", typeof(CRMPatternResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to h1. New event added to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has added a new event to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}": + /// $AdditionalData.get_item("EventContent") + /// + /// #foreach($fileInfo in $AdditionalData.get_item("Files").Keys) + /// + /// #beforeall + /// + /// ---------------------------------------- + /// + /// #each + /// /// [rest of string was truncated]";. + /// + public static string pattern_AddRelationshipEvent { + get { + return ResourceManager.GetString("pattern_AddRelationshipEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. New contact created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" + /// + ///$__DateTime A new contact has been created using the 'Website Contact Form' "$EntityTitle":"${__VirtualRootPath}/products/crm/default.aspx?ID=$EntityID" + /// + ///Contact information: + /// + ///#foreach($contactInfo in $AdditionalData.Keys) + ///#each + /// + ///$contactInfo: $AdditionalData.get_item($contactInfo) + /// + ///#end. + /// + public static string pattern_CreateNewContact { + get { + return ResourceManager.GetString("pattern_CreateNewContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data export successfully completed + /// + ///Please, follow this link to download the archive: "exportdata.zip":"${EntityRelativeURL}" + /// + ///*Note*: this link is valid for 24 hours only. + /// + ///If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" + /// + ///Best regards, + ///ONLYOFFICE™ Support Team + ///"www.onlyoffice.com":"http://onlyoffice.com/". + /// + public static string pattern_ExportCompleted { + get { + return ResourceManager.GetString("pattern_ExportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data export successfully completed + /// + ///Please, follow this link to download the archive: "${EntityTitle}":"${EntityRelativeURL}" + /// + ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. + /// + public static string pattern_ExportCompletedCustomMode { + get { + return ResourceManager.GetString("pattern_ExportCompletedCustomMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data import successfully completed + /// + ///Go to the "Contacts":"$__VirtualRootPath/products/crm/" list. + /// + ///If you have any questions or need assistance please feel free to contact us at "support.onlyoffice.com":"http://support.onlyoffice.com" + /// + ///Best regards, + ///ONLYOFFICE™ Support Team + ///"www.onlyoffice.com":"http://onlyoffice.com/". + /// + public static string pattern_ImportCompleted { + get { + return ResourceManager.GetString("pattern_ImportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. CRM. Data import successfully completed + /// + ///Go to the "${Tag_EntityListTitle}":"$__VirtualRootPath/${Tag_EntityListRelativeURL}" list. + /// + ///^You receive this email because you are a registered user of the "${__VirtualRootPath}":"${__VirtualRootPath}" portal. To change the notification type, please manage your "subscription settings":"$RecipientSubscriptionConfigURL".^. + /// + public static string pattern_ImportCompletedCustomMode { + get { + return ResourceManager.GetString("pattern_ImportCompletedCustomMode", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1.You were appointed responsible for the opportunity: "$EntityTitle":"${__VirtualRootPath}/products/crm/deals.aspx?id=$EntityID" + /// + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the opportunity: $EntityTitle . + /// + ///#if($AdditionalData.get_item("OpportunityDescription")&&$AdditionalData.get_item("OpportunityDescription")!="") + /// + ///Opportunity description: + ///$AdditionalData.get_item("OpportunityDescription") + ///#end. + /// + public static string pattern_ResponsibleForOpportunity { + get { + return ResourceManager.GetString("pattern_ResponsibleForOpportunity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1.Task assigned to you: $EntityTitle + /// + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has appointed you responsible for the task: $EntityTitle. + ///#if($AdditionalData.get_item("TaskCategory")) + /// + ///Task category: $AdditionalData.get_item("TaskCategory") + ///#end + ///#if($AdditionalData.get_item("ContactRelativeUrl")) + /// + ///Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" + ///#end + ///#if($AdditionalData.get_item("CaseRelativeUrl")) + /// + ///Link with [rest of string was truncated]";. + /// + public static string pattern_ResponsibleForTask { + get { + return ResourceManager.GetString("pattern_ResponsibleForTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1.Access granted to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}" + /// + ///$__DateTime "$__AuthorName":"$__AuthorUrl" has granted you the access to "$EntityTitle":"${__VirtualRootPath}/${EntityRelativeURL}".. + /// + public static string pattern_SetAccess { + get { + return ResourceManager.GetString("pattern_SetAccess", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to h1. Reminder about the task: $EntityTitle + ///#if($AdditionalData.get_item("TaskCategory")) + /// + ///Task category: $AdditionalData.get_item("TaskCategory") + ///#end + ///#if($AdditionalData.get_item("ContactRelativeUrl")) + /// + ///Link with contact: "$AdditionalData.get_item("ContactTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("ContactRelativeUrl")" + ///#end + ///#if($AdditionalData.get_item("CaseRelativeUrl")) + /// + ///Link with case: "$AdditionalData.get_item("CaseTitle")":"${__VirtualRootPath}/$AdditionalData.get_item("CaseRe [rest of string was truncated]";. + /// + public static string pattern_TaskReminder { + get { + return ResourceManager.GetString("pattern_TaskReminder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <patterns> + /// <formatter type="ASC.Notify.Patterns.NVelocityPatternFormatter, ASC.Common" /> + /// + /// <!--Export is completed--> + /// <pattern id="ExportCompleted" sender="email.sender"> + /// <subject resource="|subject_ExportCompleted|ASC.Web.CRM.Services.NotifyService.CRMPatternResource,ASC.Web.CRM" /> + /// <body styler="ASC.Notify.Textile.TextileStyler,ASC.Notify.Textile" resource="|pattern_ExportCompleted|ASC.Web.CRM.Services.NotifyService.CRMPatternResource,ASC.Web.CRM" /> + /// </pattern> + /// <pattern id="Expor [rest of string was truncated]";. + /// + public static string patterns { + get { + return ResourceManager.GetString("patterns", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. New event added to $EntityTitle. + /// + public static string subject_AddRelationshipEvent { + get { + return ResourceManager.GetString("subject_AddRelationshipEvent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. New contact created using 'Website Contact Form'. + /// + public static string subject_CreateNewContact { + get { + return ResourceManager.GetString("subject_CreateNewContact", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Data export successfully completed. + /// + public static string subject_ExportCompleted { + get { + return ResourceManager.GetString("subject_ExportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Data import successfully completed. + /// + public static string subject_ImportCompleted { + get { + return ResourceManager.GetString("subject_ImportCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. You were appointed as a responsible person for the opportunity: $EntityTitle. + /// + public static string subject_ResponsibleForOpportunity { + get { + return ResourceManager.GetString("subject_ResponsibleForOpportunity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Task assigned to you: $EntityTitle. + /// + public static string subject_ResponsibleForTask { + get { + return ResourceManager.GetString("subject_ResponsibleForTask", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Access granted to $EntityTitle. + /// + public static string subject_SetAccess { + get { + return ResourceManager.GetString("subject_SetAccess", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to CRM. Reminder about the task: $EntityTitle. + /// + public static string subject_TaskReminder { + get { + return ResourceManager.GetString("subject_TaskReminder", resourceCulture); + } + } + } +} From 36e6b0a7918321126914c06be33ee0861c843924 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 16 Mar 2020 11:58:34 +0300 Subject: [PATCH 03/61] crm: migrate DAO to EF Core --- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 6 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 31 +- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 7 +- .../Server/Core/Dao/CurrencyInfoDao.cs | 56 +-- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 180 +++++--- .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 8 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 114 +++-- .../Server/Core/Dao/DealMilestoneDao.cs | 156 +++---- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 434 ++++++++++-------- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 10 +- .../Server/Core/Dao/ListItemHistoryDao.cs | 239 ---------- .../Server/Core/Dao/RelationshipEventDao.cs | 291 ++++++------ products/ASC.CRM/Server/Core/Dao/TagDao.cs | 2 + products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 134 +++--- .../Core/Dao/TaskTemplateContainerDao.cs | 1 - .../ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs | 11 +- .../Server/Core/EF/DbFieldDescription.cs | 13 +- .../ASC.CRM/Server/Core/EF/DbFieldValue.cs | 16 +- products/ASC.CRM/Server/Core/EF/DbInvoice.cs | 37 +- .../Server/Core/EF/DbRelationshipEvent.cs | 22 +- products/ASC.CRM/Server/Core/EF/DbTask.cs | 2 +- 21 files changed, 863 insertions(+), 907 deletions(-) delete mode 100644 products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index af85343c9b3..5933931fdb0 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -302,8 +302,7 @@ protected string GetTenantColumnName(string table) if (!table.Contains(" ")) return tenant; - return table.Substring(table.IndexOf(" ")).Trim() + "." + tenant; - + return table.Substring(table.IndexOf(" ")).Trim() + "." + tenant; } @@ -311,8 +310,7 @@ protected static Guid ToGuid(object guid) { var str = guid as string; - return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty; - + return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty; } } diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 50ee9cda3d6..796204ca18e 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -31,6 +31,7 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.Files.Core; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; using System; @@ -46,9 +47,24 @@ public class CachedCasesDao : CasesDao { private readonly HttpRequestDictionary _casesCache = new HttpRequestDictionary("crm_cases"); - public CachedCasesDao(int tenantID) - : base(tenantID) + public CachedCasesDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + FilesIntegration filesIntegration + ) : + base(dbContextManager, + tenantManager, + securityContext, + cRMSecurity, + tenantUtil, + filesIntegration) + { + + + } public override Cases GetByID(int caseID) @@ -90,7 +106,8 @@ public CasesDao( SecurityContext securityContext, CRMSecurity cRMSecurity, TenantUtil tenantUtil, - FilesIntegration filesIntegration + FilesIntegration filesIntegration, + AuthorizationManager authorizationManager ) : base(dbContextManager, tenantManager, @@ -99,9 +116,10 @@ FilesIntegration filesIntegration CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; FilesIntegration = filesIntegration; + AuthorizationManager = authorizationManager; } - public CoreContext CoreContext { get; } + public AuthorizationManager AuthorizationManager { get; } public FilesIntegration FilesIntegration { get; } @@ -324,7 +342,7 @@ private void DeleteBatchCasesExecute(List caseses) tx.Commit(); - caseses.ForEach(item => CoreContext.AuthorizationManager.RemoveAllAces(item)); + caseses.ForEach(item => AuthorizationManager.RemoveAllAces(item)); if (0 < tagNames.Length) { @@ -341,7 +359,7 @@ private void DeleteBatchCasesExecute(List caseses) public List GetAllCases() { - return GetCases(String.Empty, 0, null, null, 0, 0, new OrderBy(SortedByType.Title, true)); + return GetCases(String.Empty, 0, null, null, 0, 0, new OrderBy(Enums.SortedByType.Title, true)); } public int GetCasesCount() @@ -533,6 +551,7 @@ public List GetCases( sqlQuery.OrderBy("is_closed", true); + if (orderBy != null && Enum.IsDefined(typeof(SortedByType), orderBy.SortedBy)) switch ((SortedByType)orderBy.SortedBy) { diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 509482d5609..7dabffe58fd 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -93,15 +93,12 @@ public override int Update(ContactInfo contactInfo) } public class ContactInfoDao : AbstractDao - { - #region Constructor - + { public ContactInfoDao(int tenantID) : base(tenantID) { - } - #endregion + } public virtual ContactInfo GetByID(int id) { diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 349f7c59625..5c34373112f 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -24,18 +24,13 @@ */ -#region Import - using System; using System.Collections.Generic; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; +using System.Linq; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; -#endregion - namespace ASC.CRM.Core.Dao { public class CurrencyInfoDao : AbstractDao @@ -55,51 +50,40 @@ public CurrencyInfoDao(DbContextManager dbContextManager, public virtual List GetAll() { - return Db.ExecuteList(GetSqlQuery(null)).ConvertAll(ToCurrencyInfo); + return CRMDbContext.CurrencyInfo.ToList().ConvertAll(ToCurrencyInfo); } public virtual CurrencyInfo GetByAbbreviation(string abbreviation) { - var currencies = Db.ExecuteList(GetSqlQuery(Exp.Eq("abbreviation", abbreviation))).ConvertAll(ToCurrencyInfo); - - return currencies.Count > 0 ? currencies[0] : null; + return ToCurrencyInfo(CRMDbContext.CurrencyInfo + .FirstOrDefault(x => String.Compare(x.Abbreviation, abbreviation, true) == 0)); } public List GetBasic() { - return Db.ExecuteList(GetSqlQuery(Exp.Eq("is_basic", true))).ConvertAll(ToCurrencyInfo); + return CRMDbContext.CurrencyInfo + .Where(x => x.IsBasic) + .ToList() + .ConvertAll(ToCurrencyInfo); } public List GetOther() { - return Db.ExecuteList(GetSqlQuery(Exp.Eq("is_basic", false))).ConvertAll(ToCurrencyInfo); + return CRMDbContext.CurrencyInfo + .Where(x => !x.IsBasic) + .ToList() + .ConvertAll(ToCurrencyInfo); } - - private SqlQuery GetSqlQuery(Exp where) - { - var sqlQuery = new SqlQuery("crm_currency_info") - .Select("resource_key", - "abbreviation", - "symbol", - "culture_name", - "is_convertable", - "is_basic"); - - if (where != null) - sqlQuery.Where(where); - - return sqlQuery; - } - - private static CurrencyInfo ToCurrencyInfo(object[] row) + + private static CurrencyInfo ToCurrencyInfo(DbCurrencyInfo dbCurrencyInfo) { return new CurrencyInfo( - Convert.ToString(row[0]), - Convert.ToString(row[1]), - Convert.ToString(row[2]), - Convert.ToString(row[3]), - Convert.ToBoolean(row[4]), - Convert.ToBoolean(row[5]) + dbCurrencyInfo.ResourceKey, + dbCurrencyInfo.Abbreviation, + dbCurrencyInfo.Abbreviation, + dbCurrencyInfo.CultureName, + dbCurrencyInfo.IsConvertable, + dbCurrencyInfo.IsBasic ); } } diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index f28d6f1f42c..8bd7e01347a 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -23,51 +23,55 @@ * */ - -#region Import - -using System; -using System.Collections.Generic; -using System.Linq; +using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; -using ASC.Web.CRM.Classes; -using Newtonsoft.Json; -using ASC.Common.Data; -using ASC.Core; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.ElasticSearch; +using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using ASC.Web.CRM.Resources; - -#endregion +using System; +using System.Collections.Generic; +using System.Linq; namespace ASC.CRM.Core.Dao { public class CustomFieldDao : AbstractDao { - public CustomFieldDao(int tenantID) - : base(tenantID) + public CustomFieldDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + TenantUtil tenantUtil + ) : + base(dbContextManager, + tenantManager, + securityContext) { - + TenantUtil = tenantUtil; } + public TenantUtil TenantUtil { get; } + + public FactoryIndexer FactoryIndexer { get; } + public void SaveList(List items) { if (items == null || items.Count == 0) return; - using (var tx = Db.BeginTransaction(true)) - { - foreach (var customField in items) - { - SetFieldValueInDb(customField.EntityType, customField.EntityID, customField.ID, customField.Value); - } + var tx = CRMDbContext.Database.BeginTransaction(); - tx.Commit(); + foreach (var customField in items) + { + SetFieldValueInDb(customField.EntityType, customField.EntityID, customField.ID, customField.Value); } + tx.Commit(); } public void SetFieldValue(EntityType entityType, int entityID, int fieldID, String fieldValue) @@ -86,12 +90,17 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, throw new ArgumentException(); fieldValue = fieldValue.Trim(); + + var itemToDelete = Query(CRMDbContext.FieldValue) + .Where(x => x.EntityId == entityID && x.EntityType == entityType && x.FieldId == fieldID); - Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType) & Exp.Eq("field_id", fieldID))); + CRMDbContext.FieldValue.RemoveRange(itemToDelete); + CRMDbContext.SaveChanges(); if (!String.IsNullOrEmpty(fieldValue)) { var lastModifiedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); + var id = Db.ExecuteScalar( Insert("crm_field_value") .InColumnValue("id", 0) @@ -101,10 +110,9 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, .InColumnValue("entity_type", (int)entityType) .InColumnValue("last_modifed_on", lastModifiedOn) .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true) - ); + .Identity(1, 0, true)); - FactoryIndexer.IndexAsync(new FieldsWrapper + FactoryIndexer.IndexAsync(new FieldsWrapper { Id = id, EntityId = entityID, @@ -112,7 +120,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, Value = fieldValue, FieldId = fieldID, LastModifiedOn = lastModifiedOn, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = TenantID }); } } @@ -124,7 +132,7 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) if (customFieldType == CustomFieldType.CheckBox || customFieldType == CustomFieldType.Heading || customFieldType == CustomFieldType.Date) return String.Empty; - if(String.IsNullOrEmpty(mask)) + if (String.IsNullOrEmpty(mask)) throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); try @@ -215,21 +223,31 @@ public int CreateField(EntityType entityType, String label, CustomFieldType cust throw new ArgumentException(); var resultMask = GetValidMask(customFieldType, mask); - var sortOrder = Db.ExecuteScalar(Query("crm_field_description").SelectMax("sort_order")) + 1; - - return Db.ExecuteScalar( - Insert("crm_field_description") - .InColumnValue("id", 0) - .InColumnValue("label", label) - .InColumnValue("type", (int)customFieldType) - .InColumnValue("mask", resultMask) - .InColumnValue("sort_order", sortOrder) - .InColumnValue("entity_type", (int)entityType) - .Identity(1, 0, true)); + var sortOrder = Query(CRMDbContext.FieldDescription).Select(x => x.SortOrder).Max() + 1; + + var itemToInsert = new DbFieldDescription + { + Label = label, + Type = customFieldType, + Mask = resultMask, + SortOrder = sortOrder, + EntityType = entityType, + TenantId = TenantID + }; + + CRMDbContext.FieldDescription.Add(itemToInsert); + + CRMDbContext.SaveChanges(); + + return itemToInsert.Id; } public String GetValue(EntityType entityType, int entityID, int fieldID) { + + Query(CRMDbContext.FieldValue).Where(x => x.FieldId == fieldID && x.EntityId == entityID); + + var sqlQuery = Query("crm_field_value") .Select("value") .Where(Exp.Eq("field_id", fieldID) @@ -241,6 +259,10 @@ public String GetValue(EntityType entityType, int entityID, int fieldID) public List GetEntityIds(EntityType entityType, int fieldID, String fieldValue) { + + Query(CRMDbContext.FieldValue).Where(x => x.FieldId == fieldID && String.Compare(x.Value, fieldValue, true) == 0); + + var sqlQuery = Query("crm_field_value") .Select("entity_id") .Where(Exp.Eq("field_id", fieldID) @@ -252,8 +274,7 @@ public List GetEntityIds(EntityType entityType, int fieldID, String field public bool IsExist(int id) { - return Db.ExecuteScalar("select exists(select 1 from crm_field_description where tenant_id = @tid and id = @id)", - new { tid = TenantID, id = id }); + return Query(CRMDbContext.FieldDescription).Where(x => x.Id == id).Any(); } public int GetFieldId(EntityType entityType, String label, CustomFieldType customFieldType) @@ -264,6 +285,7 @@ public int GetFieldId(EntityType entityType, String label, CustomFieldType custo & Exp.Eq("label", label))).ConvertAll(row => ToCustomField(row)); if (result.Count == 0) return 0; + else return result[0].ID; } @@ -294,7 +316,7 @@ public void EditItem(CustomField customField) else { var maskObjOld = JToken.Parse(oldMask); - var maskObjNew =JToken.Parse(customField.Mask); + var maskObjNew = JToken.Parse(customField.Mask); if (!(maskObjOld is JArray && maskObjNew is JArray)) { @@ -332,28 +354,35 @@ public void EditItem(CustomField customField) else { var resultMask = GetValidMask(customField.FieldType, customField.Mask); + Db.ExecuteNonQuery( Update("crm_field_description") .Set("label", customField.Label) .Set("type", (int)customField.FieldType) .Set("mask", resultMask) .Where(Exp.Eq("id", customField.ID))); + } } public void ReorderFields(int[] fieldID) { for (int index = 0; index < fieldID.Length; index++) - Db.ExecuteNonQuery(Update("crm_field_description") - .Set("sort_order", index) - .Where(Exp.Eq("id", fieldID[index]))); + { + var itemToUpdate = Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID[index]); + + itemToUpdate.SortOrder = index; + + CRMDbContext.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); + } } private bool HaveRelativeLink(int fieldID) { - return - Db.ExecuteScalar( - Query("crm_field_value").Where(Exp.Eq("field_id", fieldID)).SelectCount()) > 0; + return Query(CRMDbContext.FieldValue) + .Where(x => x.FieldId == fieldID).Any(); } public String GetContactLinkCountJSON(EntityType entityType) @@ -379,6 +408,8 @@ public int GetContactLinkCount(EntityType entityType, int entityID) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); + Query(); + var sqlQuery = Query("crm_field_description tblFD") .Select("count(tblFV.field_id)") .LeftOuterJoin("crm_field_value tblFV", Exp.EqColumns("tblFD.id", "tblFV.field_id")) @@ -510,28 +541,39 @@ public void DeleteField(int fieldID) //if (HaveRelativeLink(fieldID)) // throw new ArgumentException(); - using (var tx = Db.BeginTransaction()) - { - Db.ExecuteNonQuery(Delete("crm_field_description").Where(Exp.Eq("id", fieldID))); - Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.Eq("field_id", fieldID))); + var tx = CRMDbContext.Database.BeginTransaction(); - tx.Commit(); - } + var fieldDescription = new DbFieldDescription { Id = fieldID }; + + CRMDbContext.FieldDescription.Attach(fieldDescription); + CRMDbContext.FieldDescription.Remove(fieldDescription); + + var fieldValue = Query(CRMDbContext.FieldValue).FirstOrDefault(x => x.FieldId == fieldID); + + CRMDbContext.Remove(fieldValue); + + CRMDbContext.SaveChanges(); + + tx.Commit(); } - public static CustomField ToCustomField(object[] row) + public static CustomField ToCustomField(DbFieldDescription dbFieldDescription, + DbFieldValue dbFieldValue) { - return new CustomField - { - ID = Convert.ToInt32(row[0]), - EntityID = Convert.ToInt32(row[1]), - EntityType = (EntityType)Convert.ToInt32(row[7]), - Label = Convert.ToString(row[2]), - Value = Convert.ToString(row[3]), - FieldType = (CustomFieldType)Convert.ToInt32(row[4]), - Position = Convert.ToInt32(row[5]), - Mask = Convert.ToString(row[6]) - }; + + + throw new NotImplementedException(); + //return new CustomField + //{ + // ID = Convert.ToInt32(row[0]), + // EntityID = Convert.ToInt32(row[1]), + // EntityType = (EntityType)Convert.ToInt32(row[7]), + // Label = Convert.ToString(row[2]), + // Value = Convert.ToString(row[3]), + // FieldType = (CustomFieldType)Convert.ToInt32(row[4]), + // Position = Convert.ToInt32(row[5]), + // Mask = Convert.ToString(row[6]) + //}; } } diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 7d62d5e84d8..4cace532364 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -34,17 +34,11 @@ public class DaoFactory private readonly TypedParameter tenant; public ILifetimeScope Container { get; set; } - #region Constructor - public DaoFactory(int tenantID) { tenant = GetParameter(tenantID); } - #endregion - - #region Methods - public TaskDao TaskDao { get { return Container.Resolve(tenant); } @@ -164,6 +158,6 @@ private TypedParameter GetParameter(T data) { return new TypedParameter(typeof(T), data); } - #endregion + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 8e0a990483f..bb3a36052e9 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -48,9 +48,18 @@ public class CachedDealDao : DealDao { private readonly HttpRequestDictionary _dealCache = new HttpRequestDictionary("crm_deal"); - public CachedDealDao(int tenantID) - : base(tenantID) + public CachedDealDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + FactoryIndexer factoryIndexer) + : base(dbContextManager, + tenantManager, + securityContext, + cRMSecurity, + factoryIndexer) { + } public override void EditDeal(Deal deal) @@ -95,18 +104,23 @@ public class DealDao : AbstractDao public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity) : + CRMSecurity cRMSecurity, + FactoryIndexer factoryIndexer) : base(dbContextManager, tenantManager, securityContext) { - + CRMSecurity = cRMSecurity; + FactoryIndexer = factoryIndexer; } + FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } public CRMSecurity CRMSecurity { get; } + public AuthorizationManager AuthorizationManager { get; } + #endregion #region Methods @@ -159,7 +173,7 @@ public virtual int CreateNewDeal(Deal deal) deal.ID = result; - FactoryIndexer.IndexAsync(deal); + FactoryIndexer.IndexAsync(deal); return result; } @@ -208,7 +222,7 @@ public virtual int[] SaveDealList(List items) tx.Commit(); foreach (var item in items) { - FactoryIndexer.IndexAsync(item); + FactoryIndexer.IndexAsync(item); } return result; } @@ -244,7 +258,7 @@ public virtual void EditDeal(Deal deal) .Where(Exp.Eq("id", deal.ID)) ); - FactoryIndexer.IndexAsync(deal); + FactoryIndexer.IndexAsync(deal); } @@ -293,7 +307,7 @@ private Exp WhereConditional( { if (!BundleSearch.TrySelectOpportunity(searchText, out ids)) { - conditions.Add(BuildLike(new[] {"tblDeal.title", "tblDeal.description"}, keywords)); + conditions.Add(BuildLike(new[] { "tblDeal.title", "tblDeal.description" }, keywords)); } else if (ids.Count == 0) return null; } @@ -706,7 +720,7 @@ public virtual Deal DeleteDeal(int dealID) DeleteBatchDealsExecute(new List() { deal }); - FactoryIndexer.DeleteAsync(deal); + FactoryIndexer.DeleteAsync(deal); return deal; } @@ -762,40 +776,59 @@ private void DeleteBatchDealsExecute(List deals) tx.Commit(); } - deals.ForEach(deal => CoreContext.AuthorizationManager.RemoveAllAces(deal)); + deals.ForEach(deal => AuthorizationManager.RemoveAllAces(deal)); } - using (var filedao = FilesIntegration.GetFileDao()) + var filedao = FilesIntegration.GetFileDao(); + + foreach (var filesID in filesIDs) { - foreach (var filesID in filesIDs) - { - filedao.DeleteFile(filesID); - } + filedao.DeleteFile(filesID); } - } - #region Private Methods + } - private static Deal ToDeal(object[] row) + private Deal ToDeal(DbDeal dbDeal) { + if (dbDeal == null) return null; + return new Deal - { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - Description = Convert.ToString(row[2]), - ResponsibleID = ToGuid(row[3]), - ContactID = Convert.ToInt32(row[4]), - BidCurrency = Convert.ToString(row[5]), - BidValue = Convert.ToDecimal(row[6]), - BidType = (BidType)Convert.ToInt32(row[7]), - DealMilestoneID = Convert.ToInt32(row[8]), - ExpectedCloseDate = Convert.ToDateTime(row[9]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[9])), - PerPeriodValue = Convert.ToInt32(row[10]), - DealMilestoneProbability = Convert.ToInt32(row[11]), - CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[12])), - CreateBy = ToGuid(row[13]), - ActualCloseDate = Convert.ToDateTime(row[14]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[14])) - }; + { + ID = dbDeal.Id, + Title = dbDeal.Title, + Description = dbDeal.Description, + ResponsibleID = dbDeal.ResponsibleId, + ContactID = dbDeal.ContactId, + BidCurrency = dbDeal.BidCurrency, + BidValue = dbDeal.BidValue, + DealMilestoneID = dbDeal.DealMilestoneId, + ExpectedCloseDate = dbDeal.ExpectedCloseDate, + PerPeriodValue = dbDeal.PerPeriodValue, + DealMilestoneProbability = dbDeal.DealMilestoneProbability, + CreateOn = dbDeal.CreateOn, + CreateBy = dbDeal.CreateBy, + ActualCloseDate = Convert.ToDateTime(row[14]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[14])) + }; + + return new Deal + { + ID = Convert.ToInt32(row[0]), + Title = Convert.ToString(row[1]), + Description = Convert.ToString(row[2]), + ResponsibleID = ToGuid(row[3]), + ContactID = Convert.ToInt32(row[4]), + BidCurrency = Convert.ToString(row[5]), + BidValue = Convert.ToDecimal(row[6]), + BidType = (BidType)Convert.ToInt32(row[7]), + DealMilestoneID = Convert.ToInt32(row[8]), + ExpectedCloseDate = Convert.ToDateTime(row[9]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[9])), + PerPeriodValue = Convert.ToInt32(row[10]), + DealMilestoneProbability = Convert.ToInt32(row[11]), + CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[12])), + CreateBy = ToGuid(row[13]), + ActualCloseDate = + Convert.ToDateTime(row[14]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[14])) + }; } private SqlQuery GetDealSqlQuery(Exp where) @@ -834,8 +867,6 @@ then tblDeal.expected_close_date return sqlQuery; } - #endregion - public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) { @@ -844,7 +875,7 @@ public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) 0, null, 0, - DealMilestoneStatus.Open, + DealMilestoneStatus.Open, null, DateTime.MinValue, DateTime.MinValue, @@ -869,9 +900,6 @@ public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) } } - #endregion - - /// /// Test method /// @@ -894,13 +922,13 @@ public void SetDealCreationDate(int opportunityid, DateTime creationDate) /// public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) { - + Db.ExecuteNonQuery( Update("crm_deal") .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) .Where(Exp.Eq("id", opportunityid))); - + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 1850c69e23b..5e79cbf7677 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -46,10 +46,16 @@ public class CachedDealMilestoneDao : DealMilestoneDao private readonly HttpRequestDictionary _dealMilestoneCache = new HttpRequestDictionary("crm_deal_milestone"); - public CachedDealMilestoneDao(int tenantID) - : base(tenantID) + public CachedDealMilestoneDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { + + } private void ResetCache(int id) @@ -102,8 +108,6 @@ public override void Reorder(int[] ids) public class DealMilestoneDao : AbstractDao { - #region Constructor - public DealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext) : @@ -117,30 +121,22 @@ public DealMilestoneDao(DbContextManager dbContextManager, } - - #endregion - public virtual void Reorder(int[] ids) { using var tx = CRMDbContext.Database.BeginTransaction(); for (int index = 0; index < ids.Length; index++) { - Query(CRMDbContext.DealMilestones) - } - + var itemToUpdate = Query(CRMDbContext.DealMilestones).FirstOrDefault(x => x.Id == ids[index]); - tx.Commit(); + itemToUpdate.SortOrder = index; + CRMDbContext.Update(itemToUpdate); + } - throw new NotImplementedException(); - - // .Where(x => ids.Contains(x.Id)); - - Db.ExecuteNonQuery(Update("crm_deal_milestone") - .Set("sort_order", index) - .Where(Exp.Eq("id", ids[index]))); - + CRMDbContext.SaveChanges(); + + tx.Commit(); } public int GetCount() @@ -151,17 +147,30 @@ public int GetCount() public Dictionary GetRelativeItemsCount() { - var sqlQuery = Query("crm_deal_milestone tbl_deal_milestone") - .Select("tbl_deal_milestone.id") - .OrderBy("tbl_deal_milestone.sort_order", true) - .GroupBy("tbl_deal_milestone.id"); - - sqlQuery.LeftOuterJoin("crm_deal tbl_crm_deal", - Exp.EqColumns("tbl_deal_milestone.id", "tbl_crm_deal.deal_milestone_id")) - .Select("count(tbl_crm_deal.deal_milestone_id)"); - - var queryResult = Db.ExecuteList(sqlQuery); - return queryResult.ToDictionary(x => Convert.ToInt32(x[0]), y => Convert.ToInt32(y[1])); + var sqlQuery = Query(CRMDbContext.DealMilestones) + .GroupJoin(CRMDbContext.Deals, + x => x.Id, + x => x.DealMilestoneId, + (x,y) => + { + + }); + + + + throw new Exception(); + + //var sqlQuery = Query("crm_deal_milestone tbl_deal_milestone") + // .Select("tbl_deal_milestone.id") + // .OrderBy("tbl_deal_milestone.sort_order", true) + // .GroupBy("tbl_deal_milestone.id"); + + //sqlQuery.LeftOuterJoin("crm_deal tbl_crm_deal", + // Exp.EqColumns("tbl_deal_milestone.id", "tbl_crm_deal.deal_milestone_id")) + // .Select("count(tbl_crm_deal.deal_milestone_id)"); + + //var queryResult = Db.ExecuteList(sqlQuery); + //return queryResult.ToDictionary(x => Convert.ToInt32(x[0]), y => Convert.ToInt32(y[1])); } public int GetRelativeItemsCount(int id) @@ -178,30 +187,32 @@ public virtual int Create(DealMilestone item) int id; - using (var tx = Db.BeginTransaction()) + using var tx = CRMDbContext.Database.BeginTransaction(); + + if (item.SortOrder == 0) + item.SortOrder = Query(CRMDbContext.DealMilestones).Select(x => x.SortOrder).Max() + 1; + + var itemToAdd = new DbDealMilestone { - if (item.SortOrder == 0) - item.SortOrder = Db.ExecuteScalar(Query("crm_deal_milestone") - .SelectMax("sort_order")) + 1; - - id = Db.ExecuteScalar( - Insert("crm_deal_milestone") - .InColumnValue("id", 0) - .InColumnValue("title", item.Title) - .InColumnValue("description", item.Description) - .InColumnValue("color", item.Color) - .InColumnValue("probability", item.Probability) - .InColumnValue("status", (int)item.Status) - .InColumnValue("sort_order", item.SortOrder) - .Identity(1, 0, true)); - tx.Commit(); - } + Title = item.Title, + Description = item.Description, + Color = item.Color, + Probability = item.Probability, + Status = item.Status, + SortOrder = item.SortOrder, + TenantId = TenantID + }; + + CRMDbContext.DealMilestones.Add(itemToAdd); + CRMDbContext.SaveChanges(); + + id = itemToAdd.Id; + tx.Commit(); + return id; - } - public virtual void ChangeColor(int id, String newColor) { var item = CRMDbContext.DealMilestones.First(x => x.Id == id); @@ -215,20 +226,19 @@ public virtual void Edit(DealMilestone item) { if (HaveContactLink(item.ID)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.DealMilestoneHasRelatedDeals)); + + var itemToUpdate = Query(CRMDbContext.DealMilestones) + .FirstOrDefault(x => x.Id == item.ID); - Query(CRMDbContext.DealMilestones) - .First(x => x.Id == item.ID); - - - //CRMDbContext.DealMilestones.Update(); + itemToUpdate.Title = item.Title; + itemToUpdate.Description = item.Description; + itemToUpdate.Color = item.Color; + itemToUpdate.Probability = item.Probability; + itemToUpdate.Status = item.Status; - //Db.ExecuteNonQuery(Update("crm_deal_milestone") - // .Set("title", item.Title) - // .Set("description", item.Description) - // .Set("color", item.Color) - // .Set("probability", item.Probability) - // .Set("status", (int)item.Status) - // .Where(Exp.Eq("id", item.ID))); + CRMDbContext.DealMilestones.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); } public bool HaveContactLink(int dealMilestoneID) @@ -252,13 +262,7 @@ public virtual void Delete(int id) public virtual DealMilestone GetByID(int id) { - - //var dealMilestones = Db.ExecuteList(GetDealMilestoneQuery(Exp.Eq("id", id))).ConvertAll(row => ToDealMilestone(row)); - - //if (dealMilestones.Count == 0) - // return null; - - //return dealMilestones[0]; + return ToDealMilestone(Query(CRMDbContext.DealMilestones).FirstOrDefault(x => x.Id == id)); } public Boolean IsExist(int id) @@ -268,19 +272,15 @@ public Boolean IsExist(int id) public List GetAll(int[] id) { - - - - - - // return Db.ExecuteList(GetDealMilestoneQuery(Exp.In("id", id))).ConvertAll(row => ToDealMilestone(row)); + return Query(CRMDbContext.DealMilestones) + .Where(x => id.Contains(x.Id)).ToList().ConvertAll(ToDealMilestone); } public List GetAll() { - - -// return Db.ExecuteList(GetDealMilestoneQuery(null)).ConvertAll(row => ToDealMilestone(row)); + return Query(CRMDbContext.DealMilestones) + .ToList() + .ConvertAll(ToDealMilestone); } //private SqlQuery GetDealMilestoneQuery(Exp where) @@ -312,7 +312,7 @@ private static DealMilestone ToDealMilestone(DbDealMilestone dbDealMilestone) Status = dbDealMilestone.Status, Description = dbDealMilestone.Description, Probability = dbDealMilestone.Probability, - SortOrder = dbDealMilestone.SortOrder + SortOrder = dbDealMilestone.SortOrder }; } } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 7ea80f7f4e6..24069a19c7e 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -24,14 +24,7 @@ */ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; using ASC.Collections; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Tenants; @@ -42,6 +35,12 @@ using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; +using System.Text.RegularExpressions; using SecurityContext = ASC.Core.SecurityContext; namespace ASC.CRM.Core.Dao @@ -50,8 +49,14 @@ public class CachedInvoiceDao : InvoiceDao { private readonly HttpRequestDictionary _invoiceCache = new HttpRequestDictionary("crm_invoice"); - public CachedInvoiceDao(int tenantID) - : base(tenantID) + public CachedInvoiceDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + FactoryIndexer factoryIndexer) + : base(dbContextManager, + tenantManager, + securityContext, + factoryIndexer) { } @@ -97,29 +102,31 @@ public class InvoiceDao : AbstractDao new KeyValuePair(InvoiceStatus.Paid, InvoiceStatus.Sent)//Bug 23450 }; - public InvoiceDao(DbContextManager dbContextManager, + public InvoiceDao( + DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + FactoryIndexer factoryIndexer) : base(dbContextManager, tenantManager, securityContext) { - + FactoryIndexer = factoryIndexer; } + public FactoryIndexer FactoryIndexer { get; } + + public TenantUtil TenantUtil { get; } public CRMSecurity CRMSecurity { get; } public Boolean IsExist(int invoiceID) { return IsExistFromDb(invoiceID); } - - + public Boolean IsExistFromDb(int invoiceID) { - - return Db.ExecuteScalar(@"select exists(select 1 from crm_invoice where tenant_id = @tid and id = @id)", - new { tid = TenantID, id = invoiceID }); + return Query(CRMDbContext.Invoices).Where(x => x.Id == invoiceID).Any(); } public Boolean IsExist(string number) @@ -129,21 +136,24 @@ public Boolean IsExist(string number) public Boolean IsExistFromDb(string number) { - var q = new SqlQuery("crm_invoice") - .SelectCount() - .Where("tenant_id", TenantID) - .Where("number", number); - return Db.ExecuteScalar(q) > 0; + return Query(CRMDbContext.Invoices) + .Where(x => x.Number == number) + .Any(); } public virtual List GetAll() { - return Db.ExecuteList(GetInvoiceSqlQuery(null, null)).ConvertAll(ToInvoice); + return Query(CRMDbContext.Invoices) + .ToList() + .ConvertAll(ToInvoice); } public virtual List GetByID(int[] ids) { - return Db.ExecuteList(GetInvoiceSqlQuery(Exp.In("id", ids), null)).ConvertAll(ToInvoice); + return Query(CRMDbContext.Invoices) + .Where(x => ids.Contains(x.Id)) + .ToList() + .ConvertAll(ToInvoice); } public virtual Invoice GetByID(int id) @@ -153,20 +163,18 @@ public virtual Invoice GetByID(int id) public virtual Invoice GetByIDFromDb(int id) { - var invoices = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("id", id), null)).ConvertAll(ToInvoice); - return invoices.Count > 0 ? invoices[0] : null; + return ToInvoice(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == id)); } public Invoice GetByNumber(string number) { - var invoices = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("number", number), null)).ConvertAll(ToInvoice); - return invoices.Count > 0 ? invoices[0] : null; + return ToInvoice(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Number == number)); } public Invoice GetByFileId(Int32 fileID) { - var invoices = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("file_id", fileID), null)).ConvertAll(ToInvoice); - return invoices.Count > 0 ? invoices[0] : null; + return ToInvoice(Query(CRMDbContext.Invoices) + .FirstOrDefault(x => x.FileId == fileID)); } public List GetInvoices( @@ -322,7 +330,7 @@ public List GetCrudeInvoices( public int GetAllInvoicesCount() { - return Db.ExecuteScalar(Query("crm_invoice").SelectCount()); + return Query(CRMDbContext.Invoices).Count(); } @@ -360,11 +368,14 @@ public int GetInvoicesCount( if (withParams) { var whereConditional = WhereConditional(null, exceptIDs, searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); + result = whereConditional != null ? Db.ExecuteScalar(Query("crm_invoice").Where(whereConditional).SelectCount()) : 0; + } else { - var countWithoutPrivate = Db.ExecuteScalar(Query("crm_invoice").SelectCount()); + var countWithoutPrivate = Query(CRMDbContext.Invoices).Count(); + var privateCount = exceptIDs.Count; if (privateCount > countWithoutPrivate) @@ -390,8 +401,11 @@ public List GetInvoices(int[] ids) { if (ids == null || !ids.Any()) return new List(); - return Db.ExecuteList(GetInvoiceSqlQuery(Exp.In("id", ids), null)) - .ConvertAll(ToInvoice).FindAll(CRMSecurity.CanAccessTo).ToList(); + return Query(CRMDbContext.Invoices) + .Where(x => ids.Contains(x.Id)) + .ToList() + .ConvertAll(ToInvoice) + .FindAll(CRMSecurity.CanAccessTo); } public List GetEntityInvoices(EntityType entityType, int entityID) @@ -401,10 +415,12 @@ public List GetEntityInvoices(EntityType entityType, int entityID) return result; if (entityType == EntityType.Opportunity) - return Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType), null)) + { + return Query(CRMDbContext.Invoices).Where(x => x.EntityId == entityID && x.EntityType == entityType) + .ToList() .ConvertAll(ToInvoice) - .FindAll(CRMSecurity.CanAccessTo) - .ToList(); + .FindAll(CRMSecurity.CanAccessTo); + } if (entityType == EntityType.Contact || entityType == EntityType.Person || entityType == EntityType.Company) return GetContactInvoices(entityID); @@ -415,13 +431,14 @@ public List GetEntityInvoices(EntityType entityType, int entityID) public List GetContactInvoices(int contactID) { var result = new List(); + if (contactID <= 0) return result; - return Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("contact_id", contactID), null)) + return Query(CRMDbContext.Invoices).Where(x => x.ContactId == contactID) + .ToList() .ConvertAll(ToInvoice) - .FindAll(CRMSecurity.CanAccessTo) - .ToList(); + .FindAll(CRMSecurity.CanAccessTo); } public string GetNewInvoicesNumber() @@ -431,12 +448,7 @@ public string GetNewInvoicesNumber() if (!settings.Autogenerated) return string.Empty; - var query = Query("crm_invoice") - .Select("number") - .OrderBy("id", false) - .SetMaxResults(1); - - var stringNumber = Db.ExecuteScalar(query); + var stringNumber = Query(CRMDbContext.Invoices).OrderByDescending(x => x.Id).Select(x => x.Number).ToString(); if (string.IsNullOrEmpty(stringNumber) || !stringNumber.StartsWith(settings.Prefix)) return string.Concat(settings.Prefix, settings.Number); @@ -470,7 +482,7 @@ public virtual int SaveOrUpdateInvoice(Invoice invoice) var result = SaveOrUpdateInvoiceInDb(invoice); - FactoryIndexer.IndexAsync(invoice); + FactoryIndexer.IndexAsync(invoice); return result; } @@ -486,40 +498,73 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) String.IsNullOrEmpty(invoice.Terms)) throw new ArgumentException(); - - + invoice.PurchaseOrderNumber = !String.IsNullOrEmpty(invoice.PurchaseOrderNumber) ? invoice.PurchaseOrderNumber : String.Empty; if (!IsExistFromDb(invoice.ID)) { if (IsExistFromDb(invoice.Number)) throw new ArgumentException(); - - invoice.ID = Db.ExecuteScalar( - Insert("crm_invoice") - .InColumnValue("id", 0) - .InColumnValue("status", (int)invoice.Status) - .InColumnValue("number", invoice.Number) - .InColumnValue("issue_date", TenantUtil.DateTimeToUtc(invoice.IssueDate)) - .InColumnValue("template_type", invoice.TemplateType) - .InColumnValue("contact_id", invoice.ContactID) - .InColumnValue("consignee_id", invoice.ConsigneeID) - .InColumnValue("entity_type", (int)invoice.EntityType) - .InColumnValue("entity_id", invoice.EntityID) - .InColumnValue("due_date", TenantUtil.DateTimeToUtc(invoice.DueDate)) - .InColumnValue("language", invoice.Language) - .InColumnValue("currency", invoice.Currency) - .InColumnValue("exchange_rate", invoice.ExchangeRate) - .InColumnValue("purchase_order_number", invoice.PurchaseOrderNumber) - .InColumnValue("terms", invoice.Terms) - .InColumnValue("description", invoice.Description) - .InColumnValue("json_data", null) - .InColumnValue("file_id", 0) - .InColumnValue("create_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); + + + //invoice.ID = Db.ExecuteScalar( + // Insert("crm_invoice") + // .InColumnValue("id", 0) + // .InColumnValue("status", (int)invoice.Status) + // .InColumnValue("number", invoice.Number) + // .InColumnValue("issue_date", TenantUtil.DateTimeToUtc(invoice.IssueDate)) + // .InColumnValue("template_type", invoice.TemplateType) + // .InColumnValue("contact_id", invoice.ContactID) + // .InColumnValue("consignee_id", invoice.ConsigneeID) + // .InColumnValue("entity_type", (int)invoice.EntityType) + // .InColumnValue("entity_id", invoice.EntityID) + // .InColumnValue("due_date", TenantUtil.DateTimeToUtc(invoice.DueDate)) + // .InColumnValue("language", invoice.Language) + // .InColumnValue("currency", invoice.Currency) + // .InColumnValue("exchange_rate", invoice.ExchangeRate) + // .InColumnValue("purchase_order_number", invoice.PurchaseOrderNumber) + // .InColumnValue("terms", invoice.Terms) + // .InColumnValue("description", invoice.Description) + // .InColumnValue("json_data", null) + // .InColumnValue("file_id", 0) + // .InColumnValue("create_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) + // .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) + // .InColumnValue("last_modifed_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) + // .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) + // .Identity(1, 0, true)); + + var itemToInsert = new DbInvoice + { + Status = invoice.Status, + Number = invoice.Number, + IssueDate = invoice.IssueDate, + TemplateType = invoice.TemplateType, + ContactId = invoice.ContactID, + ConsigneeId = invoice.ConsigneeID, + EntityType = invoice.EntityType, + EntityId = invoice.EntityID, + DueDate = invoice.DueDate, + Language = invoice.Language, + Currency = invoice.Currency, + ExchangeRate = invoice.ExchangeRate, + PurchaseOrderNumber = invoice.PurchaseOrderNumber, + Terms = invoice.Terms, + Description = invoice.Description, + JsonData = invoice.JsonData, + FileId = invoice.FileID, + CreateOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, + CreateBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.Invoices.Add(itemToInsert); + + CRMDbContext.SaveChanges(); + + invoice.ID = itemToInsert.Id; + } else { @@ -585,6 +630,7 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) if (invoice == null) { _log.Error("Invoice not found"); + return null; } CRMSecurity.DemandAccessTo(invoice); @@ -595,15 +641,20 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) return invoice; } - Db.ExecuteNonQuery( - Update("crm_invoice") - .Set("status", (int)status) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", invoiceid))); + var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceid); + + itemToUpdate.Status = status; + itemToUpdate.LastModifedOn = DateTime.UtcNow; + itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + + CRMDbContext.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); invoice.Status = status; + return invoice; + } public virtual int UpdateInvoiceJsonData(int invoiceId, string jsonData) @@ -613,12 +664,14 @@ public virtual int UpdateInvoiceJsonData(int invoiceId, string jsonData) private int UpdateInvoiceJsonDataInDb(int invoiceId, string jsonData) { - Db.ExecuteNonQuery( - Update("crm_invoice") - .Set("json_data", jsonData) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", invoiceId))); + var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + + itemToUpdate.JsonData = jsonData; + itemToUpdate.LastModifedOn = DateTime.UtcNow; + itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + + CRMDbContext.Update(itemToUpdate); + CRMDbContext.SaveChanges(); return invoiceId; } @@ -651,12 +704,15 @@ public virtual int UpdateInvoiceFileID(int invoiceId, int fileId) private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) { - Db.ExecuteNonQuery( - Update("crm_invoice") - .Set("file_id", fileId) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", invoiceId))); + + var sqlToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + + sqlToUpdate.FileId = fileId; + sqlToUpdate.LastModifedOn = DateTime.UtcNow; + sqlToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + + CRMDbContext.Update(sqlToUpdate); + CRMDbContext.SaveChanges(); return invoiceId; } @@ -702,102 +758,80 @@ public List DeleteBatchInvoices(int[] invoiceID) private void DeleteBatchInvoicesExecute(List invoices) { - var invoiceID = invoices.Select(x => x.ID).ToArray(); - using (var tx = Db.BeginTransaction()) - { - Db.ExecuteNonQuery(Delete("crm_invoice_line").Where(Exp.In("invoice_id", invoiceID))); - Db.ExecuteNonQuery(Delete("crm_invoice").Where(Exp.In("id", invoiceID))); + using var tx = CRMDbContext.Database.BeginTransaction(); + + CRMDbContext.InvoiceLine.RemoveRange(Query(CRMDbContext.InvoiceLine).Where(x => invoiceID.Contains(x.InvoiceId))); + CRMDbContext.Invoices.RemoveRange(Query(CRMDbContext.Invoices).Where(x => invoiceID.Contains(x.Id))); - tx.Commit(); - } - invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(invoice)); + CRMDbContext.SaveChanges(); + + tx.Commit(); + + invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(invoice)); + } - private static Invoice ToInvoice(object[] row) + private Invoice ToInvoice(DbInvoice dbInvoice) { + if (dbInvoice == null) return null; + return new Invoice { - ID = Convert.ToInt32(row[0]), - Status = (InvoiceStatus)Convert.ToInt32(row[1]), - Number = Convert.ToString(row[2]), - IssueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[3].ToString())), - TemplateType = (InvoiceTemplateType)Convert.ToInt32(row[4]), - ContactID = Convert.ToInt32(row[5]), - ConsigneeID = Convert.ToInt32(row[6]), - EntityType = (EntityType)Convert.ToInt32(row[7]), - EntityID = Convert.ToInt32(row[8]), - DueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[9].ToString())), - Language = Convert.ToString(row[10]), - Currency = Convert.ToString(row[11]), - ExchangeRate = Convert.ToDecimal(row[12]), - PurchaseOrderNumber = Convert.ToString(row[13]), - Terms = Convert.ToString(row[14]), - Description = Convert.ToString(row[15]), - JsonData = Convert.ToString(row[16]), - FileID = Convert.ToInt32(row[17]), - CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[18].ToString())), - CreateBy = ToGuid(row[19]), - LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[20].ToString())), - LastModifedBy = ToGuid(row[21]) + ID = dbInvoice.Id, + Status = dbInvoice.Status, + Number = dbInvoice.Number, + IssueDate = dbInvoice.IssueDate, + TemplateType = dbInvoice.TemplateType, + ContactID = dbInvoice.ContactId, + ConsigneeID = dbInvoice.ConsigneeId, + EntityType = dbInvoice.EntityType, + EntityID = dbInvoice.EntityId, + DueDate = dbInvoice.DueDate, + Language = dbInvoice.Language, + Currency = dbInvoice.Currency, + ExchangeRate = dbInvoice.ExchangeRate, + PurchaseOrderNumber = dbInvoice.PurchaseOrderNumber, + Terms = dbInvoice.Terms, + Description = dbInvoice.Description, + JsonData = dbInvoice.JsonData, + FileID = dbInvoice.FileId, + CreateOn = dbInvoice.CreateOn, + CreateBy = dbInvoice.CreateBy, + LastModifedOn = dbInvoice.LastModifedOn, + LastModifedBy = dbInvoice.LastModifedBy }; - } - - private SqlQuery GetInvoiceSqlQuery(Exp where, String alias) - { - var q = Query("crm_invoice"); - if (!string.IsNullOrEmpty(alias)) - { - q = new SqlQuery("crm_invoice " + alias) - .Where(alias + ".tenant_id", TenantID); - q.Select(GetInvoiceColumnsTable(alias)); - } - else - { - q.Select(GetInvoiceColumnsTable(String.Empty)); - } - - if (where != null) - q.Where(where); - - return q; - } - - private String[] GetInvoiceColumnsTable(String alias) - { - var result = new string[] - { - "id", - "status", - "number", - "issue_date", - "template_type", - "contact_id", - "consignee_id", - "entity_type", - "entity_id", - "due_date", - "language", - "currency", - "exchange_rate", - "purchase_order_number", - "terms", - "description", - "json_data", - "file_id", - "create_on", - "create_by", - "last_modifed_on", - "last_modifed_by" - }; - - return string.IsNullOrEmpty(alias) ? result : result.Select(c => alias + "." + c).ToArray(); - } - - private Exp WhereConditional(String tblAlias, + //return new Invoice + //{ + // ID = Convert.ToInt32(row[0]), + // Status = (InvoiceStatus)Convert.ToInt32(row[1]), + // Number = Convert.ToString(row[2]), + // IssueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[3].ToString())), + // TemplateType = (InvoiceTemplateType)Convert.ToInt32(row[4]), + // ContactID = Convert.ToInt32(row[5]), + // ConsigneeID = Convert.ToInt32(row[6]), + // EntityType = (EntityType)Convert.ToInt32(row[7]), + // EntityID = Convert.ToInt32(row[8]), + // DueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[9].ToString())), + // Language = Convert.ToString(row[10]), + // Currency = Convert.ToString(row[11]), + // ExchangeRate = Convert.ToDecimal(row[12]), + // PurchaseOrderNumber = Convert.ToString(row[13]), + // Terms = Convert.ToString(row[14]), + // Description = Convert.ToString(row[15]), + // JsonData = Convert.ToString(row[16]), + // FileID = Convert.ToInt32(row[17]), + // CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[18].ToString())), + // CreateBy = ToGuid(row[19]), + // LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[20].ToString())), + // LastModifedBy = ToGuid(row[21]) + //}; + } + + private Expression WhereConditional( ICollection exceptIDs, String searchText, InvoiceStatus? status, @@ -808,11 +842,11 @@ private Exp WhereConditional(String tblAlias, EntityType entityType, int entityID, String currency) - { - var tblAliasPrefix = !String.IsNullOrEmpty(tblAlias) ? tblAlias + "." : ""; - var conditions = new List(); + { + var conditions = new List(); - if (entityID > 0) + if (entityID > 0) { + switch (entityType) { case EntityType.Contact: @@ -827,6 +861,8 @@ private Exp WhereConditional(String tblAlias, break; } + } + if (status != null) { conditions.Add(Exp.Eq(tblAliasPrefix + "status", (int)status.Value)); @@ -843,7 +879,7 @@ private Exp WhereConditional(String tblAlias, if (keywords.Length > 0) { List invoicesIds; - if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out invoicesIds)) + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out invoicesIds)) { conditions.Add(BuildLike(new[] {tblAliasPrefix + "number", tblAliasPrefix + "description"}, keywords)); } @@ -900,21 +936,21 @@ private bool hasParams( dueDateFrom == DateTime.MinValue && dueDateTo == DateTime.MinValue && entityID == 0 && String.IsNullOrEmpty(currency)); } - - #endregion - - + /// /// Test method /// /// /// public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) - { - Db.ExecuteNonQuery( - Update("crm_invoice") - .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) - .Where(Exp.Eq("id", invoiceId))); + { + var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + + itemToUpdate.CreateOn = TenantUtil.DateTimeToUtc(creationDate); + + CRMDbContext.Invoices.Update(itemToUpdate); + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); } @@ -925,11 +961,15 @@ public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) /// /// public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) - { - Db.ExecuteNonQuery( - Update("crm_invoice") - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) - .Where(Exp.Eq("id", invoiceId))); + { + var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + + itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate); + + CRMDbContext.Invoices.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 36da62eb929..5b574fa7560 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -41,8 +41,14 @@ public class CachedInvoiceTaxDao : InvoiceTaxDao { private readonly HttpRequestDictionary _invoiceTaxCache = new HttpRequestDictionary("crm_invoice_tax"); - public CachedInvoiceTaxDao(int tenantID) - : base(tenantID) + public CachedInvoiceTaxDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext + ) + : base(dbContextManager, + tenantManager, + securityContext) + { } diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs deleted file mode 100644 index 20dd03ba0eb..00000000000 --- a/products/ASC.CRM/Server/Core/Dao/ListItemHistoryDao.cs +++ /dev/null @@ -1,239 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -#region Import - -using System; -using System.Collections.Generic; -using System.Globalization; -using ASC.Collections; -using ASC.Core; -using ASC.Core.Tenants; -using ASC.Web.CRM.Classes; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; - - -#endregion - -namespace ASC.CRM.Core.Dao -{ - - public class CachedListItemHistory : ListItemHistoryDao - { - - #region Members - - private readonly HttpRequestDictionary _listItemHistoryCache = new HttpRequestDictionary("crm_list_item_history"); - - #endregion - - #region Constructor - - public CachedListItemHistory(int tenantId, DaoFactory factory) - : base(tenantId, factory) - { - - } - - #endregion - - #region Members - - public override ListItemHistory GetByID(int id) - { - return _listItemHistoryCache.Get(id.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(id)); - } - - private ListItemHistory GetByIDBase(int id) - { - return base.GetByID(id); - } - - private void ResetCache(int id) - { - _listItemHistoryCache.Reset(id.ToString(CultureInfo.InvariantCulture)); - } - - #endregion - - - } - - public class ListItemHistoryDao : AbstractDao - { - #region Constructor - - private DaoFactory DaoFactory { get; set; } - - public ListItemHistoryDao(int tenantId, DaoFactory daoFactory) - : base(tenantId) - { - DaoFactory = daoFactory; - } - - #endregion - - public List GetItems(EntityType entityType, int statusID, DateTime? startDate, DateTime? endDate) - { - var sqlQuery = GetListItemSqlQuery(Exp.Eq("entity_type", (int)entityType) & Exp.Eq("status", statusID)); - - if (startDate.HasValue) - sqlQuery.Where(Exp.Gt("modifed_on", startDate)); - - if (endDate.HasValue) - sqlQuery.Where(Exp.Lt("modifed_on", endDate)); - - return Db.ExecuteList(sqlQuery.OrderBy("entity_id", true)) - .ConvertAll(ToListItemHistory); - } - - public int GetItemsCount(EntityType entityType, int statusID, DateTime? startDate, DateTime? endDate) - { - var sqlQuery = Query("crm_item_history") - .SelectCount() - .Where(Exp.Eq("entity_type", (int) entityType) & Exp.Eq("status", statusID)); - - if (startDate.HasValue) - sqlQuery.Where(Exp.Gt("modifed_on", startDate)); - - if (endDate.HasValue) - sqlQuery.Where(Exp.Lt("modifed_on", endDate)); - - return Db.ExecuteScalar(sqlQuery); - } - - public virtual ListItemHistory GetByID(int id) - { - var sqlQuery = GetListItemSqlQuery(Exp.Eq("id", id)); - - var result = Db.ExecuteList(sqlQuery).ConvertAll(ToListItemHistory); - - return result.Count > 0 ? result[0] : null; - } - - public virtual List GetAll(EntityType entityType) - { - var sqlQuery = GetListItemSqlQuery(Exp.Eq("entity_type", (int) entityType)) - .OrderBy("entity_id", true); - - return Db.ExecuteList(sqlQuery).ConvertAll(ToListItemHistory); - } - - public virtual int CreateItem(ListItemHistory item) - { - if (item.EntityType != EntityType.Opportunity || item.EntityType != EntityType.Contact) - throw new ArgumentException(); - - if (item.EntityType == EntityType.Opportunity && - (DaoFactory.DealDao.GetByID(item.EntityID) == null || - DaoFactory.DealMilestoneDao.GetByID(item.StatusID) == null)) - throw new ArgumentException(); - - if (item.EntityType == EntityType.Contact && - (DaoFactory.ContactDao.GetByID(item.EntityID) == null || - DaoFactory.ListItemDao.GetByID(item.StatusID) == null)) - throw new ArgumentException(); - - var sqlQuery = Insert("crm_item_history") - .InColumnValue("id", 0) - .InColumnValue("entity_id", item.EntityID) - .InColumnValue("entity_type", (int) item.EntityType) - .InColumnValue("status", item.StatusID) - .InColumnValue("modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .InColumnValue("modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true); - - return Db.ExecuteScalar(sqlQuery); - } - - public virtual void DeleteItem(EntityType entityType, int statusID) - { - if (HaveRelativeItems(entityType, statusID)) - throw new ArgumentException(); - - var sqlQuery = Delete("crm_item_history") - .Where(Exp.Eq("entity_type", (int) entityType) & Exp.Eq("status", statusID)); - - Db.ExecuteNonQuery(sqlQuery); - } - - private bool HaveRelativeItems(EntityType entityType, int statusID) - { - SqlQuery sqlQuery; - - switch (entityType) - { - case EntityType.Contact: - sqlQuery = Query("crm_contact") - .Where(Exp.Eq("status_id", statusID)); - break; - case EntityType.Opportunity: - sqlQuery = Query("crm_deal") - .Where(Exp.Eq("deal_milestone_id", statusID)); - break; - default: - throw new ArgumentException(); - } - - return Db.ExecuteScalar(sqlQuery.SelectCount()) > 0; - } - - private SqlQuery GetListItemSqlQuery(Exp where) - { - var result = Query("crm_list_item_history") - .Select( - "id", - "entity_id", - "entity_type", - "status", - "modifed_on", - "modifed_by" - ); - - if (where != null) - result.Where(where); - - return result; - - } - - public static ListItemHistory ToListItemHistory(object[] row) - { - return new ListItemHistory - { - ID = Convert.ToInt32(row[0]), - EntityID = Convert.ToInt32(row[1]), - EntityType = (EntityType)Convert.ToInt32(row[2]), - StatusID = Convert.ToInt32(row[3]), - ModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[4].ToString())), - ModifedBy = ToGuid(row[5]), - }; - } - } -} diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index a0c57eef6b9..99b4111b5cc 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -34,8 +34,6 @@ using System.Runtime.Serialization.Json; using ASC.Collections; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; using ASC.Core.Tenants; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -53,31 +51,24 @@ using OrderBy = ASC.CRM.Core.Entities.OrderBy; using File = ASC.Files.Core.File; using ASC.CRM.Core.Enums; +using ASC.Core.Common.EF; +using ASC.CRM.Core.EF; +using ASC.Core; +using ASC.CRM.Classes; namespace ASC.CRM.Core.Dao { public class CachedRelationshipEventDao : RelationshipEventDao { - #region Import - private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_relationshipEvent"); - #endregion - - #region Constructor - public CachedRelationshipEventDao(int tenantID) : base(tenantID) { } - - #endregion - - #region Methods - public override RelationshipEvent GetByID(int eventID) { return _contactCache.Get(eventID.ToString(), () => GetByIDBase(eventID)); @@ -93,29 +84,39 @@ private void ResetCache(int dealID) { _contactCache.Reset(dealID.ToString()); } - - #endregion - } public class RelationshipEventDao : AbstractDao { - #region Members + public RelationshipEventDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + FilesIntegration filesIntegration, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + SetupInfo setupInfo + ) : + base(dbContextManager, + tenantManager, + securityContext) + { + FilesIntegration = filesIntegration; + TenantUtil = tenantUtil; + CRMSecurity = cRMSecurity; + SetupInfo = setupInfo; + } - #endregion - #region Constructor + public SetupInfo SetupInfo { get; } - public RelationshipEventDao(int tenantID) - : base(tenantID) - { + public CRMSecurity CRMSecurity { get; } - } + public TenantUtil TenantUtil { get; } - #endregion + public FilesIntegration FilesIntegration { get; } - #region Methods + public FactoryIndexer FactoryIndexer { get; } public RelationshipEvent AttachFiles(int contactID, EntityType entityType, int entityID, int[] fileIDs) { @@ -143,12 +144,11 @@ public void AttachFiles(int eventID, int[] fileIDs) { if (fileIDs.Length == 0) return; - using (var dao = FilesIntegration.GetTagDao()) - { - var tags = fileIDs.ToList().ConvertAll(fileID => new Tag("RelationshipEvent_" + eventID, TagType.System, Guid.Empty) { EntryType = FileEntryType.File, EntryId = fileID }); + var dao = FilesIntegration.GetTagDao(); - dao.SaveTags(tags); - } + var tags = fileIDs.ToList().ConvertAll(fileID => new Tag("RelationshipEvent_" + eventID, TagType.System, Guid.Empty) { EntryType = FileEntryType.File, EntryId = fileID }); + + dao.SaveTags(tags); if (fileIDs.Length > 0) Db.ExecuteNonQuery(Update("crm_relationship_event").Set("have_files", true).Where("id", eventID)); @@ -163,8 +163,7 @@ private object[] GetFilesIDs(int[] contactID, EntityType entityType, int entityI { if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) throw new ArgumentException(); - - + var sqlQuery = Query("crm_relationship_event").Select("id"); if (contactID != null && contactID.Length > 0) @@ -176,23 +175,24 @@ private object[] GetFilesIDs(int[] contactID, EntityType entityType, int entityI sqlQuery.Where(Exp.Eq("have_files", true)); var tagNames = Db.ExecuteList(sqlQuery).ConvertAll(row => String.Format("RelationshipEvent_{0}", row[0])); - using (var tagdao = FilesIntegration.GetTagDao()) - { - return tagdao.GetTags(tagNames.ToArray(), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); - } + var tagdao = FilesIntegration.GetTagDao(); + + return tagdao.GetTags(tagNames.ToArray(), TagType.System) + .Where(t => t.EntryType == FileEntryType.File) + .Select(t => t.EntryId).ToArray(); + } public List GetAllFiles(int[] contactID, EntityType entityType, int entityID) { - using (var filedao = FilesIntegration.GetFileDao()) - { - var ids = GetFilesIDs(contactID, entityType, entityID); - var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); + var filedao = FilesIntegration.GetFileDao(); - files.ForEach(CRMSecurity.SetAccessTo); + var ids = GetFilesIDs(contactID, entityType, entityID); + var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); - return files.ToList(); - } + files.ForEach(CRMSecurity.SetAccessTo); + + return files.ToList(); } public Dictionary> GetFiles(int[] eventID) @@ -201,33 +201,26 @@ public Dictionary> GetFiles(int[] eventID) if (eventID == null || eventID.Length == 0) throw new ArgumentException("eventID"); - using (var tagdao = FilesIntegration.GetTagDao()) - using (var filedao = FilesIntegration.GetFileDao()) - { - + var tagdao = FilesIntegration.GetTagDao(); + var filedao = FilesIntegration.GetFileDao(); - var findedTags = tagdao.GetTags(eventID.Select(item => String.Concat("RelationshipEvent_", item)).ToArray(), - TagType.System).Where(t => t.EntryType == FileEntryType.File); + var findedTags = tagdao.GetTags(eventID.Select(item => String.Concat("RelationshipEvent_", item)).ToArray(), + TagType.System).Where(t => t.EntryType == FileEntryType.File); - var filesID = findedTags.Select(t => t.EntryId).ToArray(); + var filesID = findedTags.Select(t => t.EntryId).ToArray(); - var files = 0 < filesID.Length ? filedao.GetFiles(filesID) : new List(); + var files = 0 < filesID.Length ? filedao.GetFiles(filesID) : new List(); - var filesTemp = new Dictionary(); + var filesTemp = new Dictionary(); - files.ForEach(item => - { - if (!filesTemp.ContainsKey(item.ID)) - filesTemp.Add(item.ID, item); - }); - - return findedTags.Where(x => filesTemp.ContainsKey(x.EntryId)).GroupBy(x => x.TagName).ToDictionary(x => Convert.ToInt32(x.Key.Split(new[] { '_' })[1]), - x => x.Select(item => filesTemp[item.EntryId]).ToList()); - - - - } + files.ForEach(item => + { + if (!filesTemp.ContainsKey(item.ID)) + filesTemp.Add(item.ID, item); + }); + return findedTags.Where(x => filesTemp.ContainsKey(x.EntryId)).GroupBy(x => x.TagName).ToDictionary(x => Convert.ToInt32(x.Key.Split(new[] { '_' })[1]), + x => x.Select(item => filesTemp[item.EntryId]).ToList()); } public List GetFiles(int eventID) @@ -235,34 +228,34 @@ public List GetFiles(int eventID) if (eventID == 0) throw new ArgumentException("eventID"); - using (var tagdao = FilesIntegration.GetTagDao()) - using (var filedao = FilesIntegration.GetFileDao()) - { - var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); - var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); + var tagdao = FilesIntegration.GetTagDao(); + var filedao = FilesIntegration.GetFileDao(); - files.ForEach(CRMSecurity.SetAccessTo); + var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); + + files.ForEach(CRMSecurity.SetAccessTo); + + return files.ToList(); - return files.ToList(); - } } private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID) { - if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) { throw new ArgumentException(); } - + var files = GetAllFiles(contactID, entityType, entityID); - using (var dao = FilesIntegration.GetFileDao()) + + var dao = FilesIntegration.GetFileDao(); + + foreach (var file in files) { - foreach (var file in files) - { - dao.DeleteFile(file.ID); - } + dao.DeleteFile(file.ID); } + } public List RemoveFile(File file) @@ -271,25 +264,38 @@ public List RemoveFile(File file) List eventIDs; - using (var tagdao = FilesIntegration.GetTagDao()) - { - var tags = tagdao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); - eventIDs = tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); - } - using (var dao = FilesIntegration.GetFileDao()) - { - dao.DeleteFile(file.ID); - } + var tagdao = FilesIntegration.GetTagDao(); + + var tags = tagdao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); + + eventIDs = tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); + + var dao = FilesIntegration.GetFileDao(); + + dao.DeleteFile(file.ID); foreach (var eventID in eventIDs) { if (GetFiles(eventID).Count == 0) { - Db.ExecuteNonQuery(Update("crm_relationship_event").Set("have_files", false).Where("id", eventID)); + + CRMDbContext.Attach(); + + // context.Attach(person); + // context.Entry(person).Property("Name").IsModified = true; + // Db.ExecuteNonQuery(Update("crm_relationship_event").Set("have_files", false).Where("id", eventID)); + + CRMDbContext.SaveChanges(); } } - Db.ExecuteNonQuery(Update("crm_invoice").Set("file_id", 0).Where("file_id", file.ID)); + var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.FileId == Convert.ToInt32(file.ID)); + + itemToUpdate.FileId = 0; + + CRMDbContext.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); return eventIDs; } @@ -344,9 +350,9 @@ public RelationshipEvent CreateItem(RelationshipEvent item) using (var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(htmlBody))) { - var filePath = String.Format("folder_{0}/message_{1}.html", (messageId/1000 + 1)*1000, messageId); + var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); - Global.GetStore().Save("mail_messages",filePath,fileStream); + Global.GetStore().Save("mail_messages", filePath, fileStream); messageUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=mailmessage&message_id={1}", PathProvider.BaseAbsolutePath, messageId).ToLower(); @@ -355,20 +361,20 @@ public RelationshipEvent CreateItem(RelationshipEvent item) var msg_date_created = msgRequestObj.Value("date"); var message_id = msgRequestObj.Value("id"); item.Content = JsonConvert.SerializeObject(new - { - @from = msgRequestObj.Value("from"), - to = msgRequestObj.Value("to"), - cc = msgRequestObj.Value("cc"), - bcc = msgRequestObj.Value("bcc"), - subject = msgRequestObj.Value("subject"), - important = msgRequestObj.Value("important"), - chain_id = msgRequestObj.Value("chainId"), - is_sended = msgRequestObj.Value("folder") != 1, - date_created = msg_date_created, - introduction = msgRequestObj.Value("introduction"), - message_id = message_id, - message_url = messageUrl - }); + { + @from = msgRequestObj.Value("from"), + to = msgRequestObj.Value("to"), + cc = msgRequestObj.Value("cc"), + bcc = msgRequestObj.Value("bcc"), + subject = msgRequestObj.Value("subject"), + important = msgRequestObj.Value("important"), + chain_id = msgRequestObj.Value("chainId"), + is_sended = msgRequestObj.Value("folder") != 1, + date_created = msg_date_created, + introduction = msgRequestObj.Value("introduction"), + message_id = message_id, + message_url = messageUrl + }); item.CreateOn = DateTime.Parse(msg_date_created, CultureInfo.InvariantCulture); @@ -402,19 +408,22 @@ public RelationshipEvent CreateItem(RelationshipEvent item) if (item.CreateOn.Kind == DateTimeKind.Utc) item.CreateOn = TenantUtil.DateTimeFromUtc(item.CreateOn); - FactoryIndexer.IndexAsync(item); + FactoryIndexer.IndexAsync(item); return item; } public virtual RelationshipEvent GetByID(int eventID) { - return Db.ExecuteList(GetRelationshipEventQuery(Exp.Eq("id", eventID))) - .ConvertAll(ToRelationshipEvent).FirstOrDefault(); + + + + return Db.ExecuteList(GetRelationshipEventQuery(Exp.Eq("id", eventID))) + .ConvertAll(ToRelationshipEvent).FirstOrDefault(); } public int GetAllItemsCount() { - return Db.ExecuteScalar(Query("crm_relationship_event").SelectCount()); + return Query(CRMDbContext.RelationshipEvent).Count(); } public List GetAllItems() @@ -499,7 +508,7 @@ public List GetItems( .ToArray(); List eventsIds; - if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out eventsIds)) + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out eventsIds)) { if (keywords.Length > 0) sqlQuery.Where(BuildLike(new[] { "content" }, keywords)); @@ -542,20 +551,20 @@ public List GetItems( } - private static RelationshipEvent ToRelationshipEvent(object[] row) + private RelationshipEvent ToRelationshipEvent(object[] row) { return new RelationshipEvent - { - - ID = Convert.ToInt32(row[0]), - ContactID = Convert.ToInt32(row[1]), - Content = Convert.ToString(row[2]), - EntityID = Convert.ToInt32(row[3]), - EntityType = (EntityType)Convert.ToInt32(row[4]), - CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[5])), - CreateBy = ToGuid(row[6]), - CategoryID = Convert.ToInt32(row[7]) - }; + { + + ID = Convert.ToInt32(row[0]), + ContactID = Convert.ToInt32(row[1]), + Content = Convert.ToString(row[2]), + EntityID = Convert.ToInt32(row[3]), + EntityType = (EntityType)Convert.ToInt32(row[4]), + CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[5])), + CreateBy = ToGuid(row[6]), + CategoryID = Convert.ToInt32(row[7]) + }; } private SqlQuery GetRelationshipEventQuery(Exp where) @@ -581,7 +590,7 @@ public void DeleteItem(int id) { var item = GetByID(id); if (item == null) throw new ArgumentException(); - + DeleteItem(item); } @@ -597,13 +606,15 @@ public void DeleteItem(RelationshipEvent item) throw new ArgumentException(); relativeFiles.ForEach(f => RemoveFile(f)); + + + Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.Eq("id", item.ID))); - FactoryIndexer.DeleteAsync(item); - } - #endregion + FactoryIndexer.DeleteAsync(item); + } [DataContract] internal class CrmHistoryContent @@ -635,19 +646,19 @@ internal class CrmHistoryContent private static string GetHistoryContentJson(JObject apiResponse) { var content_struct = new CrmHistoryContent - { - @from = apiResponse.Value("from"), - to = apiResponse.Value("to"), - cc = apiResponse.Value("cc"), - bcc = apiResponse.Value("bcc"), - subject = apiResponse.Value("subject"), - important = apiResponse.Value("important"), - chain_id = apiResponse.Value("chainId"), - is_sended = apiResponse.Value("folder") == 1, - date_created = apiResponse.Value("date"), - introduction = apiResponse.Value("introduction"), - message_id = apiResponse.Value("id") - }; + { + @from = apiResponse.Value("from"), + to = apiResponse.Value("to"), + cc = apiResponse.Value("cc"), + bcc = apiResponse.Value("bcc"), + subject = apiResponse.Value("subject"), + important = apiResponse.Value("important"), + chain_id = apiResponse.Value("chainId"), + is_sended = apiResponse.Value("folder") == 1, + date_created = apiResponse.Value("date"), + introduction = apiResponse.Value("introduction"), + message_id = apiResponse.Value("id") + }; var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent)); using (var stream = new MemoryStream()) diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index eb2a7523a94..08bac4f594f 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -96,6 +96,8 @@ public String GetTagsLinkCountJSON(EntityType entityType) public IEnumerable GetTagsLinkCount(EntityType entityType) { + + //var temp = Query(CRMDbContext.Tags) // .Join(CRMDbContext.CrmEntityTag, // x => x.Id, diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index e90f706a08c..7098d21b34d 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -46,13 +46,25 @@ public class CachedTaskDao : TaskDao { private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_task"); - - public CachedTaskDao(int tenantID) - : base(tenantID) + + public CachedTaskDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + FactoryIndexer factoryIndexer + ): + base(dbContextManager, + tenantManager, + securityContext, + cRMSecurity, + tenantUtil, + factoryIndexer) { - + } + public override Task GetByID(int taskID) { return _contactCache.Get(taskID.ToString(), () => GetByIDBase(taskID)); @@ -110,6 +122,7 @@ FactoryIndexer factoryIndexer public FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } + public CRMSecurity CRMSecurity { get; } public void OpenTask(int taskId) @@ -130,7 +143,6 @@ public void OpenTask(int taskId) CRMDbContext.Tasks.Update(entity); CRMDbContext.SaveChanges(); - } public void CloseTask(int taskId) @@ -174,13 +186,12 @@ public int GetAllTasksCount() public List GetAllTasks() { - - - return Db.ExecuteList( - GetTaskQuery(null) - .OrderBy("deadline", true) - .OrderBy("title", true)) - .ConvertAll(row => ToTask(row)).FindAll(CRMSecurity.CanAccessTo); + return Query(CRMDbContext.Tasks) + .OrderBy(x => x.Deadline) + .OrderBy(x => x.Title) + .ToList() + .ConvertAll(ToTask) + .FindAll(CRMSecurity.CanAccessTo); } public void ExecAlert(IEnumerable ids) @@ -679,50 +690,50 @@ private SqlQuery WhereConditional( public Dictionary GetNearestTask(int[] contactID) { - var sqlSubQuery = - Query("crm_task") - .SelectMin("id") - .SelectMin("deadline") - .Select("contact_id") - .Where(Exp.In("contact_id", contactID) & Exp.Eq("is_closed", false)) - .GroupBy("contact_id"); - - var taskIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => row[0]); - - if (taskIDs.Count == 0) return new Dictionary(); - var tasks = Db.ExecuteList(GetTaskQuery(Exp.In("id", taskIDs))).ConvertAll(row => ToTask(row)).Where(CRMSecurity.CanAccessTo); + + throw new Exception(); - var result = new Dictionary(); + //Query(CRMDbContext.Tasks) + // .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed) + // .GroupBy(x => x.ContactId) + // .Select(x => x.); - foreach (var task in tasks.Where(task => !result.ContainsKey(task.ContactID))) - { - result.Add(task.ContactID, task); - } - return result; - } + // var sqlSubQuery = + // Query("crm_task") + // .SelectMin("id") + // .SelectMin("deadline") + // .Select("contact_id") + // .Where(Exp.In("contact_id", contactID) & Exp.Eq("is_closed", false)) + // .GroupBy("contact_id"); - public IEnumerable GetResponsibles(int categoryID) - { + //var taskIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => row[0]); + //if (taskIDs.Count == 0) return new Dictionary(); - // CRMDbContext.Tasks.Select(x=>x.ResponsibleId) + //var tasks = Db.ExecuteList(GetTaskQuery(Exp.In("id", taskIDs))).ConvertAll(row => ToTask(row)).Where(CRMSecurity.CanAccessTo); - var q = Query("crm_task") - .Select("responsible_id") - .GroupBy(1); + //var result = new Dictionary(); - if (0 < categoryID) q.Where("category_id", categoryID); + //foreach (var task in tasks.Where(task => !result.ContainsKey(task.ContactID))) + //{ + // result.Add(task.ContactID, task); + //} - return Db.ExecuteList(q) - .ConvertAll(r => (string)r[0]) - .Select(r => new Guid(r)) - .Where(g => g != Guid.Empty) - .ToList(); + //return result; } + public IEnumerable GetResponsibles(int categoryID) + { + var sqlQuery = Query(CRMDbContext.Tasks); + if (0 < categoryID) + sqlQuery = sqlQuery.Where(x => x.CategoryId == categoryID); + + return sqlQuery.GroupBy(x => x.ResponsibleId).Select(x => x.Key).ToList(); + } + public Dictionary GetTasksCount(int[] contactID) { return CRMDbContext.Tasks @@ -742,17 +753,10 @@ public int GetTasksCount(int contactID) public Dictionary HaveLateTask(int[] contactID) { - var sqlQuery = Query("crm_task") - .Select("contact_id") - .Where(Exp.In("contact_id", contactID)) - .Where(Exp.Eq("is_closed", false) & - Exp.Lt("deadline", DateTime.UtcNow)) - .SelectCount() - .GroupBy("contact_id"); - - var sqlResult = Db.ExecuteList(sqlQuery); - - return sqlResult.ToDictionary(item => Convert.ToInt32(item[0]), item => Convert.ToInt32(item[1]) > 0); + return Query(CRMDbContext.Tasks) + .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed && x.Deadline <= DateTime.UtcNow) + .GroupBy(x => x.ContactId) + .ToDictionary(x => x.Key, x => x.Any()); } @@ -1128,7 +1132,27 @@ public void SetTaskLastModifedDate(int taskId, DateTime lastModifedDate) public Task ToTask(DbTask dbTask) { - throw new NotImplementedException(); + if (dbTask == null) return null; + + return new Task + { + ID = dbTask.Id, + AlertValue = dbTask.AlertValue, + CategoryID = dbTask.CategoryId, + ContactID = dbTask.ContactId, + CreateBy = dbTask.CreateBy, + CreateOn = dbTask.CreateOn, + DeadLine = dbTask.Deadline, + Description = dbTask.Description, + IsClosed = dbTask.IsClosed, + EntityID = dbTask.EntityId, + EntityType = dbTask.EntityType, + LastModifedBy = dbTask.LastModifedBy, + LastModifedOn = dbTask.LastModifedOn, + ResponsibleID = dbTask.ResponsibleId, + Title = dbTask.Title + }; + } } } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 986d5f68fc1..089179710af 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -287,5 +287,4 @@ protected TaskTemplate ToObject(DbTaskTemplate dbTaskTemplate) }; } } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs b/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs index 30962ac3905..6c5eadc9bcb 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs @@ -7,23 +7,28 @@ namespace ASC.CRM.Core.EF { [Table("crm_currency_info")] - public partial class DbCurrencyInfo + public partial class DbCurrencyInfo { [Required] [Column("resource_key", TypeName = "varchar(255)")] public string ResourceKey { get; set; } + [Key] [Column("abbreviation", TypeName = "varchar(255)")] public string Abbreviation { get; set; } + [Required] [Column("symbol", TypeName = "varchar(255)")] public string Symbol { get; set; } + [Required] [Column("culture_name", TypeName = "varchar(255)")] public string CultureName { get; set; } + [Column("is_convertable", TypeName = "tinyint(4)")] - public sbyte IsConvertable { get; set; } + public bool IsConvertable { get; set; } + [Column("is_basic", TypeName = "tinyint(4)")] - public sbyte IsBasic { get; set; } + public bool IsBasic { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbFieldDescription.cs b/products/ASC.CRM/Server/Core/EF/DbFieldDescription.cs index 9bed51f3ddf..31146395869 100644 --- a/products/ASC.CRM/Server/Core/EF/DbFieldDescription.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldDescription.cs @@ -1,4 +1,5 @@ // This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -7,23 +8,29 @@ namespace ASC.CRM.Core.EF { [Table("crm_field_description")] - public partial class DbFieldDescription + public partial class DbFieldDescription : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Required] [Column("label", TypeName = "varchar(255)")] public string Label { get; set; } + [Column("type", TypeName = "int(11)")] - public int Type { get; set; } + public CustomFieldType Type { get; set; } + [Column("sort_order", TypeName = "int(11)")] public int SortOrder { get; set; } + [Column("mask", TypeName = "text")] public string Mask { get; set; } + [Column("entity_type", TypeName = "int(255)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs index f630b0e1aea..4d5f0a9f588 100644 --- a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs @@ -1,28 +1,36 @@ -using System; +using ASC.CRM.Core.Enums; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_field_value")] - public partial class DbFieldValue + public partial class DbFieldValue : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Column("value", TypeName = "text")] public string Value { get; set; } + [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Column("field_id", TypeName = "int(11)")] public int FieldId { get; set; } + [Column("entity_type", TypeName = "int(10)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs index c5733d08ef6..0469625f735 100644 --- a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs @@ -1,64 +1,85 @@ -// This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_invoice")] - public partial class DbInvoice + public partial class DbInvoice : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Column("status", TypeName = "int(11)")] - public int Status { get; set; } + public InvoiceStatus Status { get; set; } + [Required] [Column("number", TypeName = "varchar(255)")] public string Number { get; set; } + [Column("issue_date", TypeName = "datetime")] public DateTime IssueDate { get; set; } + [Column("template_type", TypeName = "int(11)")] - public int TemplateType { get; set; } + public InvoiceTemplateType TemplateType { get; set; } + [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } + [Column("consignee_id", TypeName = "int(11)")] public int ConsigneeId { get; set; } + [Column("entity_type", TypeName = "int(11)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } + [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } + [Column("due_date", TypeName = "datetime")] public DateTime DueDate { get; set; } + [Required] [Column("language", TypeName = "varchar(255)")] public string Language { get; set; } + [Required] [Column("currency", TypeName = "varchar(255)")] public string Currency { get; set; } + [Column("exchange_rate", TypeName = "decimal(10,2)")] public decimal ExchangeRate { get; set; } + [Required] [Column("purchase_order_number", TypeName = "varchar(255)")] public string PurchaseOrderNumber { get; set; } + [Column("terms", TypeName = "text")] public string Terms { get; set; } + [Column("description", TypeName = "text")] public string Description { get; set; } + [Column("json_data", TypeName = "text")] public string JsonData { get; set; } + [Column("file_id", TypeName = "int(11)")] public int FileId { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index 0d60c6b3558..182c99c8882 100644 --- a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -1,38 +1,48 @@ -// This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_relationship_event")] - public partial class DbRelationshipEvent + public partial class DbRelationshipEvent : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } + [Column("content", TypeName = "text")] public string Content { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [Column("entity_type", TypeName = "int(11)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } + [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } + [Column("category_id", TypeName = "int(11)")] public int CategoryId { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("have_files", TypeName = "int(11)")] public int HaveFiles { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/DbTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs index a5aa91477cc..57972d24e87 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -6,7 +6,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_task")] - public partial class DbTask + public partial class DbTask: IDbCrm { [Key] [Column("id", TypeName = "int(11)")] From 039f88378c4082c9733b7037299a1da70bbef652 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Thu, 26 Mar 2020 21:57:06 +0300 Subject: [PATCH 04/61] crm: migrate DAO to EF Core --- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 75 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 184 +-- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 1367 +++++++++-------- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 258 ++-- .../Server/Core/Dao/CurrencyInfoDao.cs | 3 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 334 ++-- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 9 +- .../Server/Core/Dao/DealMilestoneDao.cs | 61 +- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 2 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 7 +- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 206 +-- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 83 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 10 +- products/ASC.CRM/Server/Core/EF/DbCase.cs | 2 +- products/ASC.CRM/Server/Core/EF/DbContact.cs | 34 +- .../ASC.CRM/Server/Core/EF/DbContactInfo.cs | 11 +- .../ASC.CRM/Server/Core/EF/DbEntityContact.cs | 8 +- .../Server/Core/EF/DbOrganisationLogo.cs | 2 +- products/ASC.CRM/Server/Core/EF/DbProjects.cs | 2 +- .../Server/Core/EF/DbRelationshipEvent.cs | 2 +- .../Server/Core/Security/CRMSecutiry.cs | 1 + 21 files changed, 1403 insertions(+), 1258 deletions(-) diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index 5933931fdb0..c1f741dcf05 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -95,7 +95,7 @@ SecurityContext securityContext protected int TenantID { get; private set; } - protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumerable tags) + protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumerable tags) { if (tags == null || !tags.Any()) throw new ArgumentException(); @@ -108,35 +108,16 @@ protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumer .Where(x => x.EntityType == entityType && String.Compare(x.Title, tag.Trim(), true) == 0) .Select(x => x.Id).Single()); } - - Expression> exp = null; - - if (exceptIDs != null && exceptIDs.Length > 0) - exp = x => exceptIDs.Contains(x.EntityId) && x.EntityType == entityType; - else - exp = x => x.EntityType == entityType; - - throw new NotImplementedException(); - - // exp.Update() Exp.In("tag_id", tagIDs) - // return CRMDbContext.CrmEntityTag.Where(exp).GroupBy(x => x.EntityId).Select(x=>) - // .Where(x => true).Select(x=>x); - - //var sqlQuery = new SqlQuery("crm_entity_tag") - // .Select("entity_id") - // .Select("count(*) as count") - // .GroupBy("entity_id") - // .Having(Exp.Eq("count", tags.Count())); + var sqlQuery = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && tagIDs.Contains(x.TagId)); - //if (exceptIDs != null && exceptIDs.Length > 0) - // sqlQuery.Where(Exp.In("entity_id", exceptIDs) & Exp.Eq("entity_type", (int)entityType)); - //else - // sqlQuery.Where(Exp.Eq("entity_type", (int)entityType)); - - //sqlQuery.Where(Exp.In("tag_id", tagIDs)); - - //return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToInt32(row[0])); + if (exceptIDs != null && exceptIDs.Length > 0) + sqlQuery = sqlQuery.Where(x => exceptIDs.Contains(x.EntityId)); + + return sqlQuery.GroupBy(x => x.EntityId) + .Where(x => x.Count() == tags.Count()) + .Select(x => x.Key) + .ToList(); } protected Dictionary GetRelativeToEntity(int[] contactID, EntityType entityType, int[] entityID) @@ -144,9 +125,9 @@ protected Dictionary GetRelativeToEntity(int[] contactID, EntityType Expression> exp = null; if (contactID != null && contactID.Length > 0 && (entityID == null || entityID.Length == 0)) - exp = x => x.EntityType == (int)entityType && contactID.Contains(x.ContactId); + exp = x => x.EntityType == entityType && contactID.Contains(x.ContactId); else if (entityID != null && entityID.Length > 0 && (contactID == null || contactID.Length == 0)) - exp = x => x.EntityType == (int)entityType && entityID.Contains(x.EntityId); + exp = x => x.EntityType == entityType && entityID.Contains(x.EntityId); return CRMDbContext.EntityContact.Where(exp).GroupBy(x => x.EntityId).ToDictionary( x => x.Key, @@ -162,13 +143,13 @@ protected int[] GetRelativeToEntityInDb(int? contactID, EntityType entityType, i { if (contactID.HasValue && !entityID.HasValue) return CRMDbContext.EntityContact - .Where(x => x.EntityType == (int)entityType && x.ContactId == contactID.Value) + .Where(x => x.EntityType == entityType && x.ContactId == contactID.Value) .Select(x => x.EntityId) .ToArray(); if (!contactID.HasValue && entityID.HasValue) return CRMDbContext.EntityContact - .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID.Value) + .Where(x => x.EntityType == entityType && x.EntityId == entityID.Value) .Select(x => x.ContactId) .ToArray(); @@ -183,14 +164,14 @@ protected void SetRelative(int[] contactID, EntityType entityType, int entityID) using var tx = CRMDbContext.Database.BeginTransaction(); var exists = CRMDbContext.EntityContact - .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID) + .Where(x => x.EntityType == entityType && x.EntityId == entityID) .Select(x => x.ContactId) .ToArray(); foreach (var existContact in exists) { var items = CRMDbContext.EntityContact - .Where(x => x.EntityType == (int)entityType && x.EntityId == entityID && x.ContactId == existContact); + .Where(x => x.EntityType == entityType && x.EntityId == entityID && x.ContactId == existContact); CRMDbContext.EntityContact.RemoveRange(items); } @@ -207,7 +188,7 @@ protected void SetRelative(int contactID, EntityType entityType, int entityID) CRMDbContext.EntityContact.Add(new DbEntityContact { ContactId = contactID, - EntityType = (int)entityType, + EntityType = entityType, EntityId = entityID }); @@ -225,7 +206,7 @@ protected void RemoveRelativeInDb(int[] contactID, EntityType entityType, int[] expr = x => contactID.Contains(x.ContactId); if (entityID != null && entityID.Length > 0) - expr = x => entityID.Contains(x.EntityId) && x.EntityType == (int)entityType; + expr = x => entityID.Contains(x.EntityId) && x.EntityType == entityType; var dbCrmEntity = CRMDbContext.EntityContact; @@ -268,29 +249,23 @@ public int SaveOrganisationLogo(byte[] bytes) } public string GetOrganisationLogoBase64(int logo_id) - { - + { if (logo_id <= 0) throw new ArgumentException(); - - - return CRMDbContext.OrganisationLogo + + return Query(CRMDbContext.OrganisationLogo) .Where(x => x.Id == logo_id) .Select(x => x.Content) .FirstOrDefault(); } - - #region HasCRMActivity - public bool HasActivity() { - return Db.ExecuteScalar(@"select exists(select 1 from crm_case where tenant_id = @tid) or " + - "exists(select 1 from crm_deal where tenant_id = @tid) or exists(select 1 from crm_task where tenant_id = @tid) or " + - "exists(select 1 from crm_contact where tenant_id = @tid)", new { tid = TenantID }); + return Query(CRMDbContext.Cases).Any() && + Query(CRMDbContext.Deals).Any() && + Query(CRMDbContext.Tasks).Any() && + Query(CRMDbContext.Contacts).Any(); } - #endregion - protected IQueryable Query(DbSet set) where T : class, IDbCrm { return set.Where(r => r.TenantId == TenantID); @@ -305,13 +280,11 @@ protected string GetTenantColumnName(string table) return table.Substring(table.IndexOf(" ")).Trim() + "." + tenant; } - protected static Guid ToGuid(object guid) { var str = guid as string; return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty; } - } } diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 796204ca18e..1bba88fa689 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -34,37 +34,41 @@ using ASC.Files.Core; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; +using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using OrderBy = ASC.CRM.Core.Entities.OrderBy; +using Microsoft.EntityFrameworkCore; +using SortedByType = ASC.CRM.Core.Enums.SortedByType; namespace ASC.CRM.Core.Dao { public class CachedCasesDao : CasesDao { - private readonly HttpRequestDictionary _casesCache = new HttpRequestDictionary("crm_cases"); + private readonly HttpRequestDictionary _casesCache; public CachedCasesDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, CRMSecurity cRMSecurity, TenantUtil tenantUtil, - FilesIntegration filesIntegration - ) : + FilesIntegration filesIntegration, + AuthorizationManager authorizationManager, + IHttpContextAccessor httpContextAccessor) + : base(dbContextManager, tenantManager, securityContext, cRMSecurity, tenantUtil, - filesIntegration) + filesIntegration, + authorizationManager) { - - - + _casesCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_cases"); } public override Cases GetByID(int caseID) @@ -176,7 +180,7 @@ public Cases CloseCases(int caseID) CRMSecurity.DemandAccessTo(cases); - CRMDbContext.Cases.Update(new DbCase + var itemToUpdate = new DbCase { Id = cases.ID, CreateBy = cases.CreateBy, @@ -186,7 +190,9 @@ public Cases CloseCases(int caseID) LastModifedOn = cases.LastModifedOn, TenantId = TenantID, Title = cases.Title - }); + }; + + CRMDbContext.Cases.Update(itemToUpdate); CRMDbContext.SaveChanges(); @@ -281,6 +287,7 @@ public virtual Cases DeleteCases(int casesID) if (casesID <= 0) return null; var cases = GetByID(casesID); + if (cases == null) return null; CRMSecurity.DemandDelete(cases); @@ -295,6 +302,7 @@ public virtual Cases DeleteCases(int casesID) public virtual List DeleteBatchCases(List caseses) { caseses = caseses.FindAll(CRMSecurity.CanDelete).ToList(); + if (!caseses.Any()) return caseses; // Delete relative keys @@ -310,6 +318,7 @@ public virtual List DeleteBatchCases(int[] casesID) if (casesID == null || !casesID.Any()) return null; var cases = GetCases(casesID).FindAll(CRMSecurity.CanDelete).ToList(); + if (!cases.Any()) return cases; // Delete relative keys @@ -324,21 +333,33 @@ private void DeleteBatchCasesExecute(List caseses) { var casesID = caseses.Select(x => x.ID).ToArray(); - var tagdao = FilesIntegration.GetTagDao(); - - var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id") - .Where(Exp.Eq("have_files", true) & Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))) - .Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); + var tagdao = FilesIntegration.TagDao(); + var tagNames = Query(CRMDbContext.RelationshipEvent) + .Where(x => x.HaveFiles && casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case) + .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); + var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); using var tx = CRMDbContext.Database.BeginTransaction(); - Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", casesID) & Exp.Eq("entity_type", (int)EntityType.Case))); - Db.ExecuteNonQuery(Delete("crm_case").Where(Exp.In("id", casesID))); + CRMDbContext.RemoveRange(Query(CRMDbContext.FieldValue) + .Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); + + CRMDbContext.RemoveRange(Query(CRMDbContext.RelationshipEvent) + .Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); + + CRMDbContext.RemoveRange(Query(CRMDbContext.Tasks) + .Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); + + CRMDbContext.RemoveRange(CRMDbContext.EntityTags.Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); + + CRMDbContext.Cases.RemoveRange(caseses.ConvertAll(x => new DbCase + { + Id = x.ID + })); + + CRMDbContext.SaveChanges(); tx.Commit(); @@ -403,12 +424,16 @@ public int GetCasesCount( if (withParams) { - var whereConditional = WhereConditional(exceptIDs, searchText, contactID, isClosed, tags); - result = whereConditional != null ? Db.ExecuteScalar(Query("crm_case").Where(whereConditional).SelectCount()) : 0; + var dbCasesQuery = GetDbCasesByFilters(exceptIDs, searchText, contactID, isClosed, tags); + + result = dbCasesQuery != null ? dbCasesQuery.Count() : 0; + } else { - var countWithoutPrivate = Db.ExecuteScalar(Query("crm_case").SelectCount()); + + var countWithoutPrivate = Query(CRMDbContext.Cases).Count(); + var privateCount = exceptIDs.Count; if (privateCount > countWithoutPrivate) @@ -428,11 +453,13 @@ public int GetCasesCount( { _cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30)); } + return result; + } - private Exp WhereConditional( + private IQueryable GetDbCasesByFilters( ICollection exceptIDs, String searchText, int contactID, @@ -440,7 +467,7 @@ private Exp WhereConditional( IEnumerable tags) { - var conditions = new List(); + var result = Query(CRMDbContext.Cases); var ids = new List(); @@ -455,32 +482,35 @@ private Exp WhereConditional( { if (!BundleSearch.TrySelectCase(searchText, out ids)) { - conditions.Add(BuildLike(new[] { "title" }, keywords)); + foreach(var k in keywords) + { + result = result.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k)); + } } else if (!ids.Any()) { return null; - } } } if (contactID > 0) { - - var sqlQuery = new SqlQuery("crm_entity_contact") - .Select("entity_id") - .Where(Exp.Eq("contact_id", contactID) & Exp.Eq("entity_type", (int)EntityType.Case)); - + var sqlQuery = CRMDbContext.EntityContact + .Where(x => x.ContactId == contactID && x.EntityType == EntityType.Case); + if (ids.Count > 0) - sqlQuery.Where(Exp.In("entity_id", ids)); + sqlQuery = sqlQuery.Where(x => ids.Contains(x.EntityId)); - ids = Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList(); + ids = sqlQuery.Select(x => x.EntityId).ToList(); + if (ids.Count == 0) return null; } if (isClosed.HasValue) - conditions.Add(Exp.Eq("is_closed", isClosed)); + { + result = result.Where(x => x.IsClosed == isClosed); + } if (tags != null && tags.Any()) { @@ -498,27 +528,26 @@ private Exp WhereConditional( if (ids.Count == 0) return null; } - conditions.Add(Exp.In("id", ids)); + result = result.Where(x => ids.Contains(x.Id)); } else if (exceptIDs.Count > 0) { - conditions.Add(!Exp.In("id", exceptIDs.ToArray())); + result = result.Where(x => !exceptIDs.Contains(x.Id)); } - if (conditions.Count == 0) return null; - - return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + return result; } public List GetCases(IEnumerable casesID) { - if (casesID == null || !casesID.Any()) return new List(); - var sqlQuery = GetCasesSqlQuery(Exp.In("id", casesID.ToArray())); - - return Db.ExecuteList(sqlQuery).ConvertAll(ToCases).FindAll(CRMSecurity.CanAccessTo); + return Query(CRMDbContext.Cases) + .Where(x => casesID.Contains(x.Id)) + .ToList() + .ConvertAll(ToCases) + .FindAll(CRMSecurity.CanAccessTo); } public List GetCases( @@ -530,44 +559,33 @@ public List GetCases( int count, OrderBy orderBy) { - var sqlQuery = GetCasesSqlQuery(null); - - var withParams = !(String.IsNullOrEmpty(searchText) && - contactID <= 0 && - isClosed == null && - (tags == null || !tags.Any())); - - var whereConditional = WhereConditional(CRMSecurity.GetPrivateItems(typeof(Cases)).ToList(), searchText, + var dbCasesQuery = GetDbCasesByFilters(CRMSecurity.GetPrivateItems(typeof(Cases)).ToList(), searchText, contactID, isClosed, tags); - if (withParams && whereConditional == null) - return new List(); + if (dbCasesQuery == null) return new List(); - sqlQuery.Where(whereConditional); + if (0 < from && from < int.MaxValue) dbCasesQuery.Skip(from); + if (0 < count && count < int.MaxValue) dbCasesQuery.Take(count); - if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); - if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + dbCasesQuery = dbCasesQuery.OrderBy(x => x.IsClosed); - sqlQuery.OrderBy("is_closed", true); - - - if (orderBy != null && Enum.IsDefined(typeof(SortedByType), orderBy.SortedBy)) + if (orderBy != null && Enum.IsDefined(typeof(Enums.SortedByType), orderBy.SortedBy)) switch ((SortedByType)orderBy.SortedBy) { case SortedByType.Title: - sqlQuery.OrderBy("title", orderBy.IsAsc); + dbCasesQuery = dbCasesQuery.OrderBy(x => x.Title); break; case SortedByType.CreateBy: - sqlQuery.OrderBy("create_by", orderBy.IsAsc); + dbCasesQuery = dbCasesQuery.OrderBy(x => x.CreateBy); break; case SortedByType.DateAndTime: - sqlQuery.OrderBy("create_on", orderBy.IsAsc); + dbCasesQuery = dbCasesQuery.OrderBy(x => x.CreateOn); break; } - return Db.ExecuteList(sqlQuery).ConvertAll(ToCases); + return dbCasesQuery.ToList().ConvertAll(ToCases); } public List GetCasesByPrefix(String prefix, int from, int count) @@ -579,27 +597,29 @@ public List GetCasesByPrefix(String prefix, int from, int count) var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); - var q = GetCasesSqlQuery(null); - + var q = Query(CRMDbContext.Cases); + if (keywords.Length == 1) { - q.Where(Exp.Like("title", keywords[0])); + q = q.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, keywords[0])); } else { foreach (var k in keywords) { - q.Where(Exp.Like("title", k)); + q = q.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k)); } } + + if (0 < from && from < int.MaxValue) q = q.Skip(from); + if (0 < count && count < int.MaxValue) q = q.Take(count); - if (0 < from && from < int.MaxValue) q.SetFirstResult(from); - if (0 < count && count < int.MaxValue) q.SetMaxResults(count); - - var sqlResult = Db.ExecuteList(q).ConvertAll(row => ToCases(row)).FindAll(CRMSecurity.CanAccessTo); - return sqlResult.OrderBy(cases => cases.Title).ToList(); + q = q.OrderBy(x => x.Title); + + return q.ToList().ConvertAll(ToCases).FindAll(CRMSecurity.CanAccessTo); } + public virtual List GetByID(int[] ids) { return CRMDbContext.Cases @@ -619,32 +639,20 @@ public virtual Cases GetByID(int id) private Cases ToCases(DbCase dbCase) { + if (dbCase == null) return null; + return new Cases { ID = dbCase.Id, Title = dbCase.Title, CreateBy = dbCase.CreateBy, - CreateOn = dbCase.CreateOn, + CreateOn = TenantUtil.DateTimeFromUtc(dbCase.CreateOn), IsClosed = dbCase.IsClosed, LastModifedBy = dbCase.LastModifedBy, LastModifedOn = dbCase.LastModifedOn }; } - private SqlQuery GetCasesSqlQuery(Exp where) - { - - var sqlQuery = Query("crm_case") - .Select("id", "title", "create_by", "create_on", "is_closed"); - - if (where != null) - { - sqlQuery.Where(where); - } - - return sqlQuery; - } - public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) { var cases = GetAllCases(); diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 73679165be0..a9784e31891 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -32,7 +32,11 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.Files.Core; using ASC.Web.CRM.Core.Search; +using ASC.Web.Files.Api; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Globalization; @@ -44,13 +48,30 @@ namespace ASC.CRM.Core.Dao { public class CachedContactDao : ContactDao { + private readonly HttpRequestDictionary _contactCache; - private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_contact"); - - public CachedContactDao(int tenantID) - : base(tenantID) + public CachedContactDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + IHttpContextAccessor httpContextAccessor, + TenantUtil tenantUtil, + AuthorizationManager authorizationManager, + FilesIntegration filesIntegration, + FactoryIndexer factoryIndexerContactsWrapper, + FactoryIndexer factoryIndexerEmailWrapper) : + base(dbContextManager, + tenantManager, + securityContext, + cRMSecurity, + tenantUtil, + authorizationManager, + filesIntegration, + factoryIndexerContactsWrapper, + factoryIndexerEmailWrapper) { - + _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact"); } public override Contact GetByID(int contactID) @@ -95,30 +116,40 @@ private void ResetCache(int contactID) _contactCache.Reset(contactID.ToString()); } } - + public class ContactDao : AbstractDao { - #region Constructor - public ContactDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity) : + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + AuthorizationManager authorizationManager, + FilesIntegration filesIntegration, + FactoryIndexer factoryIndexerContactsWrapper, + FactoryIndexer factoryIndexerEmailWrapper + ) : base(dbContextManager, tenantManager, securityContext) { CRMSecurity = cRMSecurity; - } - - #endregion - - #region Members + TenantUtil = tenantUtil; + AuthorizationManager = authorizationManager; + FilesIntegration = filesIntegration; + FactoryIndexerContactsWrapper = factoryIndexerContactsWrapper; + FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; + } + + public FactoryIndexer FactoryIndexerEmailWrapper { get; } + public FactoryIndexer FactoryIndexerContactsWrapper { get; } + public FilesIntegration FilesIntegration { get; } + public AuthorizationManager AuthorizationManager { get; } + public TenantUtil TenantUtil { get; } public CRMSecurity CRMSecurity { get; } + private readonly String _displayNameSeparator = "!=!"; - - #endregion public List GetContactsByPrefix(String prefix, int searchType, int from, int count) { @@ -127,27 +158,27 @@ public List GetContactsByPrefix(String prefix, int searchType, int from var keywords = prefix.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - var query = Query("crm_contact c").Select(GetContactColumnsTable("c")); + var query = Query(CRMDbContext.Contacts); switch (searchType) { case 0: // Company - query.Where(Exp.Eq("c.is_company", true)); + query = query.Where(x => x.IsCompany); break; case 1: // Persons - query.Where(Exp.Eq("c.is_company", false)); + query = query.Where(x => !x.IsCompany); break; case 2: // PersonsWithoutCompany - query.Where(Exp.Eq("c.company_id", 0) & Exp.Eq("c.is_company", false)); + query = query.Where(x => x.CompanyId == 0 && !x.IsCompany); break; - case 3: // CompaniesAndPersonsWithoutCompany - query.Where(Exp.Eq("c.company_id", 0)); + case 3: // CompaniesAndPersonsWithoutCompany + query = query.Where(x => x.CompanyId == 0); break; } foreach (var k in keywords) { - query.Where(Exp.Like("c.display_name", k)); + query = query.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k)); } if (!CRMSecurity.IsAdmin) @@ -158,18 +189,21 @@ public List GetContactsByPrefix(String prefix, int searchType, int from var privateContacts = Exp.And(Exp.Eq("c.is_shared", 0), ExistAclRecord(true, "c")); - query.Where(Exp.Or(sharedContacts, Exp.Or(oldContacts, privateContacts))); + query = query.Where(Exp.Or(sharedContacts, Exp.Or(oldContacts, privateContacts))); + + query = query.Where(x => x.IsShared >= 0 || (x.IsShared == null && )); + } - query.OrderBy("c.display_name", true); + query = query.OrderBy(x => x.DisplayName); - if (0 < from && from < int.MaxValue) query.SetFirstResult(from); - if (0 < count && count < int.MaxValue) query.SetMaxResults(count); + if (0 < from && from < int.MaxValue) query = query.Skip(from); + if (0 < count && count < int.MaxValue) query = query.Take(count); - return Db.ExecuteList(query).ConvertAll(ToContact); + return query.ToList().ConvertAll(ToContact); } - private static Exp ExistAclRecord(bool forCurrentUser, string contactTebleAlias = "") + private Exp ExistAclRecord(bool forCurrentUser, string contactTebleAlias = "") { var alias = string.IsNullOrEmpty(contactTebleAlias) ? string.Empty : contactTebleAlias + "."; @@ -247,64 +281,78 @@ public int GetContactsCount(String searchText, isShared); int result; - if (withParams) + if (withParams) + { + ICollection excludedContactIDs; + + var sharedTypes = new[] { ShareType.Read, ShareType.ReadWrite }.ToList(); + + switch (contactListView) { - ICollection excludedContactIDs; + case ContactListViewType.Person: + { - switch (contactListView) - { - case ContactListViewType.Person: excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) - .Except(Db.ExecuteList(Query("crm_contact").Select("id") - .Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite }) & Exp.Eq("is_company", false))) - .Select(x => Convert.ToInt32(x[0]))).ToList(); - break; - case ContactListViewType.Company: - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)) - .Except(Db.ExecuteList(Query("crm_contact").Select("id") - .Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite }) & Exp.Eq("is_company", true))) - .Select(x => Convert.ToInt32(x[0]))).ToList(); + .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + sharedTypes.Contains(x.IsShared.Value) : + true && !x.IsCompany).Select(x => x.Id)) + .ToList(); break; - default: - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)).Union(CRMSecurity.GetPrivateItems(typeof(Person))) - .Except(Db.ExecuteList(Query("crm_contact").Select("id").Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite }))) - .Select(x => Convert.ToInt32(x[0]))).ToList(); + } + case ContactListViewType.Company: + { + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) + .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + sharedTypes.Contains(x.IsShared.Value) : + true && x.IsCompany).Select(x => x.Id)) + .ToList(); + break; + } + default: + { + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)) + .Union(CRMSecurity.GetPrivateItems(typeof(Person))) + .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + sharedTypes.Contains(x.IsShared.Value) : + true && x.IsCompany).Select(x => x.Id)) + .ToList(); break; - } + } + } - var whereConditional = WhereConditional(excludedContactIDs, - searchText, - tags, - contactStage, - contactType, - contactListView, - fromDate, - toDate, - responsibleid, - isShared); - - if (whereConditional != null) + var dbContactsByFilters = GetDbContactsByFilters(excludedContactIDs, + searchText, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + responsibleid, + isShared); + + if (dbContactsByFilters != null) { if (!isShared.HasValue) { - var sqlQuery = Query("crm_contact").SelectCount().Where(whereConditional); - result = Db.ExecuteScalar(sqlQuery); + result = dbContactsByFilters.Count(); } else { - var sqlQuery = Query("crm_contact").Select("id, is_company, is_shared").Where(whereConditional); - var sqlResultRows = Db.ExecuteList(sqlQuery); + var sqlResultRows = dbContactsByFilters.Select(x => new { x.Id, x.IsCompany, x.IsShared }).ToList(); - var resultContactsNewScheme_Count = sqlResultRows.Where(row => row[2] != null).ToList().Count; //new scheme + var resultContactsNewScheme_Count = sqlResultRows.Where(x => x.IsShared != null).ToList().Count; //new scheme var fakeContactsOldScheme = sqlResultRows - .Where(row => row[2] == null).ToList() // old scheme - .ConvertAll(row => Convert.ToBoolean(row[1]) == true ? new Company() {ID = Convert.ToInt32(row[0])} as Contact : new Person() {ID = Convert.ToInt32(row[0])} as Contact ); - var resultFakeContactsOldScheme_Count = fakeContactsOldScheme.Where(fc => { + .Where(x => x.IsShared == null).ToList() // old scheme + .ConvertAll(x => x.IsCompany ? new Company() { ID = x.Id } as Contact : new Person() { ID = x.Id } as Contact); + + var resultFakeContactsOldScheme_Count = fakeContactsOldScheme.Where(fc => + { var accessSubjectToContact = CRMSecurity.GetAccessSubjectTo(fc); if (isShared.Value == true) { @@ -314,6 +362,7 @@ public int GetContactsCount(String searchText, { return accessSubjectToContact.Any(); } + }).ToList().Count; return resultContactsNewScheme_Count + resultFakeContactsOldScheme_Count; @@ -326,12 +375,15 @@ public int GetContactsCount(String searchText, } else { - var countWithoutPrivate = Db.ExecuteScalar(Query("crm_contact").SelectCount()); + var countWithoutPrivate = Query(CRMDbContext.Contacts).Count(); + + var sharedTypes = new[] { ShareType.Read, ShareType.ReadWrite }.ToList(); var privateCount = CRMSecurity.GetPrivateItemsCount(typeof(Person)) + CRMSecurity.GetPrivateItemsCount(typeof(Company)) - - Db.ExecuteScalar(Query("crm_contact").Where(Exp.In("is_shared", new[] { (int)ShareType.Read, (int)ShareType.ReadWrite })).SelectCount()); - + Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + sharedTypes.Contains(x.IsShared.Value) : + true).Count(); if (privateCount < 0) privateCount = 0; @@ -359,23 +411,11 @@ public List SearchContactsByEmail(string searchText, int maxCount) if (string.IsNullOrEmpty(searchText) || maxCount <= 0) return contacts; - Func getBaseQuery = () => - { - var query = new SqlQuery("crm_contact cc") - .Select(GetContactColumnsTable("cc")) - .InnerJoin("crm_contact_info cci", - Exp.EqColumns("cc.tenant_id", "cci.tenant_id") & - Exp.EqColumns("cc.id", "cci.contact_id")) - .Where("cci.type", (int) ContactInfoType.Email) - .Where("cc.tenant_id", TenantID); - - return query; - }; - var ids = new List(); List contactsIds; - if (FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out contactsIds)) + + if (FactoryIndexerEmailWrapper.TrySelectIds(s => s.MatchAll(searchText), out contactsIds)) { if (!contactsIds.Any()) return contacts; @@ -384,33 +424,39 @@ public List SearchContactsByEmail(string searchText, int maxCount) } var isAdmin = CRMSecurity.IsAdmin; + const int count_per_query = 100; var f = 0; + do { - var query = getBaseQuery(); + var query = Query(CRMDbContext.Contacts).Join(CRMDbContext.ContactsInfo, + x => new { Column1 = x.TenantId, Column2 = x.Id }, + y => new { Column1 = y.TenantId, Column2 = y.ContactId }, + (x, y) => new { x, y }) + .Where(x => x.y.Type == ContactInfoType.Email); if (ids.Any()) { var partIds = ids.Skip(f).Take(count_per_query).ToList(); if (!partIds.Any()) + break; - query - .Where(Exp.In("cc.id", partIds)); + query = query.Where(x => partIds.Contains(x.x.Id)); + } else { - query - .Where(Exp.Like("concat(cc.display_name, ' ', cci.data)", searchText, SqlLike.AnyWhere)) - .SetFirstResult(f) - .SetMaxResults(count_per_query); + + query = query.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(String.Concat(x.x.DisplayName, " ", x.y.Data), "%" + searchText + "%")); + + query = query.Skip(f).Take(count_per_query); } - var partContacts = Db.ExecuteList(query) - .ConvertAll(ToContact); + var partContacts = query.Select(x => x.x).ToList().ConvertAll(ToContact); foreach (var partContact in partContacts) { @@ -510,10 +556,10 @@ public List GetContacts(String searchText, result.AddRange(crudeContacts.Where(c => (isShared.Value == true ? c.ShareType != ShareType.None : c.ShareType == ShareType.None))); - if ((result.Count >= count + from) || (crudeContacts.Count < localCount)) break; + if ((result.Count >= count + from) || (crudeContacts.Count < localCount)) break; - localFrom += localCount; - localCount = localCount * 2; + localFrom += localCount; + localCount = localCount * 2; } return result.Skip(from).Take(count).ToList(); @@ -608,7 +654,7 @@ private bool HasSearchParams(String searchText, return !hasNoParams; } - private Exp WhereConditional( + private IQueryable GetDbContactsByFilters( ICollection exceptIDs, String searchText, IEnumerable tags, @@ -620,7 +666,8 @@ private Exp WhereConditional( Guid? responsibleid = null, bool? isShared = null) { - var conditions = new List(); + + var sqlQuery = Query(CRMDbContext.Contacts); var ids = new List(); @@ -656,12 +703,17 @@ private Exp WhereConditional( if (!BundleSearch.TrySelectContact(searchText, out contactsIds)) { _log.Debug("FullTextSearch.SupportModule('CRM.Contacts') = false"); - conditions.Add(BuildLike(new[] { "display_name" }, keywords)); + + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k)); + } } else { _log.Debug("FullTextSearch.SupportModule('CRM.Contacts') = true"); _log.DebugFormat("FullTextSearch.Search: searchText = {0}", searchText); + var full_text_ids = contactsIds; if (full_text_ids.Count == 0) return null; @@ -694,25 +746,31 @@ private Exp WhereConditional( switch (contactListView) { case ContactListViewType.Company: - conditions.Add(Exp.Eq("is_company", true)); - break; + { + sqlQuery = sqlQuery.Where(x => x.IsCompany); + + break; + } case ContactListViewType.Person: - conditions.Add(Exp.Eq("is_company", false)); - break; + { + sqlQuery = sqlQuery.Where(x => !x.IsCompany); + + break; + } case ContactListViewType.WithOpportunity: if (ids.Count > 0) { - ids = Db.ExecuteList(new SqlQuery("crm_entity_contact").Select("contact_id") - .Distinct() - .Where(Exp.In("contact_id", ids) & Exp.Eq("entity_type", (int)EntityType.Opportunity))) - .ConvertAll(row => Convert.ToInt32(row[0])); + ids = CRMDbContext.EntityContact.Where(x => ids.Contains(x.ContactId) && x.EntityType == EntityType.Opportunity) + .Select(x => x.ContactId) + .Distinct() + .ToList(); } else { - ids = Db.ExecuteList(new SqlQuery("crm_entity_contact").Select("contact_id") - .Distinct() - .Where(Exp.Eq("entity_type", (int)EntityType.Opportunity))) - .ConvertAll(row => Convert.ToInt32(row[0])); + ids = CRMDbContext.EntityContact.Where(x => x.EntityType == EntityType.Opportunity) + .Select(x => x.ContactId) + .Distinct() + .ToList(); } if (ids.Count == 0) return null; @@ -721,23 +779,35 @@ private Exp WhereConditional( } if (contactStage >= 0) - conditions.Add(Exp.Eq("status_id", contactStage)); + sqlQuery = sqlQuery.Where(x => x.StatusId == contactStage); + if (contactType >= 0) - conditions.Add(Exp.Eq("contact_type_id", contactType)); + sqlQuery = sqlQuery.Where(x => x.ContactTypeId == contactType); if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) - conditions.Add(Exp.Between("create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1)))); + { + sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); + } else if (fromDate != DateTime.MinValue) - conditions.Add(Exp.Ge("create_on", TenantUtil.DateTimeToUtc(fromDate))); + { + sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate)); + } else if (toDate != DateTime.MinValue) - conditions.Add(Exp.Le("create_on", TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1)))); + { + sqlQuery = sqlQuery.Where(x => x.CreateOn <= TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); + } if (isShared.HasValue) { - if (isShared.Value == true) { - conditions.Add(Exp.Or(Exp.In("is_shared", new[]{(int)ShareType.Read , (int)ShareType.ReadWrite}), Exp.Eq("is_shared", null))); - } else { - conditions.Add(Exp.Or(Exp.Eq("is_shared", (int)ShareType.None), Exp.Eq("is_shared", null))); + var sharedTypes = new[] { ShareType.Read, ShareType.ReadWrite }.ToList(); + + if (isShared.Value) + { + sqlQuery = sqlQuery.Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : x.IsShared == null ); + } + else + { + sqlQuery = sqlQuery.Where(x => x.IsShared.HasValue ? x.IsShared == ShareType.None : x.IsShared == null); } } @@ -749,8 +819,7 @@ private Exp WhereConditional( if (ids.Count == 0) return null; } - conditions.Add(Exp.In("id", ids)); - + sqlQuery = sqlQuery.Where(x => ids.Contains(x.Id)); } else if (exceptIDs.Count > 0) { @@ -758,25 +827,26 @@ private Exp WhereConditional( if (exceptIDs.Count > _MaxCountForSQLNotIn) { - ids = Db.ExecuteList(Query("crm_contact").Select("id")).ConvertAll(row => Convert.ToInt32(row[0])); //get all contact ids + ids = Query(CRMDbContext.Contacts).Select(x => x.Id).ToList(); + ids = ids.Except(exceptIDs).ToList(); if (ids.Count == 0) return null; - conditions.Add(Exp.In("id", ids)); + sqlQuery = sqlQuery.Where(x => ids.Contains(x.Id)); - } else { - conditions.Add(!Exp.In("id", exceptIDs.ToArray())); + } + else + { + sqlQuery = sqlQuery.Where(x => !exceptIDs.Contains(x.Id)); } } - if (conditions.Count == 0) return null; - - return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + return sqlQuery; } private List GetCrudeContacts( String searchText, - IEnumerable tags, + IEnumerable tags, int contactStage, int contactType, ContactListViewType contactListView, @@ -789,9 +859,6 @@ private List GetCrudeContacts( bool? isShared = null, bool selectIsSharedInNewScheme = true) { - - var sqlQuery = GetContactSqlQuery(null); - var withParams = HasSearchParams(searchText, tags, contactStage, @@ -802,7 +869,7 @@ private List GetCrudeContacts( responsibleid, isShared); - var whereConditional = WhereConditional(new List(), + var dbContactsQuery = GetDbContactsByFilters(new List(), searchText, tags, contactStage, @@ -813,14 +880,11 @@ private List GetCrudeContacts( responsibleid, isShared); - if (withParams && whereConditional == null) - return new List(); - - sqlQuery.Where(whereConditional); - - if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); - if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + if (withParams && dbContactsQuery == null) return new List(); + if (0 < from && from < int.MaxValue) dbContactsQuery = dbContactsQuery.Skip(from); + if (0 < count && count < int.MaxValue) dbContactsQuery = dbContactsQuery.Take(count); + if (orderBy != null) { @@ -830,37 +894,48 @@ private List GetCrudeContacts( switch ((ContactSortedByType)orderBy.SortedBy) { case ContactSortedByType.DisplayName: - sqlQuery.OrderBy("display_name", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.DisplayName); break; case ContactSortedByType.Created: - sqlQuery.OrderBy("create_on", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.CreateOn); break; case ContactSortedByType.ContactType: - sqlQuery.OrderBy("status_id", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.StatusId); break; case ContactSortedByType.FirstName: - sqlQuery.OrderBy("first_name", orderBy.IsAsc); - sqlQuery.OrderBy("last_name", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.FirstName); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.LastName); break; case ContactSortedByType.LastName: - sqlQuery.OrderBy("last_name", orderBy.IsAsc); - sqlQuery.OrderBy("first_name", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.LastName); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.FirstName); break; case ContactSortedByType.History: - sqlQuery.Select("last_event_modifed_on"); - var subSqlQuery = Query("crm_relationship_event") - .Select("contact_id") - .Select("max(last_modifed_on) as last_event_modifed_on") - .Where(Exp.Gt("contact_id", 0)) - .GroupBy("contact_id"); + throw new NotImplementedException(); + + //dbContactsQuery.GroupJoin(Query(CRMDbContext.RelationshipEvent), + // x => x.Id, + // y => y.ContactId, + // (x, y) => new { x, y }) + // .OrderBy(x => x.y?.Select(x=>x.LastModifedOn)) + + + //sqlQuery.Select("last_event_modifed_on"); + //var subSqlQuery = Query("crm_relationship_event") + // .Select("contact_id") + // .Select("max(last_modifed_on) as last_event_modifed_on") + // .Where(Exp.Gt("contact_id", 0)) + // .GroupBy("contact_id"); + //sqlQuery.LeftOuterJoin(subSqlQuery, "evt", Exp.EqColumns("id", "evt.contact_id")); + //sqlQuery.OrderBy("last_event_modifed_on", orderBy.IsAsc); + //sqlQuery.OrderBy("create_on", orderBy.IsAsc); - sqlQuery.LeftOuterJoin(subSqlQuery, "evt", Exp.EqColumns("id", "evt.contact_id")); - sqlQuery.OrderBy("last_event_modifed_on", orderBy.IsAsc); - sqlQuery.OrderBy("create_on", orderBy.IsAsc); + //dbContactsQuery = dbContactsQuery.OrderBy(x => x.la); + // dbContactsQuery = dbContactsQuery.OrderBy(x => x.CreateOn); break; default: - sqlQuery.OrderBy("display_name", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy(x => x.DisplayName); break; } } @@ -883,10 +958,10 @@ public List GetContactsByName(String title, bool isCompany) if (isCompany) { - return Db.ExecuteList( - GetContactSqlQuery(Exp.Eq("display_name", title) & Exp.Eq("is_company", true))) - .ConvertAll(ToContact) - .FindAll(CRMSecurity.CanAccessTo); + return CRMDbContext.Contacts.Where(x => String.Compare(x.DisplayName, title) == 0 && x.IsCompany) + .ToList() + .ConvertAll(ToContact) + .FindAll(CRMSecurity.CanAccessTo); } else { @@ -895,17 +970,22 @@ public List GetContactsByName(String title, bool isCompany) if (titleParts.Length == 1 || titleParts.Length == 2) { if (titleParts.Length == 1) - return Db.ExecuteList( - GetContactSqlQuery(Exp.Eq("display_name", title) & Exp.Eq("is_company", false))) - .ConvertAll(ToContact) - .FindAll(CRMSecurity.CanAccessTo); + { + return Query(CRMDbContext.Contacts).Where(x => String.Compare(x.DisplayName, title) == 0 && !x.IsCompany) + .ToList() + .ConvertAll(ToContact) + .FindAll(CRMSecurity.CanAccessTo); + } else - return Db.ExecuteList( - GetContactSqlQuery(Exp.Eq("display_name", String.Concat(titleParts[0], _displayNameSeparator, titleParts[1])) & Exp.Eq("is_company", false))) - .ConvertAll(ToContact) - .FindAll(CRMSecurity.CanAccessTo); + { + return Query(CRMDbContext.Contacts).Where(x => String.Compare(x.DisplayName, String.Concat(titleParts[0], _displayNameSeparator, titleParts[1])) == 0 && !x.IsCompany) + .ToList() + .ConvertAll(ToContact) + .FindAll(CRMSecurity.CanAccessTo); + } } } + return GetContacts(title, null, -1, -1, isCompany ? ContactListViewType.Company : ContactListViewType.Person, DateTime.MinValue, DateTime.MinValue, 0, 0, null); } @@ -913,21 +993,57 @@ public void RemoveMember(int[] peopleID) { if ((peopleID == null) || (peopleID.Length == 0)) return; - Db.ExecuteNonQuery(Update("crm_contact").Set("company_id", 0).Where(Exp.In("id", peopleID))); + foreach (var id in peopleID) + { + var itemToUpdate = new DbContact + { + Id = id, + CompanyId = 0, + TenantId = TenantID + }; + + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + } + + CRMDbContext.SaveChanges(); + RemoveRelativeInDb(null, EntityType.Person, peopleID); + } public void RemoveMember(int peopleID) { - Db.ExecuteNonQuery(Update("crm_contact").Set("company_id", 0).Where("id", peopleID)); + var itemToUpdate = new DbContact + { + Id = peopleID, + CompanyId = 0, + TenantId = TenantID + }; + + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + + CRMDbContext.SaveChanges(); + RemoveRelative(0, EntityType.Person, peopleID); } public void AddMemberInDb(int peopleID, int companyID) { - Db.ExecuteNonQuery(Update("crm_contact") - .Set("company_id", companyID) - .Where("id", peopleID)); + + var itemToUpdate = new DbContact + { + Id = peopleID, + CompanyId = companyID, + TenantId = TenantID + }; + + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + + CRMDbContext.SaveChanges(); + SetRelative(companyID, EntityType.Person, peopleID); } @@ -941,61 +1057,80 @@ public void SetMembers(int companyID, params int[] peopleIDs) if (companyID == 0) throw new ArgumentException(); - using (var tx = Db.BeginTransaction()) - { - Db.ExecuteNonQuery(new SqlDelete("crm_entity_contact") - .Where(Exp.Eq("entity_type", EntityType.Person) & - Exp.Eq("contact_id", companyID))); + var tx = CRMDbContext.Database.BeginTransaction(); + + CRMDbContext.EntityContact + .RemoveRange(CRMDbContext.EntityContact + .Where(x => x.EntityType == EntityType.Person && x.ContactId == companyID)); - Db.ExecuteNonQuery(Update("crm_contact") - .Set("company_id", 0) - .Where(Exp.Eq("company_id", companyID))); + var itemsToUpdate = Query(CRMDbContext.Contacts).Where(x => x.CompanyId == companyID).ToList(); + itemsToUpdate.ForEach(x => x.CompanyId = 0); - if (!(peopleIDs == null || peopleIDs.Length == 0)) + CRMDbContext.UpdateRange(itemsToUpdate); + + CRMDbContext.SaveChanges(); + + if (!(peopleIDs == null || peopleIDs.Length == 0)) + { + foreach (var id in peopleIDs) { - Db.ExecuteNonQuery(Update("crm_contact") - .Set("company_id", companyID) - .Where(Exp.In("id", peopleIDs))); - foreach (var peopleID in peopleIDs) - SetRelative(companyID, EntityType.Person, peopleID); + var contactItemToUpdate = new DbContact + { + Id = id, + CompanyId = companyID, + TenantId = TenantID + }; + + CRMDbContext.Attach(contactItemToUpdate); + CRMDbContext.Entry(contactItemToUpdate).Property(x => x.CompanyId).IsModified = true; + CRMDbContext.Update(contactItemToUpdate); } - tx.Commit(); + CRMDbContext.SaveChanges(); + foreach (var peopleID in peopleIDs) + { + SetRelative(companyID, EntityType.Person, peopleID); + } } + tx.Commit(); + } public void SetRelativeContactProject(IEnumerable contactid, int projectid) { - using (var tx = Db.BeginTransaction()) + var tx = CRMDbContext.Database.BeginTransaction(); + + foreach (var id in contactid) { - foreach (var id in contactid) + var itemToInsert = new DbProjects { + ContactId = id, + ProjectId = projectid, + TenantId = TenantID + }; - Db.ExecuteNonQuery(Insert("crm_projects") - .InColumnValue("contact_id", id) - .InColumnValue("project_id", projectid)); - } - - tx.Commit(); + CRMDbContext.Projects.Add(itemToInsert); } + + tx.Commit(); + } public void RemoveRelativeContactProject(int contactid, int projectid) { - Db.ExecuteNonQuery(Delete("crm_projects") - .Where(Exp.Eq("contact_id", contactid) & Exp.Eq("project_id", projectid))); + CRMDbContext.RemoveRange(Query(CRMDbContext.Projects) + .Where(x => x.ContactId == contactid && x.ProjectId == projectid)); } public IEnumerable GetContactsByProjectID(int projectid) { - var contactIds = Db.ExecuteList(Query("crm_projects") - .Select("contact_id") - .Where("project_id", projectid)).Select(x => Convert.ToInt32(x[0])); - + var contactIds = Query(CRMDbContext.Projects) + .Where(x => x.ProjectId == projectid) + .Select(x => x.ContactId); if (!contactIds.Any()) return new List(); @@ -1014,59 +1149,42 @@ public List GetRestrictedMembers(int companyID) public Dictionary GetMembersCount(int[] companyID) { - - var sqlQuery = new SqlQuery("crm_entity_contact") - .Select("contact_id") - .SelectCount() - .Where(Exp.In("contact_id", companyID) & Exp.Eq("entity_type", (int)EntityType.Person)) - .GroupBy("contact_id"); - - var sqlResult = Db.ExecuteList(sqlQuery); - - return sqlResult.ToDictionary(item => Convert.ToInt32(item[0]), item => Convert.ToInt32(item[1])); + return CRMDbContext.EntityContact + .Where(x => companyID.Contains(x.ContactId) && x.EntityType == EntityType.Person) + .GroupBy(x => x.ContactId) + .Select(x => new { GroupId = x.Key, Count = x.Count() }) + .ToDictionary(x => x.GroupId, x => x.Count); } public int GetMembersCount(int companyID) { - return Db.ExecuteScalar( - new SqlQuery("crm_entity_contact") - .SelectCount() - .Where(Exp.Eq("contact_id", companyID) & Exp.Eq("entity_type", (int)EntityType.Person))); + return CRMDbContext.EntityContact + .Where(x => x.ContactId == companyID && x.EntityType == EntityType.Person) + .Count(); } public List GetMembersIDs(int companyID) { - return Db.ExecuteList( - new SqlQuery("crm_entity_contact") - .Select("entity_id") - .Where(Exp.Eq("contact_id", companyID) & Exp.Eq("entity_type", (int)EntityType.Person))) - .ConvertAll(row => (int)(row[0])); + return CRMDbContext.EntityContact + .Where(x => x.ContactId == companyID && x.EntityType == EntityType.Person) + .Select(x => x.EntityId) + .ToList(); } public Dictionary GetMembersIDsAndShareType(int companyID) { - var result = new Dictionary(); - - var query = new SqlQuery("crm_entity_contact ec") - .Select("ec.entity_id") - .Select("c.is_shared") - .LeftOuterJoin("crm_contact c", Exp.EqColumns("ec.entity_id", "c.id")) - .Where(Exp.Eq("ec.contact_id", companyID) & Exp.Eq("ec.entity_type", (int)EntityType.Person)); - var rows = Db.ExecuteList(query); - - foreach (var row in rows) { - if (row[1] == null) - { - result.Add((int)(row[0]), null); - } - else - { - result.Add((int)(row[0]), (ShareType)(Convert.ToInt32(row[1]))); - } - } - - return result; + return CRMDbContext.EntityContact + .Where(x => x.ContactId == companyID && x.EntityType == EntityType.Person) + .GroupJoin(CRMDbContext.Contacts, + x => x.EntityId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new + { + EntityId = x.x.EntityId, + IsShared = y.IsShared + }).ToDictionary(x => x.EntityId, y => y.IsShared); } @@ -1136,35 +1254,53 @@ private void UpdateContactFromDb(Contact contact) contact.Industry = contact.Industry.Trim(); - Db.ExecuteNonQuery( - Update("crm_contact") - .Set("first_name", firstName) - .Set("last_name", lastName) - .Set("company_name", companyName) - .Set("title", title) - .Set("notes", contact.About) - .Set("industry", contact.Industry) - .Set("status_id", contact.StatusID) - .Set("company_id", companyID) - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Set("display_name", displayName) - .Set("is_shared", (int)contact.ShareType) - .Set("contact_type_id", contact.ContactTypeID) - .Set("currency", contact.Currency) - .Where(Exp.Eq("id", contact.ID))); + var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.Id == contact.ID); + + itemToUpdate.FirstName = firstName; + itemToUpdate.LastName = lastName; + itemToUpdate.CompanyName = companyName; + itemToUpdate.Title = title; + itemToUpdate.Notes = contact.About; + itemToUpdate.Industry = contact.Industry; + itemToUpdate.StatusId = contact.StatusID; + itemToUpdate.CompanyId = companyID; + itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); + itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.DisplayName = displayName; + itemToUpdate.IsShared = contact.ShareType; + itemToUpdate.ContactTypeId = contact.ContactTypeID; + itemToUpdate.Currency = contact.Currency; + itemToUpdate.TenantId = TenantID; + + CRMDbContext.Update(itemToUpdate); + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); - FactoryIndexer.UpdateAsync(contact); + + FactoryIndexerContactsWrapper.UpdateAsync(contact); + } public void UpdateContactStatus(IEnumerable contactid, int statusid) { - Db.ExecuteNonQuery( - Update("crm_contact") - .Set("status_id", statusid) - .Where(Exp.In("id", contactid.ToArray()))); + foreach (var item in contactid) + { + var itemToUpdate = new DbContact + { + Id = item, + StatusId = statusid, + TenantId = TenantID + }; + + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.StatusId).IsModified = true; + + } + + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } @@ -1176,24 +1312,23 @@ public List FindDuplicateByEmail(List items, bool resultReal) var result = new List(); var emails = items.ConvertAll(i => i.Data).ToList(); - var sqlQuery = Query("crm_contact_info") - .Select("contact_id", "data") - .Where(Exp.In("data", emails) & Exp.Eq("type", (int)ContactInfoType.Email)); + var sqlQuery = Query(CRMDbContext.ContactsInfo) + .Where(x => emails.Contains(x.Data) && x.Type == ContactInfoType.Email); if (resultReal) { - result = Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToInt32(row[0])); + result = sqlQuery.Select(x => x.ContactId).ToList(); } else { List emailsAlreadyExists; - emailsAlreadyExists = Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToString(row[1])); + emailsAlreadyExists = sqlQuery.Select(x => x.Data).ToList(); - if (emailsAlreadyExists.Count != 0) { + if (emailsAlreadyExists.Count != 0) + { result = items.Where(i => emailsAlreadyExists.Contains(i.Data)).Select(i => i.ContactID).ToList(); } - } return result; @@ -1201,69 +1336,75 @@ public List FindDuplicateByEmail(List items, bool resultReal) public virtual Dictionary SaveContactList(List items) { - using (var tx = Db.BeginTransaction()) - { - var result = new Dictionary(); + var tx = CRMDbContext.Database.BeginTransaction(); - for (int index = 0; index < items.Count; index++) - { - var item = items[index]; + var result = new Dictionary(); - if (item.ID == 0) - item.ID = index; + for (int index = 0; index < items.Count; index++) + { + var item = items[index]; - result.Add(item.ID, SaveContactToDb(item)); - } + if (item.ID == 0) + item.ID = index; - tx.Commit(); + result.Add(item.ID, SaveContactToDb(item)); + } - // Delete relative keys - _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + tx.Commit(); - return result; - } + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + + return result; } public virtual void UpdateContactList(List items) { - using (var tx = Db.BeginTransaction()) + var tx = CRMDbContext.Database.BeginTransaction(); + + for (int index = 0; index < items.Count; index++) { - for (int index = 0; index < items.Count; index++) - { - var item = items[index]; + var item = items[index]; - if (item.ID == 0) - item.ID = index; + if (item.ID == 0) + item.ID = index; - UpdateContactFromDb(item); - } + UpdateContactFromDb(item); + } - tx.Commit(); + tx.Commit(); - // Delete relative keys - _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); - } + // Delete relative keys + _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } public void MakePublic(int contactId, bool isShared) { if (contactId <= 0) throw new ArgumentException(); - Db.ExecuteNonQuery( - Update("crm_contact") - .Set("is_shared", isShared) - .Where(Exp.Eq("id", contactId))); + var itemToUpdate = new DbContact + { + Id = contactId, + IsShared = isShared ? ShareType.ReadWrite : ShareType.None, + TenantId = TenantID + }; + + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.IsShared).IsModified = true; + CRMDbContext.SaveChanges(); } public virtual int SaveContact(Contact contact) { var result = SaveContactToDb(contact); - FactoryIndexer.IndexAsync(contact); + FactoryIndexerContactsWrapper.IndexAsync(contact); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); + return result; + } private int SaveContactToDb(Contact contact) @@ -1282,7 +1423,7 @@ private int SaveContactToDb(Contact contact) firstName = String.Empty; lastName = String.Empty; title = String.Empty; - companyName = (((Company) contact).CompanyName ?? "").Trim(); + companyName = (((Company)contact).CompanyName ?? "").Trim(); isCompany = true; companyID = 0; displayName = companyName; @@ -1308,7 +1449,6 @@ private int SaveContactToDb(Contact contact) displayName = String.Concat(firstName, _displayNameSeparator, lastName); - if (String.IsNullOrEmpty(firstName))// || String.IsNullOrEmpty(lastName)) lastname is not required field now throw new ArgumentException(); @@ -1323,66 +1463,64 @@ private int SaveContactToDb(Contact contact) if (!String.IsNullOrEmpty(contact.Industry)) contact.Industry = contact.Industry.Trim(); - var contactID = Db.ExecuteScalar( - Insert("crm_contact") - .InColumnValue("id", 0) - .InColumnValue("first_name", firstName) - .InColumnValue("last_name", lastName) - .InColumnValue("company_name", companyName) - .InColumnValue("title", title) - .InColumnValue("notes", contact.About) - .InColumnValue("is_company", isCompany) - .InColumnValue("industry", contact.Industry) - .InColumnValue("status_id", contact.StatusID) - .InColumnValue("company_id", companyID) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("create_on", TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn)) - .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn)) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("display_name", displayName) - .InColumnValue("is_shared", (int)contact.ShareType) - .InColumnValue("contact_type_id", contact.ContactTypeID) - .InColumnValue("currency", contact.Currency) - .Identity(1, 0, true)); - - contact.ID = contactID; + var itemToInsert = new DbContact + { + Id = 0, + FirstName = firstName, + LastName = lastName, + CompanyName = companyName, + Title = title, + Notes = contact.About, + IsCompany = isCompany, + Industry = contact.Industry, + StatusId = contact.StatusID, + CompanyId = companyID, + CreateBy = SecurityContext.CurrentAccount.ID, + CreateOn = TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn), + LastModifedOn = TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn), + LastModifedBy = SecurityContext.CurrentAccount.ID, + DisplayName = displayName, + IsShared = contact.ShareType, + ContactTypeId = contact.ContactTypeID, + Currency = contact.Currency + }; + + CRMDbContext.Contacts.Add(itemToInsert); + CRMDbContext.SaveChanges(); + + contact.ID = itemToInsert.Id; if (companyID > 0) - AddMemberInDb(contactID, companyID); + AddMemberInDb(contact.ID, companyID); - return contactID; + return contact.ID; } public Boolean IsExist(int contactID) { - return Db.ExecuteScalar("select exists(select 1 from crm_contact where tenant_id = @tid and id = @id)", - new { tid = TenantID, id = contactID }); + return Query(CRMDbContext.Contacts).Where(x => x.Id == contactID).Any(); } public Boolean CanDelete(int contactID) { - return Db.ExecuteScalar("select count(*) from crm_invoice where tenant_id = @tid and (contact_id = @id or consignee_id = @id)", - new { tid = TenantID, id = contactID }) == 0; + return !Query(CRMDbContext.Invoices).Where(x => x.ContactId == contactID || x.ConsigneeId == contactID).Any(); } public Dictionary CanDelete(int[] contactID) { var result = new Dictionary(); + if (contactID.Length == 0) return result; var contactIDs = contactID.Distinct().ToList(); - var contactIDsDBString = ""; - contactIDs.ForEach(id => contactIDsDBString += String.Format("{0},", id)); - contactIDsDBString = contactIDsDBString.TrimEnd(','); - - List hasInvoiceIDs; - var query = String.Format( - @"select distinct contact_id from crm_invoice where tenant_id = {0} and contact_id in ({1}) - union all - select distinct consignee_id from crm_invoice where tenant_id = {0} and consignee_id in ({1})", TenantID, contactIDsDBString); + List hasInvoiceIDs = Query(CRMDbContext.Invoices).Where(x => contactID.Contains(x.ContactId)) + .Distinct() + .Select(x => x.ContactId).Union( + Query(CRMDbContext.Invoices).Where(x => contactID.Contains(x.ConsigneeId)) + .Distinct() + .Select(x => x.ConsigneeId)).ToList(); - hasInvoiceIDs = Db.ExecuteList(query).ConvertAll(row => Convert.ToInt32(row[0])); foreach (var cid in contactIDs) { @@ -1399,40 +1537,40 @@ public virtual Contact GetByID(int contactID) public Contact GetByIDFromDb(int contactID) { - SqlQuery sqlQuery = GetContactSqlQuery(Exp.Eq("id", contactID)); - - var contacts = Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)); - - if (contacts.Count == 0) return null; - - return contacts[0]; + return ToContact(Query(CRMDbContext.Contacts) + .FirstOrDefault(x => x.Id == contactID)); } public List GetContacts(int[] contactID) { if (contactID == null || contactID.Length == 0) return new List(); - SqlQuery sqlQuery = GetContactSqlQuery(Exp.In("id", contactID)); - - return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)).FindAll(CRMSecurity.CanAccessTo); + return Query(CRMDbContext.Contacts) + .Where(x => contactID.Contains(x.Id)) + .ToList() + .ConvertAll(ToContact) + .FindAll(CRMSecurity.CanAccessTo); } public List GetRestrictedContacts(int[] contactID) { if (contactID == null || contactID.Length == 0) return new List(); - SqlQuery sqlQuery = GetContactSqlQuery(Exp.In("id", contactID)); - - return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)).FindAll(cont => !CRMSecurity.CanAccessTo(cont)); + return Query(CRMDbContext.Contacts) + .Where(x => contactID.Contains(x.Id)) + .ToList() + .ConvertAll(ToContact) + .FindAll(cont => !CRMSecurity.CanAccessTo(cont)); } public List GetRestrictedAndAccessedContacts(int[] contactID) { if (contactID == null || contactID.Length == 0) return new List(); - SqlQuery sqlQuery = GetContactSqlQuery(Exp.In("id", contactID)); - - return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContact(row)); + return Query(CRMDbContext.Contacts) + .Where(x => contactID.Contains(x.Id)) + .ToList() + .ConvertAll(ToContact); } public virtual List DeleteBatchContact(int[] contactID) @@ -1480,11 +1618,11 @@ public virtual Contact DeleteContact(int contactID) var person = contact as Person; if (person != null) { - FactoryIndexer.DeleteAsync(person); + FactoryIndexerContactsWrapper.DeleteAsync(person); } else { - FactoryIndexer.DeleteAsync(contact as Company); + FactoryIndexerContactsWrapper.DeleteAsync(contact as Company); } return contact; @@ -1509,46 +1647,75 @@ private void DeleteBatchContactsExecute(List contacts) var contactID = newContactID.ToArray(); var filesIDs = new object[0]; - using (var tx = Db.BeginTransaction()) - using (var tagdao = FilesIntegration.GetTagDao()) + var tx = CRMDbContext.Database.BeginTransaction(); + + var tagdao = FilesIntegration.TagDao(); + + var tagNames = Query(CRMDbContext.RelationshipEvent).Where(x => contactID.Contains(x.ContactId) && x.HaveFiles) + .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); + + if (0 < tagNames.Length) { - var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id").Where(Exp.In("contact_id", contactID) & Exp.Eq("have_files", true))).Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); - if (0 < tagNames.Length) - { - filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); - } + filesIDs = tagdao.GetTags(tagNames, TagType.System) + .Where(t => t.EntryType == FileEntryType.File) + .Select(t => t.EntryId) + .ToArray(); + } - Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", contactID) & Exp.In("entity_type", new[] { (int)EntityType.Contact, (int)EntityType.Person, (int)EntityType.Company }))); - Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("contact_id", contactID))); - Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", contactID) & Exp.Eq("entity_type", (int)EntityType.Contact))); + CRMDbContext.RemoveRange(Query(CRMDbContext.FieldValue) + .Where(x => contactID.Contains(x.EntityId)) + .Where(x => x.EntityType == EntityType.Contact || x.EntityType == EntityType.Person || x.EntityType == EntityType.Company) + ); - Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("contact_id", contactID))); - Db.ExecuteNonQuery(Update("crm_deal").Set("contact_id", 0).Where(Exp.In("contact_id", contactID))); + CRMDbContext.RemoveRange(Query(CRMDbContext.Tasks) + .Where(x => contactID.Contains(x.ContactId))); - if (companyID.Count > 0) - { - Db.ExecuteNonQuery(Update("crm_contact").Set("company_id", 0).Where(Exp.In("company_id", companyID))); - } - if (personsID.Count > 0) - { - RemoveRelativeInDb(null, EntityType.Person, personsID.ToArray()); - } - RemoveRelativeInDb(contactID, EntityType.Any, null); + CRMDbContext.RemoveRange(CRMDbContext.EntityTags + .Where(x => contactID.Contains(x.EntityId) && x.EntityType == EntityType.Contact)); - Db.ExecuteNonQuery(Delete("crm_contact_info").Where(Exp.In("contact_id", contactID))); - Db.ExecuteNonQuery(Delete("crm_contact").Where(Exp.In("id", contactID))); + CRMDbContext.RemoveRange(CRMDbContext.RelationshipEvent.Where(x => contactID.Contains(x.ContactId))); - tx.Commit(); + var dealToUpdate = CRMDbContext.Deals.Where(x => contactID.Contains(x.ContactId)).ToList(); + + dealToUpdate.ForEach(x => x.ContactId = 0); + + CRMDbContext.SaveChanges(); + + if (companyID.Count > 0) + { + var itemToUpdate = Query(CRMDbContext.Contacts).Where(x => companyID.Contains(x.CompanyId)).ToList(); + + itemToUpdate.ForEach(x => x.CompanyId = 0); + + CRMDbContext.SaveChanges(); } - contacts.ForEach(contact => CoreContext.AuthorizationManager.RemoveAllAces(contact)); + if (personsID.Count > 0) + { + RemoveRelativeInDb(null, EntityType.Person, personsID.ToArray()); + } - using (var filedao = FilesIntegration.GetFileDao()) + RemoveRelativeInDb(contactID, EntityType.Any, null); + + CRMDbContext.RemoveRange(Query(CRMDbContext.ContactsInfo).Where(x => contactID.Contains(x.ContactId))); + + CRMDbContext.RemoveRange(contactID.ToList().ConvertAll(x => new DbContact { - foreach (var filesID in filesIDs) - { - filedao.DeleteFile(filesID); - } + Id = x, + TenantId = TenantID + })); + + CRMDbContext.SaveChanges(); + + tx.Commit(); + + contacts.ForEach(contact => AuthorizationManager.RemoveAllAces(contact)); + + var filedao = FilesIntegration.GetFileDao(); + + foreach (var filesID in filesIDs) + { + filedao.DeleteFile(filesID); } //todo: remove indexes @@ -1556,7 +1723,6 @@ private void DeleteBatchContactsExecute(List contacts) private void MergeContactInfo(Contact fromContact, Contact toContact) { - if ((toContact is Person) && (fromContact is Person)) { var fromPeople = (Person)fromContact; @@ -1598,282 +1764,262 @@ public void MergeDublicate(int fromContactID, int toContactID) if (fromContact == null || toContact == null) throw new ArgumentException(); - using (var tx = Db.BeginTransaction()) + using (var tx = CRMDbContext.Database.BeginTransaction()) { - ISqlInstruction q = Update("crm_task") - .Set("contact_id", toContactID) - .Where(Exp.Eq("contact_id", fromContactID)); - Db.ExecuteNonQuery(q); + var taskToUpdate = Query(CRMDbContext.Tasks) + .Where(x => x.ContactId == fromContactID) + .ToList(); + + taskToUpdate.ForEach(x => x.ContactId = toContactID); + + CRMDbContext.UpdateRange(taskToUpdate); + CRMDbContext.SaveChanges(); // crm_entity_contact - q = new SqlQuery("crm_entity_contact l") - .From("crm_entity_contact r") - .Select("l.entity_id", "l.entity_type", "l.contact_id") - .Where(Exp.EqColumns("l.entity_id", "r.entity_id") & Exp.EqColumns("l.entity_type", "r.entity_type")) - .Where("l.contact_id", fromContactID) - .Where("r.contact_id", toContactID); - Db.ExecuteList(q) - .ForEach(row => - Db.ExecuteNonQuery(new SqlDelete("crm_entity_contact").Where("entity_id", row[0]).Where("entity_type", row[1]).Where("contact_id", row[2])) - ); - - q = new SqlUpdate("crm_entity_contact") - .Set("contact_id", toContactID) - .Where("contact_id", fromContactID); - Db.ExecuteNonQuery(q); + CRMDbContext.EntityContact.RemoveRange( + CRMDbContext.EntityContact + .Join(CRMDbContext.EntityContact, + x => new { x.EntityId, x.EntityType }, + y => new { y.EntityId, y.EntityType }, + (x, y) => new { x, y }) + .Where(x => x.x.ContactId == fromContactID && x.y.ContactId == toContactID) + .Select(x => x.x)); + + var entityContactToUpdate = CRMDbContext.EntityContact.Where(x => x.ContactId == fromContactID).ToList(); + entityContactToUpdate.ForEach(x => x.ContactId = toContactID); + + CRMDbContext.UpdateRange(entityContactToUpdate); + CRMDbContext.SaveChanges(); // crm_deal - q = Update("crm_deal") - .Set("contact_id", toContactID) - .Where("contact_id", fromContactID); - Db.ExecuteNonQuery(q); + var dealsToUpdate = Query(CRMDbContext.Deals).Where(x => x.ContactId == fromContactID).ToList(); + dealsToUpdate.ForEach(x => x.ContactId = toContactID); + + CRMDbContext.UpdateRange(dealsToUpdate); + CRMDbContext.SaveChanges(); // crm_invoice - q = Update("crm_invoice") - .Set("contact_id", toContactID) - .Where("contact_id", fromContactID); - Db.ExecuteNonQuery(q); + var invoicesToUpdate = Query(CRMDbContext.Invoices).Where(x => x.ContactId == fromContactID).ToList(); + invoicesToUpdate.ForEach(x => x.ContactId = toContactID); + + CRMDbContext.UpdateRange(invoicesToUpdate); + CRMDbContext.SaveChanges(); // crm_projects - q = new SqlQuery("crm_projects p") - .Select("p.project_id") - .From("crm_projects r") - .Where(Exp.EqColumns("p.project_id", "r.project_id")) - .Where("p.contact_id", fromContactID) - .Where("r.contact_id", toContactID); - var dublicateProjectID = Db.ExecuteList(q).ConvertAll(row => row[0]); + var dublicateProjectID = Query(CRMDbContext.Projects) + .Join(CRMDbContext.Projects, + x => x.ProjectId, + y => y.ProjectId, + (x, y) => new { x, y }) + .Where(x => x.x.ContactId == fromContactID && x.y.ContactId == toContactID) + .Select(x => x.x.ProjectId); - q = new SqlDelete("crm_projects").Where(Exp.Eq("contact_id", fromContactID) & Exp.In("project_id", dublicateProjectID)); - Db.ExecuteNonQuery(q); + CRMDbContext.RemoveRange(Query(CRMDbContext.Projects) + .Where(x => x.ContactId == fromContactID && dublicateProjectID.Contains(x.ProjectId))); - q = new SqlUpdate("crm_projects").Set("contact_id", toContactID).Where("contact_id", fromContactID); - Db.ExecuteNonQuery(q); + var projectsToUpdate = Query(CRMDbContext.Projects).Where(x => x.ContactId == fromContactID).ToList(); + projectsToUpdate.ForEach(x => x.ContactId = toContactID); + + CRMDbContext.UpdateRange(projectsToUpdate); + CRMDbContext.SaveChanges(); // crm_relationship_event - q = Update("crm_relationship_event") - .Set("contact_id", toContactID) - .Where("contact_id", fromContactID); - Db.ExecuteNonQuery(q); + var relationshipEventToUpdate = Query(CRMDbContext.RelationshipEvent).Where(x => x.ContactId == fromContactID).ToList(); + relationshipEventToUpdate.ForEach(x => x.ContactId = toContactID); + + CRMDbContext.UpdateRange(relationshipEventToUpdate); + CRMDbContext.SaveChanges(); // crm_entity_tag - q = new SqlQuery("crm_entity_tag l") - .Select("l.tag_id") - .From("crm_entity_tag r") - .Where(Exp.EqColumns("l.tag_id", "r.tag_id") & Exp.EqColumns("l.entity_type", "r.entity_type")) - .Where("l.entity_id", fromContactID) - .Where("r.entity_id", toContactID); - var dublicateTagsID = Db.ExecuteList(q).ConvertAll(row => row[0]); + var dublicateTagsID = CRMDbContext.EntityTags.Join(CRMDbContext.EntityTags, + x => new { x.TagId, x.EntityType }, + y => new { y.TagId, y.EntityType }, + (x, y) => new { x, y } + ) + .Where(x => x.x.EntityId == fromContactID && x.y.EntityId == toContactID) + .Select(x => x.x.TagId).ToList(); + + CRMDbContext.EntityTags.Where(x => x.EntityId == fromContactID && + x.EntityType == EntityType.Contact && + dublicateTagsID.Contains(x.TagId)); + - q = new SqlDelete("crm_entity_tag").Where(Exp.Eq("entity_id", fromContactID) & Exp.Eq("entity_type", (int)EntityType.Contact) & Exp.In("tag_id", dublicateTagsID)); - Db.ExecuteNonQuery(q); + var entityTagToUpdate = CRMDbContext.EntityTags.Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact).ToList(); - q = new SqlUpdate("crm_entity_tag").Set("entity_id", toContactID).Where("entity_id", fromContactID).Where("entity_type", (int)EntityType.Contact); - Db.ExecuteNonQuery(q); + entityTagToUpdate.ForEach(x => x.EntityId = toContactID); + + CRMDbContext.UpdateRange(entityTagToUpdate); + CRMDbContext.SaveChanges(); // crm_field_value - q = Query("crm_field_value l") - .From("crm_field_value r") - .Select("l.field_id") - .Where(Exp.EqColumns("l.tenant_id", "r.tenant_id") & Exp.EqColumns("l.field_id", "r.field_id") & Exp.EqColumns("l.entity_type", "r.entity_type")) - .Where("l.entity_id", fromContactID) - .Where("r.entity_id", toContactID); - var dublicateCustomFieldValueID = Db.ExecuteList(q).ConvertAll(row => row[0]); - - q = Delete("crm_field_value") - .Where("entity_id", fromContactID) - .Where(Exp.In("entity_type", new[] { (int)EntityType.Contact, (int)EntityType.Person, (int)EntityType.Company })) - .Where(Exp.In("field_id", dublicateCustomFieldValueID)); - Db.ExecuteNonQuery(q); - - q = Update("crm_field_value") - .Set("entity_id", toContactID) - .Where("entity_id", fromContactID) - .Where("entity_type", (int)EntityType.Contact); - Db.ExecuteNonQuery(q); + var dublicateCustomFieldValueID = Query(CRMDbContext.FieldValue) + .Join(CRMDbContext.FieldValue, + x => new { x.TenantId, x.FieldId, x.EntityType }, + y => new { y.TenantId, y.FieldId, y.EntityType }, + (x, y) => new { x, y }) + .Where(x => x.x.EntityId == fromContactID && x.y.EntityId == toContactID) + .Select(x => x.x.FieldId); + + CRMDbContext.RemoveRange(CRMDbContext.FieldValue.Where(x => x.EntityId == fromContactID && + (new[] { EntityType.Contact, EntityType.Person, EntityType.Company }).Contains(x.EntityType) && + dublicateCustomFieldValueID.Contains(x.FieldId))); + var fieldValueToUpdate = Query(CRMDbContext.FieldValue) + .Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact).ToList(); + fieldValueToUpdate.ForEach(x => x.EntityId = toContactID); + + CRMDbContext.UpdateRange(fieldValueToUpdate); + CRMDbContext.SaveChanges(); // crm_contact_info + var dublicatePrimaryContactInfoID = Query(CRMDbContext.ContactsInfo) + .Join(CRMDbContext.ContactsInfo, + x => new { x.TenantId, x.Type, x.Category, x.IsPrimary }, + y => new { y.TenantId, y.Type, y.Category, y.IsPrimary }, + (x, y) => new { x, y }) + .Where(x => x.x.IsPrimary && + x.x.Data != x.y.Data && + x.x.ContactId == fromContactID && + x.y.ContactId == toContactID) + .Select(x => x.x.Id); + + var contactInfosToUpdate = Query(CRMDbContext.ContactsInfo) + .Where(x => x.ContactId == fromContactID && dublicatePrimaryContactInfoID.Contains(x.Id)) + .ToList(); + + contactInfosToUpdate.ForEach(x => x.IsPrimary = false); + + CRMDbContext.UpdateRange(fieldValueToUpdate); + CRMDbContext.SaveChanges(); + + var dublicateContactInfoID = Query(CRMDbContext.ContactsInfo) + .Join(CRMDbContext.ContactsInfo, + x => new { x.TenantId, x.Type, x.IsPrimary, x.Category, x.Data }, + y => new { y.TenantId, y.Type, y.IsPrimary, y.Category, y.Data }, + (x, y) => new { x, y }) + .Where(x => x.x.ContactId == fromContactID && x.y.ContactId == toContactID) + .Select(x => x.x.Id) + .ToList(); + + CRMDbContext.ContactsInfo.RemoveRange(dublicateContactInfoID.ConvertAll(x => new DbContactInfo + { + Id = x, + ContactId = fromContactID, + TenantId = TenantID + })); - q = Query("crm_contact_info l") - .From("crm_contact_info r") - .Select("l.id") - .Where(Exp.Eq("l.is_primary", true)) - .Where(Exp.Eq("r.is_primary", true)) - .Where(Exp.EqColumns("l.tenant_id", "r.tenant_id")) - .Where(Exp.EqColumns("l.type", "r.type")) - .Where(Exp.EqColumns("l.category", "r.category")) - .Where(!Exp.EqColumns("l.data", "r.data")) - .Where("l.contact_id", fromContactID) - .Where("r.contact_id", toContactID); - var dublicatePrimaryContactInfoID = Db.ExecuteList(q).ConvertAll(row => row[0]); - - q = Update("crm_contact_info") - .Set("is_primary", false) - .Where("contact_id", fromContactID) - .Where(Exp.In("id", dublicatePrimaryContactInfoID)); - Db.ExecuteNonQuery(q); - - q = Query("crm_contact_info l") - .From("crm_contact_info r") - .Select("l.id") - .Where(Exp.EqColumns("l.tenant_id", "r.tenant_id")) - .Where(Exp.EqColumns("l.type", "r.type")) - .Where(Exp.EqColumns("l.is_primary", "r.is_primary")) - .Where(Exp.EqColumns("l.category", "r.category")) - .Where(Exp.EqColumns("l.data", "r.data")) - .Where("l.contact_id", fromContactID) - .Where("r.contact_id", toContactID); - var dublicateContactInfoID = Db.ExecuteList(q).ConvertAll(row => row[0]); - - q = Delete("crm_contact_info") - .Where("contact_id", fromContactID) - .Where(Exp.In("id", dublicateContactInfoID)); - Db.ExecuteNonQuery(q); - - - q = Update("crm_contact_info") - .Set("contact_id", toContactID) - .Where("contact_id", fromContactID); - Db.ExecuteNonQuery(q); + CRMDbContext.SaveChanges(); + var contactInfoToUpdate = Query(CRMDbContext.ContactsInfo).Where(x => x.ContactId == fromContactID).ToList(); + contactInfoToUpdate.ForEach(x => x.ContactId = toContactID); + + CRMDbContext.UpdateRange(contactInfoToUpdate); + CRMDbContext.SaveChanges(); MergeContactInfo(fromContact, toContact); // crm_contact if ((fromContact is Company) && (toContact is Company)) { - q = Update("crm_contact") - .Set("company_id", toContactID) - .Where("company_id", fromContactID); - Db.ExecuteNonQuery(q); + var contactsToUpdate = Query(CRMDbContext.Contacts).Where(x => x.CompanyId == fromContactID).ToList(); + + contactsToUpdate.ForEach(x => x.CompanyId = toContactID); + + CRMDbContext.UpdateRange(contactsToUpdate); + CRMDbContext.SaveChanges(); + } - q = Delete("crm_contact").Where("id", fromContactID); - Db.ExecuteNonQuery(q); + CRMDbContext.Contacts.Remove(new DbContact + { + Id = fromContactID + }); + + CRMDbContext.SaveChanges(); tx.Commit(); } - CoreContext.AuthorizationManager.RemoveAllAces(fromContact); + AuthorizationManager.RemoveAllAces(fromContact); } public List GetContactIDsByCompanyIds(List companyIDs) { - return Db.ExecuteList(Query("crm_contact") - .Select("id") + return Query(CRMDbContext.Contacts) + .Where(x => companyIDs.Contains(x.CompanyId) && !x.IsCompany) + .Select(x => x.Id) .Distinct() - .Where(Exp.In("company_id", companyIDs) & Exp.Eq("is_company", false))) - .ConvertAll(row => Convert.ToInt32(row[0])); + .ToList(); } public List GetContactIDsByContactInfo(ContactInfoType infoType, String data, int? category, bool? isPrimary) { - List ids; - var q = Query("crm_contact_info") - .Select("contact_id") - .Where(Exp.Eq("type", (int)infoType)); + var q = Query(CRMDbContext.ContactsInfo) + .Where(x => x.Type == infoType); if (!string.IsNullOrWhiteSpace(data)) { - q = q.Where(Exp.Like("data", data, SqlLike.AnyWhere)); + q = q.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Data, "%" + data + "%")); } if (category.HasValue) { - q = q.Where("category", category.Value); + q = q.Where(x => x.Category == category.Value); } + if (isPrimary.HasValue) { - q = q.Where("is_primary", isPrimary.Value); + q = q.Where(x => x.IsPrimary == isPrimary.Value); } - ids = Db.ExecuteList(q).ConvertAll(row => (int)row[0]); - return ids; + return q.Select(x => x.ContactId).ToList(); } - protected static Contact ToContact(object[] row) + protected Contact ToContact(DbContact dbContact) { + if (dbContact == null) return null; + Contact contact; - var isCompany = Convert.ToBoolean(row[6]); + var isCompany = dbContact.IsCompany; if (isCompany) contact = new Company - { - CompanyName = Convert.ToString(row[3]) - }; + { + CompanyName = dbContact.CompanyName + }; else contact = new Person - { - FirstName = Convert.ToString(row[1]), - LastName = Convert.ToString(row[2]), - JobTitle = Convert.ToString(row[4]), - CompanyID = Convert.ToInt32(row[9]) - }; - - contact.ID = Convert.ToInt32(row[0]); - contact.About = Convert.ToString(row[5]); - contact.Industry = Convert.ToString(row[7]); - contact.StatusID = Convert.ToInt32(row[8]); - contact.CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[10])); - contact.CreateBy = ToGuid(row[11]); - contact.ContactTypeID = Convert.ToInt32(row[14]); - contact.Currency = Convert.ToString(row[15]); - - if (row[13] == null) + { + FirstName = dbContact.FirstName, + LastName = dbContact.LastName, + JobTitle = dbContact.Title, + CompanyID = dbContact.CompanyId + }; + + contact.ID = dbContact.Id; + contact.About = dbContact.Notes; + contact.Industry = dbContact.Industry; + contact.StatusID = dbContact.StatusId; + contact.CreateOn = TenantUtil.DateTimeFromUtc(dbContact.CreateOn); + contact.CreateBy = dbContact.CreateBy; + contact.ContactTypeID = dbContact.ContactTypeId; + contact.Currency = dbContact.Currency; + + if (dbContact.IsShared == null) { var accessSubjectToContact = CRMSecurity.GetAccessSubjectTo(contact); contact.ShareType = !accessSubjectToContact.Any() ? ShareType.ReadWrite : ShareType.None; } else - contact.ShareType = (ShareType)(Convert.ToInt32(row[13])); + { + contact.ShareType = (ShareType)(Convert.ToInt32(dbContact.IsShared)); + } return contact; } - private static string[] GetContactColumnsTable(String alias) - { - if (!String.IsNullOrEmpty(alias)) - alias = alias + "."; - - var result = new List - { - "id", - "first_name", - "last_name", - "company_name", - "title", - "notes", - "is_company", - "industry", - "status_id", - "company_id", - "create_on", - "create_by", - "display_name", - "is_shared", - "contact_type_id", - "currency" - }; - - return string.IsNullOrEmpty(alias) ? result.ToArray() : result.ConvertAll(item => string.Concat(alias, item)).ToArray(); - } - - private SqlQuery GetContactSqlQuery(Exp where) - { - var sqlQuery = Query("crm_contact").UseIndex("company_id"); - - sqlQuery.Select(GetContactColumnsTable(String.Empty)); - - if (where != null) - sqlQuery.Where(where); - - return sqlQuery; - - } - - public void ReassignContactsResponsible(Guid fromUserId, Guid toUserId) { var ids = CRMSecurity.GetContactsIdByManager(fromUserId).ToList(); @@ -1903,10 +2049,17 @@ public void ReassignContactsResponsible(Guid fromUserId, Guid toUserId) /// public void SetContactCreationDate(int contactId, DateTime creationDate) { - Db.ExecuteNonQuery( - Update("crm_contact") - .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) - .Where(Exp.Eq("id", contactId))); + var itemToUpdate = new DbContact + { + Id = contactId, + TenantId = TenantID, + CreateOn = TenantUtil.DateTimeToUtc(creationDate) + }; + + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.CreateOn).IsModified = true; + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } @@ -1918,10 +2071,18 @@ public void SetContactCreationDate(int contactId, DateTime creationDate) /// public void SetContactLastModifedDate(int contactId, DateTime lastModifedDate) { - Db.ExecuteNonQuery( - Update("crm_contact") - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) - .Where(Exp.Eq("id", contactId))); + + var itemToUpdate = new DbContact + { + Id = contactId, + TenantId = TenantID, + LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate) + }; + + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.LastModifedOn).IsModified = true; + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 7dabffe58fd..f77176798fd 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -23,34 +23,39 @@ * */ - -#region Import - -using System; -using System.Collections.Generic; -using System.Linq; using ASC.Collections; -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; +using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; -using ASC.Common.Data; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; -using ASC.CRM.Core.Enums; - -#endregion +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; namespace ASC.CRM.Core.Dao { public class CachedContactInfo : ContactInfoDao { - private readonly HttpRequestDictionary _contactInfoCache = new HttpRequestDictionary("crm_contact_info"); - - public CachedContactInfo(int tenantID) - : base(tenantID) + private readonly HttpRequestDictionary _contactInfoCache; + + public CachedContactInfo( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + TenantUtil tenantUtil, + IHttpContextAccessor httpContextAccessor) + : base( + dbContextManager, + tenantManager, + securityContext, + tenantUtil) { - + _contactInfoCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact_info"); } public override ContactInfo GetByID(int id) @@ -94,35 +99,56 @@ public override int Update(ContactInfo contactInfo) public class ContactInfoDao : AbstractDao { - public ContactInfoDao(int tenantID) - : base(tenantID) + public ContactInfoDao( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + TenantUtil tenantUtil) + : base(dbContextManager, + tenantManager, + securityContext) { - + TenantUtil = tenantUtil; } + TenantUtil TenantUtil { get; } + FactoryIndexer emailWrapperIndexer; + FactoryIndexer infoWrapperIndexer; + public virtual ContactInfo GetByID(int id) { - var sqlResult = Db.ExecuteList(GetSqlQuery(Exp.Eq("id", id))).ConvertAll(row => ToContactInfo(row)); - - if (sqlResult.Count == 0) return null; - - return sqlResult[0]; + return ToContactInfo(CRMDbContext.ContactsInfo.SingleOrDefault(x => x.Id == id)); } public virtual void Delete(int id) { - Db.ExecuteNonQuery(Delete("crm_contact_info").Where(Exp.Eq("id", id))); - FactoryIndexer.DeleteAsync(r => r.Where(a => a.Id, id)); + var itemToDelete = new DbContactInfo + { + Id = id + }; + + CRMDbContext.ContactsInfo.Remove(itemToDelete); + CRMDbContext.SaveChanges(); + + infoWrapperIndexer.DeleteAsync(r => r.Where(a => a.Id, id)); + } public virtual void DeleteByContact(int contactID) { if (contactID <= 0) return; - Db.ExecuteNonQuery(Delete("crm_contact_info").Where(Exp.Eq("contact_id", contactID))); - FactoryIndexer.DeleteAsync(r => r.Where(a => a.ContactId, contactID)); + + CRMDbContext.RemoveRange(Query(CRMDbContext.ContactsInfo) + .Where(x => x.ContactId == contactID)); + + CRMDbContext.SaveChanges(); + + infoWrapperIndexer.DeleteAsync(r => r.Where(a => a.ContactId, contactID)); var infos = GetList(contactID, ContactInfoType.Email, null, null); - FactoryIndexer.Update(new EmailWrapper { Id = contactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); + + emailWrapperIndexer.Update(new EmailWrapper { Id = contactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); + } public virtual int Update(ContactInfo contactInfo) @@ -133,10 +159,10 @@ public virtual int Update(ContactInfo contactInfo) { var infos = GetList(contactInfo.ContactID, ContactInfoType.Email, null, null); - FactoryIndexer.Update(new EmailWrapper { Id = contactInfo.ContactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); + emailWrapperIndexer.Update(new EmailWrapper { Id = contactInfo.ContactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); } - FactoryIndexer.UpdateAsync(contactInfo); + infoWrapperIndexer.UpdateAsync(contactInfo); return result; } @@ -146,16 +172,23 @@ private int UpdateInDb(ContactInfo contactInfo) if (contactInfo == null || contactInfo.ID == 0 || contactInfo.ContactID == 0) throw new ArgumentException(); - Db.ExecuteNonQuery(Update("crm_contact_info") - .Where("id", contactInfo.ID) - .Set("data", contactInfo.Data) - .Set("category", contactInfo.Category) - .Set("is_primary", contactInfo.IsPrimary) - .Set("contact_id", contactInfo.ContactID) - .Set("type", (int)contactInfo.InfoType) - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - ); + var itemToUpdate = new DbContactInfo + { + Id = contactInfo.ID, + Data = contactInfo.Data, + Category = contactInfo.Category, + IsPrimary = contactInfo.IsPrimary, + ContactId = contactInfo.ContactID, + Type = contactInfo.InfoType, + LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.ContactsInfo.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); + return contactInfo.ID; } @@ -166,11 +199,11 @@ public int Save(ContactInfo contactInfo) contactInfo.ID = id; - FactoryIndexer.IndexAsync(contactInfo); + infoWrapperIndexer.IndexAsync(contactInfo); if (contactInfo.InfoType == ContactInfoType.Email) { - FactoryIndexer.Index(new EmailWrapper + emailWrapperIndexer.Index(new EmailWrapper { Id = contactInfo.ContactID, TenantId = TenantID, @@ -186,16 +219,25 @@ public int Save(ContactInfo contactInfo) private int SaveInDb(ContactInfo contactInfo) { - return Db.ExecuteScalar(Insert("crm_contact_info") - .InColumnValue("id", 0) - .InColumnValue("data", contactInfo.Data) - .InColumnValue("category", contactInfo.Category) - .InColumnValue("is_primary", contactInfo.IsPrimary) - .InColumnValue("contact_id", contactInfo.ContactID) - .InColumnValue("type", (int)contactInfo.InfoType) - .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); + var itemToInsert = new DbContactInfo + { + Data = contactInfo.Data, + Category = contactInfo.Category, + IsPrimary = contactInfo.IsPrimary, + ContactId = contactInfo.ContactID, + Type = contactInfo.InfoType, + LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + + }; + + CRMDbContext.Add(itemToInsert); + + CRMDbContext.SaveChanges(); + + return itemToInsert.Id; + } public List GetListData(int contactID, ContactInfoType infoType) @@ -210,131 +252,105 @@ public List GetAll() public List GetAll(int[] contactID) { - if (contactID == null || contactID.Length == 0) return null; - SqlQuery sqlQuery = GetSqlQuery(null); - - sqlQuery.Where(Exp.In("contact_id", contactID)); - - return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContactInfo(row)); + return Query(CRMDbContext.ContactsInfo) + .Where(x => contactID.Contains(x.ContactId)) + .ToList().ConvertAll(ToContactInfo); } public virtual List GetList(int contactID, ContactInfoType? infoType, int? categoryID, bool? isPrimary) { - SqlQuery sqlQuery = GetSqlQuery(null); + var items = Query(CRMDbContext.ContactsInfo); if (contactID > 0) - sqlQuery.Where(Exp.Eq("contact_id", contactID)); + items = items.Where(x => x.ContactId == contactID); if (infoType.HasValue) - sqlQuery.Where(Exp.Eq("type", infoType.Value)); + items = items.Where(x => x.Type == infoType.Value); if (categoryID.HasValue) - sqlQuery.Where(Exp.Eq("category", categoryID.Value)); + items = items.Where(x => x.Category == categoryID.Value); if (isPrimary.HasValue) - sqlQuery.Where(Exp.Eq("is_primary", isPrimary.Value)); - - sqlQuery.OrderBy("type", true); - // sqlQuery.OrderBy("category", true); - // sqlQuery.OrderBy("is_primary", true); + items = items.Where(x => x.IsPrimary == isPrimary.Value); + items = items.OrderBy(x => x.Type); - return Db.ExecuteList(sqlQuery).ConvertAll(row => ToContactInfo(row)); + return items.ToList().ConvertAll(row => ToContactInfo(row)); } public int[] UpdateList(List items, Contact contact = null) { - if (items == null || items.Count == 0) return null; var result = new List(); - using (var tx = Db.BeginTransaction(true)) - { - foreach (var contactInfo in items) - result.Add(UpdateInDb(contactInfo)); - - - tx.Commit(); - } - + var tx = CRMDbContext.Database.BeginTransaction(); + + foreach (var contactInfo in items) + result.Add(UpdateInDb(contactInfo)); + + tx.Commit(); + if (contact != null) { - FactoryIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + emailWrapperIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) { - FactoryIndexer.IndexAsync(item); + infoWrapperIndexer.IndexAsync(item); } } return result.ToArray(); } - - - public int[] SaveList(List items, Contact contact = null) { if (items == null || items.Count == 0) return null; var result = new List(); + + var tx = CRMDbContext.Database.BeginTransaction(); - using (var tx = Db.BeginTransaction(true)) + foreach (var contactInfo in items) { - foreach (var contactInfo in items) - { - var contactInfoId = SaveInDb(contactInfo); - contactInfo.ID = contactInfoId; - result.Add(contactInfoId); - } - - - tx.Commit(); + var contactInfoId = SaveInDb(contactInfo); + contactInfo.ID = contactInfoId; + result.Add(contactInfoId); } + tx.Commit(); + if (contact != null) { - FactoryIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + emailWrapperIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) { - FactoryIndexer.IndexAsync(item); + infoWrapperIndexer.IndexAsync(item); } + } return result.ToArray(); } - protected static ContactInfo ToContactInfo(object[] row) + protected static ContactInfo ToContactInfo(DbContactInfo dbContactInfo) { + if (dbContactInfo == null) return null; + return new ContactInfo { - ID = Convert.ToInt32(row[0]), - Category = Convert.ToInt32(row[1]), - Data = row[2].ToString(), - InfoType = (ContactInfoType)Convert.ToInt32(row[3]), - IsPrimary = Convert.ToBoolean(row[4]), - ContactID = Convert.ToInt32(row[5]) + ID = dbContactInfo.Id, + Category = dbContactInfo.Category, + ContactID = dbContactInfo.ContactId, + Data = dbContactInfo.Data, + InfoType = dbContactInfo.Type, + IsPrimary = dbContactInfo.IsPrimary }; } - - private SqlQuery GetSqlQuery(Exp where) - { - var sqlQuery = Query("crm_contact_info") - .Select("id", - "category", - "data", - "type", - "is_primary", - "contact_id"); - - if (where != null) - sqlQuery.Where(where); - - return sqlQuery; - - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 5c34373112f..c2751af60ee 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -35,8 +35,7 @@ namespace ASC.CRM.Core.Dao { public class CurrencyInfoDao : AbstractDao { - - + public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext): diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 8bd7e01347a..9f46425e35e 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -47,7 +47,7 @@ public CustomFieldDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - TenantUtil tenantUtil + TenantUtil tenantUtil ) : base(dbContextManager, tenantManager, @@ -90,7 +90,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, throw new ArgumentException(); fieldValue = fieldValue.Trim(); - + var itemToDelete = Query(CRMDbContext.FieldValue) .Where(x => x.EntityId == entityID && x.EntityType == entityType && x.FieldId == fieldID); @@ -100,17 +100,22 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, if (!String.IsNullOrEmpty(fieldValue)) { var lastModifiedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); - - var id = Db.ExecuteScalar( - Insert("crm_field_value") - .InColumnValue("id", 0) - .InColumnValue("entity_id", entityID) - .InColumnValue("value", fieldValue) - .InColumnValue("field_id", fieldID) - .InColumnValue("entity_type", (int)entityType) - .InColumnValue("last_modifed_on", lastModifiedOn) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); + + var dbFieldValue = new DbFieldValue + { + EntityId = entityID, + Value = fieldValue, + FieldId = fieldID, + EntityType = entityType, + LastModifedOn = lastModifiedOn, + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.Add(dbFieldValue); + CRMDbContext.SaveChanges(); + + var id = dbFieldValue.Id; FactoryIndexer.IndexAsync(new FieldsWrapper { @@ -225,14 +230,14 @@ public int CreateField(EntityType entityType, String label, CustomFieldType cust var sortOrder = Query(CRMDbContext.FieldDescription).Select(x => x.SortOrder).Max() + 1; - var itemToInsert = new DbFieldDescription + var itemToInsert = new DbFieldDescription { - Label = label, - Type = customFieldType, - Mask = resultMask, - SortOrder = sortOrder, - EntityType = entityType, - TenantId = TenantID + Label = label, + Type = customFieldType, + Mask = resultMask, + SortOrder = sortOrder, + EntityType = entityType, + TenantId = TenantID }; CRMDbContext.FieldDescription.Add(itemToInsert); @@ -244,32 +249,36 @@ public int CreateField(EntityType entityType, String label, CustomFieldType cust public String GetValue(EntityType entityType, int entityID, int fieldID) { + var sqlQuery = Query(CRMDbContext.FieldValue).Where(x => x.FieldId == fieldID && x.EntityId == entityID); - Query(CRMDbContext.FieldValue).Where(x => x.FieldId == fieldID && x.EntityId == entityID); - - - var sqlQuery = Query("crm_field_value") - .Select("value") - .Where(Exp.Eq("field_id", fieldID) - & BuildEntityTypeConditions(entityType, "entity_type") - & Exp.Eq("entity_id", entityID)); + if (entityType == EntityType.Company || entityType == EntityType.Person) + { + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType || x.EntityType == EntityType.Contact); + } + else + { + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType); + } - return Db.ExecuteScalar(sqlQuery); + return sqlQuery.Select(x => x.Value).FirstOrDefault(); } public List GetEntityIds(EntityType entityType, int fieldID, String fieldValue) { + var sqlQuery = Query(CRMDbContext.FieldValue) + .Where(x => x.FieldId == fieldID && String.Compare(x.Value, fieldValue, true) == 0); - Query(CRMDbContext.FieldValue).Where(x => x.FieldId == fieldID && String.Compare(x.Value, fieldValue, true) == 0); - + if (entityType == EntityType.Company || entityType == EntityType.Person) + { + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType || x.EntityType == EntityType.Contact); + } + else + { + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType); + } - var sqlQuery = Query("crm_field_value") - .Select("entity_id") - .Where(Exp.Eq("field_id", fieldID) - & BuildEntityTypeConditions(entityType, "entity_type") - & Exp.Eq("value", fieldValue)); - return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToInt32(row[0])); + return sqlQuery.Select(x => x.EntityId).ToList(); } public bool IsExist(int id) @@ -279,14 +288,23 @@ public bool IsExist(int id) public int GetFieldId(EntityType entityType, String label, CustomFieldType customFieldType) { - var result = Db.ExecuteList(GetFieldDescriptionSqlQuery( - Exp.Eq("type", (int)customFieldType) - & BuildEntityTypeConditions(entityType, "entity_type") - & Exp.Eq("label", label))).ConvertAll(row => ToCustomField(row)); + var sqlQuery = Query(CRMDbContext.FieldDescription).Where(x => x.Type == customFieldType && x.Label == label); - if (result.Count == 0) return 0; + if (entityType == EntityType.Company || entityType == EntityType.Person) + { + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType || x.EntityType == EntityType.Contact); + } + else + { + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType); + } - else return result[0].ID; + + var result = sqlQuery.FirstOrDefault(); + + if (result == null) return 0; + + return result.Id; } public void EditItem(CustomField customField) @@ -300,12 +318,10 @@ public void EditItem(CustomField customField) { var resultMask = ""; - var row = Db.ExecuteList(Query("crm_field_description") - .Where(Exp.Eq("id", customField.ID)) - .Select("type", "mask")).FirstOrDefault(); + var row = Query(CRMDbContext.FieldDescription).Where(x => x.Id == customField.ID).Select(x => new { x.Type, x.Mask }).Single(); - var fieldType = (CustomFieldType)Convert.ToInt32(row[0]); - var oldMask = Convert.ToString(row[1]); + var fieldType = row.Type; + var oldMask = row.Mask; if (fieldType == CustomFieldType.SelectBox) { @@ -345,23 +361,27 @@ public void EditItem(CustomField customField) throw ex; } - Db.ExecuteNonQuery( - Update("crm_field_description") - .Set("label", customField.Label) - .Set("mask", customField.Mask) - .Where(Exp.Eq("id", customField.ID))); + var itemToUpdate = Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); + + itemToUpdate.Label = customField.Label; + itemToUpdate.Mask = customField.Mask; + + CRMDbContext.Update(itemToUpdate); + CRMDbContext.SaveChanges(); + } else { var resultMask = GetValidMask(customField.FieldType, customField.Mask); - - Db.ExecuteNonQuery( - Update("crm_field_description") - .Set("label", customField.Label) - .Set("type", (int)customField.FieldType) - .Set("mask", resultMask) - .Where(Exp.Eq("id", customField.ID))); - + + var itemToUpdate = Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); + + itemToUpdate.Label = customField.Label; + itemToUpdate.Type = customField.FieldType; + itemToUpdate.Mask = customField.Mask; + + CRMDbContext.Update(itemToUpdate); + CRMDbContext.SaveChanges(); } } @@ -390,17 +410,24 @@ public String GetContactLinkCountJSON(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query("crm_field_description tblFD") - .Select("count(tblFV.field_id)") - .LeftOuterJoin("crm_field_value tblFV", Exp.EqColumns("tblFD.id", "tblFV.field_id")) - .OrderBy("tblFD.sort_order", true) - .GroupBy("tblFD.id"); + var sqlQuery = Query(CRMDbContext.FieldDescription).GroupJoin(Query(CRMDbContext.FieldValue), + x => x.Id, + y => y.FieldId, + (x, y) => new { x = x, count = y.Count() } + ); - sqlQuery.Where(BuildEntityTypeConditions(entityType, "tblFD.entity_type")); + if (entityType == EntityType.Company || entityType == EntityType.Person) + { + sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType || x.x.EntityType == EntityType.Contact); + } + else + { + sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType); + } - var queryResult = Db.ExecuteList(sqlQuery); + sqlQuery = sqlQuery.OrderBy(x => x.x.SortOrder); - return JsonConvert.SerializeObject(queryResult.ConvertAll(row => row[0])); + return JsonConvert.SerializeObject(sqlQuery.Select(x => x.count).ToList()); } public int GetContactLinkCount(EntityType entityType, int entityID) @@ -408,17 +435,25 @@ public int GetContactLinkCount(EntityType entityType, int entityID) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - Query(); - - var sqlQuery = Query("crm_field_description tblFD") - .Select("count(tblFV.field_id)") - .LeftOuterJoin("crm_field_value tblFV", Exp.EqColumns("tblFD.id", "tblFV.field_id")) - .Where(Exp.Eq("tblFD.id", entityID)) - .OrderBy("tblFD.sort_order", true); + var sqlQuery = Query(CRMDbContext.FieldDescription).GroupJoin(Query(CRMDbContext.FieldValue), + x => x.Id, + y => y.FieldId, + (x, y) => new { x = x, count = y.Count() } + ); - sqlQuery.Where(BuildEntityTypeConditions(entityType, "tblFD.entity_type")); + if (entityType == EntityType.Company || entityType == EntityType.Person) + { + sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType || x.x.EntityType == EntityType.Contact); + } + else + { + sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType); + } + + sqlQuery = sqlQuery.Where(x => x.x.Id == entityID); + sqlQuery = sqlQuery.OrderBy(x => x.x.SortOrder); - return Db.ExecuteScalar(sqlQuery); + return sqlQuery.Single().count; } public List GetEnityFields(EntityType entityType, int entityID, bool includeEmptyFields) @@ -434,59 +469,44 @@ public List GetEnityFields(EntityType entityType, int[] entityID) private List GetEnityFields(EntityType entityType, int[] entityID, bool includeEmptyFields) { // TODO: Refactoring Query!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - SqlQuery sqlQuery = Query("crm_field_description tbl_field") - .Select("tbl_field.id", - "tbl_field_value.entity_id", - "tbl_field.label", - "tbl_field_value.value", - "tbl_field.type", - "tbl_field.sort_order", - "tbl_field.mask", - "tbl_field.entity_type"); + var sqlQuery = Query(CRMDbContext.FieldDescription).GroupJoin(Query(CRMDbContext.FieldValue), + x => x.Id, + y => y.FieldId, + (x, y) => new { x, y } + ).SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }); - sqlQuery.Where(BuildEntityTypeConditions(entityType, "tbl_field.entity_type")); + if (entityType == EntityType.Company || entityType == EntityType.Person) + { + sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType || x.x.EntityType == EntityType.Contact); + } + else + { + sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType); + } if (entityID != null && entityID.Length > 0) - sqlQuery.LeftOuterJoin("crm_field_value tbl_field_value", - Exp.EqColumns("tbl_field_value.field_id", "tbl_field.id") & - Exp.In("tbl_field_value.entity_id", entityID)) - .OrderBy("tbl_field.sort_order", true); + { + sqlQuery = sqlQuery.Where(x => entityID.Contains(x.y.EntityId)); + sqlQuery = sqlQuery.OrderBy(x => x.x.SortOrder); + } else - sqlQuery.LeftOuterJoin("crm_field_value tbl_field_value", - Exp.EqColumns("tbl_field_value.field_id", "tbl_field.id")) - .Where(Exp.Eq("tbl_field_value.tenant_id", TenantID)) - .OrderBy("tbl_field_value.entity_id", true) - .OrderBy("tbl_field.sort_order", true); + { + sqlQuery = sqlQuery.OrderBy(x => x.y.EntityId); + sqlQuery = sqlQuery.OrderBy(x => x.x.SortOrder); + } if (!includeEmptyFields) - return Db.ExecuteList(sqlQuery) - .ConvertAll(row => ToCustomField(row)).FindAll(item => - { - if (item.FieldType == CustomFieldType.Heading) - return true; - - return !String.IsNullOrEmpty(item.Value.Trim()); + sqlQuery = sqlQuery.Where(x => x.y != null && x.x.Type == CustomFieldType.Heading); - }).ToList(); - - return Db.ExecuteList(sqlQuery) - .ConvertAll(row => ToCustomField(row)); + return sqlQuery.ToList().ConvertAll(x => ToCustomField(x.x, x.y)); } public CustomField GetFieldDescription(int fieldID) { - - var sqlQuery = GetFieldDescriptionSqlQuery(null); - - sqlQuery.Where(Exp.Eq("id", fieldID)); - - var fields = Db.ExecuteList(sqlQuery).ConvertAll(row => ToCustomField(row)); - - return fields.Count == 0 ? null : fields[0]; + return ToCustomField(Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID)); } public List GetFieldsDescription(EntityType entityType) @@ -494,46 +514,18 @@ public List GetFieldsDescription(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - SqlQuery sqlQuery = GetFieldDescriptionSqlQuery(null); - - sqlQuery.Where(BuildEntityTypeConditions(entityType, "entity_type")); - - return Db.ExecuteList(sqlQuery) - .ConvertAll(row => ToCustomField(row)); - } + var sqlQuery = Query(CRMDbContext.FieldDescription); - private SqlQuery GetFieldDescriptionSqlQuery(Exp where) - { - var sqlQuery = Query("crm_field_description") - .Select("id", - "-1", - "label", - "\" \"", - "type", - "sort_order", - "mask", - "entity_type") - .OrderBy("sort_order", true); - - if (where != null) - sqlQuery.Where(where); - - return sqlQuery; - } - - private Exp BuildEntityTypeConditions(EntityType entityType, String dbFieldName) - { - switch (entityType) + if (entityType == EntityType.Company || entityType == EntityType.Person) { - case EntityType.Company: - case EntityType.Person: - return Exp.In(dbFieldName, new[] { (int)entityType, (int)EntityType.Contact }); - - default: - return Exp.Eq(dbFieldName, (int)entityType); - + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType || x.EntityType == EntityType.Contact); + } + else + { + sqlQuery = sqlQuery.Where(x => x.EntityType == entityType); } + return sqlQuery.ToList().ConvertAll(x => ToCustomField(x)); } public void DeleteField(int fieldID) @@ -554,26 +546,32 @@ public void DeleteField(int fieldID) CRMDbContext.SaveChanges(); - tx.Commit(); + tx.Commit(); } - public static CustomField ToCustomField(DbFieldDescription dbFieldDescription, - DbFieldValue dbFieldValue) + public CustomField ToCustomField(DbFieldDescription dbFieldDescription, + DbFieldValue dbFieldValue = null) { + if (dbFieldDescription == null || dbFieldValue == null) return null; + var customField = new CustomField + { + ID = dbFieldDescription.Id, + EntityType = dbFieldDescription.EntityType, + FieldType = dbFieldDescription.Type, + Label = dbFieldDescription.Label, + Mask = dbFieldDescription.Mask, + Position = dbFieldDescription.SortOrder + + }; + + if (dbFieldValue != null) + { + dbFieldValue.Value = dbFieldValue.Value; + dbFieldValue.EntityId = dbFieldValue.EntityId; + } - throw new NotImplementedException(); - //return new CustomField - //{ - // ID = Convert.ToInt32(row[0]), - // EntityID = Convert.ToInt32(row[1]), - // EntityType = (EntityType)Convert.ToInt32(row[7]), - // Label = Convert.ToString(row[2]), - // Value = Convert.ToString(row[3]), - // FieldType = (CustomFieldType)Convert.ToInt32(row[4]), - // Position = Convert.ToInt32(row[5]), - // Mask = Convert.ToString(row[6]) - //}; + return customField; } } diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index bb3a36052e9..903647dd46b 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -98,9 +98,7 @@ private void ResetCache(int dealID) } public class DealDao : AbstractDao - { - #region Constructor - + { public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -121,10 +119,7 @@ public DealDao(DbContextManager dbContextManager, public AuthorizationManager AuthorizationManager { get; } - #endregion - - #region Methods - + public void AddMember(int dealID, int memberID) { SetRelative(memberID, EntityType.Opportunity, dealID); diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 5e79cbf7677..31160827d82 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -33,6 +33,7 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Linq; @@ -43,19 +44,18 @@ namespace ASC.CRM.Core.Dao { public class CachedDealMilestoneDao : DealMilestoneDao { - private readonly HttpRequestDictionary _dealMilestoneCache = - new HttpRequestDictionary("crm_deal_milestone"); + private readonly HttpRequestDictionary _dealMilestoneCache; public CachedDealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + IHttpContextAccessor httpContextAccessor) : base(dbContextManager, tenantManager, securityContext) { - - + _dealMilestoneCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal_milestone"); } private void ResetCache(int id) @@ -147,30 +147,12 @@ public int GetCount() public Dictionary GetRelativeItemsCount() { - var sqlQuery = Query(CRMDbContext.DealMilestones) - .GroupJoin(CRMDbContext.Deals, + return Query(CRMDbContext.DealMilestones).GroupJoin(CRMDbContext.Deals, x => x.Id, - x => x.DealMilestoneId, - (x,y) => - { - - }); - - - - throw new Exception(); - - //var sqlQuery = Query("crm_deal_milestone tbl_deal_milestone") - // .Select("tbl_deal_milestone.id") - // .OrderBy("tbl_deal_milestone.sort_order", true) - // .GroupBy("tbl_deal_milestone.id"); - - //sqlQuery.LeftOuterJoin("crm_deal tbl_crm_deal", - // Exp.EqColumns("tbl_deal_milestone.id", "tbl_crm_deal.deal_milestone_id")) - // .Select("count(tbl_crm_deal.deal_milestone_id)"); - - //var queryResult = Db.ExecuteList(sqlQuery); - //return queryResult.ToDictionary(x => Convert.ToInt32(x[0]), y => Convert.ToInt32(y[1])); + x => x.DealMilestoneId, + (x, y) => new { x = x, count = y.Count() }) + .OrderBy(x => x.x.SortOrder) + .ToDictionary(x => x.x.Id, y => y.count); } public int GetRelativeItemsCount(int id) @@ -215,10 +197,15 @@ public virtual int Create(DealMilestone item) public virtual void ChangeColor(int id, String newColor) { - var item = CRMDbContext.DealMilestones.First(x => x.Id == id); - - item.Color = newColor; + var itemToUpdate = new DbDealMilestone + { + Id = id, + Color = newColor, + TenantId = TenantID + }; + CRMDbContext.Attach(itemToUpdate); + CRMDbContext.Entry(itemToUpdate).Property(x => x.Color).IsModified = true; CRMDbContext.SaveChanges(); } @@ -252,9 +239,13 @@ public virtual void Delete(int id) if (HaveContactLink(id)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.DealMilestoneHasRelatedDeals)); - var item = CRMDbContext.DealMilestones.First(x => x.Id == id); + var dbDealMilestones = new DbDealMilestone + { + Id = id, + TenantId = TenantID + }; - CRMDbContext.DealMilestones.Remove(item); + CRMDbContext.DealMilestones.Remove(dbDealMilestones); CRMDbContext.SaveChanges(); @@ -273,12 +264,14 @@ public Boolean IsExist(int id) public List GetAll(int[] id) { return Query(CRMDbContext.DealMilestones) - .Where(x => id.Contains(x.Id)).ToList().ConvertAll(ToDealMilestone); + .OrderBy(x => x.SortOrder) + .Where(x => id.Contains(x.Id)).ToList().ConvertAll(ToDealMilestone); } public List GetAll() { return Query(CRMDbContext.DealMilestones) + .OrderBy(x => x.SortOrder) .ToList() .ConvertAll(ToDealMilestone); } diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 74bc411c02d..84157e9f254 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -85,7 +85,7 @@ public File SaveFile(File file, System.IO.Stream stream) public List GetEventsByFile(int id) { - var tagdao = FilesIntegration.GetTagDao(); + var tagdao = FilesIntegration.TagDao(); var tags = tagdao.GetTags(id, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); return tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 24069a19c7e..c90ab754896 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -34,6 +34,7 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; +using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -47,17 +48,19 @@ namespace ASC.CRM.Core.Dao { public class CachedInvoiceDao : InvoiceDao { - private readonly HttpRequestDictionary _invoiceCache = new HttpRequestDictionary("crm_invoice"); + private readonly HttpRequestDictionary _invoiceCache; public CachedInvoiceDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - FactoryIndexer factoryIndexer) + FactoryIndexer factoryIndexer, + IHttpContextAccessor httpContextAccessor) : base(dbContextManager, tenantManager, securityContext, factoryIndexer) { + _invoiceCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice"); } public override Invoice GetByID(int invoiceID) diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 0b8e9a1fdce..b47107c47b5 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -31,6 +31,7 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Collections.Specialized; @@ -43,8 +44,13 @@ public class CachedListItem : ListItemDao { private readonly HttpRequestDictionary _listItemCache = new HttpRequestDictionary("crm_list_item"); - public CachedListItem(int tenantID) - : base(tenantID) + public CachedListItem( + DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext) + : base(dbContextManager, + tenantManager, + securityContext) { @@ -210,13 +216,13 @@ public List GetSystemItems() public virtual ListItem GetByID(int id) { if (id < 0) return GetSystemListItem(id); - - return ToListItem(Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == id)); + + return ToListItem(Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == id)); } public virtual List GetItems(int[] id) { - var sqlResult = Db.ExecuteList(GetListItemSqlQuery(Exp.In("id", id))).ConvertAll(ToListItem); + var sqlResult = CRMDbContext.ListItem.Where(x => id.Contains(x.Id)).ToList().ConvertAll(ToListItem); var systemItem = id.Where(item => item < 0).Select(GetSystemListItem); @@ -233,21 +239,28 @@ public virtual List GetAll() public virtual void ChangeColor(int id, string newColor) { - Db.ExecuteNonQuery(Update("crm_list_item") - .Set("color", newColor) - .Where(Exp.Eq("id", id))); + var listItem = new DbListItem + { + Id = id, + Color = newColor + }; + + + CRMDbContext.Attach(listItem); + CRMDbContext.Entry(listItem).Property("Color").IsModified = true; + CRMDbContext.SaveChanges(); } public NameValueCollection GetColors(ListType listType) { - var where = Exp.Eq("list_type", (int)listType); - var result = new NameValueCollection(); - Db.ExecuteList(Query("crm_list_item") - .Select("id", "color") - .Where(where)) - .ForEach(row => result.Add(row[0].ToString(), row[1].ToString())); + Query(CRMDbContext.ListItem) + .Where(x => x.ListType == listType) + .Select(x => new { x.Id, x.Color }) + .ToList() + .ForEach(x => result.Add(x.Id.ToString(), x.Color.ToString())); + return result; } @@ -260,43 +273,35 @@ public ListItem GetByTitle(ListType listType, string title) public int GetRelativeItemsCount(ListType listType, int id) { - - SqlQuery sqlQuery; - - + int result; + switch (listType) { case ListType.ContactStatus: - sqlQuery = Query("crm_contact") - .Select("count(*)") - .Where(Exp.Eq("status_id", id)); + result = Query(CRMDbContext.Contacts).Where(x => x.StatusId == id).Count(); break; case ListType.ContactType: - sqlQuery = Query("crm_contact") - .Select("count(*)") - .Where(Exp.Eq("contact_type_id", id)); + result = Query(CRMDbContext.Contacts).Where(x => x.ContactTypeId == id).Count(); break; case ListType.TaskCategory: - sqlQuery = Query("crm_task") - .Select("count(*)") - .Where(Exp.Eq("category_id", id)); + result = Query(CRMDbContext.Tasks).Where(x => x.CategoryId == id).Count(); break; case ListType.HistoryCategory: - sqlQuery = Query("crm_relationship_event") - .Select("count(*)") - .Where(Exp.Eq("category_id", id)); - + result = Query(CRMDbContext.RelationshipEvent).Where(x => x.CategoryId == id).Count(); break; default: throw new ArgumentException(); } - return Db.ExecuteScalar(sqlQuery); + return result; } public Dictionary GetRelativeItemsCount(ListType listType) { + + + var sqlQuery = Query("crm_list_item tbl_list_item") .Where(Exp.Eq("tbl_list_item.list_type", (int)listType)) .Select("tbl_list_item.id") @@ -361,26 +366,32 @@ public virtual int CreateItem(ListType listType, ListItem enumItem) var sortOrder = enumItem.SortOrder; if (sortOrder == 0) - sortOrder = Db.ExecuteScalar(Query("crm_list_item") - .Where(Exp.Eq("list_type", (int)listType)) - .SelectMax("sort_order")) + 1; - - return Db.ExecuteScalar( - Insert("crm_list_item") - .InColumnValue("id", 0) - .InColumnValue("list_type", (int)listType) - .InColumnValue("description", enumItem.Description) - .InColumnValue("title", enumItem.Title) - .InColumnValue("additional_params", enumItem.AdditionalParams) - .InColumnValue("color", enumItem.Color) - .InColumnValue("sort_order", sortOrder) - .Identity(1, 0, true)); + sortOrder = Query(CRMDbContext.ListItem) + .Where(x => x.ListType == listType) + .Max(x => x.SortOrder) + 1; + + var listItem = new DbListItem + { + ListType = listType, + Description = enumItem.Description, + Title = enumItem.Title, + AdditionalParams = enumItem.AdditionalParams, + Color = enumItem.Color, + SortOrder = sortOrder, + TenantId = TenantID + }; + + CRMDbContext.Add(listItem); + + CRMDbContext.SaveChanges(); + + return listItem.Id; } public virtual void EditItem(ListType listType, ListItem enumItem) { - if (HaveRelativeItemsLink(listType, enumItem.ID)) + { switch (listType) { case ListType.ContactStatus: @@ -393,52 +404,52 @@ public virtual void EditItem(ListType listType, ListItem enumItem) default: throw new ArgumentException(string.Format("{0}.", CRMErrorsResource.BasicCannotBeEdited)); } + } - Db.ExecuteNonQuery(Update("crm_list_item") - .Set("description", enumItem.Description) - .Set("title", enumItem.Title) - .Set("additional_params", enumItem.AdditionalParams) - .Set("color", enumItem.Color) - .Where(Exp.Eq("id", enumItem.ID))); + var itemToUpdate = Query(CRMDbContext.ListItem).Single(x => x.Id == enumItem.ID); + + itemToUpdate.Description = enumItem.Description; + itemToUpdate.Title = enumItem.Title; + itemToUpdate.AdditionalParams = enumItem.AdditionalParams; + itemToUpdate.Color = enumItem.Color; + + CRMDbContext.SaveChanges(); } public virtual void ChangePicture(int id, String newPicture) { + var itemToUpdate = Query(CRMDbContext.ListItem).Single(x => x.Id == id); - Db.ExecuteNonQuery(Update("crm_list_item") - .Set("additional_params", newPicture) - .Where(Exp.Eq("id", id))); + itemToUpdate.AdditionalParams = newPicture; + + CRMDbContext.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); } private bool HaveRelativeItemsLink(ListType listType, int itemID) { - SqlQuery sqlQuery; + bool result; switch (listType) { - case ListType.ContactStatus: - sqlQuery = Query("crm_contact") - .Where(Exp.Eq("status_id", itemID)); + result = Query(CRMDbContext.Contacts).Where(x => x.StatusId == itemID).Any(); break; case ListType.ContactType: - sqlQuery = Query("crm_contact") - .Where(Exp.Eq("contact_type_id", itemID)); - + result = Query(CRMDbContext.Contacts).Where(x => x.ContactTypeId == itemID).Any(); break; case ListType.TaskCategory: - sqlQuery = Query("crm_task") - .Where(Exp.Eq("category_id", itemID)); + result = Query(CRMDbContext.Tasks).Where(x => x.CategoryId == itemID).Any(); break; case ListType.HistoryCategory: - sqlQuery = Query("crm_relationship_event") - .Where(Exp.Eq("category_id", itemID)); + result = Query(CRMDbContext.RelationshipEvent).Where(x => x.CategoryId == itemID).Any(); break; default: throw new ArgumentException(); } - return Db.ExecuteScalar(sqlQuery.SelectCount()) > 0; + return result; } public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toItemID) @@ -454,30 +465,44 @@ public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toIte switch (listType) { case ListType.ContactStatus: - sqlUpdate = Update("crm_contact") - .Set("status_id", toItemID) - .Where(Exp.Eq("status_id", fromItemID)); + { + var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.StatusId == fromItemID); + + itemToUpdate.StatusId = toItemID; + + CRMDbContext.Update(itemToUpdate); + } break; case ListType.ContactType: - sqlUpdate = Update("crm_contact") - .Set("contact_type_id", toItemID) - .Where(Exp.Eq("contact_type_id", fromItemID)); + { + var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.ContactTypeId == fromItemID); + + itemToUpdate.ContactTypeId = toItemID; + + CRMDbContext.Update(itemToUpdate); + } break; case ListType.TaskCategory: - sqlUpdate = Update("crm_task") - .Set("category_id", toItemID) - .Where(Exp.Eq("category_id", fromItemID)); + { + var itemToUpdate = Query(CRMDbContext.Tasks).Single(x => x.CategoryId == fromItemID); + itemToUpdate.CategoryId = toItemID; + + CRMDbContext.Update(itemToUpdate); + } break; case ListType.HistoryCategory: - sqlUpdate = Update("crm_relationship_event") - .Set("category_id", toItemID) - .Where(Exp.Eq("category_id", fromItemID)); + { + var itemToUpdate = Query(CRMDbContext.RelationshipEvent).Single(x => x.CategoryId == fromItemID); + itemToUpdate.CategoryId = toItemID; + + CRMDbContext.Update(itemToUpdate); + } break; default: throw new ArgumentException(); } - Db.ExecuteNonQuery(sqlUpdate); + CRMDbContext.SaveChanges(); } public virtual void DeleteItem(ListType listType, int itemID, int toItemID) @@ -501,9 +526,10 @@ public virtual void DeleteItem(ListType listType, int itemID, int toItemID) } } - var itemToRemove = Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == itemID); + var itemToRemove = new DbListItem { Id = itemID }; + + CRMDbContext.Entry(itemToRemove).State = EntityState.Deleted; - CRMDbContext.ListItem.Remove(itemToRemove); CRMDbContext.SaveChanges(); } @@ -513,15 +539,19 @@ public virtual void ReorderItems(ListType listType, String[] titles) using var tx = CRMDbContext.Database.BeginTransaction(); for (int index = 0; index < titles.Length; index++) - { - Db.ExecuteNonQuery(Update("crm_list_item") - .Set("sort_order", index) - .Where(Exp.Eq("title", titles[index]) & Exp.Eq("list_type", (int)listType))); + { + var itemToUpdate = Query(CRMDbContext.ListItem) + .Single(x => String.Compare(x.Title, titles[index]) == 0 && x.ListType == listType); + itemToUpdate.SortOrder = index; + + CRMDbContext.Update(itemToUpdate); } - tx.Commit(); + CRMDbContext.SaveChanges(); + + tx.Commit(); } public static ListItem ToListItem(DbListItem dbListItem) diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 08bac4f594f..859f432d2f2 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -95,78 +95,30 @@ public String GetTagsLinkCountJSON(EntityType entityType) public IEnumerable GetTagsLinkCount(EntityType entityType) { - - - - //var temp = Query(CRMDbContext.Tags) - // .Join(CRMDbContext.CrmEntityTag, - // x => x.Id, - // y => y.TagId, - // (x, y) => new - // { - // x, - // y - - // }) - // .Where(x => x.y.EntityType == entityType) - // .GroupBy(x=> x.x.Id) - // .OrderBy(x => x.x.Title) - - // .Count(); - - - - //var sqlQuery = new SqlQuery("crm_tag tbl_tag") - // .SelectCount("tag_id") - // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) - // .Where(Exp.Eq("tbl_tag.entity_type", (int)entityType) & Exp.Eq("tbl_tag.tenant_id", TenantID)) - // .OrderBy("title", true) - // .GroupBy("tbl_tag.id"); - - //var queryResult = Db.ExecuteList(sqlQuery); - - // return queryResult.ConvertAll(row => Convert.ToInt32(row[0])); - - throw new NotImplementedException(); + return Query(CRMDbContext.Tags) + .GroupJoin(CRMDbContext.EntityTags, + x => x.Id, + y => y.TagId, + (x, y) => new { x = x, count = y.Count() }) + .Where(x => x.x.EntityType == entityType) + .OrderBy(x => x.x.Title) + .Select(x => x.count).ToList(); } public Dictionary> GetEntitiesTags(EntityType entityType) { - var result = new Dictionary>(); - - var sqlQuery = - new SqlQuery("crm_entity_tag") - .Select("entity_id", "title") - .LeftOuterJoin("crm_tag", Exp.EqColumns("id", "tag_id")) - .Where(Exp.Eq("crm_tag.entity_type", (int)entityType) & Exp.Eq("crm_tag.tenant_id", TenantID)); - - Db.ExecuteList(sqlQuery).ForEach(row => - { - var entityID = Convert.ToInt32(row[0]); - var tagTitle = Convert.ToString(row[1]); - - if (!result.ContainsKey(entityID)) - result.Add(entityID, new List - { - tagTitle - }); - else - result[entityID].Add(tagTitle); - - }); - return result; + return CRMDbContext.EntityTags.Join(Query(CRMDbContext.Tags), + x => x.TagId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => x.x.EntityType == entityType) + .GroupBy(x => x.x.EntityId) + .ToDictionary(x => x.Key, x => x.ToList().ConvertAll(x => x.y.Title)); } public String[] GetEntityTags(EntityType entityType, int entityID) { - //SqlQuery sqlQuery = Query("crm_tag") - // .Select("title") - // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("id", "tag_id")) - // .Where(Exp.Eq("entity_id", entityID) & Exp.Eq("crm_tag.entity_type", (int)entityType)); - - //return Db.ExecuteList(sqlQuery).ConvertAll(row => Convert.ToString(row[0])).ToArray(); - return Query(CRMDbContext.Tags) .Join(CRMDbContext.EntityTags, x => x.Id, @@ -189,11 +141,6 @@ public string[] GetUnusedTags(EntityType entityType) (x, y) => new { x, y }) .Where(x => x.y == null && x.x.EntityType == entityType) .Select(x => x.x.Title).ToArray(); - - //return Db.ExecuteList(Query("crm_tag") - // .Select("title") - // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) - // .Where(Exp.Eq("tag_id", Exp.Empty) & Exp.Eq("crm_tag.entity_type", (int)entityType))).ConvertAll(row => Convert.ToString(row[0])).ToArray(); } public bool CanDeleteTag(EntityType entityType, String tagName) diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 7098d21b34d..0ffff59c331 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -34,6 +34,7 @@ using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; +using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Globalization; @@ -45,15 +46,16 @@ namespace ASC.CRM.Core.Dao public class CachedTaskDao : TaskDao { - private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_task"); + private readonly HttpRequestDictionary _contactCache; public CachedTaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, CRMSecurity cRMSecurity, TenantUtil tenantUtil, - FactoryIndexer factoryIndexer - ): + FactoryIndexer factoryIndexer, + IHttpContextAccessor httpContextAccessor + ) : base(dbContextManager, tenantManager, securityContext, @@ -61,7 +63,7 @@ FactoryIndexer factoryIndexer tenantUtil, factoryIndexer) { - + _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_task"); } diff --git a/products/ASC.CRM/Server/Core/EF/DbCase.cs b/products/ASC.CRM/Server/Core/EF/DbCase.cs index 8fbc3c754dd..82f98621900 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCase.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCase.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_case")] - public partial class DbCase + public partial class DbCase : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/DbContact.cs b/products/ASC.CRM/Server/Core/EF/DbContact.cs index 65687ddd2d2..67ae56c536d 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContact.cs @@ -1,51 +1,71 @@ -using System; +using ASC.CRM.Core.Enums; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_contact")] - public partial class DbContact + public partial class DbContact : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } - [Column("tenant_id", TypeName = "int(11)")] - public int TenantId { get; set; } + [Column("is_company")] public bool IsCompany { get; set; } + [Column("notes", TypeName = "text")] public string Notes { get; set; } + [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } + [Column("first_name", TypeName = "varchar(255)")] public string FirstName { get; set; } + [Column("last_name", TypeName = "varchar(255)")] public string LastName { get; set; } + [Column("company_name", TypeName = "varchar(255)")] public string CompanyName { get; set; } + [Column("industry", TypeName = "varchar(255)")] public string Industry { get; set; } + [Column("status_id", TypeName = "int(11)")] public int StatusId { get; set; } + [Column("company_id", TypeName = "int(11)")] public int CompanyId { get; set; } + [Column("contact_type_id", TypeName = "int(11)")] public int ContactTypeId { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } + [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } + [Column("display_name", TypeName = "varchar(255)")] public string DisplayName { get; set; } + [Column("is_shared", TypeName = "tinyint(4)")] - public sbyte? IsShared { get; set; } + public ShareType? IsShared { get; set; } + [Column("currency", TypeName = "varchar(3)")] public string Currency { get; set; } + + [Column("tenant_id", TypeName = "int(11)")] + public int TenantId { get; set; } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs index 40c9cbbedd8..efc67f0e207 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs @@ -1,11 +1,12 @@ -using System; +using ASC.CRM.Core.Enums; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF { [Table("crm_contact_info")] - public partial class DbContactInfo + public partial class DbContactInfo : IDbCrm { [Key] [Column("id", TypeName = "int(10)")] @@ -22,19 +23,19 @@ public partial class DbContactInfo public int TenantId { get; set; } [Column("is_primary", TypeName = "tinyint(4)")] - public sbyte IsPrimary { get; set; } + public bool IsPrimary { get; set; } [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } [Column("type", TypeName = "int(255)")] - public int Type { get; set; } + public ContactInfoType Type { get; set; } [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } [Column("last_modifed_by", TypeName = "char(38)")] - public string LastModifedBy { get; set; } + public Guid LastModifedBy { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs b/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs index 37d26ba4b2a..15de02e3642 100644 --- a/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs @@ -1,7 +1,5 @@ -// This file has been auto generated by EF Core Power Tools. -using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; + +using ASC.CRM.Core.Enums; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -16,7 +14,7 @@ public partial class DbEntityContact [Key] [Column("entity_type", TypeName = "int(11)")] - public int EntityType { get; set; } + public EntityType EntityType { get; set; } [Key] [Column("contact_id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/DbOrganisationLogo.cs b/products/ASC.CRM/Server/Core/EF/DbOrganisationLogo.cs index f34acd47a47..ab5c889c243 100644 --- a/products/ASC.CRM/Server/Core/EF/DbOrganisationLogo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbOrganisationLogo.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_organisation_logo")] - public partial class DbOrganisationLogo + public partial class DbOrganisationLogo : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/EF/DbProjects.cs b/products/ASC.CRM/Server/Core/EF/DbProjects.cs index 63a2dc86107..d7e0e64f85e 100644 --- a/products/ASC.CRM/Server/Core/EF/DbProjects.cs +++ b/products/ASC.CRM/Server/Core/EF/DbProjects.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_projects")] - public partial class DbProjects + public partial class DbProjects : IDbCrm { [Key] [Column("project_id", TypeName = "int(10)")] diff --git a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index 182c99c8882..137fbe76b6f 100644 --- a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -44,6 +44,6 @@ public partial class DbRelationshipEvent : IDbCrm public DateTime? LastModifedOn { get; set; } [Column("have_files", TypeName = "int(11)")] - public int HaveFiles { get; set; } + public bool HaveFiles { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 38a93624a28..70c648cf096 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -35,6 +35,7 @@ using ASC.Web.Core; using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Configuration; using ASC.Web.CRM.Core; using Autofac; using System; From acdebad251f2debe490436300572e7c370a3a220 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 30 Mar 2020 11:52:01 +0300 Subject: [PATCH 05/61] crm: migrate DAO to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 1 + products/ASC.CRM/Server/Core/Dao/DealDao.cs | 423 ++++++++++-------- .../Server/Core/Dao/DealMilestoneDao.cs | 21 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 95 ++-- .../Server/Core/Dao/RelationshipEventDao.cs | 305 +++++++------ products/ASC.CRM/Server/Core/Dao/TagDao.cs | 40 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 132 +++--- .../Core/Dao/TaskTemplateContainerDao.cs | 109 ++--- products/ASC.CRM/Server/Core/EF/DbDeal.cs | 2 +- .../ASC.CRM/Server/Core/EF/DbDealMilestone.cs | 10 +- .../ASC.CRM/Server/Core/EF/DbInvoiceTax.cs | 2 +- .../Server/Core/EF/DbRelationshipEvent.cs | 2 +- .../Server/Core/Entities/DealMilestone.cs | 1 + .../Server/Core/Entities/InvoiceTax.cs | 2 - .../Server/Core/Security/CRMSecutiry.cs | 1 + 15 files changed, 583 insertions(+), 563 deletions(-) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 6308fa3b1e7..b00e2fa10d2 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -6,6 +6,7 @@ + diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 903647dd46b..5b936b39ae0 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -35,6 +35,8 @@ using ASC.Files.Core; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Globalization; @@ -46,20 +48,23 @@ namespace ASC.CRM.Core.Dao { public class CachedDealDao : DealDao { - private readonly HttpRequestDictionary _dealCache = new HttpRequestDictionary("crm_deal"); + private readonly HttpRequestDictionary _dealCache; public CachedDealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, CRMSecurity cRMSecurity, - FactoryIndexer factoryIndexer) + FactoryIndexer factoryIndexer, + FilesIntegration filesIntegration, + IHttpContextAccessor httpContextAccessor) : base(dbContextManager, tenantManager, securityContext, cRMSecurity, - factoryIndexer) + factoryIndexer, + filesIntegration) { - + _dealCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal"); } public override void EditDeal(Deal deal) @@ -98,20 +103,24 @@ private void ResetCache(int dealID) } public class DealDao : AbstractDao - { + { public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, CRMSecurity cRMSecurity, - FactoryIndexer factoryIndexer) : + FactoryIndexer factoryIndexer, + FilesIntegration filesIntegration) : base(dbContextManager, tenantManager, securityContext) { CRMSecurity = cRMSecurity; FactoryIndexer = factoryIndexer; + FilesIntegration = filesIntegration; } + FilesIntegration FilesIntegration { get; } + FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } @@ -119,7 +128,6 @@ public DealDao(DbContextManager dbContextManager, public AuthorizationManager AuthorizationManager { get; } - public void AddMember(int dealID, int memberID) { SetRelative(memberID, EntityType.Opportunity, dealID); @@ -149,8 +157,10 @@ public virtual List GetDeals(int[] id) { if (id == null || !id.Any()) return new List(); - return Db.ExecuteList(GetDealSqlQuery(Exp.In("tblDeal.id", id))) - .ConvertAll(ToDeal).FindAll(CRMSecurity.CanAccessTo).ToList(); + return Query(CRMDbContext.Deals).Where(x => id.Contains(x.Id)) + .ToList() + .ConvertAll(ToDeal) + .FindAll(CRMSecurity.CanAccessTo); } public virtual Deal GetByID(int dealID) @@ -181,27 +191,31 @@ private int CreateNewDealInDb(Deal deal) // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); + var itemToInsert = new DbDeal + { + Title = deal.Title, + Description = deal.Description, + ResponsibleId = deal.ResponsibleID, + ContactId = deal.ContactID, + BidCurrency = deal.BidCurrency, + BidValue = deal.BidValue, + BidType = deal.BidType, + DealMilestoneId = deal.DealMilestoneID, + DealMilestoneProbability = deal.DealMilestoneProbability, + ExpectedCloseDate = deal.ExpectedCloseDate, + ActualCloseDate = deal.ActualCloseDate, + PerPeriodValue = deal.PerPeriodValue, + CreateOn = TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn), + CreateBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn), + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.Deals.Add(itemToInsert); + CRMDbContext.SaveChanges(); - var dealID = Db.ExecuteScalar( - Insert("crm_deal") - .InColumnValue("id", 0) - .InColumnValue("title", deal.Title) - .InColumnValue("description", deal.Description) - .InColumnValue("responsible_id", deal.ResponsibleID) - .InColumnValue("contact_id", deal.ContactID) - .InColumnValue("bid_currency", deal.BidCurrency) - .InColumnValue("bid_value", deal.BidValue) - .InColumnValue("bid_type", deal.BidType) - .InColumnValue("deal_milestone_id", deal.DealMilestoneID) - .InColumnValue("deal_milestone_probability", deal.DealMilestoneProbability) - .InColumnValue("expected_close_date", TenantUtil.DateTimeToUtc(deal.ExpectedCloseDate)) - .InColumnValue("actual_close_date", TenantUtil.DateTimeToUtc(deal.ActualCloseDate)) - .InColumnValue("per_period_value", deal.PerPeriodValue) - .InColumnValue("create_on", TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn)) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn)) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); + var dealID = itemToInsert.Id; // if (deal.ContactID > 0) // AddMember(dealID, deal.ContactID); @@ -211,16 +225,19 @@ private int CreateNewDealInDb(Deal deal) public virtual int[] SaveDealList(List items) { - using (var tx = Db.BeginTransaction()) + var tx = CRMDbContext.Database.BeginTransaction(); + + var result = items.Select(item => CreateNewDealInDb(item)).ToArray(); + + tx.Commit(); + + foreach (var item in items) { - var result = items.Select(item => CreateNewDealInDb(item)).ToArray(); - tx.Commit(); - foreach (var item in items) - { - FactoryIndexer.IndexAsync(item); - } - return result; + FactoryIndexer.IndexAsync(item); } + + return result; + } public virtual void EditDeal(Deal deal) @@ -234,24 +251,23 @@ public virtual void EditDeal(Deal deal) // AddMember(deal.ID, deal.ContactID); - Db.ExecuteNonQuery( - Update("crm_deal") - .Set("title", deal.Title) - .Set("description", deal.Description) - .Set("responsible_id", deal.ResponsibleID) - .Set("contact_id", deal.ContactID) - .Set("bid_currency", deal.BidCurrency) - .Set("bid_value", deal.BidValue) - .Set("bid_type", deal.BidType) - .Set("deal_milestone_id", deal.DealMilestoneID) - .Set("deal_milestone_probability", deal.DealMilestoneProbability) - .Set("expected_close_date", TenantUtil.DateTimeToUtc(deal.ExpectedCloseDate)) - .Set("per_period_value", deal.PerPeriodValue) - .Set("actual_close_date", TenantUtil.DateTimeToUtc(deal.ActualCloseDate)) - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", deal.ID)) - ); + var itemToUpdate = Query(CRMDbContext.Deals).Single(x => x.Id == deal.ID); + + itemToUpdate.Title = deal.Title; + itemToUpdate.Description = deal.Description; + itemToUpdate.ResponsibleId = deal.ResponsibleID; + itemToUpdate.ContactId = deal.ContactID; + itemToUpdate.BidCurrency = deal.BidCurrency; + itemToUpdate.BidValue = deal.BidValue; + itemToUpdate.BidType = deal.BidType; + itemToUpdate.DealMilestoneId = deal.DealMilestoneID; + itemToUpdate.DealMilestoneProbability = deal.DealMilestoneProbability; + itemToUpdate.ExpectedCloseDate = deal.ExpectedCloseDate; + itemToUpdate.PerPeriodValue = deal.PerPeriodValue; + + itemToUpdate.ActualCloseDate = TenantUtil.DateTimeToUtc(deal.ActualCloseDate); + itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); + itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; FactoryIndexer.IndexAsync(deal); } @@ -278,7 +294,7 @@ public List GetAllDeals() new OrderBy(DealSortedByType.Stage, true)); } - private Exp WhereConditional( + private IQueryable GetDbDealByFilters( ICollection exceptIDs, String searchText, Guid responsibleID, @@ -288,7 +304,8 @@ private Exp WhereConditional( DealMilestoneStatus? stageType, bool? contactAlsoIsParticipant) { - var conditions = new List(); + + var sqlQuery = Query(CRMDbContext.Deals); var ids = new List(); @@ -302,11 +319,13 @@ private Exp WhereConditional( { if (!BundleSearch.TrySelectOpportunity(searchText, out ids)) { - conditions.Add(BuildLike(new[] { "tblDeal.title", "tblDeal.description" }, keywords)); + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k) || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k)); + } } else if (ids.Count == 0) return null; } - } if (tags != null && tags.Any()) @@ -324,7 +343,7 @@ private Exp WhereConditional( if (relativeContactsID.Count == 0) { - conditions.Add(Exp.Eq("tblDeal.contact_id", contactID)); + sqlQuery = sqlQuery.Where(x => x.ContactId == contactID); } else { @@ -342,22 +361,29 @@ private Exp WhereConditional( } else { - conditions.Add(Exp.Eq("tblDeal.contact_id", contactID)); + sqlQuery = sqlQuery.Where(x => x.ContactId == contactID); } } if (0 < milestoneID && milestoneID < int.MaxValue) { - conditions.Add(Exp.Eq("tblDeal.deal_milestone_id", milestoneID)); + sqlQuery = sqlQuery.Where(x => x.DealMilestoneId == milestoneID); } if (responsibleID != Guid.Empty) { - conditions.Add(Exp.Eq("tblDeal.responsible_id", responsibleID)); + sqlQuery = sqlQuery.Where(x => x.ResponsibleId == responsibleID); } if (stageType != null) { + sqlQuery = sqlQuery.Join(CRMDbContext.DealMilestones, + x => x.DealMilestoneId, + y => y.Id, + (x,y) => new { x,y } + ) + .Where(x => x.y.Status == stageType.Value); + conditions.Add(Exp.Eq("tblDM.status", (int)stageType.Value)); } @@ -369,16 +395,14 @@ private Exp WhereConditional( if (ids.Count == 0) return null; } - conditions.Add(Exp.In("tblDeal.id", ids)); + sqlQuery = sqlQuery.Where(x => ids.Contains(x.Id)); } else if (exceptIDs.Count > 0) { - conditions.Add(!Exp.In("tblDeal.id", exceptIDs.ToArray())); + sqlQuery = sqlQuery.Where(x => !exceptIDs.Contains(x.Id)); } - if (conditions.Count == 0) return null; - - return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + return sqlQuery; } public int GetDealsCount(String searchText, @@ -434,33 +458,29 @@ public int GetDealsCount(String searchText, if (withParams) { - var whereConditional = WhereConditional(exceptIDs, searchText, responsibleID, milestoneID, tags, + var sqlQuery = GetDbDealByFilters(exceptIDs, searchText, responsibleID, milestoneID, tags, contactID, stageType, contactAlsoIsParticipant); - - var sqlQuery = GetDealSqlQuery(whereConditional); - if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) { sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - result = Db.ExecuteList(sqlQuery).Count; + result = sqlQuery.Count(); } - else if (whereConditional == null) + else if (sqlQuery == null) { result = 0; } else { - result = Db.ExecuteList(sqlQuery).Count; + result = sqlQuery.Count(); } - } else { - var countWithoutPrivate = Db.ExecuteScalar(Query("crm_deal").SelectCount()); + var countWithoutPrivate = Query(CRMDbContext.Deals).Count(); var privateCount = exceptIDs.Count; if (privateCount > countWithoutPrivate) @@ -476,8 +496,8 @@ public int GetDealsCount(String searchText, { _cache.Insert(cacheKey, result, TimeSpan.FromSeconds(30)); } - return result; + return result; } public List GetDeals( @@ -576,8 +596,6 @@ private List GetCrudeDeals( int count, OrderBy orderBy) { - var sqlQuery = GetDealSqlQuery(null); - var withParams = !(String.IsNullOrEmpty(searchText) && responsibleID == Guid.Empty && milestoneID <= 0 && @@ -588,7 +606,7 @@ private List GetCrudeDeals( fromDate == DateTime.MinValue && toDate == DateTime.MinValue); - var whereConditional = WhereConditional(new List(), + var sqlQuery = GetDbDealByFilters(new List(), searchText, responsibleID, milestoneID, @@ -600,56 +618,99 @@ private List GetCrudeDeals( if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) + { + sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + } else if (withParams && whereConditional == null) + { return new List(); - - sqlQuery.Where(whereConditional); + } if (0 < from && from < int.MaxValue) - sqlQuery.SetFirstResult(from); + { + sqlQuery = sqlQuery.Skip(from); + } if (0 < count && count < int.MaxValue) - sqlQuery.SetMaxResults(count); + { + sqlQuery = sqlQuery.Take(count); + } if (orderBy != null && Enum.IsDefined(typeof(DealSortedByType), orderBy.SortedBy)) switch ((DealSortedByType)orderBy.SortedBy) { case DealSortedByType.Title: - sqlQuery.OrderBy("tblDeal.title", orderBy.IsAsc); - break; + { + sqlQuery = sqlQuery.OrderBy(x => x.Title); + + break; + } case DealSortedByType.BidValue: - sqlQuery.OrderBy("tblDeal.bid_value", orderBy.IsAsc); - break; + { + sqlQuery = sqlQuery.OrderBy(x => x.BidValue); + + break; + } case DealSortedByType.Responsible: - - sqlQuery.OrderBy("tblDeal.responsible_id", orderBy.IsAsc) - .OrderBy("tblDM.sort_order", orderBy.IsAsc) - .OrderBy("tblDeal.contact_id", true) - .OrderBy("tblDeal.actual_close_date", false) - .OrderBy("tblDeal.expected_close_date", true) - .OrderBy("tblDeal.title", true); - - break; + { + sqlQuery = sqlQuery.OrderBy(x => x.ResponsibleId) + .OrderBy(x => x.ContactId) + .OrderBy(x => x.ActualCloseDate) + .OrderBy(x => x.ExpectedCloseDate) + .OrderBy(x => x.Title); + + throw new NotImplementedException(); + //sqlQuery.OrderBy("tblDeal.responsible_id", orderBy.IsAsc) + // .OrderBy("tblDM.sort_order", orderBy.IsAsc) + // .OrderBy("tblDeal.contact_id", true) + // .OrderBy("tblDeal.actual_close_date", false) + // .OrderBy("tblDeal.expected_close_date", true) + // .OrderBy("tblDeal.title", true); + + break; + } case DealSortedByType.Stage: - sqlQuery.OrderBy("tblDM.sort_order", orderBy.IsAsc) + { + sqlQuery = sqlQuery + .OrderBy(x => x.ContactId) + .OrderBy(x => x.ActualCloseDate) + .OrderBy(x => x.ExpectedCloseDate) + .OrderBy(x => x.Title); + + sqlQuery.OrderBy("tblDM.sort_order", orderBy.IsAsc) .OrderBy("tblDeal.contact_id", true) .OrderBy("tblDeal.actual_close_date", false) .OrderBy("tblDeal.expected_close_date", true) .OrderBy("tblDeal.title", true); - break; + + break; + + } case DealSortedByType.DateAndTime: - sqlQuery.OrderBy("close_date", orderBy.IsAsc); - break; + { + + sqlQuery.OrderBy("close_date", orderBy.IsAsc); + + break; + + } default: throw new ArgumentException(); } else - sqlQuery.OrderBy("tblDM.sort_order", true) - .OrderBy("tblDeal.contact_id", true) - .OrderBy("tblDeal.title", true); + { + + sqlQuery = sqlQuery.OrderBy(x => x.ContactId) + .OrderBy(x => x.Title); + + //sqlQuery.OrderBy("tblDM.sort_order", true) + // .OrderBy("tblDeal.contact_id", true) + // .OrderBy("tblDeal.title", true); - return Db.ExecuteList(sqlQuery).ConvertAll(ToDeal); + } + + return sqlQuery.ToList().ConvertAll(ToDeal); } public List GetDealsByContactID(int contactID) @@ -669,36 +730,36 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); - var q = GetDealSqlQuery(null); + var sqlQuery = Query(CRMDbContext.Deals); if (keywords.Length == 1) { - q.Where(Exp.Like("tblDeal.title", keywords[0])); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, keywords[0])); } else { foreach (var k in keywords) { - q.Where(Exp.Like("tblDeal.title", k)); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k)); } } - if (0 < from && from < int.MaxValue) q.SetFirstResult(from); - if (0 < count && count < int.MaxValue) q.SetMaxResults(count); + if (0 < from && from < int.MaxValue) sqlQuery = sqlQuery.Skip(from); + if (0 < count && count < int.MaxValue) sqlQuery = sqlQuery.Take(count); if (contactId > 0) { var ids = GetRelativeToEntity(contactId, EntityType.Opportunity, null); if (internalSearch) - q.Where(Exp.Eq("tblDeal.contact_id", contactId) | Exp.In("tblDeal.id", ids)); + sqlQuery = sqlQuery.Where(x => x.ContactId == contactId || ids.Contains(x.Id)); else - q.Where(!Exp.Eq("tblDeal.contact_id", contactId) & !Exp.In("tblDeal.id", ids)); + sqlQuery = sqlQuery.Where(x => x.ContactId != contactId && !ids.Contains(x.Id)); } - var sqlResult = Db.ExecuteList(q).ConvertAll(ToDeal).FindAll(CRMSecurity.CanAccessTo); + sqlQuery = sqlQuery.OrderBy(x => x.Title); - return sqlResult.OrderBy(deal => deal.Title).ToList(); + return sqlQuery.ToList().ConvertAll(ToDeal).FindAll(CRMSecurity.CanAccessTo); } public virtual Deal DeleteDeal(int dealID) @@ -751,28 +812,35 @@ private void DeleteBatchDealsExecute(List deals) var dealID = deals.Select(x => x.ID).ToArray(); object[] filesIDs; - using (var tagdao = FilesIntegration.GetTagDao()) - { - var tagNames = Db.ExecuteList(Query("crm_relationship_event").Select("id") - .Where(Exp.Eq("have_files", true) & Exp.In("entity_id", dealID) & Exp.Eq("entity_type", (int)EntityType.Opportunity))) - .Select(row => String.Format("RelationshipEvent_{0}", row[0])).ToArray(); - filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + var tagdao = FilesIntegration.TagDao(); - using (var tx = Db.BeginTransaction(true)) - { + var tagNames = Query(CRMDbContext.RelationshipEvent) + .Where(x => x.HaveFiles && dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) + .Select(x => string.Format("RelationshipEvent_{0}", x.Id)).ToArray(); - Db.ExecuteNonQuery(Delete("crm_field_value").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", (int)EntityType.Opportunity))); - Db.ExecuteNonQuery(new SqlDelete("crm_entity_contact").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); - Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); - Db.ExecuteNonQuery(Delete("crm_task").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); - Db.ExecuteNonQuery(new SqlDelete("crm_entity_tag").Where(Exp.In("entity_id", dealID) & Exp.Eq("entity_type", EntityType.Opportunity))); - Db.ExecuteNonQuery(Delete("crm_deal").Where(Exp.In("id", dealID))); + filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); - tx.Commit(); - } + var tx = CRMDbContext.Database.BeginTransaction(); - deals.ForEach(deal => AuthorizationManager.RemoveAllAces(deal)); - } + + CRMDbContext.RemoveRange(Query(CRMDbContext.FieldValue) + .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) + ); + + CRMDbContext.RemoveRange(CRMDbContext.EntityContact.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + + CRMDbContext.RemoveRange(Query(CRMDbContext.RelationshipEvent) + .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + + CRMDbContext.RemoveRange(Query(CRMDbContext.Tasks).Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + + CRMDbContext.RemoveRange(CRMDbContext.EntityTags.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + + CRMDbContext.RemoveRange(Query(CRMDbContext.Deals).Where(x => dealID.Contains(x.Id))); + + tx.Commit(); + + deals.ForEach(deal => AuthorizationManager.RemoveAllAces(deal)); var filedao = FilesIntegration.GetFileDao(); @@ -796,71 +864,17 @@ private Deal ToDeal(DbDeal dbDeal) ContactID = dbDeal.ContactId, BidCurrency = dbDeal.BidCurrency, BidValue = dbDeal.BidValue, + BidType = dbDeal.BidType, DealMilestoneID = dbDeal.DealMilestoneId, ExpectedCloseDate = dbDeal.ExpectedCloseDate, PerPeriodValue = dbDeal.PerPeriodValue, DealMilestoneProbability = dbDeal.DealMilestoneProbability, - CreateOn = dbDeal.CreateOn, + CreateOn = TenantUtil.DateTimeFromUtc(dbDeal.CreateOn), CreateBy = dbDeal.CreateBy, - ActualCloseDate = Convert.ToDateTime(row[14]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[14])) - }; - - return new Deal - { - ID = Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - Description = Convert.ToString(row[2]), - ResponsibleID = ToGuid(row[3]), - ContactID = Convert.ToInt32(row[4]), - BidCurrency = Convert.ToString(row[5]), - BidValue = Convert.ToDecimal(row[6]), - BidType = (BidType)Convert.ToInt32(row[7]), - DealMilestoneID = Convert.ToInt32(row[8]), - ExpectedCloseDate = Convert.ToDateTime(row[9]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[9])), - PerPeriodValue = Convert.ToInt32(row[10]), - DealMilestoneProbability = Convert.ToInt32(row[11]), - CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[12])), - CreateBy = ToGuid(row[13]), - ActualCloseDate = - Convert.ToDateTime(row[14]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[14])) + ActualCloseDate = Convert.ToDateTime(dbDeal.ActualCloseDate) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(dbDeal.ActualCloseDate)) }; } - private SqlQuery GetDealSqlQuery(Exp where) - { - - SqlQuery sqlQuery = Query("crm_deal tblDeal") - .Select( - "tblDeal.id", - "tblDeal.title", - "tblDeal.description", - "tblDeal.responsible_id", - "tblDeal.contact_id", - "tblDeal.bid_currency", - "tblDeal.bid_value", - "tblDeal.bid_type", - "tblDeal.deal_milestone_id", - "tblDeal.expected_close_date", - "tblDeal.per_period_value", - "tblDeal.deal_milestone_probability", - "tblDeal.create_on", - "tblDeal.create_by", - "tblDeal.actual_close_date" - ) - .Select(@"case tblDM.status - when 0 - then tblDeal.expected_close_date - else - tblDeal.actual_close_date - end as close_date") - .LeftOuterJoin("crm_deal_milestone tblDM", - Exp.EqColumns("tblDeal.deal_milestone_id", "tblDM.id")); - - if (where != null) - sqlQuery.Where(where); - - return sqlQuery; - } public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) @@ -902,10 +916,17 @@ public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) /// public void SetDealCreationDate(int opportunityid, DateTime creationDate) { - Db.ExecuteNonQuery( - Update("crm_deal") - .Set("create_on", TenantUtil.DateTimeToUtc(creationDate)) - .Where(Exp.Eq("id", opportunityid))); + var dbDeal = new DbDeal + { + Id = opportunityid, + CreateOn = TenantUtil.DateTimeToUtc(creationDate), + TenantId = TenantID + }; + + CRMDbContext.Attach(dbDeal); + CRMDbContext.Entry(dbDeal).Property(x => x.CreateOn).IsModified = true; + CRMDbContext.SaveChanges(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); } @@ -917,12 +938,16 @@ public void SetDealCreationDate(int opportunityid, DateTime creationDate) /// public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) { + var dbDeal = new DbDeal + { + Id = opportunityid, + LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate), + TenantId = TenantID + }; - - Db.ExecuteNonQuery( - Update("crm_deal") - .Set("last_modifed_on", TenantUtil.DateTimeToUtc(lastModifedDate)) - .Where(Exp.Eq("id", opportunityid))); + CRMDbContext.Attach(dbDeal); + CRMDbContext.Entry(dbDeal).Property(x => x.LastModifedOn).IsModified = true; + CRMDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 31160827d82..a9f7d4a98ae 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -275,26 +275,7 @@ public List GetAll() .ToList() .ConvertAll(ToDealMilestone); } - - //private SqlQuery GetDealMilestoneQuery(Exp where) - //{ - // SqlQuery sqlQuery = Query("crm_deal_milestone") - // .Select("id", - // "title", - // "description", - // "color", - // "probability", - // "status", - // "sort_order") - // .OrderBy("sort_order", true); - - // if (where != null) - // sqlQuery.Where(where); - - // return sqlQuery; - - //} - + private static DealMilestone ToDealMilestone(DbDealMilestone dbDealMilestone) { return new DealMilestone diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 5b574fa7560..928f798b5c4 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -30,6 +30,7 @@ using ASC.Core.Tenants; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Globalization; @@ -39,17 +40,19 @@ namespace ASC.CRM.Core.Dao { public class CachedInvoiceTaxDao : InvoiceTaxDao { - private readonly HttpRequestDictionary _invoiceTaxCache = new HttpRequestDictionary("crm_invoice_tax"); + private readonly HttpRequestDictionary _invoiceTaxCache; public CachedInvoiceTaxDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext + SecurityContext securityContext, + IHttpContextAccessor httpContextAccessor ) : base(dbContextManager, tenantManager, securityContext) { + _invoiceTaxCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_tax"); } public override InvoiceTax GetByID(int invoiceTaxID) @@ -94,7 +97,7 @@ SecurityContext securityContext tenantManager, securityContext) { - + } public TenantUtil TenantUtil { get; } @@ -107,13 +110,13 @@ public Boolean IsExist(int invoiceTaxID) public Boolean IsExist(String invoiceName) { - return Query(CRMDbContext.InvoiceTax).Where(x => String.Compare(x.Name, invoiceName, true) == 0).Any(); + return Query(CRMDbContext.InvoiceTax).Where(x => String.Compare(x.Name, invoiceName, true) == 0).Any(); } public Boolean CanDelete(int invoiceTaxID) { - return !Query(CRMDbContext.InvoiceItem) - .Where(x => x.InvoiceTax1Id == invoiceTaxID || x.InvoiceTax2Id == invoiceTaxID).Any() && + return !Query(CRMDbContext.InvoiceItem) + .Where(x => x.InvoiceTax1Id == invoiceTaxID || x.InvoiceTax2Id == invoiceTaxID).Any() && !Query(CRMDbContext.InvoiceLine) .Where(x => x.InvoiceTax1Id == invoiceTaxID || x.InvoiceTax2Id == invoiceTaxID).Any(); } @@ -127,10 +130,11 @@ public virtual List GetAll() public DateTime GetMaxLastModified() { - throw new NotImplementedException(); + var result = Query(CRMDbContext.InvoiceTax).Max(x => x.LastModifedOn); + + if (result.HasValue) return result.Value; -// return Query(CRMDbContext.InvoiceItem).Select(x => x.la) -// return Db.ExecuteScalar(Query("crm_invoice_tax").Select("last_modifed_on")); + return DateTime.MinValue; } public virtual List GetByID(int[] ids) @@ -169,12 +173,11 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) var itemToInsert = new DbInvoiceTax { - Id = 0, Name = invoiceTax.Name, Description = invoiceTax.Description, Rate = invoiceTax.Rate, CreateOn = invoiceTax.CreateOn, - CreateBy = invoiceTax.CreateBy, + CreateBy = SecurityContext.CurrentAccount.ID, LastModifedBy = invoiceTax.LastModifedBy, LastModifedOn = invoiceTax.LastModifedOn, TenantId = TenantID @@ -183,47 +186,33 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) CRMDbContext.InvoiceTax.Add(itemToInsert); CRMDbContext.SaveChanges(); - - //invoiceTax.ID = Db.ExecuteScalar( - // Insert("crm_invoice_tax") - // .InColumnValue("id", 0) - // .InColumnValue("name", invoiceTax.Name) - // .InColumnValue("description", invoiceTax.Description) - // .InColumnValue("rate", invoiceTax.Rate) - // .InColumnValue("create_on", invoiceTax.CreateOn) - // .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - // .InColumnValue("last_modifed_on", invoiceTax.LastModifedOn) - // .InColumnValue("last_modifed_by", invoiceTax.LastModifedBy) - // .Identity(1, 0, true)); - - - + + invoiceTax.ID = itemToInsert.Id; } else { - var oldInvoiceTax = GetByID(invoiceTax.ID); - + var oldInvoiceTax = GetByID(invoiceTax.ID); + CRMSecurity.DemandEdit(oldInvoiceTax); + + var itemToUpdate = Query(CRMDbContext.InvoiceTax) + .FirstOrDefault(x => x.Id == invoiceTax.ID); -// throw new NotImplementedException(); + itemToUpdate.Name = invoiceTax.Name; + itemToUpdate.Description = invoiceTax.Description; + itemToUpdate.Rate = invoiceTax.Rate; + itemToUpdate.LastModifedOn = itemToUpdate.LastModifedOn; + itemToUpdate.LastModifedBy = itemToUpdate.LastModifedBy; - CRMDbContext.InvoiceTax.Add(itemToInsert); + CRMDbContext.InvoiceTax.Update(itemToUpdate); CRMDbContext.SaveChanges(); - Db.ExecuteNonQuery( - Update("crm_invoice_tax") - .Set("name", invoiceTax.Name) - .Set("description", invoiceTax.Description) - .Set("rate", invoiceTax.Rate) - .Set("last_modifed_on", invoiceTax.LastModifedOn) - .Set("last_modifed_by", invoiceTax.LastModifedBy) - .Where(Exp.Eq("id", invoiceTax.ID))); } return invoiceTax; } - + public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) { var invoiceTax = GetByID(invoiceTaxID); @@ -240,10 +229,10 @@ public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) CRMDbContext.Attach(invoiceTax); CRMDbContext.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CRMDbContext.SaveChanges(); - /* _cache.Remove(_invoiceItemCacheKey); - _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ + /* _cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ return invoiceTax; } @@ -251,29 +240,21 @@ private InvoiceTax ToInvoiceTax(DbInvoiceTax dbInvoiceTax) { if (dbInvoiceTax == null) return null; - return new InvoiceTax + var result = new InvoiceTax { ID = dbInvoiceTax.Id, Name = dbInvoiceTax.Name, Description = dbInvoiceTax.Description, Rate = dbInvoiceTax.Rate, - CreateOn = dbInvoiceTax.CreateOn, + CreateOn = TenantUtil.DateTimeFromUtc(dbInvoiceTax.CreateOn), CreateBy = dbInvoiceTax.CreateBy, - LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoiceTax.LastModifedOn), - LastModifedBy = dbInvoiceTax.LastModifedBy + LastModifedBy = dbInvoiceTax.LastModifedBy }; - //return new InvoiceTax - // { - // ID = Convert.ToInt32(row[0]), - // Name = Convert.ToString(row[1]), - // Description = Convert.ToString(row[2]), - // Rate = Convert.ToDecimal(row[3]), - // CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[4].ToString())), - // CreateBy = ToGuid(row[5]), - // LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[6].ToString())), - // LastModifedBy = ToGuid(row[7]) - // }; + if (dbInvoiceTax.LastModifedOn.HasValue) + result.LastModifedOn = TenantUtil.DateTimeFromUtc(result.LastModifedOn.Value); + + return result; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 99b4111b5cc..29b986b053b 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -55,24 +55,41 @@ using ASC.CRM.Core.EF; using ASC.Core; using ASC.CRM.Classes; +using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; namespace ASC.CRM.Core.Dao { public class CachedRelationshipEventDao : RelationshipEventDao { - private readonly HttpRequestDictionary _contactCache = new HttpRequestDictionary("crm_relationshipEvent"); + private readonly HttpRequestDictionary _contactCache; - public CachedRelationshipEventDao(int tenantID) - : base(tenantID) + public CachedRelationshipEventDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + FilesIntegration filesIntegration, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + SetupInfo setupInfo, + PathProvider pathProvider, + IHttpContextAccessor httpContextAccessor + ) : + base(dbContextManager, + tenantManager, + securityContext, + filesIntegration, + cRMSecurity, + tenantUtil, + setupInfo, + pathProvider) { - + _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_relationshipEvent"); } public override RelationshipEvent GetByID(int eventID) { return _contactCache.Get(eventID.ToString(), () => GetByIDBase(eventID)); - } private RelationshipEvent GetByIDBase(int eventID) @@ -95,7 +112,8 @@ public RelationshipEventDao(DbContextManager dbContextManager, FilesIntegration filesIntegration, CRMSecurity cRMSecurity, TenantUtil tenantUtil, - SetupInfo setupInfo + SetupInfo setupInfo, + PathProvider pathProvider ) : base(dbContextManager, tenantManager, @@ -105,9 +123,12 @@ SetupInfo setupInfo TenantUtil = tenantUtil; CRMSecurity = cRMSecurity; SetupInfo = setupInfo; + PathProvider = pathProvider; } + public PathProvider PathProvider { get; } + public SetupInfo SetupInfo { get; } public CRMSecurity CRMSecurity { get; } @@ -123,7 +144,6 @@ public RelationshipEvent AttachFiles(int contactID, EntityType entityType, int e if (entityID > 0 && !_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var relationshipEvent = new RelationshipEvent { CategoryID = (int)HistoryCategorySystem.FilesUpload, @@ -144,14 +164,25 @@ public void AttachFiles(int eventID, int[] fileIDs) { if (fileIDs.Length == 0) return; - var dao = FilesIntegration.GetTagDao(); + var dao = FilesIntegration.TagDao(); var tags = fileIDs.ToList().ConvertAll(fileID => new Tag("RelationshipEvent_" + eventID, TagType.System, Guid.Empty) { EntryType = FileEntryType.File, EntryId = fileID }); dao.SaveTags(tags); if (fileIDs.Length > 0) - Db.ExecuteNonQuery(Update("crm_relationship_event").Set("have_files", true).Where("id", eventID)); + { + var dbRelationshipEvent = new DbRelationshipEvent + { + Id = eventID, + HaveFiles = true, + TenantId = TenantID + }; + + CRMDbContext.RelationshipEvent.Attach(dbRelationshipEvent); + CRMDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; + CRMDbContext.SaveChanges(); + } } public int GetFilesCount(int[] contactID, EntityType entityType, int entityID) @@ -163,24 +194,24 @@ private object[] GetFilesIDs(int[] contactID, EntityType entityType, int entityI { if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) throw new ArgumentException(); - - var sqlQuery = Query("crm_relationship_event").Select("id"); + + var sqlQuery = Query(CRMDbContext.RelationshipEvent); if (contactID != null && contactID.Length > 0) - sqlQuery.Where(Exp.In("contact_id", contactID)); + sqlQuery = sqlQuery.Where(x => contactID.Contains(x.ContactId)); if (entityID > 0) - sqlQuery.Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType)); + sqlQuery = sqlQuery.Where(x => x.EntityId == entityID && x.EntityType == entityType); - sqlQuery.Where(Exp.Eq("have_files", true)); + sqlQuery = sqlQuery.Where(x => x.HaveFiles); + + var tagNames = sqlQuery.Select(x => String.Format("RelationshipEvent_{0}", x.Id)); + var tagdao = FilesIntegration.TagDao(); + + return tagdao.GetTags(tagNames.ToArray(), TagType.System) + .Where(t => t.EntryType == FileEntryType.File) + .Select(t => t.EntryId).ToArray(); - var tagNames = Db.ExecuteList(sqlQuery).ConvertAll(row => String.Format("RelationshipEvent_{0}", row[0])); - var tagdao = FilesIntegration.GetTagDao(); - - return tagdao.GetTags(tagNames.ToArray(), TagType.System) - .Where(t => t.EntryType == FileEntryType.File) - .Select(t => t.EntryId).ToArray(); - } public List GetAllFiles(int[] contactID, EntityType entityType, int entityID) @@ -197,11 +228,10 @@ public List GetAllFiles(int[] contactID, EntityType entityType, int entity public Dictionary> GetFiles(int[] eventID) { - if (eventID == null || eventID.Length == 0) throw new ArgumentException("eventID"); - var tagdao = FilesIntegration.GetTagDao(); + var tagdao = FilesIntegration.TagDao(); var filedao = FilesIntegration.GetFileDao(); var findedTags = tagdao.GetTags(eventID.Select(item => String.Concat("RelationshipEvent_", item)).ToArray(), @@ -228,7 +258,7 @@ public List GetFiles(int eventID) if (eventID == 0) throw new ArgumentException("eventID"); - var tagdao = FilesIntegration.GetTagDao(); + var tagdao = FilesIntegration.TagDao(); var filedao = FilesIntegration.GetFileDao(); var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); @@ -237,7 +267,6 @@ public List GetFiles(int eventID) files.ForEach(CRMSecurity.SetAccessTo); return files.ToList(); - } private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID) @@ -255,7 +284,6 @@ private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID { dao.DeleteFile(file.ID); } - } public List RemoveFile(File file) @@ -264,7 +292,7 @@ public List RemoveFile(File file) List eventIDs; - var tagdao = FilesIntegration.GetTagDao(); + var tagdao = FilesIntegration.TagDao(); var tags = tagdao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); @@ -278,12 +306,14 @@ public List RemoveFile(File file) { if (GetFiles(eventID).Count == 0) { - - CRMDbContext.Attach(); - - // context.Attach(person); - // context.Entry(person).Property("Name").IsModified = true; - // Db.ExecuteNonQuery(Update("crm_relationship_event").Set("have_files", false).Where("id", eventID)); + var dbRelationshipEvent = new DbRelationshipEvent { + Id = eventID, + HaveFiles = false, + TenantId = TenantID + }; + + CRMDbContext.Attach(dbRelationshipEvent); + CRMDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; CRMDbContext.SaveChanges(); } @@ -306,17 +336,15 @@ public int GetCount(int[] contactID, EntityType entityType, int entityID) if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) throw new ArgumentException(); - var sqlQuery = Query("crm_relationship_event").SelectCount(); - - contactID = contactID.Where(item => item != 0).ToArray(); + var sqlQuery = Query(CRMDbContext.RelationshipEvent); if (contactID.Length > 0) - sqlQuery.Where(Exp.In("contact_id", contactID)); + sqlQuery = sqlQuery.Where(x => contactID.Contains(x.ContactId)); if (entityID > 0) - sqlQuery.Where(Exp.Eq("entity_id", entityID) & Exp.Eq("entity_type", (int)entityType)); + sqlQuery = sqlQuery.Where(x => x.EntityId == entityID && x.EntityType == entityType); - return Db.ExecuteScalar(sqlQuery); + return sqlQuery.Count(); } public RelationshipEvent CreateItem(RelationshipEvent item) @@ -327,6 +355,7 @@ public RelationshipEvent CreateItem(RelationshipEvent item) if (item.CreateOn == DateTime.MinValue) item.CreateOn = TenantUtil.DateTimeNow(); + item.CreateBy = SecurityContext.CurrentAccount.ID; item.LastModifedBy = SecurityContext.CurrentAccount.ID; @@ -335,11 +364,12 @@ public RelationshipEvent CreateItem(RelationshipEvent item) var jsonObj = JObject.Parse(item.Content); var messageId = jsonObj.Value("message_id"); - var apiServer = new Api.ApiServer(); - var msg = apiServer.GetApiResponse( - String.Format("{0}mail/messages/{1}.json?id={1}&loadImages=true&needSanitize=true", SetupInfo.WebApiBaseUrl, messageId), "GET"); + //var apiServer = new ApiServer(); + //var msg = apiServer.GetApiResponse( + // String.Format("{0}mail/messages/{1}.json?id={1}&loadImages=true&needSanitize=true", SetupInfo.WebApiBaseUrl, messageId), "GET"); - if (msg == null) + String msg = null; +// if (msg == null) throw new ArgumentException("Mail message cannot be found"); var msgResponseWrapper = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg))); @@ -378,47 +408,49 @@ public RelationshipEvent CreateItem(RelationshipEvent item) item.CreateOn = DateTime.Parse(msg_date_created, CultureInfo.InvariantCulture); - var sqlQueryFindMailsAlready = Query("crm_relationship_event") - .SelectCount() - .Where("contact_id", item.ContactID) - .Where(Exp.Like("content", string.Format("\"message_id\":{0},", message_id))) - .Where("entity_type", (int)item.EntityType) - .Where("entity_id", item.EntityID) - .Where("category_id", item.CategoryID); - if (Db.ExecuteScalar(sqlQueryFindMailsAlready) > 0) + var sqlQueryFindMailsAlready = Query(CRMDbContext.RelationshipEvent) + .Where(x => x.ContactId == item.ContactID) + .Where(x => x.EntityType == item.EntityType) + .Where(x => x.EntityId == item.EntityID) + .Where(x => x.CategoryId == item.CategoryID) + .Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, String.Format("\"message_id\":{0},", message_id))); + + if (sqlQueryFindMailsAlready.Count() > 0) throw new Exception("Already exists"); } + var itemToInsert = new DbRelationshipEvent + { + ContactId = item.ContactID, + Content = item.Content, + CreateOn = TenantUtil.DateTimeToUtc(item.CreateOn), + CreateBy = item.CreateBy, + EntityType = item.EntityType, + EntityId = item.EntityID, + CategoryId = item.CategoryID, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = item.LastModifedBy, + TenantId = TenantID, + HaveFiles = false + }; + + CRMDbContext.RelationshipEvent.Add(itemToInsert); + CRMDbContext.SaveChanges(); - item.ID = Db.ExecuteScalar( - Insert("crm_relationship_event") - .InColumnValue("id", 0) - .InColumnValue("contact_id", item.ContactID) - .InColumnValue("content", item.Content) - .InColumnValue("create_on", TenantUtil.DateTimeToUtc(item.CreateOn)) - .InColumnValue("create_by", item.CreateBy) - .InColumnValue("entity_type", (int)item.EntityType) - .InColumnValue("entity_id", item.EntityID) - .InColumnValue("category_id", item.CategoryID) - .InColumnValue("last_modifed_on", DateTime.UtcNow) - .InColumnValue("last_modifed_by", item.LastModifedBy) - .InColumnValue("have_files", false) - .Identity(1, 0, true)); + item.ID = itemToInsert.Id; if (item.CreateOn.Kind == DateTimeKind.Utc) item.CreateOn = TenantUtil.DateTimeFromUtc(item.CreateOn); FactoryIndexer.IndexAsync(item); + return item; } public virtual RelationshipEvent GetByID(int eventID) { - - - - return Db.ExecuteList(GetRelationshipEventQuery(Exp.Eq("id", eventID))) - .ConvertAll(ToRelationshipEvent).FirstOrDefault(); + return ToRelationshipEvent(Query(CRMDbContext.RelationshipEvent) + .FirstOrDefault(x => x.Id == eventID)); } public int GetAllItemsCount() @@ -451,54 +483,67 @@ public List GetItems( int count, OrderBy orderBy) { - var sqlQuery = GetRelationshipEventQuery(null); + + var sqlQuery = Query(CRMDbContext.RelationshipEvent); if (entityID > 0) switch (entityType) { case EntityType.Contact: var isCompany = false; - isCompany = Db.ExecuteScalar(Query("crm_contact").Select("is_company").Where(Exp.Eq("id", entityID))); + + isCompany = Query(CRMDbContext.Contacts).Where(x => x.Id == entityID).Select(x => x.IsCompany).Single(); if (isCompany) return GetItems(searchText, EntityType.Company, entityID, createBy, categoryID, fromDate, toDate, from, count, orderBy); else return GetItems(searchText, EntityType.Person, entityID, createBy, categoryID, fromDate, toDate, from, count, orderBy); case EntityType.Person: - sqlQuery.Where(Exp.Eq("contact_id", entityID)); + sqlQuery = sqlQuery.Where(x => x.ContactId == entityID); break; case EntityType.Company: var personIDs = GetRelativeToEntity(entityID, EntityType.Person, null).ToList(); if (personIDs.Count == 0) - sqlQuery.Where(Exp.Eq("contact_id", entityID)); + { + sqlQuery = sqlQuery.Where(x => x.ContactId == entityID); + } else { personIDs.Add(entityID); - sqlQuery.Where(Exp.In("contact_id", personIDs)); + sqlQuery = sqlQuery.Where(x => personIDs.Contains(x.ContactId)); } break; case EntityType.Case: case EntityType.Opportunity: - sqlQuery.Where(Exp.Eq("entity_id", entityID) & - Exp.Eq("entity_type", (int)entityType)); + sqlQuery = sqlQuery.Where(x => x.EntityId == entityID && x.EntityType == entityType); break; } if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) - sqlQuery.Where(Exp.Between("create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1)))); + { + sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); + } else if (fromDate != DateTime.MinValue) - sqlQuery.Where(Exp.Ge("create_on", TenantUtil.DateTimeToUtc(fromDate))); + { + sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate)); + } else if (toDate != DateTime.MinValue) - sqlQuery.Where(Exp.Le("create_on", TenantUtil.DateTimeToUtc(toDate).AddDays(1).AddMinutes(-1))); + { + sqlQuery = sqlQuery.Where(x => x.CreateOn <= TenantUtil.DateTimeToUtc(toDate).AddDays(1).AddMinutes(-1)); + } if (createBy != Guid.Empty) - sqlQuery.Where(Exp.Eq("create_by", createBy)); + { + sqlQuery = sqlQuery.Where(x => x.CreateBy == createBy); + } if (categoryID != 0) - sqlQuery.Where(Exp.Eq("category_id", categoryID)); + { + sqlQuery = sqlQuery.Where(x => x.CategoryId == categoryID); + } if (!String.IsNullOrEmpty(searchText)) { @@ -508,84 +553,73 @@ public List GetItems( .ToArray(); List eventsIds; + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out eventsIds)) { if (keywords.Length > 0) - sqlQuery.Where(BuildLike(new[] { "content" }, keywords)); + { + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, k)); + } + } } else { if (eventsIds.Count == 0) return new List(); - sqlQuery.Where(Exp.In("id", eventsIds)); + + sqlQuery = sqlQuery.Where(x => eventsIds.Contains(x.Id)); } } if (0 < from && from < int.MaxValue) - sqlQuery.SetFirstResult(from); + sqlQuery = sqlQuery.Skip(from); if (0 < count && count < int.MaxValue) - sqlQuery.SetMaxResults(count); + sqlQuery = sqlQuery.Take(count); if (orderBy != null && Enum.IsDefined(typeof(RelationshipEventByType), orderBy.SortedBy)) switch ((RelationshipEventByType)orderBy.SortedBy) { - case RelationshipEventByType.Category: - sqlQuery.OrderBy("category_id", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy(x => x.CategoryId); break; case RelationshipEventByType.Content: - sqlQuery.OrderBy("content", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy(x => x.Content); break; case RelationshipEventByType.CreateBy: - sqlQuery.OrderBy("create_by", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy(x => x.CreateBy); break; case RelationshipEventByType.Created: - sqlQuery.OrderBy("create_on", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy(x => x.CreateOn); break; } else - sqlQuery.OrderBy("create_on", false); + sqlQuery = sqlQuery.OrderBy(x => x.CreateOn); - return Db.ExecuteList(sqlQuery) - .ConvertAll(row => ToRelationshipEvent(row)); + return sqlQuery.ToList().ConvertAll(ToRelationshipEvent); } - private RelationshipEvent ToRelationshipEvent(object[] row) + private RelationshipEvent ToRelationshipEvent(DbRelationshipEvent relationshipEvent) { + if (relationshipEvent == null) return null; + return new RelationshipEvent { - - ID = Convert.ToInt32(row[0]), - ContactID = Convert.ToInt32(row[1]), - Content = Convert.ToString(row[2]), - EntityID = Convert.ToInt32(row[3]), - EntityType = (EntityType)Convert.ToInt32(row[4]), - CreateOn = TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[5])), - CreateBy = ToGuid(row[6]), - CategoryID = Convert.ToInt32(row[7]) + ID = relationshipEvent.Id, + ContactID = relationshipEvent.ContactId, + Content = relationshipEvent.Content, + EntityID = relationshipEvent.EntityId, + EntityType = relationshipEvent.EntityType, + CreateOn = TenantUtil.DateTimeFromUtc(relationshipEvent.CreateOn), + CreateBy = relationshipEvent.CreateBy, + CategoryID = relationshipEvent.CategoryId, + LastModifedBy = relationshipEvent.LastModifedBy, + LastModifedOn = relationshipEvent.LastModifedOn }; } - private SqlQuery GetRelationshipEventQuery(Exp where) - { - SqlQuery sqlQuery = Query("crm_relationship_event") - .Select("id", - "contact_id", - "content", - "entity_id", - "entity_type", - "create_on", - "create_by", - "category_id" - ); - - if (where != null) - sqlQuery.Where(where); - - return sqlQuery; - } - public void DeleteItem(int id) { var item = GetByID(id); @@ -606,14 +640,17 @@ public void DeleteItem(RelationshipEvent item) throw new ArgumentException(); relativeFiles.ForEach(f => RemoveFile(f)); - - - - Db.ExecuteNonQuery(Delete("crm_relationship_event").Where(Exp.Eq("id", item.ID))); + var itemToDelete = new DbRelationshipEvent + { + Id = item.ID, + TenantId = TenantID + }; + CRMDbContext.RelationshipEvent.Remove(itemToDelete); + CRMDbContext.SaveChanges(); - FactoryIndexer.DeleteAsync(item); + FactoryIndexer.DeleteAsync(item); } [DataContract] @@ -621,26 +658,37 @@ internal class CrmHistoryContent { [DataMember] public string to; + [DataMember] public string from; + [DataMember] public string cc; + [DataMember] public string bcc; + [DataMember] public string subject; + [DataMember] public bool important; + [DataMember] public string chain_id; + [DataMember] public bool is_sended; + [DataMember] public string date_created; + [DataMember] public string introduction; + [DataMember] public long message_id; + } private static string GetHistoryContentJson(JObject apiResponse) @@ -661,6 +709,7 @@ private static string GetHistoryContentJson(JObject apiResponse) }; var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent)); + using (var stream = new MemoryStream()) { serializer.WriteObject(stream, content_struct); diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 859f432d2f2..883a449e5d7 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -193,36 +193,16 @@ public void DeleteUnusedTags(EntityType entityType) { if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - - using var tx = CRMDbContext.Database.BeginTransaction(); - - - //var temp = from e in CRMDbContext.Tags - // select new { }; - -// Query(CRMDbContext.Tags).Join() -// .Select(x => x.Id); - - //var sqlSubQuery = Query("crm_tag") - // .Select("id") - // .LeftOuterJoin("crm_entity_tag", Exp.EqColumns("tag_id", "id")) - // .Where(Exp.Eq("crm_tag.entity_type", (int)entityType) & Exp.Eq("tag_id", Exp.Empty)); - - //List tagIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => Convert.ToInt32(row[0])); - - // Query(CRMDbContext.Tags).Join() - - - //if (tagIDs.Count > 0) - //{ - // var itemToDelete = Query(CRMDbContext.Tags).Where(x => x.EntityType == entityType && tagIDs.Contains(x.Id)); - - // CRMDbContext.RemoveRange(itemToDelete); - //} - + + var itemToDelete = Query(CRMDbContext.Tags).GroupJoin(CRMDbContext.EntityTags, + x => x.Id, + y => y.TagId, + (x, y) => new { x, y } + ).Where(x => x.x.EntityType == entityType && x.y == null).Select(x => x.x).ToList(); + + CRMDbContext.RemoveRange(itemToDelete); + CRMDbContext.SaveChanges(); - - tx.Commit(); } public int AddTag(EntityType entityType, String tagName, bool returnExisted = false) @@ -432,4 +412,4 @@ private static string CorrectTag(string tag) } } -} +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 0ffff59c331..a05ffb0d648 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -35,6 +35,7 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Globalization; @@ -54,6 +55,7 @@ public CachedTaskDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, TenantUtil tenantUtil, FactoryIndexer factoryIndexer, + IOptionsMonitor logger, IHttpContextAccessor httpContextAccessor ) : base(dbContextManager, @@ -61,7 +63,8 @@ IHttpContextAccessor httpContextAccessor securityContext, cRMSecurity, tenantUtil, - factoryIndexer) + factoryIndexer, + logger) { _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_task"); } @@ -110,7 +113,8 @@ public TaskDao(DbContextManager dbContextManager, SecurityContext securityContext, CRMSecurity cRMSecurity, TenantUtil tenantUtil, - FactoryIndexer factoryIndexer + FactoryIndexer factoryIndexer, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, @@ -119,8 +123,11 @@ FactoryIndexer factoryIndexer CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; FactoryIndexer = factoryIndexer; + Logger = logger.Get("ASC.CRM"); } + public ILog Logger { get; } + public FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } @@ -358,7 +365,7 @@ public int GetTasksCount( int result = 0; - LogManager.GetLogger("ASC.CRM").DebugFormat("Starting GetTasksCount: {0}", DateTime.Now.ToString()); + Logger.DebugFormat("Starting GetTasksCount: {0}", DateTime.Now.ToString()); var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + "tasks" + @@ -373,7 +380,7 @@ public int GetTasksCount( if (!String.IsNullOrEmpty(_cache.Get(cacheKey))) { - LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. From cache", DateTime.Now.ToString()); + Logger.DebugFormat("End GetTasksCount: {0}. From cache", DateTime.Now.ToString()); return Convert.ToInt32(_cache.Get(cacheKey)); } @@ -444,7 +451,8 @@ public int GetTasksCount( taskIds = Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList(); - LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks without entityId and only open contacts", DateTime.Now.ToString()); + + Logger.DebugFormat("End GetTasksCount: {0}. count tasks without entityId and only open contacts", DateTime.Now.ToString()); sqlQuery = Query("crm_task tbl_tsk") @@ -471,8 +479,8 @@ public int GetTasksCount( // count tasks with entityId and only close contacts taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - - LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); + + Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); sqlQuery = Query("crm_task tbl_tsk") .Select("tbl_tsk.id") @@ -499,7 +507,7 @@ public int GetTasksCount( // count tasks with entityId and only close contacts taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); + Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); sqlQuery = Query("crm_task tbl_tsk") @@ -525,7 +533,7 @@ public int GetTasksCount( // count tasks with entityId and without contact taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); + Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); sqlQuery = Query("crm_task tbl_tsk") .Select("tbl_tsk.id") @@ -552,9 +560,9 @@ public int GetTasksCount( result = taskIds.Distinct().Count(); - LogManager.GetLogger("ASC.CRM").DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); + Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); - LogManager.GetLogger("ASC.CRM").Debug("Finish"); + Logger.Debug("Finish"); } } @@ -569,8 +577,7 @@ public int GetTasksCount( } - private SqlQuery WhereConditional( - SqlQuery sqlQuery, + private IQueryable WhereConditional( String alias, Guid responsibleID, int categoryID, @@ -761,7 +768,6 @@ public Dictionary HaveLateTask(int[] contactID) .ToDictionary(x => x.Key, x => x.Any()); } - public bool HaveLateTask(int contactID) { var result = HaveLateTask(new[] { contactID }); @@ -794,7 +800,7 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.CategoryID <= 0) throw new ArgumentException(); - if (newTask.ID == 0 || Db.ExecuteScalar(Query("crm_task").SelectCount().Where(Exp.Eq("id", newTask.ID))) == 0) + if (newTask.ID == 0 || Query(CRMDbContext.Tasks).Where(x => x.Id == newTask.ID).Count() == 0) { newTask.CreateOn = DateTime.UtcNow; newTask.CreateBy = SecurityContext.CurrentAccount.ID; @@ -843,12 +849,31 @@ private Task SaveOrUpdateTaskInDb(Task newTask) } else { - var oldTask = Db.ExecuteList(GetTaskQuery(Exp.Eq("id", newTask.ID))) - .ConvertAll(row => ToTask(row)) - .FirstOrDefault(); + + var itemToUpdate = Query(CRMDbContext.Tasks).FirstOrDefault(x => x.Id == newTask.ID); + + var oldTask = ToTask(itemToUpdate); CRMSecurity.DemandEdit(oldTask); + itemToUpdate.Title = newTask.Title; + itemToUpdate.Description = newTask.Description; + itemToUpdate.Deadline = TenantUtil.DateTimeToUtc(newTask.DeadLine); + itemToUpdate.ResponsibleId = newTask.ResponsibleID; + itemToUpdate.ContactId = newTask.ContactID; + itemToUpdate.EntityType = newTask.EntityType; + itemToUpdate.EntityId = newTask.EntityID; + itemToUpdate.CategoryId = newTask.CategoryID; + itemToUpdate.LastModifedOn = newTask.LastModifedOn; + itemToUpdate.LastModifedBy = newTask.LastModifedBy; + itemToUpdate.AlertValue = newTask.AlertValue; + itemToUpdate.ExecAlert = 0; + itemToUpdate.TenantId = TenantID; + + CRMDbContext.Update(itemToUpdate); + CRMDbContext.SaveChanges(); + + newTask.CreateOn = oldTask.CreateOn; newTask.CreateBy = oldTask.CreateBy; @@ -857,21 +882,6 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.IsClosed = oldTask.IsClosed; - Db.ExecuteNonQuery( - Update("crm_task") - .Set("title", newTask.Title) - .Set("description", newTask.Description) - .Set("deadline", TenantUtil.DateTimeToUtc(newTask.DeadLine)) - .Set("responsible_id", newTask.ResponsibleID) - .Set("contact_id", newTask.ContactID) - .Set("entity_type", (int)newTask.EntityType) - .Set("entity_id", newTask.EntityID) - .Set("category_id", newTask.CategoryID) - .Set("last_modifed_on", newTask.LastModifedOn) - .Set("last_modifed_by", newTask.LastModifedBy) - .Set("alert_value", (int)newTask.AlertValue) - .Set("exec_alert", 0) - .Where(Exp.Eq("id", newTask.ID))); } FactoryIndexer.IndexAsync(newTask); @@ -1017,32 +1027,32 @@ public List CreateByTemplate(List templateItems, EntityType #region Private Methods - private String[] GetTaskColumnsTable(String alias) - { - if (!String.IsNullOrEmpty(alias)) - alias = alias + "."; - - var result = new List - { - "id", - "contact_id", - "title", - "description", - "deadline", - "responsible_id", - "is_closed", - "category_id", - "entity_id", - "entity_type", - "create_on", - "create_by", - "alert_value" - }; - - if (String.IsNullOrEmpty(alias)) return result.ToArray(); - - return result.ConvertAll(item => String.Concat(alias, item)).ToArray(); - } + //private String[] GetTaskColumnsTable(String alias) + //{ + // if (!String.IsNullOrEmpty(alias)) + // alias = alias + "."; + + // var result = new List + // { + // "id", + // "contact_id", + // "title", + // "description", + // "deadline", + // "responsible_id", + // "is_closed", + // "category_id", + // "entity_id", + // "entity_type", + // "create_on", + // "create_by", + // "alert_value" + // }; + + // if (String.IsNullOrEmpty(alias)) return result.ToArray(); + + // return result.ConvertAll(item => String.Concat(alias, item)).ToArray(); + //} //private SqlQuery GetTaskQuery(Exp where, String alias) //{ @@ -1143,8 +1153,8 @@ public Task ToTask(DbTask dbTask) CategoryID = dbTask.CategoryId, ContactID = dbTask.ContactId, CreateBy = dbTask.CreateBy, - CreateOn = dbTask.CreateOn, - DeadLine = dbTask.Deadline, + CreateOn = TenantUtil.DateTimeFromUtc(dbTask.CreateOn), + DeadLine = TenantUtil.DateTimeFromUtc(dbTask.Deadline), Description = dbTask.Description, IsClosed = dbTask.IsClosed, EntityID = dbTask.EntityId, diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 089179710af..0a060e69274 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -65,15 +65,15 @@ public virtual int SaveOrUpdate(TaskTemplateContainer item) if (item.ID == 0 && Query(CRMDbContext.TaskTemplateContainer).Where(x => x.Id == item.ID).Any()) { CRMDbContext.TaskTemplateContainer.Add(dbTaskTemplateContainer); - - item.ID = dbTaskTemplateContainer.Id; - + CRMDbContext.SaveChanges(); + item.ID = dbTaskTemplateContainer.Id; } else { CRMDbContext.TaskTemplateContainer.Attach(dbTaskTemplateContainer); + CRMDbContext.TaskTemplateContainer.Update(dbTaskTemplateContainer); CRMDbContext.SaveChanges(); } @@ -141,48 +141,40 @@ public TaskTemplateDao(DbContextManager dbContextManager, public int SaveOrUpdate(TaskTemplate item) { - if (item.ID == 0) + var itemToInsert = new DbTaskTemplate { - var itemToInsert = new DbTaskTemplate - { - Id = item.ID, - Title = item.Title, - CategoryId = item.CategoryID, - Description = item.Description, - ResponsibleId = item.ResponsibleID, - IsNotify = item.isNotify, - Offset = item.Offset.Ticks, - DeadLineIsFixed = item.DeadLineIsFixed, - ContainerId = item.ContainerID, - CreateOn = DateTime.UtcNow, - CreateBy = SecurityContext.CurrentAccount.ID, - LastModifedOn = DateTime.UtcNow, - LastModifedBy = SecurityContext.CurrentAccount.ID, - TenantId = TenantID - }; + Id = item.ID, + Title = item.Title, + CategoryId = item.CategoryID, + Description = item.Description, + ResponsibleId = item.ResponsibleID, + IsNotify = item.isNotify, + Offset = item.Offset.Ticks, + DeadLineIsFixed = item.DeadLineIsFixed, + ContainerId = item.ContainerID, + CreateOn = item.CreateOn, + CreateBy = item.CreateBy, + TenantId = TenantID + }; + if (item.ID == 0) + { + itemToInsert.CreateOn = DateTime.UtcNow; + itemToInsert.CreateBy = SecurityContext.CurrentAccount.ID; + CRMDbContext.TaskTemplates.Add(itemToInsert); CRMDbContext.SaveChanges(); } else { - //Db.ExecuteNonQuery( - // Update("crm_task_template") - // .Set("title", item.Title) - // .Set("category_id", item.CategoryID) - // .Set("description", item.Description) - // .Set("responsible_id", item.ResponsibleID) - // .Set("is_notify", item.isNotify) - // .Set("offset", item.Offset.Ticks) - // .Set("deadLine_is_fixed", item.DeadLineIsFixed) - // .Set("container_id", item.ContainerID) - // .Set("last_modifed_on", DateTime.UtcNow) - // .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - // .Where("id", item.ID)); - - //CRMDbContext.TaskTemplates.Add(itemToInsert); - //CRMDbContext.SaveChanges(); + itemToInsert.LastModifedOn = DateTime.UtcNow; + itemToInsert.LastModifedBy = SecurityContext.CurrentAccount.ID; + + CRMDbContext.TaskTemplates.Attach(itemToInsert); + CRMDbContext.TaskTemplates.Update(itemToInsert); + + CRMDbContext.SaveChanges(); } return item.ID; @@ -192,37 +184,30 @@ public TaskTemplate GetNext(int taskID) { using var tx = CRMDbContext.Database.BeginTransaction(); - var temp = Query(CRMDbContext.TaskTemplateTask) - .Join(CRMDbContext.TaskTemplates, - x => new { x.TenantId, x.TaskTemplateId }, - y => new { y.TenantId, y.Id }, - (x, y) => new - { - x, y - }); - - //var sqlResult = Db.ExecuteList( - // Query("crm_task_template_task tblTTT") - // .Select("tblTT.container_id") - // .Select("tblTT.sort_order") - // .LeftOuterJoin("crm_task_template tblTT", Exp.EqColumns("tblTT.tenant_id", "tblTTT.tenant_id") & Exp.EqColumns("tblTT.id", "tblTTT.task_template_id")) - // .Where(Exp.Eq("tblTTT.task_id", taskID) & Exp.Eq("tblTT.tenant_id", TenantID))); + var sqlResult = Query(CRMDbContext.TaskTemplateTask) + .Join(Query(CRMDbContext.TaskTemplates), + x => x.TaskTemplateId, + y => y.Id, + (x, y) => new { x, y } + ).Where(x => x.x.TaskId == taskID) + .Select(x => new { x.y.ContainerId, x.y.SortOrder }) + .SingleOrDefault(); - //if (sqlResult.Count == 0) return null; + if (sqlResult == null) return null; - //var result = Db.ExecuteList(GetQuery(Exp.Eq("container_id", sqlResult[0][0]) & - // Exp.Gt("sort_order", sqlResult[0][1]) & - // Exp.Eq("deadLine_is_fixed", false)).SetMaxResults(1)).ConvertAll( - // row => ToObject(row)); + var result = ToObject(Query(CRMDbContext.TaskTemplates) + .FirstOrDefault(x => x.ContainerId == sqlResult.ContainerId && + x.SortOrder > sqlResult.SortOrder && !x.DeadLineIsFixed)); - //Db.ExecuteNonQuery(Delete("crm_task_template_task").Where(Exp.Eq("task_id", taskID))); + CRMDbContext.Remove(new DbTaskTemplateTask + { + TaskId = taskID, + TenantId = TenantID + }); tx.Commit(); -// if (result.Count == 0) return null; - - // return result[0]; - + return result; } public List GetAll() diff --git a/products/ASC.CRM/Server/Core/EF/DbDeal.cs b/products/ASC.CRM/Server/Core/EF/DbDeal.cs index 6b911630961..4cb8b959c45 100644 --- a/products/ASC.CRM/Server/Core/EF/DbDeal.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDeal.cs @@ -79,7 +79,7 @@ public partial class DbDeal : IDbCrm public int PerPeriodValue { get; set; } [Column("deal_milestone_probability", TypeName = "int(11)")] - public int? DealMilestoneProbability { get; set; } + public int DealMilestoneProbability { get; set; } [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbDealMilestone.cs b/products/ASC.CRM/Server/Core/EF/DbDealMilestone.cs index 80014bcac36..1c557c67174 100644 --- a/products/ASC.CRM/Server/Core/EF/DbDealMilestone.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDealMilestone.cs @@ -1,4 +1,5 @@ // This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -12,20 +13,27 @@ public partial class DbDealMilestone : IDbCrm [Key] [Column("id", TypeName = "int(10)")] public int Id { get; set; } + [Required] [Column("color", TypeName = "varchar(50)")] public string Color { get; set; } + [Column("sort_order", TypeName = "int(10)")] public int SortOrder { get; set; } + [Required] [Column("title", TypeName = "varchar(250)")] public string Title { get; set; } + [Column("description", TypeName = "text")] public string Description { get; set; } + [Column("probability", TypeName = "int(10)")] public int Probability { get; set; } + [Column("status", TypeName = "int(10)")] - public int Status { get; set; } + public DealMilestoneStatus Status { get; set; } + [Column("tenant_id", TypeName = "int(10)")] public int TenantId { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/DbInvoiceTax.cs b/products/ASC.CRM/Server/Core/EF/DbInvoiceTax.cs index 5d489e7bd22..bcfef3bd752 100644 --- a/products/ASC.CRM/Server/Core/EF/DbInvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoiceTax.cs @@ -35,7 +35,7 @@ public partial class DbInvoiceTax : IDbCrm public DateTime? LastModifedOn { get; set; } [Column("last_modifed_by", TypeName = "char(38)")] - public Guid LastModifedBy { get; set; } + public Guid? LastModifedBy { get; set; } [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index 137fbe76b6f..a8d7f221725 100644 --- a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -38,7 +38,7 @@ public partial class DbRelationshipEvent : IDbCrm public int CategoryId { get; set; } [Column("last_modifed_by", TypeName = "char(38)")] - public Guid LastModifedBy { get; set; } + public Guid? LastModifedBy { get; set; } [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs index d9e5b5bc3ca..47b7b588417 100644 --- a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs +++ b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs @@ -34,6 +34,7 @@ using System.Text; using ASC.Common.Security; using ASC.Common.Security.Authorizing; +using ASC.CRM.Core.Enums; #endregion diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs index 982e3e7108b..48c42fd4607 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -56,8 +56,6 @@ public class InvoiceTax : DomainObject, ISecurityObjectId [DataMember(Name = "lastModifedBy")] public Guid? LastModifedBy { get; set; } - - public object SecurityId { get { return ID; } diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 70c648cf096..397778ac336 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -32,6 +32,7 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using ASC.Files.Core; using ASC.Web.Core; using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; From 6313464cdf2dcea9db3250651b7baa17eea1ad53 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Thu, 2 Apr 2020 22:42:03 +0300 Subject: [PATCH 06/61] crm: migrate DAO to EF Core --- .../ASC.CRM/Server/Classes/CRMSettings.cs | 40 +- products/ASC.CRM/Server/Classes/Global.cs | 121 +++--- products/ASC.CRM/Server/Classes/VoipEngine.cs | 12 +- .../Server/Configuration/ProductEntryPoint.cs | 83 ++-- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 11 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 61 +-- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 162 ++++---- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 15 +- .../Server/Core/Dao/CurrencyInfoDao.cs | 8 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 14 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 47 ++- .../Server/Core/Dao/DealMilestoneDao.cs | 14 +- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 8 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 334 ++++++++--------- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 136 +++---- .../ASC.CRM/Server/Core/Dao/ManagerDao.cs | 12 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 354 ++++++++++-------- .../Core/Dao/TaskTemplateContainerDao.cs | 15 +- products/ASC.CRM/Server/Core/EF/DbTask.cs | 2 +- .../Server/Core/Security/CRMSecutiry.cs | 71 +--- .../Core/Security/FileSecurityProvider.cs | 45 ++- .../Services/NotifyService/NotifyClient.cs | 75 ++-- .../Services/NotifyService/NotifySource.cs | 21 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 35 +- 24 files changed, 892 insertions(+), 804 deletions(-) diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index 52a6f5ba935..8a1cf522c3b 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -24,16 +24,13 @@ */ -#region Import - +using ASC.Core; using ASC.Core.Common.Settings; using ASC.CRM.Core; +using Microsoft.Extensions.Configuration; using System; using System.Runtime.Serialization; - -#endregion - namespace ASC.Web.CRM.Classes { [Serializable] @@ -95,7 +92,7 @@ public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) [DataContract] public class InvoiceSetting { - public InvoiceSetting() + public InvoiceSetting(IConfiguration configuration) { Autogenerated = false; Prefix = String.Empty; @@ -103,14 +100,16 @@ public InvoiceSetting() Terms = String.Empty; } - public static InvoiceSetting DefaultSettings + public IConfiguration Configuration { get; } + + public InvoiceSetting DefaultSettings { get { - return new InvoiceSetting + return new InvoiceSetting(Configuration) { Autogenerated = true, - Prefix = WebConfigurationManager.AppSettings["crm.invoice.prefix"] ?? "INV-", + Prefix = Configuration["crm:invoice:prefix"] ?? "INV-", Number = "0000001", Terms = String.Empty, CompanyName = String.Empty, @@ -145,8 +144,15 @@ public static InvoiceSetting DefaultSettings [Serializable] [DataContract] - public class CRMSettings : BaseSettings + public class CRMSettings : ISettings { + public CRMSettings(CoreConfiguration coreConfiguration) + { + CoreConfiguration = coreConfiguration; + } + + public CoreConfiguration CoreConfiguration { get; } + [DataMember(Name = "DefaultCurrency")] private string defaultCurrency; @@ -155,7 +161,7 @@ public SMTPServerSetting SMTPServerSetting { get { - return new SMTPServerSetting(CoreContext.Configuration.SmtpSettings); + return new SMTPServerSetting(CoreConfiguration.SmtpSettings); } } @@ -168,7 +174,7 @@ public SMTPServerSetting SMTPServerSetting [DataMember] public Guid WebFormKey { get; set; } - public override Guid ID + public Guid ID { get { return new Guid("fdf39b9a-ec96-4eb7-aeab-63f2c608eada"); } } @@ -208,13 +214,13 @@ public Boolean? AddTagToContactGroupAuto [DataMember(Name = "IsConfiguredSmtp")] public bool IsConfiguredSmtp { get; set; } - public override ISettings GetDefault() + public ISettings GetDefault(IServiceProvider serviceProvider) { var languageName = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; var findedCurrency = CurrencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); - return new CRMSettings + return new CRMSettings(CoreConfiguration) { defaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", IsConfiguredPortal = false, @@ -230,17 +236,17 @@ public override ISettings GetDefault() [Serializable] [DataContract] - public class CRMReportSampleSettings : BaseSettings + public class CRMReportSampleSettings : ISettings { [DataMember(Name = "NeedToGenerate")] public bool NeedToGenerate { get; set; } - public override Guid ID + public Guid ID { get { return new Guid("{54CD64AD-E73B-45A3-89E4-4D42A234D7A3}"); } } - public override ISettings GetDefault() + public ISettings GetDefault(IServiceProvider serviceProvider) { return new CRMReportSampleSettings { NeedToGenerate = true }; } diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index d94a7324609..f612c99a766 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -24,13 +24,17 @@ */ +using ASC.Core; +using ASC.Core.Common.Settings; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.Web.Core; using ASC.Web.Core.Files; using ASC.Web.Studio.Core; +using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; @@ -45,11 +49,30 @@ namespace ASC.Web.CRM.Classes { public class Global { - public Global() + public Global(StorageFactory storageFactory, + SecurityContext securityContext, + SetupInfo setupInfo, + FilesLinkUtility filesLinkUtility, + CRMSecurity cRMSecurity, + TenantManager tenantManager, + SettingsManager settingsManager, + IConfiguration configuration + ) { - + StorageFactory = storageFactory; + FilesLinkUtility = filesLinkUtility; + SetupInfo = setupInfo; + SecurityContext = securityContext; + CRMSecurity = cRMSecurity; + TenantID = tenantManager.GetCurrentTenant().TenantId; + SettingsManager = settingsManager; + Configuration = configuration; } + public IConfiguration Configuration { get; } + + public SettingsManager SettingsManager { get; } + public static readonly int EntryCountOnPage = 25; public static readonly int VisiblePageCount = 10; @@ -64,22 +87,30 @@ public Global() public static readonly int MaxHistoryEventCharacters = 65000; public static readonly decimal MaxInvoiceItemPrice = (decimal) 99999999.99; - public static CRMSettings TenantSettings - { - get { return CRMSettings.Load(); } - } + protected int TenantID { get; private set; } + + public FilesLinkUtility FilesLinkUtility { get; } + + public SetupInfo SetupInfo { get; } + public SecurityContext SecurityContext { get; } - public static IDataStore GetStore() + public StorageFactory StorageFactory { get; } + + public CRMSecurity CRMSecurity { get; } + + + + public IDataStore GetStore() { - return StorageFactory.GetStorage(TenantProvider.CurrentTenantID.ToString(), "crm"); + return StorageFactory.GetStorage(TenantID.ToString(), "crm"); } - public static IDataStore GetStoreTemplate() + public IDataStore GetStoreTemplate() { return StorageFactory.GetStorage(String.Empty, "crm_template"); } - public static bool CanCreateProjects() + public bool CanCreateProjects() { try { @@ -87,22 +118,24 @@ public static bool CanCreateProjects() var cacheKey = String.Format("{0}-{1}", SecurityContext.CurrentAccount.ID, apiUrl); - bool canCreateProject; + bool canCreateProject = false; - if (HttpRuntime.Cache[cacheKey] != null) - return Convert.ToBoolean(HttpRuntime.Cache[cacheKey]); + throw new NotImplementedException(); + //if (HttpRuntime.Cache[cacheKey] != null) + // return Convert.ToBoolean(HttpRuntime.Cache[cacheKey]); - var apiServer = new Api.ApiServer(); + //var apiServer = new Api.ApiServer(); - var responseApi = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(apiServer.GetApiResponse(apiUrl, "GET"))))["response"]; + //var responseApi = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(apiServer.GetApiResponse(apiUrl, "GET"))))["response"]; - if (responseApi.HasValues) - canCreateProject = Convert.ToBoolean(responseApi["canCreateProject"].Value()); - else - canCreateProject = false; - HttpRuntime.Cache.Remove(cacheKey); - HttpRuntime.Cache.Insert(cacheKey, canCreateProject, null, System.Web.Caching.Cache.NoAbsoluteExpiration, - TimeSpan.FromMinutes(5)); + //if (responseApi.HasValues) + // canCreateProject = Convert.ToBoolean(responseApi["canCreateProject"].Value()); + //else + // canCreateProject = false; + + //HttpRuntime.Cache.Remove(cacheKey); + //HttpRuntime.Cache.Insert(cacheKey, canCreateProject, null, System.Web.Caching.Cache.NoAbsoluteExpiration, + // TimeSpan.FromMinutes(5)); return canCreateProject; @@ -114,17 +147,15 @@ public static bool CanCreateProjects() } - public static bool CanDownloadInvoices + public bool CanDownloadInvoices { get { - var canDownloadFiles = false; + var value = Configuration["crm:invoice:download:enable"]; - var value = WebConfigurationManager.AppSettings["crm.invoice.download.enable"]; if (string.IsNullOrEmpty(value)) return false; - canDownloadFiles = Convert.ToBoolean(value); - + bool canDownloadFiles = Convert.ToBoolean(value); if (canDownloadFiles && string.IsNullOrEmpty(FilesLinkUtility.DocServiceConverterUrl)) { canDownloadFiles = false; @@ -134,7 +165,7 @@ public static bool CanDownloadInvoices } } - public static bool CanCreateReports + public bool CanCreateReports { get { @@ -142,20 +173,14 @@ public static bool CanCreateReports } } - #region CRM Settings - - public static void SaveDefaultCurrencySettings(CurrencyInfo currency) + public void SaveDefaultCurrencySettings(CurrencyInfo currency) { - var tenantSettings = TenantSettings; - tenantSettings.DefaultCurrency = currency; - tenantSettings.Save(); + var tenantSettings = SettingsManager.Load(); + tenantSettings.DefaultCurrency = currency; + SettingsManager.Save(tenantSettings); } - - #endregion - - #region Invoice PDF - - public static ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) + + public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) { var existingFile = invoice.GetInvoiceFile(factory); if (existingFile != null) @@ -172,8 +197,6 @@ public static ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Ent } } - #endregion - //Code snippet public static String GetUpButtonHTML(Uri requestUrlReferrer) @@ -271,9 +294,7 @@ public static byte[] ToByteArray(Stream inputStream) br.Close(); return br.ToArray(); } - - #region CRM Images download - + public static string GetImgFormatName(ImageFormat format) { if (format.Equals(ImageFormat.Bmp)) return "bmp"; @@ -294,11 +315,7 @@ public static byte[] SaveToBytes(Image img) { return CommonPhotoManager.SaveToBytes(img, GetImgFormatName(img.RawFormat)); } - - #endregion - - #region Parse JOjbect with ApiDateTime - + private static readonly string[] Formats = new[] { "o", @@ -328,8 +345,6 @@ public static JObject JObjectParseWithDateAsString(string data) ); reader.DateParseHandling = DateParseHandling.None; return JObject.Load(reader); - } - - #endregion + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index 467a79bd7e5..001b142dbde 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -24,22 +24,21 @@ */ -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.Common.Logging; using ASC.Common.Threading.Workers; using ASC.Core; using ASC.Core.Tenants; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.VoipService; using ASC.VoipService.Dao; using ASC.Web.CRM.Core; -using ASC.Web.CRM.Core.Enums; -using ASC.Web.CRM.Resources; using Autofac; +using System; +using System.Collections.Generic; +using System.Linq; namespace ASC.Web.CRM.Classes { @@ -53,6 +52,7 @@ public VoipEngine(DaoFactory daoFactory) { this.daoFactory = daoFactory; } + public VoipCall SaveOrUpdateCall(VoipCall callHistory) { var dao = daoFactory.VoipDao; diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index 17f9a8871a1..ebf2d1387ce 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -23,9 +23,9 @@ * */ - using ASC.Common.Logging; using ASC.Core; +using ASC.Core.Common.Settings; using ASC.Core.Configuration; using ASC.CRM.Core; using ASC.CRM.Core.Dao; @@ -36,7 +36,9 @@ using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core; using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Api; using Autofac; +using Microsoft.Extensions.Options; using System; using System.Linq; @@ -48,29 +50,51 @@ public class ProductEntryPoint : Product public ProductEntryPoint(SecurityContext securityContext, UserManager userManager, PathProvider pathProvider, - DaoFactory daoFactory) + DaoFactory daoFactory, + FilesIntegration filesIntegration, + IOptionsMonitor logger, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CoreConfiguration coreConfiguration, + Global global) { SecurityContext = securityContext; UserManager = userManager; PathProvider = pathProvider; DaoFactory = daoFactory; + FilesIntegration = filesIntegration; + Logger = logger.Get("ASC"); + CRMSecurity = cRMSecurity; + SettingsManager = settingsManager; + CoreConfiguration = coreConfiguration; + Global = global; } - - #region Property - - #endregion - public static readonly Guid ID = WebItemManager.CRMProductID; + private ProductContext context; private static readonly object Locker = new object(); private static bool registered; + + public Global Global { get; } + + public CoreConfiguration CoreConfiguration { get; } + + public ILog Logger { get; } + + public SettingsManager SettingsManager { get; } + + public CRMSecurity CRMSecurity { get; } + + public FilesIntegration FilesIntegration { get; } public DaoFactory DaoFactory { get; } public PathProvider PathProvider { get; } + public SecurityContext SecurityContext { get; } + public UserManager UserManager { get; } // TODO: CRM: Реализовать проперти ApiURL @@ -105,7 +129,6 @@ public override string Description public string ModuleSysName { get; set; } - public override void Init() { context = new ProductContext @@ -122,26 +145,26 @@ public override void Init() if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) { - FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider()); + FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider(FilesIntegration, CRMSecurity)); } if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "opportunity")) { - FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", new FileSecurityProvider()); + FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", new FileSecurityProvider(FilesIntegration, CRMSecurity)); } - SearchHandlerManager.Registry(new SearchHandler()); +// SearchHandlerManager.Registry(new SearchHandler()); - GlobalConfiguration.Configuration.Routes.MapHttpRoute( - name: "Twilio", - routeTemplate: "twilio/{action}", - defaults: new {controller = "Twilio", action = "index" }); + //GlobalConfiguration.Configuration.Routes.MapHttpRoute( + // name: "Twilio", + // routeTemplate: "twilio/{action}", + // defaults: new {controller = "Twilio", action = "index" }); // ClientScriptLocalization = new ClientLocalizationResources(); DIHelper.Register(); } - public static void ConfigurePortal() + public void ConfigurePortal() { if (!Global.TenantSettings.IsConfiguredPortal) { @@ -165,6 +188,7 @@ public static void ConfigurePortal() // Deal Milestone New var milestoneDao = daoFactory.DealMilestoneDao; + milestoneDao.Create(new DealMilestone { Title = CRMDealResource.DealMilestone_InitialContact_Title, @@ -267,16 +291,22 @@ public static void ConfigurePortal() daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Staff, true); var tenantSettings = Global.TenantSettings; + tenantSettings.WebFormKey = Guid.NewGuid(); tenantSettings.IsConfiguredPortal = true; - tenantSettings.Save(); + + if (!SettingsManager.Save(tenantSettings)) + { + throw new Exception("not save CRMSettings"); + } } } if (!Global.TenantSettings.IsConfiguredSmtp) { - var smtp = CRMSettings.Load().SMTPServerSettingOld; - if (smtp != null && CoreContext.Configuration.SmtpSettings.IsDefaultSettings) + var smtp = SettingsManager.Load().SMTPServerSettingOld; + + if (smtp != null && CoreConfiguration.SmtpSettings.IsDefaultSettings) { try { @@ -290,18 +320,25 @@ public static void ConfigurePortal() if (!string.IsNullOrEmpty(smtp.HostLogin) && !string.IsNullOrEmpty(smtp.HostPassword)) { newSettings.SetCredentials(smtp.HostLogin, smtp.HostPassword); - } + } - CoreContext.Configuration.SmtpSettings = newSettings; + CoreConfiguration.SmtpSettings = newSettings; + } catch (Exception e) { - LogManager.GetLogger("ASC").Error("ConfigurePortal", e); + Logger.Error("ConfigurePortal", e); } } + var tenantSettings = Global.TenantSettings; tenantSettings.IsConfiguredSmtp = true; - tenantSettings.Save(); + + if (!SettingsManager.Save(tenantSettings)) + { + throw new Exception("not save CRMSettings"); + } + } } diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index c1f741dcf05..a7b94050044 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -35,25 +35,30 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao { public class AbstractDao { protected readonly List _supportedEntityType = new List(); - protected readonly ILog _log = LogManager.GetLogger("ASC.CRM"); - + public CRMDbContext CRMDbContext { get; } public SecurityContext SecurityContext { get; } protected readonly ICache _cache; + public ILog Logger { get; } public AbstractDao( DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext + SecurityContext securityContext, + IOptionsMonitor logger ) { + + Logger = logger.Get("ASC.CRM"); + _cache = AscCache.Memory; CRMDbContext = dbContextManager.Get(CRMConstants.DatabaseId); TenantID = tenantManager.GetCurrentTenant().TenantId; diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 1bba88fa689..078c92ca16e 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -43,6 +43,8 @@ using OrderBy = ASC.CRM.Core.Entities.OrderBy; using Microsoft.EntityFrameworkCore; using SortedByType = ASC.CRM.Core.Enums.SortedByType; +using Microsoft.Extensions.Options; +using ASC.Common.Logging; namespace ASC.CRM.Core.Dao { @@ -57,6 +59,7 @@ public CachedCasesDao(DbContextManager dbContextManager, TenantUtil tenantUtil, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, + IOptionsMonitor logger, IHttpContextAccessor httpContextAccessor) : base(dbContextManager, @@ -65,7 +68,8 @@ public CachedCasesDao(DbContextManager dbContextManager, cRMSecurity, tenantUtil, filesIntegration, - authorizationManager) + authorizationManager, + logger) { _casesCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_cases"); @@ -111,11 +115,13 @@ public CasesDao( CRMSecurity cRMSecurity, TenantUtil tenantUtil, FilesIntegration filesIntegration, - AuthorizationManager authorizationManager + AuthorizationManager authorizationManager, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; @@ -302,7 +308,7 @@ public virtual Cases DeleteCases(int casesID) public virtual List DeleteBatchCases(List caseses) { caseses = caseses.FindAll(CRMSecurity.CanDelete).ToList(); - + if (!caseses.Any()) return caseses; // Delete relative keys @@ -318,7 +324,7 @@ public virtual List DeleteBatchCases(int[] casesID) if (casesID == null || !casesID.Any()) return null; var cases = GetCases(casesID).FindAll(CRMSecurity.CanDelete).ToList(); - + if (!cases.Any()) return cases; // Delete relative keys @@ -338,7 +344,7 @@ private void DeleteBatchCasesExecute(List caseses) var tagNames = Query(CRMDbContext.RelationshipEvent) .Where(x => x.HaveFiles && casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case) .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); - + var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); using var tx = CRMDbContext.Database.BeginTransaction(); @@ -356,7 +362,7 @@ private void DeleteBatchCasesExecute(List caseses) CRMDbContext.Cases.RemoveRange(caseses.ConvertAll(x => new DbCase { - Id = x.ID + Id = x.ID })); CRMDbContext.SaveChanges(); @@ -425,23 +431,22 @@ public int GetCasesCount( if (withParams) { var dbCasesQuery = GetDbCasesByFilters(exceptIDs, searchText, contactID, isClosed, tags); - + result = dbCasesQuery != null ? dbCasesQuery.Count() : 0; - + } else { var countWithoutPrivate = Query(CRMDbContext.Cases).Count(); - + var privateCount = exceptIDs.Count; if (privateCount > countWithoutPrivate) { - _log.ErrorFormat(@"Private cases count more than all cases. Tenant: {0}. CurrentAccount: {1}", + Logger.ErrorFormat(@"Private cases count more than all cases. Tenant: {0}. CurrentAccount: {1}", TenantID, SecurityContext.CurrentAccount.ID); - privateCount = 0; } @@ -455,7 +460,7 @@ public int GetCasesCount( } return result; - + } @@ -482,8 +487,8 @@ private IQueryable GetDbCasesByFilters( { if (!BundleSearch.TrySelectCase(searchText, out ids)) { - foreach(var k in keywords) - { + foreach (var k in keywords) + { result = result.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k)); } } @@ -498,12 +503,12 @@ private IQueryable GetDbCasesByFilters( { var sqlQuery = CRMDbContext.EntityContact .Where(x => x.ContactId == contactID && x.EntityType == EntityType.Case); - + if (ids.Count > 0) sqlQuery = sqlQuery.Where(x => ids.Contains(x.EntityId)); ids = sqlQuery.Select(x => x.EntityId).ToList(); - + if (ids.Count == 0) return null; } @@ -565,24 +570,26 @@ public List GetCases( if (dbCasesQuery == null) return new List(); - if (0 < from && from < int.MaxValue) dbCasesQuery.Skip(from); - if (0 < count && count < int.MaxValue) dbCasesQuery.Take(count); + if (0 < from && from < int.MaxValue) dbCasesQuery = dbCasesQuery.Skip(from); + if (0 < count && count < int.MaxValue) dbCasesQuery = dbCasesQuery.Take(count); - dbCasesQuery = dbCasesQuery.OrderBy(x => x.IsClosed); + dbCasesQuery = dbCasesQuery.OrderBy("IsClosed", orderBy.IsAsc); if (orderBy != null && Enum.IsDefined(typeof(Enums.SortedByType), orderBy.SortedBy)) + { switch ((SortedByType)orderBy.SortedBy) { case SortedByType.Title: - dbCasesQuery = dbCasesQuery.OrderBy(x => x.Title); + dbCasesQuery = dbCasesQuery.OrderBy("Title", orderBy.IsAsc); break; case SortedByType.CreateBy: - dbCasesQuery = dbCasesQuery.OrderBy(x => x.CreateBy); + dbCasesQuery = dbCasesQuery.OrderBy("CreateBy", orderBy.IsAsc); break; case SortedByType.DateAndTime: - dbCasesQuery = dbCasesQuery.OrderBy(x => x.CreateOn); + dbCasesQuery = dbCasesQuery.OrderBy("CreateOn", orderBy.IsAsc); break; } + } return dbCasesQuery.ToList().ConvertAll(ToCases); @@ -597,8 +604,8 @@ public List GetCasesByPrefix(String prefix, int from, int count) var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); - var q = Query(CRMDbContext.Cases); - + var q = Query(CRMDbContext.Cases); + if (keywords.Length == 1) { q = q.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, keywords[0])); @@ -610,12 +617,12 @@ public List GetCasesByPrefix(String prefix, int from, int count) q = q.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k)); } } - + if (0 < from && from < int.MaxValue) q = q.Skip(from); if (0 < count && count < int.MaxValue) q = q.Take(count); q = q.OrderBy(x => x.Title); - + return q.ToList().ConvertAll(ToCases).FindAll(CRMSecurity.CanAccessTo); } diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index a9784e31891..61b8de6811b 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -25,7 +25,9 @@ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; +using ASC.Core.Caching; using ASC.Core.Common.EF; using ASC.Core.Tenants; using ASC.CRM.Core.EF; @@ -37,10 +39,12 @@ using ASC.Web.Files.Api; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Linq.Expressions; using System.Text.RegularExpressions; using OrderBy = ASC.CRM.Core.Entities.OrderBy; @@ -60,7 +64,9 @@ public CachedContactDao( AuthorizationManager authorizationManager, FilesIntegration filesIntegration, FactoryIndexer factoryIndexerContactsWrapper, - FactoryIndexer factoryIndexerEmailWrapper) : + FactoryIndexer factoryIndexerEmailWrapper, + IOptionsMonitor logger, + DbContextManager coreDbContext) : base(dbContextManager, tenantManager, securityContext, @@ -69,7 +75,9 @@ public CachedContactDao( authorizationManager, filesIntegration, factoryIndexerContactsWrapper, - factoryIndexerEmailWrapper) + factoryIndexerEmailWrapper, + logger, + coreDbContext) { _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact"); } @@ -128,11 +136,14 @@ public ContactDao( AuthorizationManager authorizationManager, FilesIntegration filesIntegration, FactoryIndexer factoryIndexerContactsWrapper, - FactoryIndexer factoryIndexerEmailWrapper + FactoryIndexer factoryIndexerEmailWrapper, + IOptionsMonitor logger, + DbContextManager coreDbContext ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; @@ -140,8 +151,11 @@ FactoryIndexer factoryIndexerEmailWrapper FilesIntegration = filesIntegration; FactoryIndexerContactsWrapper = factoryIndexerContactsWrapper; FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; + CoreDbContext = coreDbContext.Value; } + public CoreDbContext CoreDbContext { get; } + public FactoryIndexer FactoryIndexerEmailWrapper { get; } public FactoryIndexer FactoryIndexerContactsWrapper { get; } public FilesIntegration FilesIntegration { get; } @@ -158,71 +172,51 @@ public List GetContactsByPrefix(String prefix, int searchType, int from var keywords = prefix.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - var query = Query(CRMDbContext.Contacts); + var sqlQuery = Query(CRMDbContext.Contacts); switch (searchType) { case 0: // Company - query = query.Where(x => x.IsCompany); + sqlQuery = sqlQuery.Where(x => x.IsCompany); break; case 1: // Persons - query = query.Where(x => !x.IsCompany); + sqlQuery = sqlQuery.Where(x => !x.IsCompany); break; case 2: // PersonsWithoutCompany - query = query.Where(x => x.CompanyId == 0 && !x.IsCompany); + sqlQuery = sqlQuery.Where(x => x.CompanyId == 0 && !x.IsCompany); break; case 3: // CompaniesAndPersonsWithoutCompany - query = query.Where(x => x.CompanyId == 0); + sqlQuery = sqlQuery.Where(x => x.CompanyId == 0); break; } foreach (var k in keywords) { - query = query.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k)); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k)); } + sqlQuery = sqlQuery.OrderBy(x => x.DisplayName); + if (!CRMSecurity.IsAdmin) { - var sharedContacts = Exp.Gt("c.is_shared", 0); - - var oldContacts = Exp.And(Exp.Eq("c.is_shared", null), !ExistAclRecord(false, "c")); + var idsFromAcl = CoreDbContext.Acl.Where(x => x.Tenant == TenantID && + x.Action == CRMSecurity._actionRead.ID && + x.Subject == SecurityContext.CurrentAccount.ID && + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName. )) + .Select(x => Convert.ToInt32(x.Object.Split('|', StringSplitOptions.None)[1])) + .ToList(); - var privateContacts = Exp.And(Exp.Eq("c.is_shared", 0), ExistAclRecord(true, "c")); - - query = query.Where(Exp.Or(sharedContacts, Exp.Or(oldContacts, privateContacts))); - - query = query.Where(x => x.IsShared >= 0 || (x.IsShared == null && )); + objectId.ObjectType.FullName + // oldContacts || publicContact || contact is private, but user is ManagerContact + sqlQuery = sqlQuery.Where(x => x.IsShared == null || x.IsShared > 0 || idsFromAcl.Contains(x.Id)); } - query = query.OrderBy(x => x.DisplayName); - - if (0 < from && from < int.MaxValue) query = query.Skip(from); - if (0 < count && count < int.MaxValue) query = query.Take(count); - - return query.ToList().ConvertAll(ToContact); - } - - private Exp ExistAclRecord(bool forCurrentUser, string contactTebleAlias = "") - { - var alias = string.IsNullOrEmpty(contactTebleAlias) ? string.Empty : contactTebleAlias + "."; - - var query = new SqlQuery("core_acl a") - .Select("a.object") - .Where(Exp.EqColumns("a.tenant", alias + "tenant_id")) - .Where(Exp.Eq("a.action", CRMSecurity._actionRead.ID)); - - if (forCurrentUser) - query.Where(Exp.Eq("a.subject", SecurityContext.CurrentAccount.ID)); - query.Where( - Exp.Or( - Exp.EqColumns("a.object", string.Format("concat('ASC.CRM.Core.Entities.Company|', {0}id)", alias)), - Exp.EqColumns("a.object", string.Format("concat('ASC.CRM.Core.Entities.Person|', {0}id)", alias)) - ) - ); + if (0 < from && from < int.MaxValue) sqlQuery = sqlQuery.Skip(from); + if (0 < count && count < int.MaxValue) sqlQuery = sqlQuery.Take(count); - return Exp.Exists(query); + return sqlQuery.ToList().ConvertAll(ToContact); } public int GetAllContactsCount() @@ -389,7 +383,7 @@ public int GetContactsCount(String searchText, if (privateCount > countWithoutPrivate) { - _log.Error("Private contacts count more than all contacts"); + Logger.Error("Private contacts count more than all contacts"); privateCount = 0; } @@ -702,7 +696,7 @@ private IQueryable GetDbContactsByFilters( List contactsIds; if (!BundleSearch.TrySelectContact(searchText, out contactsIds)) { - _log.Debug("FullTextSearch.SupportModule('CRM.Contacts') = false"); + Logger.Debug("FullTextSearch.SupportModule('CRM.Contacts') = false"); foreach (var k in keywords) { @@ -711,8 +705,8 @@ private IQueryable GetDbContactsByFilters( } else { - _log.Debug("FullTextSearch.SupportModule('CRM.Contacts') = true"); - _log.DebugFormat("FullTextSearch.Search: searchText = {0}", searchText); + Logger.Debug("FullTextSearch.SupportModule('CRM.Contacts') = true"); + Logger.DebugFormat("FullTextSearch.Search: searchText = {0}", searchText); var full_text_ids = contactsIds; @@ -748,13 +742,13 @@ private IQueryable GetDbContactsByFilters( case ContactListViewType.Company: { sqlQuery = sqlQuery.Where(x => x.IsCompany); - + break; } case ContactListViewType.Person: { sqlQuery = sqlQuery.Where(x => !x.IsCompany); - + break; } case ContactListViewType.WithOpportunity: @@ -780,7 +774,7 @@ private IQueryable GetDbContactsByFilters( if (contactStage >= 0) sqlQuery = sqlQuery.Where(x => x.StatusId == contactStage); - + if (contactType >= 0) sqlQuery = sqlQuery.Where(x => x.ContactTypeId == contactType); @@ -803,11 +797,11 @@ private IQueryable GetDbContactsByFilters( if (isShared.Value) { - sqlQuery = sqlQuery.Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : x.IsShared == null ); + sqlQuery = sqlQuery.Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : x.IsShared == null); } else { - sqlQuery = sqlQuery.Where(x => x.IsShared.HasValue ? x.IsShared == ShareType.None : x.IsShared == null); + sqlQuery = sqlQuery.Where(x => x.IsShared.HasValue ? x.IsShared == ShareType.None : x.IsShared == null); } } @@ -884,66 +878,66 @@ private List GetCrudeContacts( if (0 < from && from < int.MaxValue) dbContactsQuery = dbContactsQuery.Skip(from); if (0 < count && count < int.MaxValue) dbContactsQuery = dbContactsQuery.Take(count); - + if (orderBy != null) { if (!Enum.IsDefined(typeof(ContactSortedByType), orderBy.SortedBy.ToString())) + { orderBy.SortedBy = ContactSortedByType.Created; + } switch ((ContactSortedByType)orderBy.SortedBy) { case ContactSortedByType.DisplayName: - dbContactsQuery = dbContactsQuery.OrderBy(x => x.DisplayName); + dbContactsQuery = dbContactsQuery.OrderBy("DisplayName", orderBy.IsAsc); break; case ContactSortedByType.Created: - dbContactsQuery = dbContactsQuery.OrderBy(x => x.CreateOn); + dbContactsQuery = dbContactsQuery.OrderBy("CreateOn", orderBy.IsAsc); break; case ContactSortedByType.ContactType: - dbContactsQuery = dbContactsQuery.OrderBy(x => x.StatusId); + + dbContactsQuery = dbContactsQuery.OrderBy("StatusId", orderBy.IsAsc); + break; case ContactSortedByType.FirstName: - dbContactsQuery = dbContactsQuery.OrderBy(x => x.FirstName); - dbContactsQuery = dbContactsQuery.OrderBy(x => x.LastName); + { + dbContactsQuery = dbContactsQuery.OrderBy("FirstName", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy("LastName", orderBy.IsAsc); + } + break; case ContactSortedByType.LastName: - dbContactsQuery = dbContactsQuery.OrderBy(x => x.LastName); - dbContactsQuery = dbContactsQuery.OrderBy(x => x.FirstName); + { + dbContactsQuery = dbContactsQuery.OrderBy("LastName", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy("FirstName", orderBy.IsAsc); + } break; case ContactSortedByType.History: - - throw new NotImplementedException(); - - //dbContactsQuery.GroupJoin(Query(CRMDbContext.RelationshipEvent), - // x => x.Id, - // y => y.ContactId, - // (x, y) => new { x, y }) - // .OrderBy(x => x.y?.Select(x=>x.LastModifedOn)) + { + dbContactsQuery = dbContactsQuery.GroupJoin(Query(CRMDbContext.RelationshipEvent), + x => x.Id, + y => y.ContactId, + (x, y) => new { x, y }) + .OrderBy(x => x.y.Max(x => x.LastModifedOn)) + .ThenBy(x => x.x.CreateOn) + .Select(x => x.x); - //sqlQuery.Select("last_event_modifed_on"); - //var subSqlQuery = Query("crm_relationship_event") - // .Select("contact_id") - // .Select("max(last_modifed_on) as last_event_modifed_on") - // .Where(Exp.Gt("contact_id", 0)) - // .GroupBy("contact_id"); - //sqlQuery.LeftOuterJoin(subSqlQuery, "evt", Exp.EqColumns("id", "evt.contact_id")); - //sqlQuery.OrderBy("last_event_modifed_on", orderBy.IsAsc); - //sqlQuery.OrderBy("create_on", orderBy.IsAsc); + } - //dbContactsQuery = dbContactsQuery.OrderBy(x => x.la); - // dbContactsQuery = dbContactsQuery.OrderBy(x => x.CreateOn); break; default: - dbContactsQuery = dbContactsQuery.OrderBy(x => x.DisplayName); + { + dbContactsQuery = dbContactsQuery.OrderBy("DisplayName", orderBy.IsAsc); + } + break; } } - var data = Db.ExecuteList(sqlQuery); - - var contacts = data.ConvertAll(ToContact); + var contacts = dbContactsQuery.ToList().ConvertAll(ToContact); return selectIsSharedInNewScheme && isShared.HasValue ? contacts.Where(c => (isShared.Value ? c.ShareType != ShareType.None : c.ShareType == ShareType.None)).ToList() : diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index f77176798fd..5408d7a96aa 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -24,6 +24,7 @@ */ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Tenants; @@ -33,6 +34,7 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; @@ -48,12 +50,14 @@ public CachedContactInfo( TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - IHttpContextAccessor httpContextAccessor) + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger) : base( dbContextManager, tenantManager, securityContext, - tenantUtil) + tenantUtil, + logger) { _contactInfoCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact_info"); } @@ -103,10 +107,13 @@ public ContactInfoDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - TenantUtil tenantUtil) + TenantUtil tenantUtil, + IOptionsMonitor logger + ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { TenantUtil = tenantUtil; } diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index c2751af60ee..9971a7649fe 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -27,9 +27,11 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; +using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao { @@ -38,10 +40,12 @@ public class CurrencyInfoDao : AbstractDao public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext): + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 9f46425e35e..6bd112a7544 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -23,6 +23,7 @@ * */ +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Tenants; @@ -33,6 +34,7 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; @@ -47,11 +49,13 @@ public CustomFieldDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - TenantUtil tenantUtil + TenantUtil tenantUtil, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { TenantUtil = tenantUtil; } @@ -215,7 +219,8 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) } if (customFieldType == CustomFieldType.SelectBox) { - _log.Error(ex); + Logger.Error(ex); + throw ex; } } @@ -357,7 +362,8 @@ public void EditItem(CustomField customField) } catch (Exception ex) { - _log.Error(ex); + Logger.Error(ex); + throw ex; } diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 5b936b39ae0..e12a8651a0f 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Tenants; @@ -37,6 +38,7 @@ using ASC.Web.Files.Api; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Globalization; @@ -56,13 +58,15 @@ public CachedDealDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, FactoryIndexer factoryIndexer, FilesIntegration filesIntegration, - IHttpContextAccessor httpContextAccessor) + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, securityContext, cRMSecurity, factoryIndexer, - filesIntegration) + filesIntegration, + logger) { _dealCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal"); } @@ -109,10 +113,12 @@ public DealDao(DbContextManager dbContextManager, SecurityContext securityContext, CRMSecurity cRMSecurity, FactoryIndexer factoryIndexer, - FilesIntegration filesIntegration) : + FilesIntegration filesIntegration, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { CRMSecurity = cRMSecurity; FactoryIndexer = factoryIndexer; @@ -485,7 +491,7 @@ public int GetDealsCount(String searchText, if (privateCount > countWithoutPrivate) { - _log.Error("Private deals count more than all deals"); + Logger.Error("Private deals count more than all deals"); privateCount = 0; } @@ -620,9 +626,10 @@ private List GetCrudeDeals( if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) { + sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); } - else if (withParams && whereConditional == null) + else if (withParams && sqlQuery == null) { return new List(); } @@ -642,23 +649,23 @@ private List GetCrudeDeals( { case DealSortedByType.Title: { - sqlQuery = sqlQuery.OrderBy(x => x.Title); + sqlQuery = sqlQuery.OrderBy("Title", orderBy.IsAsc); break; } case DealSortedByType.BidValue: { - sqlQuery = sqlQuery.OrderBy(x => x.BidValue); + sqlQuery = sqlQuery.OrderBy("BidValue", orderBy.IsAsc); break; } case DealSortedByType.Responsible: { sqlQuery = sqlQuery.OrderBy(x => x.ResponsibleId) - .OrderBy(x => x.ContactId) - .OrderBy(x => x.ActualCloseDate) - .OrderBy(x => x.ExpectedCloseDate) - .OrderBy(x => x.Title); + .ThenBy(x => x.ContactId) + .ThenByDescending(x => x.ActualCloseDate) + .ThenBy(x => x.ExpectedCloseDate) + .ThenBy(x => x.Title); throw new NotImplementedException(); //sqlQuery.OrderBy("tblDeal.responsible_id", orderBy.IsAsc) @@ -674,15 +681,15 @@ private List GetCrudeDeals( { sqlQuery = sqlQuery .OrderBy(x => x.ContactId) - .OrderBy(x => x.ActualCloseDate) - .OrderBy(x => x.ExpectedCloseDate) - .OrderBy(x => x.Title); + .ThenByDescending(x => x.ActualCloseDate) + .ThenBy(x => x.ExpectedCloseDate) + .ThenBy(x => x.Title); sqlQuery.OrderBy("tblDM.sort_order", orderBy.IsAsc) - .OrderBy("tblDeal.contact_id", true) - .OrderBy("tblDeal.actual_close_date", false) - .OrderBy("tblDeal.expected_close_date", true) - .OrderBy("tblDeal.title", true); + .ThenBy("tblDeal.contact_id", true) + .ThenBy("tblDeal.actual_close_date", false) + .ThenBy("tblDeal.expected_close_date", true) + .ThenBy("tblDeal.title", true); break; @@ -702,7 +709,7 @@ private List GetCrudeDeals( { sqlQuery = sqlQuery.OrderBy(x => x.ContactId) - .OrderBy(x => x.Title); + .ThenBy(x => x.Title); //sqlQuery.OrderBy("tblDM.sort_order", true) // .OrderBy("tblDeal.contact_id", true) diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index a9f7d4a98ae..9033266b5d4 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -27,6 +27,7 @@ #region Import using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; @@ -34,6 +35,7 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; @@ -49,10 +51,12 @@ public class CachedDealMilestoneDao : DealMilestoneDao public CachedDealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IHttpContextAccessor httpContextAccessor) + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { _dealMilestoneCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal_milestone"); @@ -110,10 +114,12 @@ public class DealMilestoneDao : AbstractDao public DealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) : + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 84157e9f254..8006f126c69 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -27,11 +27,13 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; using ASC.Files.Core; using ASC.Web.Files.Api; +using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao { @@ -40,10 +42,12 @@ public class FileDao : AbstractDao public FileDao(FilesIntegration filesIntegration, DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext): + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { FilesIntegration = filesIntegration; } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index c90ab754896..03fd9e65d35 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -25,8 +25,10 @@ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; +using ASC.Core.Common.Settings; using ASC.Core.Tenants; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; @@ -35,6 +37,8 @@ using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -54,11 +58,18 @@ public CachedInvoiceDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, FactoryIndexer factoryIndexer, - IHttpContextAccessor httpContextAccessor) + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger, + SettingsManager settingsManager, + InvoiceSetting invoiceSetting) : base(dbContextManager, tenantManager, securityContext, - factoryIndexer) + factoryIndexer, + logger, + settingsManager, + invoiceSetting + ) { _invoiceCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice"); } @@ -109,14 +120,23 @@ public InvoiceDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - FactoryIndexer factoryIndexer) + FactoryIndexer factoryIndexer, + IOptionsMonitor logger, + SettingsManager settingsManager, + InvoiceSetting invoiceSetting) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { FactoryIndexer = factoryIndexer; + SettingsManager = settingsManager; } + public InvoiceSetting InvoiceSetting { get; } + + public SettingsManager SettingsManager { get; } + public FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } @@ -126,7 +146,7 @@ public Boolean IsExist(int invoiceID) { return IsExistFromDb(invoiceID); } - + public Boolean IsExistFromDb(int invoiceID) { return Query(CRMDbContext.Invoices).Where(x => x.Id == invoiceID).Any(); @@ -143,7 +163,7 @@ public Boolean IsExistFromDb(string number) .Where(x => x.Number == number) .Any(); } - + public virtual List GetAll() { return Query(CRMDbContext.Invoices) @@ -171,7 +191,7 @@ public virtual Invoice GetByIDFromDb(int id) public Invoice GetByNumber(string number) { - return ToInvoice(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Number == number)); + return ToInvoice(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Number == number)); } public Invoice GetByFileId(Int32 fileID) @@ -279,56 +299,68 @@ public List GetCrudeInvoices( int from, int count, OrderBy orderBy) - { - var invoicesTableAlias = "i_tbl"; - - var sqlQuery = GetInvoiceSqlQuery(null, invoicesTableAlias); - + { var withParams = hasParams(searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); + + var sqlQuery = GetDbInvoceByFilters(new List(), searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); - var whereConditional = WhereConditional(invoicesTableAlias, new List(), searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); - // WhereConditional(CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(), searchText); - - if (withParams && whereConditional == null) + if (withParams && sqlQuery == null) return new List(); - sqlQuery.Where(whereConditional); - - if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); - if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + if (0 < from && from < int.MaxValue) sqlQuery = sqlQuery.Skip(from); + if (0 < count && count < int.MaxValue) sqlQuery = sqlQuery.Take(count); if (orderBy != null && Enum.IsDefined(typeof(InvoiceSortedByType), orderBy.SortedBy)) { switch ((InvoiceSortedByType)orderBy.SortedBy) { case InvoiceSortedByType.Number: - sqlQuery.OrderBy(invoicesTableAlias + ".number", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("Number", orderBy.IsAsc); break; case InvoiceSortedByType.Status: - sqlQuery.OrderBy(invoicesTableAlias + ".status", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("Status", orderBy.IsAsc); break; case InvoiceSortedByType.DueDate: - sqlQuery.OrderBy(invoicesTableAlias + ".due_date", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("DueDate", orderBy.IsAsc); break; case InvoiceSortedByType.IssueDate: - sqlQuery.OrderBy(invoicesTableAlias + ".issue_date", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("IssueDate", orderBy.IsAsc); break; case InvoiceSortedByType.Contact: - sqlQuery.LeftOuterJoin("crm_contact c_tbl", Exp.EqColumns(invoicesTableAlias + ".contact_id", "c_tbl.id") & Exp.EqColumns(invoicesTableAlias + ".tenant_id", "c_tbl.tenant_id")) - .OrderBy("case when c_tbl.display_name is null then 1 else 0 end, c_tbl.display_name", orderBy.IsAsc) - .OrderBy(invoicesTableAlias + ".number", true); + + var subSqlQuery = sqlQuery.GroupJoin(CRMDbContext.Contacts, + x => x.ContactId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }); + + if (orderBy.IsAsc) + { + subSqlQuery = subSqlQuery.OrderBy(x => x.y != null ? x.y.DisplayName : "") + .ThenBy(x => x.x.Number); + } + else + { + subSqlQuery = subSqlQuery.OrderByDescending(x => x.y != null ? x.y.DisplayName : "") + .ThenBy(x => x.x.Number); + + } + + sqlQuery = subSqlQuery.Select(x => x.x); + break; default: - sqlQuery.OrderBy(invoicesTableAlias + ".number", true); + sqlQuery = sqlQuery.OrderBy("Number", orderBy.IsAsc); + break; } } else { - sqlQuery.OrderBy(invoicesTableAlias + ".number", true); + sqlQuery = sqlQuery.OrderBy("Number", orderBy.IsAsc); } - return Db.ExecuteList(sqlQuery).ConvertAll(ToInvoice); + return sqlQuery.ToList().ConvertAll(ToInvoice); } public int GetAllInvoicesCount() @@ -370,10 +402,10 @@ public int GetInvoicesCount( if (withParams) { - var whereConditional = WhereConditional(null, exceptIDs, searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); + var sqlQuery = GetDbInvoceByFilters(exceptIDs, searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); - result = whereConditional != null ? Db.ExecuteScalar(Query("crm_invoice").Where(whereConditional).SelectCount()) : 0; - + result = sqlQuery != null ? sqlQuery.Count() : 0; + } else { @@ -383,7 +415,7 @@ public int GetInvoicesCount( if (privateCount > countWithoutPrivate) { - _log.ErrorFormat(@"Private invoice count more than all cases. Tenant: {0}. CurrentAccount: {1}", + Logger.ErrorFormat(@"Private invoice count more than all cases. Tenant: {0}. CurrentAccount: {1}", TenantID, SecurityContext.CurrentAccount.ID); @@ -434,7 +466,7 @@ public List GetEntityInvoices(EntityType entityType, int entityID) public List GetContactInvoices(int contactID) { var result = new List(); - + if (contactID <= 0) return result; @@ -451,7 +483,7 @@ public string GetNewInvoicesNumber() if (!settings.Autogenerated) return string.Empty; - var stringNumber = Query(CRMDbContext.Invoices).OrderByDescending(x => x.Id).Select(x => x.Number).ToString(); + var stringNumber = Query(CRMDbContext.Invoices).OrderByDescending(x => x.Id).Select(x => x.Number).ToString(); if (string.IsNullOrEmpty(stringNumber) || !stringNumber.StartsWith(settings.Prefix)) return string.Concat(settings.Prefix, settings.Number); @@ -476,14 +508,16 @@ public string GetNewInvoicesNumber() public InvoiceSetting GetSettings() { - return Global.TenantSettings.InvoiceSetting ?? InvoiceSetting.DefaultSettings; + var tenantSettings = SettingsManager.Load(); + + return tenantSettings.InvoiceSetting ?? InvoiceSetting.DefaultSettings; } - + public virtual int SaveOrUpdateInvoice(Invoice invoice) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); - var result = SaveOrUpdateInvoiceInDb(invoice); + var result = SaveOrUpdateInvoiceInDb(invoice); FactoryIndexer.IndexAsync(invoice); @@ -501,52 +535,25 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) String.IsNullOrEmpty(invoice.Terms)) throw new ArgumentException(); - + invoice.PurchaseOrderNumber = !String.IsNullOrEmpty(invoice.PurchaseOrderNumber) ? invoice.PurchaseOrderNumber : String.Empty; if (!IsExistFromDb(invoice.ID)) { if (IsExistFromDb(invoice.Number)) throw new ArgumentException(); - - - //invoice.ID = Db.ExecuteScalar( - // Insert("crm_invoice") - // .InColumnValue("id", 0) - // .InColumnValue("status", (int)invoice.Status) - // .InColumnValue("number", invoice.Number) - // .InColumnValue("issue_date", TenantUtil.DateTimeToUtc(invoice.IssueDate)) - // .InColumnValue("template_type", invoice.TemplateType) - // .InColumnValue("contact_id", invoice.ContactID) - // .InColumnValue("consignee_id", invoice.ConsigneeID) - // .InColumnValue("entity_type", (int)invoice.EntityType) - // .InColumnValue("entity_id", invoice.EntityID) - // .InColumnValue("due_date", TenantUtil.DateTimeToUtc(invoice.DueDate)) - // .InColumnValue("language", invoice.Language) - // .InColumnValue("currency", invoice.Currency) - // .InColumnValue("exchange_rate", invoice.ExchangeRate) - // .InColumnValue("purchase_order_number", invoice.PurchaseOrderNumber) - // .InColumnValue("terms", invoice.Terms) - // .InColumnValue("description", invoice.Description) - // .InColumnValue("json_data", null) - // .InColumnValue("file_id", 0) - // .InColumnValue("create_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) - // .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - // .InColumnValue("last_modifed_on", invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn) - // .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - // .Identity(1, 0, true)); var itemToInsert = new DbInvoice { Status = invoice.Status, Number = invoice.Number, - IssueDate = invoice.IssueDate, + IssueDate = TenantUtil.DateTimeToUtc(invoice.IssueDate), TemplateType = invoice.TemplateType, ContactId = invoice.ContactID, ConsigneeId = invoice.ConsigneeID, EntityType = invoice.EntityType, EntityId = invoice.EntityID, - DueDate = invoice.DueDate, + DueDate = TenantUtil.DateTimeToUtc(invoice.DueDate), Language = invoice.Language, Currency = invoice.Currency, ExchangeRate = invoice.ExchangeRate, @@ -567,38 +574,38 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) CRMDbContext.SaveChanges(); invoice.ID = itemToInsert.Id; - + } else { + var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoice.ID); - var oldInvoice = Db.ExecuteList(GetInvoiceSqlQuery(Exp.Eq("id", invoice.ID), null)) - .ConvertAll(ToInvoice) - .FirstOrDefault(); + var oldInvoice = ToInvoice(itemToUpdate); CRMSecurity.DemandEdit(oldInvoice); - Db.ExecuteNonQuery( - Update("crm_invoice") - .Set("status", (int)invoice.Status) - .Set("issue_date", TenantUtil.DateTimeToUtc(invoice.IssueDate)) - .Set("template_type", invoice.TemplateType) - .Set("contact_id", invoice.ContactID) - .Set("consignee_id", invoice.ConsigneeID) - .Set("entity_type", (int)invoice.EntityType) - .Set("entity_id", invoice.EntityID) - .Set("due_date", TenantUtil.DateTimeToUtc(invoice.DueDate)) - .Set("language", invoice.Language) - .Set("currency", invoice.Currency) - .Set("exchange_rate", invoice.ExchangeRate) - .Set("purchase_order_number", invoice.PurchaseOrderNumber) - .Set("terms", invoice.Terms) - .Set("description", invoice.Description) - .Set("json_data", null) - .Set("file_id", 0) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", invoice.ID))); + itemToUpdate.Status = invoice.Status; + itemToUpdate.IssueDate = TenantUtil.DateTimeToUtc(invoice.IssueDate); + itemToUpdate.TemplateType = invoice.TemplateType; + itemToUpdate.ContactId = invoice.ContactID; + itemToUpdate.ConsigneeId = invoice.ConsigneeID; + itemToUpdate.EntityType = invoice.EntityType; + itemToUpdate.EntityId = invoice.EntityID; + itemToUpdate.DueDate = TenantUtil.DateTimeToUtc(invoice.DueDate); + itemToUpdate.Language = invoice.Language; + itemToUpdate.Currency = invoice.Currency; + itemToUpdate.ExchangeRate = invoice.ExchangeRate; + itemToUpdate.PurchaseOrderNumber = invoice.PurchaseOrderNumber; + itemToUpdate.Description = invoice.Description; + itemToUpdate.JsonData = null; + itemToUpdate.FileId = 0; + itemToUpdate.LastModifedOn = DateTime.UtcNow; + itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.TenantId = TenantID; + + CRMDbContext.SaveChanges(); + + } return invoice.ID; @@ -632,7 +639,7 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) var invoice = GetByIDFromDb(invoiceid); if (invoice == null) { - _log.Error("Invoice not found"); + Logger.Error("Invoice not found"); return null; } @@ -640,7 +647,8 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) if (!invoiceStatusMap.Contains(new KeyValuePair(invoice.Status, status))) { - _log.ErrorFormat("Status for invoice with ID={0} can't be changed. Return without changes", invoiceid); + Logger.ErrorFormat("Status for invoice with ID={0} can't be changed. Return without changes", invoiceid); + return invoice; } @@ -652,12 +660,12 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CRMDbContext.SaveChanges(); invoice.Status = status; - + return invoice; - + } public virtual int UpdateInvoiceJsonData(int invoiceId, string jsonData) @@ -715,20 +723,21 @@ private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) sqlToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; CRMDbContext.Update(sqlToUpdate); - CRMDbContext.SaveChanges(); + CRMDbContext.SaveChanges(); return invoiceId; } public InvoiceSetting SaveInvoiceSettings(InvoiceSetting invoiceSetting) { - var tenantSettings = Global.TenantSettings; + var tenantSettings = SettingsManager.Load(); tenantSettings.InvoiceSetting = invoiceSetting; - tenantSettings.Save(); + + SettingsManager.Save(tenantSettings); return tenantSettings.InvoiceSetting; } - + public virtual Invoice DeleteInvoice(int invoiceID) { if (invoiceID <= 0) return null; @@ -764,34 +773,34 @@ private void DeleteBatchInvoicesExecute(List invoices) var invoiceID = invoices.Select(x => x.ID).ToArray(); using var tx = CRMDbContext.Database.BeginTransaction(); - + CRMDbContext.InvoiceLine.RemoveRange(Query(CRMDbContext.InvoiceLine).Where(x => invoiceID.Contains(x.InvoiceId))); CRMDbContext.Invoices.RemoveRange(Query(CRMDbContext.Invoices).Where(x => invoiceID.Contains(x.Id))); CRMDbContext.SaveChanges(); tx.Commit(); - + invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(invoice)); - + } private Invoice ToInvoice(DbInvoice dbInvoice) { if (dbInvoice == null) return null; - return new Invoice + var result = new Invoice { ID = dbInvoice.Id, Status = dbInvoice.Status, Number = dbInvoice.Number, - IssueDate = dbInvoice.IssueDate, + IssueDate = TenantUtil.DateTimeFromUtc(dbInvoice.IssueDate), TemplateType = dbInvoice.TemplateType, ContactID = dbInvoice.ContactId, ConsigneeID = dbInvoice.ConsigneeId, EntityType = dbInvoice.EntityType, EntityID = dbInvoice.EntityId, - DueDate = dbInvoice.DueDate, + DueDate = TenantUtil.DateTimeFromUtc(dbInvoice.DueDate), Language = dbInvoice.Language, Currency = dbInvoice.Currency, ExchangeRate = dbInvoice.ExchangeRate, @@ -800,41 +809,20 @@ private Invoice ToInvoice(DbInvoice dbInvoice) Description = dbInvoice.Description, JsonData = dbInvoice.JsonData, FileID = dbInvoice.FileId, - CreateOn = dbInvoice.CreateOn, + CreateOn = TenantUtil.DateTimeFromUtc(dbInvoice.CreateOn), CreateBy = dbInvoice.CreateBy, - LastModifedOn = dbInvoice.LastModifedOn, LastModifedBy = dbInvoice.LastModifedBy }; + if (dbInvoice.LastModifedOn.HasValue) + { + result.LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoice.LastModifedOn.Value); + } - //return new Invoice - //{ - // ID = Convert.ToInt32(row[0]), - // Status = (InvoiceStatus)Convert.ToInt32(row[1]), - // Number = Convert.ToString(row[2]), - // IssueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[3].ToString())), - // TemplateType = (InvoiceTemplateType)Convert.ToInt32(row[4]), - // ContactID = Convert.ToInt32(row[5]), - // ConsigneeID = Convert.ToInt32(row[6]), - // EntityType = (EntityType)Convert.ToInt32(row[7]), - // EntityID = Convert.ToInt32(row[8]), - // DueDate = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[9].ToString())), - // Language = Convert.ToString(row[10]), - // Currency = Convert.ToString(row[11]), - // ExchangeRate = Convert.ToDecimal(row[12]), - // PurchaseOrderNumber = Convert.ToString(row[13]), - // Terms = Convert.ToString(row[14]), - // Description = Convert.ToString(row[15]), - // JsonData = Convert.ToString(row[16]), - // FileID = Convert.ToInt32(row[17]), - // CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[18].ToString())), - // CreateBy = ToGuid(row[19]), - // LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[20].ToString())), - // LastModifedBy = ToGuid(row[21]) - //}; - } - - private Expression WhereConditional( + return result; + } + + private IQueryable GetDbInvoceByFilters( ICollection exceptIDs, String searchText, InvoiceStatus? status, @@ -845,22 +833,22 @@ private Expression WhereConditional( EntityType entityType, int entityID, String currency) - { - var conditions = new List(); + { + var sqlQuery = Query(CRMDbContext.Invoices); + + if (entityID > 0) + { - if (entityID > 0) { - switch (entityType) { case EntityType.Contact: case EntityType.Person: case EntityType.Company: - conditions.Add(Exp.Eq(tblAliasPrefix + "contact_id", entityID)); + sqlQuery = sqlQuery.Where(x => x.ContactId == entityID); break; case EntityType.Case: case EntityType.Opportunity: - conditions.Add(Exp.Eq(tblAliasPrefix + "entity_id", entityID) & - Exp.Eq(tblAliasPrefix + "entity_type", (int)entityType)); + sqlQuery = sqlQuery.Where(x => x.EntityId == entityID && x.EntityType == entityType); break; } @@ -868,10 +856,9 @@ private Expression WhereConditional( if (status != null) { - conditions.Add(Exp.Eq(tblAliasPrefix + "status", (int)status.Value)); + sqlQuery = sqlQuery.Where(x => x.Status == status.Value); } - if (!String.IsNullOrEmpty(searchText)) { searchText = searchText.Trim(); @@ -884,43 +871,56 @@ private Expression WhereConditional( List invoicesIds; if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out invoicesIds)) { - conditions.Add(BuildLike(new[] {tblAliasPrefix + "number", tblAliasPrefix + "description"}, keywords)); + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Number, k) || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k)); + } } else { - conditions.Add(Exp.In(tblAliasPrefix + "id", invoicesIds)); + sqlQuery = sqlQuery.Where(x => invoicesIds.Contains(x.Id)); } } } if (exceptIDs.Count > 0) { - conditions.Add(!Exp.In(tblAliasPrefix + "id", exceptIDs.ToArray())); + sqlQuery = sqlQuery.Where(x => !exceptIDs.Contains(x.Id)); } if (issueDateFrom != DateTime.MinValue && issueDateTo != DateTime.MinValue) - conditions.Add(Exp.Between(tblAliasPrefix + "issue_date", TenantUtil.DateTimeToUtc(issueDateFrom), TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1)))); + { + sqlQuery = sqlQuery.Where(x => x.IssueDate >= TenantUtil.DateTimeToUtc(issueDateFrom) && x.DueDate <= TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1))); + } else if (issueDateFrom != DateTime.MinValue) - conditions.Add(Exp.Ge(tblAliasPrefix + "issue_date", TenantUtil.DateTimeToUtc(issueDateFrom))); + { + sqlQuery = sqlQuery.Where(x => x.IssueDate > TenantUtil.DateTimeToUtc(issueDateFrom)); + } else if (issueDateTo != DateTime.MinValue) - conditions.Add(Exp.Le(tblAliasPrefix + "issue_date", TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1)))); - + { + sqlQuery = sqlQuery.Where(x => x.IssueDate < TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1))); + } if (dueDateFrom != DateTime.MinValue && dueDateTo != DateTime.MinValue) - conditions.Add(Exp.Between(tblAliasPrefix + "due_date", TenantUtil.DateTimeToUtc(dueDateFrom), TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1)))); + { + sqlQuery = sqlQuery.Where(x => x.DueDate >= TenantUtil.DateTimeToUtc(dueDateFrom) && x.DueDate <= TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1))); + } else if (dueDateFrom != DateTime.MinValue) - conditions.Add(Exp.Ge(tblAliasPrefix + "due_date", TenantUtil.DateTimeToUtc(dueDateFrom))); + { + sqlQuery = sqlQuery.Where(x => x.DueDate > TenantUtil.DateTimeToUtc(dueDateFrom)); + } else if (dueDateTo != DateTime.MinValue) - conditions.Add(Exp.Le(tblAliasPrefix + "due_date", TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1)))); + { + sqlQuery = sqlQuery.Where(x => x.DueDate < TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1))); + } if (!String.IsNullOrEmpty(currency)) { - conditions.Add(Exp.Eq(tblAliasPrefix + "currency", currency)); + sqlQuery = sqlQuery.Where(x => x.Currency == currency); } - if (conditions.Count == 0) return null; - - return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + return sqlQuery; } private bool hasParams( @@ -939,14 +939,14 @@ private bool hasParams( dueDateFrom == DateTime.MinValue && dueDateTo == DateTime.MinValue && entityID == 0 && String.IsNullOrEmpty(currency)); } - + /// /// Test method /// /// /// public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) - { + { var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); itemToUpdate.CreateOn = TenantUtil.DateTimeToUtc(creationDate); @@ -964,15 +964,15 @@ public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) /// /// public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) - { + { var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate); - + CRMDbContext.Invoices.Update(itemToUpdate); CRMDbContext.SaveChanges(); - + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index a9192ee03c9..c5b22383bf6 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Tenants; @@ -32,6 +33,8 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.CRM.Classes; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Globalization; @@ -41,20 +44,24 @@ namespace ASC.CRM.Core.Dao { public class CachedInvoiceItemDao : InvoiceItemDao { - private readonly HttpRequestDictionary _invoiceItemCache = new HttpRequestDictionary("crm_invoice_item"); + private readonly HttpRequestDictionary _invoiceItemCache; public CachedInvoiceItemDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - CRMSecurity cRMSecurity + CRMSecurity cRMSecurity, + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, - securityContext, + securityContext, tenantUtil, - cRMSecurity) + cRMSecurity, + logger) { + _invoiceItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_item"); } public override InvoiceItem GetByID(int invoiceItemID) @@ -95,10 +102,12 @@ public InvoiceItemDao( TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - CRMSecurity cRMSecurity + CRMSecurity cRMSecurity, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { TenantUtil = tenantUtil; CRMSecurity = cRMSecurity; @@ -168,7 +177,7 @@ public List GetInvoiceItems( var whereConditional = WhereConditional(new List(), searchText, status, inventoryStock); - // WhereConditional(CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(), searchText); + // WhereConditional(CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(), searchText); if (withParams && whereConditional == null) return new List(); @@ -248,10 +257,10 @@ public int GetInvoiceItemsCount( if (privateCount > countWithoutPrivate) { - _log.ErrorFormat(@"Private invoice items count more than all cases. Tenant: {0}. CurrentAccount: {1}", - TenantID, + _log.ErrorFormat(@"Private invoice items count more than all cases. Tenant: {0}. CurrentAccount: {1}", + TenantID, SecurityContext.CurrentAccount.ID); - + privateCount = 0; } @@ -283,7 +292,8 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) if (!CRMSecurity.IsAdmin) CRMSecurity.CreateSecurityException(); - if (String.IsNullOrEmpty(invoiceItem.Description)) { + if (String.IsNullOrEmpty(invoiceItem.Description)) + { invoiceItem.Description = String.Empty; } if (String.IsNullOrEmpty(invoiceItem.StockKeepingUnit)) @@ -311,7 +321,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) .Identity(1, 0, true)); - invoiceItem.CreateOn = DateTime.UtcNow; + invoiceItem.CreateOn = DateTime.UtcNow; invoiceItem.LastModifedOn = invoiceItem.CreateOn; invoiceItem.CreateBy = SecurityContext.CurrentAccount.ID; invoiceItem.LastModifedBy = invoiceItem.CreateBy; @@ -354,10 +364,13 @@ public virtual InvoiceItem DeleteInvoiceItem(int invoiceItemID) CRMSecurity.DemandDelete(invoiceItem); + CRMDbContext.Remove(new DbInvoiceItem + { + Id = invoiceItemID, + TenantId = TenantID + }); - - -// Db.ExecuteNonQuery(Delete("crm_invoice_item").Where("id", invoiceItemID)); + CRMDbContext.SaveChanges(); /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ @@ -370,6 +383,7 @@ public virtual List DeleteBatchInvoiceItems(int[] invoiceItemIDs) if (invoiceItemIDs == null || !invoiceItemIDs.Any()) return null; var items = GetInvoiceItems(invoiceItemIDs).Where(CRMSecurity.CanDelete).ToList(); + if (!items.Any()) return items; // Delete relative keys @@ -383,18 +397,18 @@ public virtual List DeleteBatchInvoiceItems(int[] invoiceItemIDs) private void DeleteBatchItemsExecute(List items) { - var ids = items.Select(x => x.ID).ToArray(); + CRMDbContext.RemoveRange(items.ConvertAll(x => new DbInvoiceItem + { + Id = x.ID, + TenantId = TenantID + })); - //using (var tx = db.BeginTransaction(true)) - ///{ - Db.ExecuteNonQuery(Delete("crm_invoice_item").Where(Exp.In("id", ids))); - // tx.Commit(); - //} + CRMDbContext.SaveChanges(); } private InvoiceItem ToInvoiceItem(DbInvoiceItem dbInvoiceItem) { - return new InvoiceItem + var result = new InvoiceItem { ID = dbInvoiceItem.Id, Title = dbInvoiceItem.Title, @@ -408,57 +422,42 @@ private InvoiceItem ToInvoiceItem(DbInvoiceItem dbInvoiceItem) Currency = dbInvoiceItem.Currency, CreateOn = TenantUtil.DateTimeFromUtc(dbInvoiceItem.CreateOn), CreateBy = dbInvoiceItem.CreateBy, - LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoiceItem.LastModifedOn), LastModifedBy = dbInvoiceItem.LastModifedBy }; + if (result.LastModifedOn.HasValue) + result.LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoiceItem.LastModifedOn.Value); + return result; - //return new InvoiceItem - // { - // ID = Convert.ToInt32(row[0]), - // Title = Convert.ToString(row[1]), - // Description = Convert.ToString(row[2]), - // StockKeepingUnit = Convert.ToString(row[3]), - // Price = Convert.ToDecimal(row[4]), - // StockQuantity = Convert.ToDecimal(row[5]), - // TrackInventory = Convert.ToBoolean(row[6]), - // InvoiceTax1ID = Convert.ToInt32(row[7]), - // InvoiceTax2ID = Convert.ToInt32(row[8]), - // Currency = Convert.ToString(row[9]), - // CreateOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[10].ToString())), - // CreateBy = ToGuid(row[11]), - // LastModifedOn = TenantUtil.DateTimeFromUtc(DateTime.Parse(row[12].ToString())), - // LastModifedBy = ToGuid(row[13]) - // }; } - private SqlQuery GetInvoiceItemSqlQuery(Exp where) - { - var sqlQuery = Query("crm_invoice_item") - .Select( - "id", - "title", - "description", - "stock_keeping_unit", - "price", - "stock_quantity", - "track_inventory", - "invoice_tax1_id", - "invoice_tax2_id", - "currency", - "create_on", - "create_by", - "last_modifed_on", - "last_modifed_by"); - - if (where != null) - { - sqlQuery.Where(where); - } - - return sqlQuery; - } + //private SqlQuery GetInvoiceItemSqlQuery(Exp where) + //{ + // var sqlQuery = Query("crm_invoice_item") + // .Select( + // "id", + // "title", + // "description", + // "stock_keeping_unit", + // "price", + // "stock_quantity", + // "track_inventory", + // "invoice_tax1_id", + // "invoice_tax2_id", + // "currency", + // "create_on", + // "create_by", + // "last_modifed_on", + // "last_modifed_by"); + + // if (where != null) + // { + // sqlQuery.Where(where); + // } + + // return sqlQuery; + //} private Exp WhereConditional( ICollection exceptIDs, @@ -491,7 +490,7 @@ private Exp WhereConditional( // if (ids.Count == 0) return null; //} //else - conditions.Add(BuildLike(new[] {"title", "description", "stock_keeping_unit" }, keywords)); + conditions.Add(BuildLike(new[] { "title", "description", "stock_keeping_unit" }, keywords)); } if (exceptIDs.Count > 0) @@ -500,7 +499,8 @@ private Exp WhereConditional( } - if (inventoryStock.HasValue) { + if (inventoryStock.HasValue) + { conditions.Add(Exp.Eq("track_inventory", inventoryStock.Value)); } diff --git a/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs b/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs index 688bb1a58b1..1699f71a972 100644 --- a/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs @@ -26,20 +26,10 @@ #region Import +using ASC.Core.Users; using System; using System.Collections.Generic; using System.Linq; -using ASC.CRM.Core.Entities; -using ASC.Common.Data.Sql.Expressions; -using ASC.Core.Users; -using ASC.Files.Core; -using ASC.Web.Core.Utility.Skins; -using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Configuration; -using ASC.Web.Files.Api; -using ASC.Web.Studio.Helpers; -using ASC.Web.Studio.Utility; -using log4net; #endregion diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index a05ffb0d648..2680e7ba4c7 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -35,6 +35,7 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; @@ -48,7 +49,7 @@ public class CachedTaskDao : TaskDao { private readonly HttpRequestDictionary _contactCache; - + public CachedTaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -114,24 +115,27 @@ public TaskDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, TenantUtil tenantUtil, FactoryIndexer factoryIndexer, - IOptionsMonitor logger + IOptionsMonitor logger, + DbContextManager coreDbContext ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; FactoryIndexer = factoryIndexer; - Logger = logger.Get("ASC.CRM"); + CoreDbContext = coreDbContext.Value; + } - public ILog Logger { get; } + public CoreDbContext CoreDbContext { get; } public FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } - + public CRMSecurity CRMSecurity { get; } public void OpenTask(int taskId) @@ -195,31 +199,31 @@ public int GetAllTasksCount() public List GetAllTasks() { - return Query(CRMDbContext.Tasks) - .OrderBy(x => x.Deadline) - .OrderBy(x => x.Title) - .ToList() - .ConvertAll(ToTask) - .FindAll(CRMSecurity.CanAccessTo); + return Query(CRMDbContext.Tasks) + .OrderBy(x => x.Deadline) + .OrderBy(x => x.Title) + .ToList() + .ConvertAll(ToTask) + .FindAll(CRMSecurity.CanAccessTo); } public void ExecAlert(IEnumerable ids) { if (!ids.Any()) return; - CRMDbContext.Tasks.UpdateRange(ids.Select(x => new DbTask { ExecAlert = true, Id = x })); ; + CRMDbContext.Tasks.UpdateRange(ids.Select(x => new DbTask { ExecAlert = 1, Id = x })); ; CRMDbContext.SaveChanges(); } public List GetInfoForReminder(DateTime scheduleDate) { - return CRMDbContext.Tasks.Where(x => + return CRMDbContext.Tasks.Where(x => x.IsClosed == false && x.AlertValue != 0 && - x.ExecAlert == false && - ( x.Deadline.AddMinutes(-x.AlertValue) >= scheduleDate.AddHours(-1) && x.Deadline.AddMinutes(-x.AlertValue) <= scheduleDate.AddHours(-1)) - ).Select(x => new object[]{ x.TenantId, x.Id, x.Deadline, x.AlertValue, x.ResponsibleId }).ToList(); + x.ExecAlert == 0 && + (x.Deadline.AddMinutes(-x.AlertValue) >= scheduleDate.AddHours(-1) && x.Deadline.AddMinutes(-x.AlertValue) <= scheduleDate.AddHours(-1)) + ).Select(x => new object[] { x.TenantId, x.Id, x.Deadline, x.AlertValue, x.ResponsibleId }).ToList(); } public List GetTasks( @@ -317,39 +321,44 @@ private List GetCrudeTasks( int count, OrderBy orderBy) { - var taskTableAlias = "t"; - var sqlQuery = WhereConditional(GetTaskQuery(null, taskTableAlias), taskTableAlias, responsibleID, - categoryID, isClosed, fromDate, toDate, entityType, entityID, from, count, - orderBy); - if (!String.IsNullOrEmpty(searchText)) + var sqlQuery = GetDbTaskByFilters(responsibleID, categoryID, isClosed, fromDate, toDate, entityType, entityID, from, count, orderBy); + + if (!string.IsNullOrEmpty(searchText)) { searchText = searchText.Trim(); - var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) .ToArray(); if (keywords.Length > 0) { List tasksIds; + if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out tasksIds)) { - sqlQuery.Where(BuildLike(new[] { taskTableAlias + ".title", taskTableAlias + ".description" }, keywords)); + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k) || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k)); + } } else { if (tasksIds.Any()) - sqlQuery.Where(Exp.In(taskTableAlias + ".id", tasksIds)); + { + sqlQuery = sqlQuery.Where(x => tasksIds.Contains(x.Id)); + } else + { return new List(); + } } } } - return Db.ExecuteList(sqlQuery) - .ConvertAll(row => ToTask(row)); + return sqlQuery.ToList().ConvertAll(ToTask); } public int GetTasksCount( @@ -409,10 +418,7 @@ public int GetTasksCount( { if (CRMSecurity.IsAdmin) { - - var sqlQuery = Query("crm_task tbl_tsk").SelectCount(); - - sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", + result = GetDbTaskByFilters( responsibleId, categoryId, isClosed, @@ -422,21 +428,14 @@ public int GetTasksCount( entityId, 0, 0, - null); - - result = Db.ExecuteScalar(sqlQuery); + null).Count(); } else { var taskIds = new List(); - var sqlQuery = Query("crm_task tbl_tsk") - .Select("tbl_tsk.id") - .LeftOuterJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) - .Where(Exp.Or(Exp.Eq("tbl_ctc.is_shared", Exp.Empty), Exp.Gt("tbl_ctc.is_shared", 0))); - - sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", - responsibleId, + // count tasks without entityId and only open contacts + taskIds = GetDbTaskByFilters(responsibleId, categoryId, isClosed, fromDate, @@ -445,15 +444,40 @@ public int GetTasksCount( entityId, 0, 0, - null); + null).GroupJoin(CRMDbContext.Contacts, + x => x.ContactId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) + .Where(x => x.y == null || + x.y.IsShared == null || + x.y.IsShared.Value == ShareType.Read || + x.y.IsShared.Value == ShareType.ReadWrite) + .Select(x => x.x.Id) + .ToList(); - // count tasks without entityId and only open contacts - - taskIds = Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList(); - - Logger.DebugFormat("End GetTasksCount: {0}. count tasks without entityId and only open contacts", DateTime.Now.ToString()); + taskIds = GetDbTaskByFilters(responsibleId, + categoryId, + isClosed, + fromDate, + toDate, + entityType, + entityId, + 0, + 0, + null).GroupJoin(CRMDbContext.Contacts, + x => x.ContactId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) + .Where(x => x.y != null || + x.y.IsShared == null || + x.y.IsShared.Value == ShareType.Read || + x.y.IsShared.Value == ShareType.ReadWrite) + .Select(x => x.x.Id) + .ToList(); sqlQuery = Query("crm_task tbl_tsk") .Select("tbl_tsk.id") @@ -465,8 +489,7 @@ public int GetTasksCount( .Where(Exp.Eq("tbl_ctc.is_shared", 0)) .Where(Exp.Eq("tbl_ctc.is_company", 1)); - sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", - responsibleId, + sqlQuery = GetDbTaskByFilters(responsibleId, categoryId, isClosed, fromDate, @@ -479,7 +502,7 @@ public int GetTasksCount( // count tasks with entityId and only close contacts taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - + Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); sqlQuery = Query("crm_task tbl_tsk") @@ -492,8 +515,7 @@ public int GetTasksCount( .Where(Exp.Eq("tbl_ctc.is_shared", 0)) .Where(Exp.Eq("tbl_ctc.is_company", 0)); - sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", - responsibleId, + sqlQuery = GetDbTaskByFilters(responsibleId, categoryId, isClosed, fromDate, @@ -518,8 +540,7 @@ public int GetTasksCount( Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Deal|', tbl_tsk.entity_id)")) .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Opportunity) & Exp.Eq("tbl_tsk.contact_id", 0)); - sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", - responsibleId, + sqlQuery = GetDbTaskByFilters(responsibleId, categoryId, isClosed, fromDate, @@ -543,8 +564,7 @@ public int GetTasksCount( Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Cases|', tbl_tsk.entity_id)")) .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Case) & Exp.Eq("tbl_tsk.contact_id", 0)); - sqlQuery = WhereConditional(sqlQuery, "tbl_tsk", - responsibleId, + sqlQuery = GetDbTaskByFilters(responsibleId, categoryId, isClosed, fromDate, @@ -576,9 +596,7 @@ public int GetTasksCount( return result; } - - private IQueryable WhereConditional( - String alias, + private IQueryable GetDbTaskByFilters( Guid responsibleID, int categoryID, bool? isClosed, @@ -590,107 +608,164 @@ private IQueryable WhereConditional( int count, OrderBy orderBy) { - var aliasPrefix = !String.IsNullOrEmpty(alias) ? alias + "." : ""; + var sqlQuery = Query(CRMDbContext.Tasks); if (responsibleID != Guid.Empty) - sqlQuery.Where(Exp.Eq("responsible_id", responsibleID)); + sqlQuery = sqlQuery.Where(x => x.ResponsibleId == responsibleID); if (entityID > 0) switch (entityType) { case EntityType.Contact: - var isCompany = true; - isCompany = Db.ExecuteScalar(Query("crm_contact").Select("is_company").Where(Exp.Eq("id", entityID))); + var isCompany = Query(CRMDbContext.Contacts).Where(x => x.Id == entityID).Select(x => x.IsCompany).Single(); if (isCompany) - return WhereConditional(sqlQuery, alias, responsibleID, categoryID, isClosed, fromDate, toDate, EntityType.Company, entityID, from, count, orderBy); + return GetDbTaskByFilters(responsibleID, categoryID, isClosed, fromDate, toDate, EntityType.Company, entityID, from, count, orderBy); else - return WhereConditional(sqlQuery, alias, responsibleID, categoryID, isClosed, fromDate, toDate, EntityType.Person, entityID, from, count, orderBy); + return GetDbTaskByFilters(responsibleID, categoryID, isClosed, fromDate, toDate, EntityType.Person, entityID, from, count, orderBy); case EntityType.Person: - sqlQuery.Where(Exp.Eq(aliasPrefix + "contact_id", entityID)); + sqlQuery = sqlQuery.Where(x => x.ContactId == entityID); break; case EntityType.Company: var personIDs = GetRelativeToEntity(entityID, EntityType.Person, null).ToList(); if (personIDs.Count == 0) - sqlQuery.Where(Exp.Eq(aliasPrefix + "contact_id", entityID)); + { + sqlQuery = sqlQuery.Where(x => x.ContactId == entityID); + } else { personIDs.Add(entityID); - sqlQuery.Where(Exp.In(aliasPrefix + "contact_id", personIDs)); + sqlQuery = sqlQuery.Where(x => personIDs.Contains(x.ContactId)); } break; case EntityType.Case: case EntityType.Opportunity: - sqlQuery.Where(Exp.Eq(aliasPrefix + "entity_id", entityID) & - Exp.Eq(aliasPrefix + "entity_type", (int)entityType)); + sqlQuery = sqlQuery.Where(x => x.EntityId == entityID && x.EntityType == entityType); break; } if (isClosed.HasValue) - sqlQuery.Where(aliasPrefix + "is_closed", isClosed); + { + sqlQuery = sqlQuery.Where(x => x.IsClosed == isClosed); + } if (categoryID > 0) - sqlQuery.Where(Exp.Eq(aliasPrefix + "category_id", categoryID)); + { + sqlQuery = sqlQuery.Where(x => x.CategoryId == categoryID); + } if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) - sqlQuery.Where(Exp.Between(aliasPrefix + "deadline", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + { + sqlQuery = sqlQuery.Where(x => x.Deadline >= TenantUtil.DateTimeToUtc(fromDate) && x.Deadline <= TenantUtil.DateTimeToUtc(toDate)); + } else if (fromDate != DateTime.MinValue) - sqlQuery.Where(Exp.Ge(aliasPrefix + "deadline", TenantUtil.DateTimeToUtc(fromDate))); + { + sqlQuery = sqlQuery.Where(x => x.Deadline > TenantUtil.DateTimeToUtc(fromDate)); + } else if (toDate != DateTime.MinValue) - sqlQuery.Where(Exp.Le(aliasPrefix + "deadline", TenantUtil.DateTimeToUtc(toDate))); + { + sqlQuery = sqlQuery.Where(x => x.Deadline < TenantUtil.DateTimeToUtc(toDate)); + } if (0 < from && from < int.MaxValue) - sqlQuery.SetFirstResult(from); + sqlQuery = sqlQuery.Skip(from); if (0 < count && count < int.MaxValue) - sqlQuery.SetMaxResults(count); + sqlQuery = sqlQuery.Take(count); - sqlQuery.OrderBy(aliasPrefix + "is_closed", true); + sqlQuery = sqlQuery.OrderBy(x => x.IsClosed); if (orderBy != null && Enum.IsDefined(typeof(TaskSortedByType), orderBy.SortedBy)) { switch ((TaskSortedByType)orderBy.SortedBy) { case TaskSortedByType.Title: - sqlQuery - .OrderBy(aliasPrefix + "title", orderBy.IsAsc) - .OrderBy(aliasPrefix + "deadline", true); + { + if (orderBy.IsAsc) + sqlQuery = sqlQuery.OrderBy(x => x.Title) + .ThenBy(x => x.Deadline); + else + sqlQuery = sqlQuery.OrderByDescending(x => x.Title) + .ThenBy(x => x.Deadline); + } + break; case TaskSortedByType.DeadLine: - sqlQuery.OrderBy(aliasPrefix + "deadline", orderBy.IsAsc) - .OrderBy(aliasPrefix + "title", true); + { + if (orderBy.IsAsc) + sqlQuery = sqlQuery.OrderBy(x => x.Deadline) + .ThenBy(x => x.Title); + else + sqlQuery = sqlQuery.OrderByDescending(x => x.Deadline) + .ThenBy(x => x.Title); + } break; case TaskSortedByType.Category: - sqlQuery.OrderBy(aliasPrefix + "category_id", orderBy.IsAsc) - .OrderBy(aliasPrefix + "deadline", true) - .OrderBy(aliasPrefix + "title", true); + { + if (orderBy.IsAsc) + sqlQuery = sqlQuery.OrderBy(x => x.CategoryId) + .ThenBy(x => x.Deadline) + .ThenBy(x => x.Title); + else + sqlQuery = sqlQuery.OrderByDescending(x => x.CategoryId) + .ThenBy(x => x.Deadline) + .ThenBy(x => x.Title); + } + break; case TaskSortedByType.ContactManager: - sqlQuery.LeftOuterJoin("core_user u", Exp.EqColumns(aliasPrefix + "responsible_id", "u.id")) - .OrderBy("case when u.lastname is null or u.lastname = '' then 1 else 0 end, u.lastname", orderBy.IsAsc) - .OrderBy("case when u.firstname is null or u.firstname = '' then 1 else 0 end, u.firstname", orderBy.IsAsc) - .OrderBy(aliasPrefix + "deadline", true) - .OrderBy(aliasPrefix + "title", true); + { + + + + + sqlQuery.LeftOuterJoin("core_user u", Exp.EqColumns(aliasPrefix + "responsible_id", "u.id")) + .OrderBy("case when u.lastname is null or u.lastname = '' then 1 else 0 end, u.lastname", orderBy.IsAsc) + .OrderBy("case when u.firstname is null or u.firstname = '' then 1 else 0 end, u.firstname", orderBy.IsAsc) + .OrderBy(aliasPrefix + "deadline", true) + .OrderBy(aliasPrefix + "title", true); + } + break; case TaskSortedByType.Contact: - sqlQuery.LeftOuterJoin("crm_contact c_tbl", Exp.EqColumns(aliasPrefix + "contact_id", "c_tbl.id")) - .OrderBy("case when c_tbl.display_name is null then 1 else 0 end, c_tbl.display_name", orderBy.IsAsc) - .OrderBy(aliasPrefix + "deadline", true) - .OrderBy(aliasPrefix + "title", true); - break; + { + var subSqlQuery = sqlQuery.GroupJoin(CRMDbContext.Contacts, + x => x.ContactId, + y => y.Id, + (x, y) => new { x, y } + ) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }); + + if (orderBy.IsAsc) + { + subSqlQuery = subSqlQuery.OrderBy(x => x.y != null ? x.y.DisplayName : "") + .ThenBy(x => x.x.Deadline) + .ThenBy(x => x.x.Title); + } + else + { + subSqlQuery = subSqlQuery.OrderByDescending(x => x.y != null ? x.y.DisplayName : "") + .ThenBy(x => x.x.Deadline) + .ThenBy(x => x.x.Title); + + } + + sqlQuery = subSqlQuery.Select(x => x.x); + + break; + } } } else { - sqlQuery - .OrderBy(aliasPrefix + "deadline", true) - .OrderBy(aliasPrefix + "title", true); + sqlQuery = sqlQuery.OrderBy(x => x.Deadline) + .ThenBy(x => x.Title); } return sqlQuery; @@ -699,38 +774,10 @@ private IQueryable WhereConditional( public Dictionary GetNearestTask(int[] contactID) { - - - throw new Exception(); - - //Query(CRMDbContext.Tasks) - // .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed) - // .GroupBy(x => x.ContactId) - // .Select(x => x.); - - - // var sqlSubQuery = - // Query("crm_task") - // .SelectMin("id") - // .SelectMin("deadline") - // .Select("contact_id") - // .Where(Exp.In("contact_id", contactID) & Exp.Eq("is_closed", false)) - // .GroupBy("contact_id"); - - //var taskIDs = Db.ExecuteList(sqlSubQuery).ConvertAll(row => row[0]); - - //if (taskIDs.Count == 0) return new Dictionary(); - - //var tasks = Db.ExecuteList(GetTaskQuery(Exp.In("id", taskIDs))).ConvertAll(row => ToTask(row)).Where(CRMSecurity.CanAccessTo); - - //var result = new Dictionary(); - - //foreach (var task in tasks.Where(task => !result.ContainsKey(task.ContactID))) - //{ - // result.Add(task.ContactID, task); - //} - - //return result; + return Query(CRMDbContext.Tasks) + .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed) + .GroupBy(x => x.ContactId) + .ToDictionary(x => x.Key, y => ToTask(y.Single(x => x.Id == y.Min(x => x.Id)))); } public IEnumerable GetResponsibles(int categoryID) @@ -739,16 +786,16 @@ public IEnumerable GetResponsibles(int categoryID) if (0 < categoryID) sqlQuery = sqlQuery.Where(x => x.CategoryId == categoryID); - + return sqlQuery.GroupBy(x => x.ResponsibleId).Select(x => x.Key).ToList(); } - + public Dictionary GetTasksCount(int[] contactID) { - return CRMDbContext.Tasks + return Query(CRMDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId)) .GroupBy(x => x.ContactId) - .ToDictionary(x => x.Key, x => x.Count()); + .ToDictionary(x => x.Key, x => x.Count()); } public int GetTasksCount(int contactID) @@ -765,7 +812,7 @@ public Dictionary HaveLateTask(int[] contactID) return Query(CRMDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed && x.Deadline <= DateTime.UtcNow) .GroupBy(x => x.ContactId) - .ToDictionary(x => x.Key, x => x.Any()); + .ToDictionary(x => x.Key, x => x.Any()); } public bool HaveLateTask(int contactID) @@ -796,10 +843,10 @@ public virtual Task[] SaveOrUpdateTaskList(List newTasks) private Task SaveOrUpdateTaskInDb(Task newTask) { - if (String.IsNullOrEmpty(newTask.Title) || newTask.DeadLine == DateTime.MinValue || + if (string.IsNullOrEmpty(newTask.Title) || newTask.DeadLine == DateTime.MinValue || newTask.CategoryID <= 0) throw new ArgumentException(); - + if (newTask.ID == 0 || Query(CRMDbContext.Tasks).Where(x => x.Id == newTask.ID).Count() == 0) { newTask.CreateOn = DateTime.UtcNow; @@ -808,7 +855,7 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.LastModifedOn = DateTime.UtcNow; newTask.LastModifedBy = SecurityContext.CurrentAccount.ID; - new DbTask + var itemToInsert = new DbTask { Title = newTask.Title, Description = newTask.Description, @@ -827,25 +874,11 @@ private Task SaveOrUpdateTaskInDb(Task newTask) TenantId = TenantID }; + CRMDbContext.Add(itemToInsert); + CRMDbContext.SaveChanges(); + + newTask.ID = itemToInsert.Id; - newTask.ID = Db.ExecuteScalar( - Insert("crm_task") - .InColumnValue("id", 0) - .InColumnValue("title", newTask.Title) - .InColumnValue("description", newTask.Description) - .InColumnValue("deadline", TenantUtil.DateTimeToUtc(newTask.DeadLine)) - .InColumnValue("responsible_id", newTask.ResponsibleID) - .InColumnValue("contact_id", newTask.ContactID) - .InColumnValue("entity_type", (int)newTask.EntityType) - .InColumnValue("entity_id", newTask.EntityID) - .InColumnValue("is_closed", newTask.IsClosed) - .InColumnValue("category_id", newTask.CategoryID) - .InColumnValue("create_on", newTask.CreateOn) - .InColumnValue("create_by", newTask.CreateBy) - .InColumnValue("last_modifed_on", newTask.LastModifedOn) - .InColumnValue("last_modifed_by", newTask.LastModifedBy) - .InColumnValue("alert_value", newTask.AlertValue) - .Identity(1, 0, true)); } else { @@ -917,11 +950,11 @@ private int SaveTaskInDb(Task newTask) LastModifedOn = newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn, LastModifedBy = SecurityContext.CurrentAccount.ID, AlertValue = newTask.AlertValue, - TenantId = TenantID + TenantId = TenantID }; CRMDbContext.Tasks.Add(dbTask); - + CRMDbContext.SaveChanges(); newTask.ID = dbTask.Id; @@ -946,7 +979,7 @@ public virtual int[] SaveTaskList(List items) CRMDbContext.SaveChanges(); tx.Commit(); - + return result.ToArray(); } @@ -1086,7 +1119,6 @@ public List CreateByTemplate(List templateItems, EntityType #endregion - public void ReassignTasksResponsible(Guid fromUserId, Guid toUserId) { var tasks = GetTasks(String.Empty, fromUserId, 0, false, DateTime.MinValue, DateTime.MinValue, diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 0a060e69274..3f46a5c0275 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -23,12 +23,14 @@ * */ +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; @@ -40,10 +42,13 @@ public class TaskTemplateContainerDao : AbstractDao public TaskTemplateContainerDao( DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + IOptionsMonitor logger + ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { } @@ -131,10 +136,12 @@ public class TaskTemplateDao : AbstractDao { public TaskTemplateDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { } diff --git a/products/ASC.CRM/Server/Core/EF/DbTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs index 57972d24e87..f6f77bb27c2 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -61,6 +61,6 @@ public partial class DbTask: IDbCrm public int AlertValue { get; set; } [Column("exec_alert", TypeName = "int(10)")] - public bool ExecAlert { get; set; } + public int ExecAlert { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 397778ac336..abdd538451e 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -33,6 +33,7 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Files.Core; +using ASC.Files.Core.Security; using ASC.Web.Core; using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; @@ -50,32 +51,31 @@ namespace ASC.CRM.Core { public class CRMSecurity - { - #region Members - + { public readonly IAction _actionRead = new Action(new Guid("{6F05C382-8BCA-4469-9424-C807A98C40D7}"), "", true, false); - - #endregion - - #region Constructor + public CRMSecurity(SecurityContext securityContext, AuthorizationManager authorizationManager, UserManager userManager, DisplayUserSettingsHelper displayUserSettingsHelper, - DaoFactory daoFactory) + DaoFactory daoFactory, + WebItemSecurity webItemSecurity, + PermissionContext permissionContext) { SecurityContext = securityContext; AuthorizationManager = authorizationManager; UserManager = userManager; DisplayUserSettingsHelper = displayUserSettingsHelper; DaoFactory = daoFactory; + WebItemSecurity = webItemSecurity; + PermissionContext = permissionContext; } + + public PermissionContext PermissionContext { get; } - #endregion - - #region Property + public WebItemSecurity WebItemSecurity { get; } - public DaoFactory DaoFactory { get; } + public DaoFactory DaoFactory { get; } public SecurityContext SecurityContext { get; } @@ -84,10 +84,7 @@ public CRMSecurity(SecurityContext securityContext, public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public UserManager UserManager { get; } - #endregion - - #region Check Permissions - + private ISecurityObjectProvider GetCRMSecurityProvider() { return new CRMSecurityObjectProvider(); @@ -105,7 +102,7 @@ public bool CanAccessTo(ISecurityObjectId entity) public bool CanAccessTo(ISecurityObjectId entity, Guid userId) { - return IsAdministrator(userId) || SecurityContext.CheckPermissions(entity, GetCRMSecurityProvider(), _actionRead); + return IsAdministrator(userId) || PermissionContext.CheckPermissions(entity, GetCRMSecurityProvider(), _actionRead); } public void MakePublic(ISecurityObjectId entity) @@ -118,7 +115,6 @@ public IEnumerable GetPrivateItems(Type objectType) if (IsAdmin) return new List(); return GetPrivateItems(objectType, Guid.Empty, true); - } private IEnumerable GetPrivateItems(Type objectType, Guid userId, bool withoutUser) @@ -230,10 +226,6 @@ public void SetAccessTo(ISecurityObjectId entity, List subjectID) AuthorizationManager.AddAce(new AzRecord(Constants.GroupEveryone.ID, _actionRead.ID, AceType.Deny, entity)); } - #endregion - - #region SetAccessTo - public void SetAccessTo(File file) { if (IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID) @@ -258,11 +250,6 @@ public void SetAccessTo(Cases cases, List subjectID) } } - #endregion - - #region CanAccessTo - - public bool CanAccessTo(RelationshipEvent relationshipEvent) { return CanAccessTo(relationshipEvent, SecurityContext.CurrentAccount.ID); @@ -400,10 +387,6 @@ public bool CanAccessTo(InvoiceTax invoiceTax, Guid userId) return false; } - #endregion - - #region CanEdit - public bool CanEdit(File file) { if (!(IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID)) @@ -499,9 +482,6 @@ public bool CanEdit(InvoiceItem invoiceItem) return IsAdmin; } - #endregion - - #region CanDelete public bool CanDelete(Contact contact) { @@ -547,20 +527,11 @@ public bool CanDelete(RelationshipEvent relationshipEvent) return CanEdit(relationshipEvent); } - #endregion - - #region IsPrivate - public bool IsPrivate(Contact contact) { return contact.ShareType == ShareType.None; } - #endregion - - - #region DemandAccessTo - public void DemandAccessTo(File file) { // if (!CanAccessTo((File)file)) CreateSecurityException(); @@ -601,10 +572,6 @@ public void DemandAccessTo(InvoiceTax invoiceTax) if (!CanAccessTo(invoiceTax)) throw CreateSecurityException(); } - #endregion - - #region DemandEdit - public void DemandEdit(File file) { if (!CanEdit(file)) throw CreateSecurityException(); @@ -650,10 +617,6 @@ public void DemandEdit(InvoiceItem invoiceItem) if (!CanEdit(invoiceItem)) throw CreateSecurityException(); } - #endregion - - #region DemandDelete - public void DemandDelete(File file) { if (!CanEdit(file)) throw CreateSecurityException(); @@ -695,10 +658,6 @@ public void DemandDelete(RelationshipEvent relationshipEvent) if (!CanDelete(relationshipEvent)) throw CreateSecurityException(); } - #endregion - - #region DemandCreateOrUpdate - public void DemandCreateOrUpdate(RelationshipEvent relationshipEvent) { if (String.IsNullOrEmpty(relationshipEvent.Content) || relationshipEvent.CategoryID == 0 || (relationshipEvent.ContactID == 0 && relationshipEvent.EntityID == 0)) @@ -813,8 +772,6 @@ public void DemandCreateOrUpdate(Invoice invoice) } } - #endregion - public Exception CreateSecurityException() { throw new SecurityException(CRMErrorsResource.AccessDenied); diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index 9a5f204d1cb..10979d4436b 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -38,6 +38,17 @@ namespace ASC.CRM.Core { public class FileSecurity : IFileSecurity { + public FileSecurity(FilesIntegration filesIntegration, + CRMSecurity cRMSecurity) + { + FilesIntegration = filesIntegration; + CRMSecurity = cRMSecurity; + } + + public FilesIntegration FilesIntegration { get; } + + public CRMSecurity CRMSecurity { get; } + public bool CanCreate(FileEntry entry, Guid userId) { return true; @@ -85,18 +96,18 @@ public bool CanRead(FileEntry entry, Guid userId) if (reportFile != null) return true; - using (var tagDao = FilesIntegration.GetTagDao()) - { - var eventIds = tagDao.GetTags(entry.ID, FileEntryType.File, TagType.System) - .Where(x => x.TagName.StartsWith("RelationshipEvent_")) - .Select(x => Convert.ToInt32(x.TagName.Split(new[] { '_' })[1])) - .ToList(); + var tagDao = FilesIntegration.TagDao(); + + var eventIds = tagDao.GetTags(entry.ID, FileEntryType.File, TagType.System) + .Where(x => x.TagName.StartsWith("RelationshipEvent_")) + .Select(x => Convert.ToInt32(x.TagName.Split(new[] { '_' })[1])) + .ToList(); - if (!eventIds.Any()) return false; + if (!eventIds.Any()) return false; - var eventItem = daoFactory.RelationshipEventDao.GetByID(eventIds.First()); - return CRMSecurity.CanAccessTo(eventItem, userId); - } + var eventItem = daoFactory.RelationshipEventDao.GetByID(eventIds.First()); + + return CRMSecurity.CanAccessTo(eventItem, userId); } } @@ -108,14 +119,24 @@ public IEnumerable WhoCanRead(FileEntry entry) public class FileSecurityProvider : IFileSecurityProvider { + public FileSecurityProvider(FilesIntegration filesIntegration, + CRMSecurity cRMSecurity) + { + FilesIntegration = filesIntegration; + CRMSecurity = cRMSecurity; + } + + public FilesIntegration FilesIntegration { get; } + public CRMSecurity CRMSecurity { get; } + public IFileSecurity GetFileSecurity(string data) { - return new FileSecurity(); + return new FileSecurity(FilesIntegration, CRMSecurity); } public Dictionary GetFileSecurity(Dictionary data) { - return data.ToDictionary, object, IFileSecurity>(d => d.Key, d => new FileSecurity()); + return data.ToDictionary, object, IFileSecurity>(d => d.Key, d => new FileSecurity(FilesIntegration, CRMSecurity)); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index 3ac9418312b..bd65d893a47 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -41,6 +41,8 @@ using ASC.Notify.Recipients; using ASC.Web.CRM.Core; using Autofac; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Collections; using System.Collections.Generic; @@ -56,55 +58,21 @@ namespace ASC.Web.CRM.Services.NotifyService { public class NotifyClient { - public NotifyClient(PathProvider pathProvider, - SecurityContext securityContext, - PaymentManager paymentManager, - TenantManager tenantManager, - TenantUtil tenantUtil, - UserManager userManager, - DaoFactory daoFactory) + public NotifyClient(IServiceProvider serviceProvider) { - PathProvider = pathProvider; - SecurityContext = securityContext; - PaymentManager = paymentManager; - TenantManager = tenantManager; - TenantUtil = tenantUtil; - UserManager = userManager; - DaoFactory = daoFactory; - } - - public DaoFactory DaoFactory { get; } - - public UserManager UserManager { get; } - public TenantUtil TenantUtil { get; } - public TenantManager TenantManager { get;} - public PaymentManager PaymentManager { get; } - public SecurityContext SecurityContext { get; } - public PathProvider PathProvider { get; } - - private static NotifyClient instance; - private readonly INotifyClient client; - private readonly INotifySource source; - - public static NotifyClient Instance - { - get - { - if (instance == null) - { - lock (typeof(NotifyClient)) - { - if (instance == null) instance = new NotifyClient(WorkContext.NotifyContext.NotifyService.RegisterClient(NotifySource.Instance), NotifySource.Instance); - } - } - return instance; - } + ServiceProvider = serviceProvider; } + public IServiceProvider ServiceProvider { get; } + public void SendAboutCreateNewContact(List recipientID, int contactID, String contactTitle, NameValueCollection fields) { if ((recipientID.Count == 0) || String.IsNullOrEmpty(contactTitle)) return; + using var scope = ServiceProvider.CreateScope(); + var notifySource = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + client.SendNoticeToAsync( NotifyConstants.Event_CreateNewContact, null, @@ -121,6 +89,10 @@ public void SendAboutSetAccess(EntityType entityType, int entityID, DaoFactory d { if (userID.Length == 0) return; + using var scope = ServiceProvider.CreateScope(); + var notifySource = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + var baseData = ExtractBaseDataFrom(entityType, entityID, daoFactory); client.SendNoticeToAsync( @@ -182,6 +154,11 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable { if (userID.Length == 0) return; + using var scope = ServiceProvider.CreateScope(); + var notifySource = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + NameValueCollection baseEntityData; if (entity.EntityID != 0) @@ -242,7 +219,7 @@ public void SendAboutExportCompleted(Guid recipientID, String fileName, String f var recipient = ToRecipient(recipientID); - client.SendNoticeToAsync(CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, + client.SendNoticeToAsync(CoreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, null, new[] { recipient }, true, @@ -282,7 +259,7 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) } client.SendNoticeToAsync( - CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, + CoreBaseSettings.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, null, new[] { recipient }, true, @@ -376,8 +353,7 @@ public void SendAutoReminderAboutTask(DateTime scheduleDate) } catch (Exception ex) { - LogManager.GetLogger("ASC.CRM.Tasks") - .Error("SendAutoReminderAboutTask, tenant: " + tenant.TenantDomain, ex); + Logger.Error("SendAutoReminderAboutTask, tenant: " + tenant.TenantDomain, ex); } } @@ -448,7 +424,7 @@ public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskCo ); } - public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal, Hashtable fileListInfoHashtable) + public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Contact taskContact, Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal, Hashtable fileListInfoHashtable) { var recipient = ToRecipient(task.ResponsibleID); @@ -519,6 +495,11 @@ public void SendAboutResponsibleForOpportunity(Deal deal) if (recipient == null) return; + using var scope = ServiceProvider.CreateScope(); + var notifySource = scope.ServiceProvider.GetService(); + var securityContext = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + client.SendNoticeToAsync( NotifyConstants.Event_ResponsibleForOpportunity, null, diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs index 1db7761ccda..827e41c1787 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs @@ -23,35 +23,22 @@ * */ - -#region Import - +using ASC.Core; using ASC.CRM.Services.NotifyService; using ASC.Notify.Model; using ASC.Notify.Patterns; +using ASC.Notify.Recipients; using System; using NotifySourceBase = ASC.Core.Notify.NotifySource; -#endregion - namespace ASC.Web.CRM.Services.NotifyService { public class NotifySource : NotifySourceBase { - public static NotifySource Instance - { - get; - private set; - } - - static NotifySource() - { - Instance = new NotifySource(); - } - public NotifySource() - : base(new Guid("{13FF36FB-0272-4887-B416-74F52B0D0B02}")) + public NotifySource(UserManager userManager, IRecipientProvider recipientsProvider, SubscriptionManager subscriptionManager) + : base(new Guid("{13FF36FB-0272-4887-B416-74F52B0D0B02}"), userManager, recipientsProvider, subscriptionManager) { } diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index 52753c7fc80..b1f075c2dd5 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -28,19 +28,34 @@ using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using ASC.Files.Core; using ASC.Web.CRM.Core; +using ASC.Web.Files.Services.DocumentService; using Autofac; using Newtonsoft.Json; using System; using System.Collections.Generic; -using System.IO; using System.Net; namespace ASC.Web.CRM.Classes { public class ReportHelper { - private static string GetFileName(ReportType reportType) + public ReportHelper(TenantUtil tenantUtil, + Global global, + DocbuilderReportsUtility docbuilderReportsUtility) + { + TenantUtil = tenantUtil; + Global = global; + DocbuilderReportsUtility = docbuilderReportsUtility; + } + + public DocbuilderReportsUtility DocbuilderReportsUtility { get; } + public Global Global { get; } + + public TenantUtil TenantUtil { get; } + + private string GetFileName(ReportType reportType) { string reportName; @@ -87,7 +102,7 @@ private static string GetFileName(ReportType reportType) TenantUtil.DateTimeNow().ToShortTimeString()); } - public static bool CheckReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) + public bool CheckReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { using (var scope = DIHelper.Resolve()) { @@ -121,7 +136,7 @@ public static bool CheckReportData(ReportType reportType, ReportTimePeriod timeP } } - public static List GetMissingRates(ReportType reportType) + public List GetMissingRates(ReportType reportType) { using (var scope = DIHelper.Resolve()) { @@ -133,7 +148,7 @@ public static List GetMissingRates(ReportType reportType) } } - private static object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) + private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { using (var scope = DIHelper.Resolve()) { @@ -169,7 +184,7 @@ private static object GetReportData(ReportType reportType, ReportTimePeriod time } } - private static string GetReportScript(object data, ReportType type, string fileName) + private string GetReportScript(object data, ReportType type, string fileName) { var script = FileHelper.ReadTextFromEmbeddedResource(string.Format("ASC.Web.CRM.ReportTemplates.{0}.docbuilder", type)); @@ -181,16 +196,16 @@ private static string GetReportScript(object data, ReportType type, string fileN .Replace("${reportData}", JsonConvert.SerializeObject(data)); } - private static void SaveReportFile(ReportState state, string url) + private void SaveReportFile(ReportState state, string url) { using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); var data = new WebClient().DownloadData(url); - using (var stream = new MemoryStream(data)) + using (var stream = new System.IO.MemoryStream(data)) { - var document = new ASC.Files.Core.File + var document = new File { Title = state.FileName, FolderID = daoFactory.FileDao.GetRoot(), @@ -205,7 +220,7 @@ private static void SaveReportFile(ReportState state, string url) } } - public static ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) + public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { var reportData = GetReportData(reportType, timePeriod, managers); if (reportData == null) From 47a2c521f372d9debe4ccbc92acc5691169ca827 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 7 Apr 2020 23:48:40 +0300 Subject: [PATCH 07/61] crm: migrate DAO to EF Core --- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 2 +- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 15 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 8 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 111 ++-- .../Server/Core/Dao/RelationshipEventDao.cs | 190 ++++--- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 512 ++++++++++-------- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 12 +- products/ASC.CRM/Server/Core/Entities/Deal.cs | 43 +- .../Server/Core/Search/BundleSearch.cs | 117 +++- .../Server/Core/Security/CRMSecutiry.cs | 10 +- 12 files changed, 579 insertions(+), 453 deletions(-) diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 078c92ca16e..7f28b834129 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -489,7 +489,7 @@ private IQueryable GetDbCasesByFilters( { foreach (var k in keywords) { - result = result.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k)); + result = result.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%")); } } else if (!ids.Any()) diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 61b8de6811b..c808a0701d4 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -202,12 +202,11 @@ public List GetContactsByPrefix(String prefix, int searchType, int from var idsFromAcl = CoreDbContext.Acl.Where(x => x.Tenant == TenantID && x.Action == CRMSecurity._actionRead.ID && x.Subject == SecurityContext.CurrentAccount.ID && - Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName. )) + (Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Person).FullName + "%"))) .Select(x => Convert.ToInt32(x.Object.Split('|', StringSplitOptions.None)[1])) .ToList(); - objectId.ObjectType.FullName - // oldContacts || publicContact || contact is private, but user is ManagerContact sqlQuery = sqlQuery.Where(x => x.IsShared == null || x.IsShared > 0 || idsFromAcl.Contains(x.Id)); } @@ -700,7 +699,7 @@ private IQueryable GetDbContactsByFilters( foreach (var k in keywords) { - sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k)); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k + "%")); } } else @@ -1639,11 +1638,11 @@ private void DeleteBatchContactsExecute(List contacts) } var contactID = newContactID.ToArray(); - var filesIDs = new object[0]; + int[] filesIDs = new int[0]; var tx = CRMDbContext.Database.BeginTransaction(); - var tagdao = FilesIntegration.TagDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); var tagNames = Query(CRMDbContext.RelationshipEvent).Where(x => contactID.Contains(x.ContactId) && x.HaveFiles) .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); @@ -1652,7 +1651,7 @@ private void DeleteBatchContactsExecute(List contacts) { filesIDs = tagdao.GetTags(tagNames, TagType.System) .Where(t => t.EntryType == FileEntryType.File) - .Select(t => t.EntryId) + .Select(t => Convert.ToInt32(t.EntryId)) .ToArray(); } @@ -1705,7 +1704,7 @@ private void DeleteBatchContactsExecute(List contacts) contacts.ForEach(contact => AuthorizationManager.RemoveAllAces(contact)); - var filedao = FilesIntegration.GetFileDao(); + var filedao = FilesIntegration.DaoFactory.GetFileDao(); foreach (var filesID in filesIDs) { diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index e12a8651a0f..da3f7e16bae 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -327,7 +327,7 @@ private IQueryable GetDbDealByFilters( { foreach (var k in keywords) { - sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k) || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k)); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%")); } } else if (ids.Count == 0) return null; @@ -819,7 +819,7 @@ private void DeleteBatchDealsExecute(List deals) var dealID = deals.Select(x => x.ID).ToArray(); object[] filesIDs; - var tagdao = FilesIntegration.TagDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); var tagNames = Query(CRMDbContext.RelationshipEvent) .Where(x => x.HaveFiles && dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) @@ -849,11 +849,11 @@ private void DeleteBatchDealsExecute(List deals) deals.ForEach(deal => AuthorizationManager.RemoveAllAces(deal)); - var filedao = FilesIntegration.GetFileDao(); + var filedao = FilesIntegration.DaoFactory.GetFileDao(); foreach (var filesID in filesIDs) { - filedao.DeleteFile(filesID); + filedao.DeleteFile(Convert.ToInt32(filesID)); } } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 03fd9e65d35..e434740df11 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -873,8 +873,8 @@ private IQueryable GetDbInvoceByFilters( { foreach (var k in keywords) { - sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Number, k) || - Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k)); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Number, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%")); } } else diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index b47107c47b5..bb8194fe01f 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -24,6 +24,7 @@ */ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Classes; @@ -31,7 +32,9 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Collections.Specialized; @@ -42,18 +45,20 @@ namespace ASC.CRM.Core.Dao public class CachedListItem : ListItemDao { - private readonly HttpRequestDictionary _listItemCache = new HttpRequestDictionary("crm_list_item"); + private readonly HttpRequestDictionary _listItemCache; public CachedListItem( DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { - - + _listItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_list_item"); } public override void ChangeColor(int id, string newColor) @@ -112,10 +117,12 @@ public class ListItemDao : AbstractDao public ListItemDao( DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { @@ -274,7 +281,7 @@ public ListItem GetByTitle(ListType listType, string title) public int GetRelativeItemsCount(ListType listType, int id) { int result; - + switch (listType) { case ListType.ContactStatus: @@ -300,48 +307,66 @@ public int GetRelativeItemsCount(ListType listType, int id) public Dictionary GetRelativeItemsCount(ListType listType) { - - - var sqlQuery = Query("crm_list_item tbl_list_item") - .Where(Exp.Eq("tbl_list_item.list_type", (int)listType)) - .Select("tbl_list_item.id") - .OrderBy("tbl_list_item.sort_order", true) - .GroupBy("tbl_list_item.id"); + Dictionary result; switch (listType) { case ListType.ContactStatus: - sqlQuery.LeftOuterJoin("crm_contact tbl_crm_contact", - Exp.EqColumns("tbl_list_item.id", "tbl_crm_contact.status_id") - & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_contact.tenant_id")) - .Select("count(tbl_crm_contact.status_id)"); - break; + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.Contacts), + x => x.Id, + y => y.StatusId, + (x, y) => new { Column1 = x, Column2 = y.Count() }) + .Where(x => x.Column1.ListType == listType) + .OrderBy(x => x.Column1.SortOrder) + .ToDictionary(x => x.Column1.Id, x => x.Column2); + + break; + } case ListType.ContactType: - sqlQuery.LeftOuterJoin("crm_contact tbl_crm_contact", - Exp.EqColumns("tbl_list_item.id", "tbl_crm_contact.contact_type_id") - & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_contact.tenant_id")) - .Select("count(tbl_crm_contact.contact_type_id)"); - break; + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.Contacts), + x => x.Id, + y => y.ContactTypeId, + (x, y) => new { Column1 = x, Column2 = y.Count() }) + .Where(x => x.Column1.ListType == listType) + .OrderBy(x => x.Column1.SortOrder) + .ToDictionary(x => x.Column1.Id, x => x.Column2); + break; + } case ListType.TaskCategory: - sqlQuery.LeftOuterJoin("crm_task tbl_crm_task", - Exp.EqColumns("tbl_list_item.id", "tbl_crm_task.category_id") - & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_task.tenant_id")) - .Select("count(tbl_crm_task.category_id)"); - break; + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.Tasks), + x => x.Id, + y => y.CategoryId, + (x, y) => new { Column1 = x, Column2 = y.Count() }) + .Where(x => x.Column1.ListType == listType) + .OrderBy(x => x.Column1.SortOrder) + .ToDictionary(x => x.Column1.Id, x => x.Column2); + + break; + } case ListType.HistoryCategory: - sqlQuery.LeftOuterJoin("crm_relationship_event tbl_crm_relationship_event", - Exp.EqColumns("tbl_list_item.id", "tbl_crm_relationship_event.category_id") - & Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_relationship_event.tenant_id")) - .Select("count(tbl_crm_relationship_event.category_id)"); + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.RelationshipEvent), + x => x.Id, + y => y.CategoryId, + (x, y) => new { Column1 = x, Column2 = y.Count() }) + .Where(x => x.Column1.ListType == listType) + .OrderBy(x => x.Column1.SortOrder) + .ToDictionary(x => x.Column1.Id, x => x.Column2); - break; + break; + } default: throw new ArgumentException(); } - var queryResult = Db.ExecuteList(sqlQuery); - - return queryResult.ToDictionary(x => Convert.ToInt32(x[0]), y => Convert.ToInt32(y[1])); + return result; } public virtual int CreateItem(ListType listType, ListItem enumItem) @@ -412,7 +437,7 @@ public virtual void EditItem(ListType listType, ListItem enumItem) itemToUpdate.Title = enumItem.Title; itemToUpdate.AdditionalParams = enumItem.AdditionalParams; itemToUpdate.Color = enumItem.Color; - + CRMDbContext.SaveChanges(); } @@ -476,18 +501,18 @@ public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toIte case ListType.ContactType: { var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.ContactTypeId == fromItemID); - + itemToUpdate.ContactTypeId = toItemID; - + CRMDbContext.Update(itemToUpdate); } break; case ListType.TaskCategory: - { + { var itemToUpdate = Query(CRMDbContext.Tasks).Single(x => x.CategoryId == fromItemID); itemToUpdate.CategoryId = toItemID; - CRMDbContext.Update(itemToUpdate); + CRMDbContext.Update(itemToUpdate); } break; case ListType.HistoryCategory: diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 29b986b053b..0cfb47d14bc 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -24,39 +24,32 @@ */ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; - using ASC.Collections; +using ASC.Common.Logging; +using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Classes; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Files.Core; - using ASC.Web.CRM; -using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; using ASC.Web.Studio.Core; - -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -using OrderBy = ASC.CRM.Core.Entities.OrderBy; -using File = ASC.Files.Core.File; -using ASC.CRM.Core.Enums; -using ASC.Core.Common.EF; -using ASC.CRM.Core.EF; -using ASC.Core; -using ASC.CRM.Classes; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Text; +using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Core.Dao { @@ -73,7 +66,9 @@ public CachedRelationshipEventDao(DbContextManager dbContextManage TenantUtil tenantUtil, SetupInfo setupInfo, PathProvider pathProvider, - IHttpContextAccessor httpContextAccessor + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger + ) : base(dbContextManager, tenantManager, @@ -82,7 +77,8 @@ IHttpContextAccessor httpContextAccessor cRMSecurity, tenantUtil, setupInfo, - pathProvider) + pathProvider, + logger) { _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_relationshipEvent"); } @@ -113,11 +109,13 @@ public RelationshipEventDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, TenantUtil tenantUtil, SetupInfo setupInfo, - PathProvider pathProvider + PathProvider pathProvider, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { FilesIntegration = filesIntegration; TenantUtil = tenantUtil; @@ -164,7 +162,7 @@ public void AttachFiles(int eventID, int[] fileIDs) { if (fileIDs.Length == 0) return; - var dao = FilesIntegration.TagDao(); + var dao = FilesIntegration.DaoFactory.GetTagDao(); var tags = fileIDs.ToList().ConvertAll(fileID => new Tag("RelationshipEvent_" + eventID, TagType.System, Guid.Empty) { EntryType = FileEntryType.File, EntryId = fileID }); @@ -190,7 +188,7 @@ public int GetFilesCount(int[] contactID, EntityType entityType, int entityID) return GetFilesIDs(contactID, entityType, entityID).Length; } - private object[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID) + private int[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID) { if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) throw new ArgumentException(); @@ -206,42 +204,42 @@ private object[] GetFilesIDs(int[] contactID, EntityType entityType, int entityI sqlQuery = sqlQuery.Where(x => x.HaveFiles); var tagNames = sqlQuery.Select(x => String.Format("RelationshipEvent_{0}", x.Id)); - var tagdao = FilesIntegration.TagDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); return tagdao.GetTags(tagNames.ToArray(), TagType.System) .Where(t => t.EntryType == FileEntryType.File) - .Select(t => t.EntryId).ToArray(); - + .Select(t => Convert.ToInt32(t.EntryId)).ToArray(); + } - public List GetAllFiles(int[] contactID, EntityType entityType, int entityID) + public List> GetAllFiles(int[] contactID, EntityType entityType, int entityID) { - var filedao = FilesIntegration.GetFileDao(); + var filedao = FilesIntegration.DaoFactory.GetFileDao(); var ids = GetFilesIDs(contactID, entityType, entityID); - var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); + var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List>(); files.ForEach(CRMSecurity.SetAccessTo); return files.ToList(); } - public Dictionary> GetFiles(int[] eventID) + public Dictionary>> GetFiles(int[] eventID) { if (eventID == null || eventID.Length == 0) throw new ArgumentException("eventID"); - var tagdao = FilesIntegration.TagDao(); - var filedao = FilesIntegration.GetFileDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var filedao = FilesIntegration.DaoFactory.GetFileDao(); var findedTags = tagdao.GetTags(eventID.Select(item => String.Concat("RelationshipEvent_", item)).ToArray(), TagType.System).Where(t => t.EntryType == FileEntryType.File); - var filesID = findedTags.Select(t => t.EntryId).ToArray(); + var filesID = findedTags.Select(t => Convert.ToInt32(t.EntryId)).ToArray(); - var files = 0 < filesID.Length ? filedao.GetFiles(filesID) : new List(); + var files = 0 < filesID.Length ? filedao.GetFiles(filesID) : new List>(); - var filesTemp = new Dictionary(); + var filesTemp = new Dictionary>(); files.ForEach(item => { @@ -253,16 +251,16 @@ public Dictionary> GetFiles(int[] eventID) x => x.Select(item => filesTemp[item.EntryId]).ToList()); } - public List GetFiles(int eventID) + public List> GetFiles(int eventID) { if (eventID == 0) throw new ArgumentException("eventID"); - var tagdao = FilesIntegration.TagDao(); - var filedao = FilesIntegration.GetFileDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var filedao = FilesIntegration.DaoFactory.GetFileDao(); - var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); - var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List(); + var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => Convert.ToInt32(t.EntryId)).ToArray(); + var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List>(); files.ForEach(CRMSecurity.SetAccessTo); @@ -278,7 +276,7 @@ private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID var files = GetAllFiles(contactID, entityType, entityID); - var dao = FilesIntegration.GetFileDao(); + var dao = FilesIntegration.DaoFactory.GetFileDao(); foreach (var file in files) { @@ -286,19 +284,19 @@ private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID } } - public List RemoveFile(File file) + public List RemoveFile(File file) { CRMSecurity.DemandDelete(file); List eventIDs; - var tagdao = FilesIntegration.TagDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); var tags = tagdao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); eventIDs = tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); - var dao = FilesIntegration.GetFileDao(); + var dao = FilesIntegration.DaoFactory.GetFileDao(); dao.DeleteFile(file.ID); @@ -372,51 +370,51 @@ public RelationshipEvent CreateItem(RelationshipEvent item) // if (msg == null) throw new ArgumentException("Mail message cannot be found"); - var msgResponseWrapper = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg))); - var msgRequestObj = msgResponseWrapper.Value("response"); - string messageUrl; - - htmlBody = msgRequestObj.Value("htmlBody"); - - using (var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(htmlBody))) - { - var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); - - Global.GetStore().Save("mail_messages", filePath, fileStream); - - messageUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=mailmessage&message_id={1}", PathProvider.BaseAbsolutePath, messageId).ToLower(); - - } - - var msg_date_created = msgRequestObj.Value("date"); - var message_id = msgRequestObj.Value("id"); - item.Content = JsonConvert.SerializeObject(new - { - @from = msgRequestObj.Value("from"), - to = msgRequestObj.Value("to"), - cc = msgRequestObj.Value("cc"), - bcc = msgRequestObj.Value("bcc"), - subject = msgRequestObj.Value("subject"), - important = msgRequestObj.Value("important"), - chain_id = msgRequestObj.Value("chainId"), - is_sended = msgRequestObj.Value("folder") != 1, - date_created = msg_date_created, - introduction = msgRequestObj.Value("introduction"), - message_id = message_id, - message_url = messageUrl - }); - - item.CreateOn = DateTime.Parse(msg_date_created, CultureInfo.InvariantCulture); - - var sqlQueryFindMailsAlready = Query(CRMDbContext.RelationshipEvent) - .Where(x => x.ContactId == item.ContactID) - .Where(x => x.EntityType == item.EntityType) - .Where(x => x.EntityId == item.EntityID) - .Where(x => x.CategoryId == item.CategoryID) - .Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, String.Format("\"message_id\":{0},", message_id))); - - if (sqlQueryFindMailsAlready.Count() > 0) - throw new Exception("Already exists"); + //var msgResponseWrapper = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg))); + //var msgRequestObj = msgResponseWrapper.Value("response"); + //string messageUrl; + + //htmlBody = msgRequestObj.Value("htmlBody"); + + //using (var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(htmlBody))) + //{ + // var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); + + // Global.GetStore().Save("mail_messages", filePath, fileStream); + + // messageUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=mailmessage&message_id={1}", PathProvider.BaseAbsolutePath, messageId).ToLower(); + + //} + + //var msg_date_created = msgRequestObj.Value("date"); + //var message_id = msgRequestObj.Value("id"); + //item.Content = JsonConvert.SerializeObject(new + //{ + // @from = msgRequestObj.Value("from"), + // to = msgRequestObj.Value("to"), + // cc = msgRequestObj.Value("cc"), + // bcc = msgRequestObj.Value("bcc"), + // subject = msgRequestObj.Value("subject"), + // important = msgRequestObj.Value("important"), + // chain_id = msgRequestObj.Value("chainId"), + // is_sended = msgRequestObj.Value("folder") != 1, + // date_created = msg_date_created, + // introduction = msgRequestObj.Value("introduction"), + // message_id = message_id, + // message_url = messageUrl + //}); + + //item.CreateOn = DateTime.Parse(msg_date_created, CultureInfo.InvariantCulture); + + //var sqlQueryFindMailsAlready = Query(CRMDbContext.RelationshipEvent) + // .Where(x => x.ContactId == item.ContactID) + // .Where(x => x.EntityType == item.EntityType) + // .Where(x => x.EntityId == item.EntityID) + // .Where(x => x.CategoryId == item.CategoryID) + // .Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, String.Format("\"message_id\":{0},", message_id))); + + //if (sqlQueryFindMailsAlready.Count() > 0) + // throw new Exception("Already exists"); } var itemToInsert = new DbRelationshipEvent @@ -560,7 +558,7 @@ public List GetItems( { foreach (var k in keywords) { - sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, k)); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, k + "%")); } } } @@ -710,7 +708,7 @@ private static string GetHistoryContentJson(JObject apiResponse) var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent)); - using (var stream = new MemoryStream()) + using (var stream = new System.IO.MemoryStream()) { serializer.WriteObject(stream, content_struct); return Encoding.UTF8.GetString(stream.ToArray()); diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index f48258654cd..d9c7e1b94f7 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -24,38 +24,72 @@ */ -using System; -using System.Collections.Generic; -using System.Linq; - -using ASC.Common.Data.Sql; -using ASC.Common.Data.Sql.Expressions; +using ASC.Common.Logging; using ASC.Common.Utils; +using ASC.Core; +using ASC.Core.Common.EF; using ASC.Core.Tenants; +using ASC.CRM.Classes; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Web.Core.ModuleManagement.Common; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM; -using ASC.Web.CRM.Classes; using ASC.Web.CRM.Configuration; using ASC.Web.CRM.Core.Search; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; namespace ASC.CRM.Core.Dao { public class SearchDao : AbstractDao - { + { private Dictionary> _findedIDs; private bool _fullTextSearchEnable; private DaoFactory DaoFactory { get; set; } - - public SearchDao(int tenantID, DaoFactory daoFactory) - : base(tenantID) + + + public SearchDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + PathProvider pathProvider, + FactoryIndexer tasksWrapperIndexer, + FactoryIndexer invoicesWrapperIndexer, + IOptionsMonitor logger, + WebImageSupplier webImageSupplier, + BundleSearch bundleSearch + ) : + base(dbContextManager, + tenantManager, + securityContext, + logger) { - DaoFactory = daoFactory; + TasksWrapperIndexer = tasksWrapperIndexer; + InvoicesWrapperIndexer = invoicesWrapperIndexer; + CRMSecurity = cRMSecurity; + TenantUtil = tenantUtil; + PathProvider = pathProvider; + WebImageSupplier = webImageSupplier; + BundleSearch = bundleSearch; } + public BundleSearch BundleSearch { get; } + + public WebImageSupplier WebImageSupplier { get; } + + public TenantUtil TenantUtil { get; } + public PathProvider PathProvider { get; } + public FactoryIndexer TasksWrapperIndexer { get; } + public FactoryIndexer InvoicesWrapperIndexer { get; } + public CRMSecurity CRMSecurity { get; } + public SearchResultItem[] Search(String searchText) { var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) @@ -68,7 +102,7 @@ public SearchResultItem[] Search(String searchText) && BundleSearch.Support(EntityType.Opportunity) && BundleSearch.Support(EntityType.Task) && BundleSearch.Support(EntityType.Invoice); - + if (_fullTextSearchEnable) { _findedIDs = new Dictionary>(); @@ -92,13 +126,15 @@ public SearchResultItem[] Search(String searchText) } List tasksId; - if (FactoryIndexer.TrySelectIds(r => r.MatchAll(searchText), out tasksId)) + + if (TasksWrapperIndexer.TrySelectIds(r => r.MatchAll(searchText), out tasksId)) { _findedIDs.Add(EntityType.Task, tasksId); } List invoicesId; - if (FactoryIndexer.TrySelectIds(r => r.MatchAll(searchText), out invoicesId)) + + if (InvoicesWrapperIndexer.TrySelectIds(r => r.MatchAll(searchText), out invoicesId)) { _findedIDs.Add(EntityType.Invoice, invoicesId); } @@ -112,285 +148,293 @@ public SearchResultItem[] Search(String searchText) .ToDictionary(group => group.Key, group => group.First()); } - - var searchQuery = GetSearchQuery(keywords); - - if (searchQuery == null) return new SearchResultItem[0]; - - return ToSearchResultItem(Db.ExecuteList(searchQuery)); + return GetSearchResultItems(keywords); } - + private Dictionary> SearchByRelationshipEvent(String[] keywords) { - var historyQuery = Query("crm_relationship_event") - .Select( - "contact_id", - "entity_id", - "entity_type") - .Distinct() - .Where(BuildLike(new[] { "content" }, keywords)); - - return Db.ExecuteList(historyQuery).ConvertAll(row => - { - var entityID = Convert.ToInt32(row[1]); + var sqlQuery = Query(CRMDbContext.RelationshipEvent); - if (entityID > 0) - return new[] { row[1], row[2] }; - - return new[] { row[0], (int)EntityType.Contact }; + if (keywords.Length > 0) + { + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, k + "%")); + } + } - }).GroupBy(row => row[1]) - .ToDictionary(x => (EntityType)x.Key, x => x.SelectMany(item => item).Select(Convert.ToInt32)); + return sqlQuery.GroupBy(x => x.EntityType) + .ToDictionary(x => x.Key, x => x.Select(y => y.EntityId > 0 ? y.EntityId : y.ContactId)); } private Dictionary> SearchByCustomFields(String[] keywords) { + var sqlQuery = Query(CRMDbContext.FieldValue); - var customFieldQuery = Query("crm_field_value") - .Select("entity_id", - "entity_type") - .Distinct() - .Where(BuildLike(new[] { "value" }, keywords)); + if (keywords.Length > 0) + { + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Value, k + "%")); + } + } - return Db.ExecuteList(customFieldQuery) - .GroupBy(row => row[1]) - .ToDictionary(x => (EntityType)x.Key, x => x.SelectMany(item => item).Select(Convert.ToInt32)); + return sqlQuery.GroupBy(x => x.EntityType) + .ToDictionary(x => x.Key, x => x.Select(x => x.EntityId)); } private Dictionary> SearchByContactInfos(String[] keywords) { - var sqlResult = Db.ExecuteList(Query("crm_contact_info").Distinct() - .Select("contact_id") - .Where(BuildLike(new[] { "data" }, keywords))).Select(item => Convert.ToInt32(item[0])); - + var sqlQuery = Query(CRMDbContext.ContactsInfo); - return new Dictionary> { { EntityType.Contact, sqlResult } }; - } - - private String ToColumn(EntityType entityType) - { - return String.Format("{0} as container_type", (int)entityType); - } - - - private Exp BuildWhereExp(EntityType entityType, String[] keywords) - { - Exp where = Exp.Empty; - - if (_findedIDs.ContainsKey(entityType)) - where = Exp.In("id", _findedIDs[entityType].ToArray()); - - if (BundleSearch.Support(entityType)) return where; - - Exp byField; - - switch (entityType) + if (keywords.Length > 0) { - case EntityType.Contact: - byField = BuildLike(new[] - { - "first_name", - "last_name", - "company_name", - "title", - "notes" - }, keywords); - break; - case EntityType.Opportunity: - byField = BuildLike(new[] - { - "title", - "description" - }, keywords); - break; - case EntityType.Task: - byField = BuildLike(new[] - { - "title", - "description" - }, keywords); - break; - case EntityType.Case: - byField = BuildLike(new[] - { - "title" - }, keywords); - break; - case EntityType.Invoice: - byField = BuildLike(new[] - { - "number", - "description" - }, keywords); - break; - default: - throw new ArgumentException(); - + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Data, k + "%")); + } } - if (where != Exp.Empty) - where &= byField; - else - where = byField; - - return where; + return new Dictionary> { { EntityType.Contact, sqlQuery.Select(x => x.ContactId).Distinct() } }; } - + private bool IncludeToSearch(EntityType entityType) { - return !BundleSearch.Support(entityType) || _findedIDs.ContainsKey(entityType); + return !BundleSearch.Support(entityType) || _findedIDs.ContainsKey(entityType); } - private SqlQuery GetSearchQuery(String[] keywords) + private SearchResultItem[] GetSearchResultItems(String[] keywords) { - var queries = new List(); + var result = new List(); if (IncludeToSearch(EntityType.Task)) - queries.Add(Query("crm_task") - .Select(ToColumn(EntityType.Task), "id", "title", "description", "contact_id", "entity_id", - "entity_type", "create_on") - .Where(BuildWhereExp(EntityType.Task, keywords))); + { + var sqlQuery = Query(CRMDbContext.Tasks); - if (IncludeToSearch(EntityType.Opportunity)) - queries.Add(Query("crm_deal") - .Select(ToColumn(EntityType.Opportunity), "id", "title", "description", "contact_id", "0 as entity_id", "0 as entity_type", "create_on") - .Where(BuildWhereExp(EntityType.Opportunity, keywords))); + if (_findedIDs.ContainsKey(EntityType.Task)) + { + sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Task].Contains(x.Id)); + } + else + { + if (keywords.Length > 0) + { + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%")); + } + } + } - if (IncludeToSearch(EntityType.Contact)) - queries.Add(Query("crm_contact") - .Select(ToColumn(EntityType.Contact), - "id", - String.Format(@"case is_company - when 0 then - concat(first_name, ' ', last_name) - else - company_name - end as title"), - "notes as description", "0 as contact_id", "0 as entity_id", "0 as entity_type", "create_on") - .Where(BuildWhereExp(EntityType.Contact, keywords))); + sqlQuery.ToList().ForEach(x => + { + if (!CRMSecurity.CanAccessTo(new Task { ID = x.Id })) return; + + result.Add(new SearchResultItem + { + Name = x.Title, + Description = HtmlUtil.GetText(x.Description, 120), + URL = PathProvider.BaseAbsolutePath, + Date = TenantUtil.DateTimeFromUtc(x.CreateOn), + Additional = new Dictionary + { { "imageRef", WebImageSupplier.GetAbsoluteWebPath("tasks_widget.png", ProductEntryPoint.ID) }, + {"relativeInfo", GetPath( + x.ContactId, + x.EntityId, + x.EntityType)}, + {"typeInfo", EntityType.Task.ToLocalizedString()} + } + }); + }); + } + if (IncludeToSearch(EntityType.Opportunity)) + { + var sqlQuery = Query(CRMDbContext.Deals); - if (IncludeToSearch(EntityType.Case)) - queries.Add(Query("crm_case") - .Select(ToColumn(EntityType.Case), "id", "title", "'' as description", "0 as contact_id", "0 as entity_id", "0 as entity_type", "create_on") - .Where(BuildWhereExp(EntityType.Case, keywords))); + if (_findedIDs.ContainsKey(EntityType.Opportunity)) + { + sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Opportunity].Contains(x.Id)); + } + else + { + if (keywords.Length > 0) + { + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%")); + } + } + } - if (IncludeToSearch(EntityType.Invoice)) - queries.Add(Query("crm_invoice") - .Select(ToColumn(EntityType.Invoice), "id", "number as title", "description", "contact_id", "entity_id", "entity_type", "create_on") - .Where(BuildWhereExp(EntityType.Invoice, keywords))); + sqlQuery.ToList().ForEach(x => + { + if (!CRMSecurity.CanAccessTo(new Deal { ID = x.Id })) return; + + result.Add(new SearchResultItem + { + Name = x.Title, + Description = HtmlUtil.GetText(x.Description, 120), + URL = string.Concat(PathProvider.BaseAbsolutePath, string.Format("deals.aspx?id={0}", x.Id)), + Date = TenantUtil.DateTimeFromUtc(x.CreateOn), + Additional = new Dictionary + { { "imageRef", WebImageSupplier.GetAbsoluteWebPath("deal_widget.png", ProductEntryPoint.ID) }, + {"relativeInfo", GetPath( + x.ContactId, + 0, + 0)}, + {"typeInfo", EntityType.Opportunity.ToLocalizedString()} + } + }); - if (queries.Count == 0) return null; - if (queries.Count == 1) return queries[0]; - return queries[0].UnionAll(queries.Skip(1).ToArray()); - } + }); + } - private SearchResultItem[] ToSearchResultItem(IEnumerable rows) - { - var result = new List(); - foreach (var row in rows) + if (IncludeToSearch(EntityType.Contact)) { - var containerType = ((EntityType)Convert.ToInt32(row[0])); - var id = row[1]; - string imageRef; - String url; + var sqlQuery = Query(CRMDbContext.Contacts); - switch (containerType) + if (_findedIDs.ContainsKey(EntityType.Contact)) + { + sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Contact].Contains(x.Id)); + } + else { - case EntityType.Contact: + if (keywords.Length > 0) + { + foreach (var k in keywords) { - - var contact = DaoFactory.ContactDao.GetByID(Convert.ToInt32(id)); - - if (contact == null || !CRMSecurity.CanAccessTo(contact)) continue; - - url = String.Format("default.aspx?id={0}", id); - - if (contact is Company) - imageRef = WebImageSupplier.GetAbsoluteWebPath("companies_widget.png", - ProductEntryPoint.ID); - else - imageRef = WebImageSupplier.GetAbsoluteWebPath("people_widget.png", - ProductEntryPoint.ID); - - break; + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.FirstName, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.LastName, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.CompanyName, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Notes, k + "%") + ); } - case EntityType.Opportunity: - { - - var deal = DaoFactory.DealDao.GetByID(Convert.ToInt32(id)); + } + } - if (deal == null || !CRMSecurity.CanAccessTo(deal)) continue; + sqlQuery.ToList().ForEach(x => + { + if (x.IsCompany) + { + if (!CRMSecurity.CanAccessTo(new Company { ID = x.Id })) return; + } + else + { + if (!CRMSecurity.CanAccessTo(new Person { ID = x.Id })) return; + } + + result.Add(new SearchResultItem + { + Name = x.IsCompany ? x.CompanyName : String.Format("{0} {1}", x.FirstName, x.LastName), + Description = HtmlUtil.GetText(x.Notes, 120), + URL = String.Concat(PathProvider.BaseAbsolutePath, String.Format("default.aspx?id={0}", x.Id)), + Date = TenantUtil.DateTimeFromUtc(x.CreateOn), + Additional = new Dictionary + { { "imageRef", WebImageSupplier.GetAbsoluteWebPath(x.IsCompany ? "companies_widget.png" : "people_widget.png", ProductEntryPoint.ID) }, + {"relativeInfo", GetPath( + 0, + 0, + 0)}, + {"typeInfo", EntityType.Contact.ToLocalizedString()} + } + }); + }); + } - url = String.Format("deals.aspx?id={0}", id); + if (IncludeToSearch(EntityType.Case)) + { + var sqlQuery = Query(CRMDbContext.Cases); - imageRef = WebImageSupplier.GetAbsoluteWebPath("deal_widget.png", - ProductEntryPoint.ID); - break; - } - case EntityType.Case: + if (_findedIDs.ContainsKey(EntityType.Case)) + { + sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Case].Contains(x.Id)); + } + else + { + if (keywords.Length > 0) + { + foreach (var k in keywords) { - var cases = DaoFactory.CasesDao.GetByID(Convert.ToInt32(id)); - - if (cases == null || !CRMSecurity.CanAccessTo(cases)) continue; - - url = String.Format("cases.aspx?id={0}", id); - - imageRef = WebImageSupplier.GetAbsoluteWebPath("cases_widget.png", - ProductEntryPoint.ID); - - break; + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%")); } - case EntityType.Task: - { - var task = DaoFactory.TaskDao.GetByID(Convert.ToInt32(id)); - - if (task == null || !CRMSecurity.CanAccessTo(task)) continue; + } + } - url = ""; + sqlQuery.ToList().ForEach(x => + { + if (!CRMSecurity.CanAccessTo(new Cases { ID = x.Id })) return; + + result.Add(new SearchResultItem + { + Name = x.Title, + Description = String.Empty, + URL = String.Concat(PathProvider.BaseAbsolutePath, String.Format("cases.aspx?id={0}", x.Id)), + Date = TenantUtil.DateTimeFromUtc(x.CreateOn), + Additional = new Dictionary + { { "imageRef", WebImageSupplier.GetAbsoluteWebPath("cases_widget.png", ProductEntryPoint.ID) }, + {"relativeInfo", GetPath( + 0, + 0, + 0)}, + {"typeInfo", EntityType.Case.ToLocalizedString()} + } + }); - imageRef = WebImageSupplier.GetAbsoluteWebPath("tasks_widget.png", - ProductEntryPoint.ID); - break; - } - case EntityType.Invoice: - { - var invoice = DaoFactory.InvoiceDao.GetByID(Convert.ToInt32(id)); + }); - if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) continue; + } - url = String.Format("invoices.aspx?id={0}", id); - imageRef = WebImageSupplier.GetAbsoluteWebPath("invoices_widget.png", - ProductEntryPoint.ID); + if (IncludeToSearch(EntityType.Invoice)) + { + var sqlQuery = Query(CRMDbContext.Invoices); - break; + if (_findedIDs.ContainsKey(EntityType.Invoice)) + { + sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Invoice].Contains(x.Id)); + } + else + { + if (keywords.Length > 0) + { + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Number, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%")); } - default: - throw new ArgumentException(); + } } - result.Add(new SearchResultItem + sqlQuery.ToList().ForEach(x => { - Name = Convert.ToString(row[2]), - Description = HtmlUtil.GetText(Convert.ToString(row[3]), 120), - URL = !string.IsNullOrEmpty(url) ? String.Concat(PathProvider.BaseAbsolutePath, url) : string.Empty, - Date = TenantUtil.DateTimeFromUtc(DateTime.Parse(Convert.ToString(row[7]))), - Additional = new Dictionary - { { "imageRef", imageRef }, - {"relativeInfo", GetPath( - Convert.ToInt32(row[4]), - Convert.ToInt32(row[5]), - (EntityType)Convert.ToInt32(row[6]))}, - {"typeInfo", containerType.ToLocalizedString()} - } + if (!CRMSecurity.CanAccessTo(new Invoice { ID = x.Id })) return; + + result.Add(new SearchResultItem + { + Name = x.Number, + Description = String.Empty, + URL = String.Concat(PathProvider.BaseAbsolutePath, String.Format("invoices.aspx?id={0}", x.Id)), + Date = TenantUtil.DateTimeFromUtc(x.CreateOn), + Additional = new Dictionary + { { "imageRef", WebImageSupplier.GetAbsoluteWebPath("invoices_widget.png", ProductEntryPoint.ID) }, + {"relativeInfo", GetPath( + x.ContactId, + x.EntityId, + x.EntityType)}, + {"typeInfo", EntityType.Invoice.ToLocalizedString()} + } + }); + }); } return result.ToArray(); - } private String GetPath(int contactID, int entityID, EntityType entityType) diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 883a449e5d7..625ce62ac7b 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -24,12 +24,14 @@ */ +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using Microsoft.EntityFrameworkCore.Internal; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -41,10 +43,12 @@ public class TagDao : AbstractDao { public TagDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) : + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 2680e7ba4c7..e370c990528 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -115,8 +115,7 @@ public TaskDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, TenantUtil tenantUtil, FactoryIndexer factoryIndexer, - IOptionsMonitor logger, - DbContextManager coreDbContext + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, @@ -126,12 +125,9 @@ DbContextManager coreDbContext CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; FactoryIndexer = factoryIndexer; - CoreDbContext = coreDbContext.Value; - + } - public CoreDbContext CoreDbContext { get; } - public FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } @@ -339,8 +335,8 @@ private List GetCrudeTasks( { foreach (var k in keywords) { - sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k) || - Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k)); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%")); } } else diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index c8fba077e59..515ea7cb5e0 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -24,13 +24,10 @@ */ -#region Usings - using System; using System.Runtime.Serialization; using ASC.Common.Security; - -#endregion +using ASC.CRM.Core.Enums; namespace ASC.CRM.Core.Entities { @@ -80,30 +77,30 @@ public class Deal : DomainObject, ISecurityObjectId public DateTime ActualCloseDate { get; set; } - [DataMember(Name = "actual_close_date")] - private String ActualCloseDateStr - { - get - { - return ActualCloseDate.Date == DateTime.MinValue.Date - ? string.Empty : ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern); - } - set { ; } - } + //[DataMember(Name = "actual_close_date")] + //private String ActualCloseDateStr + //{ + // get + // { + // return ActualCloseDate.Date == DateTime.MinValue.Date + // ? string.Empty : ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern); + // } + // set { ; } + //} public DateTime ExpectedCloseDate { get; set; } [DataMember(Name = "expected_close_date")] - private String ExpectedCloseDateStr - { - get - { - return ExpectedCloseDate.Date == DateTime.MinValue.Date - ? string.Empty : ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern); - } - set { ; } - } + //private String ExpectedCloseDateStr + //{ + // get + // { + // return ExpectedCloseDate.Date == DateTime.MinValue.Date + // ? string.Empty : ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern); + // } + // set { ; } + //} public object SecurityId { diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index cb7c74dd37f..cf2529ec7ad 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -27,63 +27,122 @@ using System.Collections.Generic; using System.Linq; using ASC.CRM.Core; +using ASC.CRM.Core.Enums; using ASC.ElasticSearch; namespace ASC.Web.CRM.Core.Search { public class BundleSearch { - public static bool Support(EntityType entityType) + public BundleSearch(FactoryIndexer contactsWrapperFactoryIndexer, + FactoryIndexer infoWrapperFactoryIndexer, + FactoryIndexer fieldsWrapperFactoryIndexer, + FactoryIndexer eventsWrapperFactoryIndexer, + FactoryIndexer dealsWrapperFactoryIndexer, + FactoryIndexer tasksWrapperFactoryIndexer, + FactoryIndexer casesWrapperFactoryIndexer, + FactoryIndexer invoicesWrapperFactoryIndexer, + FactoryIndexerHelper factoryIndexerHelper, + ContactsWrapper contactsWrapper, + InfoWrapper infoWrapper, + FieldsWrapper fieldsWrapper, + EventsWrapper eventsWrapper, + DealsWrapper dealsWrapper, + TasksWrapper tasksWrapper, + CasesWrapper casesWrapper, + InvoicesWrapper invoicesWrapper) + { + ContactsWrapperFactoryIndexer = contactsWrapperFactoryIndexer; + InfoWrapperFactoryIndexer = infoWrapperFactoryIndexer; + FieldsWrapperFactoryIndexer = fieldsWrapperFactoryIndexer; + EventsWrapperFactoryIndexer = eventsWrapperFactoryIndexer; + DealsWrapperFactoryIndexer = dealsWrapperFactoryIndexer; + TasksWrapperFactoryIndexer = tasksWrapperFactoryIndexer; + CasesWrapperFactoryIndexer = casesWrapperFactoryIndexer; + InvoicesWrapperFactoryIndexer = invoicesWrapperFactoryIndexer; + FactoryIndexerHelper = factoryIndexerHelper; + + ContactsWrapper = contactsWrapper; + InfoWrapper = infoWrapper; + FieldsWrapper = fieldsWrapper; + EventsWrapper = eventsWrapper; + DealsWrapper = dealsWrapper; + TasksWrapper = tasksWrapper; + CasesWrapper = casesWrapper; + InvoicesWrapper = invoicesWrapper; + + } + + public ContactsWrapper ContactsWrapper { get; } + public InfoWrapper InfoWrapper { get; } + public FieldsWrapper FieldsWrapper { get; } + public EventsWrapper EventsWrapper { get; } + public DealsWrapper DealsWrapper { get; } + public TasksWrapper TasksWrapper { get; } + public CasesWrapper CasesWrapper { get; } + public InvoicesWrapper InvoicesWrapper { get; } + + public FactoryIndexerHelper FactoryIndexerHelper { get; } + public FactoryIndexer ContactsWrapperFactoryIndexer { get; } + public FactoryIndexer InfoWrapperFactoryIndexer { get; } + public FactoryIndexer FieldsWrapperFactoryIndexer { get; } + public FactoryIndexer EventsWrapperFactoryIndexer { get; } + public FactoryIndexer DealsWrapperFactoryIndexer { get; } + public FactoryIndexer TasksWrapperFactoryIndexer { get; } + public FactoryIndexer CasesWrapperFactoryIndexer { get; } + public FactoryIndexer InvoicesWrapperFactoryIndexer { get; } + + public bool Support(EntityType entityType) { switch (entityType) { case EntityType.Person: case EntityType.Contact: case EntityType.Company: - return FactoryIndexer.Support && - FactoryIndexer.Support && - FactoryIndexer.Support && - FactoryIndexer.Support; + return FactoryIndexerHelper.Support(ContactsWrapper) && + FactoryIndexerHelper.Support(InfoWrapper) && + FactoryIndexerHelper.Support(FieldsWrapper) && + FactoryIndexerHelper.Support(EventsWrapper); case EntityType.Opportunity: - return FactoryIndexer.Support && - FactoryIndexer.Support && - FactoryIndexer.Support; + return FactoryIndexerHelper.Support(DealsWrapper) && + FactoryIndexerHelper.Support(FieldsWrapper) && + FactoryIndexerHelper.Support(EventsWrapper); case EntityType.RelationshipEvent: - return FactoryIndexer.Support; + return FactoryIndexerHelper.Support(EventsWrapper); case EntityType.Task: - return FactoryIndexer.Support; + return FactoryIndexerHelper.Support(TasksWrapper); case EntityType.Case: - return FactoryIndexer.Support && - FactoryIndexer.Support && - FactoryIndexer.Support; + return FactoryIndexerHelper.Support(CasesWrapper) && + FactoryIndexerHelper.Support(FieldsWrapper) && + FactoryIndexerHelper.Support(EventsWrapper); case EntityType.Invoice: - return FactoryIndexer.Support; + return FactoryIndexerHelper.Support(InvoicesWrapper); } return false; } - public static bool TrySelectCase(string text, out List result) + public bool TrySelectCase(string text, out List result) { var success = false; result = new List(); List casesId; - if (FactoryIndexer.TrySelectIds(s => s.MatchAll(text), out casesId)) + if (CasesWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out casesId)) { result.AddRange(casesId); success = true; } IReadOnlyCollection casesCustom; - if (FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7), out casesCustom)) + if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7), out casesCustom)) { result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); success = true; } IReadOnlyCollection events; - if (!FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) + if (!EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) { result.AddRange(events.Select(r => r.EntityId).ToList()); success = true; @@ -92,34 +151,38 @@ public static bool TrySelectCase(string text, out List result) return success; } - public static bool TrySelectContact(string text, out List result) + public bool TrySelectContact(string text, out List result) { var success = false; result = new List(); List contactsId; - if (FactoryIndexer.TrySelectIds(s => s.MatchAll(text), out contactsId)) + + if (ContactsWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out contactsId)) { result.AddRange(contactsId); success = true; } IReadOnlyCollection infos; - if (FactoryIndexer.TrySelect(s => s.MatchAll(text), out infos)) + + if (InfoWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text), out infos)) { result.AddRange(infos.Select(r => r.ContactId).ToList()); success = true; } IReadOnlyCollection personCustom; - if (FactoryIndexer.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] {0, 4, 5}), out personCustom)) + + if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] {0, 4, 5}), out personCustom)) { result.AddRange(personCustom.Select(r => r.EntityId).ToList()); success = true; } IReadOnlyCollection events; - if (FactoryIndexer.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events)) + + if (EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events)) { result.AddRange(events.Select(r => r.ContactId).ToList()); success = true; @@ -128,27 +191,27 @@ public static bool TrySelectContact(string text, out List result) return success; } - public static bool TrySelectOpportunity(string text, out List result) + public bool TrySelectOpportunity(string text, out List result) { var success = false; result = new List(); List dealsId; - if (FactoryIndexer.TrySelectIds(s => s.MatchAll(text), out dealsId)) + if (DealsWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out dealsId)) { result.AddRange(dealsId); success = true; } IReadOnlyCollection casesCustom; - if (FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1), out casesCustom)) + if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1), out casesCustom)) { result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); success = true; } IReadOnlyCollection events; - if (!FactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1).Gt(r => r.EntityId, 0), out events)) + if (!EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1).Gt(r => r.EntityId, 0), out events)) { result.AddRange(events.Select(r => r.EntityId).ToList()); success = true; diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index abdd538451e..9e01a63e57e 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -226,7 +226,7 @@ public void SetAccessTo(ISecurityObjectId entity, List subjectID) AuthorizationManager.AddAce(new AzRecord(Constants.GroupEveryone.ID, _actionRead.ID, AceType.Deny, entity)); } - public void SetAccessTo(File file) + public void SetAccessTo(File file) { if (IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID) file.Access = FileShare.None; @@ -387,7 +387,7 @@ public bool CanAccessTo(InvoiceTax invoiceTax, Guid userId) return false; } - public bool CanEdit(File file) + public bool CanEdit(File file) { if (!(IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID)) return false; @@ -532,7 +532,7 @@ public bool IsPrivate(Contact contact) return contact.ShareType == ShareType.None; } - public void DemandAccessTo(File file) + public void DemandAccessTo(File file) { // if (!CanAccessTo((File)file)) CreateSecurityException(); } @@ -572,7 +572,7 @@ public void DemandAccessTo(InvoiceTax invoiceTax) if (!CanAccessTo(invoiceTax)) throw CreateSecurityException(); } - public void DemandEdit(File file) + public void DemandEdit(File file) { if (!CanEdit(file)) throw CreateSecurityException(); } @@ -617,7 +617,7 @@ public void DemandEdit(InvoiceItem invoiceItem) if (!CanEdit(invoiceItem)) throw CreateSecurityException(); } - public void DemandDelete(File file) + public void DemandDelete(File file) { if (!CanEdit(file)) throw CreateSecurityException(); } From f8f3f09cc460c0c5cca6d205735c952ba8fe2463 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 10 Apr 2020 00:22:26 +0300 Subject: [PATCH 08/61] crm: migrate DAO to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 1 + .../Server/Classes/InvoiceFormattedData.cs | 12 +- .../Server/Configuration/ProductEntryPoint.cs | 12 +- .../Server/Core/Dao/CurrencyRateDao.cs | 8 +- .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 8 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 254 ++--- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 21 +- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 229 ++--- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 15 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 891 +++++++++--------- products/ASC.CRM/Server/Core/EF/DbDeal.cs | 3 +- .../ASC.CRM/Server/Core/EF/DbReportFile.cs | 11 +- .../ASC.CRM/Server/Core/EF/DbVoipCalls.cs | 4 +- .../ASC.CRM/Server/Core/Entities/Invoice.cs | 3 +- .../Server/Core/Entities/InvoiceItem.cs | 1 - .../Core/Security/FileSecurityProvider.cs | 19 +- .../HttpHandlers/ContactPhotoHandler.cs | 32 +- .../Server/HttpHandlers/FileHandler.ashx.cs | 21 +- .../HttpHandlers/FileUploaderHandler.cs | 9 + .../Server/HttpHandlers/ImportFileHandler.cs | 18 +- .../HttpHandlers/OrganisationLogoHandler.cs | 18 +- .../HttpHandlers/WebToLeadFromHandler.ashx.cs | 31 +- .../Services/NotifyService/NotifyClient.cs | 109 ++- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 82 +- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 131 +-- .../Utils/Import/CSV/ImportCSVSettings.cs | 3 +- .../Server/Utils/Import/CSV/ImportCases.cs | 11 +- .../Server/Utils/Import/CSV/ImportContacts.cs | 70 +- .../Utils/Import/CSV/ImportDataOperation.cs | 115 ++- .../Server/Utils/Import/CSV/ImportDeals.cs | 16 +- .../Server/Utils/Import/CSV/ImportTasks.cs | 11 +- products/ASC.CRM/Server/Utils/MailSender.cs | 295 +++--- products/ASC.CRM/Server/Utils/PdfCreator.cs | 118 ++- .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 6 +- 35 files changed, 1366 insertions(+), 1230 deletions(-) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index b00e2fa10d2..93a0d0a00d2 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -6,6 +6,7 @@ + diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 00aa1cef506..85b1d1ed54f 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -24,19 +24,17 @@ */ -using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; -using ASC.Web.CRM.Resources; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.CRM.Core; +using Autofac; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Text; -using System.Web; -using ASC.CRM.Core.Dao; -using ASC.Web.CRM.Core; -using Autofac; namespace ASC.Web.CRM.Classes { diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index ebf2d1387ce..0367ba3679f 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -166,7 +166,9 @@ public override void Init() public void ConfigurePortal() { - if (!Global.TenantSettings.IsConfiguredPortal) + var tenantSettings = SettingsManager.Load(); + + if (!tenantSettings.IsConfiguredPortal) { using (var scope = DIHelper.Resolve()) { @@ -289,9 +291,7 @@ public void ConfigurePortal() daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Customer, true); daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Supplier, true); daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Staff, true); - - var tenantSettings = Global.TenantSettings; - + tenantSettings.WebFormKey = Guid.NewGuid(); tenantSettings.IsConfiguredPortal = true; @@ -302,7 +302,7 @@ public void ConfigurePortal() } } - if (!Global.TenantSettings.IsConfiguredSmtp) + if (!tenantSettings.IsConfiguredSmtp) { var smtp = SettingsManager.Load().SMTPServerSettingOld; @@ -331,7 +331,7 @@ public void ConfigurePortal() } } - var tenantSettings = Global.TenantSettings; + tenantSettings.IsConfiguredSmtp = true; if (!SettingsManager.Save(tenantSettings)) diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index f9c8b2cc1b7..ef9ed9cfe45 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -26,9 +26,11 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; +using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao { @@ -37,10 +39,12 @@ public class CurrencyRateDao : AbstractDao public CurrencyRateDao( DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) : + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { } diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 4cace532364..625f99406ce 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -109,10 +109,10 @@ public TaskTemplateDao TaskTemplateDao get { return Container.Resolve(tenant); } } - public ReportDao ReportDao - { - get { return Container.Resolve(tenant); } - } + //public ReportDao ReportDao + //{ + // get { return Container.Resolve(tenant); } + //} public CurrencyRateDao CurrencyRateDao { diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index da3f7e16bae..3f9d244b4bc 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -59,14 +59,16 @@ public CachedDealDao(DbContextManager dbContextManager, FactoryIndexer factoryIndexer, FilesIntegration filesIntegration, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger) + IOptionsMonitor logger, + BundleSearch bundleSearch) : base(dbContextManager, tenantManager, securityContext, cRMSecurity, factoryIndexer, filesIntegration, - logger) + logger, + bundleSearch) { _dealCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal"); } @@ -114,7 +116,8 @@ public DealDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, FactoryIndexer factoryIndexer, FilesIntegration filesIntegration, - IOptionsMonitor logger) : + IOptionsMonitor logger, + BundleSearch bundleSearch) : base(dbContextManager, tenantManager, securityContext, @@ -123,11 +126,14 @@ public DealDao(DbContextManager dbContextManager, CRMSecurity = cRMSecurity; FactoryIndexer = factoryIndexer; FilesIntegration = filesIntegration; + BundleSearch = bundleSearch; } - FilesIntegration FilesIntegration { get; } + public BundleSearch BundleSearch { get; } + + public FilesIntegration FilesIntegration { get; } - FactoryIndexer FactoryIndexer { get; } + public FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } public CRMSecurity CRMSecurity { get; } @@ -275,6 +281,9 @@ public virtual void EditDeal(Deal deal) itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + CRMDbContext.Update(itemToUpdate); + CRMDbContext.SaveChanges(); + FactoryIndexer.IndexAsync(deal); } @@ -308,10 +317,17 @@ private IQueryable GetDbDealByFilters( IEnumerable tags, int contactID, DealMilestoneStatus? stageType, - bool? contactAlsoIsParticipant) + bool? contactAlsoIsParticipant, + DateTime fromDate, + DateTime toDate, + OrderBy orderBy) { - var sqlQuery = Query(CRMDbContext.Deals); + var sqlQuery = Query(CRMDbContext.Deals).Join(CRMDbContext.DealMilestones, + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y } + ); var ids = new List(); @@ -327,7 +343,7 @@ private IQueryable GetDbDealByFilters( { foreach (var k in keywords) { - sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%")); + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.x.Title, k + "%") || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.x.Description, k + "%")); } } else if (ids.Count == 0) return null; @@ -349,7 +365,7 @@ private IQueryable GetDbDealByFilters( if (relativeContactsID.Count == 0) { - sqlQuery = sqlQuery.Where(x => x.ContactId == contactID); + sqlQuery = sqlQuery.Where(x => x.x.ContactId == contactID); } else { @@ -367,32 +383,21 @@ private IQueryable GetDbDealByFilters( } else { - sqlQuery = sqlQuery.Where(x => x.ContactId == contactID); + sqlQuery = sqlQuery.Where(x => x.x.ContactId == contactID); } } if (0 < milestoneID && milestoneID < int.MaxValue) { - sqlQuery = sqlQuery.Where(x => x.DealMilestoneId == milestoneID); + sqlQuery = sqlQuery.Where(x => x.x.DealMilestoneId == milestoneID); } if (responsibleID != Guid.Empty) { - sqlQuery = sqlQuery.Where(x => x.ResponsibleId == responsibleID); - } - - if (stageType != null) - { - sqlQuery = sqlQuery.Join(CRMDbContext.DealMilestones, - x => x.DealMilestoneId, - y => y.Id, - (x,y) => new { x,y } - ) - .Where(x => x.y.Status == stageType.Value); - - conditions.Add(Exp.Eq("tblDM.status", (int)stageType.Value)); + sqlQuery = sqlQuery.Where(x => x.x.ResponsibleId == responsibleID); } + if (ids.Count > 0) { if (exceptIDs.Count > 0) @@ -401,14 +406,105 @@ private IQueryable GetDbDealByFilters( if (ids.Count == 0) return null; } - sqlQuery = sqlQuery.Where(x => ids.Contains(x.Id)); + sqlQuery = sqlQuery.Where(x => ids.Contains(x.x.Id)); } else if (exceptIDs.Count > 0) { - sqlQuery = sqlQuery.Where(x => !exceptIDs.Contains(x.Id)); + sqlQuery = sqlQuery.Where(x => !exceptIDs.Contains(x.x.Id)); + } + + if ((stageType != null) || (fromDate != DateTime.MinValue && toDate != DateTime.MinValue)) + { + if (stageType != null) + sqlQuery = sqlQuery.Where(x => x.y.Status == stageType.Value); + + if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) + sqlQuery = sqlQuery.Where(x => x.y.Status == 0 ? x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= TenantUtil.DateTimeToUtc(toDate) + : x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)); + } - return sqlQuery; + + if (orderBy != null && Enum.IsDefined(typeof(DealSortedByType), orderBy.SortedBy)) + switch ((DealSortedByType)orderBy.SortedBy) + { + case DealSortedByType.Title: + { + sqlQuery = sqlQuery.OrderBy("x.x.Title", orderBy.IsAsc); + + break; + } + case DealSortedByType.BidValue: + { + sqlQuery = sqlQuery.OrderBy("x.x.BidValue", orderBy.IsAsc); + + break; + } + case DealSortedByType.Responsible: + { + if (orderBy.IsAsc) + { + sqlQuery = sqlQuery.OrderBy(x => x.x.ResponsibleId) + .ThenBy(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); + } + else + { + sqlQuery = sqlQuery.OrderByDescending(x => x.x.ResponsibleId) + .OrderByDescending(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); + + } + + break; + } + case DealSortedByType.Stage: + { + if (orderBy.IsAsc) + { + sqlQuery = sqlQuery.OrderBy(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); + } + else + { + sqlQuery = sqlQuery.OrderByDescending(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); + + } + + break; + + } + case DealSortedByType.DateAndTime: + { + sqlQuery.OrderBy("x.x.close_date", orderBy.IsAsc); + + break; + + } + default: + throw new ArgumentException(); + } + else + { + sqlQuery = sqlQuery.OrderBy(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenBy(x => x.x.Title); + } + + return sqlQuery.Select(x => x.x); } public int GetDealsCount(String searchText, @@ -465,19 +561,14 @@ public int GetDealsCount(String searchText, if (withParams) { var sqlQuery = GetDbDealByFilters(exceptIDs, searchText, responsibleID, milestoneID, tags, - contactID, stageType, contactAlsoIsParticipant); - - if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) - { - sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + contactID, stageType, contactAlsoIsParticipant, + fromDate, + toDate, null); - result = sqlQuery.Count(); - - } - else if (sqlQuery == null) + if (sqlQuery == null) { result = 0; - } + } else { result = sqlQuery.Count(); @@ -619,17 +710,12 @@ private List GetCrudeDeals( tags, contactID, stageType, - contactAlsoIsParticipant); + contactAlsoIsParticipant, + fromDate, + toDate, + orderBy); - - - if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) - { - - - sqlQuery.Having(Exp.Between("close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - } - else if (withParams && sqlQuery == null) + if (withParams && sqlQuery == null) { return new List(); } @@ -644,78 +730,6 @@ private List GetCrudeDeals( sqlQuery = sqlQuery.Take(count); } - if (orderBy != null && Enum.IsDefined(typeof(DealSortedByType), orderBy.SortedBy)) - switch ((DealSortedByType)orderBy.SortedBy) - { - case DealSortedByType.Title: - { - sqlQuery = sqlQuery.OrderBy("Title", orderBy.IsAsc); - - break; - } - case DealSortedByType.BidValue: - { - sqlQuery = sqlQuery.OrderBy("BidValue", orderBy.IsAsc); - - break; - } - case DealSortedByType.Responsible: - { - sqlQuery = sqlQuery.OrderBy(x => x.ResponsibleId) - .ThenBy(x => x.ContactId) - .ThenByDescending(x => x.ActualCloseDate) - .ThenBy(x => x.ExpectedCloseDate) - .ThenBy(x => x.Title); - - throw new NotImplementedException(); - //sqlQuery.OrderBy("tblDeal.responsible_id", orderBy.IsAsc) - // .OrderBy("tblDM.sort_order", orderBy.IsAsc) - // .OrderBy("tblDeal.contact_id", true) - // .OrderBy("tblDeal.actual_close_date", false) - // .OrderBy("tblDeal.expected_close_date", true) - // .OrderBy("tblDeal.title", true); - - break; - } - case DealSortedByType.Stage: - { - sqlQuery = sqlQuery - .OrderBy(x => x.ContactId) - .ThenByDescending(x => x.ActualCloseDate) - .ThenBy(x => x.ExpectedCloseDate) - .ThenBy(x => x.Title); - - sqlQuery.OrderBy("tblDM.sort_order", orderBy.IsAsc) - .ThenBy("tblDeal.contact_id", true) - .ThenBy("tblDeal.actual_close_date", false) - .ThenBy("tblDeal.expected_close_date", true) - .ThenBy("tblDeal.title", true); - - break; - - } - case DealSortedByType.DateAndTime: - { - - sqlQuery.OrderBy("close_date", orderBy.IsAsc); - - break; - - } - default: - throw new ArgumentException(); - } - else - { - - sqlQuery = sqlQuery.OrderBy(x => x.ContactId) - .ThenBy(x => x.Title); - - //sqlQuery.OrderBy("tblDM.sort_order", true) - // .OrderBy("tblDeal.contact_id", true) - // .OrderBy("tblDeal.title", true); - - } return sqlQuery.ToList().ConvertAll(ToDeal); } @@ -882,8 +896,6 @@ private Deal ToDeal(DbDeal dbDeal) }; } - - public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) { var deals = GetDeals(String.Empty, diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 8006f126c69..686271bf881 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -54,9 +54,9 @@ public FileDao(FilesIntegration filesIntegration, public FilesIntegration FilesIntegration { get; } - public File GetFile(int id, int version) + public File GetFile(int id, int version) { - var dao = FilesIntegration.GetFileDao(); + var dao = FilesIntegration.DaoFactory.GetFileDao(); var file = 0 < version ? dao.GetFile(id, version) : dao.GetFile(id); @@ -65,31 +65,32 @@ public File GetFile(int id, int version) public void DeleteFile(int id) { - var dao = FilesIntegration.GetFileDao(); + var dao = FilesIntegration.DaoFactory.GetFileDao(); dao.DeleteFile(id); } - public object GetRoot() + public int GetRoot() { - return FilesIntegration.RegisterBunch("crm", "crm_common", ""); + return FilesIntegration.RegisterBunch("crm", "crm_common", ""); } - public object GetMy() + public int GetMy() { - return FilesIntegration.RegisterBunch("files", "my", SecurityContext.CurrentAccount.ID.ToString()); + return FilesIntegration.RegisterBunch("files", "my", SecurityContext.CurrentAccount.ID.ToString()); } - public File SaveFile(File file, System.IO.Stream stream) + public File SaveFile(File file, System.IO.Stream stream) { - var dao = FilesIntegration.GetFileDao(); + var dao = FilesIntegration.DaoFactory.GetFileDao(); return dao.SaveFile(file, stream); } public List GetEventsByFile(int id) { - var tagdao = FilesIntegration.TagDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var tags = tagdao.GetTags(id, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); return tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index c5b22383bf6..5b46183b661 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -34,6 +34,7 @@ using ASC.CRM.Core.Enums; using ASC.Web.CRM.Classes; using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; @@ -113,6 +114,7 @@ IOptionsMonitor logger CRMSecurity = cRMSecurity; } + public CRMSecurity CRMSecurity { get; } public TenantUtil TenantUtil { get; } @@ -138,28 +140,30 @@ public virtual List GetAll() } public virtual List GetAllInDb() { - return Db.ExecuteList(GetInvoiceItemSqlQuery(null)).ConvertAll(ToInvoiceItem); + return Query(CRMDbContext.InvoiceItem).ToList().ConvertAll(ToInvoiceItem); } public virtual List GetByID(int[] ids) { - return Db.ExecuteList(GetInvoiceItemSqlQuery(Exp.In("id", ids))).ConvertAll(ToInvoiceItem); + return Query(CRMDbContext.InvoiceItem) + .Where(x => ids.Contains(x.Id)) + .ToList() + .ConvertAll(ToInvoiceItem); } public virtual InvoiceItem GetByID(int id) { - var invoiceItems = Db.ExecuteList(GetInvoiceItemSqlQuery(Exp.Eq("id", id))).ConvertAll(ToInvoiceItem); - - return invoiceItems.Count > 0 ? invoiceItems[0] : null; + return ToInvoiceItem(Query(CRMDbContext.InvoiceItem).FirstOrDefault(x => x.Id == id)); } public List GetInvoiceItems(IEnumerable ids) { if (ids == null || !ids.Any()) return new List(); - var sqlQuery = GetInvoiceItemSqlQuery(Exp.In("id", ids.ToArray())); - - return Db.ExecuteList(sqlQuery).ConvertAll(ToInvoiceItem); + return Query(CRMDbContext.InvoiceItem) + .Where(x => ids.Contains(x.Id)) + .ToList() + .ConvertAll(ToInvoiceItem); } public List GetInvoiceItems( @@ -171,52 +175,49 @@ public List GetInvoiceItems( OrderBy orderBy) { - var sqlQuery = GetInvoiceItemSqlQuery(null); + var sqlQuery = GetDbInvoiceItemByFilters(new List(), searchText, status, inventoryStock); var withParams = !(String.IsNullOrEmpty(searchText) || status != 0 || inventoryStock.HasValue); - - var whereConditional = WhereConditional(new List(), searchText, status, inventoryStock); - // WhereConditional(CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(), searchText); - - if (withParams && whereConditional == null) + if (withParams && sqlQuery == null) return new List(); - sqlQuery.Where(whereConditional); - - if (0 < from && from < int.MaxValue) sqlQuery.SetFirstResult(from); - if (0 < count && count < int.MaxValue) sqlQuery.SetMaxResults(count); + if (0 < from && from < int.MaxValue) sqlQuery = sqlQuery.Skip(from); + if (0 < count && count < int.MaxValue) sqlQuery = sqlQuery.Take(count); if (orderBy != null && Enum.IsDefined(typeof(InvoiceItemSortedByType), orderBy.SortedBy)) { switch ((InvoiceItemSortedByType)orderBy.SortedBy) { case InvoiceItemSortedByType.Name: - sqlQuery.OrderBy("title", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("Title", orderBy.IsAsc); break; case InvoiceItemSortedByType.SKU: - sqlQuery.OrderBy("stock_keeping_unit", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("StockKeepingUnit", orderBy.IsAsc); break; case InvoiceItemSortedByType.Price: - sqlQuery.OrderBy("price", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("Price", orderBy.IsAsc); break; case InvoiceItemSortedByType.Quantity: - sqlQuery.OrderBy("stock_quantity", orderBy.IsAsc).OrderBy("title", true); - break; + { + sqlQuery = sqlQuery.OrderBy("StockQuantity", orderBy.IsAsc) + .OrderBy("Title", true); + break; + } case InvoiceItemSortedByType.Created: - sqlQuery.OrderBy("create_on", orderBy.IsAsc); + sqlQuery = sqlQuery.OrderBy("CreateOn", orderBy.IsAsc); break; default: - sqlQuery.OrderBy("title", true); + sqlQuery = sqlQuery.OrderBy("Title", true); break; } } else { - sqlQuery.OrderBy("title", true); + sqlQuery = sqlQuery.OrderBy("Title", true); } - return Db.ExecuteList(sqlQuery).ConvertAll(ToInvoiceItem); + return sqlQuery.ToList().ConvertAll(ToInvoiceItem); } @@ -239,25 +240,25 @@ public int GetInvoiceItemsCount( if (fromCache != null) return Convert.ToInt32(fromCache); - var withParams = !(String.IsNullOrEmpty(searchText) || status != 0 || inventoryStock.HasValue); - var exceptIDs = CRMSecurity.GetPrivateItems(typeof(InvoiceItem)).ToList(); - + int result; + var withParams = !(String.IsNullOrEmpty(searchText) || status != 0 || inventoryStock.HasValue); + if (withParams) { - var whereConditional = WhereConditional(exceptIDs, searchText, status, inventoryStock); - result = whereConditional != null ? Db.ExecuteScalar(Query("crm_invoice_item").Where(whereConditional).SelectCount()) : 0; + result = GetDbInvoiceItemByFilters(exceptIDs, searchText, status, inventoryStock).Count(); } else { - var countWithoutPrivate = Db.ExecuteScalar(Query("crm_invoice_item").SelectCount()); + var countWithoutPrivate = Query(CRMDbContext.InvoiceItem).Count(); + var privateCount = exceptIDs.Count; if (privateCount > countWithoutPrivate) { - _log.ErrorFormat(@"Private invoice items count more than all cases. Tenant: {0}. CurrentAccount: {1}", + Logger.ErrorFormat(@"Private invoice items count more than all cases. Tenant: {0}. CurrentAccount: {1}", TenantID, SecurityContext.CurrentAccount.ID); @@ -303,55 +304,57 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) if (!IsExistInDb(invoiceItem.ID)) { - invoiceItem.ID = Db.ExecuteScalar( - Insert("crm_invoice_item") - .InColumnValue("id", 0) - .InColumnValue("title", invoiceItem.Title) - .InColumnValue("description", invoiceItem.Description) - .InColumnValue("stock_keeping_unit", invoiceItem.StockKeepingUnit) - .InColumnValue("price", invoiceItem.Price) - .InColumnValue("stock_quantity", invoiceItem.StockQuantity) - .InColumnValue("track_inventory", invoiceItem.TrackInventory) - .InColumnValue("invoice_tax1_id", invoiceItem.InvoiceTax1ID) - .InColumnValue("invoice_tax2_id", invoiceItem.InvoiceTax2ID) - .InColumnValue("currency", String.Empty) - .InColumnValue("create_on", DateTime.UtcNow) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .InColumnValue("last_modifed_on", DateTime.UtcNow) - .InColumnValue("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); - - invoiceItem.CreateOn = DateTime.UtcNow; - invoiceItem.LastModifedOn = invoiceItem.CreateOn; - invoiceItem.CreateBy = SecurityContext.CurrentAccount.ID; - invoiceItem.LastModifedBy = invoiceItem.CreateBy; + var itemToInsert = new DbInvoiceItem + { + Title = invoiceItem.Title, + Description = invoiceItem.Description, + StockKeepingUnit = invoiceItem.StockKeepingUnit, + Price = invoiceItem.Price, + StockQuantity = invoiceItem.StockQuantity, + TrackInventory = invoiceItem.TrackInventory, + InvoiceTax1Id = invoiceItem.InvoiceTax1ID, + InvoiceTax2Id = invoiceItem.InvoiceTax2ID, + Currency = String.Empty, + CreateOn = DateTime.UtcNow, + CreateBy = SecurityContext.CurrentAccount.ID, + LastModifedOn = DateTime.Now, + LastModifedBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.Add(itemToInsert); + CRMDbContext.SaveChanges(); + + invoiceItem.ID = itemToInsert.Id; + + + } else { - var oldInvoiceItem = Db.ExecuteList(GetInvoiceItemSqlQuery(Exp.Eq("id", invoiceItem.ID))) - .ConvertAll(ToInvoiceItem) - .FirstOrDefault(); + var itemToUpdate = Query(CRMDbContext.InvoiceItem).Single(x => x.Id == invoiceItem.ID); + var oldInvoiceItem = ToInvoiceItem(itemToUpdate); CRMSecurity.DemandEdit(oldInvoiceItem); - Db.ExecuteNonQuery( - Update("crm_invoice_item") - .Set("title", invoiceItem.Title) - .Set("description", invoiceItem.Description) - .Set("stock_keeping_unit", invoiceItem.StockKeepingUnit) - .Set("price", invoiceItem.Price) - .Set("stock_quantity", invoiceItem.StockQuantity) - .Set("track_inventory", invoiceItem.TrackInventory) - .Set("invoice_tax1_id", invoiceItem.InvoiceTax1ID) - .Set("invoice_tax2_id", invoiceItem.InvoiceTax2ID) - .Set("currency", String.Empty) - .Set("last_modifed_on", DateTime.UtcNow) - .Set("last_modifed_by", SecurityContext.CurrentAccount.ID) - .Where(Exp.Eq("id", invoiceItem.ID))); - - invoiceItem.LastModifedOn = DateTime.UtcNow; - invoiceItem.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.Title = invoiceItem.Title; + itemToUpdate.Description = invoiceItem.Description; + itemToUpdate.StockKeepingUnit = invoiceItem.StockKeepingUnit; + itemToUpdate.Price = invoiceItem.Price; + itemToUpdate.StockQuantity = invoiceItem.StockQuantity; + itemToUpdate.TrackInventory = invoiceItem.TrackInventory; + itemToUpdate.InvoiceTax1Id = invoiceItem.InvoiceTax1ID; + itemToUpdate.InvoiceTax2Id = invoiceItem.InvoiceTax2ID; + + itemToUpdate.Currency = invoiceItem.Currency; + itemToUpdate.LastModifedOn = invoiceItem.LastModifedOn; + itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + + CRMDbContext.Add(itemToUpdate); + CRMDbContext.SaveChanges(); + + } return invoiceItem; @@ -398,16 +401,18 @@ public virtual List DeleteBatchInvoiceItems(int[] invoiceItemIDs) private void DeleteBatchItemsExecute(List items) { CRMDbContext.RemoveRange(items.ConvertAll(x => new DbInvoiceItem - { - Id = x.ID, - TenantId = TenantID - })); + { + Id = x.ID, + TenantId = TenantID + })); CRMDbContext.SaveChanges(); } private InvoiceItem ToInvoiceItem(DbInvoiceItem dbInvoiceItem) { + if (dbInvoiceItem == null) return null; + var result = new InvoiceItem { ID = dbInvoiceItem.Id, @@ -432,47 +437,21 @@ private InvoiceItem ToInvoiceItem(DbInvoiceItem dbInvoiceItem) } - //private SqlQuery GetInvoiceItemSqlQuery(Exp where) - //{ - // var sqlQuery = Query("crm_invoice_item") - // .Select( - // "id", - // "title", - // "description", - // "stock_keeping_unit", - // "price", - // "stock_quantity", - // "track_inventory", - // "invoice_tax1_id", - // "invoice_tax2_id", - // "currency", - // "create_on", - // "create_by", - // "last_modifed_on", - // "last_modifed_by"); - - // if (where != null) - // { - // sqlQuery.Where(where); - // } - - // return sqlQuery; - //} - - private Exp WhereConditional( + private IQueryable GetDbInvoiceItemByFilters( ICollection exceptIDs, String searchText, int status, bool? inventoryStock) { - var conditions = new List(); - //if (status != null) + var sqlQuery = Query(CRMDbContext.InvoiceItem); + + //if (status > 0) //{ + // sqlQuery = sqlQuery.Where(x => x.); // conditions.Add(Exp.Eq("status", (int)status.Value)); //} - if (!String.IsNullOrEmpty(searchText)) { searchText = searchText.Trim(); @@ -481,33 +460,29 @@ private Exp WhereConditional( .ToArray(); if (keywords.Length > 0) - //if (FullTextSearch.SupportModule(FullTextSearch.CRMInvoiceItemModule)) - //{ - // ids = FullTextSearch.Search(searchText, FullTextSearch.CRMInvoiceItemModule) - // .GetIdentifiers() - // .Select(item => Convert.ToInt32(item.Split('_')[1])).Distinct().ToList(); - - // if (ids.Count == 0) return null; - //} - //else - conditions.Add(BuildLike(new[] { "title", "description", "stock_keeping_unit" }, keywords)); + { + foreach (var k in keywords) + { + sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%") || + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.StockKeepingUnit, k + "%") + ); + } + } } if (exceptIDs.Count > 0) { - conditions.Add(!Exp.In("id", exceptIDs.ToArray())); + sqlQuery = sqlQuery.Where(x => !exceptIDs.Contains(x.Id)); } if (inventoryStock.HasValue) { - conditions.Add(Exp.Eq("track_inventory", inventoryStock.Value)); + sqlQuery = sqlQuery.Where(x => x.TrackInventory == inventoryStock.Value); } - if (conditions.Count == 0) return null; - - return conditions.Count == 1 ? conditions[0] : conditions.Aggregate((i, j) => i & j); + return sqlQuery; } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 55b2b92fbaf..7a42196aaad 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -25,10 +25,13 @@ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -40,15 +43,17 @@ namespace ASC.CRM.Core.Dao { public class CachedInvoiceLineDao : InvoiceLineDao { - private readonly HttpRequestDictionary _invoiceLineCache = new HttpRequestDictionary("crm_invoice_line"); + private readonly HttpRequestDictionary _invoiceLineCache; public CachedInvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + IHttpContextAccessor httpContextAccessor) : base(dbContextManager, tenantManager, securityContext) { + _invoiceLineCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_line"); } public override InvoiceLine GetByID(int invoiceLineID) @@ -86,10 +91,12 @@ public class InvoiceLineDao : AbstractDao { public InvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext) + SecurityContext securityContext, + IOptionsMonitor logger) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 928f798b5c4..2ad81350b15 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -25,12 +25,14 @@ using ASC.Collections; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Tenants; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Globalization; @@ -91,11 +93,13 @@ public class InvoiceTaxDao : AbstractDao public InvoiceTaxDao( DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext + SecurityContext securityContext, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { } diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 930895e2301..ce6bba9d600 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -26,22 +26,26 @@ #region Import -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using ASC.Common.Data.Sql.Expressions; +using ASC.Common.Logging; using ASC.Core; +using ASC.Core.Common.EF; +using ASC.Core.Common.Settings; using ASC.Core.Tenants; -using ASC.Data.Storage.S3; -using ASC.VoipService; -using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Resources; +using ASC.CRM.Classes; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; -using ASC.Web.Files.Api; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using ASC.VoipService; +using ASC.Web.CRM.Classes; +using ASC.Web.Files.Api; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; #endregion @@ -53,22 +57,49 @@ public class ReportDao : AbstractDao const string TimeFormat = "[h]:mm:ss;@"; const string ShortDateFormat = "M/d/yyyy"; - private DaoFactory DaoFactory {get; set; } + private DaoFactory DaoFactory { get; set; } #region Constructor - public ReportDao(int tenantID, DaoFactory daoFactory) - : base(tenantID) + public ReportDao(DbContextManager dbContextManager, + TenantManager tenantManager, + SecurityContext securityContext, + FilesIntegration filesIntegration, + IOptionsMonitor logger, + TenantUtil tenantUtil, + SettingsManager settingsManager, + Global global, + UserManager userManager) : + base(dbContextManager, + tenantManager, + securityContext, + logger) { - this.DaoFactory = daoFactory; + TenantUtil = tenantUtil; + + FilesIntegration = filesIntegration; + CRMSettings = settingsManager.Load(); + Global = global; + UserManager = userManager; + TenantManager = tenantManager; } + #endregion + public TenantManager TenantManager { get; } + + public UserManager UserManager { get; } + public Global Global { get; } + public FilesIntegration FilesIntegration { get; } + + public CRMSettings CRMSettings { get; } + + public TenantUtil TenantUtil { get; } #region Common Methods - private static void GetTimePeriod(ReportTimePeriod timePeriod, out DateTime fromDate, out DateTime toDate) + private void GetTimePeriod(ReportTimePeriod timePeriod, out DateTime fromDate, out DateTime toDate) { var now = TenantUtil.DateTimeNow().Date; @@ -167,7 +198,7 @@ private static void GetTimePeriod(ReportTimePeriod timePeriod, out DateTime from } } - private static string GetTimePeriodText(ReportTimePeriod timePeriod) + private string GetTimePeriodText(ReportTimePeriod timePeriod) { DateTime fromDate; DateTime toDate; @@ -205,17 +236,16 @@ private static string GetTimePeriodText(ReportTimePeriod timePeriod) public List GetMissingRates(string defaultCurrency) { - var existingRatesQuery = Query("crm_currency_rate r") - .Select("distinct r.from_currency") - .Where("r.to_currency", defaultCurrency); + var existingRatesQuery = CRMDbContext.CurrencyRate + .Where(x => x.ToCurrency == defaultCurrency) + .Select(x => x.FromCurrency).Distinct().ToList(); - var missingRatesQuery = Query("crm_deal d") - .Select("distinct d.bid_currency") - .Where(!Exp.Eq("d.bid_currency", defaultCurrency)) - .Where(!Exp.In("d.bid_currency", existingRatesQuery)); + var missingRatesQuery = Query(CRMDbContext.Deals) + .Where(x => x.BidCurrency != defaultCurrency && !existingRatesQuery.Contains(x.BidCurrency)) + .Select(x => x.BidCurrency) + .Distinct(); - - return Db.ExecuteList(missingRatesQuery).ConvertAll(row => row[0].ToString()); + return missingRatesQuery.ToList(); } #endregion @@ -223,16 +253,16 @@ public List GetMissingRates(string defaultCurrency) #region Report Files - public List SaveSampleReportFiles() + public List> SaveSampleReportFiles() { - var result = new List(); + var result = new List>(); var storeTemplate = Global.GetStoreTemplate(); if (storeTemplate == null) return result; - var culture = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture() ?? - CoreContext.TenantManager.GetCurrentTenant().GetCulture(); + var culture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture() ?? + TenantManager.GetCurrentTenant().GetCulture(); var path = culture + "/"; @@ -246,16 +276,16 @@ public List GetMissingRates(string defaultCurrency) { using (var stream = storeTemplate.GetReadStream("", filePath)) { - var document = new Files.Core.File - { - Title = Path.GetFileName(filePath), - FolderID = DaoFactory.FileDao.GetRoot(), - ContentLength = stream.Length - }; + var document = new Files.Core.File + { + Title = Path.GetFileName(filePath), + FolderID = DaoFactory.FileDao.GetRoot(), + ContentLength = stream.Length + }; var file = DaoFactory.FileDao.SaveFile(document, stream); - SaveFile((int) file.ID, -1); + SaveFile((int)file.ID, -1); result.Add(file); } @@ -264,91 +294,87 @@ public List GetMissingRates(string defaultCurrency) return result; } - public List GetFiles() + public List> GetFiles() { return GetFiles(SecurityContext.CurrentAccount.ID); } - public List GetFiles(Guid userId) + public List> GetFiles(Guid userId) { - var query = Query("crm_report_file") - .Select("file_id") - .Where("create_by", userId); + var filedao = FilesIntegration.DaoFactory.GetFileDao(); + + var fileIds = Query(CRMDbContext.ReportFile).Where(x => x.CreateBy == userId).Select(x => x.FileId).ToArray(); + + return fileIds.Length > 0 ? filedao.GetFiles(fileIds) : new List>(); - using (var filedao = FilesIntegration.GetFileDao()) - { - var fileIds = Db.ExecuteList(query).ConvertAll(row => row[0]).ToArray(); - return fileIds.Length > 0 ? filedao.GetFiles(fileIds) : new List(); - } } public List GetFileIds(Guid userId) { - var query = Query("crm_report_file") - .Select("file_id") - .Where("create_by", userId); - - return Db.ExecuteList(query).ConvertAll(row => Convert.ToInt32(row[0])); + return Query(CRMDbContext.ReportFile) + .Where(x => x.CreateBy == userId).Select(x => x.FileId).ToList(); } - public Files.Core.File GetFile(int fileid) + public Files.Core.File GetFile(int fileid) { return GetFile(fileid, SecurityContext.CurrentAccount.ID); } - public Files.Core.File GetFile(int fileid, Guid userId) + public Files.Core.File GetFile(int fileid, Guid userId) { - var query = Query("crm_report_file") - .SelectCount() - .Where("file_id", fileid) - .Where("create_by", userId); + var exist = Query(CRMDbContext.ReportFile) + .Any(x => x.CreateBy == userId && x.FileId == fileid); + + var filedao = FilesIntegration.DaoFactory.GetFileDao(); + + return exist ? filedao.GetFile(fileid) : null; - using (var filedao = FilesIntegration.GetFileDao()) - { - return Db.ExecuteScalar(query) > 0 ? filedao.GetFile(fileid) : null; - } } public void DeleteFile(int fileid) { - var query = Delete("crm_report_file") - .Where("file_id", fileid) - .Where("create_by", SecurityContext.CurrentAccount.ID); + var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.FileId == fileid && x.CreateBy == SecurityContext.CurrentAccount.ID); - using (var filedao = FilesIntegration.GetFileDao()) - { - Db.ExecuteNonQuery(query); - filedao.DeleteFile(fileid); - } + CRMDbContext.Remove(itemToDelete); + CRMDbContext.SaveChanges(); + + var filedao = FilesIntegration.DaoFactory.GetFileDao(); + + filedao.DeleteFile(fileid); } public void DeleteFiles(Guid userId) { var fileIds = GetFileIds(userId); - var query = Delete("crm_report_file") - .Where("create_by", userId); + var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.CreateBy == SecurityContext.CurrentAccount.ID); - using (var filedao = FilesIntegration.GetFileDao()) - { - Db.ExecuteNonQuery(query); + CRMDbContext.Remove(itemToDelete); + CRMDbContext.SaveChanges(); - foreach (var fileId in fileIds) - { - filedao.DeleteFile(fileId); - } + var filedao = FilesIntegration.DaoFactory.GetFileDao(); + + foreach (var fileId in fileIds) + { + filedao.DeleteFile(fileId); } + } - public void SaveFile(int fileId, int reportType) + public void SaveFile(int fileId, ReportType reportType) { - Db.ExecuteScalar( - Insert("crm_report_file") - .InColumnValue("file_id", fileId) - .InColumnValue("report_type", reportType) - .InColumnValue("create_on", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) - .InColumnValue("create_by", SecurityContext.CurrentAccount.ID) - .Identity(1, 0, true)); + + var itemToInsert = new DbReportFile + { + FileId = fileId, + ReportType = reportType, + CreateOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + CreateBy = SecurityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CRMDbContext.Add(itemToInsert); + CRMDbContext.SaveChanges(); } #endregion @@ -363,15 +389,15 @@ public bool CheckSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] m GetTimePeriod(timePeriod, out fromDate, out toDate); - var sqlQuery = Query("crm_deal d") - .Select("d.id") - .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) - .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); - return Db.ExecuteList(sqlQuery).Any(); + return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => x.y.Status == DealMilestoneStatus.ClosedAndWon) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); } public object GetSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) @@ -389,7 +415,7 @@ private List BuildSalesByManagersReport(ReportTimePeriod timePer GetTimePeriod(timePeriod, out fromDate, out toDate); string dateSelector; - + switch (timePeriod) { case ReportTimePeriod.Today: @@ -425,7 +451,7 @@ when 0 then .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) - .Where("m.status", (int) DealMilestoneStatus.ClosedAndWon) + .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) .GroupBy("responsible_id", "close_date"); @@ -434,7 +460,7 @@ when 0 then return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesByManagers); } - private static SalesByManager ToSalesByManagers(object[] row) + private SalesByManager ToSalesByManagers(object[] row) { return new SalesByManager { @@ -445,7 +471,7 @@ private static SalesByManager ToSalesByManagers(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + private object GenerateReportData(ReportTimePeriod timePeriod, List data) { switch (timePeriod) { @@ -467,7 +493,7 @@ private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + private object GenerateReportDataByHours(ReportTimePeriod timePeriod, List data) { DateTime fromDate; DateTime toDate; @@ -490,7 +516,7 @@ private static object GenerateReportDataByHours(ReportTimePeriod timePeriod, Lis } else { - res.Add(userId, new Dictionary {{date, 0}}); + res.Add(userId, new Dictionary { { date, 0 } }); } date = date.AddHours(1); @@ -528,31 +554,31 @@ private static object GenerateReportDataByHours(ReportTimePeriod timePeriod, Lis foreach (var key in res.First().Value.Keys) { - head.Add(new {format = "H:mm", value = key.ToShortTimeString()}); + head.Add(new { format = "H:mm", value = key.ToShortTimeString() }); } return new + { + resource = new { - resource = new - { - manager = CRMReportResource.Manager, - summary = CRMReportResource.Sum, - total = CRMReportResource.Total, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - sheetName = CRMReportResource.SalesByManagersReport, - header = CRMReportResource.SalesByManagersReport, - header1 = CRMReportResource.SalesByHour + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - header2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.SalesByHour + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol - }, - thead = head, - tbody = body - }; + manager = CRMReportResource.Manager, + summary = CRMReportResource.Sum, + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesByManagersReport, + header = CRMReportResource.SalesByManagersReport, + header1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol + }, + thead = head, + tbody = body + }; } - private static object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) + private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) { DateTime fromDate; DateTime toDate; @@ -629,17 +655,17 @@ private static object GenerateReportDataByDays(ReportTimePeriod timePeriod, List dateRangeValue = GetTimePeriodText(timePeriod), sheetName = CRMReportResource.SalesByManagersReport, header = CRMReportResource.SalesByManagersReport, - header1 = CRMReportResource.SalesByDay + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - header2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.SalesByDay + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName2 = CRMReportResource.TotalSalesByManagers + ", " + Global.TenantSettings.DefaultCurrency.Symbol + header1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol }, thead = head, tbody = body }; } - private static object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) + private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) { DateTime fromDate; DateTime toDate; @@ -714,10 +740,10 @@ private static object GenerateReportByMonths(ReportTimePeriod timePeriod, List x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => x.y.Status == DealMilestoneStatus.Open) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); } public object GetSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) @@ -759,7 +784,7 @@ private List BuildSalesForecastReport(ReportTimePeriod timePeriod DateTime fromDate; DateTime toDate; - GetTimePeriod(timePeriod, out fromDate, out toDate); + GetTimePeriod(timePeriod, out fromDate, out toDate); string dateSelector; @@ -805,7 +830,7 @@ when 0 then return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesForecast); } - private static SalesForecast ToSalesForecast(object[] row) + private SalesForecast ToSalesForecast(object[] row) { return new SalesForecast { @@ -815,7 +840,7 @@ private static SalesForecast ToSalesForecast(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + private object GenerateReportData(ReportTimePeriod timePeriod, List data) { switch (timePeriod) { @@ -834,7 +859,7 @@ private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) { DateTime fromDate; DateTime toDate; @@ -860,7 +885,7 @@ private static object GenerateReportDataByDays(ReportTimePeriod timePeriod, List if (key > res.Last().Key) key = res.Last().Key; - + res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, res[key].Item2 + item.Value); } @@ -889,23 +914,23 @@ private static object GenerateReportDataByDays(ReportTimePeriod timePeriod, List }; return new + { + resource = new { - resource = new - { - total = CRMReportResource.Total, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - sheetName = CRMReportResource.SalesForecastReport, - header = CRMReportResource.SalesForecastReport, - header1 = CRMReportResource.SalesForecastReport + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName = CRMReportResource.SalesForecastReport + ", " + Global.TenantSettings.DefaultCurrency.Symbol - }, - thead = head, - tbody = body - }; + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesForecastReport, + header = CRMReportResource.SalesForecastReport, + header1 = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol + }, + thead = head, + tbody = body + }; } - private static object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) + private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) { DateTime fromDate; DateTime toDate; @@ -958,20 +983,20 @@ private static object GenerateReportByMonths(ReportTimePeriod timePeriod, List managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); } public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) @@ -1033,7 +1055,7 @@ when 0 then return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesFunnel); } - private static SalesFunnel ToSalesFunnel(object[] row) + private SalesFunnel ToSalesFunnel(object[] row) { return new SalesFunnel { @@ -1045,8 +1067,8 @@ private static SalesFunnel ToSalesFunnel(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, List data) - { + private object GenerateReportData(ReportTimePeriod timePeriod, List data) + { var totalCount = data.Sum(x => x.Count); if (totalCount == 0) return null; @@ -1054,7 +1076,7 @@ private static object GenerateReportData(ReportTimePeriod timePeriod, List x.Value); var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); - + var reportData = data.Select(item => new List { item.Title, @@ -1064,46 +1086,46 @@ private static object GenerateReportData(ReportTimePeriod timePeriod, List x.Duration)/closed.Count, - - header1 = CRMReportResource.ByCount, - header2 = CRMReportResource.ByBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - - stage = CRMReportResource.Stage, - count = CRMReportResource.Count, - budget = CRMReportResource.Budget, - conversion = CRMReportResource.Conversion, - - deals = CRMDealResource.Deals, - status0 = DealMilestoneStatus.Open.ToLocalizedString(), - status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), - status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() - }, - data = reportData - }; + header = CRMReportResource.SalesFunnelReport, + sheetName = CRMReportResource.SalesFunnelReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.SalesFunnelByCount, + chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.DealsCount, + chartName3 = CRMReportResource.DealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + + totalCountLabel = CRMReportResource.TotalDealsCount, + totalCountValue = totalCount, + + totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + totalBudgetValue = totalBudget, + + averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + averageBidValue = totalBudget / totalCount, + + averageDurationLabel = CRMReportResource.AverageDealsDuration, + averageDurationValue = closed.Sum(x => x.Duration) / closed.Count, + + header1 = CRMReportResource.ByCount, + header2 = CRMReportResource.ByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + + stage = CRMReportResource.Stage, + count = CRMReportResource.Count, + budget = CRMReportResource.Budget, + conversion = CRMReportResource.Conversion, + + deals = CRMDealResource.Deals, + status0 = DealMilestoneStatus.Open.ToLocalizedString(), + status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), + status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() + }, + data = reportData + }; } #endregion @@ -1118,14 +1140,10 @@ public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[ GetTimePeriod(timePeriod, out fromDate, out toDate); - var sqlQuery = Query("crm_contact c") - .Select("c.id") - .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); - - return Db.ExecuteList(sqlQuery).Any(); - + return Query(CRMDbContext.Contacts) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); } public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) @@ -1142,6 +1160,18 @@ private List BuildWorkloadByContactsReport(ReportTimePeriod GetTimePeriod(timePeriod, out fromDate, out toDate); + var sqlQuery = Query(CRMDbContext.Contacts) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.ContactTypeId, + y => y.Id, + (x, y) => new { x, y }) + .GroupJoin(Query(CRMDbContext.Deals), + x => x.x.Id, + y=> y.Id, + (x,y) => new { x, y }) + + + var sqlQuery = Query("crm_contact c") .Select("c.create_by", "concat(u.firstname, ' ', u.lastname) as full_name", @@ -1160,7 +1190,7 @@ private List BuildWorkloadByContactsReport(ReportTimePeriod return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByContacts); } - private static WorkloadByContacts ToWorkloadByContacts(object[] row) + private WorkloadByContacts ToWorkloadByContacts(object[] row) { return new WorkloadByContacts { @@ -1173,7 +1203,7 @@ private static WorkloadByContacts ToWorkloadByContacts(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) { return new { @@ -1186,7 +1216,7 @@ private static object GenerateReportData(ReportTimePeriod timePeriod, List t.deadline")))) - .SetMaxResults(1); + var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); - bool res; + var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.IsClosed) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); - using (var tx = Db.BeginTransaction()) - { - res = Db.ExecuteList(sqlNewTasksQuery).Any() || - Db.ExecuteList(sqlClosedTasksQuery).Any() || - Db.ExecuteList(sqlOverdueTasksQuery).Any(); - tx.Commit(); - } - return res; + var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.IsClosed) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) + .Where(x => (!x.IsClosed && x.Deadline < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || + (x.IsClosed && x.LastModifedOn > x.Deadline)) + .Any(); + + return sqlNewTasksQuery || + sqlClosedTasksQuery || + sqlOverdueTasksQuery; } public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) @@ -1320,7 +1342,7 @@ private Dictionary> BuildWorkloadByTasksReport(Rep return res; } - private static WorkloadByTasks ToWorkloadByTasks(object[] row) + private WorkloadByTasks ToWorkloadByTasks(object[] row) { return new WorkloadByTasks { @@ -1332,7 +1354,7 @@ private static WorkloadByTasks ToWorkloadByTasks(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) + private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) { return new { @@ -1366,16 +1388,11 @@ public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] m GetTimePeriod(timePeriod, out fromDate, out toDate); - var sqlQuery = Query("crm_deal d") - .Select("d.id") - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - Exp.Empty : - Exp.Or(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), - Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) - .SetMaxResults(1); - - return Db.ExecuteList(sqlQuery).Any(); + return Query(CRMDbContext.Deals) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) || + (x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate))) + .Any(); } public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) @@ -1417,7 +1434,7 @@ when 0 then return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByDeals); } - private static WorkloadByDeals ToWorkloadByDeals(object[] row) + private WorkloadByDeals ToWorkloadByDeals(object[] row) { return new WorkloadByDeals { @@ -1429,7 +1446,7 @@ private static WorkloadByDeals ToWorkloadByDeals(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + private object GenerateReportData(ReportTimePeriod timePeriod, List data) { var reportData = data.Select(item => new List { @@ -1450,10 +1467,10 @@ private static object GenerateReportData(ReportTimePeriod timePeriod, List i.due_date")); - - var sqlQuery = Query("crm_invoice i") - .Select("i.id") - .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - .Where(Exp.Or(Exp.Or(sent, paid), Exp.Or(rejected, overdue))) - .SetMaxResults(1); - - return Db.ExecuteList(sqlQuery).Any(); + return Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= TenantUtil.DateTimeToUtc(toDate))) || + (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || + (x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || + ((timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= TenantUtil.DateTimeToUtc(toDate))) && + (x.Status == InvoiceStatus.Sent && x.DueDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()) || x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) + .Any(); } public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) @@ -1529,7 +1542,7 @@ private List BuildWorkloadByInvoicesReport(ReportTimePeriod return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByInvoices); } - private static WorkloadByInvoices ToWorkloadByInvoices(object[] row) + private WorkloadByInvoices ToWorkloadByInvoices(object[] row) { return new WorkloadByInvoices { @@ -1542,7 +1555,7 @@ private static WorkloadByInvoices ToWorkloadByInvoices(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) { return new { @@ -1582,16 +1595,13 @@ public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] ma GetTimePeriod(timePeriod, out fromDate, out toDate); - var sqlQuery = Query("crm_voip_calls c") - .Select("c.id") - .Where(Exp.EqColumns("c.parent_call_id", "''")) - .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - Exp.Empty : - Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); - - return Db.ExecuteList(sqlQuery).Any(); + return Query(CRMDbContext.VoipCalls) + .Where(x => x.ParentCallId == "") + .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? + true : + x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); } public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) @@ -1626,7 +1636,7 @@ private List BuildWorkloadByViopReport(ReportTimePeriod timePeri return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByViop); } - private static WorkloadByViop ToWorkloadByViop(object[] row) + private WorkloadByViop ToWorkloadByViop(object[] row) { return new WorkloadByViop { @@ -1638,7 +1648,7 @@ private static WorkloadByViop ToWorkloadByViop(object[] row) }; } - private static object GenerateReportData(ReportTimePeriod timePeriod, List data) + private object GenerateReportData(ReportTimePeriod timePeriod, List data) { var reportData = data.Select(item => new List { @@ -1648,7 +1658,7 @@ private static object GenerateReportData(ReportTimePeriod timePeriod, List d.expected_close_date")))); - - var invoicesSqlQuery = Query("crm_invoice i") - .Select("i.id") - .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - .Where(Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); - - var contactsSqlQuery = Query("crm_contact c") - .Select("c.id") - .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - .Where(Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); - - var tasksSqlQuery = Query("crm_task t") - .Select("t.id") - .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); - - var voipSqlQuery = Query("crm_voip_calls c") - .Select("c.id") - .Where(Exp.EqColumns("c.parent_call_id", "''")) - .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) - .Where(Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("c.status"); - - bool res; - - using (var tx = Db.BeginTransaction()) - { - res = Db.ExecuteList(newDealsSqlQuery).Any() || - Db.ExecuteList(closedDealsSqlQuery).Any() || - Db.ExecuteList(overdueDealsSqlQuery).Any() || - Db.ExecuteList(invoicesSqlQuery).Any() || - Db.ExecuteList(contactsSqlQuery).Any() || - Db.ExecuteList(tasksSqlQuery).Any() || - Db.ExecuteList(voipSqlQuery).Any(); - - tx.Commit(); - } - - return res; + var newDealsSqlQuery = Query(CRMDbContext.Deals) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); + + var closedDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.DealMilestones), + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.y.Status != DealMilestoneStatus.Open) + .Any(); + + var overdueDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.DealMilestones), + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + .Where(x => (x.y.Status == DealMilestoneStatus.Open && x.x.ExpectedCloseDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || + (x.y.Status == DealMilestoneStatus.ClosedAndWon && x.x.ActualCloseDate > x.x.ExpectedCloseDate)) + .Any(); + + var invoicesSqlQuery = Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); + + var contactsSqlQuery = Query(CRMDbContext.Contacts) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); + + + var tasksSqlQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); + + + var voipSqlQuery = Query(CRMDbContext.VoipCalls) + .Where(x => x.ParentCallId == "") + .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) + .Where(x => x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); + + return newDealsSqlQuery || + closedDealsSqlQuery || + overdueDealsSqlQuery || + invoicesSqlQuery || + contactsSqlQuery || + tasksSqlQuery || + voipSqlQuery; } public object GetSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) @@ -1815,7 +1812,7 @@ when 0 then Exp.EqColumns("m.id", "d.deal_milestone_id")) .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int) DealMilestoneStatus.ClosedAndWon); + .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon); var lostDealsSqlQuery = Query("crm_deal d") .Select("count(d.id) as count", @@ -1833,7 +1830,7 @@ when 0 then Exp.EqColumns("m.id", "d.deal_milestone_id")) .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int) DealMilestoneStatus.ClosedAndLost); + .Where("m.status", (int)DealMilestoneStatus.ClosedAndLost); var overdueDealsSqlQuery = Query("crm_deal d") .Select("count(d.id) as count", @@ -1854,13 +1851,13 @@ when 0 then Exp.And( Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), Exp.Or(Exp.Eq("m.status", (int)DealMilestoneStatus.Open) & Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), - Exp.Eq("m.status", (int) DealMilestoneStatus.ClosedAndWon) & Exp.Sql("d.actual_close_date > d.expected_close_date")))); + Exp.Eq("m.status", (int)DealMilestoneStatus.ClosedAndWon) & Exp.Sql("d.actual_close_date > d.expected_close_date")))); var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft), 1, 0)); var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid), 1, 0)); var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected), 1, 0)); var overdue = Exp.Sum(Exp.If(Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), - Exp.Eq("i.status", (int) InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); + Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); var invoicesSqlQuery = Query("crm_invoice i") .Select(sent) @@ -1876,7 +1873,7 @@ when 0 then "count(c.id)") .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & - Exp.Eq("i.list_type", (int) ListType.ContactType)) + Exp.Eq("i.list_type", (int)ListType.ContactType)) .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) .Where(Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) .GroupBy("i.id") @@ -1907,19 +1904,19 @@ when 0 then using (var tx = Db.BeginTransaction()) { res = new + { + DealsInfo = new { - DealsInfo = new - { - Created = Db.ExecuteList(newDealsSqlQuery), - Won = Db.ExecuteList(wonDealsSqlQuery), - Lost = Db.ExecuteList(lostDealsSqlQuery), - Overdue = Db.ExecuteList(overdueDealsSqlQuery), - }, - InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), - ContactsInfo = Db.ExecuteList(contactsSqlQuery), - TasksInfo = Db.ExecuteList(tasksSqlQuery), - VoipInfo = Db.ExecuteList(voipSqlQuery) - }; + Created = Db.ExecuteList(newDealsSqlQuery), + Won = Db.ExecuteList(wonDealsSqlQuery), + Lost = Db.ExecuteList(lostDealsSqlQuery), + Overdue = Db.ExecuteList(overdueDealsSqlQuery), + }, + InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), + ContactsInfo = Db.ExecuteList(contactsSqlQuery), + TasksInfo = Db.ExecuteList(tasksSqlQuery), + VoipInfo = Db.ExecuteList(voipSqlQuery) + }; tx.Commit(); } @@ -1927,7 +1924,7 @@ when 0 then return res; } - private static object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) + private object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) { return new { @@ -1937,11 +1934,11 @@ private static object GenerateSummaryForThePeriodReportData(ReportTimePeriod tim sheetName = CRMReportResource.SummaryForThePeriodReport, dateRangeLabel = CRMReportResource.TimePeriod + ":", dateRangeValue = GetTimePeriodText(timePeriod), - chartName = CRMReportResource.DealsByBudget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName1=CRMReportResource.DealsByCount, - chartName2=CRMReportResource.ContactsByType, - chartName3=CRMReportResource.TasksForThePeriod, - chartName4=CRMReportResource.InvoicesForThePeriod, + chartName = CRMReportResource.DealsByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.DealsByCount, + chartName2 = CRMReportResource.ContactsByType, + chartName3 = CRMReportResource.TasksForThePeriod, + chartName4 = CRMReportResource.InvoicesForThePeriod, chartName5 = CRMReportResource.CallsForThePeriod, header1 = CRMDealResource.Deals, header2 = CRMContactResource.Contacts, @@ -1949,7 +1946,7 @@ private static object GenerateSummaryForThePeriodReportData(ReportTimePeriod tim header4 = CRMInvoiceResource.Invoices, header5 = CRMReportResource.Calls, byBudget = CRMReportResource.ByBudget, - currency = Global.TenantSettings.DefaultCurrency.Symbol, + currency = CRMSettings.DefaultCurrency.Symbol, byCount = CRMReportResource.ByCount, item = CRMReportResource.Item, type = CRMReportResource.Type, @@ -1987,47 +1984,37 @@ public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid GetTimePeriod(timePeriod, out fromDate, out toDate); - var dealsSqlQuery = Query("crm_deal d") - .Select("d.id") - .LeftOuterJoin("crm_deal_milestone m", - Exp.EqColumns("m.tenant_id", "d.tenant_id") & - Exp.EqColumns("m.id", "d.deal_milestone_id")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int)DealMilestoneStatus.Open) - .SetMaxResults(1); - - var contactsSqlQuery = Query("crm_contact c") - .Select("c.id") - .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); + var dealsSqlQuery = Query(CRMDbContext.Deals) + .Join(CRMDbContext.DealMilestones, + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.y.Status == DealMilestoneStatus.Open) + .Any(); - var tasksSqlQuery = Query("crm_task t") - .Select("t.id") - .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); - var invoicesSqlQuery = Query("crm_invoice i") - .Select("i.id") - .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .SetMaxResults(1); + var contactsSqlQuery = Query(CRMDbContext.Contacts) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); - bool res; + var tasksSqlQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); - using (var tx = Db.BeginTransaction()) - { - res = Db.ExecuteList(dealsSqlQuery).Any() || - Db.ExecuteList(contactsSqlQuery).Any() || - Db.ExecuteList(tasksSqlQuery).Any() || - Db.ExecuteList(invoicesSqlQuery).Any(); + var invoicesSqlQuery = Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + .Any(); - tx.Commit(); - } + return dealsSqlQuery || + contactsSqlQuery || + tasksSqlQuery || + invoicesSqlQuery; - return res; } public object GetSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) @@ -2125,7 +2112,7 @@ when 0 then "count(c.id) as count") .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & - Exp.Eq("i.list_type", (int) ListType.ContactType)) + Exp.Eq("i.list_type", (int)ListType.ContactType)) .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) .GroupBy("i.id") @@ -2166,22 +2153,22 @@ when 0 then using (var tx = Db.BeginTransaction()) { res = new + { + DealsInfo = new { - DealsInfo = new - { - Open = Db.ExecuteList(openDealsSqlQuery), - Overdue = Db.ExecuteList(overdueDealsSqlQuery), - Near = Db.ExecuteList(nearDealsSqlQuery), - ByStage = Db.ExecuteList(dealsByStageSqlQuery) - }, - ContactsInfo = new - { - ByType = Db.ExecuteList(contactsByTypeSqlQuery), - ByStage = Db.ExecuteList(contactsByStageSqlQuery) - }, - TasksInfo = Db.ExecuteList(tasksSqlQuery), - InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), - }; + Open = Db.ExecuteList(openDealsSqlQuery), + Overdue = Db.ExecuteList(overdueDealsSqlQuery), + Near = Db.ExecuteList(nearDealsSqlQuery), + ByStage = Db.ExecuteList(dealsByStageSqlQuery) + }, + ContactsInfo = new + { + ByType = Db.ExecuteList(contactsByTypeSqlQuery), + ByStage = Db.ExecuteList(contactsByStageSqlQuery) + }, + TasksInfo = Db.ExecuteList(tasksSqlQuery), + InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), + }; tx.Commit(); } @@ -2189,7 +2176,7 @@ when 0 then return res; } - private static object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) + private object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) { return new { @@ -2199,9 +2186,9 @@ private static object GenerateSummaryAtThisMomentReportData(ReportTimePeriod tim sheetName = CRMReportResource.SummaryAtThisMomentReport, dateRangeLabel = CRMReportResource.TimePeriod + ":", dateRangeValue = GetTimePeriodText(timePeriod), - chartName = CRMReportResource.DealsByStatus + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.DealsByStage + ", " + Global.TenantSettings.DefaultCurrency.Symbol, - chartName2=CRMReportResource.ContactsByType, + chartName = CRMReportResource.DealsByStatus + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName1 = CRMReportResource.DealsByStage + ", " + CRMSettings.DefaultCurrency.Symbol, + chartName2 = CRMReportResource.ContactsByType, chartName3 = CRMReportResource.ContactsByStage, chartName4 = CRMReportResource.TasksByStatus, chartName5 = CRMReportResource.InvoicesByStatus, @@ -2209,7 +2196,7 @@ private static object GenerateSummaryAtThisMomentReportData(ReportTimePeriod tim header2 = CRMContactResource.Contacts, header3 = CRMTaskResource.Tasks, header4 = CRMInvoiceResource.Invoices, - budget = CRMReportResource.Budget + ", " + Global.TenantSettings.DefaultCurrency.Symbol, + budget = CRMReportResource.Budget + ", " + CRMSettings.DefaultCurrency.Symbol, count = CRMReportResource.Count, open = CRMReportResource.Opened, overdue = CRMReportResource.Overdue, diff --git a/products/ASC.CRM/Server/Core/EF/DbDeal.cs b/products/ASC.CRM/Server/Core/EF/DbDeal.cs index 4cb8b959c45..01475a4dbec 100644 --- a/products/ASC.CRM/Server/Core/EF/DbDeal.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDeal.cs @@ -23,6 +23,7 @@ * */ +using ASC.CRM.Core.Enums; using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -64,7 +65,7 @@ public partial class DbDeal : IDbCrm public decimal BidValue { get; set; } [Column("bid_type", TypeName = "int(11)")] - public int BidType { get; set; } + public BidType BidType { get; set; } [Column("deal_milestone_id", TypeName = "int(11)")] public int DealMilestoneId { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbReportFile.cs b/products/ASC.CRM/Server/Core/EF/DbReportFile.cs index c239b0355ce..c7d60ba9861 100644 --- a/products/ASC.CRM/Server/Core/EF/DbReportFile.cs +++ b/products/ASC.CRM/Server/Core/EF/DbReportFile.cs @@ -1,4 +1,5 @@ // This file has been auto generated by EF Core Power Tools. +using ASC.CRM.Core.Enums; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -7,18 +8,22 @@ namespace ASC.CRM.Core.EF { [Table("crm_report_file")] - public partial class DbReportFile + public partial class DbReportFile : IDbCrm { [Key] [Column("file_id", TypeName = "int(11)")] public int FileId { get; set; } + [Column("report_type", TypeName = "int(11)")] - public int ReportType { get; set; } + public ReportType ReportType { get; set; } + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } + [Required] [Column("create_by", TypeName = "char(38)")] - public string CreateBy { get; set; } + public Guid CreateBy { get; set; } + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } } diff --git a/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs b/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs index 5d787568a3b..aaaafb3d389 100644 --- a/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs +++ b/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_voip_calls")] - public partial class DbVoipCalls + public partial class DbVoipCalls : IDbCrm { [Key] [Column("id", TypeName = "varchar(50)")] @@ -25,7 +25,7 @@ public partial class DbVoipCalls public int? Status { get; set; } [Required] [Column("answered_by", TypeName = "varchar(50)")] - public string AnsweredBy { get; set; } + public Guid AnsweredBy { get; set; } [Column("dial_date", TypeName = "datetime")] public DateTime? DialDate { get; set; } [Column("dial_duration", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs index 579b3160d10..aabe8c95315 100644 --- a/products/ASC.CRM/Server/Core/Entities/Invoice.cs +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -27,6 +27,7 @@ using ASC.Common.Security; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; +using ASC.Files.Core; using System; using System.Collections.Generic; @@ -96,7 +97,7 @@ public List GetInvoiceLines(DaoFactory daoFactory) return daoFactory.InvoiceLineDao.GetInvoiceLines(ID); } - public File GetInvoiceFile(DaoFactory daoFactory) + public File GetInvoiceFile(DaoFactory daoFactory) { return daoFactory.FileDao.GetFile(FileID, 0); } diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs index a5eacbb5196..922b46e7d18 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs @@ -61,7 +61,6 @@ public class InvoiceItem : DomainObject, ISecurityObjectId [DataMember(Name = "currency")] public string Currency { get; set; } - [DataMember(Name = "createOn")] public DateTime CreateOn { get; set; } diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index 10979d4436b..cbbb9a49bb5 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -49,39 +49,39 @@ public FileSecurity(FilesIntegration filesIntegration, public CRMSecurity CRMSecurity { get; } - public bool CanCreate(FileEntry entry, Guid userId) + public bool CanCreate(FileEntry entry, Guid userId) { return true; } - public bool CanComment(FileEntry entry, Guid userId) + public bool CanComment(FileEntry entry, Guid userId) { return CanEdit(entry, userId); } - public bool CanFillForms(FileEntry entry, Guid userId) + public bool CanFillForms(FileEntry entry, Guid userId) { return CanEdit(entry, userId); } - public bool CanReview(FileEntry entry, Guid userId) + public bool CanReview(FileEntry entry, Guid userId) { return CanEdit(entry, userId); } - public bool CanDelete(FileEntry entry, Guid userId) + public bool CanDelete(FileEntry entry, Guid userId) { return CanEdit(entry, userId); } - public bool CanEdit(FileEntry entry, Guid userId) + public bool CanEdit(FileEntry entry, Guid userId) { return CanRead(entry, userId) && entry.CreateBy == userId || entry.ModifiedBy == userId || CRMSecurity.IsAdministrator(userId); } - public bool CanRead(FileEntry entry, Guid userId) + public bool CanRead(FileEntry entry, Guid userId) { if (entry.FileEntryType == FileEntryType.Folder) return false; @@ -93,10 +93,11 @@ public bool CanRead(FileEntry entry, Guid userId) return CRMSecurity.CanAccessTo(invoice, userId); var reportFile = daoFactory.ReportDao.GetFile(Convert.ToInt32(entry.ID), userId); + if (reportFile != null) return true; - var tagDao = FilesIntegration.TagDao(); + var tagDao = FilesIntegration.DaoFactory.GetTagDao(); var eventIds = tagDao.GetTags(entry.ID, FileEntryType.File, TagType.System) .Where(x => x.TagName.StartsWith("RelationshipEvent_")) @@ -111,7 +112,7 @@ public bool CanRead(FileEntry entry, Guid userId) } } - public IEnumerable WhoCanRead(FileEntry entry) + public IEnumerable WhoCanRead(FileEntry entry) { throw new NotImplementedException(); } diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs index 5a7c96fb190..638f8f246d6 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs @@ -25,26 +25,44 @@ using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Resources; using ASC.MessagingSystem; -using ASC.Web.CRM.Configuration; using ASC.Web.Core; using ASC.Web.Core.Files; using ASC.Web.Core.Utility; -using ASC.Web.CRM.Resources; -using ASC.Web.Studio.Controls.FileUploader; -using ASC.Web.Studio.Core; -using System; -using System.Web; -using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Configuration; using ASC.Web.CRM.Core; +using ASC.Web.Studio.Core; using Autofac; +using Microsoft.AspNetCore.Http; +using System; namespace ASC.Web.CRM.Classes { public class ContactPhotoHandler : IFileUploadHandler { + public ContactPhotoHandler(SetupInfo setupInfo, + CRMSecurity cRMSecurity, + FileSizeComment fileSizeComment, + WebItemSecurity webItemSecurity, + MessageTarget messageTarget) + { + SetupInfo = setupInfo; + FileSizeComment = fileSizeComment; + CRMSecurity = cRMSecurity; + WebItemSecurity = webItemSecurity; + MessageTarget = messageTarget; + } + + public MessageTarget MessageTarget { get; } + public WebItemSecurity WebItemSecurity { get; } + public FileSizeComment FileSizeComment { get; } + public CRMSecurity CRMSecurity { get; } + public SetupInfo SetupInfo { get; } + public FileUploadResult ProcessUpload(HttpContext context) { if (!WebItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs index 314df286b83..e6edbbf2c16 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs @@ -26,27 +26,10 @@ #region Import +using ASC.CRM.Resources; +using ASC.Web.CRM.Classes; using System; -using System.Collections.Generic; -using System.Drawing; using System.IO; -using System.Net; -using System.Web; -using System.Linq; -using ASC.Collections; -using ASC.Common.Threading.Workers; -using ASC.Data.Storage; -using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Configuration; -using ASC.Web.Core.Utility; -using ASC.Web.Core.Utility.Skins; -using ASC.Web.Studio.Controls.FileUploader; -using ASC.Web.Studio.Core; -using ASC.Web.Studio.Utility; -using System.Drawing.Imaging; -using System.Drawing.Drawing2D; -using ASC.Web.CRM.Resources; -using ASC.Common.Logging; #endregion diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs index 0dc23385174..fc23f570641 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs @@ -35,11 +35,20 @@ using ASC.CRM.Core.Dao; using ASC.Web.CRM.Core; using Autofac; +using Microsoft.AspNetCore.Http; +using ASC.CRM.Resources; namespace ASC.Web.CRM.Classes { public class FileUploaderHandler : FileUploadHandler { + public FileUploaderHandler(SetupInfo setupInfo) + { + SetupInfo = setupInfo; + } + + public SetupInfo SetupInfo { get; } + public override FileUploadResult ProcessUpload(HttpContext context) { var fileUploadResult = new FileUploadResult(); diff --git a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs index 67088a571ce..92dff9eac51 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs @@ -24,20 +24,32 @@ */ -using ASC.Core; using ASC.CRM.Core; using ASC.Web.Core; using ASC.Web.Core.Utility; using ASC.Web.CRM.Configuration; -using ASC.Web.Studio.Controls.FileUploader; +using Microsoft.AspNetCore.Http; using System; -using System.Web; namespace ASC.Web.CRM.Classes { public class ImportFileHandler : IFileUploadHandler { + public ImportFileHandler(WebItemSecurity webItemSecurity, + CRMSecurity cRMSecurity, + Global global) + { + CRMSecurity = cRMSecurity; + WebItemSecurity = webItemSecurity; + Global = global; + + } + + public Global Global { get; } + public CRMSecurity CRMSecurity { get; } + public WebItemSecurity WebItemSecurity { get; } + public FileUploadResult ProcessUpload(HttpContext context) { if (!WebItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs index 1c55245f59e..12899880736 100644 --- a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs @@ -25,19 +25,31 @@ using ASC.CRM.Core; +using ASC.CRM.Resources; using ASC.Web.Core.Files; using ASC.Web.Core.Utility; -using ASC.Web.CRM.Resources; -using ASC.Web.Studio.Controls.FileUploader; using ASC.Web.Studio.Core; +using Microsoft.AspNetCore.Http; using System; -using System.Web; namespace ASC.Web.CRM.Classes { public class OrganisationLogoHandler : IFileUploadHandler { + public OrganisationLogoHandler(CRMSecurity cRMSecurity, + SetupInfo setupInfo, + FileSizeComment fileSizeComment) + { + CRMSecurity = cRMSecurity; + SetupInfo = setupInfo; + FileSizeComment = fileSizeComment; + } + + public FileSizeComment FileSizeComment { get; } + public SetupInfo SetupInfo { get; } + public CRMSecurity CRMSecurity { get; } + public FileUploadResult ProcessUpload(HttpContext context) { if (!CRMSecurity.IsAdmin) diff --git a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs index d6d4217f73b..3fd29cbc99c 100644 --- a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs +++ b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs @@ -24,32 +24,31 @@ */ -using System; -using System.Collections.Specialized; -using System.Text; -using System.Web; +using ASC.Core; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; -using ASC.Core; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.MessagingSystem; -using ASC.Web.CRM.Classes; -using System.Collections.Generic; -using System.Linq; -using System.Xml.Linq; -using ASC.Common.Logging; -using ASC.CRM.Core.Dao; -using ASC.Web.CRM.Services.NotifyService; -using Newtonsoft.Json.Linq; -using ASC.Web.CRM.Resources; using ASC.Web.Core; +using ASC.Web.CRM.Classes; using ASC.Web.CRM.Configuration; using ASC.Web.CRM.Core; -using ASC.Web.CRM.Core.Enums; +using ASC.Web.CRM.Services.NotifyService; using Autofac; +using Microsoft.AspNetCore.Http; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Text; +using System.Web; namespace ASC.Web.CRM.HttpHandlers { - public class WebToLeadFromHandler : IHttpHandler + public class WebToLeadFromHandler // : IHttpHandler { private HttpContext _context; diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index bd65d893a47..56e1b641c8e 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -23,10 +23,6 @@ * */ - -#region Import - -using ASC.Common.Logging; using ASC.Core; using ASC.Core.Billing; using ASC.Core.Tenants; @@ -36,13 +32,11 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Notify; -using ASC.Notify.Model; using ASC.Notify.Patterns; using ASC.Notify.Recipients; using ASC.Web.CRM.Core; using Autofac; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; using System; using System.Collections; using System.Collections.Generic; @@ -52,8 +46,6 @@ using System.Threading; using System.Web; -#endregion - namespace ASC.Web.CRM.Services.NotifyService { public class NotifyClient @@ -62,10 +54,12 @@ public NotifyClient(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; } - + public IServiceProvider ServiceProvider { get; } - - public void SendAboutCreateNewContact(List recipientID, int contactID, String contactTitle, NameValueCollection fields) + + public void SendAboutCreateNewContact(List recipientID, + int contactID, + string contactTitle, NameValueCollection fields) { if ((recipientID.Count == 0) || String.IsNullOrEmpty(contactTitle)) return; @@ -76,13 +70,12 @@ public void SendAboutCreateNewContact(List recipientID, int contactID, Str client.SendNoticeToAsync( NotifyConstants.Event_CreateNewContact, null, - recipientID.ConvertAll(item => ToRecipient(item)).ToArray(), + recipientID.ConvertAll(item => notifySource.GetRecipientsProvider().GetRecipient(item.ToString())).ToArray(), true, new TagValue(NotifyConstants.Tag_AdditionalData, fields), new TagValue(NotifyConstants.Tag_EntityTitle, contactTitle), new TagValue(NotifyConstants.Tag_EntityID, contactID) ); - } public void SendAboutSetAccess(EntityType entityType, int entityID, DaoFactory daoFactory, params Guid[] userID) @@ -98,7 +91,7 @@ public void SendAboutSetAccess(EntityType entityType, int entityID, DaoFactory d client.SendNoticeToAsync( NotifyConstants.Event_SetAccess, null, - userID.Select(item => ToRecipient(item)).ToArray(), + userID.Select(item => notifySource.GetRecipientsProvider().GetRecipient(item.ToString())).ToArray(), true, new TagValue(NotifyConstants.Tag_EntityID, baseData["id"]), new TagValue(NotifyConstants.Tag_EntityTitle, baseData["title"]), @@ -108,6 +101,9 @@ public void SendAboutSetAccess(EntityType entityType, int entityID, DaoFactory d private NameValueCollection ExtractBaseDataFrom(EntityType entityType, int entityID, DaoFactory daoFactory) { + using var scope = ServiceProvider.CreateScope(); + var pathProvider = scope.ServiceProvider.GetService(); + var result = new NameValueCollection(); String title; @@ -145,7 +141,7 @@ private NameValueCollection ExtractBaseDataFrom(EntityType entityType, int entit result.Add("title", title); result.Add("id", entityID.ToString()); - result.Add("entityRelativeURL", String.Concat(PathProvider.BaseAbsolutePath, relativeURL)); + result.Add("entityRelativeURL", String.Concat(pathProvider.BaseAbsolutePath, relativeURL)); return result; } @@ -156,9 +152,11 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable using var scope = ServiceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); - var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); - + var pathProvider = scope.ServiceProvider.GetService(); + var securityContext = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + NameValueCollection baseEntityData; if (entity.EntityID != 0) @@ -177,13 +175,13 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable if (contact is Person) baseEntityData["entityRelativeURL"] += "&type=people"; - baseEntityData["entityRelativeURL"] = String.Concat(PathProvider.BaseAbsolutePath, + baseEntityData["entityRelativeURL"] = String.Concat(pathProvider.BaseAbsolutePath, baseEntityData["entityRelativeURL"]); } client.BeginSingleRecipientEvent("send about add relationship event add"); - var interceptor = new InitiatorInterceptor(new DirectRecipient(SecurityContext.CurrentAccount.ID.ToString(), "")); + var interceptor = new InitiatorInterceptor(new DirectRecipient(securityContext.CurrentAccount.ID.ToString(), "")); client.AddInterceptor(interceptor); @@ -193,7 +191,7 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable client.SendNoticeToAsync( NotifyConstants.Event_AddRelationshipEvent, null, - userID.Select(item => ToRecipient(item)).ToArray(), + userID.Select(item => notifySource.GetRecipientsProvider().GetRecipient(item.ToString())).ToArray(), true, new TagValue(NotifyConstants.Tag_EntityTitle, baseEntityData["title"]), new TagValue(NotifyConstants.Tag_EntityID, baseEntityData["id"]), @@ -217,9 +215,14 @@ public void SendAboutExportCompleted(Guid recipientID, String fileName, String f { if (recipientID == Guid.Empty) return; - var recipient = ToRecipient(recipientID); + using var scope = ServiceProvider.CreateScope(); + var coreBaseSettings = scope.ServiceProvider.GetService(); + var notifySource = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); - client.SendNoticeToAsync(CoreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, + var recipient = notifySource.GetRecipientsProvider().GetRecipient(recipientID.ToString()); + + client.SendNoticeToAsync(coreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, null, new[] { recipient }, true, @@ -232,10 +235,16 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) { if (recipientID == Guid.Empty) return; - var recipient = ToRecipient(recipientID); + using var scope = ServiceProvider.CreateScope(); + var notifySource = scope.ServiceProvider.GetService(); + var coreBaseSettings = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + var recipient = notifySource.GetRecipientsProvider().GetRecipient(recipientID.ToString()); var entitiyListTitle = ""; var entitiyListRelativeURL = ""; + switch (entityType) { case EntityType.Contact: @@ -259,7 +268,7 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) } client.SendNoticeToAsync( - CoreBaseSettings.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, + coreBaseSettings.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, null, new[] { recipient }, true, @@ -362,11 +371,16 @@ public void SendAutoReminderAboutTask(DateTime scheduleDate) } public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal) - { - var recipient = ToRecipient(task.ResponsibleID); + { + using var scope = ServiceProvider.CreateScope(); + var notifySource = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString()); if (recipient == null) return; + var deadLineString = task.DeadLine.Hour == 0 && task.DeadLine.Minute == 0 ? task.DeadLine.ToShortDateString() : task.DeadLine.ToString(CultureInfo.InvariantCulture); @@ -425,12 +439,18 @@ public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskCo } public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Contact taskContact, Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal, Hashtable fileListInfoHashtable) - { - var recipient = ToRecipient(task.ResponsibleID); + { + using var scope = ServiceProvider.CreateScope(); + var notifySource = scope.ServiceProvider.GetService(); + var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + var tenantUtil = scope.ServiceProvider.GetService(); + + var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString()); if (recipient == null) return; - task.DeadLine = TenantUtil.DateTimeFromUtc(task.DeadLine); + task.DeadLine = tenantUtil.DateTimeFromUtc(task.DeadLine); + var deadLineString = task.DeadLine.Hour == 0 && task.DeadLine.Minute == 0 ? task.DeadLine.ToShortDateString() : task.DeadLine.ToString(); @@ -491,14 +511,14 @@ public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Cont public void SendAboutResponsibleForOpportunity(Deal deal) { - var recipient = ToRecipient(deal.ResponsibleID); - - if (recipient == null) return; - using var scope = ServiceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var securityContext = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); + + var recipient = notifySource.GetRecipientsProvider().GetRecipient(deal.ResponsibleID.ToString()); + + if (recipient == null) return; client.SendNoticeToAsync( NotifyConstants.Event_ResponsibleForOpportunity, @@ -514,21 +534,16 @@ public void SendAboutResponsibleForOpportunity(Deal deal) ); } - private IRecipient ToRecipient(Guid userID) - { - return source.GetRecipientsProvider().GetRecipient(userID.ToString()); - } + //public INotifyClient Client + //{ + // get { return client; } + //} - public INotifyClient Client - { - get { return client; } - } - - private NotifyClient(INotifyClient client, INotifySource source) - { - this.client = client; - this.source = source; - } + //private NotifyClient(INotifyClient client, INotifySource source) + //{ + // this.client = client; + // this.source = source; + //} } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index a690c3e11c3..c9551406529 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -24,6 +24,11 @@ */ +using ASC.Common.Logging; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Core; +using Autofac; using System; using System.Collections.Generic; using System.Globalization; @@ -31,33 +36,19 @@ using System.Linq; using System.Net; using System.Text.RegularExpressions; -using System.Web.Configuration; -using ASC.CRM.Core; -using ASC.Common.Logging; -using ASC.CRM.Core.Dao; -using ASC.Web.CRM.Core; -using Autofac; namespace ASC.Web.CRM.Classes { - - public static class CurrencyProvider + public class CurrencyProvider { - - #region Members - - private static readonly ILog _log = LogManager.GetLogger("ASC"); - private static readonly object _syncRoot = new object(); - private static readonly Dictionary _currencies; - private static Dictionary _exchangeRates; - private static DateTime _publisherDate; + private readonly ILog _log = LogManager.GetLogger("ASC"); + private readonly object _syncRoot = new object(); + private readonly Dictionary _currencies; + private Dictionary _exchangeRates; + private DateTime _publisherDate; private const String _formatDate = "yyyy-MM-ddTHH:mm:ss.fffffffK"; - - #endregion - - #region Constructor - - static CurrencyProvider() + + CurrencyProvider() { using (var scope = DIHelper.Resolve()) { @@ -76,22 +67,14 @@ static CurrencyProvider() } } - #endregion - - #region Property - - public static DateTime GetPublisherDate + public DateTime GetPublisherDate { get { TryToReadPublisherDate(GetExchangesTempPath()); return _publisherDate; } } - #endregion - - #region Public Methods - - public static CurrencyInfo Get(string currencyAbbreviation) + public CurrencyInfo Get(string currencyAbbreviation) { if (!_currencies.ContainsKey(currencyAbbreviation)) return null; @@ -99,22 +82,22 @@ public static CurrencyInfo Get(string currencyAbbreviation) return _currencies[currencyAbbreviation]; } - public static List GetAll() + public List GetAll() { return _currencies.Values.OrderBy(v => v.Abbreviation).ToList(); } - public static List GetBasic() + public List GetBasic() { return _currencies.Values.Where(c => c.IsBasic).OrderBy(v => v.Abbreviation).ToList(); } - public static List GetOther() + public List GetOther() { return _currencies.Values.Where(c => !c.IsBasic).OrderBy(v => v.Abbreviation).ToList(); } - public static Dictionary MoneyConvert(CurrencyInfo baseCurrency) + public Dictionary MoneyConvert(CurrencyInfo baseCurrency) { if (baseCurrency == null) throw new ArgumentNullException("baseCurrency"); if (!_currencies.ContainsKey(baseCurrency.Abbreviation)) throw new ArgumentOutOfRangeException("baseCurrency", "Not found."); @@ -142,7 +125,7 @@ public static Dictionary MoneyConvert(CurrencyInfo baseCu } - public static bool IsConvertable(String abbreviation) + public bool IsConvertable(String abbreviation) { var findedItem = _currencies.Keys.ToList().Find(item => String.Compare(abbreviation, item) == 0); @@ -152,7 +135,7 @@ public static bool IsConvertable(String abbreviation) return _currencies[findedItem].IsConvertable; } - public static Decimal MoneyConvert(decimal amount, string from, string to) + public Decimal MoneyConvert(decimal amount, string from, string to) { if (string.IsNullOrEmpty(from) || string.IsNullOrEmpty(to) || string.Compare(from, to, true) == 0) return amount; @@ -165,27 +148,23 @@ public static Decimal MoneyConvert(decimal amount, string from, string to) return Math.Round(rates[key] * amount, 4, MidpointRounding.AwayFromZero); } - public static Decimal MoneyConvertToDefaultCurrency(decimal amount, string from) + public Decimal MoneyConvertToDefaultCurrency(decimal amount, string from) { return MoneyConvert(amount, from, Global.TenantSettings.DefaultCurrency.Abbreviation); } - #endregion - - #region Private Methods - - private static bool ObsoleteData() + private bool ObsoleteData() { return _exchangeRates == null || (DateTime.UtcNow.Date.Subtract(_publisherDate.Date).Days > 0); } - private static string GetExchangesTempPath() { + private string GetExchangesTempPath() { return Path.Combine(Path.GetTempPath(), Path.Combine("onlyoffice", "exchanges")); } - private static Regex CurRateRegex = new Regex("[a-zA-Z]{3})\">(?[\\d\\.]+)"); + private Regex CurRateRegex = new Regex("[a-zA-Z]{3})\">(?[\\d\\.]+)"); - private static Dictionary GetExchangeRates() + private Dictionary GetExchangeRates() { if (ObsoleteData()) { @@ -252,7 +231,7 @@ private static Dictionary GetExchangeRates() return _exchangeRates; } - private static bool TryGetRatesFromFile(string filepath, CurrencyInfo curCI) + private bool TryGetRatesFromFile(string filepath, CurrencyInfo curCI) { var success = false; var currencyLines = File.ReadAllLines(filepath); @@ -282,7 +261,7 @@ private static bool TryGetRatesFromFile(string filepath, CurrencyInfo curCI) } - private static void TryToReadPublisherDate(string tmppath) + private void TryToReadPublisherDate(string tmppath) { if (_publisherDate == default(DateTime)) { @@ -302,7 +281,7 @@ private static void TryToReadPublisherDate(string tmppath) } } - private static void WritePublisherDate(string tmppath) + private void WritePublisherDate(string tmppath) { try { @@ -315,7 +294,7 @@ private static void WritePublisherDate(string tmppath) } } - private static void DownloadCurrencyPage(string currency, string filepath) + private void DownloadCurrencyPage(string currency, string filepath) { try @@ -351,6 +330,5 @@ private static void DownloadCurrencyPage(string currency, string filepath) } } - #endregion } } diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 9b64e5b811b..b49ae9d900c 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -24,92 +24,103 @@ */ -using System.Globalization; using ASC.Common.Caching; +using ASC.Common.Logging; using ASC.Common.Security.Authentication; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.Core.Users; +using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.Web.Core.Files; -using ASC.Web.CRM.Resources; +using ASC.Web.CRM.Core; using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Utils; using ASC.Web.Studio.Utility; +using Autofac; using Ionic.Zip; +using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Data; +using System.Globalization; using System.IO; using System.Linq; using System.Text; -using ASC.Common.Logging; -using ASC.Web.CRM.Core; -using Autofac; -using ASC.CRM.Resources; namespace ASC.Web.CRM.Classes { - class ExportDataCache + public class ExportDataCache { - public static readonly ICache Cache = AscCache.Default; + public readonly ICache Cache = AscCache.Memory; - public static String GetStateCacheKey(string key) + public String GetStateCacheKey(string key) { return String.Format("{0}:crm:queue:exporttocsv", key); } - public static String GetCancelCacheKey(string key) + public String GetCancelCacheKey(string key) { return String.Format("{0}:crm:queue:exporttocsv:cancel", key); } - public static ExportDataOperation Get(string key) + public ExportDataOperation Get(string key) { return Cache.Get(GetStateCacheKey(key)); } - public static void Insert(string key, ExportDataOperation data) + public void Insert(string key, ExportDataOperation data) { Cache.Insert(GetStateCacheKey(key), data, TimeSpan.FromMinutes(1)); } - public static bool CheckCancelFlag(string key) + public bool CheckCancelFlag(string key) { var fromCache = Cache.Get(GetCancelCacheKey(key)); return !String.IsNullOrEmpty(fromCache); } - public static void SetCancelFlag(string key) + public void SetCancelFlag(string key) { Cache.Insert(GetCancelCacheKey(key), "true", TimeSpan.FromMinutes(1)); } - public static void ResetAll(string key) + public void ResetAll(string key) { Cache.Remove(GetStateCacheKey(key)); Cache.Remove(GetCancelCacheKey(key)); } } - class ExportDataOperation : IProgressItem + public class ExportDataOperation : IProgressItem { - #region Constructor - - public ExportDataOperation(FilterObject filterObject, string fileName) + public ExportDataOperation(UserManager userManager, + FileUtility fileUtility, + SecurityContext securityContext, + IOptionsMonitor logger, + TenantManager tenantManager, + Global global, + ExportDataCache exportDataCache) { - _tenantId = TenantProvider.CurrentTenantID; - _author = SecurityContext.CurrentAccount; - _dataStore = Global.GetStore(); + UserManager = userManager; + FileUtility = fileUtility; + + _tenantId = tenantManager.GetCurrentTenant().TenantId; + + _author = securityContext.CurrentAccount; + _dataStore = global.GetStore(); _notifyClient = NotifyClient.Instance; _filterObject = filterObject; - _log = LogManager.GetLogger("ASC.CRM"); + + _log = logger.Get("ASC.CRM"); Id = ExportToCsv.GetKey(filterObject != null); Status = ProgressStatus.Queued; @@ -118,16 +129,18 @@ public ExportDataOperation(FilterObject filterObject, string fileName) IsCompleted = false; FileName = fileName ?? CRMSettingResource.Export + (filterObject == null ? ".zip" : ".csv"); FileUrl = null; - } - public ExportDataOperation() - : this(null, null) - { + ExportDataCache = exportDataCache; + SecurityContext = securityContext; } + + public SecurityContext SecurityContext { get; } - #endregion + public ExportDataCache ExportDataCache { get; } - #region Members + public UserManager UserManager { get; } + + public FileUtility FileUtility { get; } private readonly int _tenantId; @@ -142,9 +155,7 @@ public ExportDataOperation() private readonly ILog _log; private int _totalCount; - - #endregion - + public override bool Equals(object obj) { if (obj == null) return false; @@ -176,9 +187,7 @@ public object Clone() return cloneObj; } - - #region Property - + public object Id { get; set; } public object Status { get; set; } @@ -192,17 +201,13 @@ public object Clone() public string FileName { get; set; } public string FileUrl { get; set; } - - #endregion - - #region Private Methods - - private static String WrapDoubleQuote(String value) + + private String WrapDoubleQuote(String value) { return "\"" + value.Trim().Replace("\"", "\"\"") + "\""; } - private static String DataTableToCsv(DataTable dataTable) + private String DataTableToCsv(DataTable dataTable) { var result = new StringBuilder(); @@ -236,8 +241,6 @@ private static String DataTableToCsv(DataTable dataTable) return result.ToString(); } - #endregion - public void RunJob() { try @@ -879,7 +882,7 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) deal.PerPeriodValue == 0 ? "" : deal.PerPeriodValue.ToString(CultureInfo.InvariantCulture), deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern), deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern), - CoreContext.UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(false), + UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(false), currentDealMilestone.Title, currentDealMilestoneStatus, deal.DealMilestoneProbability.ToString(CultureInfo.InvariantCulture), @@ -1082,7 +1085,7 @@ private String ExportHistoryToCsv(IEnumerable events, DaoFact categoryTitle, contactTitle, entityTitle, - CoreContext.UserManager.GetUsers(item.CreateBy).DisplayUserName(false), + UserManager.GetUsers(item.CreateBy).DisplayUserName(false), item.CreateOn.ToShortString() }); } @@ -1315,7 +1318,7 @@ private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, Da return DataTableToCsv(dataTable); } - private static String SaveCsvFileInMyDocument(String title, String data) + private String SaveCsvFileInMyDocument(String title, String data) { string fileUrl; @@ -1342,24 +1345,34 @@ private static String SaveCsvFileInMyDocument(String title, String data) public class ExportToCsv { - #region Members + private readonly object Locker = new object(); - private static readonly object Locker = new object(); + private readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromSeconds(60), true); + + public ExportToCsv(SecurityContext securityContext, + ExportDataCache exportDataCache, + TenantManager tenantManager) + { + SecurityContext = securityContext; + ExportDataCache = exportDataCache; + TenantID = tenantManager.GetCurrentTenant().TenantId; + } + + protected int TenantID { get; private set; } - private static readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromSeconds(60), true); + public ExportDataCache ExportDataCache { get; } - #endregion + public SecurityContext SecurityContext { get; } - #region Public Methods - public static IProgressItem GetStatus(bool partialDataExport) + public IProgressItem GetStatus(bool partialDataExport) { var key = GetKey(partialDataExport); return Queue.GetStatus(key) ?? ExportDataCache.Get(key); } - public static IProgressItem Start(FilterObject filterObject, string fileName) + public IProgressItem Start(FilterObject filterObject, string fileName) { lock (Locker) { @@ -1389,7 +1402,7 @@ public static IProgressItem Start(FilterObject filterObject, string fileName) } } - public static void Cancel(bool partialDataExport) + public void Cancel(bool partialDataExport) { lock (Locker) { @@ -1406,13 +1419,13 @@ public static void Cancel(bool partialDataExport) } } - public static string GetKey(bool partialDataExport) + public string GetKey(bool partialDataExport) { - return string.Format("{0}_{1}", TenantProvider.CurrentTenantID, + return string.Format("{0}_{1}", TenantID, partialDataExport ? SecurityContext.CurrentAccount.ID : Guid.Empty); } - public static String ExportItems(FilterObject filterObject, string fileName) + public String ExportItems(FilterObject filterObject, string fileName) { var operation = new ExportDataOperation(filterObject, fileName); @@ -1420,7 +1433,5 @@ public static String ExportItems(FilterObject filterObject, string fileName) return operation.FileUrl; } - - #endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs index 50ce6761560..de8b6c6eb3a 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs @@ -24,13 +24,12 @@ */ -using ASC.Web.CRM.Core.Enums; +using ASC.CRM.Core.Enums; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; -using System.Web; namespace ASC.Web.CRM.Classes { diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index f037e3b99b6..88f71ccfbcb 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -26,16 +26,15 @@ #region Import -using System; -using System.Collections.Generic; -using System.Linq; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; -using ASC.Web.CRM.Resources; +using ASC.CRM.Core.Enums; using LumenWorks.Framework.IO.Csv; using Newtonsoft.Json.Linq; -using ASC.Common.Threading.Progress; -using ASC.CRM.Core.Dao; +using System; +using System.Collections.Generic; +using System.Linq; #endregion diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index a06d2c6c73c..1ecffececb2 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -26,16 +26,15 @@ #region Import -using System; -using System.Collections.Generic; -using System.Linq; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; -using ASC.Web.CRM.Core.Enums; +using ASC.CRM.Core.Enums; using LumenWorks.Framework.IO.Csv; using Newtonsoft.Json.Linq; -using ASC.CRM.Core.Dao; -using ASC.Common.Threading.Progress; +using System; +using System.Collections.Generic; +using System.Linq; #endregion @@ -45,6 +44,9 @@ public partial class ImportDataOperation { private Int32 DaoIterationStep = 200; + + + private void ImportContactsData(DaoFactory _daoFactory) { var index = 0; @@ -63,8 +65,9 @@ private void ImportContactsData(DaoFactory _daoFactory) #region Read csv using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) - using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { + CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings); + int currentIndex = 0; while (csv.ReadNextRecord()) @@ -131,7 +134,7 @@ private void ImportContactsData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); #endregion #region Processing duplicate rule @@ -140,7 +143,8 @@ private void ImportContactsData(DaoFactory _daoFactory) _log.Info("ImportContactsData. _DuplicateRecordRuleProcess. End"); - if (IsCompleted) { + if (IsCompleted) + { return; } @@ -156,7 +160,7 @@ private void ImportContactsData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Contact,(ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); #endregion #region Manipulation for saving Companies for persons + CRMSecurity @@ -181,11 +185,11 @@ private void ImportContactsData(DaoFactory _daoFactory) .ToDictionary(item => item.Key, item => item.Value); - #region CRMSecurity set -by every item- + #region CRMSecurity set -by every item- portion.ForEach(ct => CRMSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); - #endregion + #endregion index += DaoIterationStep; @@ -220,7 +224,7 @@ private void ImportContactsData(DaoFactory _daoFactory) if (findedCompany == null) { #region create COMPANY for person in csv - + findedCompany = new Company { CompanyName = item.Value, @@ -262,11 +266,11 @@ private void ImportContactsData(DaoFactory _daoFactory) contactDao.SaveContactList(portion)) .ToDictionary(item => item.Key, item => item.Value); - #region CRMSecurity set -by every item- + #region CRMSecurity set -by every item- portion.ForEach(ct => CRMSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); - #endregion + #endregion index += DaoIterationStep; @@ -289,7 +293,7 @@ private void ImportContactsData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); #endregion #region Save contact infos -by portions- @@ -333,7 +337,7 @@ private void ImportContactsData(DaoFactory _daoFactory) if (findedCustomField.Count != 0) { findedCustomField.ForEach(item => item.EntityID = fakeRealContactIdHash[item.EntityID]); - + index = 0; while (index < findedCustomField.Count) { @@ -361,7 +365,7 @@ private void ImportContactsData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); #endregion #region Save tags @@ -452,7 +456,8 @@ private bool _CommonData(int currentIndex, DaoFactory _daoFactory, ref Contact c } else { - contact.StatusID = listItemDao.CreateItem(ListType.ContactStatus, new ListItem(){ + contact.StatusID = listItemDao.CreateItem(ListType.ContactStatus, new ListItem() + { Title = contactStageName, Color = "#77cf9a", Description = "" @@ -469,7 +474,8 @@ private bool _CommonData(int currentIndex, DaoFactory _daoFactory, ref Contact c } else { - contact.ContactTypeID = listItemDao.CreateItem(ListType.ContactType, new ListItem(){ + contact.ContactTypeID = listItemDao.CreateItem(ListType.ContactType, new ListItem() + { Title = contactTypeName, Description = "" }); @@ -524,10 +530,10 @@ private void _ReadContactInfo(JProperty jToken, String propertyValue, Contact co if (contactInfoType == ContactInfoType.Email) { var validEmails = propertyValue - .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) + .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Where(email => email.TestEmailRegex()).ToArray(); - if(!validEmails.Any()) + if (!validEmails.Any()) return; propertyValue = string.Join(",", validEmails); @@ -580,23 +586,23 @@ private void _ReadContactInfo(JProperty jToken, String propertyValue, Contact co return; } - var items = propertyValue.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); + var items = propertyValue.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (var item in items) { findedContactInfos.Add(new ContactInfo - { - Category = category, - InfoType = contactInfoType, - Data = item, - ContactID = contact.ID, - IsPrimary = isPrimary - }); + { + Category = category, + InfoType = contactInfoType, + Data = item, + ContactID = contact.ID, + IsPrimary = isPrimary + }); isPrimary = false; } } - + #endregion private void _DuplicateRecordRuleProcess(DaoFactory _daoFactory, @@ -693,6 +699,6 @@ private void _DuplicateRecordRuleProcess(DaoFactory _daoFactory, break; } } - + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 8f9651a2e24..7eee76bb65f 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -24,61 +24,68 @@ */ -using System; -using System.Linq; -using System.Globalization; - using ASC.Common.Caching; +using ASC.Common.Logging; using ASC.Common.Security.Authentication; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.CRM.Core; using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.Data.Storage; -using ASC.Web.CRM.Resources; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Web.Studio.Utility; -using ASC.Common.Logging; using ASC.Web.CRM.Core; +using ASC.Web.CRM.Services.NotifyService; using Autofac; +using Microsoft.Extensions.Options; +using System; +using System.Globalization; +using System.Linq; namespace ASC.Web.CRM.Classes { - class ImportDataCache + public class ImportDataCache { - public static readonly ICache Cache = AscCache.Default; + public ImportDataCache(TenantManager tenantManager) + { + TenantID = tenantManager.CurrentTenant.TenantId; + } + + public int TenantID { get; } - public static String GetStateCacheKey(EntityType entityType, int tenantId = -1) + public readonly ICache Cache = AscCache.Memory; + + public String GetStateCacheKey(EntityType entityType, int tenantId = -1) { if (tenantId == -1) { - tenantId = TenantProvider.CurrentTenantID; + tenantId = TenantID; } return String.Format("{0}:crm:queue:importtocsv:{1}", tenantId.ToString(CultureInfo.InvariantCulture), entityType.ToString()); } - public static String GetCancelCacheKey(EntityType entityType, int tenantId = -1) + public String GetCancelCacheKey(EntityType entityType, int tenantId = -1) { if (tenantId == -1) { - tenantId = TenantProvider.CurrentTenantID; + tenantId = TenantID; } return String.Format("{0}:crm:queue:importtocsv:{1}:cancel", tenantId.ToString(CultureInfo.InvariantCulture), entityType.ToString()); } - public static ImportDataOperation Get(EntityType entityType) + public ImportDataOperation Get(EntityType entityType) { return Cache.Get(GetStateCacheKey(entityType)); } - public static void Insert(EntityType entityType,ImportDataOperation data) + public void Insert(EntityType entityType,ImportDataOperation data) { Cache.Insert(GetStateCacheKey(entityType), data, TimeSpan.FromMinutes(1)); } - public static bool CheckCancelFlag(EntityType entityType) + public bool CheckCancelFlag(EntityType entityType) { var fromCache = Cache.Get(GetCancelCacheKey(entityType)); @@ -89,12 +96,12 @@ public static bool CheckCancelFlag(EntityType entityType) } - public static void SetCancelFlag(EntityType entityType) + public void SetCancelFlag(EntityType entityType) { Cache.Insert(GetCancelCacheKey(entityType), true, TimeSpan.FromMinutes(1)); } - public static void ResetAll(EntityType entityType, int tenantId = -1) + public void ResetAll(EntityType entityType, int tenantId = -1) { Cache.Remove(GetStateCacheKey(entityType, tenantId)); Cache.Remove(GetCancelCacheKey(entityType, tenantId)); @@ -103,34 +110,52 @@ public static void ResetAll(EntityType entityType, int tenantId = -1) public partial class ImportDataOperation : IProgressItem { - #region Constructor - - public ImportDataOperation() - : this(EntityType.Contact, String.Empty, String.Empty) + public ImportDataOperation(EntityType entityType, + string CSVFileURI, + string importSettingsJSON, + SecurityContext securityContext, + Global global, + TenantManager tenantManager, + IOptionsMonitor logger, + UserManager userManager, + ImportDataCache importDataCache, + CRMSecurity cRMSecurity) { - } + ImportDataCache = importDataCache; - public ImportDataOperation(EntityType entityType, String CSVFileURI, String importSettingsJSON) - { - _CSVFileURI = CSVFileURI; - _dataStore = Global.GetStore(); - _tenantID = TenantProvider.CurrentTenantID; _entityType = entityType; - _author = SecurityContext.CurrentAccount; + _CSVFileURI = CSVFileURI; + UserManager = userManager; + if (!String.IsNullOrEmpty(importSettingsJSON)) + _importSettings = new ImportCSVSettings(importSettingsJSON); + + SecurityContext = securityContext; + _dataStore = global.GetStore(); + + _tenantID = tenantManager.CurrentTenant.TenantId; + _author = SecurityContext.CurrentAccount; + _notifyClient = NotifyClient.Instance; - Id = String.Format("{0}_{1}", TenantProvider.CurrentTenantID, (int)_entityType); + Id = String.Format("{0}_{1}", _tenantID, (int)_entityType); - _log = LogManager.GetLogger("ASC.CRM"); + _log = logger.Get("ASC.CRM"); - if (!String.IsNullOrEmpty(importSettingsJSON)) - _importSettings = new ImportCSVSettings(importSettingsJSON); + CRMSecurity = cRMSecurity; } - #endregion + public CRMSecurity CRMSecurity { get; } - #region Members + public ImportDataCache ImportDataCache { get; } + + public TenantManager TenantManager { get; } + + public SecurityContext SecurityContext { get; } + + public UserManager UserManager { get; } + + public ILog LogManager { get; } private readonly ILog _log; @@ -142,15 +167,13 @@ public ImportDataOperation(EntityType entityType, String CSVFileURI, String impo private readonly int _tenantID; - private readonly String _CSVFileURI; + private readonly string _CSVFileURI; private readonly ImportCSVSettings _importSettings; private readonly EntityType _entityType; - private String[] _columns; - - #endregion + private string[] _columns; public override bool Equals(object obj) { @@ -171,7 +194,7 @@ public override int GetHashCode() public object Clone() { - var cloneObj = new ImportDataOperation + var cloneObj = new ImportDataOperation() { Error = Error, Id = Id, @@ -183,8 +206,6 @@ public object Clone() return cloneObj; } - #region Property - public object Id { get; set; } public object Status { get; set; } @@ -194,9 +215,7 @@ public object Clone() public double Percentage { get; set; } public bool IsCompleted { get; set; } - - #endregion - + private String GetPropertyValue(String propertyName) { if (_importSettings.ColumnMapping[propertyName] == null) return String.Empty; @@ -226,13 +245,13 @@ public void RunJob() { try { - CoreContext.TenantManager.SetCurrentTenant(_tenantID); + TenantManager.SetCurrentTenant(_tenantID); SecurityContext.AuthenticateMe(_author); using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); - var userCulture = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index 3fc310469d5..47b54a82da8 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -26,19 +26,17 @@ #region Import -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; +using ASC.Core.Users; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; -using ASC.Core.Users; -using ASC.Web.CRM.Resources; -using ASC.Web.Studio.Core.Users; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using LumenWorks.Framework.IO.Csv; using Newtonsoft.Json.Linq; -using ASC.Common.Threading.Progress; -using ASC.CRM.Core.Dao; +using System; +using System.Collections.Generic; +using System.Linq; #endregion diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs index 60629d2dfc7..d0bd18e24e7 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs @@ -26,16 +26,15 @@ #region Import -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.CRM.Core; -using ASC.CRM.Core.Entities; using ASC.Core.Tenants; using ASC.Core.Users; using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Resources; using LumenWorks.Framework.IO.Csv; -using ASC.Web.CRM.Resources; +using System; +using System.Collections.Generic; +using System.Linq; #endregion diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index ef721b11030..a27ccf9ea67 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -27,12 +27,26 @@ #region Import using ASC.Common.Caching; +using ASC.Common.Logging; using ASC.Common.Threading.Progress; +using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.Core.Tenants; +using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; -using ASC.Web.CRM.Resources; -using ASC.Web.Studio.Utility; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.CRM.Core; +using ASC.Web.Files.Api; +using Autofac; +using MailKit; +using MailKit.Net.Smtp; +using MailKit.Security; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; +using MimeKit; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -43,17 +57,6 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading; -using System.Web.Configuration; -using ASC.Common.Logging; -using ASC.Core; -using ASC.Core.Tenants; -using ASC.Web.CRM.Core; -using ASC.Web.Files.Api; -using Autofac; -using MailKit; -using MailKit.Net.Smtp; -using MailKit.Security; -using MimeKit; using File = System.IO.File; using SmtpClient = MailKit.Net.Smtp.SmtpClient; @@ -61,8 +64,7 @@ namespace ASC.Web.CRM.Classes { - - class SendBatchEmailsOperation : IProgressItem, IDisposable + public class SendBatchEmailsOperation : IProgressItem, IDisposable { private readonly bool _storeInHistory; private readonly ILog _log; @@ -76,16 +78,13 @@ class SendBatchEmailsOperation : IProgressItem, IDisposable private int historyCategory; private double _exactPercentageValue = 0; - public object Id { get; set; } public object Status { get; set; } public object Error { get; set; } public double Percentage { get; set; } public bool IsCompleted { get; set; } - private SendBatchEmailsOperation() - : this(new List(), new List(), String.Empty, String.Empty, false) { } @@ -94,18 +93,32 @@ public SendBatchEmailsOperation( List contactID, String subject, String bodyTempate, - bool storeInHistory) + bool storeInHistory, + TenantUtil tenantUtil, + IOptionsMonitor logger, + Global global, + SecurityContext securityContext, + TenantManager tenantManager, + UserManager userManager, + AuthManager authManager, + SettingsManager settingsManager, + MailSenderDataCache mailSenderDataCache + ) { - Id = TenantProvider.CurrentTenantID; + TenantUtil = tenantUtil; + SecurityContext = securityContext; + Percentage = 0; + _fileID = fileID; _contactID = contactID; _subject = subject; _bodyTempate = bodyTempate; - _log = LogManager.GetLogger("ASC.CRM.MailSender"); - _tenantID = TenantProvider.CurrentTenantID; - _smtpSetting = Global.TenantSettings.SMTPServerSetting; + _log = logger.Get("ASC.CRM.MailSender"); + + _tenantID = tenantManager.GetCurrentTenant().TenantId; + _smtpSetting = settingsManager.Load().SMTPServerSetting; _currUser = SecurityContext.CurrentAccount.ID; _storeInHistory = storeInHistory; @@ -115,8 +128,25 @@ public SendBatchEmailsOperation( EstimatedTime = 0, DeliveryCount = 0 }; + + AuthManager = authManager; + UserManager = userManager; + MailSenderDataCache = mailSenderDataCache; } + public FilesIntegration FilesIntegration { get; } + + public MailSenderDataCache MailSenderDataCache { get; } + public AuthManager AuthManager { get; } + + public UserManager UserManager { get; } + + public TenantManager TenantManager { get; } + + public SecurityContext SecurityContext { get; } + + public TenantUtil TenantUtil { get; } + private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) { if (contactID == 0 || String.IsNullOrEmpty(content)) return; @@ -158,15 +188,15 @@ public void RunJob() SmtpClient smtpClient = null; try { - CoreContext.TenantManager.SetCurrentTenant(_tenantID); - SecurityContext.AuthenticateMe(CoreContext.Authentication.GetAccountByID(_currUser)); + TenantManager.SetCurrentTenant(_tenantID); + SecurityContext.AuthenticateMe(AuthManager.GetAccountByID(_tenantID, _currUser)); smtpClient = GetSmtpClient(); using (var scope = DIHelper.Resolve()) { var _daoFactory = scope.Resolve(); - var userCulture = CoreContext.UserManager.GetUsers(_currUser).GetCulture(); + var userCulture = UserManager.GetUsers(_currUser).GetCulture(); Thread.CurrentThread.CurrentCulture = userCulture; Thread.CurrentThread.CurrentUICulture = userCulture; @@ -179,31 +209,35 @@ public void RunJob() return; } - MailSenderDataCache.Insert((SendBatchEmailsOperation) Clone()); + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); var filePaths = new List(); - using (var fileDao = FilesIntegration.GetFileDao()) + var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + + foreach (var fileID in _fileID) { - foreach (var fileID in _fileID) + var fileObj = fileDao.GetFile(fileID); + if (fileObj == null) continue; + using (var fileStream = fileDao.GetFileStream(fileObj)) { - var fileObj = fileDao.GetFile(fileID); - if (fileObj == null) continue; - using (var fileStream = fileDao.GetFileStream(fileObj)) + var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), + "crm/files/mailsender/"); + + if (!Directory.Exists(directoryPath)) { - var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), - "crm/files/mailsender/"); - if (!Directory.Exists(directoryPath)) - { - Directory.CreateDirectory(directoryPath); - } - var filePath = Path.Combine(directoryPath, fileObj.Title); - using (var newFileStream = File.Create(filePath)) - { - fileStream.StreamCopyTo(newFileStream); - } - filePaths.Add(filePath); + Directory.CreateDirectory(directoryPath); + } + + var filePath = Path.Combine(directoryPath, fileObj.Title); + + using (var newFileStream = File.Create(filePath)) + { + fileStream.StreamCopyTo(newFileStream); } + + filePaths.Add(filePath); + } } @@ -217,7 +251,7 @@ public void RunJob() { _exactPercentageValue += 100.0 / contactCount; Percentage = Math.Round(_exactPercentageValue); - + if (IsCompleted) break; // User selected cancel var contactInfoDao = _daoFactory.ContactInfoDao; @@ -292,7 +326,7 @@ public void RunJob() deliveryCount++; var estimatedTime = - TimeSpan.FromTicks(waitInterval.Ticks*(_contactID.Count - deliveryCount)); + TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); Status = new { @@ -309,7 +343,7 @@ public void RunJob() throw new OperationCanceledException(); } - MailSenderDataCache.Insert((SendBatchEmailsOperation) Clone()); + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); if (Percentage > 100) { @@ -322,7 +356,7 @@ public void RunJob() throw new OperationCanceledException(); } - MailSenderDataCache.Insert((SendBatchEmailsOperation) Clone()); + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); } } @@ -365,7 +399,7 @@ public void RunJob() } } - public static string GetLoggerRow(MimeMessage mailMessage) + public string GetLoggerRow(MimeMessage mailMessage) { if (mailMessage == null) return String.Empty; @@ -376,7 +410,7 @@ public static string GetLoggerRow(MimeMessage mailMessage) result.AppendLine("To:" + mailMessage.To[0]); result.AppendLine("Subject:" + mailMessage.Subject); result.AppendLine("Body:" + mailMessage.Body); - result.AppendLine("TenantID:" + TenantProvider.CurrentTenantID); + result.AppendLine("TenantID:" + _tenantID); foreach (var attachment in mailMessage.Attachments) { @@ -403,16 +437,16 @@ private void DeleteFiles() { if (_fileID == null || _fileID.Count == 0) return; - using (var fileDao = FilesIntegration.GetFileDao()) + var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + + foreach (var fileID in _fileID) { - foreach (var fileID in _fileID) - { - var fileObj = fileDao.GetFile(fileID); - if (fileObj == null) continue; + var fileObj = fileDao.GetFile(fileID); + if (fileObj == null) continue; - fileDao.DeleteFile(fileObj.ID); - } + fileDao.DeleteFile(fileObj.ID); } + } private SmtpClient GetSmtpClient() @@ -421,7 +455,7 @@ private SmtpClient GetSmtpClient() { ServerCertificateValidationCallback = (sender, certificate, chain, errors) => WorkContext.IsMono || MailKit.MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), - Timeout = (int) TimeSpan.FromSeconds(30).TotalMilliseconds + Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds }; client.Connect(_smtpSetting.Host, _smtpSetting.Port, @@ -440,7 +474,7 @@ private void Complete() IsCompleted = true; Percentage = 100; _log.Debug("Completed"); - + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); Thread.Sleep(10000); @@ -466,31 +500,38 @@ public void Dispose() } } - class MailSenderDataCache + public class MailSenderDataCache { - public static readonly ICache Cache = AscCache.Default; + public MailSenderDataCache(TenantManager tenantManager) + { + TenantID = tenantManager.GetCurrentTenant().TenantId; + } - public static String GetStateCacheKey() + public int TenantID { get; } + + public readonly ICache Cache = AscCache.Memory; + + public string GetStateCacheKey() { - return String.Format("{0}:crm:queue:sendbatchemails", TenantProvider.CurrentTenantID.ToString()); + return string.Format("{0}:crm:queue:sendbatchemails", TenantID); } - public static String GetCancelCacheKey() + public string GetCancelCacheKey() { - return String.Format("{0}:crm:queue:sendbatchemails:cancel", TenantProvider.CurrentTenantID.ToString()); + return string.Format("{0}:crm:queue:sendbatchemails:cancel", TenantID); } - public static SendBatchEmailsOperation Get() + public SendBatchEmailsOperation Get() { return Cache.Get(GetStateCacheKey()); } - public static void Insert(SendBatchEmailsOperation data) + public void Insert(SendBatchEmailsOperation data) { Cache.Insert(GetStateCacheKey(), data, TimeSpan.FromMinutes(1)); } - public static bool CheckCancelFlag() + public bool CheckCancelFlag() { var fromCache = Cache.Get(GetCancelCacheKey()); @@ -501,44 +542,65 @@ public static bool CheckCancelFlag() } - public static void SetCancelFlag() + public void SetCancelFlag() { Cache.Insert(GetCancelCacheKey(), "true", TimeSpan.FromMinutes(1)); } - public static void ResetAll() + public void ResetAll() { Cache.Remove(GetStateCacheKey()); Cache.Remove(GetCancelCacheKey()); } } - + public class MailSender { - private static readonly Object _syncObj = new Object(); - private static readonly ProgressQueue _mailQueue = new ProgressQueue(2, TimeSpan.FromSeconds(60), true); - private static readonly int quotas = 50; - - - static MailSender() + private readonly Object _syncObj = new Object(); + private readonly ProgressQueue _mailQueue = new ProgressQueue(2, TimeSpan.FromSeconds(60), true); + private readonly int quotas = 50; + + public MailSender( + IConfiguration configuration, + TenantManager tenantManager, + SettingsManager settingsManager, + MailSenderDataCache mailSenderDataCache + ) { + TenantID = tenantManager.GetCurrentTenant().TenantId; + MailSenderDataCache = mailSenderDataCache; + int parsed; - if (int.TryParse(WebConfigurationManager.AppSettings["crm.mailsender.quotas"], out parsed)) + + if (int.TryParse(configuration["crm:mailsender:quotas"], out parsed)) { quotas = parsed; } + + TenantManager = tenantManager; + SettingsManager = settingsManager; + + // LogManager = logger.Get(); } - public static int GetQuotas() + public TenantManager TenantManager { get; } + public SettingsManager SettingsManager { get; } + + public MailSenderDataCache MailSenderDataCache { get; } + public int TenantID { get; } + + public IOptionsMonitor LogManager { get; } + + public int GetQuotas() { return quotas; } - public static IProgressItem Start(List fileID, List contactID, String subject, String bodyTemplate, bool storeInHistory) + public IProgressItem Start(List fileID, List contactID, String subject, String bodyTemplate, bool storeInHistory) { lock (_syncObj) { - var operation = _mailQueue.GetStatus(TenantProvider.CurrentTenantID); + var operation = _mailQueue.GetStatus(TenantID); if (operation == null) { @@ -547,7 +609,7 @@ public static IProgressItem Start(List fileID, List contactID, String if (mailSender != null) return mailSender; } - + if (operation == null) { if (fileID == null) @@ -577,7 +639,7 @@ public static IProgressItem Start(List fileID, List contactID, String } } - private static SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) + private SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) { var client = new SmtpClient { @@ -596,18 +658,17 @@ private static SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) return client; } - public static void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) + public void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) { - var log = LogManager.GetLogger("ASC.CRM.MailSender"); + var log = LogManager.Get("ASC.CRM.MailSender"); if (!recipientEmail.TestEmailRegex()) { throw new Exception(string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail)); } - CoreContext.TenantManager.SetCurrentTenant(TenantProvider.CurrentTenantID); - - var smtpSetting = Global.TenantSettings.SMTPServerSetting; + TenantManager.SetCurrentTenant(TenantID); + var smtpSetting = SettingsManager.Load().SMTPServerSetting; ThreadPool.QueueUserWorkItem(_ => { @@ -646,9 +707,9 @@ public static void StartSendTestMail(string recipientEmail, string mailSubj, str }); } - public static IProgressItem GetStatus() + public IProgressItem GetStatus() { - var result = _mailQueue.GetStatus(TenantProvider.CurrentTenantID); + var result = _mailQueue.GetStatus(TenantID); if (result == null) return MailSenderDataCache.Get(); @@ -656,11 +717,11 @@ public static IProgressItem GetStatus() return result; } - public static void Cancel() + public void Cancel() { lock (_syncObj) { - var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantProvider.CurrentTenantID); + var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantID); if (findedItem.Any()) { @@ -672,7 +733,7 @@ public static void Cancel() { MailSenderDataCache.SetCancelFlag(); } - } + } } } @@ -694,30 +755,19 @@ public class MailTemplateTag [DataMember(Name = "name")] public String Name { get; set; } - - } public class MailTemplateManager { - - #region Members - private readonly Dictionary> _templateTagsCache = new Dictionary>(); private readonly DaoFactory _daoFactory; - #endregion - - #region Constructor - public MailTemplateManager(DaoFactory daoFactory) { _daoFactory = daoFactory; } - #endregion - private IEnumerable GetTagsFrom(String template) { if (_templateTagsCache.ContainsKey(template)) return _templateTagsCache[template]; @@ -879,7 +929,6 @@ private List GetAllTags() public List GetTags(bool isCompany) { - var result = new List(); if (isCompany) @@ -936,8 +985,6 @@ public List GetTags(bool isCompany) } - #region Contact Infos - foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) { @@ -947,13 +994,13 @@ public List GetTags(bool isCompany) if (infoTypeEnum == ContactInfoType.Address) foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) result.Add(new MailTemplateTag - { - SysName = String.Format(localName + "_{0}_{1}", addressPartEnum, (int)AddressCategory.Work), - DisplayName = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString()), - Category = CRMContactResource.GeneralInformation, - isCompany = isCompany, - Name = ToTagName(String.Format("{0} {1}", infoTypeEnum.ToString(), addressPartEnum.ToString()), isCompany) - }); + { + SysName = String.Format(localName + "_{0}_{1}", addressPartEnum, (int)AddressCategory.Work), + DisplayName = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString()), + Category = CRMContactResource.GeneralInformation, + isCompany = isCompany, + Name = ToTagName(String.Format("{0} {1}", infoTypeEnum.ToString(), addressPartEnum.ToString()), isCompany) + }); else result.Add(new MailTemplateTag { @@ -965,10 +1012,6 @@ public List GetTags(bool isCompany) }); } - #endregion - - #region Custom Fields - var entityType = isCompany ? EntityType.Company : EntityType.Person; var customFieldsDao = _daoFactory.CustomFieldDao; @@ -991,17 +1034,15 @@ public List GetTags(bool isCompany) } result.Add(new MailTemplateTag - { - SysName = "customField_" + customField.ID, - DisplayName = customField.Label.HtmlEncode(), - Category = category, - isCompany = isCompany, - Name = ToTagName(customField.Label, isCompany) - }); + { + SysName = "customField_" + customField.ID, + DisplayName = customField.Label.HtmlEncode(), + Category = category, + isCompany = isCompany, + Name = ToTagName(customField.Label, isCompany) + }); } - #endregion - return result; } diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index d78d58ebf98..db598eaedd8 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -24,30 +24,46 @@ */ -using System; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Text; -using System.Web; -using System.Xml; using ASC.Common.Logging; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Resources; +using ASC.Files.Core; +using ASC.Web.Core.Files; using ASC.Web.CRM.Core; -using ASC.Web.CRM.Resources; using ASC.Web.Files.Services.DocumentService; +using ASC.Web.Files.Utils; using Autofac; using Ionic.Zip; -using File = ASC.Files.Core.File; +using Microsoft.Extensions.Options; +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Xml; namespace ASC.Web.CRM.Classes { public class PdfCreator { - private static Stream Template + public PdfCreator(IOptionsMonitor logger, + Files.Classes.PathProvider filesPathProvider, + DocumentServiceConnector documentServiceConnector, + ASC.Web.Files.Classes.Global filesGlobal, + FilesLinkUtility filesLinkUtility, + FileUtility fileUtility, + FileConverter fileConverter) + { + FilesPathProvider = filesPathProvider; + + Logger = logger.Get("ASC.CRM"); + + DocumentServiceConnector = documentServiceConnector; + } + + private Stream Template { get { @@ -55,16 +71,22 @@ private static Stream Template return new MemoryStream(bytes); } } + + public DocumentServiceConnector DocumentServiceConnector { get; } + + public Files.Classes.PathProvider FilesPathProvider { get; } + + public ILog Logger { get; } + private const string FormatPdf = ".pdf"; private const string FormatDocx = ".docx"; private const string DocumentXml = "word/document.xml"; private const string DocumentLogoImage = "word/media/logo.jpeg"; - - public static void CreateAndSaveFile(int invoiceId) - { - var log = LogManager.GetLogger("ASC.CRM"); - log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}", invoiceId); + public void CreateAndSaveFile(int invoiceId) + { + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}", invoiceId); + try { using (var scope = DIHelper.Resolve()) @@ -74,22 +96,24 @@ public static void CreateAndSaveFile(int invoiceId) var invoice = daoFactory.InvoiceDao.GetByID(invoiceId); if (invoice == null) { - log.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); + Logger.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); + return; } - log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. Convertation", invoiceId); + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. Convertation", invoiceId); string urlToFile; + using (var docxStream = GetStreamDocx(invoice)) { urlToFile = GetUrlToFile(docxStream); } - log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, urlToFile); - var file = new File + var file = new File { Title = string.Format("{0}{1}", invoice.Number, FormatPdf), FolderID = daoFactory.FileDao.GetRoot() @@ -101,7 +125,7 @@ public static void CreateAndSaveFile(int invoiceId) { file.ContentLength = response.ContentLength; - log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); file = daoFactory.FileDao.SaveFile(file, stream); } @@ -112,60 +136,73 @@ public static void CreateAndSaveFile(int invoiceId) invoice.FileID = Int32.Parse(file.ID.ToString()); - log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); + daoFactory.InvoiceDao.UpdateInvoiceFileID(invoice.ID, invoice.FileID); - log.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); + daoFactory.RelationshipEventDao.AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] {invoice.FileID}); + } } catch (Exception e) { - log.Error(e); + Logger.Error(e); } } - public static File CreateFile(Invoice data, DaoFactory daoFactory) + public File CreateFile(Invoice data, DaoFactory daoFactory) { - var log = LogManager.GetLogger("ASC.CRM"); try { using (var docxStream = GetStreamDocx(data)) { var urlToFile = GetUrlToFile(docxStream); + return SaveFile(data, urlToFile, daoFactory); } } catch (Exception e) { - log.Error(e); + Logger.Error(e); + throw; } } - private static string GetUrlToFile(Stream docxStream) + private string GetUrlToFile(Stream docxStream) { - var externalUri = Files.Classes.PathProvider.GetTempUrl(docxStream, FormatDocx); + var externalUri = FilesPathProvider.GetTempUrl(docxStream, FormatDocx); + externalUri = DocumentServiceConnector.ReplaceCommunityAdress(externalUri); - LogManager.GetLogger("ASC.CRM").DebugFormat("PdfCreator. GetUrlToFile. externalUri = {0}", externalUri); + + Logger.DebugFormat("PdfCreator. GetUrlToFile. externalUri = {0}", externalUri); var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); + string urlToFile; + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, false, out urlToFile); - LogManager.GetLogger("ASC.CRM").DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); + Logger.DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); + return urlToFile; + } - public static ConverterData StartCreationFileAsync(Invoice data) + public ConverterData StartCreationFileAsync(Invoice data) { using (var docxStream = GetStreamDocx(data)) { - var externalUri = Files.Classes.PathProvider.GetTempUrl(docxStream, FormatDocx); + var externalUri = FilesPathProvider.GetTempUrl(docxStream, FormatDocx); + externalUri = DocumentServiceConnector.ReplaceCommunityAdress(externalUri); var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); + string urlToFile; + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, true, out urlToFile); return new ConverterData @@ -177,7 +214,7 @@ public static ConverterData StartCreationFileAsync(Invoice data) } } - public static File GetConvertedFile(ConverterData data, DaoFactory daoFactory) + public File GetConvertedFile(ConverterData data, DaoFactory daoFactory) { if (string.IsNullOrEmpty(data.StorageUrl) || string.IsNullOrEmpty(data.RevisionId)) { @@ -185,6 +222,7 @@ public static File GetConvertedFile(ConverterData data, DaoFactory daoFactory) } string urlToFile; + DocumentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, true, out urlToFile); if (string.IsNullOrEmpty(urlToFile)) @@ -197,9 +235,9 @@ public static File GetConvertedFile(ConverterData data, DaoFactory daoFactory) return SaveFile(invoice, urlToFile, daoFactory); } - private static File SaveFile(Invoice data, string url, DaoFactory daoFactory) + private File SaveFile(Invoice data, string url, DaoFactory daoFactory) { - File file = null; + File file = null; var request = (HttpWebRequest)WebRequest.Create(url); @@ -209,7 +247,7 @@ private static File SaveFile(Invoice data, string url, DaoFactory daoFactory) { if (stream != null) { - var document = new File + var document = new File { Title = string.Format("{0}{1}", data.Number, FormatPdf), FolderID = daoFactory.FileDao.GetRoot(), @@ -229,7 +267,7 @@ private static File SaveFile(Invoice data, string url, DaoFactory daoFactory) return file; } - private static Stream GetStreamDocx(Invoice data) + private Stream GetStreamDocx(Invoice data) { var invoiceData = InvoiceFormattedData.GetData(data, 0, 0); var logo = new byte[] {}; @@ -271,7 +309,7 @@ private static Stream GetStreamDocx(Invoice data) } - private static string GenerateDocumentXml(XmlDocument xDocument, InvoiceFormattedData data, byte[] logo) + private string GenerateDocumentXml(XmlDocument xDocument, InvoiceFormattedData data, byte[] logo) { XmlNodeList nodeList; XmlNode parent; @@ -696,7 +734,7 @@ private static string GenerateDocumentXml(XmlDocument xDocument, InvoiceFormatte return xDocument.InnerXml; } - private static string EncodeAndReplaceLineBreaks(string str) + private string EncodeAndReplaceLineBreaks(string str) { return str .Replace("&", "&") diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index b389e9eece1..3166b7a4b47 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -31,6 +31,7 @@ using ASC.Common.Threading.Progress; using ASC.Common.Web; using ASC.Core; +using Microsoft.AspNetCore.Http; namespace ASC.Web.CRM.Classes { @@ -96,7 +97,10 @@ public class PdfProgressItem : IProgressItem public double Percentage { get; set; } public bool IsCompleted { get; set; } - public PdfProgressItem(HttpContext context, int tenantId, Guid userId, int invoiceId) + public PdfProgressItem(IHttpContextAccessor httpContextAccessor, + int tenantId, + Guid userId, + int invoiceId) { _contextUrl = context != null ? context.Request.GetUrlRewriter().ToString() : null; _tenantId = tenantId; From 4fb3f6208668a1c608b2f65c0aa90a6be945883d Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 14 Apr 2020 10:59:07 +0300 Subject: [PATCH 09/61] crm: migrate DAO to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 25 +- .../Server/Classes/ContactPhotoManager.cs | 121 +- products/ASC.CRM/Server/Classes/Global.cs | 11 +- .../Server/Classes/ImportFromCSVManager.cs | 18 +- .../Server/Classes/InvoiceFormattedData.cs | 24 +- .../Server/Classes/OrganisationLogoManager.cs | 60 +- .../SocialMediaImageDescription.cs | 9 +- .../Classes/SocialMedia/TwitterApiHelper.cs | 4 - .../Server/Classes/SubscriptionManager.cs | 17 +- products/ASC.CRM/Server/Classes/VoipEngine.cs | 71 +- .../CRMsSpaceUsageStatManager.cs | 64 +- .../Server/Configuration/ProductEntryPoint.cs | 58 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 18 +- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 16 +- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 69 +- .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 113 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 18 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 5 +- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 72 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 6 +- .../ASC.CRM/Server/Core/Dao/ManagerDao.cs | 74 - .../Server/Core/Dao/RelationshipEventDao.cs | 12 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 3695 +++++++++-------- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 314 +- .../ASC.CRM/Server/Core/Entities/Filter.cs | 10 +- .../ASC.CRM/Server/Core/Entities/Invoice.cs | 6 +- .../Server/Core/Search/CasesWrapper.cs | 13 +- .../Server/Core/Search/ContactsWrapper.cs | 21 +- .../Server/Core/Search/DealsWrapper.cs | 9 +- .../Server/Core/Search/EmailWrapper.cs | 26 +- .../Server/Core/Search/EventsWrapper.cs | 9 +- .../Server/Core/Search/FieldsWrapper.cs | 9 +- .../ASC.CRM/Server/Core/Search/InfoWrapper.cs | 28 +- .../Server/Core/Search/InvoicesWrapper.cs | 10 +- .../Server/Core/Search/TasksWrapper.cs | 13 +- .../Security/CRMSecurityObjectProvider.cs | 6 +- .../Server/Core/Security/CRMSecutiry.cs | 62 +- .../Core/Security/FileSecurityProvider.cs | 6 +- .../Server/HttpHandlers/FileHandler.ashx.cs | 27 +- .../HttpHandlers/FileUploaderHandler.cs | 12 +- .../Services/NotifyService/NotifyClient.cs | 194 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 42 +- .../Server/Utils/Import/CSV/CsvReader.cs | 32 - .../Server/Utils/Import/CSV/ImportBase.cs | 1 + .../Server/Utils/Import/CSV/ImportCases.cs | 12 +- .../Server/Utils/Import/CSV/ImportContacts.cs | 12 +- .../Utils/Import/CSV/ImportDataOperation.cs | 37 +- .../Server/Utils/Import/CSV/ImportDeals.cs | 28 +- .../Server/Utils/Import/CSV/ImportFromCSV.cs | 82 +- .../Server/Utils/Import/CSV/ImportTasks.cs | 26 +- products/ASC.CRM/Server/Utils/PdfCreator.cs | 49 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 147 +- 53 files changed, 2985 insertions(+), 2846 deletions(-) delete mode 100644 products/ASC.CRM/Server/Core/Dao/ManagerDao.cs delete mode 100644 products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 93a0d0a00d2..0d033deecfc 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -6,11 +6,32 @@ + + + + + - + + + + + + + + + + + + + + + + + @@ -155,7 +176,9 @@ + + diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs index 9f73567395a..920a27c17d9 100644 --- a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -25,12 +25,14 @@ using ASC.Common.Caching; +using ASC.Common.Logging; using ASC.Common.Threading.Workers; using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.Web.Core; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM.Configuration; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Drawing; @@ -70,33 +72,49 @@ public override int GetHashCode() } } - public static class ContactPhotoManager + public class ContactPhotoManager { + public ContactPhotoManager(Global global, + WebImageSupplier webImageSupplier, + IOptionsMonitor logger) + { + Global = global; + WebImageSupplier = webImageSupplier; + + Logger = logger.Get("ASC.CRM"); + } + + public ILog Logger { get; } + + public Global Global { get; } + + public WebImageSupplier WebImageSupplier { get; } + #region Members private const string PhotosBaseDirName = "photos"; private const string PhotosDefaultTmpDirName = "temp"; - private static readonly Dictionary> _photoCache = new Dictionary>(); + private readonly Dictionary> _photoCache = new Dictionary>(); - private static readonly WorkerQueue ResizeQueue = new WorkerQueue(2, TimeSpan.FromSeconds(30), 1, true); - private static readonly ICacheNotify cachyNotify; + private readonly WorkerQueue ResizeQueue = new WorkerQueue(2, TimeSpan.FromSeconds(30), 1, true); + private readonly ICacheNotify cachyNotify; - private static readonly Size _oldBigSize = new Size(145, 145); + private readonly Size _oldBigSize = new Size(145, 145); - private static readonly Size _bigSize = new Size(200, 200); - private static readonly Size _mediumSize = new Size(82, 82); - private static readonly Size _smallSize = new Size(40, 40); + private readonly Size _bigSize = new Size(200, 200); + private readonly Size _mediumSize = new Size(82, 82); + private readonly Size _smallSize = new Size(40, 40); - private static readonly object locker = new object(); + private readonly object locker = new object(); #endregion #region Cache and DataStore Methods - static ContactPhotoManager() + ContactPhotoManager() { - cachyNotify = AscCache.Notify; + cachyNotify = AscCache.Memory; cachyNotify.Subscribe>>( (item, action) => { @@ -115,7 +133,7 @@ static ContactPhotoManager() }); } - private static String FromCache(int contactID, Size photoSize) + private String FromCache(int contactID, Size photoSize) { lock (locker) { @@ -134,12 +152,12 @@ private static String FromCache(int contactID, Size photoSize) return String.Empty; } - private static void RemoveFromCache(int contactID) + private void RemoveFromCache(int contactID) { cachyNotify.Publish(CreateCacheItem(contactID, "", Size.Empty), CacheNotifyAction.Remove); } - private static void RemoveFromPrivateCache(int contactID) + private void RemoveFromPrivateCache(int contactID) { lock (locker) { @@ -147,12 +165,12 @@ private static void RemoveFromPrivateCache(int contactID) } } - private static void ToCache(int contactID, String photoUri, Size photoSize) + private void ToCache(int contactID, String photoUri, Size photoSize) { cachyNotify.Publish(CreateCacheItem(contactID, photoUri, photoSize), CacheNotifyAction.InsertOrUpdate); } - private static void ToPrivateCache(int contactID, String photoUri, Size photoSize) + private void ToPrivateCache(int contactID, String photoUri, Size photoSize) { lock (locker) { @@ -166,18 +184,18 @@ private static void ToPrivateCache(int contactID, String photoUri, Size photoSiz } } - private static KeyValuePair> CreateCacheItem(int contactID, String photoUri, Size photoSize) + private KeyValuePair> CreateCacheItem(int contactID, String photoUri, Size photoSize) { var sizeUriPair = new KeyValuePair(photoSize, photoUri); return new KeyValuePair>(contactID, sizeUriPair); } - private static String FromDataStore(int contactID, Size photoSize) + private String FromDataStore(int contactID, Size photoSize) { return FromDataStore(contactID, photoSize, false, null); } - private static String FromDataStore(int contactID, Size photoSize, Boolean isTmpDir, String tmpDirName) + private String FromDataStore(int contactID, Size photoSize, Boolean isTmpDir, String tmpDirName) { var directoryPath = !isTmpDir ? BuildFileDirectory(contactID) @@ -198,7 +216,7 @@ private static String FromDataStore(int contactID, Size photoSize, Boolean isTmp return filesURI[0].ToString(); } - private static String FromDataStoreRelative(int contactID, Size photoSize, Boolean isTmpDir, String tmpDirName) + private String FromDataStoreRelative(int contactID, Size photoSize, Boolean isTmpDir, String tmpDirName) { var directoryPath = !isTmpDir ? BuildFileDirectory(contactID) @@ -219,7 +237,7 @@ private static String FromDataStoreRelative(int contactID, Size photoSize, Boole return Path.Combine(directoryPath, filesPaths[0]); } - private static PhotoData FromDataStore(Size photoSize, String tmpDirName) + private PhotoData FromDataStore(Size photoSize, String tmpDirName) { var directoryPath = BuildFileTmpDirectory(tmpDirName); @@ -237,7 +255,7 @@ private static PhotoData FromDataStore(Size photoSize, String tmpDirName) #region Private Methods - private static String GetPhotoUri(int contactID, bool isCompany, Size photoSize) + private String GetPhotoUri(int contactID, bool isCompany, Size photoSize) { var photoUri = FromCache(contactID, photoSize); @@ -253,7 +271,7 @@ private static String GetPhotoUri(int contactID, bool isCompany, Size photoSize) return photoUri; } - private static String BuildFileDirectory(int contactID) + private String BuildFileDirectory(int contactID) { var s = contactID.ToString("000000"); @@ -262,22 +280,22 @@ private static String BuildFileDirectory(int contactID) s.Substring(4), "/"); } - private static String BuildFileTmpDirectory(int contactID) + private String BuildFileTmpDirectory(int contactID) { return String.Concat(BuildFileDirectory(contactID), PhotosDefaultTmpDirName, "/"); } - private static String BuildFileTmpDirectory(string tmpDirName) + private String BuildFileTmpDirectory(string tmpDirName) { return String.Concat(PhotosBaseDirName, "/", tmpDirName.TrimEnd('/'), "/"); } - private static String BuildFileName(int contactID, Size photoSize) + private String BuildFileName(int contactID, Size photoSize) { return String.Format("contact_{0}_{1}_{2}", contactID, photoSize.Width, photoSize.Height); } - private static String BuildFilePath(int contactID, Size photoSize, String imageExtension) + private String BuildFilePath(int contactID, Size photoSize, String imageExtension) { if (photoSize.IsEmpty || contactID == 0) throw new ArgumentException(); @@ -285,7 +303,7 @@ private static String BuildFilePath(int contactID, Size photoSize, String imageE return String.Concat(BuildFileDirectory(contactID), BuildFileName(contactID, photoSize), imageExtension); } - private static String BuildFileTmpPath(int contactID, Size photoSize, String imageExtension, String tmpDirName) + private String BuildFileTmpPath(int contactID, Size photoSize, String imageExtension, String tmpDirName) { if (photoSize.IsEmpty || (contactID == 0 && String.IsNullOrEmpty(tmpDirName))) throw new ArgumentException(); @@ -297,7 +315,7 @@ private static String BuildFileTmpPath(int contactID, Size photoSize, String ima BuildFileName(contactID, photoSize), imageExtension); } - private static void ExecResizeImage(ResizeWorkerItem resizeWorkerItem) + private void ExecResizeImage(ResizeWorkerItem resizeWorkerItem) { foreach (var fotoSize in resizeWorkerItem.RequireFotoSize) { @@ -338,7 +356,7 @@ private static void ExecResizeImage(ResizeWorkerItem resizeWorkerItem) } } - private static String GetDefaultPhoto(bool isCompany, Size photoSize) + private String GetDefaultPhoto(bool isCompany, Size photoSize) { int contactID; @@ -365,12 +383,12 @@ private static String GetDefaultPhoto(bool isCompany, Size photoSize) #region Delete Methods - public static void DeletePhoto(int contactID) + public void DeletePhoto(int contactID) { DeletePhoto(contactID, false, null, true); } - public static void DeletePhoto(int contactID, bool isTmpDir, string tmpDirName, bool recursive) + public void DeletePhoto(int contactID, bool isTmpDir, string tmpDirName, bool recursive) { if (contactID == 0) throw new ArgumentException(); @@ -405,7 +423,7 @@ public static void DeletePhoto(int contactID, bool isTmpDir, string tmpDirName, } } - public static void DeletePhoto(string tmpDirName) + public void DeletePhoto(string tmpDirName) { lock (locker) { @@ -422,7 +440,7 @@ public static void DeletePhoto(string tmpDirName) #endregion - public static void TryUploadPhotoFromTmp(int contactID, bool isNewContact, string tmpDirName) + public void TryUploadPhotoFromTmp(int contactID, bool isNewContact, string tmpDirName) { var directoryPath = BuildFileDirectory(contactID); var dataStore = Global.GetStore(); @@ -458,14 +476,15 @@ public static void TryUploadPhotoFromTmp(int contactID, bool isNewContact, strin } catch(Exception ex) { - LogManager.GetLogger("ASC.CRM").ErrorFormat("TryUploadPhotoFromTmp for contactID={0} failed witth error: {1}", contactID, ex); + Logger.ErrorFormat("TryUploadPhotoFromTmp for contactID={0} failed witth error: {1}", contactID, ex); + return; } } #region Get Photo Methods - public static String GetSmallSizePhoto(int contactID, bool isCompany) + public String GetSmallSizePhoto(int contactID, bool isCompany) { if (contactID <= 0) return GetDefaultPhoto(isCompany, _smallSize); @@ -473,7 +492,7 @@ public static String GetSmallSizePhoto(int contactID, bool isCompany) return GetPhotoUri(contactID, isCompany, _smallSize); } - public static String GetMediumSizePhoto(int contactID, bool isCompany) + public String GetMediumSizePhoto(int contactID, bool isCompany) { if (contactID <= 0) return GetDefaultPhoto(isCompany, _mediumSize); @@ -481,7 +500,7 @@ public static String GetMediumSizePhoto(int contactID, bool isCompany) return GetPhotoUri(contactID, isCompany, _mediumSize); } - public static String GetBigSizePhoto(int contactID, bool isCompany) + public String GetBigSizePhoto(int contactID, bool isCompany) { if (contactID <= 0) return GetDefaultPhoto(isCompany, _bigSize); @@ -491,12 +510,12 @@ public static String GetBigSizePhoto(int contactID, bool isCompany) #endregion - private static PhotoData ResizeToBigSize(byte[] imageData, string tmpDirName) + private PhotoData ResizeToBigSize(byte[] imageData, string tmpDirName) { return ResizeToBigSize(imageData, 0, true, tmpDirName); } - private static PhotoData ResizeToBigSize(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) + private PhotoData ResizeToBigSize(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) { var resizeWorkerItem = new ResizeWorkerItem { @@ -524,18 +543,18 @@ private static PhotoData ResizeToBigSize(byte[] imageData, int contactID, bool u } } - private static void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadOnly) + private void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadOnly) { ExecGenerateThumbnail(imageData, contactID, uploadOnly, null); } - private static void ExecGenerateThumbnail(byte[] imageData, string tmpDirName) + private void ExecGenerateThumbnail(byte[] imageData, string tmpDirName) { ExecGenerateThumbnail(imageData, 0, true, tmpDirName); } - private static void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) + private void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) { var resizeWorkerItem = new ResizeWorkerItem { @@ -553,7 +572,7 @@ private static void ExecGenerateThumbnail(byte[] imageData, int contactID, bool if (!ResizeQueue.IsStarted) ResizeQueue.Start(ExecResizeImage); } - private static byte[] ToByteArray(Stream inputStream, int streamLength) + private byte[] ToByteArray(Stream inputStream, int streamLength) { using (var br = new BinaryReader(inputStream)) { @@ -563,7 +582,7 @@ private static byte[] ToByteArray(Stream inputStream, int streamLength) #region UploadPhoto Methods - public static PhotoData UploadPhoto(String imageUrl, int contactID, bool uploadOnly, bool checkFormat = true) + public PhotoData UploadPhoto(String imageUrl, int contactID, bool uploadOnly, bool checkFormat = true) { var request = (HttpWebRequest)WebRequest.Create(imageUrl); using (var response = request.GetResponse()) @@ -576,13 +595,13 @@ public static PhotoData UploadPhoto(String imageUrl, int contactID, bool uploadO } } - public static PhotoData UploadPhoto(Stream inputStream, int contactID, bool uploadOnly, bool checkFormat = true) + public PhotoData UploadPhoto(Stream inputStream, int contactID, bool uploadOnly, bool checkFormat = true) { var imageData = Global.ToByteArray(inputStream); return UploadPhoto(imageData, contactID, uploadOnly, checkFormat); } - public static PhotoData UploadPhoto(byte[] imageData, int contactID, bool uploadOnly, bool checkFormat = true) + public PhotoData UploadPhoto(byte[] imageData, int contactID, bool uploadOnly, bool checkFormat = true) { if (contactID == 0) throw new ArgumentException(); @@ -598,7 +617,7 @@ public static PhotoData UploadPhoto(byte[] imageData, int contactID, bool upload } - public static PhotoData UploadPhotoToTemp(String imageUrl, String tmpDirName, bool checkFormat = true) + public PhotoData UploadPhotoToTemp(String imageUrl, String tmpDirName, bool checkFormat = true) { var request = (HttpWebRequest)WebRequest.Create(imageUrl); using (var response = request.GetResponse()) @@ -615,13 +634,13 @@ public static PhotoData UploadPhotoToTemp(String imageUrl, String tmpDirName, bo } } - public static PhotoData UploadPhotoToTemp(Stream inputStream, String tmpDirName, bool checkFormat = true) + public PhotoData UploadPhotoToTemp(Stream inputStream, String tmpDirName, bool checkFormat = true) { var imageData = Global.ToByteArray(inputStream); return UploadPhotoToTemp(imageData, tmpDirName, checkFormat); } - public static PhotoData UploadPhotoToTemp(byte[] imageData, String tmpDirName, bool checkFormat = true) + public PhotoData UploadPhotoToTemp(byte[] imageData, String tmpDirName, bool checkFormat = true) { if (checkFormat) CheckImgFormat(imageData); @@ -633,7 +652,7 @@ public static PhotoData UploadPhotoToTemp(byte[] imageData, String tmpDirName, b return ResizeToBigSize(imageData, tmpDirName); } - public static ImageFormat CheckImgFormat(byte[] imageData) + public ImageFormat CheckImgFormat(byte[] imageData) { using (var stream = new MemoryStream(imageData)) using (var img = new Bitmap(stream)) diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index f612c99a766..14b18ed1c92 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -56,7 +56,8 @@ public Global(StorageFactory storageFactory, CRMSecurity cRMSecurity, TenantManager tenantManager, SettingsManager settingsManager, - IConfiguration configuration + IConfiguration configuration, + PdfCreator pdfCreator ) { StorageFactory = storageFactory; @@ -67,8 +68,10 @@ IConfiguration configuration TenantID = tenantManager.GetCurrentTenant().TenantId; SettingsManager = settingsManager; Configuration = configuration; + PdfCreator = pdfCreator; } + public PdfCreator PdfCreator { get; } public IConfiguration Configuration { get; } public SettingsManager SettingsManager { get; } @@ -180,7 +183,7 @@ public void SaveDefaultCurrencySettings(CurrencyInfo currency) SettingsManager.Save(tenantSettings); } - public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) + public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) { var existingFile = invoice.GetInvoiceFile(factory); if (existingFile != null) @@ -191,8 +194,8 @@ public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.I { var newFile = PdfCreator.CreateFile(invoice, factory); invoice.FileID = Int32.Parse(newFile.ID.ToString()); - factory.InvoiceDao.UpdateInvoiceFileID(invoice.ID, invoice.FileID); - factory.RelationshipEventDao.AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + factory..GetInvoiceDao()..UpdateInvoiceFileID(invoice.ID, invoice.FileID); + factory.GetRelationshipEventDao.AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); return newFile; } } diff --git a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs index 195d33330da..697930ae702 100644 --- a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs +++ b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs @@ -43,12 +43,24 @@ namespace ASC.Web.CRM.Classes { public class ImportFromCSVManager { + public ImportFromCSVManager(Global global, + ImportFromCSV importFromCSV, + MessageService messageService) + { + Global = global; + ImportFromCSV = importFromCSV; + MessageService = messageService; + } + + public MessageService MessageService { get; } + public ImportFromCSV ImportFromCSV { get; } + public Global Global { get; } + public void StartImport(EntityType entityType, String CSVFileURI, String importSettingsJSON) { ImportFromCSV.Start(entityType, CSVFileURI, importSettingsJSON); - - var action = GetMessageAction(entityType); - MessageService.Send(HttpContext.Current.Request, action); + + MessageService.Send(GetMessageAction(entityType)); } public FileUploadResult ProcessUploadFake(string fileTemp, string importSettingsJSON) diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 85b1d1ed54f..8a86130e6b8 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -101,7 +101,7 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre #region Seller, LogoBase64, LogoSrcFormat - var invoiceSettings = daoFactory.InvoiceDao.GetSettings(); + var invoiceSettings = daoFactory.GetInvoiceDao().GetSettings(); if (!string.IsNullOrEmpty(invoiceSettings.CompanyName)) { @@ -184,7 +184,7 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre #region Customer - var customer = daoFactory.ContactDao.GetByID(invoice.ContactID); + var customer = daoFactory.GetContactDao().GetByID(invoice.ContactID); if (customer != null) { @@ -261,12 +261,12 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre foreach (var line in invoiceLines) { - var item = daoFactory.InvoiceItemDao.GetByID(line.InvoiceItemID); + var item = daoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); var tax1 = line.InvoiceTax1ID > 0 - ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax1ID) + ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) : null; var tax2 = line.InvoiceTax2ID > 0 - ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax2ID) + ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) : null; var subtotalValue = Math.Round(line.Quantity*line.Price, 2); @@ -326,7 +326,7 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre foreach (var invoiceTax in invoiceTaxes) { - var iTax = daoFactory.InvoiceTaxDao.GetByID(invoiceTax.Key); + var iTax = daoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); data.TableFooterRows.Add(new Tuple( string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); @@ -367,7 +367,7 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre #region Consignee - var consignee = daoFactory.ContactDao.GetByID(invoice.ConsigneeID); + var consignee = daoFactory.GetContactDao().GetByID(invoice.ConsigneeID); if (consignee != null) { @@ -376,7 +376,7 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre sb.Append(consignee.GetTitle()); var deliveryAddress = deliveryAddressID != 0 - ? daoFactory.ContactInfoDao.GetByID(deliveryAddressID) + ? daoFactory.GetContactInfoDao().GetByID(deliveryAddressID) : null; if (deliveryAddress != null && deliveryAddress.InfoType == ContactInfoType.Address && deliveryAddress.Category == (int) AddressCategory.Postal) @@ -596,12 +596,12 @@ private static InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, foreach (var line in invoiceLines) { - var item = daoFactory.InvoiceItemDao.GetByID(line.InvoiceItemID); + var item = daoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); var tax1 = line.InvoiceTax1ID > 0 - ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax1ID) + ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) : null; var tax2 = line.InvoiceTax2ID > 0 - ? daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax2ID) + ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) : null; var subtotalValue = Math.Round(line.Quantity*line.Price, 2); @@ -661,7 +661,7 @@ private static InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, foreach (var invoiceTax in invoiceTaxes) { - var iTax = daoFactory.InvoiceTaxDao.GetByID(invoiceTax.Key); + var iTax = daoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); data.TableFooterRows.Add(new Tuple( string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs index 253f2113b5f..0e76fb686bd 100644 --- a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -36,38 +36,54 @@ using ASC.Web.CRM.Configuration; using ASC.Web.CRM.Core; using Autofac; +using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Classes { - public static class OrganisationLogoManager + public class OrganisationLogoManager { + public OrganisationLogoManager(WebImageSupplier webImageSupplier, + Global global, + IOptionsMonitor logger) + { + WebImageSupplier = webImageSupplier; + Global = global; + Logger = logger.Get("ASC.CRM"); + } + + public ILog Logger { get; } + + public Global Global { get; } + + public WebImageSupplier WebImageSupplier { get; } + #region Members - public static readonly String OrganisationLogoBaseDirName = "organisationlogo"; - public static readonly String OrganisationLogoImgName = "logo"; + public readonly String OrganisationLogoBaseDirName = "organisationlogo"; - public static readonly String OrganisationLogoSrcFormat = "data:image/jpeg;base64,{0}"; + public readonly String OrganisationLogoImgName = "logo"; - public static readonly Size OrganisationLogoSize = new Size(200, 150); + public readonly String OrganisationLogoSrcFormat = "data:image/jpeg;base64,{0}"; - private static readonly Object _synchronizedObj = new Object(); + public readonly Size OrganisationLogoSize = new Size(200, 150); + + private readonly Object _synchronizedObj = new Object(); #endregion #region Private Methods - private static String BuildFileDirectory() + private String BuildFileDirectory() { return String.Concat(OrganisationLogoBaseDirName, "/"); } - private static String BuildFilePath(String imageExtension) + private String BuildFilePath(String imageExtension) { return String.Concat(BuildFileDirectory(), OrganisationLogoImgName, imageExtension); } - - private static String ExecResizeImage(byte[] imageData, Size fotoSize, IDataStore dataStore, String photoPath) + private String ExecResizeImage(byte[] imageData, Size fotoSize, IDataStore dataStore, String photoPath) { var data = imageData; using (var stream = new MemoryStream(data)) @@ -94,32 +110,30 @@ private static String ExecResizeImage(byte[] imageData, Size fotoSize, IDataStor } } } - - - + #endregion - public static String GetDefaultLogoUrl() + public String GetDefaultLogoUrl() { return WebImageSupplier.GetAbsoluteWebPath("org_logo_default.png", ProductEntryPoint.ID); } - public static String GetOrganisationLogoBase64(int logoID) + public String GetOrganisationLogoBase64(int logoID) { if (logoID <= 0) { return ""; } using (var scope = DIHelper.Resolve()) { - return scope.Resolve().InvoiceDao.GetOrganisationLogoBase64(logoID); + return scope.Resolve().GetInvoiceDao().GetOrganisationLogoBase64(logoID); } } - public static String GetOrganisationLogoSrc(int logoID) + public String GetOrganisationLogoSrc(int logoID) { var bytestring = GetOrganisationLogoBase64(logoID); return String.IsNullOrEmpty(bytestring) ? "" : String.Format(OrganisationLogoSrcFormat, bytestring); } - public static void DeletePhoto(bool recursive) + public void DeletePhoto(bool recursive) { var photoDirectory = BuildFileDirectory(); var store = Global.GetStore(); @@ -137,7 +151,7 @@ public static void DeletePhoto(bool recursive) } } - public static int TryUploadOrganisationLogoFromTmp(DaoFactory factory) + public int TryUploadOrganisationLogoFromTmp(DaoFactory factory) { var directoryPath = BuildFileDirectory(); var dataStore = Global.GetStore(); @@ -157,21 +171,23 @@ public static int TryUploadOrganisationLogoFromTmp(DaoFactory factory) bytes = Global.ToByteArray(photoTmpStream); } - var logoID = factory.InvoiceDao.SaveOrganisationLogo(bytes); + var logoID = factory.GetInvoiceDao().SaveOrganisationLogo(bytes); dataStore.DeleteFiles(directoryPath, "*", false); return logoID; } catch (Exception ex) { - LogManager.GetLogger("ASC.CRM").ErrorFormat("TryUploadOrganisationLogoFromTmp failed with error: {0}", ex); + Logger.ErrorFormat("TryUploadOrganisationLogoFromTmp failed with error: {0}", ex); + return 0; } } - public static String UploadLogo(byte[] imageData, ImageFormat imageFormat) + public String UploadLogo(byte[] imageData, ImageFormat imageFormat) { var photoPath = BuildFilePath("." + Global.GetImgFormatName(imageFormat)); + return ExecResizeImage(imageData, OrganisationLogoSize, Global.GetStore(), photoPath); } } diff --git a/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs index fff25668c32..45dec5e47c4 100644 --- a/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs +++ b/products/ASC.CRM/Server/Classes/SocialMedia/SocialMediaImageDescription.cs @@ -23,18 +23,11 @@ * */ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using ASC.Thrdparty; - namespace ASC.Web.CRM.Classes.SocialMedia { public class SocialMediaImageDescription { - public SocialNetworks SocialNetwork { get; set; } +// public SocialNetworks SocialNetwork { get; set; } public string ImageUrl { get; set; } public string Identity { get; set; } } diff --git a/products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs b/products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs index eb8cd192199..e6b07fd02b0 100644 --- a/products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs +++ b/products/ASC.CRM/Server/Classes/SocialMedia/TwitterApiHelper.cs @@ -23,10 +23,6 @@ * */ - -using ASC.FederatedLogin.LoginProviders; -using ASC.Thrdparty.Twitter; - namespace ASC.Web.CRM.Classes.SocialMedia { public static class TwitterApiHelper diff --git a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs index 039577bdeec..c2a5f1fbcdb 100644 --- a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs +++ b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs @@ -26,10 +26,12 @@ #region Import +using ASC.Core; using ASC.CRM.Resources; using ASC.Notify.Model; using ASC.Web.Core.Subscriptions; using ASC.Web.CRM.Services.NotifyService; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; @@ -37,10 +39,8 @@ namespace ASC.Web.CRM { - public class ProductSubscriptionManager : IProductSubscriptionManager { - private readonly Guid _setAccess = new Guid("{D4D58C55-D32E-41dc-9D22-D123AFAFC7E7}"); private readonly Guid _responsibleForTask = new Guid("{2479B115-EAEB-4d9a-86DA-51BD708DEFDC}"); private readonly Guid _responsibleForOpprotunity = new Guid("{73720A31-1981-480f-AB34-074E8BAEDBA9}"); @@ -48,7 +48,14 @@ public class ProductSubscriptionManager : IProductSubscriptionManager private readonly Guid _exportCompleted = new Guid("{88D3DC5E-3E46-46a1-9FEF-6B8FFF020BA4}"); private readonly Guid _importCompleted = new Guid("{6A717AAD-16AE-4713-A782-B887766BEB9F}"); private readonly Guid _createNewContact = new Guid("{ADAC1E70-4163-41c1-8968-67A44E4D24E7}"); - + + public ProductSubscriptionManager(CoreBaseSettings coreBaseSettings) + { + CoreBaseSettings = coreBaseSettings; + } + + public CoreBaseSettings CoreBaseSettings { get; } + public List GetSubscriptionObjects(Guid subItem) { return new List(); @@ -94,7 +101,7 @@ public List GetSubscriptionTypes() { ID = _exportCompleted, Name = CRMCommonResource.SubscriptionType_ExportCompleted, - NotifyAction = CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, + NotifyAction = CoreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, Single = true, CanSubscribe = true }, @@ -102,7 +109,7 @@ public List GetSubscriptionTypes() { ID = _importCompleted, Name = CRMCommonResource.SubscriptionType_ImportCompleted, - NotifyAction = CoreContext.Configuration.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, + NotifyAction = CoreBaseSettings.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, Single = true, CanSubscribe = true }, diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index 001b142dbde..7d90891a6c5 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -24,6 +24,7 @@ */ +using ASC.Common.Logging; using ASC.Common.Threading.Workers; using ASC.Core; using ASC.Core.Tenants; @@ -36,6 +37,7 @@ using ASC.VoipService.Dao; using ASC.Web.CRM.Core; using Autofac; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; @@ -44,18 +46,44 @@ namespace ASC.Web.CRM.Classes { public class VoipEngine { - private static readonly WorkerQueue Queue = new WorkerQueue(1, TimeSpan.FromMinutes(30)); - private static readonly object Locker = new object(); + private readonly WorkerQueue Queue = new WorkerQueue(1, TimeSpan.FromMinutes(30)); + private readonly object Locker = new object(); private readonly DaoFactory daoFactory; - public VoipEngine(DaoFactory daoFactory) + public VoipEngine(DaoFactory daoFactory, + CRMSecurity cRMSecurity, + TenantUtil tenantUtil, + SecurityContext securityContext, + IOptionsMonitor logger, + TenantManager tenantManager, + VoipDao voipDao) { this.daoFactory = daoFactory; + CRMSecurity = cRMSecurity; + TenantUtil = tenantUtil; + SecurityContext = securityContext; + Logger = logger.Get("ASC.CRM"); + TenantManager = tenantManager; + VoipDao = voipDao; } + public VoipDao VoipDao { get; } + + public TenantManager TenantManager { get; } + + public ILog Logger { get; } + + public int TenantId { get; } + + public SecurityContext SecurityContext { get; } + + public TenantUtil TenantUtil { get; } + + public CRMSecurity CRMSecurity { get; } + public VoipCall SaveOrUpdateCall(VoipCall callHistory) { - var dao = daoFactory.VoipDao; + var dao = daoFactory.GetVoipDao(); var call = dao.GetCall(callHistory.Id) ?? callHistory; if (string.IsNullOrEmpty(call.ParentID)) @@ -121,9 +149,9 @@ public VoipCall SaveOrUpdateCall(VoipCall callHistory) return dao.SaveOrUpdateCall(call); } - public static void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) + public void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) { - var listItemDao = daoFactory.ListItemDao; + var listItemDao = daoFactory.GetListItemDao(); if (call == null || call.ContactId == 0) return; @@ -133,7 +161,7 @@ public static void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) category = new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png"); category.ID = listItemDao.CreateItem(ListType.HistoryCategory, category); } - var contact = daoFactory.ContactDao.GetByID(call.ContactId); + var contact = daoFactory.GetContactDao().GetByID(call.ContactId); if (contact != null && CRMSecurity.CanAccessTo(contact)) { var note = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered @@ -152,7 +180,7 @@ public static void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) CreateBy = SecurityContext.CurrentAccount.ID }; - daoFactory.RelationshipEventDao.CreateItem(relationshipEvent); + daoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent); } } @@ -165,13 +193,13 @@ public Contact GetContact(VoipCall call) var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; - var newContactIds = daoFactory.ContactDao.GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); + var newContactIds = daoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); foreach (var newContactId in newContactIds) { if (newContactId != 0) { - var existContact = daoFactory.ContactDao.GetByID(newContactId); + var existContact = daoFactory.GetContactDao().GetByID(newContactId); if (CRMSecurity.CanAccessTo(existContact)) { call.ContactId = newContactId; @@ -185,7 +213,7 @@ public Contact GetContact(VoipCall call) public List GetContacts(string contactPhone, DaoFactory daoFactory) { - var dao = daoFactory.ContactDao; + var dao = daoFactory.GetContactDao(); var ids = dao.GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); return ids.Select(r => dao.GetByID(r)).ToList(); } @@ -199,20 +227,21 @@ public void SaveAdditionalInfo(string callId) Queue.Start(SaveAdditionalInfoAction); } - Queue.Add(new QueueItem {CallID = callId, TenantID = CoreContext.TenantManager.GetCurrentTenant().TenantId}); + Queue.Add(new QueueItem {CallID = callId, TenantID = TenantId }); } } - private static void SaveAdditionalInfoAction(QueueItem queueItem) + private void SaveAdditionalInfoAction(QueueItem queueItem) { try { - CoreContext.TenantManager.SetCurrentTenant(queueItem.TenantID); + TenantManager.SetCurrentTenant(queueItem.TenantID); + using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); var voipEngine = new VoipEngine(daoFactory); - var dao = daoFactory.VoipDao; + var dao = daoFactory.GetVoipDao(); var call = dao.GetCall(queueItem.CallID); @@ -231,7 +260,7 @@ private static void SaveAdditionalInfoAction(QueueItem queueItem) if (!string.IsNullOrEmpty(call.VoipRecord.Id)) { - call.VoipRecord = VoipDao.GetProvider().GetRecord(call.Id, call.VoipRecord.Id); + call.VoipRecord = VoipDao.GetProvider().GetRecord((string)call.Id, (string)call.VoipRecord.Id); voipEngine.SaveOrUpdateCall(call); } @@ -241,11 +270,11 @@ private static void SaveAdditionalInfoAction(QueueItem queueItem) } catch (Exception ex) { - LogManager.GetLogger("ASC").ErrorFormat("SaveAdditionalInfo {0}, {1}", ex, ex.StackTrace); + Logger.ErrorFormat("SaveAdditionalInfo {0}, {1}", ex, ex.StackTrace); } } - private static void GetPriceAndDuration(VoipCall call) + private void GetPriceAndDuration(VoipCall call) { var provider = VoipDao.GetProvider(); var twilioCall = provider.GetCall(call.Id); @@ -257,7 +286,7 @@ public void AnswerCall(VoipCall call) { call.AnsweredBy = SecurityContext.CurrentAccount.ID; call.Status = VoipCallStatus.Answered; - daoFactory.VoipDao.SaveOrUpdateCall(call); + daoFactory.GetVoipDao().SaveOrUpdateCall(call); } public Contact CreateContact(string contactPhone) @@ -271,9 +300,9 @@ public Contact CreateContact(string contactPhone) CreateOn = DateTime.UtcNow }; - contact.ID = daoFactory.ContactDao.SaveContact(contact); + contact.ID = daoFactory.GetContactDao().SaveContact(contact); - daoFactory.ContactInfoDao + daoFactory.GetContactInfoDao() .Save(new ContactInfo { ContactID = contact.ID, diff --git a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs index 8925f5a093d..2cba3ff71b3 100644 --- a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs +++ b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs @@ -25,8 +25,13 @@ using ASC.Common.Web; +using ASC.Core; +using ASC.Core.Common.EF; using ASC.CRM.Resources; +using ASC.Files.Core; +using ASC.Files.Core.EF; using ASC.Web.Core; +using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; @@ -34,30 +39,45 @@ namespace ASC.Web.CRM.Configuration { public class CRMSpaceUsageStatManager : SpaceUsageStatManager - { + { + public CRMSpaceUsageStatManager(DbContextManager filesDbContext, + PathProvider pathProvider, + TenantManager tenantManager) + { + PathProvider = pathProvider; + FilesDbContext = filesDbContext.Value; + TenantId = tenantManager.CurrentTenant.TenantId; + } + + public int TenantId { get; } + public FilesDbContext FilesDbContext { get; } + public PathProvider PathProvider { get; } + public override List GetStatData() { - using (var filedb = new DbManager(FileConstant.DatabaseId)) - { - var q = new SqlQuery("files_file f") - .Select("b.right_node") - .SelectSum("f.content_length") - .InnerJoin("files_folder_tree t", Exp.EqColumns("f.folder_id", "t.folder_id")) - .InnerJoin("files_bunch_objects b", Exp.EqColumns("t.parent_id", "b.left_node")) - .Where("b.tenant_id", TenantProvider.CurrentTenantID) - .Where(Exp.Like("b.right_node", "crm/crm_common/", SqlLike.StartWith)) - .GroupBy(1); - - return filedb.ExecuteList(q) - .Select(r => new UsageSpaceStatItem - { - - Name = CRMCommonResource.WholeCRMModule, - SpaceUsage = Convert.ToInt64(r[1]), - Url = VirtualPathUtility.ToAbsolute(PathProvider.StartURL()) - }) - .ToList(); - } + var spaceUsage = FilesDbContext.Files.Join(FilesDbContext.Tree, + x => x.FolderId, + y => y.FolderId, + (x, y) => new { x, y } + ) + .Join(FilesDbContext.BunchObjects, + x => x.y.ParentId, + y => Convert.ToInt32(y.LeftNode), + (x, y) => new { x, y }) + .Where(x => x.y.TenantId == TenantId && + Microsoft.EntityFrameworkCore.EF.Functions.Like(x.y.RightNode, "crm/crm_common/%")) + .Sum(x => x.x.x.ContentLength); + + return new List + {new UsageSpaceStatItem + { + + Name = CRMCommonResource.WholeCRMModule, + SpaceUsage = spaceUsage, + Url = VirtualPathUtility.ToAbsolute(PathProvider.StartURL()) + } + + }; } } } diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index 0367ba3679f..9b146a571a0 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -137,8 +137,8 @@ public override void Init() IconFileName = "product_logo.png", LargeIconFileName = "product_logolarge.svg", DefaultSortOrder = 30, - SubscriptionManager = new ProductSubscriptionManager(), - SpaceUsageStatManager = new CRMSpaceUsageStatManager(), + // SubscriptionManager = new ProductSubscriptionManager(), + // SpaceUsageStatManager = new CRMSpaceUsageStatManager(), AdminOpportunities = () => CRMCommonResource.ProductAdminOpportunities.Split('|').ToList(), UserOpportunities = () => CRMCommonResource.ProductUserOpportunities.Split('|').ToList(), }; @@ -174,7 +174,7 @@ public void ConfigurePortal() { var daoFactory = scope.Resolve(); // Task Category - var listItemDao = daoFactory.ListItemDao; + var listItemDao = daoFactory.GetListItemDao(); listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Call, "task_category_call.png")); listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Deal, "task_category_deal.png")); listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Demo, "task_category_demo.png")); @@ -189,7 +189,7 @@ public void ConfigurePortal() listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_ThankYou, "task_category_thank_you.png")); // Deal Milestone New - var milestoneDao = daoFactory.DealMilestoneDao; + var milestoneDao = daoFactory.GetDealMilestoneDao(); milestoneDao.Create(new DealMilestone { @@ -287,10 +287,10 @@ public void ConfigurePortal() listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png")); listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Meeting, "event_category_meeting.png")); // Tags - daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Lead, true); - daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Customer, true); - daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Supplier, true); - daoFactory.TagDao.AddTag(EntityType.Contact, CRMContactResource.Staff, true); + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Lead, true); + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Customer, true); + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Supplier, true); + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Staff, true); tenantSettings.WebFormKey = Guid.NewGuid(); tenantSettings.IsConfiguredPortal = true; @@ -342,27 +342,27 @@ public void ConfigurePortal() } } - public override void Shutdown() - { - if (registered) - { - NotifyClient.Instance.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask); + //public override void Shutdown() + //{ + // if (registered) + // { + // NotifyClient.Instance.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask); - } - } - - public static void RegisterSendMethods() - { - lock (Locker) - { - if (!registered) - { - registered = true; - - NotifyClient.Instance.Client.RegisterSendMethod(NotifyClient.SendAutoReminderAboutTask, "0 * * ? * *"); - - } - } - } + // } + //} + + //public static void RegisterSendMethods() + //{ + // lock (Locker) + // { + // if (!registered) + // { + // registered = true; + + // NotifyClient.Instance.Client.RegisterSendMethod(NotifyClient.SendAutoReminderAboutTask, "0 * * ? * *"); + + // } + // } + //} } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 7f28b834129..c442ca4bb53 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -60,7 +60,8 @@ public CachedCasesDao(DbContextManager dbContextManager, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, IOptionsMonitor logger, - IHttpContextAccessor httpContextAccessor) + IHttpContextAccessor httpContextAccessor, + BundleSearch bundleSearch) : base(dbContextManager, tenantManager, @@ -69,7 +70,8 @@ public CachedCasesDao(DbContextManager dbContextManager, tenantUtil, filesIntegration, authorizationManager, - logger) + logger, + bundleSearch) { _casesCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_cases"); @@ -116,7 +118,8 @@ public CasesDao( TenantUtil tenantUtil, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, - IOptionsMonitor logger + IOptionsMonitor logger, + BundleSearch bundleSearch ) : base(dbContextManager, tenantManager, @@ -127,8 +130,11 @@ IOptionsMonitor logger TenantUtil = tenantUtil; FilesIntegration = filesIntegration; AuthorizationManager = authorizationManager; + BundleSearch = bundleSearch; } + public BundleSearch BundleSearch { get; } + public AuthorizationManager AuthorizationManager { get; } public FilesIntegration FilesIntegration { get; } @@ -339,13 +345,13 @@ private void DeleteBatchCasesExecute(List caseses) { var casesID = caseses.Select(x => x.ID).ToArray(); - var tagdao = FilesIntegration.TagDao(); + var tagdao = FilesIntegration.DaoFactory.GetTagDao(); var tagNames = Query(CRMDbContext.RelationshipEvent) .Where(x => x.HaveFiles && casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case) .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); - var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); + var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => Convert.ToInt32(t.EntryId)).ToArray(); using var tx = CRMDbContext.Database.BeginTransaction(); @@ -373,7 +379,7 @@ private void DeleteBatchCasesExecute(List caseses) if (0 < tagNames.Length) { - var filedao = FilesIntegration.GetFileDao(); + var filedao = FilesIntegration.DaoFactory.GetFileDao(); foreach (var filesID in filesIDs) { diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index c808a0701d4..402fa04c44e 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -27,7 +27,6 @@ using ASC.Collections; using ASC.Common.Logging; using ASC.Core; -using ASC.Core.Caching; using ASC.Core.Common.EF; using ASC.Core.Tenants; using ASC.CRM.Core.EF; @@ -44,7 +43,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Linq.Expressions; using System.Text.RegularExpressions; using OrderBy = ASC.CRM.Core.Entities.OrderBy; @@ -66,7 +64,8 @@ public CachedContactDao( FactoryIndexer factoryIndexerContactsWrapper, FactoryIndexer factoryIndexerEmailWrapper, IOptionsMonitor logger, - DbContextManager coreDbContext) : + DbContextManager coreDbContext, + BundleSearch bundleSearch) : base(dbContextManager, tenantManager, securityContext, @@ -77,7 +76,8 @@ public CachedContactDao( factoryIndexerContactsWrapper, factoryIndexerEmailWrapper, logger, - coreDbContext) + coreDbContext, + bundleSearch) { _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact"); } @@ -138,7 +138,8 @@ public ContactDao( FactoryIndexer factoryIndexerContactsWrapper, FactoryIndexer factoryIndexerEmailWrapper, IOptionsMonitor logger, - DbContextManager coreDbContext + DbContextManager coreDbContext, + BundleSearch bundleSearch ) : base(dbContextManager, tenantManager, @@ -152,10 +153,11 @@ DbContextManager coreDbContext FactoryIndexerContactsWrapper = factoryIndexerContactsWrapper; FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; CoreDbContext = coreDbContext.Value; + BundleSearch = bundleSearch; } + public BundleSearch BundleSearch { get; } public CoreDbContext CoreDbContext { get; } - public FactoryIndexer FactoryIndexerEmailWrapper { get; } public FactoryIndexer FactoryIndexerContactsWrapper { get; } public FilesIntegration FilesIntegration { get; } @@ -471,7 +473,7 @@ public List SearchContactsByEmail(string searchText, int maxCount) } public List GetContacts(String searchText, - IEnumerable tags, + IEnumerable tags, int contactStage, int contactType, ContactListViewType contactListView, diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 5408d7a96aa..09b37ac7881 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -34,6 +34,7 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using System; using System.Collections.Generic; @@ -50,14 +51,21 @@ public CachedContactInfo( TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, + IOptionsMonitor logger, + FactoryIndexer factoryIndexerEmailWrapper, + FactoryIndexer factoryIndexerInfoWrapper, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger) + IServiceProvider serviceProvider + ) : base( dbContextManager, tenantManager, securityContext, tenantUtil, - logger) + logger, + factoryIndexerEmailWrapper, + factoryIndexerInfoWrapper, + serviceProvider) { _contactInfoCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact_info"); } @@ -108,7 +116,10 @@ public ContactInfoDao( TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - IOptionsMonitor logger + IOptionsMonitor logger, + FactoryIndexer factoryIndexerEmailWrapper, + FactoryIndexer factoryIndexerInfoWrapper, + IServiceProvider serviceProvider ) : base(dbContextManager, tenantManager, @@ -116,12 +127,17 @@ IOptionsMonitor logger logger) { TenantUtil = tenantUtil; + ServiceProvider = serviceProvider; + + FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; + FactoryIndexerInfoWrapper = factoryIndexerInfoWrapper; } - TenantUtil TenantUtil { get; } - FactoryIndexer emailWrapperIndexer; - FactoryIndexer infoWrapperIndexer; - + public IServiceProvider ServiceProvider { get; } + public TenantUtil TenantUtil { get; } + public FactoryIndexer FactoryIndexerEmailWrapper { get; } + public FactoryIndexer FactoryIndexerInfoWrapper { get; } + public virtual ContactInfo GetByID(int id) { return ToContactInfo(CRMDbContext.ContactsInfo.SingleOrDefault(x => x.Id == id)); @@ -136,8 +152,8 @@ public virtual void Delete(int id) CRMDbContext.ContactsInfo.Remove(itemToDelete); CRMDbContext.SaveChanges(); - - infoWrapperIndexer.DeleteAsync(r => r.Where(a => a.Id, id)); + + FactoryIndexerEmailWrapper.DeleteAsync(r => r.Where(a => a.Id, id)); } @@ -149,16 +165,18 @@ public virtual void DeleteByContact(int contactID) .Where(x => x.ContactId == contactID)); CRMDbContext.SaveChanges(); - - infoWrapperIndexer.DeleteAsync(r => r.Where(a => a.ContactId, contactID)); + + FactoryIndexerInfoWrapper.DeleteAsync(r => r.Where(a => a.ContactId, contactID)); var infos = GetList(contactID, ContactInfoType.Email, null, null); - - emailWrapperIndexer.Update(new EmailWrapper { Id = contactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); + + FactoryIndexerEmailWrapper.Update(new EmailWrapper { Id = contactID, + EmailInfoWrapper = infos.Select(r => EmailInfoWrapper.FromContactInfo(TenantID, r)).ToList() }, + UpdateAction.Replace, r => r.EmailInfoWrapper); } - public virtual int Update(ContactInfo contactInfo) + public virtual int Update(ContactInfo contactInfo) { var result = UpdateInDb(contactInfo); @@ -166,10 +184,10 @@ public virtual int Update(ContactInfo contactInfo) { var infos = GetList(contactInfo.ContactID, ContactInfoType.Email, null, null); - emailWrapperIndexer.Update(new EmailWrapper { Id = contactInfo.ContactID, EmailInfoWrapper = infos.Select(r => (EmailInfoWrapper)r).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); + FactoryIndexerEmailWrapper.Update(new EmailWrapper { Id = contactInfo.ContactID, EmailInfoWrapper = infos.Select(r => EmailInfoWrapper.FromContactInfo(TenantID, r)).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); } - - infoWrapperIndexer.UpdateAsync(contactInfo); + + FactoryIndexerInfoWrapper.UpdateAsync(InfoWrapper.FromCompany(ServiceProvider, contactInfo)); return result; } @@ -205,18 +223,18 @@ public int Save(ContactInfo contactInfo) var id = SaveInDb(contactInfo); contactInfo.ID = id; - - infoWrapperIndexer.IndexAsync(contactInfo); + + FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.FromCompany(ServiceProvider, contactInfo)); if (contactInfo.InfoType == ContactInfoType.Email) { - emailWrapperIndexer.Index(new EmailWrapper + FactoryIndexerEmailWrapper.Index(new EmailWrapper { Id = contactInfo.ContactID, TenantId = TenantID, EmailInfoWrapper = new List { - contactInfo + EmailInfoWrapper.FromContactInfo(TenantID, contactInfo) } }); } @@ -303,11 +321,12 @@ public int[] UpdateList(List items, Contact contact = null) if (contact != null) { - emailWrapperIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + + FactoryIndexerEmailWrapper.IndexAsync(EmailWrapper.GetEmailWrapper(TenantID, contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) { - infoWrapperIndexer.IndexAsync(item); + FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.FromCompany(ServiceProvider, item)); } } @@ -333,11 +352,11 @@ public int[] SaveList(List items, Contact contact = null) if (contact != null) { - emailWrapperIndexer.IndexAsync(EmailWrapper.ToEmailWrapper(contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + FactoryIndexerEmailWrapper.IndexAsync(EmailWrapper.GetEmailWrapper(TenantID, contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) { - infoWrapperIndexer.IndexAsync(item); + FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.FromCompany(ServiceProvider, item)); } } diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 625f99406ce..b92a10d7533 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -23,141 +23,136 @@ * */ - +using Microsoft.Extensions.DependencyInjection; using ASC.VoipService.Dao; -using Autofac; +using System; namespace ASC.CRM.Core.Dao { public class DaoFactory { - private readonly TypedParameter tenant; - public ILifetimeScope Container { get; set; } - - public DaoFactory(int tenantID) + public DaoFactory(IServiceProvider serviceProvider) { - tenant = GetParameter(tenantID); + ServiceProvider = serviceProvider; } - public TaskDao TaskDao + public IServiceProvider ServiceProvider { get; } + + public TaskDao GetTaskDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public ListItemDao CachedListItem + public ListItemDao GetCachedListItem() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public ContactDao ContactDao + public ContactDao GetContactDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public CustomFieldDao CustomFieldDao + public CustomFieldDao GetCustomFieldDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public DealDao DealDao + public DealDao GetDealDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public DealMilestoneDao DealMilestoneDao + public DealMilestoneDao GetDealMilestoneDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); + } - public ListItemDao ListItemDao + public ListItemDao GetListItemDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public TagDao TagDao + public TagDao GetTagDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public SearchDao SearchDao + public SearchDao GetSearchDao() { - get { return Container.Resolve(tenant, GetParameter(this)); } + return ServiceProvider.GetService(); } - public RelationshipEventDao RelationshipEventDao + public RelationshipEventDao GetRelationshipEventDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public FileDao FileDao + public FileDao GetFileDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public CasesDao CasesDao + public CasesDao GetCasesDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public TaskTemplateContainerDao TaskTemplateContainerDao + public TaskTemplateContainerDao GetTaskTemplateContainerDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public TaskTemplateDao TaskTemplateDao + public TaskTemplateDao GetTaskTemplateDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - //public ReportDao ReportDao - //{ - // get { return Container.Resolve(tenant); } - //} - - public CurrencyRateDao CurrencyRateDao + public ReportDao GetReportDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public CurrencyInfoDao CurrencyInfoDao + public CurrencyRateDao GetCurrencyRateDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public ContactInfoDao ContactInfoDao + public CurrencyInfoDao GetCurrencyInfoDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); + } - public InvoiceDao InvoiceDao + public ContactInfoDao GetContactInfoDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public InvoiceItemDao InvoiceItemDao + public InvoiceDao GetInvoiceDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public InvoiceTaxDao InvoiceTaxDao + public InvoiceItemDao GetInvoiceItemDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public InvoiceLineDao InvoiceLineDao + public InvoiceTaxDao GetInvoiceTaxDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - public VoipDao VoipDao + public InvoiceLineDao GetInvoiceLineDao() { - get { return Container.Resolve(tenant); } + return ServiceProvider.GetService(); } - private TypedParameter GetParameter(T data) + public VoipDao GetVoipDao() { - return new TypedParameter(typeof(T), data); + return ServiceProvider.GetService(); } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 3f9d244b4bc..dcf4119fd18 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -190,7 +190,7 @@ public virtual int CreateNewDeal(Deal deal) deal.ID = result; - FactoryIndexer.IndexAsync(deal); + FactoryIndexer.IndexAsync(DealsWrapper.FromDeal(TenantID, deal)); return result; } @@ -243,9 +243,9 @@ public virtual int[] SaveDealList(List items) tx.Commit(); - foreach (var item in items) + foreach (var deal in items) { - FactoryIndexer.IndexAsync(item); + FactoryIndexer.IndexAsync(DealsWrapper.FromDeal(TenantID, deal)); } return result; @@ -284,7 +284,7 @@ public virtual void EditDeal(Deal deal) CRMDbContext.Update(itemToUpdate); CRMDbContext.SaveChanges(); - FactoryIndexer.IndexAsync(deal); + FactoryIndexer.IndexAsync(DealsWrapper.FromDeal(TenantID, deal)); } @@ -397,7 +397,7 @@ private IQueryable GetDbDealByFilters( sqlQuery = sqlQuery.Where(x => x.x.ResponsibleId == responsibleID); } - + if (ids.Count > 0) { if (exceptIDs.Count > 0) @@ -414,7 +414,7 @@ private IQueryable GetDbDealByFilters( } if ((stageType != null) || (fromDate != DateTime.MinValue && toDate != DateTime.MinValue)) - { + { if (stageType != null) sqlQuery = sqlQuery.Where(x => x.y.Status == stageType.Value); @@ -483,7 +483,7 @@ private IQueryable GetDbDealByFilters( .ThenBy(x => x.x.Title); } - + break; } @@ -568,7 +568,7 @@ public int GetDealsCount(String searchText, if (sqlQuery == null) { result = 0; - } + } else { result = sqlQuery.Count(); @@ -797,7 +797,7 @@ public virtual Deal DeleteDeal(int dealID) DeleteBatchDealsExecute(new List() { deal }); - FactoryIndexer.DeleteAsync(deal); + FactoryIndexer.DeleteAsync(DealsWrapper.FromDeal(TenantID, deal)); return deal; } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index e434740df11..f5ff455489c 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -131,6 +131,7 @@ public InvoiceDao( { FactoryIndexer = factoryIndexer; SettingsManager = settingsManager; + InvoiceSetting = invoiceSetting; } public InvoiceSetting InvoiceSetting { get; } @@ -519,7 +520,7 @@ public virtual int SaveOrUpdateInvoice(Invoice invoice) var result = SaveOrUpdateInvoiceInDb(invoice); - FactoryIndexer.IndexAsync(invoice); + FactoryIndexer.IndexAsync(InvoicesWrapper.FromInvoice(TenantID, invoice)); return result; } @@ -781,7 +782,7 @@ private void DeleteBatchInvoicesExecute(List invoices) tx.Commit(); - invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(invoice)); + invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(InvoicesWrapper.FromInvoice(TenantID, invoice))); } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 7a42196aaad..cd9045ef723 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -48,10 +48,12 @@ public class CachedInvoiceLineDao : InvoiceLineDao public CachedInvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IHttpContextAccessor httpContextAccessor) + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger) : base(dbContextManager, - tenantManager, - securityContext) + tenantManager, + securityContext, + logger) { _invoiceLineCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_line"); } @@ -172,40 +174,50 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) { invoiceLine.Description = String.Empty; } - - if (Db.ExecuteScalar(Query("crm_invoice_line").SelectCount().Where(Exp.Eq("id", invoiceLine.ID))) == 0) + if (Query(CRMDbContext.InvoiceLine).Where(x => x.Id == invoiceLine.ID).Any()) { - invoiceLine.ID = Db.ExecuteScalar( - Insert("crm_invoice_line") - .InColumnValue("id", 0) - .InColumnValue("invoice_id", invoiceLine.InvoiceID) - .InColumnValue("invoice_item_id", invoiceLine.InvoiceItemID) - .InColumnValue("invoice_tax1_id", invoiceLine.InvoiceTax1ID) - .InColumnValue("invoice_tax2_id", invoiceLine.InvoiceTax2ID) - .InColumnValue("sort_order", invoiceLine.SortOrder) - .InColumnValue("description", invoiceLine.Description) - .InColumnValue("quantity", invoiceLine.Quantity) - .InColumnValue("price", invoiceLine.Price) - .InColumnValue("discount", invoiceLine.Discount) - .Identity(1, 0, true)); + + var itemToInsert = new DbInvoiceLine + { + InvoiceId = invoiceLine.InvoiceItemID, + InvoiceItemId = invoiceLine.InvoiceItemID, + InvoiceTax1Id = invoiceLine.InvoiceTax1ID, + InvoiceTax2Id = invoiceLine.InvoiceTax2ID, + SortOrder = invoiceLine.SortOrder, + Description = invoiceLine.Description, + Quantity = invoiceLine.Quantity, + Price = invoiceLine.Price, + Discount = invoiceLine.Discount, + TenantId = TenantID + }; + + CRMDbContext.Add(itemToInsert); + CRMDbContext.SaveChanges(); + + invoiceLine.ID = itemToInsert.Id; } else { + var itemToUpdate = Query(CRMDbContext.InvoiceLine).Single(x => x.Id == invoiceLine.ID); + + itemToUpdate.InvoiceId = invoiceLine.InvoiceID; + itemToUpdate.InvoiceItemId = invoiceLine.InvoiceItemID; + itemToUpdate.InvoiceTax1Id = invoiceLine.InvoiceTax1ID; + itemToUpdate.InvoiceTax2Id = invoiceLine.InvoiceTax2ID; + itemToUpdate.SortOrder = invoiceLine.SortOrder; + itemToUpdate.Description = invoiceLine.Description; + itemToUpdate.Quantity = invoiceLine.Quantity; + itemToUpdate.Price = invoiceLine.Price; + itemToUpdate.Discount = invoiceLine.Discount; + + CRMDbContext.Update(itemToUpdate); + + CRMDbContext.SaveChanges(); + - Db.ExecuteNonQuery( - Update("crm_invoice_line") - .Set("invoice_id", invoiceLine.InvoiceID) - .Set("invoice_item_id", invoiceLine.InvoiceItemID) - .Set("invoice_tax1_id", invoiceLine.InvoiceTax1ID) - .Set("invoice_tax2_id", invoiceLine.InvoiceTax2ID) - .Set("sort_order", invoiceLine.SortOrder) - .Set("description", invoiceLine.Description) - .Set("quantity", invoiceLine.Quantity) - .Set("price", invoiceLine.Price) - .Set("discount", invoiceLine.Discount) - .Where(Exp.Eq("id", invoiceLine.ID))); } + return invoiceLine.ID; } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 2ad81350b15..aa10d9be6c8 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -47,11 +47,13 @@ public class CachedInvoiceTaxDao : InvoiceTaxDao public CachedInvoiceTaxDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IHttpContextAccessor httpContextAccessor + IHttpContextAccessor httpContextAccessor, + IOptionsMonitor logger ) : base(dbContextManager, tenantManager, - securityContext) + securityContext, + logger) { _invoiceTaxCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_tax"); diff --git a/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs b/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs deleted file mode 100644 index 1699f71a972..00000000000 --- a/products/ASC.CRM/Server/Core/Dao/ManagerDao.cs +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -#region Import - -using ASC.Core.Users; -using System; -using System.Collections.Generic; -using System.Linq; - -#endregion - -namespace ASC.CRM.Core.Dao -{ - - public class ManagerDao : AbstractDao - { - public ManagerDao(int tenantID, String storageKey) - : base(tenantID, storageKey) - { - - - } - - public void Add(Guid managerID) - { - DbManager.ExecuteNonQuery(Insert("crm_manager").InColumnValue("id", managerID)); - - } - - public void Remove(Guid managerID) - { - - DbManager.ExecuteNonQuery(Delete("crm_manager").Where(Exp.Eq("id", managerID))); - - } - - public List GetAll(bool includeAdmins) - { - - var managers = DbManager.ExecuteList(Query("crm_manager").Select("id")).ConvertAll(row=> ASC.Core.CoreContext.UserManager.GetUsers(ToGuid(row[0]))); - - if (includeAdmins) - return managers.Union(ASC.Core.CoreContext.UserManager.GetUsersByGroup(Constants.GroupAdmin.ID)).Distinct().ToList(); - - return managers; - } - - } - -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 0cfb47d14bc..9ea04224ed9 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -56,7 +56,7 @@ namespace ASC.CRM.Core.Dao public class CachedRelationshipEventDao : RelationshipEventDao { - private readonly HttpRequestDictionary _contactCache; + private readonly HttpRequestDictionary _relationshipEventCache; public CachedRelationshipEventDao(DbContextManager dbContextManager, TenantManager tenantManager, @@ -80,12 +80,12 @@ IOptionsMonitor logger pathProvider, logger) { - _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_relationshipEvent"); + _relationshipEventCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_relationshipEvent"); } public override RelationshipEvent GetByID(int eventID) { - return _contactCache.Get(eventID.ToString(), () => GetByIDBase(eventID)); + return _relationshipEventCache.Get(eventID.ToString(), () => GetByIDBase(eventID)); } private RelationshipEvent GetByIDBase(int eventID) @@ -95,7 +95,7 @@ private RelationshipEvent GetByIDBase(int eventID) private void ResetCache(int dealID) { - _contactCache.Reset(dealID.ToString()); + _relationshipEventCache.Reset(dealID.ToString()); } } @@ -440,7 +440,7 @@ public RelationshipEvent CreateItem(RelationshipEvent item) if (item.CreateOn.Kind == DateTimeKind.Utc) item.CreateOn = TenantUtil.DateTimeFromUtc(item.CreateOn); - FactoryIndexer.IndexAsync(item); + FactoryIndexer.IndexAsync(EventsWrapper.FromEvent(TenantID, item)); return item; } @@ -648,7 +648,7 @@ public void DeleteItem(RelationshipEvent item) CRMDbContext.RelationshipEvent.Remove(itemToDelete); CRMDbContext.SaveChanges(); - FactoryIndexer.DeleteAsync(item); + FactoryIndexer.DeleteAsync(EventsWrapper.FromEvent(TenantID, item)); } [DataContract] diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index ce6bba9d600..2ddbbf5b2b6 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -46,6 +46,7 @@ using System.Globalization; using System.IO; using System.Linq; +using Microsoft.Extensions.DependencyInjection; #endregion @@ -69,7 +70,8 @@ public ReportDao(DbContextManager dbContextManager, TenantUtil tenantUtil, SettingsManager settingsManager, Global global, - UserManager userManager) : + UserManager userManager, + IServiceProvider serviceProvider) : base(dbContextManager, tenantManager, securityContext, @@ -82,11 +84,13 @@ public ReportDao(DbContextManager dbContextManager, Global = global; UserManager = userManager; TenantManager = tenantManager; + ServiceProvider = serviceProvider; } #endregion + public IServiceProvider ServiceProvider { get; } public TenantManager TenantManager { get; } public UserManager UserManager { get; } @@ -276,14 +280,15 @@ public List GetMissingRates(string defaultCurrency) { using (var stream = storeTemplate.GetReadStream("", filePath)) { - var document = new Files.Core.File - { - Title = Path.GetFileName(filePath), - FolderID = DaoFactory.FileDao.GetRoot(), - ContentLength = stream.Length - }; - var file = DaoFactory.FileDao.SaveFile(document, stream); + var document = ServiceProvider.GetService>(); + + document.Title = Path.GetFileName(filePath); + document.FolderID = DaoFactory.GetFileDao().GetRoot(); + document.ContentLength = stream.Length; + + + var file = DaoFactory.GetFileDao().SaveFile(document, stream); SaveFile((int)file.ID, -1); @@ -353,7 +358,7 @@ public void DeleteFiles(Guid userId) CRMDbContext.SaveChanges(); var filedao = FilesIntegration.DaoFactory.GetFileDao(); - + foreach (var fileId in fileIds) { filedao.DeleteFile(fileId); @@ -361,13 +366,13 @@ public void DeleteFiles(Guid userId) } - public void SaveFile(int fileId, ReportType reportType) + public void SaveFile(int fileId, int reportType) { var itemToInsert = new DbReportFile { FileId = fileId, - ReportType = reportType, + ReportType = (ReportType)reportType, CreateOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), CreateBy = SecurityContext.CurrentAccount.ID, TenantId = TenantID @@ -380,1839 +385,1839 @@ public void SaveFile(int fileId, ReportType reportType) #endregion - #region SalesByManagersReport - - public bool CheckSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - - return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), - x => x.DealMilestoneId, - y => y.Id, - (x, y) => new { x, y }) - .Where(x => x.y.Status == DealMilestoneStatus.ClosedAndWon) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - } - - public object GetSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - var reportData = BuildSalesByManagersReport(timePeriod, managers, defaultCurrency); - - return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - } - - private List BuildSalesByManagersReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - string dateSelector; - - switch (timePeriod) - { - case ReportTimePeriod.Today: - case ReportTimePeriod.Yesterday: - dateSelector = "date_add(date(d.actual_close_date), interval extract(hour from d.actual_close_date) hour) as close_date"; - break; - case ReportTimePeriod.CurrentWeek: - case ReportTimePeriod.PreviousWeek: - case ReportTimePeriod.CurrentMonth: - case ReportTimePeriod.PreviousMonth: - dateSelector = "date(d.actual_close_date) as close_date"; - break; - case ReportTimePeriod.CurrentQuarter: - case ReportTimePeriod.PreviousQuarter: - case ReportTimePeriod.CurrentYear: - case ReportTimePeriod.PreviousYear: - dateSelector = "date_sub(date(d.actual_close_date), interval (extract(day from d.actual_close_date) - 1) day) as close_date"; - break; - default: - return null; - } - - var sqlQuery = Query("crm_deal d") - .Select("d.responsible_id", - "concat(u.firstname, ' ', u.lastname) as full_name", - string.Format(@"sum((case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end)) as bid_value", defaultCurrency), - dateSelector) - .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) - .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) - .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("responsible_id", "close_date"); - - - return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesByManagers); - } - - private SalesByManager ToSalesByManagers(object[] row) - { - return new SalesByManager - { - UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - UserName = Convert.ToString(row[1]), - Value = Convert.ToDecimal(row[2]), - Date = Convert.ToDateTime(row[3]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[3])) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, List data) - { - switch (timePeriod) - { - case ReportTimePeriod.Today: - case ReportTimePeriod.Yesterday: - return GenerateReportDataByHours(timePeriod, data); - case ReportTimePeriod.CurrentWeek: - case ReportTimePeriod.PreviousWeek: - case ReportTimePeriod.CurrentMonth: - case ReportTimePeriod.PreviousMonth: - return GenerateReportDataByDays(timePeriod, data); - case ReportTimePeriod.CurrentQuarter: - case ReportTimePeriod.PreviousQuarter: - case ReportTimePeriod.CurrentYear: - case ReportTimePeriod.PreviousYear: - return GenerateReportByMonths(timePeriod, data); - default: - return null; - } - } - - private object GenerateReportDataByHours(ReportTimePeriod timePeriod, List data) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var res = new Dictionary>(); - - var users = data.Select(x => x.UserId).Distinct().ToList(); - - foreach (var userId in users) - { - var date = fromDate; - - while (date < toDate) - { - if (res.ContainsKey(userId)) - { - res[userId].Add(date, 0); - } - else - { - res.Add(userId, new Dictionary { { date, 0 } }); - } - - date = date.AddHours(1); - } - } - - foreach (var item in data) - { - var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day, item.Date.Hour, 0, 0); - - if (itemDate < res[item.UserId].First().Key) - itemDate = res[item.UserId].First().Key; - - if (itemDate > res[item.UserId].Last().Key) - itemDate = res[item.UserId].Last().Key; - - res[item.UserId][itemDate] += item.Value; - } - - var body = new List>(); - - foreach (var resItem in res) - { - var bodyItem = new List - { - data.First(x => x.UserId == resItem.Key).UserName - }; - - bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); - - body.Add(bodyItem); - } - - var head = new List(); - - foreach (var key in res.First().Value.Keys) - { - head.Add(new { format = "H:mm", value = key.ToShortTimeString() }); - } - - return new - { - resource = new - { - manager = CRMReportResource.Manager, - summary = CRMReportResource.Sum, - total = CRMReportResource.Total, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - sheetName = CRMReportResource.SalesByManagersReport, - header = CRMReportResource.SalesByManagersReport, - header1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, - header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol - }, - thead = head, - tbody = body - }; - } - - private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var res = new Dictionary>(); - - var users = data.Select(x => x.UserId).Distinct().ToList(); - - foreach (var userId in users) - { - var date = fromDate; - - while (date < toDate) - { - if (res.ContainsKey(userId)) - { - res[userId].Add(date, 0); - } - else - { - res.Add(userId, new Dictionary { { date, 0 } }); - } - - date = date.AddDays(1); - } - } - - foreach (var item in data) - { - var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); - - if (itemDate < res[item.UserId].First().Key) - itemDate = res[item.UserId].First().Key; - - if (itemDate > res[item.UserId].Last().Key) - itemDate = res[item.UserId].Last().Key; - - res[item.UserId][itemDate] += item.Value; - } - - var body = new List>(); - - foreach (var resItem in res) - { - var bodyItem = new List - { - data.First(x => x.UserId == resItem.Key).UserName - }; - - bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); - - body.Add(bodyItem); - } - - var head = new List(); - var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); - var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); - - foreach (var key in res.First().Value.Keys) - { - head.Add(new { format = pattern, value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); - } - - return new - { - resource = new - { - manager = CRMReportResource.Manager, - summary = CRMReportResource.Sum, - total = CRMReportResource.Total, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - sheetName = CRMReportResource.SalesByManagersReport, - header = CRMReportResource.SalesByManagersReport, - header1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, - header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol - }, - thead = head, - tbody = body - }; - } - - private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var res = new Dictionary>(); - - var users = data.Select(x => x.UserId).Distinct().ToList(); - - foreach (var userId in users) - { - var date = fromDate; - - while (date < toDate) - { - if (res.ContainsKey(userId)) - { - res[userId].Add(date, 0); - } - else - { - res.Add(userId, new Dictionary { { date, 0 } }); - } - - date = date.AddMonths(1); - } - } - - foreach (var item in data) - { - var itemDate = new DateTime(item.Date.Year, item.Date.Month, 1); - - if (itemDate < res[item.UserId].First().Key) - itemDate = res[item.UserId].First().Key; - - if (itemDate > res[item.UserId].Last().Key) - itemDate = res[item.UserId].Last().Key; - - res[item.UserId][itemDate] += item.Value; - } - - var body = new List>(); - - foreach (var resItem in res) - { - var bodyItem = new List - { - data.First(x => x.UserId == resItem.Key).UserName - }; - - bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); - - body.Add(bodyItem); - } - - var head = new List(); - - foreach (var key in res.First().Value.Keys) - { - head.Add(new { format = "MMM-yy", value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); - } - - return new - { - resource = new - { - manager = CRMReportResource.Manager, - summary = CRMReportResource.Sum, - total = CRMReportResource.Total, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - sheetName = CRMReportResource.SalesByManagersReport, - header = CRMReportResource.SalesByManagersReport, - header1 = CRMReportResource.SalesByMonth + ", " + CRMSettings.DefaultCurrency.Symbol, - header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.SalesByMonth + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol - }, - thead = head, - tbody = body - }; - } - - #endregion - - - #region SalesForecastReport - - public bool CheckSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), - x => x.DealMilestoneId, - y => y.Id, - (x, y) => new { x, y }) - .Where(x => x.y.Status == DealMilestoneStatus.Open) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - } - - public object GetSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - var reportData = BuildSalesForecastReport(timePeriod, managers, defaultCurrency); - - return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - } - - private List BuildSalesForecastReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - string dateSelector; - - switch (timePeriod) - { - case ReportTimePeriod.CurrentWeek: - case ReportTimePeriod.NextWeek: - case ReportTimePeriod.CurrentMonth: - case ReportTimePeriod.NextMonth: - dateSelector = "d.expected_close_date as close_date"; - break; - case ReportTimePeriod.CurrentQuarter: - case ReportTimePeriod.NextQuarter: - case ReportTimePeriod.CurrentYear: - case ReportTimePeriod.NextYear: - dateSelector = "date_sub(date(d.expected_close_date), interval (extract(day from d.expected_close_date) - 1) day) as close_date"; - break; - default: - return null; - } - - var sqlQuery = Query("crm_deal d") - .Select(string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as value", defaultCurrency), - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 - end) as value_with_probability", defaultCurrency), - dateSelector) - .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) - .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - .Where("m.status", (int)DealMilestoneStatus.Open) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("close_date"); - - return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesForecast); - } - - private SalesForecast ToSalesForecast(object[] row) - { - return new SalesForecast - { - Value = Convert.ToDecimal(row[0]), - ValueWithProbability = Convert.ToDecimal(row[1]), - Date = Convert.ToDateTime(row[2]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[2])) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, List data) - { - switch (timePeriod) - { - case ReportTimePeriod.CurrentWeek: - case ReportTimePeriod.NextWeek: - case ReportTimePeriod.CurrentMonth: - case ReportTimePeriod.NextMonth: - return GenerateReportDataByDays(timePeriod, data); - case ReportTimePeriod.CurrentQuarter: - case ReportTimePeriod.NextQuarter: - case ReportTimePeriod.CurrentYear: - case ReportTimePeriod.NextYear: - return GenerateReportByMonths(timePeriod, data); - default: - return null; - } - } - - private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var res = new Dictionary>(); - - var date = fromDate; - - while (date < toDate) - { - res.Add(date, new Tuple(0, 0)); - date = date.AddDays(1); - } - - foreach (var item in data) - { - var key = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); - - if (key < res.First().Key) - key = res.First().Key; - - if (key > res.Last().Key) - key = res.Last().Key; - - res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, - res[key].Item2 + item.Value); - } - - var body = new List>(); - var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); - var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); - - foreach (var resItem in res) - { - var bodyItem = new List - { - new {format = pattern, value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, - new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, - new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} - }; - - body.Add(bodyItem); - } - - var head = new List - { - CRMReportResource.Day, - CRMReportResource.WithRespectToProbability, - CRMReportResource.IfAllOpportunitiesWon - }; - - return new - { - resource = new - { - total = CRMReportResource.Total, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - sheetName = CRMReportResource.SalesForecastReport, - header = CRMReportResource.SalesForecastReport, - header1 = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol - }, - thead = head, - tbody = body - }; - } - - private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var res = new Dictionary>(); - - var date = fromDate; - - while (date < toDate) - { - res.Add(date, new Tuple(0, 0)); - date = date.AddMonths(1); - } - - foreach (var item in data) - { - var key = new DateTime(item.Date.Year, item.Date.Month, 1); - - if (key < res.First().Key) - key = res.First().Key; - - if (key > res.Last().Key) - key = res.Last().Key; - - res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, - res[key].Item2 + item.Value); - } - - var body = new List>(); - - foreach (var resItem in res) - { - var bodyItem = new List - { - new {format = "MMM-yy", value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, - new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, - new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} - }; - - body.Add(bodyItem); - } - - var head = new List - { - CRMReportResource.Month, - CRMReportResource.WithRespectToProbability, - CRMReportResource.IfAllOpportunitiesWon - }; - - return new - { - resource = new - { - total = CRMReportResource.Total, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - sheetName = CRMReportResource.SalesForecastReport, - header = CRMReportResource.SalesForecastReport, - header1 = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol - }, - thead = head, - tbody = body - }; - } - - #endregion - - - #region SalesFunnelReport - - public bool CheckSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - return Query(CRMDbContext.Deals) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - } - - public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - var reportData = BuildSalesFunnelReport(timePeriod, managers, defaultCurrency); - - return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - } - - private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var sqlQuery = Query("crm_deal_milestone m") - .Select("m.status", "m.title", - "count(d.id) as deals_count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency), - "avg(if(m.status = 1, datediff(d.actual_close_date, d.create_on), 0)) as deals_duration") - .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & - Exp.EqColumns("d.deal_milestone_id", "m.id") & - (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & - Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "m.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .GroupBy("m.id") - .OrderBy("m.sort_order", true); - - - return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesFunnel); - } - - private SalesFunnel ToSalesFunnel(object[] row) - { - return new SalesFunnel - { - Status = (DealMilestoneStatus)Convert.ToInt32(row[0]), - Title = Convert.ToString(row[1]), - Count = Convert.ToInt32(row[2]), - Value = Convert.ToDecimal(row[3]), - Duration = Convert.ToInt32(row[4]) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, List data) - { - var totalCount = data.Sum(x => x.Count); - - if (totalCount == 0) return null; - - var totalBudget = data.Sum(x => x.Value); - - var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); - - var reportData = data.Select(item => new List - { - item.Title, - item.Status, - item.Count, - item.Value - }).ToList(); - - return new - { - resource = new - { - header = CRMReportResource.SalesFunnelReport, - sheetName = CRMReportResource.SalesFunnelReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - - chartName = CRMReportResource.SalesFunnelByCount, - chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName2 = CRMReportResource.DealsCount, - chartName3 = CRMReportResource.DealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - totalCountLabel = CRMReportResource.TotalDealsCount, - totalCountValue = totalCount, - - totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - totalBudgetValue = totalBudget, - - averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - averageBidValue = totalBudget / totalCount, - - averageDurationLabel = CRMReportResource.AverageDealsDuration, - averageDurationValue = closed.Sum(x => x.Duration) / closed.Count, - - header1 = CRMReportResource.ByCount, - header2 = CRMReportResource.ByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - stage = CRMReportResource.Stage, - count = CRMReportResource.Count, - budget = CRMReportResource.Budget, - conversion = CRMReportResource.Conversion, - - deals = CRMDealResource.Deals, - status0 = DealMilestoneStatus.Open.ToLocalizedString(), - status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), - status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() - }, - data = reportData - }; - } - - #endregion - - - #region WorkloadByContactsReport - - public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - return Query(CRMDbContext.Contacts) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - } - - public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - var reportData = BuildWorkloadByContactsReport(timePeriod, managers); - - return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - } - - private List BuildWorkloadByContactsReport(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var sqlQuery = Query(CRMDbContext.Contacts) - .GroupJoin(Query(CRMDbContext.ListItem), - x => x.ContactTypeId, - y => y.Id, - (x, y) => new { x, y }) - .GroupJoin(Query(CRMDbContext.Deals), - x => x.x.Id, - y=> y.Id, - (x,y) => new { x, y }) - - - - var sqlQuery = Query("crm_contact c") - .Select("c.create_by", - "concat(u.firstname, ' ', u.lastname) as full_name", - "i.id", - "i.title", - "count(c.id) as total", - "count(d.id) as `with deals`") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & Exp.Eq("i.list_type", (int)ListType.ContactType)) - .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "c.tenant_id") & Exp.EqColumns("d.contact_id", "c.id")) - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.create_by")) - .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("c.create_by", "i.id") - .OrderBy("i.sort_order, i.title", true); - - return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByContacts); - } - - private WorkloadByContacts ToWorkloadByContacts(object[] row) - { - return new WorkloadByContacts - { - UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - UserName = Convert.ToString(row[1]), - CategoryId = Convert.ToInt32(row[2]), - CategoryName = Convert.ToString(row[3]), - Count = Convert.ToInt32(row[4]), - WithDeals = Convert.ToInt32(row[5]) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) - { - return new - { - resource = new - { - header = CRMReportResource.WorkloadByContactsReport, - sheetName = CRMReportResource.WorkloadByContactsReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - - header1 = CRMReportResource.NewContacts, - header2 = CRMReportResource.NewContactsWithAndWithoutDeals, - - manager = CRMReportResource.Manager, - total = CRMReportResource.Total, - - noSet = CRMCommonResource.NoSet, - withDeals = CRMReportResource.ContactsWithDeals, - withouthDeals = CRMReportResource.ContactsWithoutDeals, - }, - data = reportData - }; - } - - #endregion - - - #region WorkloadByTasksReport - - public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var sqlNewTasksQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => x.IsClosed) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - - - var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => x.IsClosed) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) - .Where(x => (!x.IsClosed && x.Deadline < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || - (x.IsClosed && x.LastModifedOn > x.Deadline)) - .Any(); - - return sqlNewTasksQuery || - sqlClosedTasksQuery || - sqlOverdueTasksQuery; - } - - public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - var reportData = BuildWorkloadByTasksReport(timePeriod, managers); - - if (reportData == null || !reportData.Any()) return null; - - var hasData = reportData.Any(item => item.Value.Count > 0); - - return hasData ? GenerateReportData(timePeriod, reportData) : null; - } - - private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var sqlNewTasksQuery = Query("crm_task t") - .Select("i.id", - "i.title", - "t.responsible_id", - "concat(u.firstname, ' ', u.lastname) as full_name", - "count(t.id) as count") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("i.id", "t.responsible_id") - .OrderBy("i.sort_order", true); - - var sqlClosedTasksQuery = Query("crm_task t") - .Select("i.id", - "i.title", - "t.responsible_id", - "concat(u.firstname, ' ', u.lastname) as full_name", - "count(t.id) as count") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - .Where(Exp.Eq("t.is_closed", 1)) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("i.id", "t.responsible_id") - .OrderBy("i.sort_order", true); - - var sqlOverdueTasksQuery = Query("crm_task t") - .Select("i.id", - "i.title", - "t.responsible_id", - "concat(u.firstname, ' ', u.lastname) as full_name", - "count(t.id) as count") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) - .GroupBy("i.id", "t.responsible_id") - .OrderBy("i.sort_order", true); - - Dictionary> res; - - using (var tx = Db.BeginTransaction()) - { - res = new Dictionary> - { - {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, - {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, - {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} - }; - - tx.Commit(); - } - - return res; - } - - private WorkloadByTasks ToWorkloadByTasks(object[] row) - { - return new WorkloadByTasks - { - CategoryId = Convert.ToInt32(row[0]), - CategoryName = Convert.ToString(row[1]), - UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), - UserName = Convert.ToString(row[3]), - Count = Convert.ToInt32(row[4]) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) - { - return new - { - resource = new - { - header = CRMReportResource.WorkloadByTasksReport, - sheetName = CRMReportResource.WorkloadByTasksReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - - header1 = CRMReportResource.ClosedTasks, - header2 = CRMReportResource.NewTasks, - header3 = CRMReportResource.OverdueTasks, - - manager = CRMReportResource.Manager, - total = CRMReportResource.Total - }, - data = reportData - }; - } - - #endregion - - - #region WorkloadByDealsReport - - public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - return Query(CRMDbContext.Deals) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) || - (x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate))) - .Any(); - } - - public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - var reportData = BuildWorkloadByDealsReport(timePeriod, managers, defaultCurrency); - - return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - } - - private List BuildWorkloadByDealsReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var sqlQuery = Query("crm_deal d") - .Select("d.responsible_id", - "concat(u.firstname, ' ', u.lastname) as full_name", - "m.status", - "count(d.id) as deals_count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) - .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - Exp.Empty : - Exp.Or(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), - Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) - .GroupBy("d.responsible_id", "m.status"); - - - return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByDeals); - } - - private WorkloadByDeals ToWorkloadByDeals(object[] row) - { - return new WorkloadByDeals - { - UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - UserName = Convert.ToString(row[1]), - Status = (DealMilestoneStatus)Convert.ToInt32(row[2]), - Count = Convert.ToInt32(row[3]), - Value = Convert.ToDecimal(row[4]) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, List data) - { - var reportData = data.Select(item => new List - { - item.UserId, - item.UserName, - (int)item.Status, - item.Count, - item.Value - }).ToList(); - - return new - { - resource = new - { - header = CRMReportResource.WorkloadByDealsReport, - sheetName = CRMReportResource.WorkloadByDealsReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - - chartName = CRMReportResource.DealsCount, - chartName1 = CRMReportResource.DealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - header1 = CRMReportResource.ByCount, - header2 = CRMReportResource.ByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - manager = CRMReportResource.Manager, - total = CRMReportResource.Total, - - status0 = CRMReportResource.New, - status1 = CRMReportResource.Won, - status2 = CRMReportResource.Lost - }, - data = reportData - }; - } - - #endregion - - - #region WorkloadByInvoicesReport - - public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - return Query(CRMDbContext.Invoices) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= TenantUtil.DateTimeToUtc(toDate))) || - (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || - (x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || - ((timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= TenantUtil.DateTimeToUtc(toDate))) && - (x.Status == InvoiceStatus.Sent && x.DueDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()) || x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) - .Any(); - } - - public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - var reportData = BuildWorkloadByInvoicesReport(timePeriod, managers); - - if (reportData == null || !reportData.Any()) return null; - - var hasData = reportData.Any(item => item.SentCount > 0 || item.PaidCount > 0 || item.RejectedCount > 0 || item.OverdueCount > 0); - - return hasData ? GenerateReportData(timePeriod, reportData) : null; - } - - private List BuildWorkloadByInvoicesReport(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.issue_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); - var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); - var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); - var overdue = Exp.Sum(Exp.If((timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.due_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) & Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); - - var sqlQuery = Query("crm_invoice i") - .Select("i.create_by", "concat(u.firstname, ' ', u.lastname) as full_name") - .Select(sent) - .Select(paid) - .Select(rejected) - .Select(overdue) - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "i.tenant_id") & Exp.EqColumns("u.id", "i.create_by")) - .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - .GroupBy("i.create_by"); - - - return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByInvoices); - } - - private WorkloadByInvoices ToWorkloadByInvoices(object[] row) - { - return new WorkloadByInvoices - { - UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - UserName = Convert.ToString(row[1]), - SentCount = Convert.ToInt32(row[2]), - PaidCount = Convert.ToInt32(row[3]), - RejectedCount = Convert.ToInt32(row[4]), - OverdueCount = Convert.ToInt32(row[5]) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) - { - return new - { - resource = new - { - header = CRMReportResource.WorkloadByInvoicesReport, - sheetName = CRMReportResource.WorkloadByInvoicesReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - - chartName = CRMReportResource.BilledInvoices, - chartName1 = CRMInvoiceResource.Invoices, - - header1 = CRMInvoiceResource.Invoices, - - manager = CRMReportResource.Manager, - total = CRMReportResource.Total, - - billed = CRMReportResource.Billed, - paid = CRMReportResource.Paid, - rejected = CRMReportResource.Rejected, - overdue = CRMReportResource.Overdue - }, - data = reportData - }; - } - - #endregion - - - #region GetWorkloadByViopReport - - public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - return Query(CRMDbContext.VoipCalls) - .Where(x => x.ParentCallId == "") - .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? - true : - x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - } - - public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - var reportData = BuildWorkloadByViopReport(timePeriod, managers); - - return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - } - - private List BuildWorkloadByViopReport(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var sqlQuery = Query("crm_voip_calls c") - .Select("c.answered_by", - "concat(u.firstname, ' ', u.lastname) as full_name", - "c.status", - "count(c.id) as calls_count", - "sum(c.dial_duration) as duration") - .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.answered_by")) - .Where(Exp.EqColumns("c.parent_call_id", "''")) - .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - Exp.Empty : - Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("c.answered_by", "c.status"); - - - return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByViop); - } - - private WorkloadByViop ToWorkloadByViop(object[] row) - { - return new WorkloadByViop - { - UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - UserName = Convert.ToString(row[1] ?? string.Empty), - Status = (VoipCallStatus)Convert.ToInt32(row[2] ?? 0), - Count = Convert.ToInt32(row[3]), - Duration = Convert.ToInt32(row[4]) - }; - } - - private object GenerateReportData(ReportTimePeriod timePeriod, List data) - { - var reportData = data.Select(item => new List - { - item.UserId, - item.UserName, - (int) item.Status, - item.Count, - new {format = TimeFormat, value = SecondsToTimeFormat(item.Duration)} - }).ToList(); - - return new - { - resource = new - { - header = CRMReportResource.WorkloadByVoipReport, - sheetName = CRMReportResource.WorkloadByVoipReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - - chartName = CRMReportResource.CallsCount, - chartName1 = CRMReportResource.CallsDuration, - - header1 = CRMReportResource.CallsCount, - header2 = CRMReportResource.CallsDuration, - - manager = CRMReportResource.Manager, - total = CRMReportResource.Total, - - incoming = CRMReportResource.Incoming, - outcoming = CRMReportResource.Outcoming, - - timeFormat = TimeFormat - }, - data = reportData - }; - } - - private string SecondsToTimeFormat(int duration) - { - var timeSpan = TimeSpan.FromSeconds(duration); - - return string.Format("{0}:{1}:{2}", - ((timeSpan.TotalHours < 10 ? "0" : "") + (int)timeSpan.TotalHours), - ((timeSpan.Minutes < 10 ? "0" : "") + timeSpan.Minutes), - ((timeSpan.Seconds < 10 ? "0" : "") + timeSpan.Seconds)); - } - - #endregion - - - #region SummaryForThePeriodReport - - public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var newDealsSqlQuery = Query(CRMDbContext.Deals) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - var closedDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.DealMilestones), - x => x.DealMilestoneId, - y => y.Id, - (x, y) => new { x, y }) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - .Where(x => x.y.Status != DealMilestoneStatus.Open) - .Any(); - - var overdueDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.DealMilestones), - x => x.DealMilestoneId, - y => y.Id, - (x, y) => new { x, y }) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - .Where(x => (x.y.Status == DealMilestoneStatus.Open && x.x.ExpectedCloseDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || - (x.y.Status == DealMilestoneStatus.ClosedAndWon && x.x.ActualCloseDate > x.x.ExpectedCloseDate)) - .Any(); - - var invoicesSqlQuery = Query(CRMDbContext.Invoices) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - var contactsSqlQuery = Query(CRMDbContext.Contacts) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - - var tasksSqlQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - - var voipSqlQuery = Query(CRMDbContext.VoipCalls) - .Where(x => x.ParentCallId == "") - .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) - .Where(x => x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - return newDealsSqlQuery || - closedDealsSqlQuery || - overdueDealsSqlQuery || - invoicesSqlQuery || - contactsSqlQuery || - tasksSqlQuery || - voipSqlQuery; - } - - public object GetSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - var reportData = BuildSummaryForThePeriodReport(timePeriod, managers, defaultCurrency); - - if (reportData == null) return null; - - return GenerateSummaryForThePeriodReportData(timePeriod, reportData); - } - - private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var newDealsSqlQuery = Query("crm_deal d") - .Select("count(d.id) as count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "d.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - - var wonDealsSqlQuery = Query("crm_deal d") - .Select("count(d.id) as count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "d.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .LeftOuterJoin("crm_deal_milestone m", - Exp.EqColumns("m.tenant_id", "d.tenant_id") & - Exp.EqColumns("m.id", "d.deal_milestone_id")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon); - - var lostDealsSqlQuery = Query("crm_deal d") - .Select("count(d.id) as count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "d.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .LeftOuterJoin("crm_deal_milestone m", - Exp.EqColumns("m.tenant_id", "d.tenant_id") & - Exp.EqColumns("m.id", "d.deal_milestone_id")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int)DealMilestoneStatus.ClosedAndLost); - - var overdueDealsSqlQuery = Query("crm_deal d") - .Select("count(d.id) as count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "d.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .LeftOuterJoin("crm_deal_milestone m", - Exp.EqColumns("m.tenant_id", "d.tenant_id") & - Exp.EqColumns("m.id", "d.deal_milestone_id")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where( - Exp.And( - Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), - Exp.Or(Exp.Eq("m.status", (int)DealMilestoneStatus.Open) & Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), - Exp.Eq("m.status", (int)DealMilestoneStatus.ClosedAndWon) & Exp.Sql("d.actual_close_date > d.expected_close_date")))); - - var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft), 1, 0)); - var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid), 1, 0)); - var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected), 1, 0)); - var overdue = Exp.Sum(Exp.If(Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), - Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); - - var invoicesSqlQuery = Query("crm_invoice i") - .Select(sent) - .Select(paid) - .Select(rejected) - .Select(overdue) - .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - .Where(Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - - - var contactsSqlQuery = Query("crm_contact c") - .Select("i.title", - "count(c.id)") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - Exp.EqColumns("i.id", "c.contact_type_id") & - Exp.Eq("i.list_type", (int)ListType.ContactType)) - .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - .Where(Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("i.id") - .OrderBy("i.sort_order, i.title", true); - - var tasksSqlQuery = Query("crm_task t") - .Select("i.title") - .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 1) & Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), 1, 0))) - .Select(Exp.Sum(Exp.If(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")), 1, 0))) - .Select("count(t.id)") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - .Where(Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("i.id") - .OrderBy("i.sort_order, i.title", true); - - var voipSqlQuery = Query("crm_voip_calls c") - .Select("c.status", - "count(c.id) as calls_count", - "sum(c.dial_duration) as duration") - .Where(Exp.EqColumns("c.parent_call_id", "''")) - .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) - .Where(Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("c.status"); - - object res; - - using (var tx = Db.BeginTransaction()) - { - res = new - { - DealsInfo = new - { - Created = Db.ExecuteList(newDealsSqlQuery), - Won = Db.ExecuteList(wonDealsSqlQuery), - Lost = Db.ExecuteList(lostDealsSqlQuery), - Overdue = Db.ExecuteList(overdueDealsSqlQuery), - }, - InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), - ContactsInfo = Db.ExecuteList(contactsSqlQuery), - TasksInfo = Db.ExecuteList(tasksSqlQuery), - VoipInfo = Db.ExecuteList(voipSqlQuery) - }; - - tx.Commit(); - } - - return res; - } - - private object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) - { - return new - { - resource = new - { - header = CRMReportResource.SummaryForThePeriodReport, - sheetName = CRMReportResource.SummaryForThePeriodReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - chartName = CRMReportResource.DealsByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.DealsByCount, - chartName2 = CRMReportResource.ContactsByType, - chartName3 = CRMReportResource.TasksForThePeriod, - chartName4 = CRMReportResource.InvoicesForThePeriod, - chartName5 = CRMReportResource.CallsForThePeriod, - header1 = CRMDealResource.Deals, - header2 = CRMContactResource.Contacts, - header3 = CRMTaskResource.Tasks, - header4 = CRMInvoiceResource.Invoices, - header5 = CRMReportResource.Calls, - byBudget = CRMReportResource.ByBudget, - currency = CRMSettings.DefaultCurrency.Symbol, - byCount = CRMReportResource.ByCount, - item = CRMReportResource.Item, - type = CRMReportResource.Type, - won = CRMReportResource.Won, - lost = CRMReportResource.Lost, - created = CRMReportResource.Created, - closed = CRMReportResource.Closed, - overdue = CRMReportResource.Overdue, - notSpecified = CRMCommonResource.NoSet, - total = CRMReportResource.Total, - status = CRMReportResource.Status, - billed = CRMReportResource.Billed, - paid = CRMReportResource.Paid, - rejected = CRMReportResource.Rejected, - count = CRMReportResource.Count, - duration = CRMReportResource.Duration, - incoming = CRMReportResource.Incoming, - outcoming = CRMReportResource.Outcoming, - missed = CRMReportResource.MissedCount, - timeFormat = TimeFormat - }, - data = reportData - }; - } - - #endregion - - - #region SummaryAtThisMomentReport - - public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var dealsSqlQuery = Query(CRMDbContext.Deals) - .Join(CRMDbContext.DealMilestones, - x => x.DealMilestoneId, - y => y.Id, - (x, y) => new { x, y }) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Where(x => x.y.Status == DealMilestoneStatus.Open) - .Any(); - - - var contactsSqlQuery = Query(CRMDbContext.Contacts) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - var tasksSqlQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - var invoicesSqlQuery = Query(CRMDbContext.Invoices) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - .Any(); - - return dealsSqlQuery || - contactsSqlQuery || - tasksSqlQuery || - invoicesSqlQuery; - - } - - public object GetSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - var reportData = BuildSummaryAtThisMomentReport(timePeriod, managers, defaultCurrency); - - if (reportData == null) return null; - - return GenerateSummaryAtThisMomentReportData(timePeriod, reportData); - } - - private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - { - DateTime fromDate; - DateTime toDate; - - GetTimePeriod(timePeriod, out fromDate, out toDate); - - var openDealsSqlQuery = Query("crm_deal d") - .Select("count(d.id) as count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "d.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .LeftOuterJoin("crm_deal_milestone m", - Exp.EqColumns("m.tenant_id", "d.tenant_id") & - Exp.EqColumns("m.id", "d.deal_milestone_id")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int)DealMilestoneStatus.Open); - - var overdueDealsSqlQuery = Query("crm_deal d") - .Select("count(d.id) as count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "d.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .LeftOuterJoin("crm_deal_milestone m", - Exp.EqColumns("m.tenant_id", "d.tenant_id") & - Exp.EqColumns("m.id", "d.deal_milestone_id")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int)DealMilestoneStatus.Open) - .Where(Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()))); - - var nearDealsSqlQuery = Query("crm_deal d") - .Select("count(d.id) as count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_currency_rate r", - Exp.EqColumns("r.tenant_id", "d.tenant_id") & - Exp.EqColumns("r.from_currency", "d.bid_currency")) - .LeftOuterJoin("crm_deal_milestone m", - Exp.EqColumns("m.tenant_id", "d.tenant_id") & - Exp.EqColumns("m.id", "d.deal_milestone_id")) - .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .Where("m.status", (int)DealMilestoneStatus.Open) - .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow().AddDays(30)))); - - var dealsByStageSqlQuery = Query("crm_deal_milestone m") - .Select("m.title", - "count(d.id) as deals_count", - string.Format(@"sum(case d.bid_type - when 0 then - d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - else - d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - end) as deals_value", defaultCurrency)) - .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & - Exp.EqColumns("d.deal_milestone_id", "m.id") & - (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & - (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) - .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "m.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - .Where("m.status", (int)DealMilestoneStatus.Open) - .GroupBy("m.id") - .OrderBy("m.sort_order, m.title", true); - - var contactsByTypeSqlQuery = Query("crm_contact c") - .Select("i.title", - "count(c.id) as count") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - Exp.EqColumns("i.id", "c.contact_type_id") & - Exp.Eq("i.list_type", (int)ListType.ContactType)) - .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("i.id") - .OrderBy("i.sort_order, i.title", true); - - var contactsByStageSqlQuery = Query("crm_contact c") - .Select("i.title", - "count(c.id) as count") - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - Exp.EqColumns("i.id", "c.status_id") & - Exp.Eq("i.list_type", (int)ListType.ContactStatus)) - .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("i.id") - .OrderBy("i.sort_order, i.title", true); - - var tasksSqlQuery = Query("crm_task t") - .Select("i.title") - .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0), 1, 0))) - .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0))) - .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - .GroupBy("i.id") - .OrderBy("i.sort_order, i.title", true); - - var sent = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent), 1, 0)); - var overdue = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0)); - - var invoicesSqlQuery = Query("crm_invoice i") - .Select(sent) - .Select(overdue) - .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - - object res; - - using (var tx = Db.BeginTransaction()) - { - res = new - { - DealsInfo = new - { - Open = Db.ExecuteList(openDealsSqlQuery), - Overdue = Db.ExecuteList(overdueDealsSqlQuery), - Near = Db.ExecuteList(nearDealsSqlQuery), - ByStage = Db.ExecuteList(dealsByStageSqlQuery) - }, - ContactsInfo = new - { - ByType = Db.ExecuteList(contactsByTypeSqlQuery), - ByStage = Db.ExecuteList(contactsByStageSqlQuery) - }, - TasksInfo = Db.ExecuteList(tasksSqlQuery), - InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), - }; - - tx.Commit(); - } - - return res; - } - - private object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) - { - return new - { - resource = new - { - header = CRMReportResource.SummaryAtThisMomentReport, - sheetName = CRMReportResource.SummaryAtThisMomentReport, - dateRangeLabel = CRMReportResource.TimePeriod + ":", - dateRangeValue = GetTimePeriodText(timePeriod), - chartName = CRMReportResource.DealsByStatus + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName1 = CRMReportResource.DealsByStage + ", " + CRMSettings.DefaultCurrency.Symbol, - chartName2 = CRMReportResource.ContactsByType, - chartName3 = CRMReportResource.ContactsByStage, - chartName4 = CRMReportResource.TasksByStatus, - chartName5 = CRMReportResource.InvoicesByStatus, - header1 = CRMDealResource.Deals, - header2 = CRMContactResource.Contacts, - header3 = CRMTaskResource.Tasks, - header4 = CRMInvoiceResource.Invoices, - budget = CRMReportResource.Budget + ", " + CRMSettings.DefaultCurrency.Symbol, - count = CRMReportResource.Count, - open = CRMReportResource.Opened, - overdue = CRMReportResource.Overdue, - near = CRMReportResource.Near, - stage = CRMReportResource.Stage, - temperature = CRMContactResource.ContactStage, - type = CRMReportResource.Type, - total = CRMReportResource.Total, - billed = CRMReportResource.Billed, - notSpecified = CRMCommonResource.NoSet, - status = CRMReportResource.Status, - }, - data = reportData - }; - } - - #endregion + //#region SalesByManagersReport + + //public bool CheckSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + + // return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), + // x => x.DealMilestoneId, + // y => y.Id, + // (x, y) => new { x, y }) + // .Where(x => x.y.Status == DealMilestoneStatus.ClosedAndWon) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + // .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + //} + + //public object GetSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // var reportData = BuildSalesByManagersReport(timePeriod, managers, defaultCurrency); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + //} + + //private List BuildSalesByManagersReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // string dateSelector; + + // switch (timePeriod) + // { + // case ReportTimePeriod.Today: + // case ReportTimePeriod.Yesterday: + // dateSelector = "date_add(date(d.actual_close_date), interval extract(hour from d.actual_close_date) hour) as close_date"; + // break; + // case ReportTimePeriod.CurrentWeek: + // case ReportTimePeriod.PreviousWeek: + // case ReportTimePeriod.CurrentMonth: + // case ReportTimePeriod.PreviousMonth: + // dateSelector = "date(d.actual_close_date) as close_date"; + // break; + // case ReportTimePeriod.CurrentQuarter: + // case ReportTimePeriod.PreviousQuarter: + // case ReportTimePeriod.CurrentYear: + // case ReportTimePeriod.PreviousYear: + // dateSelector = "date_sub(date(d.actual_close_date), interval (extract(day from d.actual_close_date) - 1) day) as close_date"; + // break; + // default: + // return null; + // } + + // var sqlQuery = Query("crm_deal d") + // .Select("d.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // string.Format(@"sum((case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end)) as bid_value", defaultCurrency), + // dateSelector) + // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) + // .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("responsible_id", "close_date"); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesByManagers); + //} + + //private SalesByManager ToSalesByManagers(object[] row) + //{ + // return new SalesByManager + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1]), + // Value = Convert.ToDecimal(row[2]), + // Date = Convert.ToDateTime(row[3]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[3])) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, List data) + //{ + // switch (timePeriod) + // { + // case ReportTimePeriod.Today: + // case ReportTimePeriod.Yesterday: + // return GenerateReportDataByHours(timePeriod, data); + // case ReportTimePeriod.CurrentWeek: + // case ReportTimePeriod.PreviousWeek: + // case ReportTimePeriod.CurrentMonth: + // case ReportTimePeriod.PreviousMonth: + // return GenerateReportDataByDays(timePeriod, data); + // case ReportTimePeriod.CurrentQuarter: + // case ReportTimePeriod.PreviousQuarter: + // case ReportTimePeriod.CurrentYear: + // case ReportTimePeriod.PreviousYear: + // return GenerateReportByMonths(timePeriod, data); + // default: + // return null; + // } + //} + + //private object GenerateReportDataByHours(ReportTimePeriod timePeriod, List data) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var res = new Dictionary>(); + + // var users = data.Select(x => x.UserId).Distinct().ToList(); + + // foreach (var userId in users) + // { + // var date = fromDate; + + // while (date < toDate) + // { + // if (res.ContainsKey(userId)) + // { + // res[userId].Add(date, 0); + // } + // else + // { + // res.Add(userId, new Dictionary { { date, 0 } }); + // } + + // date = date.AddHours(1); + // } + // } + + // foreach (var item in data) + // { + // var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day, item.Date.Hour, 0, 0); + + // if (itemDate < res[item.UserId].First().Key) + // itemDate = res[item.UserId].First().Key; + + // if (itemDate > res[item.UserId].Last().Key) + // itemDate = res[item.UserId].Last().Key; + + // res[item.UserId][itemDate] += item.Value; + // } + + // var body = new List>(); + + // foreach (var resItem in res) + // { + // var bodyItem = new List + // { + // data.First(x => x.UserId == resItem.Key).UserName + // }; + + // bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + + // body.Add(bodyItem); + // } + + // var head = new List(); + + // foreach (var key in res.First().Value.Keys) + // { + // head.Add(new { format = "H:mm", value = key.ToShortTimeString() }); + // } + + // return new + // { + // resource = new + // { + // manager = CRMReportResource.Manager, + // summary = CRMReportResource.Sum, + // total = CRMReportResource.Total, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + // sheetName = CRMReportResource.SalesByManagersReport, + // header = CRMReportResource.SalesByManagersReport, + // header1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, + // header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol + // }, + // thead = head, + // tbody = body + // }; + //} + + //private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var res = new Dictionary>(); + + // var users = data.Select(x => x.UserId).Distinct().ToList(); + + // foreach (var userId in users) + // { + // var date = fromDate; + + // while (date < toDate) + // { + // if (res.ContainsKey(userId)) + // { + // res[userId].Add(date, 0); + // } + // else + // { + // res.Add(userId, new Dictionary { { date, 0 } }); + // } + + // date = date.AddDays(1); + // } + // } + + // foreach (var item in data) + // { + // var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); + + // if (itemDate < res[item.UserId].First().Key) + // itemDate = res[item.UserId].First().Key; + + // if (itemDate > res[item.UserId].Last().Key) + // itemDate = res[item.UserId].Last().Key; + + // res[item.UserId][itemDate] += item.Value; + // } + + // var body = new List>(); + + // foreach (var resItem in res) + // { + // var bodyItem = new List + // { + // data.First(x => x.UserId == resItem.Key).UserName + // }; + + // bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + + // body.Add(bodyItem); + // } + + // var head = new List(); + // var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); + // var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); + + // foreach (var key in res.First().Value.Keys) + // { + // head.Add(new { format = pattern, value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); + // } + + // return new + // { + // resource = new + // { + // manager = CRMReportResource.Manager, + // summary = CRMReportResource.Sum, + // total = CRMReportResource.Total, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + // sheetName = CRMReportResource.SalesByManagersReport, + // header = CRMReportResource.SalesByManagersReport, + // header1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, + // header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol + // }, + // thead = head, + // tbody = body + // }; + //} + + //private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var res = new Dictionary>(); + + // var users = data.Select(x => x.UserId).Distinct().ToList(); + + // foreach (var userId in users) + // { + // var date = fromDate; + + // while (date < toDate) + // { + // if (res.ContainsKey(userId)) + // { + // res[userId].Add(date, 0); + // } + // else + // { + // res.Add(userId, new Dictionary { { date, 0 } }); + // } + + // date = date.AddMonths(1); + // } + // } + + // foreach (var item in data) + // { + // var itemDate = new DateTime(item.Date.Year, item.Date.Month, 1); + + // if (itemDate < res[item.UserId].First().Key) + // itemDate = res[item.UserId].First().Key; + + // if (itemDate > res[item.UserId].Last().Key) + // itemDate = res[item.UserId].Last().Key; + + // res[item.UserId][itemDate] += item.Value; + // } + + // var body = new List>(); + + // foreach (var resItem in res) + // { + // var bodyItem = new List + // { + // data.First(x => x.UserId == resItem.Key).UserName + // }; + + // bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + + // body.Add(bodyItem); + // } + + // var head = new List(); + + // foreach (var key in res.First().Value.Keys) + // { + // head.Add(new { format = "MMM-yy", value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); + // } + + // return new + // { + // resource = new + // { + // manager = CRMReportResource.Manager, + // summary = CRMReportResource.Sum, + // total = CRMReportResource.Total, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + // sheetName = CRMReportResource.SalesByManagersReport, + // header = CRMReportResource.SalesByManagersReport, + // header1 = CRMReportResource.SalesByMonth + ", " + CRMSettings.DefaultCurrency.Symbol, + // header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName1 = CRMReportResource.SalesByMonth + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol + // }, + // thead = head, + // tbody = body + // }; + //} + + //#endregion + + + //#region SalesForecastReport + + //public bool CheckSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), + // x => x.DealMilestoneId, + // y => y.Id, + // (x, y) => new { x, y }) + // .Where(x => x.y.Status == DealMilestoneStatus.Open) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + // .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + //} + + //public object GetSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // var reportData = BuildSalesForecastReport(timePeriod, managers, defaultCurrency); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + //} + + //private List BuildSalesForecastReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // string dateSelector; + + // switch (timePeriod) + // { + // case ReportTimePeriod.CurrentWeek: + // case ReportTimePeriod.NextWeek: + // case ReportTimePeriod.CurrentMonth: + // case ReportTimePeriod.NextMonth: + // dateSelector = "d.expected_close_date as close_date"; + // break; + // case ReportTimePeriod.CurrentQuarter: + // case ReportTimePeriod.NextQuarter: + // case ReportTimePeriod.CurrentYear: + // case ReportTimePeriod.NextYear: + // dateSelector = "date_sub(date(d.expected_close_date), interval (extract(day from d.expected_close_date) - 1) day) as close_date"; + // break; + // default: + // return null; + // } + + // var sqlQuery = Query("crm_deal d") + // .Select(string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as value", defaultCurrency), + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 + // end) as value_with_probability", defaultCurrency), + // dateSelector) + // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("close_date"); + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesForecast); + //} + + //private SalesForecast ToSalesForecast(object[] row) + //{ + // return new SalesForecast + // { + // Value = Convert.ToDecimal(row[0]), + // ValueWithProbability = Convert.ToDecimal(row[1]), + // Date = Convert.ToDateTime(row[2]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[2])) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, List data) + //{ + // switch (timePeriod) + // { + // case ReportTimePeriod.CurrentWeek: + // case ReportTimePeriod.NextWeek: + // case ReportTimePeriod.CurrentMonth: + // case ReportTimePeriod.NextMonth: + // return GenerateReportDataByDays(timePeriod, data); + // case ReportTimePeriod.CurrentQuarter: + // case ReportTimePeriod.NextQuarter: + // case ReportTimePeriod.CurrentYear: + // case ReportTimePeriod.NextYear: + // return GenerateReportByMonths(timePeriod, data); + // default: + // return null; + // } + //} + + //private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var res = new Dictionary>(); + + // var date = fromDate; + + // while (date < toDate) + // { + // res.Add(date, new Tuple(0, 0)); + // date = date.AddDays(1); + // } + + // foreach (var item in data) + // { + // var key = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); + + // if (key < res.First().Key) + // key = res.First().Key; + + // if (key > res.Last().Key) + // key = res.Last().Key; + + // res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, + // res[key].Item2 + item.Value); + // } + + // var body = new List>(); + // var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); + // var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); + + // foreach (var resItem in res) + // { + // var bodyItem = new List + // { + // new {format = pattern, value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, + // new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, + // new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} + // }; + + // body.Add(bodyItem); + // } + + // var head = new List + // { + // CRMReportResource.Day, + // CRMReportResource.WithRespectToProbability, + // CRMReportResource.IfAllOpportunitiesWon + // }; + + // return new + // { + // resource = new + // { + // total = CRMReportResource.Total, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + // sheetName = CRMReportResource.SalesForecastReport, + // header = CRMReportResource.SalesForecastReport, + // header1 = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol + // }, + // thead = head, + // tbody = body + // }; + //} + + //private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var res = new Dictionary>(); + + // var date = fromDate; + + // while (date < toDate) + // { + // res.Add(date, new Tuple(0, 0)); + // date = date.AddMonths(1); + // } + + // foreach (var item in data) + // { + // var key = new DateTime(item.Date.Year, item.Date.Month, 1); + + // if (key < res.First().Key) + // key = res.First().Key; + + // if (key > res.Last().Key) + // key = res.Last().Key; + + // res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, + // res[key].Item2 + item.Value); + // } + + // var body = new List>(); + + // foreach (var resItem in res) + // { + // var bodyItem = new List + // { + // new {format = "MMM-yy", value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, + // new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, + // new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} + // }; + + // body.Add(bodyItem); + // } + + // var head = new List + // { + // CRMReportResource.Month, + // CRMReportResource.WithRespectToProbability, + // CRMReportResource.IfAllOpportunitiesWon + // }; + + // return new + // { + // resource = new + // { + // total = CRMReportResource.Total, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + // sheetName = CRMReportResource.SalesForecastReport, + // header = CRMReportResource.SalesForecastReport, + // header1 = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol + // }, + // thead = head, + // tbody = body + // }; + //} + + //#endregion + + + //#region SalesFunnelReport + + //public bool CheckSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Deals) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + //} + + //public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // var reportData = BuildSalesFunnelReport(timePeriod, managers, defaultCurrency); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + //} + + //private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query("crm_deal_milestone m") + // .Select("m.status", "m.title", + // "count(d.id) as deals_count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency), + // "avg(if(m.status = 1, datediff(d.actual_close_date, d.create_on), 0)) as deals_duration") + // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & + // Exp.EqColumns("d.deal_milestone_id", "m.id") & + // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & + // Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "m.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .GroupBy("m.id") + // .OrderBy("m.sort_order", true); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesFunnel); + //} + + //private SalesFunnel ToSalesFunnel(object[] row) + //{ + // return new SalesFunnel + // { + // Status = (DealMilestoneStatus)Convert.ToInt32(row[0]), + // Title = Convert.ToString(row[1]), + // Count = Convert.ToInt32(row[2]), + // Value = Convert.ToDecimal(row[3]), + // Duration = Convert.ToInt32(row[4]) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, List data) + //{ + // var totalCount = data.Sum(x => x.Count); + + // if (totalCount == 0) return null; + + // var totalBudget = data.Sum(x => x.Value); + + // var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); + + // var reportData = data.Select(item => new List + // { + // item.Title, + // item.Status, + // item.Count, + // item.Value + // }).ToList(); + + // return new + // { + // resource = new + // { + // header = CRMReportResource.SalesFunnelReport, + // sheetName = CRMReportResource.SalesFunnelReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // chartName = CRMReportResource.SalesFunnelByCount, + // chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName2 = CRMReportResource.DealsCount, + // chartName3 = CRMReportResource.DealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + + // totalCountLabel = CRMReportResource.TotalDealsCount, + // totalCountValue = totalCount, + + // totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + // totalBudgetValue = totalBudget, + + // averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + // averageBidValue = totalBudget / totalCount, + + // averageDurationLabel = CRMReportResource.AverageDealsDuration, + // averageDurationValue = closed.Sum(x => x.Duration) / closed.Count, + + // header1 = CRMReportResource.ByCount, + // header2 = CRMReportResource.ByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + + // stage = CRMReportResource.Stage, + // count = CRMReportResource.Count, + // budget = CRMReportResource.Budget, + // conversion = CRMReportResource.Conversion, + + // deals = CRMDealResource.Deals, + // status0 = DealMilestoneStatus.Open.ToLocalizedString(), + // status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), + // status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() + // }, + // data = reportData + // }; + //} + + //#endregion + + + //#region WorkloadByContactsReport + + //public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Contacts) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + //} + + //public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // var reportData = BuildWorkloadByContactsReport(timePeriod, managers); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + //} + + //private List BuildWorkloadByContactsReport(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query(CRMDbContext.Contacts) + // .GroupJoin(Query(CRMDbContext.ListItem), + // x => x.ContactTypeId, + // y => y.Id, + // (x, y) => new { x, y }) + // .GroupJoin(Query(CRMDbContext.Deals), + // x => x.x.Id, + // y=> y.Id, + // (x,y) => new { x, y }) + + + + // var sqlQuery = Query("crm_contact c") + // .Select("c.create_by", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "i.id", + // "i.title", + // "count(c.id) as total", + // "count(d.id) as `with deals`") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & Exp.Eq("i.list_type", (int)ListType.ContactType)) + // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "c.tenant_id") & Exp.EqColumns("d.contact_id", "c.id")) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.create_by")) + // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("c.create_by", "i.id") + // .OrderBy("i.sort_order, i.title", true); + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByContacts); + //} + + //private WorkloadByContacts ToWorkloadByContacts(object[] row) + //{ + // return new WorkloadByContacts + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1]), + // CategoryId = Convert.ToInt32(row[2]), + // CategoryName = Convert.ToString(row[3]), + // Count = Convert.ToInt32(row[4]), + // WithDeals = Convert.ToInt32(row[5]) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + //{ + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByContactsReport, + // sheetName = CRMReportResource.WorkloadByContactsReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // header1 = CRMReportResource.NewContacts, + // header2 = CRMReportResource.NewContactsWithAndWithoutDeals, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total, + + // noSet = CRMCommonResource.NoSet, + // withDeals = CRMReportResource.ContactsWithDeals, + // withouthDeals = CRMReportResource.ContactsWithoutDeals, + // }, + // data = reportData + // }; + //} + + //#endregion + + + //#region WorkloadByTasksReport + + //public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => x.IsClosed) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + + + // var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => x.IsClosed) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Where(x => (!x.IsClosed && x.Deadline < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || + // (x.IsClosed && x.LastModifedOn > x.Deadline)) + // .Any(); + + // return sqlNewTasksQuery || + // sqlClosedTasksQuery || + // sqlOverdueTasksQuery; + //} + + //public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // var reportData = BuildWorkloadByTasksReport(timePeriod, managers); + + // if (reportData == null || !reportData.Any()) return null; + + // var hasData = reportData.Any(item => item.Value.Count > 0); + + // return hasData ? GenerateReportData(timePeriod, reportData) : null; + //} + + //private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlNewTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + // var sqlClosedTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Eq("t.is_closed", 1)) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + // var sqlOverdueTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + // Dictionary> res; + + // using (var tx = Db.BeginTransaction()) + // { + // res = new Dictionary> + // { + // {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, + // {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, + // {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} + // }; + + // tx.Commit(); + // } + + // return res; + //} + + //private WorkloadByTasks ToWorkloadByTasks(object[] row) + //{ + // return new WorkloadByTasks + // { + // CategoryId = Convert.ToInt32(row[0]), + // CategoryName = Convert.ToString(row[1]), + // UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), + // UserName = Convert.ToString(row[3]), + // Count = Convert.ToInt32(row[4]) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) + //{ + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByTasksReport, + // sheetName = CRMReportResource.WorkloadByTasksReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // header1 = CRMReportResource.ClosedTasks, + // header2 = CRMReportResource.NewTasks, + // header3 = CRMReportResource.OverdueTasks, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total + // }, + // data = reportData + // }; + //} + + //#endregion + + + //#region WorkloadByDealsReport + + //public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Deals) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) || + // (x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate))) + // .Any(); + //} + + //public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // var reportData = BuildWorkloadByDealsReport(timePeriod, managers, defaultCurrency); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + //} + + //private List BuildWorkloadByDealsReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query("crm_deal d") + // .Select("d.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "m.status", + // "count(d.id) as deals_count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + // Exp.Empty : + // Exp.Or(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), + // Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) + // .GroupBy("d.responsible_id", "m.status"); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByDeals); + //} + + //private WorkloadByDeals ToWorkloadByDeals(object[] row) + //{ + // return new WorkloadByDeals + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1]), + // Status = (DealMilestoneStatus)Convert.ToInt32(row[2]), + // Count = Convert.ToInt32(row[3]), + // Value = Convert.ToDecimal(row[4]) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, List data) + //{ + // var reportData = data.Select(item => new List + // { + // item.UserId, + // item.UserName, + // (int)item.Status, + // item.Count, + // item.Value + // }).ToList(); + + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByDealsReport, + // sheetName = CRMReportResource.WorkloadByDealsReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // chartName = CRMReportResource.DealsCount, + // chartName1 = CRMReportResource.DealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + + // header1 = CRMReportResource.ByCount, + // header2 = CRMReportResource.ByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total, + + // status0 = CRMReportResource.New, + // status1 = CRMReportResource.Won, + // status2 = CRMReportResource.Lost + // }, + // data = reportData + // }; + //} + + //#endregion + + + //#region WorkloadByInvoicesReport + + //public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Invoices) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= TenantUtil.DateTimeToUtc(toDate))) || + // (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || + // (x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || + // ((timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= TenantUtil.DateTimeToUtc(toDate))) && + // (x.Status == InvoiceStatus.Sent && x.DueDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()) || x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) + // .Any(); + //} + + //public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // var reportData = BuildWorkloadByInvoicesReport(timePeriod, managers); + + // if (reportData == null || !reportData.Any()) return null; + + // var hasData = reportData.Any(item => item.SentCount > 0 || item.PaidCount > 0 || item.RejectedCount > 0 || item.OverdueCount > 0); + + // return hasData ? GenerateReportData(timePeriod, reportData) : null; + //} + + //private List BuildWorkloadByInvoicesReport(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.issue_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); + // var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); + // var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); + // var overdue = Exp.Sum(Exp.If((timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.due_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) & Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); + + // var sqlQuery = Query("crm_invoice i") + // .Select("i.create_by", "concat(u.firstname, ' ', u.lastname) as full_name") + // .Select(sent) + // .Select(paid) + // .Select(rejected) + // .Select(overdue) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "i.tenant_id") & Exp.EqColumns("u.id", "i.create_by")) + // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + // .GroupBy("i.create_by"); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByInvoices); + //} + + //private WorkloadByInvoices ToWorkloadByInvoices(object[] row) + //{ + // return new WorkloadByInvoices + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1]), + // SentCount = Convert.ToInt32(row[2]), + // PaidCount = Convert.ToInt32(row[3]), + // RejectedCount = Convert.ToInt32(row[4]), + // OverdueCount = Convert.ToInt32(row[5]) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + //{ + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByInvoicesReport, + // sheetName = CRMReportResource.WorkloadByInvoicesReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // chartName = CRMReportResource.BilledInvoices, + // chartName1 = CRMInvoiceResource.Invoices, + + // header1 = CRMInvoiceResource.Invoices, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total, + + // billed = CRMReportResource.Billed, + // paid = CRMReportResource.Paid, + // rejected = CRMReportResource.Rejected, + // overdue = CRMReportResource.Overdue + // }, + // data = reportData + // }; + //} + + //#endregion + + + //#region GetWorkloadByViopReport + + //public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.VoipCalls) + // .Where(x => x.ParentCallId == "") + // .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? + // true : + // x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + //} + + //public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // var reportData = BuildWorkloadByViopReport(timePeriod, managers); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + //} + + //private List BuildWorkloadByViopReport(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query("crm_voip_calls c") + // .Select("c.answered_by", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "c.status", + // "count(c.id) as calls_count", + // "sum(c.dial_duration) as duration") + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.answered_by")) + // .Where(Exp.EqColumns("c.parent_call_id", "''")) + // .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + // Exp.Empty : + // Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("c.answered_by", "c.status"); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByViop); + //} + + //private WorkloadByViop ToWorkloadByViop(object[] row) + //{ + // return new WorkloadByViop + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1] ?? string.Empty), + // Status = (VoipCallStatus)Convert.ToInt32(row[2] ?? 0), + // Count = Convert.ToInt32(row[3]), + // Duration = Convert.ToInt32(row[4]) + // }; + //} + + //private object GenerateReportData(ReportTimePeriod timePeriod, List data) + //{ + // var reportData = data.Select(item => new List + // { + // item.UserId, + // item.UserName, + // (int) item.Status, + // item.Count, + // new {format = TimeFormat, value = SecondsToTimeFormat(item.Duration)} + // }).ToList(); + + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByVoipReport, + // sheetName = CRMReportResource.WorkloadByVoipReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // chartName = CRMReportResource.CallsCount, + // chartName1 = CRMReportResource.CallsDuration, + + // header1 = CRMReportResource.CallsCount, + // header2 = CRMReportResource.CallsDuration, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total, + + // incoming = CRMReportResource.Incoming, + // outcoming = CRMReportResource.Outcoming, + + // timeFormat = TimeFormat + // }, + // data = reportData + // }; + //} + + //private string SecondsToTimeFormat(int duration) + //{ + // var timeSpan = TimeSpan.FromSeconds(duration); + + // return string.Format("{0}:{1}:{2}", + // ((timeSpan.TotalHours < 10 ? "0" : "") + (int)timeSpan.TotalHours), + // ((timeSpan.Minutes < 10 ? "0" : "") + timeSpan.Minutes), + // ((timeSpan.Seconds < 10 ? "0" : "") + timeSpan.Seconds)); + //} + + //#endregion + + + //#region SummaryForThePeriodReport + + //public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var newDealsSqlQuery = Query(CRMDbContext.Deals) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // var closedDealsSqlQuery = Query(CRMDbContext.Deals) + // .Join(Query(CRMDbContext.DealMilestones), + // x => x.DealMilestoneId, + // y => y.Id, + // (x, y) => new { x, y }) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + // .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + // .Where(x => x.y.Status != DealMilestoneStatus.Open) + // .Any(); + + // var overdueDealsSqlQuery = Query(CRMDbContext.Deals) + // .Join(Query(CRMDbContext.DealMilestones), + // x => x.DealMilestoneId, + // y => y.Id, + // (x, y) => new { x, y }) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + // .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= TenantUtil.DateTimeToUtc(toDate)) + // .Where(x => (x.y.Status == DealMilestoneStatus.Open && x.x.ExpectedCloseDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || + // (x.y.Status == DealMilestoneStatus.ClosedAndWon && x.x.ActualCloseDate > x.x.ExpectedCloseDate)) + // .Any(); + + // var invoicesSqlQuery = Query(CRMDbContext.Invoices) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // var contactsSqlQuery = Query(CRMDbContext.Contacts) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + + // var tasksSqlQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + + // var voipSqlQuery = Query(CRMDbContext.VoipCalls) + // .Where(x => x.ParentCallId == "") + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) + // .Where(x => x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // return newDealsSqlQuery || + // closedDealsSqlQuery || + // overdueDealsSqlQuery || + // invoicesSqlQuery || + // contactsSqlQuery || + // tasksSqlQuery || + // voipSqlQuery; + //} + + //public object GetSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // var reportData = BuildSummaryForThePeriodReport(timePeriod, managers, defaultCurrency); + + // if (reportData == null) return null; + + // return GenerateSummaryForThePeriodReportData(timePeriod, reportData); + //} + + //private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var newDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + + // var wonDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon); + + // var lostDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.ClosedAndLost); + + // var overdueDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where( + // Exp.And( + // Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), + // Exp.Or(Exp.Eq("m.status", (int)DealMilestoneStatus.Open) & Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), + // Exp.Eq("m.status", (int)DealMilestoneStatus.ClosedAndWon) & Exp.Sql("d.actual_close_date > d.expected_close_date")))); + + // var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft), 1, 0)); + // var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid), 1, 0)); + // var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected), 1, 0)); + // var overdue = Exp.Sum(Exp.If(Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), + // Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); + + // var invoicesSqlQuery = Query("crm_invoice i") + // .Select(sent) + // .Select(paid) + // .Select(rejected) + // .Select(overdue) + // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + // .Where(Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + + + // var contactsSqlQuery = Query("crm_contact c") + // .Select("i.title", + // "count(c.id)") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + // Exp.EqColumns("i.id", "c.contact_type_id") & + // Exp.Eq("i.list_type", (int)ListType.ContactType)) + // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + // .Where(Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); + + // var tasksSqlQuery = Query("crm_task t") + // .Select("i.title") + // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 1) & Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), 1, 0))) + // .Select(Exp.Sum(Exp.If(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")), 1, 0))) + // .Select("count(t.id)") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); + + // var voipSqlQuery = Query("crm_voip_calls c") + // .Select("c.status", + // "count(c.id) as calls_count", + // "sum(c.dial_duration) as duration") + // .Where(Exp.EqColumns("c.parent_call_id", "''")) + // .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) + // .Where(Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("c.status"); + + // object res; + + // using (var tx = Db.BeginTransaction()) + // { + // res = new + // { + // DealsInfo = new + // { + // Created = Db.ExecuteList(newDealsSqlQuery), + // Won = Db.ExecuteList(wonDealsSqlQuery), + // Lost = Db.ExecuteList(lostDealsSqlQuery), + // Overdue = Db.ExecuteList(overdueDealsSqlQuery), + // }, + // InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), + // ContactsInfo = Db.ExecuteList(contactsSqlQuery), + // TasksInfo = Db.ExecuteList(tasksSqlQuery), + // VoipInfo = Db.ExecuteList(voipSqlQuery) + // }; + + // tx.Commit(); + // } + + // return res; + //} + + //private object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) + //{ + // return new + // { + // resource = new + // { + // header = CRMReportResource.SummaryForThePeriodReport, + // sheetName = CRMReportResource.SummaryForThePeriodReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + // chartName = CRMReportResource.DealsByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName1 = CRMReportResource.DealsByCount, + // chartName2 = CRMReportResource.ContactsByType, + // chartName3 = CRMReportResource.TasksForThePeriod, + // chartName4 = CRMReportResource.InvoicesForThePeriod, + // chartName5 = CRMReportResource.CallsForThePeriod, + // header1 = CRMDealResource.Deals, + // header2 = CRMContactResource.Contacts, + // header3 = CRMTaskResource.Tasks, + // header4 = CRMInvoiceResource.Invoices, + // header5 = CRMReportResource.Calls, + // byBudget = CRMReportResource.ByBudget, + // currency = CRMSettings.DefaultCurrency.Symbol, + // byCount = CRMReportResource.ByCount, + // item = CRMReportResource.Item, + // type = CRMReportResource.Type, + // won = CRMReportResource.Won, + // lost = CRMReportResource.Lost, + // created = CRMReportResource.Created, + // closed = CRMReportResource.Closed, + // overdue = CRMReportResource.Overdue, + // notSpecified = CRMCommonResource.NoSet, + // total = CRMReportResource.Total, + // status = CRMReportResource.Status, + // billed = CRMReportResource.Billed, + // paid = CRMReportResource.Paid, + // rejected = CRMReportResource.Rejected, + // count = CRMReportResource.Count, + // duration = CRMReportResource.Duration, + // incoming = CRMReportResource.Incoming, + // outcoming = CRMReportResource.Outcoming, + // missed = CRMReportResource.MissedCount, + // timeFormat = TimeFormat + // }, + // data = reportData + // }; + //} + + //#endregion + + + //#region SummaryAtThisMomentReport + + //public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var dealsSqlQuery = Query(CRMDbContext.Deals) + // .Join(CRMDbContext.DealMilestones, + // x => x.DealMilestoneId, + // y => y.Id, + // (x, y) => new { x, y }) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Where(x => x.y.Status == DealMilestoneStatus.Open) + // .Any(); + + + // var contactsSqlQuery = Query(CRMDbContext.Contacts) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // var tasksSqlQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // var invoicesSqlQuery = Query(CRMDbContext.Invoices) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // return dealsSqlQuery || + // contactsSqlQuery || + // tasksSqlQuery || + // invoicesSqlQuery; + + //} + + //public object GetSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // var reportData = BuildSummaryAtThisMomentReport(timePeriod, managers, defaultCurrency); + + // if (reportData == null) return null; + + // return GenerateSummaryAtThisMomentReportData(timePeriod, reportData); + //} + + //private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //{ + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var openDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.Open); + + // var overdueDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .Where(Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()))); + + // var nearDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow().AddDays(30)))); + + // var dealsByStageSqlQuery = Query("crm_deal_milestone m") + // .Select("m.title", + // "count(d.id) as deals_count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & + // Exp.EqColumns("d.deal_milestone_id", "m.id") & + // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & + // (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "m.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .GroupBy("m.id") + // .OrderBy("m.sort_order, m.title", true); + + // var contactsByTypeSqlQuery = Query("crm_contact c") + // .Select("i.title", + // "count(c.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + // Exp.EqColumns("i.id", "c.contact_type_id") & + // Exp.Eq("i.list_type", (int)ListType.ContactType)) + // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); + + // var contactsByStageSqlQuery = Query("crm_contact c") + // .Select("i.title", + // "count(c.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + // Exp.EqColumns("i.id", "c.status_id") & + // Exp.Eq("i.list_type", (int)ListType.ContactStatus)) + // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); + + // var tasksSqlQuery = Query("crm_task t") + // .Select("i.title") + // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0), 1, 0))) + // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0))) + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); + + // var sent = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent), 1, 0)); + // var overdue = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0)); + + // var invoicesSqlQuery = Query("crm_invoice i") + // .Select(sent) + // .Select(overdue) + // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); + + // object res; + + // using (var tx = Db.BeginTransaction()) + // { + // res = new + // { + // DealsInfo = new + // { + // Open = Db.ExecuteList(openDealsSqlQuery), + // Overdue = Db.ExecuteList(overdueDealsSqlQuery), + // Near = Db.ExecuteList(nearDealsSqlQuery), + // ByStage = Db.ExecuteList(dealsByStageSqlQuery) + // }, + // ContactsInfo = new + // { + // ByType = Db.ExecuteList(contactsByTypeSqlQuery), + // ByStage = Db.ExecuteList(contactsByStageSqlQuery) + // }, + // TasksInfo = Db.ExecuteList(tasksSqlQuery), + // InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), + // }; + + // tx.Commit(); + // } + + // return res; + //} + + //private object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) + //{ + // return new + // { + // resource = new + // { + // header = CRMReportResource.SummaryAtThisMomentReport, + // sheetName = CRMReportResource.SummaryAtThisMomentReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + // chartName = CRMReportResource.DealsByStatus + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName1 = CRMReportResource.DealsByStage + ", " + CRMSettings.DefaultCurrency.Symbol, + // chartName2 = CRMReportResource.ContactsByType, + // chartName3 = CRMReportResource.ContactsByStage, + // chartName4 = CRMReportResource.TasksByStatus, + // chartName5 = CRMReportResource.InvoicesByStatus, + // header1 = CRMDealResource.Deals, + // header2 = CRMContactResource.Contacts, + // header3 = CRMTaskResource.Tasks, + // header4 = CRMInvoiceResource.Invoices, + // budget = CRMReportResource.Budget + ", " + CRMSettings.DefaultCurrency.Symbol, + // count = CRMReportResource.Count, + // open = CRMReportResource.Opened, + // overdue = CRMReportResource.Overdue, + // near = CRMReportResource.Near, + // stage = CRMReportResource.Stage, + // temperature = CRMContactResource.ContactStage, + // type = CRMReportResource.Type, + // total = CRMReportResource.Total, + // billed = CRMReportResource.Billed, + // notSpecified = CRMCommonResource.NoSet, + // status = CRMReportResource.Status, + // }, + // data = reportData + // }; + //} + + //#endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index d9c7e1b94f7..4089ea9cfee 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -443,20 +443,20 @@ private String GetPath(int contactID, int entityID, EntityType entityType) if (contactID == 0) return String.Empty; if (entityID == 0) - return DaoFactory.ContactDao.GetByID(contactID).GetTitle(); + return DaoFactory.GetContactDao().GetByID(contactID).GetTitle(); switch (entityType) { case EntityType.Company: case EntityType.Person: case EntityType.Contact: - var contact = DaoFactory.ContactDao.GetByID(contactID); + var contact = DaoFactory.GetContactDao().GetByID(contactID); return contact == null ? string.Empty : contact.GetTitle(); case EntityType.Opportunity: - var opportunity = DaoFactory.DealDao.GetByID(entityID); + var opportunity = DaoFactory.GetDealDao().GetByID(entityID); return opportunity == null ? string.Empty : opportunity.Title; case EntityType.Case: - var @case = DaoFactory.CasesDao.GetByID(entityID); + var @case = DaoFactory.GetCasesDao().GetByID(entityID); return @case == null ? string.Empty : @case.Title; default: throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index e370c990528..db1090b01ac 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -57,7 +57,9 @@ public CachedTaskDao(DbContextManager dbContextManager, TenantUtil tenantUtil, FactoryIndexer factoryIndexer, IOptionsMonitor logger, - IHttpContextAccessor httpContextAccessor + IHttpContextAccessor httpContextAccessor, + DbContextManager userDbContext, + DbContextManager coreDbContext ) : base(dbContextManager, tenantManager, @@ -65,7 +67,10 @@ IHttpContextAccessor httpContextAccessor cRMSecurity, tenantUtil, factoryIndexer, - logger) + logger, + userDbContext, + coreDbContext + ) { _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_task"); } @@ -115,7 +120,9 @@ public TaskDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, TenantUtil tenantUtil, FactoryIndexer factoryIndexer, - IOptionsMonitor logger + IOptionsMonitor logger, + DbContextManager userDbContext, + DbContextManager coreDbContext ) : base(dbContextManager, tenantManager, @@ -125,9 +132,14 @@ IOptionsMonitor logger CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; FactoryIndexer = factoryIndexer; - + UserDbContext = userDbContext.Value; + CoreDbContext = coreDbContext.Value; } + public CoreDbContext CoreDbContext { get; } + + public UserDbContext UserDbContext { get; } + public FactoryIndexer FactoryIndexer { get; } public TenantUtil TenantUtil { get; } @@ -428,157 +440,121 @@ public int GetTasksCount( } else { - var taskIds = new List(); - - // count tasks without entityId and only open contacts - taskIds = GetDbTaskByFilters(responsibleId, - categoryId, - isClosed, - fromDate, - toDate, - entityType, - entityId, - 0, - 0, - null).GroupJoin(CRMDbContext.Contacts, - x => x.ContactId, - y => y.Id, - (x, y) => new { x, y }) - .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) - .Where(x => x.y == null || - x.y.IsShared == null || - x.y.IsShared.Value == ShareType.Read || - x.y.IsShared.Value == ShareType.ReadWrite) - .Select(x => x.x.Id) - .ToList(); - - Logger.DebugFormat("End GetTasksCount: {0}. count tasks without entityId and only open contacts", DateTime.Now.ToString()); - - taskIds = GetDbTaskByFilters(responsibleId, - categoryId, - isClosed, - fromDate, - toDate, - entityType, - entityId, - 0, - 0, - null).GroupJoin(CRMDbContext.Contacts, - x => x.ContactId, - y => y.Id, - (x, y) => new { x, y }) - .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) - .Where(x => x.y != null || - x.y.IsShared == null || - x.y.IsShared.Value == ShareType.Read || - x.y.IsShared.Value == ShareType.ReadWrite) - .Select(x => x.x.Id) - .ToList(); - - sqlQuery = Query("crm_task tbl_tsk") - .Select("tbl_tsk.id") - .InnerJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) - .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_ctc.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & - Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & - Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Company|', tbl_ctc.id)")) - .Where(Exp.Eq("tbl_ctc.is_shared", 0)) - .Where(Exp.Eq("tbl_ctc.is_company", 1)); - - sqlQuery = GetDbTaskByFilters(responsibleId, - categoryId, - isClosed, - fromDate, - toDate, - entityType, - entityId, - 0, - 0, - null); - - // count tasks with entityId and only close contacts - taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - - Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); - - sqlQuery = Query("crm_task tbl_tsk") - .Select("tbl_tsk.id") - .InnerJoin("crm_contact tbl_ctc", Exp.EqColumns("tbl_tsk.contact_id", "tbl_ctc.id")) - .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_ctc.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & - Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & - Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Person|', tbl_ctc.id)")) - .Where(Exp.Eq("tbl_ctc.is_shared", 0)) - .Where(Exp.Eq("tbl_ctc.is_company", 0)); - - sqlQuery = GetDbTaskByFilters(responsibleId, - categoryId, - isClosed, - fromDate, - toDate, - entityType, - entityId, - 0, - 0, - null); - - // count tasks with entityId and only close contacts - taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - - Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); - - - sqlQuery = Query("crm_task tbl_tsk") - .Select("tbl_tsk.id") - .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & - Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & - Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Deal|', tbl_tsk.entity_id)")) - .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Opportunity) & Exp.Eq("tbl_tsk.contact_id", 0)); - - sqlQuery = GetDbTaskByFilters(responsibleId, - categoryId, - isClosed, - fromDate, - toDate, - entityType, - entityId, - 0, - 0, - null); - - // count tasks with entityId and without contact - taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - - Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); - - sqlQuery = Query("crm_task tbl_tsk") - .Select("tbl_tsk.id") - .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & - Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & - Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & - Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Cases|', tbl_tsk.entity_id)")) - .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Case) & Exp.Eq("tbl_tsk.contact_id", 0)); - - sqlQuery = GetDbTaskByFilters(responsibleId, - categoryId, - isClosed, - fromDate, - toDate, - entityType, - entityId, - 0, - 0, - null); - - // count tasks with entityId and without contact - taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); - - result = taskIds.Distinct().Count(); - - Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); - - Logger.Debug("Finish"); + throw new NotImplementedException(); + //var taskIds = new List(); + + //// PrivateTask + + + //// count tasks without entityId and only open contacts + //taskIds = GetDbTaskByFilters(responsibleId, + // categoryId, + // isClosed, + // fromDate, + // toDate, + // entityType, + // entityId, + // 0, + // 0, + // null).GroupJoin(Query(CRMDbContext.Contacts), + // x => x.ContactId, + // y => y.Id, + // (x, y) => new { x, y }) + // .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) + // .Where(x => + + // x.y == null || + // x.y.IsShared == null || + // x.y.IsShared.Value == ShareType.Read || + // x.y.IsShared.Value == ShareType.ReadWrite) + // .Select(x => x.x.Id) + // .ToList(); + + //Logger.DebugFormat("End GetTasksCount: {0}. count tasks without entityId and only open contacts", DateTime.Now.ToString()); + + //var idsFromAcl = CoreDbContext.Acl.Where(x => x.Tenant == TenantID && + // x.Action == CRMSecurity._actionRead.ID && + // x.Subject == SecurityContext.CurrentAccount.ID && + // (Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName + "%") || + // Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Person).FullName + "%"))) + // .Select(x => Convert.ToInt32(x.Object.Split('|', StringSplitOptions.None)[1])) + // .ToList(); + + //Query(CRMDbContext.Contacts).GroupBy(x => x.Id).Select(x => x.) + //taskIds.AddRange(GetDbTaskByFilters(responsibleId, + // categoryId, + // isClosed, + // fromDate, + // toDate, + // entityType, + // entityId, + // 0, + // 0, + // null).GroupJoin(CRMDbContext.Contacts, + // x => x.ContactId, + // y => y.Id, + // (x, y) => new { x, y }) + // .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) + // .Where(x => x.y != null && + // x.y.IsShared == 0 && + // idsFromAcl.Contains(x.y.Id)) + // .Select(x => x.x.Id) + // .ToList()); + + //Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); + + + //sqlQuery = Query("crm_task tbl_tsk") + // .Select("tbl_tsk.id") + // .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & + // Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & + // Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & + // Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Deal|', tbl_tsk.entity_id)")) + // .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Opportunity) & Exp.Eq("tbl_tsk.contact_id", 0)); + + //sqlQuery = GetDbTaskByFilters(responsibleId, + // categoryId, + // isClosed, + // fromDate, + // toDate, + // entityType, + // entityId, + // 0, + // 0, + // null); + + //// count tasks with entityId and without contact + //taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); + + //Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); + + //sqlQuery = Query("crm_task tbl_tsk") + // .Select("tbl_tsk.id") + // .InnerJoin("core_acl tbl_cl", Exp.EqColumns("tbl_tsk.tenant_id", "tbl_cl.tenant") & + // Exp.Eq("tbl_cl.subject", SecurityContext.CurrentAccount.ID.ToString()) & + // Exp.Eq("tbl_cl.action", CRMSecurity._actionRead.ID.ToString()) & + // Exp.EqColumns("tbl_cl.object", "CONCAT('ASC.CRM.Core.Entities.Cases|', tbl_tsk.entity_id)")) + // .Where(!Exp.Eq("tbl_tsk.entity_id", 0) & Exp.Eq("tbl_tsk.entity_type", (int)EntityType.Case) & Exp.Eq("tbl_tsk.contact_id", 0)); + + //sqlQuery = GetDbTaskByFilters(responsibleId, + // categoryId, + // isClosed, + // fromDate, + // toDate, + // entityType, + // entityId, + // 0, + // 0, + // null); + + //// count tasks with entityId and without contact + //taskIds.AddRange(Db.ExecuteList(sqlQuery).Select(item => Convert.ToInt32(item[0])).ToList()); + + //result = taskIds.Distinct().Count(); + + //Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and without contact", DateTime.Now.ToString()); + + //Logger.Debug("Finish"); } } @@ -717,15 +693,17 @@ private IQueryable GetDbTaskByFilters( break; case TaskSortedByType.ContactManager: { - - - - - sqlQuery.LeftOuterJoin("core_user u", Exp.EqColumns(aliasPrefix + "responsible_id", "u.id")) - .OrderBy("case when u.lastname is null or u.lastname = '' then 1 else 0 end, u.lastname", orderBy.IsAsc) - .OrderBy("case when u.firstname is null or u.firstname = '' then 1 else 0 end, u.firstname", orderBy.IsAsc) - .OrderBy(aliasPrefix + "deadline", true) - .OrderBy(aliasPrefix + "title", true); + sqlQuery = sqlQuery.GroupJoin(UserDbContext.Users.Where(x => x.Tenant == TenantID), + x => x.ResponsibleId, + y => y.Id, + (x, y) => new { x, y } + ) + .SelectMany(x => x.y.DefaultIfEmpty(), (x,y) => new { x.x,y }) + .OrderBy("x.y.LastName", orderBy.IsAsc) + .OrderBy("x.y.FirstName", orderBy.IsAsc) + .OrderBy(x => x.x.Deadline) + .OrderBy(x => x.x.Title) + .Select(x => x.x); } break; @@ -913,7 +891,9 @@ private Task SaveOrUpdateTaskInDb(Task newTask) } - FactoryIndexer.IndexAsync(newTask); + + + FactoryIndexer.IndexAsync(TasksWrapper.FromTask(TenantID, newTask)); return newTask; } @@ -955,7 +935,7 @@ private int SaveTaskInDb(Task newTask) newTask.ID = dbTask.Id; - FactoryIndexer.IndexAsync(newTask); + FactoryIndexer.IndexAsync(TasksWrapper.FromTask(TenantID, newTask)); return newTask.ID; } @@ -992,7 +972,7 @@ public virtual void DeleteTask(int taskID) _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); - FactoryIndexer.DeleteAsync(task); + FactoryIndexer.DeleteAsync(TasksWrapper.FromTask(TenantID, task)); } public List CreateByTemplate(List templateItems, EntityType entityType, int entityID) diff --git a/products/ASC.CRM/Server/Core/Entities/Filter.cs b/products/ASC.CRM/Server/Core/Entities/Filter.cs index 2c7e5f4f375..df8f5ce34a0 100644 --- a/products/ASC.CRM/Server/Core/Entities/Filter.cs +++ b/products/ASC.CRM/Server/Core/Entities/Filter.cs @@ -119,7 +119,7 @@ public override ICollection GetItemsByFilter(DaoFactory daofactory) sortBy = SortedByType.Title; } - return daofactory.CasesDao.GetCases( + return daofactory.GetCasesDao().GetCases( FilterValue, 0, IsClosed, @@ -222,7 +222,7 @@ public override ICollection GetItemsByFilter(DaoFactory daofactory) sortBy = TaskSortedByType.DeadLine; } - return daofactory.TaskDao.GetTasks( + return daofactory.GetTaskDao().GetTasks( FilterValue, ResponsibleId, CategoryId, @@ -346,7 +346,7 @@ public override ICollection GetItemsByFilter(DaoFactory daofactory) stageType = stage; } - return daofactory.DealDao.GetDeals( + return daofactory.GetDealDao().GetDeals( FilterValue, ResponsibleId, OpportunityStageId, @@ -474,7 +474,7 @@ public override ICollection GetItemsByFilter(DaoFactory daofactory) ContactListViewType contactListViewType; EnumExtension.TryParse(ContactListView, true, out contactListViewType); - return daofactory.ContactDao.GetContacts( + return daofactory.GetContactDao().GetContacts( FilterValue, Tags, ContactStage, @@ -544,7 +544,7 @@ public override ICollection GetItemsByFilter(DaoFactory daofactory) InvoiceItemSortedByType sortBy; EnumExtension.TryParse(SortBy, true, out sortBy); - return daofactory.InvoiceItemDao.GetInvoiceItems( + return daofactory.GetInvoiceItemDao().GetInvoiceItems( FilterValue, 0, InventoryStock, diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs index aabe8c95315..7c6887f0d27 100644 --- a/products/ASC.CRM/Server/Core/Entities/Invoice.cs +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -99,7 +99,7 @@ public List GetInvoiceLines(DaoFactory daoFactory) public File GetInvoiceFile(DaoFactory daoFactory) { - return daoFactory.FileDao.GetFile(FileID, 0); + return daoFactory.GetFileDao.GetFile(FileID, 0); } public decimal GetInvoiceCost(DaoFactory daoFactory) @@ -116,7 +116,7 @@ public decimal GetInvoiceCost(DaoFactory daoFactory) decimal lineTax1 = 0; if (line.InvoiceTax1ID > 0) { - var tax1 = daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax1ID); + var tax1 = daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID); if (tax1 != null) { lineTax1 = Math.Round(linePrice * tax1.Rate / 100, 2); @@ -126,7 +126,7 @@ public decimal GetInvoiceCost(DaoFactory daoFactory) decimal lineTax2 = 0; if (line.InvoiceTax2ID > 0) { - var tax2 = daoFactory.InvoiceTaxDao.GetByID(line.InvoiceTax2ID); + var tax2 = daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID); if (tax2 != null) { lineTax2 = Math.Round(linePrice * tax2.Rate / 100, 2); diff --git a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs index 81b8c232448..d1880914576 100644 --- a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs @@ -26,8 +26,11 @@ using System; using ASC.Core; +using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using Microsoft.Extensions.DependencyInjection; + namespace ASC.Web.CRM.Core.Search { public sealed class CasesWrapper : Wrapper @@ -40,13 +43,15 @@ public sealed class CasesWrapper : Wrapper protected override string Table { get { return "crm_case"; } } - public static implicit operator CasesWrapper(ASC.CRM.Core.Entities.Cases d) + public static CasesWrapper GetTasksWrapper(IServiceProvider serviceProvider, Cases item) { + var tenantManager = serviceProvider.GetService(); + return new CasesWrapper { - Id = d.ID, - Title = d.Title, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + Id = item.ID, + Title = item.Title, + TenantId = tenantManager.CurrentTenant.TenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs index a10a52787cd..dd778055b8f 100644 --- a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs @@ -29,6 +29,9 @@ using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using Microsoft.Extensions.DependencyInjection; + + namespace ASC.Web.CRM.Core.Search { public class ContactsWrapper : Wrapper @@ -66,29 +69,29 @@ public static implicit operator ContactsWrapper(Contact d) return d as Company; } - public static implicit operator ContactsWrapper(Person d) - { + public static ContactsWrapper FromCompany(int tenantId, Company d) + { return new ContactsWrapper { Id = d.ID, - Title = d.JobTitle, - FirstName = d.FirstName, - LastName = d.LastName, + CompanyName = d.CompanyName, Industry = d.Industry, Notes = d.About, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } - public static implicit operator ContactsWrapper(Company d) + public static ContactsWrapper FromPerson(int tenantId, Person d) { return new ContactsWrapper { Id = d.ID, - CompanyName = d.CompanyName, + Title = d.JobTitle, + FirstName = d.FirstName, + LastName = d.LastName, Industry = d.Industry, Notes = d.About, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs b/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs index 9665c1c67da..3712fc18903 100644 --- a/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs @@ -29,6 +29,9 @@ using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using Microsoft.Extensions.DependencyInjection; + + namespace ASC.Web.CRM.Core.Search { public sealed class DealsWrapper : Wrapper @@ -44,14 +47,14 @@ public sealed class DealsWrapper : Wrapper protected override string Table { get { return "crm_deal"; } } - public static implicit operator DealsWrapper(Deal deal) - { + public static DealsWrapper FromDeal(int tenantId, Deal deal) + { return new DealsWrapper { Id = deal.ID, Title = deal.Title, Description = deal.Description, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs b/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs index 5bfb737a8a7..124c4659762 100644 --- a/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs @@ -24,13 +24,13 @@ */ -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.Core; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using System; +using System.Collections.Generic; +using System.Linq; + namespace ASC.Web.CRM.Core.Search { @@ -47,7 +47,9 @@ protected override string IndexName } } - public static EmailWrapper ToEmailWrapper(Contact contact, List contactInfo) + public static EmailWrapper GetEmailWrapper(int tenantId, + Contact contact, + List contactInfo) { var result = new EmailWrapper(); @@ -62,10 +64,12 @@ public static EmailWrapper ToEmailWrapper(Contact contact, List con LastName = person.LastName, Industry = person.Industry, Notes = person.About, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } + var company = contact as Company; + if (company != null) { result = new EmailWrapper @@ -74,17 +78,17 @@ public static EmailWrapper ToEmailWrapper(Contact contact, List con CompanyName = company.CompanyName, Industry = company.Industry, Notes = company.About, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } - result.EmailInfoWrapper = contactInfo.Select(r => (EmailInfoWrapper)r).ToList(); + result.EmailInfoWrapper = contactInfo.Select(r => ASC.Web.CRM.Core.Search.EmailInfoWrapper.FromContactInfo(tenantId, r)).ToList(); return result; } } - public class EmailInfoWrapper: Wrapper + public class EmailInfoWrapper : Wrapper { [ColumnLastModified("last_modifed_on")] public override DateTime LastModifiedOn { get; set; } @@ -100,7 +104,7 @@ public class EmailInfoWrapper: Wrapper protected override string Table { get { return "crm_contact_info"; } } - public static implicit operator EmailInfoWrapper(ContactInfo cf) + public static EmailInfoWrapper FromContactInfo(int tenantId, ContactInfo cf) { return new EmailInfoWrapper { @@ -108,7 +112,7 @@ public static implicit operator EmailInfoWrapper(ContactInfo cf) ContactId = cf.ContactID, Data = cf.Data, Type = (int)cf.InfoType, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs b/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs index 7783c4039d6..a2a0f7511bc 100644 --- a/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs @@ -29,6 +29,9 @@ using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using Microsoft.Extensions.DependencyInjection; + + namespace ASC.Web.CRM.Core.Search { public sealed class EventsWrapper : Wrapper @@ -50,8 +53,8 @@ public sealed class EventsWrapper : Wrapper protected override string Table { get { return "crm_relationship_event"; } } - public static implicit operator EventsWrapper(RelationshipEvent relationshipEvent) - { + public static EventsWrapper FromEvent(int tenantId, RelationshipEvent relationshipEvent) + { return new EventsWrapper { Id = relationshipEvent.ID, @@ -59,7 +62,7 @@ public static implicit operator EventsWrapper(RelationshipEvent relationshipEven EntityId = relationshipEvent.EntityID, EntityType = (int)relationshipEvent.EntityType, Content = relationshipEvent.Content, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs b/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs index 38ff55187ab..41adab8dd57 100644 --- a/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs @@ -26,8 +26,11 @@ using System; using ASC.Core; +using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using Microsoft.Extensions.DependencyInjection; + namespace ASC.Web.CRM.Core.Search { public sealed class FieldsWrapper : Wrapper @@ -49,15 +52,17 @@ public sealed class FieldsWrapper : Wrapper protected override string Table { get { return "crm_field_value"; } } - public static implicit operator FieldsWrapper(ASC.CRM.Core.Entities.CustomField cf) + public static FieldsWrapper GetEventsWrapper(IServiceProvider serviceProvider, CustomField cf) { + var tenantManager = serviceProvider.GetService(); + return new FieldsWrapper { Id = cf.ID, EntityId = cf.EntityID, EntityType = (int)cf.EntityType, Value = cf.Value, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantManager.GetCurrentTenant().TenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs index 74c85419f15..534a1eaf428 100644 --- a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs @@ -29,13 +29,24 @@ using ASC.Common.Logging; using ASC.Core; using ASC.CRM.Core; +using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; +using Microsoft.Extensions.DependencyInjection; + namespace ASC.Web.CRM.Core.Search { public class InfoWrapper : Wrapper { + public InfoWrapper(IOptionsMonitor logger) + { + Logger = logger.Get("ASC"); + } + + public ILog Logger { get; } + [ColumnLastModified("last_modifed_on")] public override DateTime LastModifiedOn { get; set; } @@ -46,7 +57,7 @@ public class InfoWrapper : Wrapper public int Type { get; set; } [Column("data", 3)] - public string Data + public string Data { get { @@ -59,7 +70,7 @@ public string Data foreach (var o in obj.Values()) { var val = o.ToString(); - if(!string.IsNullOrEmpty(val)) + if (!string.IsNullOrEmpty(val)) { result.AppendFormat("{0} ", val); } @@ -68,7 +79,7 @@ public string Data } catch (Exception e) { - LogManager.GetLogger("ASC").Error("Index Contact Adrress Parse", e); + Logger.Error("Index Contact Adrress Parse", e); } return ""; @@ -79,22 +90,25 @@ public string Data set { data = value; - } + } } protected override string Table { get { return "crm_contact_info"; } } private string data; - public static implicit operator InfoWrapper(ContactInfo cf) + public static InfoWrapper FromCompany(IServiceProvider serviceProvider, ContactInfo cf) { - return new InfoWrapper + var logger = serviceProvider.GetService>(); + var tenantManager = serviceProvider.GetService(); + + return new InfoWrapper(logger) { Id = cf.ID, ContactId = cf.ContactID, Data = cf.Data, Type = (int)cf.InfoType, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantManager.GetCurrentTenant().TenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs b/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs index e151316682e..4ca0af304cd 100644 --- a/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs @@ -26,8 +26,12 @@ using System; using ASC.Core; +using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using Microsoft.Extensions.DependencyInjection; + + namespace ASC.Web.CRM.Core.Search { public sealed class InvoicesWrapper : Wrapper @@ -49,8 +53,8 @@ public sealed class InvoicesWrapper : Wrapper protected override string Table { get { return "crm_invoice"; } } - public static implicit operator InvoicesWrapper(ASC.CRM.Core.Entities.Invoice invoice) - { + public static InvoicesWrapper FromInvoice(int tenantId, Invoice invoice) + { return new InvoicesWrapper { Id = invoice.ID, @@ -58,7 +62,7 @@ public static implicit operator InvoicesWrapper(ASC.CRM.Core.Entities.Invoice in Terms = invoice.Terms, Description = invoice.Description, PurchaseOrderNumber = invoice.PurchaseOrderNumber, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId + TenantId = tenantId }; } } diff --git a/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs b/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs index 7fdb9b55148..9c0756e71c6 100644 --- a/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs @@ -29,6 +29,9 @@ using ASC.CRM.Core.Entities; using ASC.ElasticSearch; +using Microsoft.Extensions.DependencyInjection; + + namespace ASC.Web.CRM.Core.Search { public sealed class TasksWrapper : Wrapper @@ -44,15 +47,15 @@ public sealed class TasksWrapper : Wrapper protected override string Table { get { return "crm_task"; } } - public static implicit operator TasksWrapper(Task task) - { + public static TasksWrapper FromTask(int tenantId, Task task) + { return new TasksWrapper { Id = task.ID, - Title = task.Title, + Title = task.Description, Description = task.Description, - TenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId - }; + TenantId = tenantId + }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs index 3b8a31294bd..6b1b3bc4b0c 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs @@ -78,7 +78,7 @@ public ISecurityObjectId InheritFrom(ISecurityObjectId objectId) CompanyName = "fakeCompany" }; - // return _daoFactory.ContactDao.GetByID(contactId); + // return _daoFactory.GetContactDao().GetByID(contactId); switch (entityType) { @@ -89,14 +89,14 @@ public ISecurityObjectId InheritFrom(ISecurityObjectId objectId) ID = entityId, Title = "fakeDeal" }; - // return _daoFactory.DealDao.GetByID(entityId); + // return _daoFactory.GetDealDao().GetByID(entityId); case EntityType.Case: return new Cases { ID = entityId, Title = "fakeCases" }; - // return _daoFactory.CasesDao.GetByID(entityId); + // return _daoFactory.GetCasesDao().GetByID(entityId); } return null; diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 9e01a63e57e..ff6fc7fe449 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -60,7 +60,8 @@ public CRMSecurity(SecurityContext securityContext, DisplayUserSettingsHelper displayUserSettingsHelper, DaoFactory daoFactory, WebItemSecurity webItemSecurity, - PermissionContext permissionContext) + PermissionContext permissionContext, + CurrencyProvider currencyProvider) { SecurityContext = securityContext; AuthorizationManager = authorizationManager; @@ -69,8 +70,11 @@ public CRMSecurity(SecurityContext securityContext, DaoFactory = daoFactory; WebItemSecurity = webItemSecurity; PermissionContext = permissionContext; + CurrencyProvider = currencyProvider; } - + + public CurrencyProvider CurrencyProvider { get; } + public PermissionContext PermissionContext { get; } public WebItemSecurity WebItemSecurity { get; } @@ -266,19 +270,19 @@ public bool CanAccessTo(RelationshipEvent relationshipEvent, Guid userId) if (relationshipEvent.ContactID > 0) { - var contactObj = daoFactory.ContactDao.GetByID(relationshipEvent.ContactID); + var contactObj = daoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); if (contactObj != null) return CanAccessTo(contactObj, userId); } if (relationshipEvent.EntityType == EntityType.Case) { - var caseObj = daoFactory.CasesDao.GetByID(relationshipEvent.EntityID); + var caseObj = daoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); if (caseObj != null) return CanAccessTo(caseObj, userId); } if (relationshipEvent.EntityType == EntityType.Opportunity) { - var dealObj = daoFactory.DealDao.GetByID(relationshipEvent.EntityID); + var dealObj = daoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); if (dealObj != null) return CanAccessTo(dealObj, userId); } @@ -333,19 +337,19 @@ public bool CanAccessTo(Task task, Guid userId) var daoFactory = scope.Resolve(); if (task.ContactID > 0) { - var contactObj = daoFactory.ContactDao.GetByID(task.ContactID); + var contactObj = daoFactory.GetContactDao().GetByID(task.ContactID); if (contactObj != null) return CanAccessTo(contactObj, userId); } if (task.EntityType == EntityType.Case) { - var caseObj = daoFactory.CasesDao.GetByID(task.EntityID); + var caseObj = daoFactory.GetCasesDao().GetByID(task.EntityID); if (caseObj != null) return CanAccessTo(caseObj, userId); } if (task.EntityType == EntityType.Opportunity) { - var dealObj = daoFactory.DealDao.GetByID(task.EntityID); + var dealObj = daoFactory.GetDealDao().GetByID(task.EntityID); if (dealObj != null) return CanAccessTo(dealObj, userId); } @@ -366,10 +370,10 @@ public bool CanAccessTo(Invoice invoice, Guid userId) { var daoFactory = scope.Resolve(); if (invoice.ContactID > 0) - return CanAccessTo(daoFactory.ContactDao.GetByID(invoice.ContactID), userId); + return CanAccessTo(daoFactory.GetContactDao().GetByID(invoice.ContactID), userId); if (invoice.EntityType == EntityType.Opportunity) - return CanAccessTo(daoFactory.DealDao.GetByID(invoice.EntityID), userId); + return CanAccessTo(daoFactory.GetDealDao().GetByID(invoice.EntityID), userId); return false; } @@ -416,7 +420,7 @@ public bool CanEdit(RelationshipEvent relationshipEvent) if (relationshipEvent.ContactID > 0) { - var contactObj = daoFactory.ContactDao.GetByID(relationshipEvent.ContactID); + var contactObj = daoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); if (contactObj != null) { if(CanEdit(contactObj)) return true; @@ -427,7 +431,7 @@ public bool CanEdit(RelationshipEvent relationshipEvent) if (relationshipEvent.EntityType == EntityType.Case) { - var caseObj = daoFactory.CasesDao.GetByID(relationshipEvent.EntityID); + var caseObj = daoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); if (caseObj != null) { if (CanEdit(caseObj)) return true; @@ -438,7 +442,7 @@ public bool CanEdit(RelationshipEvent relationshipEvent) if (relationshipEvent.EntityType == EntityType.Opportunity) { - var dealObj = daoFactory.DealDao.GetByID(relationshipEvent.EntityID); + var dealObj = daoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); if (dealObj != null) { if (CanEdit(dealObj)) return true; @@ -487,7 +491,7 @@ public bool CanDelete(Contact contact) { using (var scope = DIHelper.Resolve()) { - return CanEdit(contact) && scope.Resolve().ContactDao.CanDelete(contact.ID); + return CanEdit(contact) && scope.Resolve().GetContactDao().CanDelete(contact.ID); } } @@ -500,7 +504,7 @@ public bool CanDelete(InvoiceItem invoiceItem) { using (var scope = DIHelper.Resolve()) { - return CanEdit(invoiceItem) && scope.Resolve().InvoiceItemDao.CanDelete(invoiceItem.ID); + return CanEdit(invoiceItem) && scope.Resolve().GetInvoiceItemDao().CanDelete(invoiceItem.ID); } } @@ -508,7 +512,7 @@ public bool CanDelete(InvoiceTax invoiceTax) { using (var scope = DIHelper.Resolve()) { - return CanEdit(invoiceTax) && scope.Resolve().InvoiceTaxDao.CanDelete(invoiceTax.ID); + return CanEdit(invoiceTax) && scope.Resolve().GetInvoiceTaxDao().CanDelete(invoiceTax.ID); } } @@ -682,12 +686,12 @@ public void DemandCreateOrUpdate(Deal deal) using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); - var listItem = daoFactory.DealMilestoneDao.GetByID(deal.DealMilestoneID); + var listItem = daoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); if (listItem == null) throw new ArgumentException(CRMErrorsResource.DealMilestoneNotFound); if (deal.ContactID != 0) { - var contact = daoFactory.ContactDao.GetByID(deal.ContactID); + var contact = daoFactory.GetContactDao().GetByID(deal.ContactID); if (contact == null) throw new ArgumentException(); if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); @@ -719,13 +723,13 @@ public void DemandCreateOrUpdate(InvoiceLine line, Invoice targetInvoice) using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); - if (!daoFactory.InvoiceItemDao.IsExist(line.InvoiceItemID)) + if (!daoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) throw new ArgumentException(); - if (line.InvoiceTax1ID > 0 && !daoFactory.InvoiceTaxDao.IsExist(line.InvoiceTax1ID)) + if (line.InvoiceTax1ID > 0 && !daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) throw new ArgumentException(); - if (line.InvoiceTax2ID > 0 && !daoFactory.InvoiceTaxDao.IsExist(line.InvoiceTax2ID)) + if (line.InvoiceTax2ID > 0 && !daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) throw new ArgumentException(); } } @@ -743,24 +747,24 @@ public void DemandCreateOrUpdate(Invoice invoice) using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); - var contact = daoFactory.ContactDao.GetByID(invoice.ContactID); + var contact = daoFactory.GetContactDao().GetByID(invoice.ContactID); if (contact == null) throw new ArgumentException(); if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); if (invoice.ConsigneeID != 0 && invoice.ConsigneeID != invoice.ContactID) { - var consignee = daoFactory.ContactDao.GetByID(invoice.ConsigneeID); + var consignee = daoFactory.GetContactDao().GetByID(invoice.ConsigneeID); if (consignee == null) throw new ArgumentException(); if (!CanAccessTo(consignee)) throw new SecurityException(CRMErrorsResource.AccessDenied); } if (invoice.EntityID != 0) { - var deal = daoFactory.DealDao.GetByID(invoice.EntityID); + var deal = daoFactory.GetDealDao().GetByID(invoice.EntityID); if (deal == null) throw new ArgumentException(); if (!CanAccessTo(deal)) throw new SecurityException(CRMErrorsResource.AccessDenied); - var dealMembers = daoFactory.DealDao.GetMembers(invoice.EntityID); + var dealMembers = daoFactory.GetDealDao().GetMembers(invoice.EntityID); if (!dealMembers.Contains(invoice.ContactID)) throw new ArgumentException(); } @@ -808,7 +812,7 @@ public IEnumerable FilterRead(IEnumerable tasks) var daoFactory = scope.Resolve(); if (contactIDs.Any()) { - contactIDs = daoFactory.ContactDao + contactIDs = daoFactory.GetContactDao() .GetContacts(contactIDs.ToArray()) .Select(x => x.ID) .ToList(); @@ -825,7 +829,7 @@ public IEnumerable FilterRead(IEnumerable tasks) if (casesIds.Any()) { - casesIds = daoFactory.CasesDao + casesIds = daoFactory.GetCasesDao() .GetCases(casesIds.ToArray()) .Select(x => x.ID) .ToList(); @@ -842,7 +846,7 @@ public IEnumerable FilterRead(IEnumerable tasks) if (dealsIds.Any()) { - dealsIds = daoFactory.DealDao + dealsIds = daoFactory.GetDealDao() .GetDeals(dealsIds.ToArray()) .Select(x => x.ID) .ToList(); @@ -873,7 +877,7 @@ public IEnumerable FilterRead(IEnumerable invoices) var daoFactory = scope.Resolve(); if (contactIDs.Any()) { - contactIDs = daoFactory.ContactDao + contactIDs = daoFactory.GetContactDao() .GetContacts(contactIDs.ToArray()) .Select(x => x.ID) .ToList(); diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index cbbb9a49bb5..cb889e604ef 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -88,11 +88,11 @@ public bool CanRead(FileEntry entry, Guid userId) using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); - var invoice = daoFactory.InvoiceDao.GetByFileId(Convert.ToInt32(entry.ID)); + var invoice = daoFactory.GetInvoiceDao().GetByFileId(Convert.ToInt32(entry.ID)); if (invoice != null) return CRMSecurity.CanAccessTo(invoice, userId); - var reportFile = daoFactory.ReportDao.GetFile(Convert.ToInt32(entry.ID), userId); + var reportFile = daoFactory.GetReportDao().GetFile(Convert.ToInt32(entry.ID), userId); if (reportFile != null) return true; @@ -106,7 +106,7 @@ public bool CanRead(FileEntry entry, Guid userId) if (!eventIds.Any()) return false; - var eventItem = daoFactory.RelationshipEventDao.GetByID(eventIds.First()); + var eventItem = daoFactory.GetRelationshipEventDao().GetByID(eventIds.First()); return CRMSecurity.CanAccessTo(eventItem, userId); } diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs index e6edbbf2c16..e4dc0fc76ea 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs @@ -24,22 +24,26 @@ */ -#region Import - using ASC.CRM.Resources; using ASC.Web.CRM.Classes; +using Microsoft.AspNetCore.Http; using System; using System.IO; -#endregion - namespace ASC.Web.CRM.HttpHandlers { - public class FileHandler : IHttpHandler + public class FileHandler { + public FileHandler(Global global) + { + Global = global; + } + + public Global Global { get; } + public void ProcessRequest(HttpContext context) { - var action = context.Request["action"]; + var action = context.Request.Query["action"]; switch (action) { @@ -56,9 +60,9 @@ public void ProcessRequest(HttpContext context) private void ResponceContactPhotoUrl(HttpContext context) { - var contactId = Convert.ToInt32(context.Request["cid"]); - var isCompany = Convert.ToBoolean(context.Request["isc"]); - var photoSize = Convert.ToInt32(context.Request["ps"]); + var contactId = Convert.ToInt32(context.Request.Query["cid"]); + var isCompany = Convert.ToBoolean(context.Request.Query["isc"]); + var photoSize = Convert.ToInt32(context.Request.Query["ps"]); String photoUrl = String.Empty; @@ -94,7 +98,7 @@ private void ResponceContactPhotoUrl(HttpContext context) private void ResponceMailMessageContent(HttpContext context) { - var messageId = Convert.ToInt32(context.Request["message_id"]); + var messageId = Convert.ToInt32(context.Request.Query["message_id"]); var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); @@ -105,9 +109,9 @@ private void ResponceMailMessageContent(HttpContext context) messageContent = streamReader.ReadToEnd(); } - context.Response.Clear(); context.Response.Write(messageContent); + try { context.Response.Flush(); @@ -120,7 +124,6 @@ private void ResponceMailMessageContent(HttpContext context) } } - public bool IsReusable { get diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs index fc23f570641..033861fb82a 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs @@ -24,19 +24,13 @@ */ -using System; -using System.Web; - -using ASC.Files.Core; -using ASC.Web.CRM.Resources; -using ASC.Web.Studio.Controls.FileUploader; -using ASC.Web.Studio.Controls.FileUploader.HttpModule; -using ASC.Web.Studio.Core; using ASC.CRM.Core.Dao; +using ASC.CRM.Resources; using ASC.Web.CRM.Core; +using ASC.Web.Studio.Core; using Autofac; using Microsoft.AspNetCore.Http; -using ASC.CRM.Resources; +using System; namespace ASC.Web.CRM.Classes { diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index 56e1b641c8e..9bd79f9c996 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -115,21 +115,21 @@ private NameValueCollection ExtractBaseDataFrom(EntityType entityType, int entit case EntityType.Company: case EntityType.Contact: { - var contact = daoFactory.ContactDao.GetByID(entityID); + var contact = daoFactory.GetContactDao().GetByID(entityID); title = contact != null ? contact.GetTitle() : string.Empty; relativeURL = "default.aspx?id=" + entityID; break; } case EntityType.Opportunity: { - var deal = daoFactory.DealDao.GetByID(entityID); + var deal = daoFactory.GetDealDao().GetByID(entityID); title = deal != null ? deal.Title : string.Empty; relativeURL = "deals.aspx?id=" + entityID; break; } case EntityType.Case: { - var cases = daoFactory.CasesDao.GetByID(entityID); + var cases = daoFactory.GetCasesDao().GetByID(entityID); title = cases != null ? cases.Title : string.Empty; relativeURL = "cases.aspx?id=" + entityID; break; @@ -165,7 +165,7 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable } else { - var contact = daoFactory.ContactDao.GetByID(entity.ContactID); + var contact = daoFactory.GetContactDao().GetByID(entity.ContactID); baseEntityData = new NameValueCollection(); baseEntityData["title"] = contact.GetTitle(); @@ -276,99 +276,99 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) new TagValue(NotifyConstants.Tag_EntityListTitle, entitiyListTitle)); } - public void SendAutoReminderAboutTask(DateTime scheduleDate) - { - using (var scope = DIHelper.Resolve(-1)) - { - var defaultDao = scope.Resolve(); - - var execAlert = new List(); - - foreach (var row in defaultDao.TaskDao - .GetInfoForReminder(scheduleDate)) - { - - var tenantId = Convert.ToInt32(row[0]); - var taskId = Convert.ToInt32(row[1]); - var deadline = Convert.ToDateTime(row[2]); - var alertValue = Convert.ToInt32(row[3]); - var responsibleID = !string.IsNullOrEmpty(Convert.ToString(row[4])) - ? new Guid(Convert.ToString(row[4])) - : Guid.Empty; - - var deadlineReminderDate = deadline.AddMinutes(-alertValue); - - if (deadlineReminderDate.Subtract(scheduleDate).Minutes > 1) continue; - - execAlert.Add(taskId); - - var tenant = TenantManager.GetTenant(tenantId); - if (tenant == null || - tenant.Status != TenantStatus.Active || - TariffState.NotPaid <= PaymentManager.GetTariff(tenant.TenantId).State) - { - continue; - } - - try - { - TenantManager.SetCurrentTenant(tenant); - SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); - - var user = UserManager.GetUsers(responsibleID); - - if (!(!Constants.LostUser.Equals(user) && user.Status == EmployeeStatus.Active)) continue; - - SecurityContext.AuthenticateMe(user.ID); - - Thread.CurrentThread.CurrentCulture = user.GetCulture(); - Thread.CurrentThread.CurrentUICulture = user.GetCulture(); - - using (var innerScope = DIHelper.Resolve(tenantId)) - { - var dao = innerScope.Resolve(); - var task = dao.TaskDao.GetByID(taskId); - - if (task == null) continue; - - ASC.CRM.Core.Entities.Contact taskContact = null; - ASC.CRM.Core.Entities.Cases taskCase = null; - ASC.CRM.Core.Entities.Deal taskDeal = null; - - if (task.ContactID > 0) - { - taskContact = dao.ContactDao.GetByID(task.ContactID); - } - - if (task.EntityID > 0) - { - switch (task.EntityType) - { - case EntityType.Case: - taskCase = dao.CasesDao.GetByID(task.EntityID); - break; - case EntityType.Opportunity: - taskDeal = dao.DealDao.GetByID(task.EntityID); - break; - } - } - - var listItem = dao.ListItemDao.GetByID(task.CategoryID); - - NotifyClient.Instance.SendTaskReminder(task, - listItem != null ? listItem.Title : string.Empty, - taskContact, taskCase, taskDeal); - } - } - catch (Exception ex) - { - Logger.Error("SendAutoReminderAboutTask, tenant: " + tenant.TenantDomain, ex); - } - } - - defaultDao.TaskDao.ExecAlert(execAlert); - } - } + //public void SendAutoReminderAboutTask(DateTime scheduleDate) + //{ + // using (var scope = DIHelper.Resolve(-1)) + // { + // var defaultDao = scope.Resolve(); + + // var execAlert = new List(); + + // foreach (var row in defaultDao.GetTaskDao() + // .GetInfoForReminder(scheduleDate)) + // { + + // var tenantId = Convert.ToInt32(row[0]); + // var taskId = Convert.ToInt32(row[1]); + // var deadline = Convert.ToDateTime(row[2]); + // var alertValue = Convert.ToInt32(row[3]); + // var responsibleID = !string.IsNullOrEmpty(Convert.ToString(row[4])) + // ? new Guid(Convert.ToString(row[4])) + // : Guid.Empty; + + // var deadlineReminderDate = deadline.AddMinutes(-alertValue); + + // if (deadlineReminderDate.Subtract(scheduleDate).Minutes > 1) continue; + + // execAlert.Add(taskId); + + // var tenant = TenantManager.GetTenant(tenantId); + // if (tenant == null || + // tenant.Status != TenantStatus.Active || + // TariffState.NotPaid <= PaymentManager.GetTariff(tenant.TenantId).State) + // { + // continue; + // } + + // try + // { + // TenantManager.SetCurrentTenant(tenant); + // SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); + + // var user = UserManager.GetUsers(responsibleID); + + // if (!(!Constants.LostUser.Equals(user) && user.Status == EmployeeStatus.Active)) continue; + + // SecurityContext.AuthenticateMe(user.ID); + + // Thread.CurrentThread.CurrentCulture = user.GetCulture(); + // Thread.CurrentThread.CurrentUICulture = user.GetCulture(); + + // using (var innerScope = DIHelper.Resolve(tenantId)) + // { + // var dao = innerScope.Resolve(); + // var task = dao.GetTaskDao().GetByID(taskId); + + // if (task == null) continue; + + // ASC.CRM.Core.Entities.Contact taskContact = null; + // ASC.CRM.Core.Entities.Cases taskCase = null; + // ASC.CRM.Core.Entities.Deal taskDeal = null; + + // if (task.ContactID > 0) + // { + // taskContact = dao.GetContactDao().GetByID(task.ContactID); + // } + + // if (task.EntityID > 0) + // { + // switch (task.EntityType) + // { + // case EntityType.Case: + // taskCase = dao.GetCasesDao().GetByID(task.EntityID); + // break; + // case EntityType.Opportunity: + // taskDeal = dao.GetDealDao().GetByID(task.EntityID); + // break; + // } + // } + + // var listItem = dao.ListItemDao.GetByID(task.CategoryID); + + // NotifyClient.Instance.SendTaskReminder(task, + // listItem != null ? listItem.Title : string.Empty, + // taskContact, taskCase, taskDeal); + // } + // } + // catch (Exception ex) + // { + // Logger.Error("SendAutoReminderAboutTask, tenant: " + tenant.TenantDomain, ex); + // } + // } + + // defaultDao.GetTaskDao().ExecAlert(execAlert); + // } + //} public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal) { diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index c9551406529..c57572bb554 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -25,10 +25,13 @@ using ASC.Common.Logging; +using ASC.Core.Common.Settings; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.Web.CRM.Core; using Autofac; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Globalization; @@ -41,15 +44,21 @@ namespace ASC.Web.CRM.Classes { public class CurrencyProvider { - private readonly ILog _log = LogManager.GetLogger("ASC"); + private readonly ILog _log; private readonly object _syncRoot = new object(); private readonly Dictionary _currencies; - private Dictionary _exchangeRates; + private Dictionary _exchangeRates; private DateTime _publisherDate; private const String _formatDate = "yyyy-MM-ddTHH:mm:ss.fffffffK"; - - CurrencyProvider() + + public CurrencyProvider(IOptionsMonitor logger, + IConfiguration configuration, + SettingsManager settingsManager) { + _log = logger.Get("ASC"); + Configuration = configuration; + SettingsManager = settingsManager; + using (var scope = DIHelper.Resolve()) { var daoFactory = scope.Resolve(); @@ -67,11 +76,16 @@ public class CurrencyProvider } } + public IConfiguration Configuration { get; } + public SettingsManager SettingsManager { get; } + public DateTime GetPublisherDate { - get { + get + { TryToReadPublisherDate(GetExchangesTempPath()); - return _publisherDate; } + return _publisherDate; + } } public CurrencyInfo Get(string currencyAbbreviation) @@ -148,9 +162,9 @@ public Decimal MoneyConvert(decimal amount, string from, string to) return Math.Round(rates[key] * amount, 4, MidpointRounding.AwayFromZero); } - public Decimal MoneyConvertToDefaultCurrency(decimal amount, string from) + public decimal MoneyConvertToDefaultCurrency(decimal amount, string from) { - return MoneyConvert(amount, from, Global.TenantSettings.DefaultCurrency.Abbreviation); + return MoneyConvert(amount, from, SettingsManager.Load().DefaultCurrency.Abbreviation); } private bool ObsoleteData() @@ -158,7 +172,8 @@ private bool ObsoleteData() return _exchangeRates == null || (DateTime.UtcNow.Date.Subtract(_publisherDate.Date).Days > 0); } - private string GetExchangesTempPath() { + private string GetExchangesTempPath() + { return Path.Combine(Path.GetTempPath(), Path.Combine("onlyoffice", "exchanges")); } @@ -180,8 +195,9 @@ private Dictionary GetExchangeRates() TryToReadPublisherDate(tmppath); + - var updateEnable = WebConfigurationManager.AppSettings["crm.update.currency.info.enable"] != "false"; + var updateEnable = Configuration["crm:update:currency:info:enable"] != "false"; var ratesUpdatedFlag = false; foreach (var ci in _currencies.Values.Where(c => c.IsConvertable)) @@ -221,7 +237,7 @@ private Dictionary GetExchangeRates() } catch (Exception error) { - LogManager.GetLogger("ASC.CRM").Error(error); + _log.Error(error); _publisherDate = DateTime.UtcNow; } } @@ -276,7 +292,7 @@ private void TryToReadPublisherDate(string tmppath) } catch (Exception err) { - LogManager.GetLogger("ASC.CRM").Error(err); + _log.Error(err); } } } @@ -290,7 +306,7 @@ private void WritePublisherDate(string tmppath) } catch (Exception err) { - LogManager.GetLogger("ASC.CRM").Error(err); + _log.Error(err); } } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs b/products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs deleted file mode 100644 index a599d274ca1..00000000000 --- a/products/ASC.CRM/Server/Utils/Import/CSV/CsvReader.cs +++ /dev/null @@ -1,32 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -namespace ASC.Web.CRM.Classes -{ - internal class CsvReader - { - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs index 6469ce2b4ac..fa6cec2bf00 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs @@ -24,6 +24,7 @@ */ +using ASC.Web.CRM.Classes; using System; namespace LumenWorks.Framework.IO.Csv diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index 88f71ccfbcb..37ec5cb6087 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -49,9 +49,9 @@ private void ImportCaseData(DaoFactory _daoFactory) { int currentIndex = 0; - var casesDao = _daoFactory.CasesDao; - var customFieldDao = _daoFactory.CustomFieldDao; - var tagDao = _daoFactory.TagDao; + var casesDao = _daoFactory.GetCasesDao(); + var customFieldDao = _daoFactory.GetCustomFieldDao(); + var tagDao = _daoFactory.GetTagDao(); var findedTags = new Dictionary>(); var findedCustomField = new List(); @@ -119,7 +119,7 @@ private void ImportCaseData(DaoFactory _daoFactory) foreach (var item in membersList) { - var findedMember = _daoFactory.ContactDao.GetContactsByName(item, true); + var findedMember = _daoFactory.GetContactDao().GetContactsByName(item, true); if (findedMember.Count > 0) { @@ -127,7 +127,7 @@ private void ImportCaseData(DaoFactory _daoFactory) } else { - findedMember = _daoFactory.ContactDao.GetContactsByName(item, false); + findedMember = _daoFactory.GetContactDao().GetContactsByName(item, false); if (findedMember.Count > 0) { localMembersCases.Add(findedMember[0].ID); @@ -180,7 +180,7 @@ private void ImportCaseData(DaoFactory _daoFactory) foreach (var findedCasesMemberKey in findedCasesMembers.Keys) { - _daoFactory.DealDao.SetMembers(newIDs[findedCasesMemberKey], findedCasesMembers[findedCasesMemberKey].ToArray()); + _daoFactory.GetDealDao().SetMembers(newIDs[findedCasesMemberKey], findedCasesMembers[findedCasesMemberKey].ToArray()); } Percentage += 12.5; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index 1ecffececb2..196268c9794 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -53,10 +53,10 @@ private void ImportContactsData(DaoFactory _daoFactory) var personFakeIdCompanyNameHash = new Dictionary(); - var contactDao = _daoFactory.ContactDao; - var contactInfoDao = _daoFactory.ContactInfoDao; - var customFieldDao = _daoFactory.CustomFieldDao; - var tagDao = _daoFactory.TagDao; + var contactDao = _daoFactory.GetContactDao(); + var contactInfoDao = _daoFactory.GetContactInfoDao(); + var customFieldDao = _daoFactory.GetCustomFieldDao(); + var tagDao = _daoFactory.GetTagDao(); var findedContacts = new Dictionary(); var findedTags = new Dictionary>(); @@ -414,7 +414,7 @@ private bool _CommonData(int currentIndex, DaoFactory _daoFactory, ref Contact c Percentage += 1.0 * 100 / (ImportFromCSV.MaxRoxCount * 3); - var listItemDao = _daoFactory.ListItemDao; + var listItemDao = _daoFactory.GetListItemDao(); if (!String.IsNullOrEmpty(firstName) || !String.IsNullOrEmpty(lastName)) @@ -612,7 +612,7 @@ private void _DuplicateRecordRuleProcess(DaoFactory _daoFactory, ref List findedCustomField, ref Dictionary> findedTags) { - var contactDao = _daoFactory.ContactDao; + var contactDao = _daoFactory.GetContactDao(); _log.Info("_DuplicateRecordRuleProcess. Start"); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 7eee76bb65f..e1a19542c50 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -29,6 +29,7 @@ using ASC.Common.Security.Authentication; using ASC.Common.Threading.Progress; using ASC.Core; +using ASC.Core.Common.Settings; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; @@ -119,7 +120,12 @@ public ImportDataOperation(EntityType entityType, IOptionsMonitor logger, UserManager userManager, ImportDataCache importDataCache, - CRMSecurity cRMSecurity) + CRMSecurity cRMSecurity, + NotifyClient notifyClient, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + IServiceProvider serviceProvider + ) { ImportDataCache = importDataCache; @@ -135,16 +141,24 @@ public ImportDataOperation(EntityType entityType, _tenantID = tenantManager.CurrentTenant.TenantId; _author = SecurityContext.CurrentAccount; - - _notifyClient = NotifyClient.Instance; + + NotifyClient = notifyClient; Id = String.Format("{0}_{1}", _tenantID, (int)_entityType); _log = logger.Get("ASC.CRM"); CRMSecurity = cRMSecurity; + SettingsManager = settingsManager; + CurrencyProvider = currencyProvider; } + public CurrencyProvider CurrencyProvider { get; } + + public NotifyClient NotifyClient { get; } + + public SettingsManager SettingsManager { get; } + public CRMSecurity CRMSecurity { get; } public ImportDataCache ImportDataCache { get; } @@ -162,9 +176,7 @@ public ImportDataOperation(EntityType entityType, private readonly IDataStore _dataStore; private readonly IAccount _author; - - private readonly NotifyClient _notifyClient; - + private readonly int _tenantID; private readonly string _CSVFileURI; @@ -194,16 +206,7 @@ public override int GetHashCode() public object Clone() { - var cloneObj = new ImportDataOperation() - { - Error = Error, - Id = Id, - IsCompleted = IsCompleted, - Percentage = Percentage, - Status = Status - }; - - return cloneObj; + return MemberwiseClone(); } public object Id { get; set; } @@ -236,7 +239,7 @@ private void Complete() _log.Debug("Import is completed"); - _notifyClient.SendAboutImportCompleted(_author.ID, _entityType); + NotifyClient.SendAboutImportCompleted(_author.ID, _entityType); ImportDataCache.Insert(_entityType, (ImportDataOperation)Clone()); } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index 47b54a82da8..75ffe70cf4d 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -44,21 +44,20 @@ namespace ASC.Web.CRM.Classes { public partial class ImportDataOperation { - private void ImportOpportunityData(DaoFactory _daoFactory) { - var allUsers = ASC.Core.CoreContext.UserManager.GetUsers(EmployeeStatus.All).ToList(); + var allUsers = UserManager.GetUsers(EmployeeStatus.All).ToList(); using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { int currentIndex = 0; - var customFieldDao = _daoFactory.CustomFieldDao; - var contactDao = _daoFactory.ContactDao; - var tagDao = _daoFactory.TagDao; - var dealDao = _daoFactory.DealDao; - var dealMilestoneDao = _daoFactory.DealMilestoneDao; + var customFieldDao = _daoFactory.GetCustomFieldDao(); + var contactDao = _daoFactory.GetContactDao(); + var tagDao = _daoFactory.GetTagDao(); + var dealDao = _daoFactory.GetDealDao(); + var dealMilestoneDao = _daoFactory.GetDealMilestoneDao(); var findedTags = new Dictionary>(); var findedCustomField = new List(); @@ -82,7 +81,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) obj.Description = GetPropertyValue("description"); var csvResponsibleValue = GetPropertyValue("responsible"); - var responsible = allUsers.Where(n => n.DisplayUserName().Equals(csvResponsibleValue)).FirstOrDefault(); + var responsible = allUsers.Where(n => n.DisplayUserName(DisplayUserSettingsHelper).Equals(csvResponsibleValue)).FirstOrDefault(); if (responsible != null) obj.ResponsibleID = responsible.ID; @@ -104,7 +103,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) if (currency != null) obj.BidCurrency = currency.Abbreviation; else - obj.BidCurrency = Global.TenantSettings.DefaultCurrency.Abbreviation; + obj.BidCurrency = SettingsManager.Load().DefaultCurrency.Abbreviation; decimal bidValue; @@ -120,7 +119,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) BidType bidType = BidType.FixedBid; - if (!String.IsNullOrEmpty(bidTypeStr)) + if (!string.IsNullOrEmpty(bidTypeStr)) { if (String.Compare(CRMDealResource.BidType_FixedBid, bidTypeStr, true) == 0) bidType = BidType.FixedBid; @@ -203,8 +202,6 @@ private void ImportOpportunityData(DaoFactory _daoFactory) localMembersDeal.Add(obj.ContactID); } } - - } var members = GetPropertyValue("member"); @@ -223,7 +220,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) } else { - findedMember = _daoFactory.ContactDao.GetContactsByName(item, false); + findedMember = _daoFactory.GetContactDao().GetContactsByName(item, false); if (findedMember.Count > 0) { localMembersDeal.Add(findedMember[0].ID); @@ -268,9 +265,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); - - + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); findedDeals.Add(obj); @@ -280,7 +275,6 @@ private void ImportOpportunityData(DaoFactory _daoFactory) } - Percentage = 50; if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index 4e2b301aa9f..768d998fca7 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -25,6 +25,7 @@ using ASC.Common.Threading.Progress; +using ASC.Core; using ASC.CRM.Core.Enums; using LumenWorks.Framework.IO.Csv; using Newtonsoft.Json.Linq; @@ -37,73 +38,82 @@ namespace ASC.Web.CRM.Classes public class ImportFromCSV { - #region Members + public ImportFromCSV(TenantManager tenantProvider, + ImportDataCache importDataCache) + { + TenantId = tenantProvider.CurrentTenant.TenantId; + ImportDataCache = importDataCache; + } + + public ImportDataCache ImportDataCache { get; } - private static readonly Object _syncObj = new Object(); + public int TenantId { get; } - private static readonly ProgressQueue _importQueue = new ProgressQueue(3, TimeSpan.FromSeconds(15), true); + private readonly object _syncObj = new object(); - public static readonly int MaxRoxCount = 10000; + private readonly ProgressQueue _importQueue = new ProgressQueue(); + // 3, TimeSpan.FromSeconds(15), true); - #endregion + public readonly int MaxRoxCount = 10000; - public static int GetQuotas() + public int GetQuotas() { return MaxRoxCount; } - public static CsvReader CreateCsvReaderInstance(Stream CSVFileStream, ImportCSVSettings importCsvSettings) + public CsvReader CreateCsvReaderInstance(Stream CSVFileStream, ImportCSVSettings importCsvSettings) { var result = new CsvReader( new StreamReader(CSVFileStream, importCsvSettings.Encoding, true), - importCsvSettings.HasHeader, importCsvSettings.DelimiterCharacter, importCsvSettings.QuoteType, '"', '#', ValueTrimmingOptions.UnquotedOnly) { SkipEmptyLines = true, SupportsMultiline = true, DefaultParseErrorAction = ParseErrorAction.AdvanceToNextLine, MissingFieldAction = MissingFieldAction.ReplaceByEmpty }; + importCsvSettings.HasHeader, importCsvSettings.DelimiterCharacter, importCsvSettings.QuoteType, '"', '#', ValueTrimmingOptions.UnquotedOnly) + { SkipEmptyLines = true, SupportsMultiline = true, DefaultParseErrorAction = ParseErrorAction.AdvanceToNextLine, MissingFieldAction = MissingFieldAction.ReplaceByEmpty }; return result; } - public static String GetRow(Stream CSVFileStream, int index, String jsonSettings) + public String GetRow(Stream CSVFileStream, int index, String jsonSettings) { var importCSVSettings = new ImportCSVSettings(jsonSettings); - using (CsvReader csv = CreateCsvReaderInstance(CSVFileStream, importCSVSettings)) - { - int countRows = 0; + CsvReader csv = CreateCsvReaderInstance(CSVFileStream, importCSVSettings); - index++; + int countRows = 0; - while (countRows++ != index && csv.ReadNextRecord()) ; + index++; + + while (countRows++ != index && csv.ReadNextRecord()) ; + + return new JObject(new JProperty("data", new JArray(csv.GetCurrentRowFields(false).ToArray())), + new JProperty("isMaxIndex", csv.EndOfStream)).ToString(); - return new JObject(new JProperty("data", new JArray(csv.GetCurrentRowFields(false).ToArray())), - new JProperty("isMaxIndex", csv.EndOfStream)).ToString(); - } } - public static JObject GetInfo(Stream CSVFileStream, String jsonSettings) + public JObject GetInfo(Stream CSVFileStream, String jsonSettings) { var importCSVSettings = new ImportCSVSettings(jsonSettings); - using (CsvReader csv = CreateCsvReaderInstance(CSVFileStream, importCSVSettings)) - { - csv.ReadNextRecord(); + CsvReader csv = CreateCsvReaderInstance(CSVFileStream, importCSVSettings); - var firstRowFields = csv.GetCurrentRowFields(false); + csv.ReadNextRecord(); - String[] headerRowFields = csv.GetFieldHeaders().ToArray(); + var firstRowFields = csv.GetCurrentRowFields(false); - if (!importCSVSettings.HasHeader) - headerRowFields = firstRowFields; + String[] headerRowFields = csv.GetFieldHeaders().ToArray(); + + if (!importCSVSettings.HasHeader) + headerRowFields = firstRowFields; + + return new JObject( + new JProperty("headerColumns", new JArray(headerRowFields)), + new JProperty("firstContactFields", new JArray(firstRowFields)), + new JProperty("isMaxIndex", csv.EndOfStream) + ); - return new JObject( - new JProperty("headerColumns", new JArray(headerRowFields)), - new JProperty("firstContactFields", new JArray(firstRowFields)), - new JProperty("isMaxIndex", csv.EndOfStream) - ); - } } - public static IProgressItem GetStatus(EntityType entityType) + public IProgressItem GetStatus(EntityType entityType) { - var result = _importQueue.GetStatus(String.Format("{0}_{1}", TenantProvider.CurrentTenantID, (int)entityType)); + var result = _importQueue.GetStatus(String.Format("{0}_{1}", TenantId, (int)entityType)); if (result == null) { @@ -113,7 +123,7 @@ public static IProgressItem GetStatus(EntityType entityType) return result; } - public static IProgressItem Start(EntityType entityType, String CSVFileURI, String importSettingsJSON) + public IProgressItem Start(EntityType entityType, String CSVFileURI, String importSettingsJSON) { lock (_syncObj) { @@ -126,9 +136,9 @@ public static IProgressItem Start(EntityType entityType, String CSVFileURI, Stri if (fromCache != null) return fromCache; - operation = new ImportDataOperation(entityType, CSVFileURI, importSettingsJSON); + // operation = new ImportDataOperation(entityType, CSVFileURI, importSettingsJSON); - _importQueue.Add(operation); + // _importQueue.Add(operation); } if (!_importQueue.IsStarted) diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs index d0bd18e24e7..4236f06fec6 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs @@ -26,11 +26,14 @@ #region Import +using ASC.Core; using ASC.Core.Tenants; using ASC.Core.Users; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using ASC.Web.Core.Users; using LumenWorks.Framework.IO.Csv; using System; using System.Collections.Generic; @@ -42,6 +45,19 @@ namespace ASC.Web.CRM.Classes { public partial class ImportDataOperation { + public ImportDataOperation(TenantUtil tenantUtil, + ImportFromCSV importFromCSV, + DisplayUserSettingsHelper displayUserSettingsHelper) + { + TenantUtil = tenantUtil; + ImportFromCSV = importFromCSV; + DisplayUserSettingsHelper = displayUserSettingsHelper; + } + + public ImportFromCSV ImportFromCSV { get; } + public TenantUtil TenantUtil { get; } + public DisplayUserSettingsHelper DisplayUserSettingsHelper { get;} + private void ImportTaskData(DaoFactory _daoFactory) { using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) @@ -49,14 +65,14 @@ private void ImportTaskData(DaoFactory _daoFactory) { int currentIndex = 0; - var contactDao = _daoFactory.ContactDao; - var listItemDao = _daoFactory.ListItemDao; - var taskDao = _daoFactory.TaskDao; + var contactDao = _daoFactory.GetContactDao(); + var listItemDao = _daoFactory.GetListItemDao(); + var taskDao = _daoFactory.GetTaskDao(); var findedTasks = new List(); var taskCategories = listItemDao.GetItems(ListType.TaskCategory); - var allUsers = ASC.Core.CoreContext.UserManager.GetUsers(EmployeeStatus.All).ToList(); + var allUsers = UserManager.GetUsers(EmployeeStatus.All).ToList(); while (csv.ReadNextRecord()) { @@ -80,7 +96,7 @@ private void ImportTaskData(DaoFactory _daoFactory) obj.DeadLine = TenantUtil.DateTimeNow(); var csvResponsibleValue = GetPropertyValue("responsible"); - var responsible = allUsers.Where(n => n.DisplayUserName().Equals(csvResponsibleValue)).FirstOrDefault(); + var responsible = allUsers.Where(n => n.DisplayUserName(DisplayUserSettingsHelper).Equals(csvResponsibleValue)).FirstOrDefault(); if (responsible != null) obj.ResponsibleID = responsible.ID; diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index db598eaedd8..ad22bc860ca 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -44,6 +44,9 @@ using System.Text; using System.Xml; +using Microsoft.Extensions.DependencyInjection; + + namespace ASC.Web.CRM.Classes { public class PdfCreator @@ -51,16 +54,17 @@ public class PdfCreator public PdfCreator(IOptionsMonitor logger, Files.Classes.PathProvider filesPathProvider, DocumentServiceConnector documentServiceConnector, - ASC.Web.Files.Classes.Global filesGlobal, - FilesLinkUtility filesLinkUtility, - FileUtility fileUtility, - FileConverter fileConverter) + IServiceProvider serviceProvider, + OrganisationLogoManager organisationLogoManager) { FilesPathProvider = filesPathProvider; Logger = logger.Get("ASC.CRM"); DocumentServiceConnector = documentServiceConnector; + ServiceProvider = serviceProvider; + OrganisationLogoManager = organisationLogoManager; + } private Stream Template @@ -72,8 +76,9 @@ private Stream Template } } + public IServiceProvider ServiceProvider { get; } public DocumentServiceConnector DocumentServiceConnector { get; } - + public OrganisationLogoManager OrganisationLogoManager { get; } public Files.Classes.PathProvider FilesPathProvider { get; } public ILog Logger { get; } @@ -93,7 +98,8 @@ public void CreateAndSaveFile(int invoiceId) { var daoFactory = scope.Resolve(); - var invoice = daoFactory.InvoiceDao.GetByID(invoiceId); + var invoice = daoFactory.GetInvoiceDao().GetByID(invoiceId); + if (invoice == null) { Logger.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); @@ -113,20 +119,20 @@ public void CreateAndSaveFile(int invoiceId) Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, urlToFile); - var file = new File - { - Title = string.Format("{0}{1}", invoice.Number, FormatPdf), - FolderID = daoFactory.FileDao.GetRoot() - }; + var file = ServiceProvider.GetService>(); + + file.Title = string.Format("{0}{1}", invoice.Number, FormatPdf); + file.FolderID = daoFactory.GetFileDao().GetRoot(); var request = WebRequest.Create(urlToFile); + using (var response = request.GetResponse()) using (var stream = response.GetResponseStream()) { file.ContentLength = response.ContentLength; Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); - file = daoFactory.FileDao.SaveFile(file, stream); + file = daoFactory.GetFileDao().SaveFile(file, stream); } if (file == null) @@ -138,11 +144,11 @@ public void CreateAndSaveFile(int invoiceId) Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); - daoFactory.InvoiceDao.UpdateInvoiceFileID(invoice.ID, invoice.FileID); + daoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); - daoFactory.RelationshipEventDao.AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] {invoice.FileID}); + daoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] {invoice.FileID}); } } @@ -230,7 +236,7 @@ public File GetConvertedFile(ConverterData data, DaoFactory daoFactory) return null; } - var invoice = daoFactory.InvoiceDao.GetByID(data.InvoiceId); + var invoice = daoFactory.GetInvoiceDao().GetByID(data.InvoiceId); return SaveFile(invoice, urlToFile, daoFactory); } @@ -247,19 +253,18 @@ private File SaveFile(Invoice data, string url, DaoFactory daoFactory) { if (stream != null) { - var document = new File - { - Title = string.Format("{0}{1}", data.Number, FormatPdf), - FolderID = daoFactory.FileDao.GetRoot(), - ContentLength = response.ContentLength - }; + var document = ServiceProvider.GetService>(); + + document.Title = string.Format("{0}{1}", data.Number, FormatPdf); + document.FolderID = daoFactory.GetFileDao().GetRoot(); + document.ContentLength = response.ContentLength; if (data.GetInvoiceFile(daoFactory) != null) { document.ID = data.FileID; } - file = daoFactory.FileDao.SaveFile(document, stream); + file = daoFactory.GetFileDao().SaveFile(document, stream); } } } diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index b1f075c2dd5..24d86243579 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -24,6 +24,7 @@ */ +using ASC.Core.Common.Settings; using ASC.Core.Tenants; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; @@ -36,6 +37,8 @@ using System; using System.Collections.Generic; using System.Net; +using Microsoft.Extensions.DependencyInjection; + namespace ASC.Web.CRM.Classes { @@ -43,16 +46,23 @@ public class ReportHelper { public ReportHelper(TenantUtil tenantUtil, Global global, - DocbuilderReportsUtility docbuilderReportsUtility) + DocbuilderReportsUtility docbuilderReportsUtility, + SettingsManager settingsManager, + IServiceProvider serviceProvider + ) { TenantUtil = tenantUtil; Global = global; DocbuilderReportsUtility = docbuilderReportsUtility; + SettingsManager = settingsManager; + ServiceProvider = serviceProvider; } + public IServiceProvider ServiceProvider { get; } + public DocbuilderReportsUtility DocbuilderReportsUtility { get; } public Global Global { get; } - + public SettingsManager SettingsManager { get; } public TenantUtil TenantUtil { get; } private string GetFileName(ReportType reportType) @@ -104,35 +114,36 @@ private string GetFileName(ReportType reportType) public bool CheckReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { + throw new NotImplementedException(); using (var scope = DIHelper.Resolve()) { - var reportDao = scope.Resolve().ReportDao; + var reportDao = scope.Resolve().GetReportDao(); - switch (reportType) - { - case ReportType.SalesByManagers: - return reportDao.CheckSalesByManagersReportData(timePeriod, managers); - case ReportType.SalesForecast: - return reportDao.CheckSalesForecastReportData(timePeriod, managers); - case ReportType.SalesFunnel: - return reportDao.CheckSalesFunnelReportData(timePeriod, managers); - case ReportType.WorkloadByContacts: - return reportDao.CheckWorkloadByContactsReportData(timePeriod, managers); - case ReportType.WorkloadByTasks: - return reportDao.CheckWorkloadByTasksReportData(timePeriod, managers); - case ReportType.WorkloadByDeals: - return reportDao.CheckWorkloadByDealsReportData(timePeriod, managers); - case ReportType.WorkloadByInvoices: - return reportDao.CheckWorkloadByInvoicesReportData(timePeriod, managers); - case ReportType.WorkloadByVoip: - return reportDao.CheckWorkloadByViopReportData(timePeriod, managers); - case ReportType.SummaryForThePeriod: - return reportDao.CheckSummaryForThePeriodReportData(timePeriod, managers); - case ReportType.SummaryAtThisMoment: - return reportDao.CheckSummaryAtThisMomentReportData(timePeriod, managers); - default: - return false; - } + //switch (reportType) + //{ + // case ReportType.SalesByManagers: + // return reportDao.CheckSalesByManagersReportData(timePeriod, managers); + // case ReportType.SalesForecast: + // return reportDao.CheckSalesForecastReportData(timePeriod, managers); + // case ReportType.SalesFunnel: + // return reportDao.CheckSalesFunnelReportData(timePeriod, managers); + // case ReportType.WorkloadByContacts: + // return reportDao.CheckWorkloadByContactsReportData(timePeriod, managers); + // case ReportType.WorkloadByTasks: + // return reportDao.CheckWorkloadByTasksReportData(timePeriod, managers); + // case ReportType.WorkloadByDeals: + // return reportDao.CheckWorkloadByDealsReportData(timePeriod, managers); + // case ReportType.WorkloadByInvoices: + // return reportDao.CheckWorkloadByInvoicesReportData(timePeriod, managers); + // case ReportType.WorkloadByVoip: + // return reportDao.CheckWorkloadByViopReportData(timePeriod, managers); + // case ReportType.SummaryForThePeriod: + // return reportDao.CheckSummaryForThePeriodReportData(timePeriod, managers); + // case ReportType.SummaryAtThisMoment: + // return reportDao.CheckSummaryAtThisMomentReportData(timePeriod, managers); + // default: + // return false; + //} } } @@ -140,47 +151,48 @@ public List GetMissingRates(ReportType reportType) { using (var scope = DIHelper.Resolve()) { - var reportDao = scope.Resolve().ReportDao; + var reportDao = scope.Resolve().GetReportDao(); if (reportType == ReportType.WorkloadByTasks || reportType == ReportType.WorkloadByInvoices || reportType == ReportType.WorkloadByContacts || reportType == ReportType.WorkloadByVoip) return null; - return reportDao.GetMissingRates(Global.TenantSettings.DefaultCurrency.Abbreviation); + return reportDao.GetMissingRates(SettingsManager.Load().DefaultCurrency.Abbreviation); } } private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { + throw new NotImplementedException(); using (var scope = DIHelper.Resolve()) { - var reportDao = scope.Resolve().ReportDao; + var reportDao = scope.Resolve().GetReportDao(); - var defaultCurrency = Global.TenantSettings.DefaultCurrency.Abbreviation; + var defaultCurrency = SettingsManager.Load().DefaultCurrency.Abbreviation; - switch (reportType) - { - case ReportType.SalesByManagers: - return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); - case ReportType.SalesForecast: - return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); - case ReportType.SalesFunnel: - return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); - case ReportType.WorkloadByContacts: - return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); - case ReportType.WorkloadByTasks: - return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); - case ReportType.WorkloadByDeals: - return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); - case ReportType.WorkloadByInvoices: - return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); - case ReportType.WorkloadByVoip: - return reportDao.GetWorkloadByViopReportData(timePeriod, managers); - case ReportType.SummaryForThePeriod: - return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); - case ReportType.SummaryAtThisMoment: - return reportDao.GetSummaryAtThisMomentReportData(timePeriod, managers, defaultCurrency); - default: - return null; - } + //switch (reportType) + //{ + // case ReportType.SalesByManagers: + // return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); + // case ReportType.SalesForecast: + // return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); + // case ReportType.SalesFunnel: + // return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); + // case ReportType.WorkloadByContacts: + // return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); + // case ReportType.WorkloadByTasks: + // return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); + // case ReportType.WorkloadByDeals: + // return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); + // case ReportType.WorkloadByInvoices: + // return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); + // case ReportType.WorkloadByVoip: + // return reportDao.GetWorkloadByViopReportData(timePeriod, managers); + // case ReportType.SummaryForThePeriod: + // return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); + // case ReportType.SummaryAtThisMoment: + // return reportDao.GetSummaryAtThisMomentReportData(timePeriod, managers, defaultCurrency); + // default: + // return null; + //} } } @@ -205,16 +217,17 @@ private void SaveReportFile(ReportState state, string url) using (var stream = new System.IO.MemoryStream(data)) { - var document = new File - { - Title = state.FileName, - FolderID = daoFactory.FileDao.GetRoot(), - ContentLength = stream.Length - }; - var file = daoFactory.FileDao.SaveFile(document, stream); + var document = ServiceProvider.GetService>(); + + document.Title = state.FileName; + document.FolderID = daoFactory.GetFileDao().GetRoot(); + document.ContentLength = stream.Length; + + var file = daoFactory.GetFileDao().SaveFile(document, stream); + + daoFactory.GetReportDao().SaveFile((int)file.ID, (ReportType)state.ReportType); - daoFactory.ReportDao.SaveFile((int)file.ID, state.ReportType); state.FileId = (int)file.ID; } } @@ -232,7 +245,9 @@ public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod tim if (string.IsNullOrEmpty(script)) throw new Exception(CRMReportResource.ErrorNullReportScript); - var state = new ReportState(GetFileName(reportType), tmpFileName, script, (int)reportType, ReportOrigin.CRM, SaveReportFile, null); + // ServiceProvider.GetService() + + var state = new ReportState(GetFileName(reportType), tmpFileName, script, (int)reportType, ReportOrigin.CRM, SaveReportFile, null); DocbuilderReportsUtility.Enqueue(state); From f76724aa04042970642f1e27bfad4725f3d62e9c Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 14 Apr 2020 17:35:52 +0300 Subject: [PATCH 10/61] crm: migrate DAO to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 1 - .../ASC.CRM/Server/Classes/CRMSettings.cs | 13 +- products/ASC.CRM/Server/Classes/Global.cs | 4 +- .../Server/Classes/InvoiceFormattedData.cs | 649 +++++++++--------- .../Server/Classes/OrganisationLogoManager.cs | 17 +- .../ASC.CRM/Server/Classes/SignalRHelper.cs | 22 +- .../Server/Classes/SubscriptionManager.cs | 5 +- products/ASC.CRM/Server/Classes/VoipEngine.cs | 73 +- .../Server/Configuration/ProductEntryPoint.cs | 33 +- .../Controllers/CurrencyRateController.cs | 17 + .../Server/Controllers/TasksController.cs | 12 + products/ASC.CRM/Server/Core/DIHelper.cs | 75 -- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 11 +- .../ASC.CRM/Server/Core/Entities/Contact.cs | 30 +- .../ASC.CRM/Server/Core/Entities/Invoice.cs | 4 +- .../Server/Core/Security/CRMSecutiry.cs | 267 +++---- .../Core/Security/FileSecurityProvider.cs | 50 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 22 +- .../Utils/Import/CSV/ImportDataOperation.cs | 70 +- products/ASC.CRM/Server/Utils/PdfCreator.cs | 33 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 169 +++-- 21 files changed, 750 insertions(+), 827 deletions(-) create mode 100644 products/ASC.CRM/Server/Controllers/CurrencyRateController.cs create mode 100644 products/ASC.CRM/Server/Controllers/TasksController.cs delete mode 100644 products/ASC.CRM/Server/Core/DIHelper.cs diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 0d033deecfc..2996841ea95 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -177,7 +177,6 @@ - diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index 8a1cf522c3b..05e97aa8311 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -31,6 +31,9 @@ using System; using System.Runtime.Serialization; +using Microsoft.Extensions.DependencyInjection; + + namespace ASC.Web.CRM.Classes { [Serializable] @@ -146,11 +149,14 @@ public InvoiceSetting DefaultSettings [DataContract] public class CRMSettings : ISettings { - public CRMSettings(CoreConfiguration coreConfiguration) + public CRMSettings(CoreConfiguration coreConfiguration, + CurrencyProvider currencyProvider) { + CurrencyProvider = currencyProvider; CoreConfiguration = coreConfiguration; } + public CurrencyProvider CurrencyProvider { get; } public CoreConfiguration CoreConfiguration { get; } [DataMember(Name = "DefaultCurrency")] @@ -219,8 +225,9 @@ public ISettings GetDefault(IServiceProvider serviceProvider) var languageName = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; var findedCurrency = CurrencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); - - return new CRMSettings(CoreConfiguration) + + return new CRMSettings(serviceProvider.GetService(), + serviceProvider.GetService()) { defaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", IsConfiguredPortal = false, diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 14b18ed1c92..b1584b2184c 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -194,8 +194,8 @@ public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entit { var newFile = PdfCreator.CreateFile(invoice, factory); invoice.FileID = Int32.Parse(newFile.ID.ToString()); - factory..GetInvoiceDao()..UpdateInvoiceFileID(invoice.ID, invoice.FileID); - factory.GetRelationshipEventDao.AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); return newFile; } } diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 8a86130e6b8..798996a8ce1 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -28,8 +28,6 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; -using ASC.Web.CRM.Core; -using Autofac; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -38,9 +36,19 @@ namespace ASC.Web.CRM.Classes { - public class InvoiceFormattedData { + public InvoiceFormattedData(DaoFactory daoFactory, + OrganisationLogoManager organisationLogoManager) + { + DaoFactory = daoFactory; + OrganisationLogoManager = organisationLogoManager; + } + + public OrganisationLogoManager OrganisationLogoManager { get; } + + public DaoFactory DaoFactory { get; } + public int TemplateType { get; set; } public Tuple Seller { get; set; } public int LogoBase64Id { get; set; } @@ -60,12 +68,12 @@ public class InvoiceFormattedData public int DeliveryAddressID { get; set; } public int BillingAddressID { get; set; } - public static InvoiceFormattedData GetData(Invoice invoice, int billingAddressID, int deliveryAddressID) + public InvoiceFormattedData GetData(Invoice invoice, int billingAddressID, int deliveryAddressID) { return invoice.JsonData != null ? ReadData(invoice.JsonData) : CreateData(invoice, billingAddressID, deliveryAddressID); } - public static InvoiceFormattedData GetDataAfterLinesUpdated(Invoice invoice) + public InvoiceFormattedData GetDataAfterLinesUpdated(Invoice invoice) { if (invoice.JsonData != null) { @@ -78,39 +86,123 @@ public static InvoiceFormattedData GetDataAfterLinesUpdated(Invoice invoice) } } - private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, int deliveryAddressID) + private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, int deliveryAddressID) { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); + var data = new InvoiceFormattedData(DaoFactory, OrganisationLogoManager); + var sb = new StringBuilder(); + var list = new List(); + var cultureInfo = string.IsNullOrEmpty(invoice.Language) + ? CultureInfo.CurrentCulture + : CultureInfo.GetCultureInfo(invoice.Language); + + #region TemplateType + + data.TemplateType = (int)invoice.TemplateType; + + #endregion + + #region Seller, LogoBase64, LogoSrcFormat - var data = new InvoiceFormattedData(); - var sb = new StringBuilder(); - var list = new List(); - var cultureInfo = string.IsNullOrEmpty(invoice.Language) - ? CultureInfo.CurrentCulture - : CultureInfo.GetCultureInfo(invoice.Language); + var invoiceSettings = DaoFactory.GetInvoiceDao().GetSettings(); + if (!string.IsNullOrEmpty(invoiceSettings.CompanyName)) + { + sb.Append(invoiceSettings.CompanyName); + } - #region TemplateType + if (!string.IsNullOrEmpty(invoiceSettings.CompanyAddress)) + { + var obj = JObject.Parse(invoiceSettings.CompanyAddress); - data.TemplateType = (int) invoice.TemplateType; + var str = obj.Value("street"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - #endregion + str = obj.Value("city"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); + str = obj.Value("state"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - #region Seller, LogoBase64, LogoSrcFormat + str = obj.Value("zip"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - var invoiceSettings = daoFactory.GetInvoiceDao().GetSettings(); + str = obj.Value("country"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - if (!string.IsNullOrEmpty(invoiceSettings.CompanyName)) + if (list.Count > 0) { - sb.Append(invoiceSettings.CompanyName); + sb.AppendLine(); + sb.Append(string.Join(", ", list)); } + } + + data.Seller = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Seller", cultureInfo), + sb.ToString()); + + if (invoiceSettings.CompanyLogoID != 0) + { + data.LogoBase64Id = invoiceSettings.CompanyLogoID; + //data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(invoiceSettings.CompanyLogoID); + data.LogoSrcFormat = OrganisationLogoManager.OrganisationLogoSrcFormat; + } + + #endregion + + #region Number + + data.Number = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Invoice", cultureInfo), + invoice.Number); + + #endregion + + + #region Invoice + + data.Invoice = new List>(); + data.Invoice.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("IssueDate", cultureInfo), + invoice.IssueDate.ToShortDateString())); + + if (!string.IsNullOrEmpty(invoice.PurchaseOrderNumber)) + { + data.Invoice.Add( + new Tuple( + CRMInvoiceResource.ResourceManager.GetString("PONumber", cultureInfo), + invoice.PurchaseOrderNumber)); + } + data.Invoice.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("DueDate", cultureInfo), + invoice.DueDate.ToShortDateString())); + + #endregion + + + #region Customer - if (!string.IsNullOrEmpty(invoiceSettings.CompanyAddress)) + var customer = DaoFactory.GetContactDao().GetByID(invoice.ContactID); + + if (customer != null) + { + sb = new StringBuilder(); + + sb.Append(customer.GetTitle()); + + var billingAddress = billingAddressID != 0 + ? DaoFactory.GetContactInfoDao().GetByID(billingAddressID) + : null; + if (billingAddress != null && billingAddress.InfoType == ContactInfoType.Address && + billingAddress.Category == (int)AddressCategory.Billing) { - var obj = JObject.Parse(invoiceSettings.CompanyAddress); + list = new List(); + + var obj = JObject.Parse(billingAddress.Data); var str = obj.Value("street"); if (!string.IsNullOrEmpty(str)) @@ -139,107 +231,17 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre } } - data.Seller = - new Tuple(CRMInvoiceResource.ResourceManager.GetString("Seller", cultureInfo), + data.Customer = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("BillTo", cultureInfo), sb.ToString()); + } - if (invoiceSettings.CompanyLogoID != 0) - { - data.LogoBase64Id = invoiceSettings.CompanyLogoID; - //data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(invoiceSettings.CompanyLogoID); - data.LogoSrcFormat = OrganisationLogoManager.OrganisationLogoSrcFormat; - } - - #endregion - - - #region Number - - data.Number = - new Tuple(CRMInvoiceResource.ResourceManager.GetString("Invoice", cultureInfo), - invoice.Number); - - #endregion - - - #region Invoice - - data.Invoice = new List>(); - data.Invoice.Add( - new Tuple(CRMInvoiceResource.ResourceManager.GetString("IssueDate", cultureInfo), - invoice.IssueDate.ToShortDateString())); - if (!string.IsNullOrEmpty(invoice.PurchaseOrderNumber)) - { - data.Invoice.Add( - new Tuple( - CRMInvoiceResource.ResourceManager.GetString("PONumber", cultureInfo), - invoice.PurchaseOrderNumber)); - } - data.Invoice.Add( - new Tuple(CRMInvoiceResource.ResourceManager.GetString("DueDate", cultureInfo), - invoice.DueDate.ToShortDateString())); - - #endregion - - - #region Customer - - var customer = daoFactory.GetContactDao().GetByID(invoice.ContactID); - - if (customer != null) - { - sb = new StringBuilder(); - - sb.Append(customer.GetTitle()); - - var billingAddress = billingAddressID != 0 - ? daoFactory.ContactInfoDao.GetByID(billingAddressID) - : null; - if (billingAddress != null && billingAddress.InfoType == ContactInfoType.Address && - billingAddress.Category == (int) AddressCategory.Billing) - { - list = new List(); - - var obj = JObject.Parse(billingAddress.Data); - - var str = obj.Value("street"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); - - str = obj.Value("city"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); - - str = obj.Value("state"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); - - str = obj.Value("zip"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); - - str = obj.Value("country"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); - - if (list.Count > 0) - { - sb.AppendLine(); - sb.Append(string.Join(", ", list)); - } - } - - data.Customer = - new Tuple(CRMInvoiceResource.ResourceManager.GetString("BillTo", cultureInfo), - sb.ToString()); - } - - #endregion + #endregion - #region TableHeaderRow, TableBodyRows, TableFooterRows, TableTotalRow + #region TableHeaderRow, TableBodyRows, TableFooterRows, TableTotalRow - data.TableHeaderRow = new List + data.TableHeaderRow = new List { CRMInvoiceResource.ResourceManager.GetString("ItemCol", cultureInfo), CRMInvoiceResource.ResourceManager.GetString("QuantityCol", cultureInfo), @@ -250,64 +252,64 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre CRMInvoiceResource.ResourceManager.GetString("AmountCol", cultureInfo) }; - data.TableBodyRows = new List>(); + data.TableBodyRows = new List>(); - var invoiceLines = invoice.GetInvoiceLines(daoFactory); - var invoiceTaxes = new Dictionary(); + var invoiceLines = invoice.GetInvoiceLines(DaoFactory); + var invoiceTaxes = new Dictionary(); - decimal subtotal = 0; - decimal discount = 0; - decimal amount = 0; + decimal subtotal = 0; + decimal discount = 0; + decimal amount = 0; - foreach (var line in invoiceLines) + foreach (var line in invoiceLines) + { + var item = DaoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); + var tax1 = line.InvoiceTax1ID > 0 + ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) + : null; + var tax2 = line.InvoiceTax2ID > 0 + ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) + : null; + + var subtotalValue = Math.Round(line.Quantity * line.Price, 2); + var discountValue = Math.Round(subtotalValue * line.Discount / 100, 2); + + decimal rate = 0; + if (tax1 != null) { - var item = daoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); - var tax1 = line.InvoiceTax1ID > 0 - ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) - : null; - var tax2 = line.InvoiceTax2ID > 0 - ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) - : null; - - var subtotalValue = Math.Round(line.Quantity*line.Price, 2); - var discountValue = Math.Round(subtotalValue*line.Discount/100, 2); - - decimal rate = 0; - if (tax1 != null) + rate += tax1.Rate; + if (invoiceTaxes.ContainsKey(tax1.ID)) + { + invoiceTaxes[tax1.ID] = invoiceTaxes[tax1.ID] + + Math.Round((subtotalValue - discountValue) * tax1.Rate / 100, 2); + } + else { - rate += tax1.Rate; - if (invoiceTaxes.ContainsKey(tax1.ID)) - { - invoiceTaxes[tax1.ID] = invoiceTaxes[tax1.ID] + - Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2); - } - else - { - invoiceTaxes.Add(tax1.ID, Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2)); - } + invoiceTaxes.Add(tax1.ID, Math.Round((subtotalValue - discountValue) * tax1.Rate / 100, 2)); } - if (tax2 != null) + } + if (tax2 != null) + { + rate += tax2.Rate; + if (invoiceTaxes.ContainsKey(tax2.ID)) { - rate += tax2.Rate; - if (invoiceTaxes.ContainsKey(tax2.ID)) - { - invoiceTaxes[tax2.ID] = invoiceTaxes[tax2.ID] + - Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2); - } - else - { - invoiceTaxes.Add(tax2.ID, Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2)); - } + invoiceTaxes[tax2.ID] = invoiceTaxes[tax2.ID] + + Math.Round((subtotalValue - discountValue) * tax2.Rate / 100, 2); } + else + { + invoiceTaxes.Add(tax2.ID, Math.Round((subtotalValue - discountValue) * tax2.Rate / 100, 2)); + } + } - decimal taxValue = Math.Round((subtotalValue - discountValue)*rate/100, 2); - decimal amountValue = Math.Round(subtotalValue - discountValue + taxValue, 2); + decimal taxValue = Math.Round((subtotalValue - discountValue) * rate / 100, 2); + decimal amountValue = Math.Round(subtotalValue - discountValue + taxValue, 2); - subtotal += subtotalValue; - discount += discountValue; - amount += amountValue; + subtotal += subtotalValue; + discount += discountValue; + amount += amountValue; - data.TableBodyRows.Add(new List + data.TableBodyRows.Add(new List { item.Title + (string.IsNullOrEmpty(line.Description) ? string.Empty : ": " + line.Description), line.Quantity.ToString(CultureInfo.InvariantCulture), @@ -317,122 +319,123 @@ private static InvoiceFormattedData CreateData(Invoice invoice, int billingAddre tax2 != null ? tax2.Name : string.Empty, (subtotalValue - discountValue).ToString(CultureInfo.InvariantCulture) }); - } + } - data.TableFooterRows = new List>(); - data.TableFooterRows.Add( - new Tuple(CRMInvoiceResource.ResourceManager.GetString("Subtotal", cultureInfo), - (subtotal - discount).ToString(CultureInfo.InvariantCulture))); + data.TableFooterRows = new List>(); + data.TableFooterRows.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Subtotal", cultureInfo), + (subtotal - discount).ToString(CultureInfo.InvariantCulture))); - foreach (var invoiceTax in invoiceTaxes) - { - var iTax = daoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); - data.TableFooterRows.Add(new Tuple( - string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), - invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); - } + foreach (var invoiceTax in invoiceTaxes) + { + var iTax = DaoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); + data.TableFooterRows.Add(new Tuple( + string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), + invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); + } - //data.TableFooterRows.Add(new Tuple(CRMInvoiceResource.ResourceManager.GetString("Discount", cultureInfo), "-" + discount.ToString(CultureInfo.InvariantCulture))); + //data.TableFooterRows.Add(new Tuple(CRMInvoiceResource.ResourceManager.GetString("Discount", cultureInfo), "-" + discount.ToString(CultureInfo.InvariantCulture))); - data.TableTotalRow = - new Tuple( - string.Format("{0} ({1})", CRMInvoiceResource.ResourceManager.GetString("Total", cultureInfo), - invoice.Currency), amount.ToString(CultureInfo.InvariantCulture)); + data.TableTotalRow = + new Tuple( + string.Format("{0} ({1})", CRMInvoiceResource.ResourceManager.GetString("Total", cultureInfo), + invoice.Currency), amount.ToString(CultureInfo.InvariantCulture)); - #endregion + #endregion - #region Terms + #region Terms - data.Terms = - new Tuple(CRMInvoiceResource.ResourceManager.GetString("Terms", cultureInfo), - invoice.Terms); + data.Terms = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Terms", cultureInfo), + invoice.Terms); - #endregion + #endregion - #region Notes + #region Notes - if (!string.IsNullOrEmpty(invoice.Description)) - { - data.Notes = - new Tuple( - CRMInvoiceResource.ResourceManager.GetString("ClientNotes", cultureInfo), - invoice.Description); - } + if (!string.IsNullOrEmpty(invoice.Description)) + { + data.Notes = + new Tuple( + CRMInvoiceResource.ResourceManager.GetString("ClientNotes", cultureInfo), + invoice.Description); + } - #endregion + #endregion - #region Consignee + #region Consignee - var consignee = daoFactory.GetContactDao().GetByID(invoice.ConsigneeID); + var consignee = DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID); - if (consignee != null) - { - sb = new StringBuilder(); + if (consignee != null) + { + sb = new StringBuilder(); - sb.Append(consignee.GetTitle()); + sb.Append(consignee.GetTitle()); - var deliveryAddress = deliveryAddressID != 0 - ? daoFactory.GetContactInfoDao().GetByID(deliveryAddressID) - : null; - if (deliveryAddress != null && deliveryAddress.InfoType == ContactInfoType.Address && - deliveryAddress.Category == (int) AddressCategory.Postal) - { - list = new List(); + var deliveryAddress = deliveryAddressID != 0 + ? DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID) + : null; + if (deliveryAddress != null && deliveryAddress.InfoType == ContactInfoType.Address && + deliveryAddress.Category == (int)AddressCategory.Postal) + { + list = new List(); - var obj = JObject.Parse(deliveryAddress.Data); + var obj = JObject.Parse(deliveryAddress.Data); - var str = obj.Value("street"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); + var str = obj.Value("street"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - str = obj.Value("city"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); + str = obj.Value("city"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - str = obj.Value("state"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); + str = obj.Value("state"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - str = obj.Value("zip"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); + str = obj.Value("zip"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - str = obj.Value("country"); - if (!string.IsNullOrEmpty(str)) - list.Add(str); + str = obj.Value("country"); + if (!string.IsNullOrEmpty(str)) + list.Add(str); - if (list.Count > 0) - { - sb.AppendLine(); - sb.Append(string.Join(", ", list)); - } + if (list.Count > 0) + { + sb.AppendLine(); + sb.Append(string.Join(", ", list)); } - - data.Consignee = - new Tuple(CRMInvoiceResource.ResourceManager.GetString("ShipTo", cultureInfo), - sb.ToString()); } - #endregion + data.Consignee = + new Tuple(CRMInvoiceResource.ResourceManager.GetString("ShipTo", cultureInfo), + sb.ToString()); + } - #region Addresses + #endregion - data.BillingAddressID = billingAddressID; - data.DeliveryAddressID = deliveryAddressID; + #region Addresses - #endregion + data.BillingAddressID = billingAddressID; + data.DeliveryAddressID = deliveryAddressID; + + #endregion + + return data; - return data; - } } - private static InvoiceFormattedData ReadData(string jsonData) + private InvoiceFormattedData ReadData(string jsonData) { - var data = new InvoiceFormattedData(); + var data = new InvoiceFormattedData(DaoFactory, OrganisationLogoManager); + var jsonObj = JObject.Parse(jsonData); @@ -456,7 +459,7 @@ private static InvoiceFormattedData ReadData(string jsonData) if (string.IsNullOrEmpty(data.LogoBase64) && data.LogoBase64Id != 0) { - data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(data.LogoBase64Id); + data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(data.LogoBase64Id); } @@ -570,79 +573,75 @@ private static InvoiceFormattedData ReadData(string jsonData) return data; } - private static InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, + private InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, InvoiceFormattedData invoiceOldData) { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - - var data = invoiceOldData; + var data = invoiceOldData; - var cultureInfo = string.IsNullOrEmpty(invoice.Language) - ? CultureInfo.CurrentCulture - : CultureInfo.GetCultureInfo(invoice.Language); + var cultureInfo = string.IsNullOrEmpty(invoice.Language) + ? CultureInfo.CurrentCulture + : CultureInfo.GetCultureInfo(invoice.Language); - #region TableBodyRows, TableFooterRows, TableTotalRow + #region TableBodyRows, TableFooterRows, TableTotalRow - data.TableBodyRows = new List>(); + data.TableBodyRows = new List>(); - var invoiceLines = invoice.GetInvoiceLines(daoFactory); - var invoiceTaxes = new Dictionary(); + var invoiceLines = invoice.GetInvoiceLines(DaoFactory); + var invoiceTaxes = new Dictionary(); - decimal subtotal = 0; - decimal discount = 0; - decimal amount = 0; + decimal subtotal = 0; + decimal discount = 0; + decimal amount = 0; - foreach (var line in invoiceLines) + foreach (var line in invoiceLines) + { + var item = DaoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); + var tax1 = line.InvoiceTax1ID > 0 + ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) + : null; + var tax2 = line.InvoiceTax2ID > 0 + ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) + : null; + + var subtotalValue = Math.Round(line.Quantity * line.Price, 2); + var discountValue = Math.Round(subtotalValue * line.Discount / 100, 2); + + decimal rate = 0; + if (tax1 != null) { - var item = daoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); - var tax1 = line.InvoiceTax1ID > 0 - ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) - : null; - var tax2 = line.InvoiceTax2ID > 0 - ? daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) - : null; - - var subtotalValue = Math.Round(line.Quantity*line.Price, 2); - var discountValue = Math.Round(subtotalValue*line.Discount/100, 2); - - decimal rate = 0; - if (tax1 != null) + rate += tax1.Rate; + if (invoiceTaxes.ContainsKey(tax1.ID)) + { + invoiceTaxes[tax1.ID] = invoiceTaxes[tax1.ID] + + Math.Round((subtotalValue - discountValue) * tax1.Rate / 100, 2); + } + else { - rate += tax1.Rate; - if (invoiceTaxes.ContainsKey(tax1.ID)) - { - invoiceTaxes[tax1.ID] = invoiceTaxes[tax1.ID] + - Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2); - } - else - { - invoiceTaxes.Add(tax1.ID, Math.Round((subtotalValue - discountValue)*tax1.Rate/100, 2)); - } + invoiceTaxes.Add(tax1.ID, Math.Round((subtotalValue - discountValue) * tax1.Rate / 100, 2)); } - if (tax2 != null) + } + if (tax2 != null) + { + rate += tax2.Rate; + if (invoiceTaxes.ContainsKey(tax2.ID)) { - rate += tax2.Rate; - if (invoiceTaxes.ContainsKey(tax2.ID)) - { - invoiceTaxes[tax2.ID] = invoiceTaxes[tax2.ID] + - Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2); - } - else - { - invoiceTaxes.Add(tax2.ID, Math.Round((subtotalValue - discountValue)*tax2.Rate/100, 2)); - } + invoiceTaxes[tax2.ID] = invoiceTaxes[tax2.ID] + + Math.Round((subtotalValue - discountValue) * tax2.Rate / 100, 2); } + else + { + invoiceTaxes.Add(tax2.ID, Math.Round((subtotalValue - discountValue) * tax2.Rate / 100, 2)); + } + } - decimal taxValue = Math.Round((subtotalValue - discountValue)*rate/100, 2); - decimal amountValue = Math.Round(subtotalValue - discountValue + taxValue, 2); + decimal taxValue = Math.Round((subtotalValue - discountValue) * rate / 100, 2); + decimal amountValue = Math.Round(subtotalValue - discountValue + taxValue, 2); - subtotal += subtotalValue; - discount += discountValue; - amount += amountValue; + subtotal += subtotalValue; + discount += discountValue; + amount += amountValue; - data.TableBodyRows.Add(new List + data.TableBodyRows.Add(new List { item.Title + (string.IsNullOrEmpty(line.Description) ? string.Empty : ": " + line.Description), line.Quantity.ToString(CultureInfo.InvariantCulture), @@ -652,35 +651,33 @@ private static InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, tax2 != null ? tax2.Name : string.Empty, (subtotalValue - discountValue).ToString(CultureInfo.InvariantCulture) }); - } + } - data.TableFooterRows = new List>(); - data.TableFooterRows.Add( - new Tuple(CRMInvoiceResource.ResourceManager.GetString("Subtotal", cultureInfo), - (subtotal - discount).ToString(CultureInfo.InvariantCulture))); + data.TableFooterRows = new List>(); + data.TableFooterRows.Add( + new Tuple(CRMInvoiceResource.ResourceManager.GetString("Subtotal", cultureInfo), + (subtotal - discount).ToString(CultureInfo.InvariantCulture))); - foreach (var invoiceTax in invoiceTaxes) - { - var iTax = daoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); - data.TableFooterRows.Add(new Tuple( - string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), - invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); - } - - //data.TableFooterRows.Add(new Tuple(CRMInvoiceResource.ResourceManager.GetString("Discount", cultureInfo), "-" + discount.ToString(CultureInfo.InvariantCulture))); + foreach (var invoiceTax in invoiceTaxes) + { + var iTax = DaoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); + data.TableFooterRows.Add(new Tuple( + string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), + invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); + } - data.TableTotalRow = - new Tuple( - string.Format("{0} ({1})", CRMInvoiceResource.ResourceManager.GetString("Total", cultureInfo), - invoice.Currency), amount.ToString(CultureInfo.InvariantCulture)); + //data.TableFooterRows.Add(new Tuple(CRMInvoiceResource.ResourceManager.GetString("Discount", cultureInfo), "-" + discount.ToString(CultureInfo.InvariantCulture))); + data.TableTotalRow = + new Tuple( + string.Format("{0} ({1})", CRMInvoiceResource.ResourceManager.GetString("Total", cultureInfo), + invoice.Currency), amount.ToString(CultureInfo.InvariantCulture)); - #endregion + #endregion - return data; - } + return data; } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs index 0e76fb686bd..53933e6f3ca 100644 --- a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -44,13 +44,16 @@ public class OrganisationLogoManager { public OrganisationLogoManager(WebImageSupplier webImageSupplier, Global global, - IOptionsMonitor logger) + IOptionsMonitor logger, + DaoFactory daoFactory) { WebImageSupplier = webImageSupplier; Global = global; Logger = logger.Get("ASC.CRM"); + DaoFactory = daoFactory; } + public DaoFactory DaoFactory { get; } public ILog Logger { get; } public Global Global { get; } @@ -110,7 +113,7 @@ private String ExecResizeImage(byte[] imageData, Size fotoSize, IDataStore dataS } } } - + #endregion public String GetDefaultLogoUrl() @@ -121,10 +124,10 @@ public String GetDefaultLogoUrl() public String GetOrganisationLogoBase64(int logoID) { if (logoID <= 0) { return ""; } - using (var scope = DIHelper.Resolve()) - { - return scope.Resolve().GetInvoiceDao().GetOrganisationLogoBase64(logoID); - } + + return DaoFactory.GetInvoiceDao().GetOrganisationLogoBase64(logoID); + + } public String GetOrganisationLogoSrc(int logoID) @@ -187,7 +190,7 @@ public int TryUploadOrganisationLogoFromTmp(DaoFactory factory) public String UploadLogo(byte[] imageData, ImageFormat imageFormat) { var photoPath = BuildFilePath("." + Global.GetImgFormatName(imageFormat)); - + return ExecResizeImage(imageData, OrganisationLogoSize, Global.GetStore(), photoPath); } } diff --git a/products/ASC.CRM/Server/Classes/SignalRHelper.cs b/products/ASC.CRM/Server/Classes/SignalRHelper.cs index 1170ad1f6a3..c4ed1408bda 100644 --- a/products/ASC.CRM/Server/Classes/SignalRHelper.cs +++ b/products/ASC.CRM/Server/Classes/SignalRHelper.cs @@ -34,37 +34,39 @@ namespace ASC.Web.CRM.Classes public class SignalRHelper { private readonly string numberId; - private readonly SignalrServiceClient signalrServiceClient; - public SignalRHelper(string numberId) + public SignalrServiceClient SignalrServiceClient { get; } + + public SignalRHelper(string numberId, + SignalrServiceClient signalrServiceClient) { - signalrServiceClient = new SignalrServiceClient("voip"); - this.numberId = numberId.TrimStart('+'); + SignalrServiceClient = signalrServiceClient; + this.numberId = numberId.TrimStart('+'); } - + public void Enqueue(string call, string agent) { - signalrServiceClient.EnqueueCall(numberId, call, agent); + SignalrServiceClient.EnqueueCall(numberId, call, agent); } public void Incoming(string call, string agent) { - signalrServiceClient.IncomingCall(call, agent); + SignalrServiceClient.IncomingCall(call, agent); } public void MissCall(string call, string agent) { - signalrServiceClient.MissCall(numberId, call, agent); + SignalrServiceClient.MissCall(numberId, call, agent); } public void Reload(string agentId = null) { - signalrServiceClient.Reload(numberId, agentId); + SignalrServiceClient.Reload(numberId, agentId); } public Tuple GetAgent(List contactsResponsibles) { - return signalrServiceClient.GetAgent>(numberId, contactsResponsibles); + return SignalrServiceClient.GetAgent>(numberId, contactsResponsibles); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs index c2a5f1fbcdb..1b95f54f55a 100644 --- a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs +++ b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs @@ -49,11 +49,12 @@ public class ProductSubscriptionManager : IProductSubscriptionManager private readonly Guid _importCompleted = new Guid("{6A717AAD-16AE-4713-A782-B887766BEB9F}"); private readonly Guid _createNewContact = new Guid("{ADAC1E70-4163-41c1-8968-67A44E4D24E7}"); - public ProductSubscriptionManager(CoreBaseSettings coreBaseSettings) + public ProductSubscriptionManager(CoreBaseSettings coreBaseSettings, NotifySource notifySource) { CoreBaseSettings = coreBaseSettings; } + public NotifySource NotifySource { get; } public CoreBaseSettings CoreBaseSettings { get; } public List GetSubscriptionObjects(Guid subItem) @@ -126,7 +127,7 @@ public List GetSubscriptionTypes() public ISubscriptionProvider SubscriptionProvider { - get { return NotifySource.Instance.GetSubscriptionProvider(); } + get { return NotifySource.GetSubscriptionProvider(); } } public GroupByType GroupByType diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index 7d90891a6c5..c397f1da833 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -46,9 +46,8 @@ namespace ASC.Web.CRM.Classes { public class VoipEngine { - private readonly WorkerQueue Queue = new WorkerQueue(1, TimeSpan.FromMinutes(30)); + private readonly WorkerQueue Queue = new WorkerQueue(); private readonly object Locker = new object(); - private readonly DaoFactory daoFactory; public VoipEngine(DaoFactory daoFactory, CRMSecurity cRMSecurity, @@ -58,15 +57,17 @@ public VoipEngine(DaoFactory daoFactory, TenantManager tenantManager, VoipDao voipDao) { - this.daoFactory = daoFactory; CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; SecurityContext = securityContext; Logger = logger.Get("ASC.CRM"); TenantManager = tenantManager; VoipDao = voipDao; + DaoFactory = daoFactory; } + public DaoFactory DaoFactory { get; } + public VoipDao VoipDao { get; } public TenantManager TenantManager { get; } @@ -83,7 +84,7 @@ public VoipEngine(DaoFactory daoFactory, public VoipCall SaveOrUpdateCall(VoipCall callHistory) { - var dao = daoFactory.GetVoipDao(); + var dao = DaoFactory.GetVoipDao(); var call = dao.GetCall(callHistory.Id) ?? callHistory; if (string.IsNullOrEmpty(call.ParentID)) @@ -193,13 +194,13 @@ public Contact GetContact(VoipCall call) var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; - var newContactIds = daoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); + var newContactIds = DaoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); foreach (var newContactId in newContactIds) { if (newContactId != 0) { - var existContact = daoFactory.GetContactDao().GetByID(newContactId); + var existContact = DaoFactory.GetContactDao().GetByID(newContactId); if (CRMSecurity.CanAccessTo(existContact)) { call.ContactId = newContactId; @@ -227,7 +228,7 @@ public void SaveAdditionalInfo(string callId) Queue.Start(SaveAdditionalInfoAction); } - Queue.Add(new QueueItem {CallID = callId, TenantID = TenantId }); + Queue.Add(new QueueItem { CallID = callId, TenantID = TenantId }); } } @@ -237,36 +238,40 @@ private void SaveAdditionalInfoAction(QueueItem queueItem) { TenantManager.SetCurrentTenant(queueItem.TenantID); - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var voipEngine = new VoipEngine(daoFactory); - var dao = daoFactory.GetVoipDao(); - - var call = dao.GetCall(queueItem.CallID); + var voipEngine = new VoipEngine(DaoFactory, + CRMSecurity, + TenantUtil, + SecurityContext, + null, + TenantManager, + VoipDao); - GetPriceAndDuration(call); + var dao = DaoFactory.GetVoipDao(); - if (call.ChildCalls.Any()) - { - call.ChildCalls.ForEach(r => - { - GetPriceAndDuration(r); - voipEngine.SaveOrUpdateCall(r); - }); - } + var call = dao.GetCall(queueItem.CallID); - call = voipEngine.SaveOrUpdateCall(call); + GetPriceAndDuration(call); - if (!string.IsNullOrEmpty(call.VoipRecord.Id)) + if (call.ChildCalls.Any()) + { + call.ChildCalls.ForEach(r => { - call.VoipRecord = VoipDao.GetProvider().GetRecord((string)call.Id, (string)call.VoipRecord.Id); - voipEngine.SaveOrUpdateCall(call); - } + GetPriceAndDuration(r); + voipEngine.SaveOrUpdateCall(r); + }); + } + + call = voipEngine.SaveOrUpdateCall(call); - SecurityContext.AuthenticateMe(call.AnsweredBy); - AddHistoryToCallContact(call, daoFactory); + if (!string.IsNullOrEmpty(call.VoipRecord.Id)) + { + call.VoipRecord = VoipDao.GetProvider().GetRecord((string)call.Id, (string)call.VoipRecord.Id); + voipEngine.SaveOrUpdateCall(call); } + + SecurityContext.AuthenticateMe(call.AnsweredBy); + AddHistoryToCallContact(call, DaoFactory); + } catch (Exception ex) { @@ -286,7 +291,7 @@ public void AnswerCall(VoipCall call) { call.AnsweredBy = SecurityContext.CurrentAccount.ID; call.Status = VoipCallStatus.Answered; - daoFactory.GetVoipDao().SaveOrUpdateCall(call); + DaoFactory.GetVoipDao().SaveOrUpdateCall(call); } public Contact CreateContact(string contactPhone) @@ -300,9 +305,9 @@ public Contact CreateContact(string contactPhone) CreateOn = DateTime.UtcNow }; - contact.ID = daoFactory.GetContactDao().SaveContact(contact); + contact.ID = DaoFactory.GetContactDao().SaveContact(contact); - daoFactory.GetContactInfoDao() + DaoFactory.GetContactInfoDao() .Save(new ContactInfo { ContactID = contact.ID, @@ -311,7 +316,7 @@ public Contact CreateContact(string contactPhone) Data = contactPhone }); - CRMSecurity.SetAccessTo(contact, new List {SecurityContext.CurrentAccount.ID}); + CRMSecurity.SetAccessTo(contact, new List { SecurityContext.CurrentAccount.ID }); return contact; } diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index 9b146a571a0..2ad652a1964 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -53,10 +53,9 @@ public ProductEntryPoint(SecurityContext securityContext, DaoFactory daoFactory, FilesIntegration filesIntegration, IOptionsMonitor logger, - CRMSecurity cRMSecurity, SettingsManager settingsManager, CoreConfiguration coreConfiguration, - Global global) + FileSecurityProvider fileSecurityProvider) { SecurityContext = securityContext; UserManager = userManager; @@ -64,10 +63,9 @@ public ProductEntryPoint(SecurityContext securityContext, DaoFactory = daoFactory; FilesIntegration = filesIntegration; Logger = logger.Get("ASC"); - CRMSecurity = cRMSecurity; SettingsManager = settingsManager; CoreConfiguration = coreConfiguration; - Global = global; + FileSecurityProvider = fileSecurityProvider; } public static readonly Guid ID = WebItemManager.CRMProductID; @@ -77,7 +75,8 @@ public ProductEntryPoint(SecurityContext securityContext, private static readonly object Locker = new object(); private static bool registered; - public Global Global { get; } + public FileSecurityProvider FileSecurityProvider { get; } + public CoreConfiguration CoreConfiguration { get; } @@ -85,8 +84,7 @@ public ProductEntryPoint(SecurityContext securityContext, public SettingsManager SettingsManager { get; } - public CRMSecurity CRMSecurity { get; } - + public FilesIntegration FilesIntegration { get; } public DaoFactory DaoFactory { get; } @@ -145,11 +143,11 @@ public override void Init() if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) { - FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider(FilesIntegration, CRMSecurity)); + FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", FileSecurityProvider); } if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "opportunity")) { - FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", new FileSecurityProvider(FilesIntegration, CRMSecurity)); + FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", FileSecurityProvider); } // SearchHandlerManager.Registry(new SearchHandler()); @@ -160,7 +158,6 @@ public override void Init() // defaults: new {controller = "Twilio", action = "index" }); // ClientScriptLocalization = new ClientLocalizationResources(); - DIHelper.Register(); } @@ -170,11 +167,8 @@ public void ConfigurePortal() if (!tenantSettings.IsConfiguredPortal) { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); // Task Category - var listItemDao = daoFactory.GetListItemDao(); + var listItemDao = DaoFactory.GetListItemDao(); listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Call, "task_category_call.png")); listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Deal, "task_category_deal.png")); listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Demo, "task_category_demo.png")); @@ -189,7 +183,7 @@ public void ConfigurePortal() listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_ThankYou, "task_category_thank_you.png")); // Deal Milestone New - var milestoneDao = daoFactory.GetDealMilestoneDao(); + var milestoneDao = DaoFactory.GetDealMilestoneDao(); milestoneDao.Create(new DealMilestone { @@ -287,10 +281,10 @@ public void ConfigurePortal() listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png")); listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Meeting, "event_category_meeting.png")); // Tags - daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Lead, true); - daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Customer, true); - daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Supplier, true); - daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Staff, true); + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Lead, true); + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Customer, true); + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Supplier, true); + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Staff, true); tenantSettings.WebFormKey = Guid.NewGuid(); tenantSettings.IsConfiguredPortal = true; @@ -299,7 +293,6 @@ public void ConfigurePortal() { throw new Exception("not save CRMSettings"); } - } } if (!tenantSettings.IsConfiguredSmtp) diff --git a/products/ASC.CRM/Server/Controllers/CurrencyRateController.cs b/products/ASC.CRM/Server/Controllers/CurrencyRateController.cs new file mode 100644 index 00000000000..428496637eb --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CurrencyRateController.cs @@ -0,0 +1,17 @@ +using ASC.Web.Api.Routing; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ASC.Api.CRM +{ + [DefaultRoute] + [ApiController] + public class CurrencyRateController : ControllerBase + { + + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/TasksController.cs b/products/ASC.CRM/Server/Controllers/TasksController.cs new file mode 100644 index 00000000000..50e23c9cf23 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/TasksController.cs @@ -0,0 +1,12 @@ +using ASC.Web.Api.Routing; +using Microsoft.AspNetCore.Mvc; + +namespace ASC.Api.CRM +{ + [DefaultRoute] + [ApiController] + public class TasksController : ControllerBase + { + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/DIHelper.cs b/products/ASC.CRM/Server/Core/DIHelper.cs deleted file mode 100644 index 2fb79db1ed6..00000000000 --- a/products/ASC.CRM/Server/Core/DIHelper.cs +++ /dev/null @@ -1,75 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.CRM.Core.Dao; -using Autofac; - -namespace ASC.Web.CRM.Core -{ - public static class DIHelper - { - internal static IContainer Builder; - private static bool isRegistered; - private static readonly object Locker = new object(); - - public static void Register() - { - if (isRegistered) return; - - lock (Locker) - { - if (isRegistered) return; - - var container = AutofacConfigLoader.Load("crm"); - - container.Register(c => DbManager.FromHttpContext("default")) - .AsSelf() - .As() - .InstancePerRequest(); - - Builder = container.Build(); - isRegistered = true; - } - } - - public static ILifetimeScope Resolve() - { - return Resolve(TenantProvider.CurrentTenantID); - } - - - public static ILifetimeScope Resolve(int tenantID) - { - Register(); - - var scope = Builder.BeginLifetimeScope(Autofac.Core.Lifetime.MatchingScopeLifetimeTags.RequestLifetimeScopeTag); - scope.Resolve(); - scope.Resolve(new TypedParameter(typeof(int), tenantID)); - - return scope; - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index f5ff455489c..a93ea83a0aa 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -61,14 +61,16 @@ public CachedInvoiceDao(DbContextManager dbContextManager, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, SettingsManager settingsManager, - InvoiceSetting invoiceSetting) + InvoiceSetting invoiceSetting, + InvoiceFormattedData invoiceFormattedData) : base(dbContextManager, tenantManager, securityContext, factoryIndexer, logger, settingsManager, - invoiceSetting + invoiceSetting, + invoiceFormattedData ) { _invoiceCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice"); @@ -123,7 +125,8 @@ public InvoiceDao( FactoryIndexer factoryIndexer, IOptionsMonitor logger, SettingsManager settingsManager, - InvoiceSetting invoiceSetting) + InvoiceSetting invoiceSetting, + InvoiceFormattedData invoiceFormattedData) : base(dbContextManager, tenantManager, securityContext, @@ -132,10 +135,12 @@ public InvoiceDao( FactoryIndexer = factoryIndexer; SettingsManager = settingsManager; InvoiceSetting = invoiceSetting; + InvoiceFormattedData = invoiceFormattedData; } public InvoiceSetting InvoiceSetting { get; } + public InvoiceFormattedData InvoiceFormattedData { get; } public SettingsManager SettingsManager { get; } public FactoryIndexer FactoryIndexer { get; } diff --git a/products/ASC.CRM/Server/Core/Entities/Contact.cs b/products/ASC.CRM/Server/Core/Entities/Contact.cs index 88cb679fc79..ae02d7080f4 100644 --- a/products/ASC.CRM/Server/Core/Entities/Contact.cs +++ b/products/ASC.CRM/Server/Core/Entities/Contact.cs @@ -81,21 +81,21 @@ public static String GetTitle(this Contact contact) return String.Format("{0} {1}", people.FirstName, people.LastName); } - public static String RenderLinkForCard(this Contact contact) - { - var isCompany = contact is Company; - var popupID = Guid.NewGuid(); - - return !CRMSecurity.CanAccessTo(contact) ? - String.Format(@"{0}", GetTitle(contact).HtmlEncode()) : - String.Format(@" - {4} - ", - isCompany ? "crm-companyInfoCardLink" : "crm-peopleInfoCardLink", - UrlConstant.ID, contact != null ? contact.ID : 0, - isCompany ? String.Empty : String.Format("&{0}=people", UrlConstant.Type), - GetTitle(contact).HtmlEncode(), popupID); - } + //public static String RenderLinkForCard(this Contact contact) + //{ + // var isCompany = contact is Company; + // var popupID = Guid.NewGuid(); + + // return !CRMSecurity.CanAccessTo(contact) ? + // String.Format(@"{0}", GetTitle(contact).HtmlEncode()) : + // String.Format(@" + // {4} + // ", + // isCompany ? "crm-companyInfoCardLink" : "crm-peopleInfoCardLink", + // UrlConstant.ID, contact != null ? contact.ID : 0, + // isCompany ? String.Empty : String.Format("&{0}=people", UrlConstant.Type), + // GetTitle(contact).HtmlEncode(), popupID); + //} } [Serializable] diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs index 7c6887f0d27..18388a4ebd3 100644 --- a/products/ASC.CRM/Server/Core/Entities/Invoice.cs +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -94,12 +94,12 @@ public Type ObjectType public List GetInvoiceLines(DaoFactory daoFactory) { - return daoFactory.InvoiceLineDao.GetInvoiceLines(ID); + return daoFactory.GetInvoiceLineDao().GetInvoiceLines(ID); } public File GetInvoiceFile(DaoFactory daoFactory) { - return daoFactory.GetFileDao.GetFile(FileID, 0); + return daoFactory.GetFileDao().GetFile(FileID, 0); } public decimal GetInvoiceCost(DaoFactory daoFactory) diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index ff6fc7fe449..81378486d0f 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -51,9 +51,9 @@ namespace ASC.CRM.Core { public class CRMSecurity - { + { public readonly IAction _actionRead = new Action(new Guid("{6F05C382-8BCA-4469-9424-C807A98C40D7}"), "", true, false); - + public CRMSecurity(SecurityContext securityContext, AuthorizationManager authorizationManager, UserManager userManager, @@ -73,6 +73,7 @@ public CRMSecurity(SecurityContext securityContext, CurrencyProvider = currencyProvider; } + public CurrencyProvider CurrencyProvider { get; } public PermissionContext PermissionContext { get; } @@ -88,7 +89,7 @@ public CRMSecurity(SecurityContext securityContext, public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public UserManager UserManager { get; } - + private ISecurityObjectProvider GetCRMSecurityProvider() { return new CRMSecurityObjectProvider(); @@ -201,7 +202,7 @@ public List GetAccessSubjectGuidsTo(ISecurityObjectId entity) public void SetAccessTo(ISecurityObjectId entity, List subjectID) { - + if (subjectID.Count == 0) { AuthorizationManager.RemoveAllAces(entity); @@ -264,30 +265,25 @@ public bool CanAccessTo(RelationshipEvent relationshipEvent, Guid userId) if (IsAdministrator(userId)) return true; - using (var scope = DIHelper.Resolve()) + if (relationshipEvent.ContactID > 0) { - var daoFactory = scope.Resolve(); - - if (relationshipEvent.ContactID > 0) - { - var contactObj = daoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); - if (contactObj != null) return CanAccessTo(contactObj, userId); - } - - if (relationshipEvent.EntityType == EntityType.Case) - { - var caseObj = daoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); - if (caseObj != null) return CanAccessTo(caseObj, userId); - } + var contactObj = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); + if (contactObj != null) return CanAccessTo(contactObj, userId); + } - if (relationshipEvent.EntityType == EntityType.Opportunity) - { - var dealObj = daoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); - if (dealObj != null) return CanAccessTo(dealObj, userId); - } + if (relationshipEvent.EntityType == EntityType.Case) + { + var caseObj = DaoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); + if (caseObj != null) return CanAccessTo(caseObj, userId); + } - return false; + if (relationshipEvent.EntityType == EntityType.Opportunity) + { + var dealObj = DaoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); + if (dealObj != null) return CanAccessTo(dealObj, userId); } + + return false; } public bool CanAccessTo(Contact contact) @@ -309,7 +305,8 @@ public bool CanAccessTo(int contactID, EntityType entityType, ShareType? shareTy { return true; } - if (entityType == EntityType.Company){ + if (entityType == EntityType.Company) + { var fakeContact = new Company() { ID = contactID }; return GetAccessSubjectTo(fakeContact).ContainsKey(SecurityContext.CurrentAccount.ID); } @@ -332,29 +329,26 @@ public bool CanAccessTo(Task task, Guid userId) (task.ContactID == 0 && task.EntityID == 0) || task.CreateBy == userId) return true; - using (var scope = DIHelper.Resolve()) + if (task.ContactID > 0) { - var daoFactory = scope.Resolve(); - if (task.ContactID > 0) - { - var contactObj = daoFactory.GetContactDao().GetByID(task.ContactID); - if (contactObj != null) return CanAccessTo(contactObj, userId); - } - - if (task.EntityType == EntityType.Case) - { - var caseObj = daoFactory.GetCasesDao().GetByID(task.EntityID); - if (caseObj != null) return CanAccessTo(caseObj, userId); - } + var contactObj = DaoFactory.GetContactDao().GetByID(task.ContactID); + if (contactObj != null) return CanAccessTo(contactObj, userId); + } - if (task.EntityType == EntityType.Opportunity) - { - var dealObj = daoFactory.GetDealDao().GetByID(task.EntityID); - if (dealObj != null) return CanAccessTo(dealObj, userId); - } + if (task.EntityType == EntityType.Case) + { + var caseObj = DaoFactory.GetCasesDao().GetByID(task.EntityID); + if (caseObj != null) return CanAccessTo(caseObj, userId); + } - return false; + if (task.EntityType == EntityType.Opportunity) + { + var dealObj = DaoFactory.GetDealDao().GetByID(task.EntityID); + if (dealObj != null) return CanAccessTo(dealObj, userId); } + + return false; + } public bool CanAccessTo(Invoice invoice) @@ -366,17 +360,14 @@ public bool CanAccessTo(Invoice invoice, Guid userId) { if (IsAdministrator(userId) || invoice.CreateBy == userId) return true; - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - if (invoice.ContactID > 0) - return CanAccessTo(daoFactory.GetContactDao().GetByID(invoice.ContactID), userId); + if (invoice.ContactID > 0) + return CanAccessTo(DaoFactory.GetContactDao().GetByID(invoice.ContactID), userId); - if (invoice.EntityType == EntityType.Opportunity) - return CanAccessTo(daoFactory.GetDealDao().GetByID(invoice.EntityID), userId); + if (invoice.EntityType == EntityType.Opportunity) + return CanAccessTo(DaoFactory.GetDealDao().GetByID(invoice.EntityID), userId); + + return false; - return false; - } } public bool CanAccessTo(InvoiceTax invoiceTax) @@ -414,45 +405,41 @@ public bool CanEdit(RelationshipEvent relationshipEvent) if (IsAdmin) return true; - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - if (relationshipEvent.ContactID > 0) + if (relationshipEvent.ContactID > 0) + { + var contactObj = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); + if (contactObj != null) { - var contactObj = daoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); - if (contactObj != null) - { - if(CanEdit(contactObj)) return true; + if (CanEdit(contactObj)) return true; - return CanAccessTo(contactObj, userId) && relationshipEvent.CreateBy == userId; - } + return CanAccessTo(contactObj, userId) && relationshipEvent.CreateBy == userId; } + } - if (relationshipEvent.EntityType == EntityType.Case) + if (relationshipEvent.EntityType == EntityType.Case) + { + var caseObj = DaoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); + if (caseObj != null) { - var caseObj = daoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); - if (caseObj != null) - { - if (CanEdit(caseObj)) return true; + if (CanEdit(caseObj)) return true; - return CanAccessTo(caseObj, userId) && relationshipEvent.CreateBy == userId; - } + return CanAccessTo(caseObj, userId) && relationshipEvent.CreateBy == userId; } + } - if (relationshipEvent.EntityType == EntityType.Opportunity) + if (relationshipEvent.EntityType == EntityType.Opportunity) + { + var dealObj = DaoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); + if (dealObj != null) { - var dealObj = daoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); - if (dealObj != null) - { - if (CanEdit(dealObj)) return true; + if (CanEdit(dealObj)) return true; - return CanAccessTo(dealObj, userId) && relationshipEvent.CreateBy == userId; - } + return CanAccessTo(dealObj, userId) && relationshipEvent.CreateBy == userId; } - - return false; } + + return false; } public bool CanEdit(Contact contact) @@ -489,10 +476,8 @@ public bool CanEdit(InvoiceItem invoiceItem) public bool CanDelete(Contact contact) { - using (var scope = DIHelper.Resolve()) - { - return CanEdit(contact) && scope.Resolve().GetContactDao().CanDelete(contact.ID); - } + return CanEdit(contact) && DaoFactory.GetContactDao().CanDelete(contact.ID); + } public bool CanDelete(Invoice invoice) @@ -502,18 +487,13 @@ public bool CanDelete(Invoice invoice) public bool CanDelete(InvoiceItem invoiceItem) { - using (var scope = DIHelper.Resolve()) - { - return CanEdit(invoiceItem) && scope.Resolve().GetInvoiceItemDao().CanDelete(invoiceItem.ID); - } + return CanEdit(invoiceItem) && DaoFactory.GetInvoiceItemDao().CanDelete(invoiceItem.ID); } public bool CanDelete(InvoiceTax invoiceTax) { - using (var scope = DIHelper.Resolve()) - { - return CanEdit(invoiceTax) && scope.Resolve().GetInvoiceTaxDao().CanDelete(invoiceTax.ID); - } + return CanEdit(invoiceTax) && DaoFactory.GetInvoiceTaxDao().CanDelete(invoiceTax.ID); + } public bool CanDelete(Deal deal) @@ -659,7 +639,7 @@ public void DemandDelete(InvoiceTax invoiceTax) public void DemandDelete(RelationshipEvent relationshipEvent) { - if (!CanDelete(relationshipEvent)) throw CreateSecurityException(); + if (!CanDelete(relationshipEvent)) throw CreateSecurityException(); } public void DemandCreateOrUpdate(RelationshipEvent relationshipEvent) @@ -682,20 +662,15 @@ public void DemandCreateOrUpdate(Deal deal) deal.DealMilestoneID <= 0 || string.IsNullOrEmpty(deal.BidCurrency)) throw new ArgumentException(); + var listItem = DaoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); + if (listItem == null) throw new ArgumentException(CRMErrorsResource.DealMilestoneNotFound); - using (var scope = DIHelper.Resolve()) + if (deal.ContactID != 0) { - var daoFactory = scope.Resolve(); - var listItem = daoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); - if (listItem == null) throw new ArgumentException(CRMErrorsResource.DealMilestoneNotFound); - - if (deal.ContactID != 0) - { - var contact = daoFactory.GetContactDao().GetByID(deal.ContactID); - if (contact == null) throw new ArgumentException(); + var contact = DaoFactory.GetContactDao().GetByID(deal.ContactID); + if (contact == null) throw new ArgumentException(); - if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); - } + if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); } if (string.IsNullOrEmpty(deal.BidCurrency)) { @@ -720,18 +695,15 @@ public void DemandCreateOrUpdate(InvoiceLine line, Invoice targetInvoice) if (targetInvoice == null || targetInvoice.ID != line.InvoiceID) throw new ArgumentException(); if (!CanEdit(targetInvoice)) throw CreateSecurityException(); - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - if (!daoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) - throw new ArgumentException(); + if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) + throw new ArgumentException(); - if (line.InvoiceTax1ID > 0 && !daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) - throw new ArgumentException(); + if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) + throw new ArgumentException(); + + if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) + throw new ArgumentException(); - if (line.InvoiceTax2ID > 0 && !daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) - throw new ArgumentException(); - } } public void DemandCreateOrUpdate(Invoice invoice) @@ -742,32 +714,28 @@ public void DemandCreateOrUpdate(Invoice invoice) String.IsNullOrEmpty(invoice.Currency) || invoice.ExchangeRate <= 0 || String.IsNullOrEmpty(invoice.Terms)) - throw new ArgumentException(); + throw new ArgumentException(); - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var contact = daoFactory.GetContactDao().GetByID(invoice.ContactID); - if (contact == null) throw new ArgumentException(); - if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); + var contact = DaoFactory.GetContactDao().GetByID(invoice.ContactID); + if (contact == null) throw new ArgumentException(); + if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); - if (invoice.ConsigneeID != 0 && invoice.ConsigneeID != invoice.ContactID) - { - var consignee = daoFactory.GetContactDao().GetByID(invoice.ConsigneeID); - if (consignee == null) throw new ArgumentException(); - if (!CanAccessTo(consignee)) throw new SecurityException(CRMErrorsResource.AccessDenied); - } + if (invoice.ConsigneeID != 0 && invoice.ConsigneeID != invoice.ContactID) + { + var consignee = DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID); + if (consignee == null) throw new ArgumentException(); + if (!CanAccessTo(consignee)) throw new SecurityException(CRMErrorsResource.AccessDenied); + } - if (invoice.EntityID != 0) - { - var deal = daoFactory.GetDealDao().GetByID(invoice.EntityID); - if (deal == null) throw new ArgumentException(); - if (!CanAccessTo(deal)) throw new SecurityException(CRMErrorsResource.AccessDenied); + if (invoice.EntityID != 0) + { + var deal = DaoFactory.GetDealDao().GetByID(invoice.EntityID); + if (deal == null) throw new ArgumentException(); + if (!CanAccessTo(deal)) throw new SecurityException(CRMErrorsResource.AccessDenied); - var dealMembers = daoFactory.GetDealDao().GetMembers(invoice.EntityID); - if (!dealMembers.Contains(invoice.ContactID)) - throw new ArgumentException(); - } + var dealMembers = DaoFactory.GetDealDao().GetMembers(invoice.EntityID); + if (!dealMembers.Contains(invoice.ContactID)) + throw new ArgumentException(); } if (CurrencyProvider.Get(invoice.Currency.ToUpper()) == null) @@ -807,12 +775,9 @@ public IEnumerable FilterRead(IEnumerable tasks) .Distinct() .ToList(); - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); if (contactIDs.Any()) { - contactIDs = daoFactory.GetContactDao() + contactIDs = DaoFactory.GetContactDao() .GetContacts(contactIDs.ToArray()) .Select(x => x.ID) .ToList(); @@ -829,7 +794,7 @@ public IEnumerable FilterRead(IEnumerable tasks) if (casesIds.Any()) { - casesIds = daoFactory.GetCasesDao() + casesIds = DaoFactory.GetCasesDao() .GetCases(casesIds.ToArray()) .Select(x => x.ID) .ToList(); @@ -846,7 +811,7 @@ public IEnumerable FilterRead(IEnumerable tasks) if (dealsIds.Any()) { - dealsIds = daoFactory.GetDealDao() + dealsIds = DaoFactory.GetDealDao() .GetDeals(dealsIds.ToArray()) .Select(x => x.ID) .ToList(); @@ -859,7 +824,7 @@ public IEnumerable FilterRead(IEnumerable tasks) } return result; - } + } @@ -872,20 +837,16 @@ public IEnumerable FilterRead(IEnumerable invoices) var result = invoices.ToList(); var contactIDs = result.Select(x => x.ContactID).Distinct().ToList(); - using (var scope = DIHelper.Resolve()) + if (contactIDs.Any()) { - var daoFactory = scope.Resolve(); - if (contactIDs.Any()) - { - contactIDs = daoFactory.GetContactDao() - .GetContacts(contactIDs.ToArray()) - .Select(x => x.ID) - .ToList(); + contactIDs = DaoFactory.GetContactDao() + .GetContacts(contactIDs.ToArray()) + .Select(x => x.ID) + .ToList(); - result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID)).ToList(); + result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID)).ToList(); - if (!result.Any()) return Enumerable.Empty(); - } + if (!result.Any()) return Enumerable.Empty(); } return result; diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index cb889e604ef..a4021f196de 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -39,12 +39,16 @@ namespace ASC.CRM.Core public class FileSecurity : IFileSecurity { public FileSecurity(FilesIntegration filesIntegration, - CRMSecurity cRMSecurity) + CRMSecurity cRMSecurity, + DaoFactory daoFactory) { FilesIntegration = filesIntegration; CRMSecurity = cRMSecurity; + DaoFactory = daoFactory; } + public DaoFactory DaoFactory { get; } + public FilesIntegration FilesIntegration { get; } public CRMSecurity CRMSecurity { get; } @@ -85,31 +89,28 @@ public bool CanRead(FileEntry entry, Guid userId) { if (entry.FileEntryType == FileEntryType.Folder) return false; - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var invoice = daoFactory.GetInvoiceDao().GetByFileId(Convert.ToInt32(entry.ID)); - if (invoice != null) - return CRMSecurity.CanAccessTo(invoice, userId); + var invoice = DaoFactory.GetInvoiceDao().GetByFileId(Convert.ToInt32(entry.ID)); + if (invoice != null) + return CRMSecurity.CanAccessTo(invoice, userId); + + var reportFile = DaoFactory.GetReportDao().GetFile(Convert.ToInt32(entry.ID), userId); + + if (reportFile != null) + return true; - var reportFile = daoFactory.GetReportDao().GetFile(Convert.ToInt32(entry.ID), userId); - - if (reportFile != null) - return true; + var tagDao = FilesIntegration.DaoFactory.GetTagDao(); - var tagDao = FilesIntegration.DaoFactory.GetTagDao(); + var eventIds = tagDao.GetTags(entry.ID, FileEntryType.File, TagType.System) + .Where(x => x.TagName.StartsWith("RelationshipEvent_")) + .Select(x => Convert.ToInt32(x.TagName.Split(new[] { '_' })[1])) + .ToList(); - var eventIds = tagDao.GetTags(entry.ID, FileEntryType.File, TagType.System) - .Where(x => x.TagName.StartsWith("RelationshipEvent_")) - .Select(x => Convert.ToInt32(x.TagName.Split(new[] { '_' })[1])) - .ToList(); + if (!eventIds.Any()) return false; - if (!eventIds.Any()) return false; + var eventItem = DaoFactory.GetRelationshipEventDao().GetByID(eventIds.First()); - var eventItem = daoFactory.GetRelationshipEventDao().GetByID(eventIds.First()); + return CRMSecurity.CanAccessTo(eventItem, userId); - return CRMSecurity.CanAccessTo(eventItem, userId); - } } public IEnumerable WhoCanRead(FileEntry entry) @@ -121,23 +122,26 @@ public IEnumerable WhoCanRead(FileEntry entry) public class FileSecurityProvider : IFileSecurityProvider { public FileSecurityProvider(FilesIntegration filesIntegration, - CRMSecurity cRMSecurity) + CRMSecurity cRMSecurity, + DaoFactory daoFactory) { FilesIntegration = filesIntegration; CRMSecurity = cRMSecurity; + DaoFactory = daoFactory; } + public DaoFactory DaoFactory { get; } public FilesIntegration FilesIntegration { get; } public CRMSecurity CRMSecurity { get; } public IFileSecurity GetFileSecurity(string data) { - return new FileSecurity(FilesIntegration, CRMSecurity); + return new FileSecurity(FilesIntegration, CRMSecurity, DaoFactory); } public Dictionary GetFileSecurity(Dictionary data) { - return data.ToDictionary, object, IFileSecurity>(d => d.Key, d => new FileSecurity(FilesIntegration, CRMSecurity)); + return data.ToDictionary, object, IFileSecurity>(d => d.Key, d => new FileSecurity(FilesIntegration, CRMSecurity, DaoFactory)); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index c57572bb554..315d6fd867a 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -53,27 +53,25 @@ public class CurrencyProvider public CurrencyProvider(IOptionsMonitor logger, IConfiguration configuration, - SettingsManager settingsManager) + SettingsManager settingsManager, + DaoFactory daoFactory) { _log = logger.Get("ASC"); Configuration = configuration; SettingsManager = settingsManager; - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var currencies = daoFactory.CurrencyInfoDao.GetAll(); + var currencies = daoFactory.GetCurrencyInfoDao().GetAll(); - if (currencies == null || currencies.Count == 0) - { - currencies = new List + if (currencies == null || currencies.Count == 0) + { + currencies = new List { new CurrencyInfo("Currency_UnitedStatesDollar", "USD", "$", "US", true, true) }; - } - - _currencies = currencies.ToDictionary(c => c.Abbreviation); } + + _currencies = currencies.ToDictionary(c => c.Abbreviation); + } public IConfiguration Configuration { get; } @@ -195,7 +193,7 @@ private Dictionary GetExchangeRates() TryToReadPublisherDate(tmppath); - + var updateEnable = Configuration["crm:update:currency:info:enable"] != "false"; var ratesUpdatedFlag = false; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index e1a19542c50..b56503d49e7 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -45,7 +45,7 @@ namespace ASC.Web.CRM.Classes { - public class ImportDataCache + public class ImportDataCache { public ImportDataCache(TenantManager tenantManager) { @@ -81,7 +81,7 @@ public ImportDataOperation Get(EntityType entityType) return Cache.Get(GetStateCacheKey(entityType)); } - public void Insert(EntityType entityType,ImportDataOperation data) + public void Insert(EntityType entityType, ImportDataOperation data) { Cache.Insert(GetStateCacheKey(entityType), data, TimeSpan.FromMinutes(1)); } @@ -112,7 +112,7 @@ public void ResetAll(EntityType entityType, int tenantId = -1) public partial class ImportDataOperation : IProgressItem { public ImportDataOperation(EntityType entityType, - string CSVFileURI, + string CSVFileURI, string importSettingsJSON, SecurityContext securityContext, Global global, @@ -124,7 +124,7 @@ public ImportDataOperation(EntityType entityType, NotifyClient notifyClient, SettingsManager settingsManager, CurrencyProvider currencyProvider, - IServiceProvider serviceProvider + DaoFactory daoFactory ) { ImportDataCache = importDataCache; @@ -138,7 +138,7 @@ IServiceProvider serviceProvider SecurityContext = securityContext; _dataStore = global.GetStore(); - + _tenantID = tenantManager.CurrentTenant.TenantId; _author = SecurityContext.CurrentAccount; @@ -151,6 +151,7 @@ IServiceProvider serviceProvider CRMSecurity = cRMSecurity; SettingsManager = settingsManager; CurrencyProvider = currencyProvider; + DaoFactory = daoFactory; } public CurrencyProvider CurrencyProvider { get; } @@ -169,6 +170,8 @@ IServiceProvider serviceProvider public UserManager UserManager { get; } + public DaoFactory DaoFactory { get; } + public ILog LogManager { get; } private readonly ILog _log; @@ -176,7 +179,7 @@ IServiceProvider serviceProvider private readonly IDataStore _dataStore; private readonly IAccount _author; - + private readonly int _tenantID; private readonly string _CSVFileURI; @@ -206,7 +209,7 @@ public override int GetHashCode() public object Clone() { - return MemberwiseClone(); + return MemberwiseClone(); } public object Id { get; set; } @@ -218,7 +221,7 @@ public object Clone() public double Percentage { get; set; } public bool IsCompleted { get; set; } - + private String GetPropertyValue(String propertyName) { if (_importSettings.ColumnMapping[propertyName] == null) return String.Empty; @@ -240,7 +243,7 @@ private void Complete() _log.Debug("Import is completed"); NotifyClient.SendAboutImportCompleted(_author.ID, _entityType); - + ImportDataCache.Insert(_entityType, (ImportDataOperation)Clone()); } @@ -250,35 +253,32 @@ public void RunJob() { TenantManager.SetCurrentTenant(_tenantID); SecurityContext.AuthenticateMe(_author); + + var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + + System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; + System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; - using (var scope = DIHelper.Resolve()) + ImportDataCache.Insert(_entityType, (ImportDataOperation)Clone()); + + switch (_entityType) { - var daoFactory = scope.Resolve(); - var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); - - System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; - System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; - - ImportDataCache.Insert(_entityType, (ImportDataOperation) Clone()); - - switch (_entityType) - { - case EntityType.Contact: - ImportContactsData(daoFactory); - break; - case EntityType.Opportunity: - ImportOpportunityData(daoFactory); - break; - case EntityType.Case: - ImportCaseData(daoFactory); - break; - case EntityType.Task: - ImportTaskData(daoFactory); - break; - default: - throw new ArgumentException(CRMErrorsResource.EntityTypeUnknown); - } + case EntityType.Contact: + ImportContactsData(DaoFactory); + break; + case EntityType.Opportunity: + ImportOpportunityData(DaoFactory); + break; + case EntityType.Case: + ImportCaseData(DaoFactory); + break; + case EntityType.Task: + ImportTaskData(DaoFactory); + break; + default: + throw new ArgumentException(CRMErrorsResource.EntityTypeUnknown); } + } catch (OperationCanceledException) { diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index ad22bc860ca..1f4684cd595 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -55,7 +55,9 @@ public PdfCreator(IOptionsMonitor logger, Files.Classes.PathProvider filesPathProvider, DocumentServiceConnector documentServiceConnector, IServiceProvider serviceProvider, - OrganisationLogoManager organisationLogoManager) + OrganisationLogoManager organisationLogoManager, + DaoFactory daoFactory, + InvoiceFormattedData invoiceFormattedData) { FilesPathProvider = filesPathProvider; @@ -64,9 +66,14 @@ public PdfCreator(IOptionsMonitor logger, DocumentServiceConnector = documentServiceConnector; ServiceProvider = serviceProvider; OrganisationLogoManager = organisationLogoManager; - + DaoFactory = daoFactory; + InvoiceFormattedData = invoiceFormattedData; } + public InvoiceFormattedData InvoiceFormattedData { get; } + + public DaoFactory DaoFactory { get; } + private Stream Template { get @@ -94,11 +101,7 @@ public void CreateAndSaveFile(int invoiceId) try { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - - var invoice = daoFactory.GetInvoiceDao().GetByID(invoiceId); + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); if (invoice == null) { @@ -122,7 +125,7 @@ public void CreateAndSaveFile(int invoiceId) var file = ServiceProvider.GetService>(); file.Title = string.Format("{0}{1}", invoice.Number, FormatPdf); - file.FolderID = daoFactory.GetFileDao().GetRoot(); + file.FolderID = DaoFactory.GetFileDao().GetRoot(); var request = WebRequest.Create(urlToFile); @@ -132,7 +135,7 @@ public void CreateAndSaveFile(int invoiceId) file.ContentLength = response.ContentLength; Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); - file = daoFactory.GetFileDao().SaveFile(file, stream); + file = DaoFactory.GetFileDao().SaveFile(file, stream); } if (file == null) @@ -144,13 +147,11 @@ public void CreateAndSaveFile(int invoiceId) Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); - daoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); - daoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] {invoice.FileID}); - - } + DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] {invoice.FileID}); } catch (Exception e) { @@ -236,7 +237,7 @@ public File GetConvertedFile(ConverterData data, DaoFactory daoFactory) return null; } - var invoice = daoFactory.GetInvoiceDao().GetByID(data.InvoiceId); + var invoice = DaoFactory.GetInvoiceDao().GetByID(data.InvoiceId); return SaveFile(invoice, urlToFile, daoFactory); } @@ -256,7 +257,7 @@ private File SaveFile(Invoice data, string url, DaoFactory daoFactory) var document = ServiceProvider.GetService>(); document.Title = string.Format("{0}{1}", data.Number, FormatPdf); - document.FolderID = daoFactory.GetFileDao().GetRoot(); + document.FolderID = DaoFactory.GetFileDao().GetRoot(); document.ContentLength = response.ContentLength; if (data.GetInvoiceFile(daoFactory) != null) @@ -264,7 +265,7 @@ private File SaveFile(Invoice data, string url, DaoFactory daoFactory) document.ID = data.FileID; } - file = daoFactory.GetFileDao().SaveFile(document, stream); + file = DaoFactory.GetFileDao().SaveFile(document, stream); } } } diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index 24d86243579..d1da9803ce9 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -48,6 +48,7 @@ public ReportHelper(TenantUtil tenantUtil, Global global, DocbuilderReportsUtility docbuilderReportsUtility, SettingsManager settingsManager, + DaoFactory daoFactory, IServiceProvider serviceProvider ) { @@ -56,8 +57,10 @@ IServiceProvider serviceProvider DocbuilderReportsUtility = docbuilderReportsUtility; SettingsManager = settingsManager; ServiceProvider = serviceProvider; + DaoFactory = daoFactory; } + public DaoFactory DaoFactory { get; } public IServiceProvider ServiceProvider { get; } public DocbuilderReportsUtility DocbuilderReportsUtility { get; } @@ -114,86 +117,79 @@ private string GetFileName(ReportType reportType) public bool CheckReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { + var reportDao = DaoFactory.GetReportDao(); + throw new NotImplementedException(); - using (var scope = DIHelper.Resolve()) - { - var reportDao = scope.Resolve().GetReportDao(); - - //switch (reportType) - //{ - // case ReportType.SalesByManagers: - // return reportDao.CheckSalesByManagersReportData(timePeriod, managers); - // case ReportType.SalesForecast: - // return reportDao.CheckSalesForecastReportData(timePeriod, managers); - // case ReportType.SalesFunnel: - // return reportDao.CheckSalesFunnelReportData(timePeriod, managers); - // case ReportType.WorkloadByContacts: - // return reportDao.CheckWorkloadByContactsReportData(timePeriod, managers); - // case ReportType.WorkloadByTasks: - // return reportDao.CheckWorkloadByTasksReportData(timePeriod, managers); - // case ReportType.WorkloadByDeals: - // return reportDao.CheckWorkloadByDealsReportData(timePeriod, managers); - // case ReportType.WorkloadByInvoices: - // return reportDao.CheckWorkloadByInvoicesReportData(timePeriod, managers); - // case ReportType.WorkloadByVoip: - // return reportDao.CheckWorkloadByViopReportData(timePeriod, managers); - // case ReportType.SummaryForThePeriod: - // return reportDao.CheckSummaryForThePeriodReportData(timePeriod, managers); - // case ReportType.SummaryAtThisMoment: - // return reportDao.CheckSummaryAtThisMomentReportData(timePeriod, managers); - // default: - // return false; - //} - } + + //switch (reportType) + //{ + // case ReportType.SalesByManagers: + // return reportDao.CheckSalesByManagersReportData(timePeriod, managers); + // case ReportType.SalesForecast: + // return reportDao.CheckSalesForecastReportData(timePeriod, managers); + // case ReportType.SalesFunnel: + // return reportDao.CheckSalesFunnelReportData(timePeriod, managers); + // case ReportType.WorkloadByContacts: + // return reportDao.CheckWorkloadByContactsReportData(timePeriod, managers); + // case ReportType.WorkloadByTasks: + // return reportDao.CheckWorkloadByTasksReportData(timePeriod, managers); + // case ReportType.WorkloadByDeals: + // return reportDao.CheckWorkloadByDealsReportData(timePeriod, managers); + // case ReportType.WorkloadByInvoices: + // return reportDao.CheckWorkloadByInvoicesReportData(timePeriod, managers); + // case ReportType.WorkloadByVoip: + // return reportDao.CheckWorkloadByViopReportData(timePeriod, managers); + // case ReportType.SummaryForThePeriod: + // return reportDao.CheckSummaryForThePeriodReportData(timePeriod, managers); + // case ReportType.SummaryAtThisMoment: + // return reportDao.CheckSummaryAtThisMomentReportData(timePeriod, managers); + // default: + // return false; + //} } public List GetMissingRates(ReportType reportType) { - using (var scope = DIHelper.Resolve()) - { - var reportDao = scope.Resolve().GetReportDao(); - if (reportType == ReportType.WorkloadByTasks || reportType == ReportType.WorkloadByInvoices || - reportType == ReportType.WorkloadByContacts || reportType == ReportType.WorkloadByVoip) return null; + var reportDao = DaoFactory.GetReportDao(); - return reportDao.GetMissingRates(SettingsManager.Load().DefaultCurrency.Abbreviation); - } + if (reportType == ReportType.WorkloadByTasks || reportType == ReportType.WorkloadByInvoices || + reportType == ReportType.WorkloadByContacts || reportType == ReportType.WorkloadByVoip) return null; + + return reportDao.GetMissingRates(SettingsManager.Load().DefaultCurrency.Abbreviation); } private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { + var reportDao = DaoFactory.GetReportDao(); + var defaultCurrency = SettingsManager.Load().DefaultCurrency.Abbreviation; + throw new NotImplementedException(); - using (var scope = DIHelper.Resolve()) - { - var reportDao = scope.Resolve().GetReportDao(); - - var defaultCurrency = SettingsManager.Load().DefaultCurrency.Abbreviation; - - //switch (reportType) - //{ - // case ReportType.SalesByManagers: - // return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); - // case ReportType.SalesForecast: - // return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); - // case ReportType.SalesFunnel: - // return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); - // case ReportType.WorkloadByContacts: - // return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); - // case ReportType.WorkloadByTasks: - // return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); - // case ReportType.WorkloadByDeals: - // return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); - // case ReportType.WorkloadByInvoices: - // return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); - // case ReportType.WorkloadByVoip: - // return reportDao.GetWorkloadByViopReportData(timePeriod, managers); - // case ReportType.SummaryForThePeriod: - // return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); - // case ReportType.SummaryAtThisMoment: - // return reportDao.GetSummaryAtThisMomentReportData(timePeriod, managers, defaultCurrency); - // default: - // return null; - //} - } + + //switch (reportType) + //{ + // case ReportType.SalesByManagers: + // return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); + // case ReportType.SalesForecast: + // return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); + // case ReportType.SalesFunnel: + // return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); + // case ReportType.WorkloadByContacts: + // return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); + // case ReportType.WorkloadByTasks: + // return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); + // case ReportType.WorkloadByDeals: + // return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); + // case ReportType.WorkloadByInvoices: + // return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); + // case ReportType.WorkloadByVoip: + // return reportDao.GetWorkloadByViopReportData(timePeriod, managers); + // case ReportType.SummaryForThePeriod: + // return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); + // case ReportType.SummaryAtThisMoment: + // return reportDao.GetSummaryAtThisMomentReportData(timePeriod, managers, defaultCurrency); + // default: + // return null; + //} } private string GetReportScript(object data, ReportType type, string fileName) @@ -210,27 +206,23 @@ private string GetReportScript(object data, ReportType type, string fileName) private void SaveReportFile(ReportState state, string url) { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var data = new WebClient().DownloadData(url); + var data = new WebClient().DownloadData(url); - using (var stream = new System.IO.MemoryStream(data)) - { + using (var stream = new System.IO.MemoryStream(data)) + { + var document = ServiceProvider.GetService>(); - var document = ServiceProvider.GetService>(); + document.Title = state.FileName; + document.FolderID = DaoFactory.GetFileDao().GetRoot(); + document.ContentLength = stream.Length; - document.Title = state.FileName; - document.FolderID = daoFactory.GetFileDao().GetRoot(); - document.ContentLength = stream.Length; - - var file = daoFactory.GetFileDao().SaveFile(document, stream); + var file = DaoFactory.GetFileDao().SaveFile(document, stream); - daoFactory.GetReportDao().SaveFile((int)file.ID, (ReportType)state.ReportType); + DaoFactory.GetReportDao().SaveFile((int)file.ID, state.ReportType); - state.FileId = (int)file.ID; - } + state.FileId = (int)file.ID; } + } public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) @@ -245,13 +237,14 @@ public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod tim if (string.IsNullOrEmpty(script)) throw new Exception(CRMReportResource.ErrorNullReportScript); - // ServiceProvider.GetService() + // ServiceProvider.GetService() - var state = new ReportState(GetFileName(reportType), tmpFileName, script, (int)reportType, ReportOrigin.CRM, SaveReportFile, null); + // var state = new ReportState(GetFileName(reportType), tmpFileName, script, (int)reportType, ReportOrigin.CRM, SaveReportFile, null); - DocbuilderReportsUtility.Enqueue(state); + // DocbuilderReportsUtility.Enqueue(state); - return state; + // return state; + throw new NotImplementedException(); } } } \ No newline at end of file From 9928c9bc46cf5a1f3eda658b170e0f84bb415c6a Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 14 Apr 2020 21:59:32 +0300 Subject: [PATCH 11/61] crm: migrate DAO to EF Core --- .../ASC.CRM/Server/Classes/CRMSettings.cs | 18 ++++++- products/ASC.CRM/Server/Classes/Global.cs | 18 +++++++ .../Server/Classes/InvoiceFormattedData.cs | 13 +++++ .../Server/Classes/OrganisationLogoManager.cs | 16 +++++- .../ASC.CRM/Server/Classes/PathProvider.cs | 12 +++++ products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 18 +++++++ .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 20 ++++++++ .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 21 +++++++- .../Server/Core/Dao/CurrencyInfoDao.cs | 18 +++++-- .../Server/Core/Dao/CurrencyRateDao.cs | 13 +++++ .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 13 +++++ .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 14 ++++- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 17 +++++++ .../Server/Core/Dao/DealMilestoneDao.cs | 51 ++++++++++++------- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 14 +++++ .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 17 +++++++ .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 17 ++++++- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 13 +++++ .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 13 +++++ .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 14 +++++ .../Server/Core/Dao/RelationshipEventDao.cs | 21 +++++++- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 18 +++++++ products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 20 ++++++++ products/ASC.CRM/Server/Core/Dao/TagDao.cs | 15 +++++- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 21 +++++++- .../Core/Dao/TaskTemplateContainerDao.cs | 14 +++++ .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 10 ++++ .../Server/Core/Search/BundleSearch.cs | 31 +++++++++-- .../Server/Core/Search/CasesWrapper.cs | 12 +++++ .../Server/Core/Search/ContactsWrapper.cs | 14 +++++ .../Server/Core/Search/DealsWrapper.cs | 12 +++++ .../Server/Core/Search/EmailWrapper.cs | 23 +++++++++ .../Server/Core/Search/EventsWrapper.cs | 12 +++++ .../Server/Core/Search/FieldsWrapper.cs | 12 +++++ .../ASC.CRM/Server/Core/Search/InfoWrapper.cs | 12 +++++ .../Server/Core/Search/InvoicesWrapper.cs | 12 +++++ .../Server/Core/Search/TasksWrapper.cs | 13 +++++ .../Server/Core/Security/CRMSecutiry.cs | 20 +++++++- products/ASC.CRM/Server/Startup.cs | 16 ++++++ .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 14 ++++- products/ASC.CRM/Server/Utils/PdfCreator.cs | 20 +++++++- 41 files changed, 653 insertions(+), 39 deletions(-) diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index 05e97aa8311..5bed2ce6af8 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -32,7 +32,7 @@ using System.Runtime.Serialization; using Microsoft.Extensions.DependencyInjection; - +using ASC.Common; namespace ASC.Web.CRM.Classes { @@ -40,7 +40,6 @@ namespace ASC.Web.CRM.Classes [DataContract] public class SMTPServerSetting { - public SMTPServerSetting() { Host = String.Empty; @@ -101,6 +100,7 @@ public InvoiceSetting(IConfiguration configuration) Prefix = String.Empty; Number = String.Empty; Terms = String.Empty; + Configuration = configuration; } public IConfiguration Configuration { get; } @@ -258,4 +258,18 @@ public ISettings GetDefault(IServiceProvider serviceProvider) return new CRMReportSampleSettings { NeedToGenerate = true }; } } + + public static class InvoiceSettingExtention + { + public static DIHelper AddInvoiceSettingService(this DIHelper services) + { + services.TryAddScoped(); + + return services; + + } + } + + + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index b1584b2184c..8f47ee25047 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Core; using ASC.Core.Common.Settings; using ASC.CRM.Core; @@ -350,4 +351,21 @@ public static JObject JObjectParseWithDateAsString(string data) return JObject.Load(reader); } } + + public static class GlobalExtention + { + public static DIHelper AddGlobalService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddStorageFactoryService() + .AddSecurityContextService() + .AddSetupInfo() + .AddFilesLinkUtilityService() + .AddCRMSecurityService() + .AddTenantManagerService() + .AddSettingsManagerService() + .AddPdfCreatorService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 798996a8ce1..3191f939444 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -680,4 +681,16 @@ private InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, } } + + + public static class InvoiceFormattedDataExtention + { + public static DIHelper AddInvoiceFormattedDataService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddOrganisationLogoManagerService() + .AddDaoFactoryService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs index 53933e6f3ca..76a3382ba40 100644 --- a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -28,6 +28,7 @@ using System.Drawing; using System.Drawing.Imaging; using System.IO; +using ASC.Common; using ASC.Common.Logging; using ASC.CRM.Core.Dao; using ASC.Data.Storage; @@ -194,4 +195,17 @@ public String UploadLogo(byte[] imageData, ImageFormat imageFormat) return ExecResizeImage(imageData, OrganisationLogoSize, Global.GetStore(), photoPath); } } -} \ No newline at end of file + + public static class OrganisationLogoManagerExtention + { + public static DIHelper AddOrganisationLogoManagerService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddWebImageSupplierService() + .AddGlobalService() + .AddDaoFactoryService(); + + } + } +} diff --git a/products/ASC.CRM/Server/Classes/PathProvider.cs b/products/ASC.CRM/Server/Classes/PathProvider.cs index 8852854da77..773eceb3d5b 100644 --- a/products/ASC.CRM/Server/Classes/PathProvider.cs +++ b/products/ASC.CRM/Server/Classes/PathProvider.cs @@ -28,6 +28,7 @@ using System; using System.Web; +using ASC.Common; using ASC.Common.Web; using ASC.Data.Storage; using ASC.Web.Studio.Utility; @@ -105,4 +106,15 @@ public String StartURL() //} } + + public static class PathProviderExtention + { + public static DIHelper AddCRMPathProviderService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCommonLinkUtilityService(); + } + } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index c442ca4bb53..18e76eb98bd 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -45,6 +45,7 @@ using SortedByType = ASC.CRM.Core.Enums.SortedByType; using Microsoft.Extensions.Options; using ASC.Common.Logging; +using ASC.Common; namespace ASC.CRM.Core.Dao { @@ -683,4 +684,21 @@ public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) } } } + + public static class CasesDaoExtention + { + public static DIHelper AddCasesDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddCRMSecurityService() + .AddTenantUtilService() + .AddFilesIntegrationService() + .AddAuthorizationManagerService() + .AddBundleSearchService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 402fa04c44e..bd808cdbde7 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -2082,4 +2083,23 @@ public void SetContactLastModifedDate(int contactId, DateTime lastModifedDate) _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } } + + public static class ContactDaoExtention + { + public static DIHelper AddContactDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddCRMSecurityService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddTenantUtilService() + .AddAuthorizationManagerService() + .AddFilesIntegrationService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddBundleSearchService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 09b37ac7881..ec08d054d18 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -24,6 +24,7 @@ */ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -119,8 +120,7 @@ public ContactInfoDao( IOptionsMonitor logger, FactoryIndexer factoryIndexerEmailWrapper, FactoryIndexer factoryIndexerInfoWrapper, - IServiceProvider serviceProvider - ) + IServiceProvider serviceProvider) : base(dbContextManager, tenantManager, securityContext, @@ -379,4 +379,21 @@ protected static ContactInfo ToContactInfo(DbContactInfo dbContactInfo) }; } } + + + + public static class ContactInfoDaoExtention + { + public static DIHelper AddContactInfoDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddTenantUtilService() + .AddFactoryIndexerService() + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 9971a7649fe..706c41e33bc 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -36,8 +37,7 @@ namespace ASC.CRM.Core.Dao { public class CurrencyInfoDao : AbstractDao - { - + { public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -90,4 +90,16 @@ private static CurrencyInfo ToCurrencyInfo(DbCurrencyInfo dbCurrencyInfo) ); } } -} \ No newline at end of file + + public static class CurrencyInfoDaoExtention + { + public static DIHelper AddCurrencyInfoDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index ef9ed9cfe45..1e8ec09c627 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -173,4 +174,16 @@ private static CurrencyRate ToCurrencyRate(DbCurrencyRate dbCurrencyRate) }; } } + + public static class CurrencyRateDaoExtention + { + public static DIHelper AddCurrencyRateDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 6bd112a7544..f8bc2b96864 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -23,6 +23,7 @@ * */ +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -581,4 +582,16 @@ public CustomField ToCustomField(DbFieldDescription dbFieldDescription, } } + public static class CustomFieldDaoExtention + { + public static DIHelper AddCustomFieldDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddTenantUtilService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index b92a10d7533..5e78a6d7763 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -26,6 +26,8 @@ using Microsoft.Extensions.DependencyInjection; using ASC.VoipService.Dao; using System; +using ASC.Common; +using ASC.Core.Common.Settings; namespace ASC.CRM.Core.Dao { @@ -155,4 +157,14 @@ public VoipDao GetVoipDao() return ServiceProvider.GetService(); } } -} \ No newline at end of file + + public static class DaoFactoryExtention + { + public static DIHelper AddDaoFactoryService(this DIHelper services) + { + services.TryAddScoped(); + + return services; + } + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index dcf4119fd18..a84fcac4f27 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -973,4 +974,20 @@ public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) } } + + public static class DealDaoExtention + { + public static DIHelper AddDealDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddCRMSecurityService() + .AddFactoryIndexerService() + .AddFilesIntegrationService() + .AddBundleSearchService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 9033266b5d4..f4da5b060ec 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -27,6 +27,7 @@ #region Import using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -52,7 +53,7 @@ public CachedDealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger) + IOptionsMonitor logger) : base(dbContextManager, tenantManager, securityContext, @@ -137,11 +138,11 @@ public virtual void Reorder(int[] ids) itemToUpdate.SortOrder = index; - CRMDbContext.Update(itemToUpdate); + CRMDbContext.Update(itemToUpdate); } CRMDbContext.SaveChanges(); - + tx.Commit(); } @@ -158,7 +159,7 @@ public Dictionary GetRelativeItemsCount() x => x.DealMilestoneId, (x, y) => new { x = x, count = y.Count() }) .OrderBy(x => x.x.SortOrder) - .ToDictionary(x => x.x.Id, y => y.count); + .ToDictionary(x => x.x.Id, y => y.count); } public int GetRelativeItemsCount(int id) @@ -179,7 +180,7 @@ public virtual int Create(DealMilestone item) if (item.SortOrder == 0) item.SortOrder = Query(CRMDbContext.DealMilestones).Select(x => x.SortOrder).Max() + 1; - + var itemToAdd = new DbDealMilestone { Title = item.Title, @@ -190,14 +191,14 @@ public virtual int Create(DealMilestone item) SortOrder = item.SortOrder, TenantId = TenantID }; - + CRMDbContext.DealMilestones.Add(itemToAdd); CRMDbContext.SaveChanges(); - + id = itemToAdd.Id; tx.Commit(); - + return id; } @@ -219,7 +220,7 @@ public virtual void Edit(DealMilestone item) { if (HaveContactLink(item.ID)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.DealMilestoneHasRelatedDeals)); - + var itemToUpdate = Query(CRMDbContext.DealMilestones) .FirstOrDefault(x => x.Id == item.ID); @@ -230,7 +231,7 @@ public virtual void Edit(DealMilestone item) itemToUpdate.Status = item.Status; CRMDbContext.DealMilestones.Update(itemToUpdate); - + CRMDbContext.SaveChanges(); } @@ -250,7 +251,7 @@ public virtual void Delete(int id) Id = id, TenantId = TenantID }; - + CRMDbContext.DealMilestones.Remove(dbDealMilestones); CRMDbContext.SaveChanges(); @@ -281,19 +282,31 @@ public List GetAll() .ToList() .ConvertAll(ToDealMilestone); } - + private static DealMilestone ToDealMilestone(DbDealMilestone dbDealMilestone) { return new DealMilestone { - ID = dbDealMilestone.Id, - Title = dbDealMilestone.Title, - Color = dbDealMilestone.Color, - Status = dbDealMilestone.Status, - Description = dbDealMilestone.Description, - Probability = dbDealMilestone.Probability, - SortOrder = dbDealMilestone.SortOrder + ID = dbDealMilestone.Id, + Title = dbDealMilestone.Title, + Color = dbDealMilestone.Color, + Status = dbDealMilestone.Status, + Description = dbDealMilestone.Description, + Probability = dbDealMilestone.Probability, + SortOrder = dbDealMilestone.SortOrder }; } } + + public static class DealMilestoneDaoExtention + { + public static DIHelper AddDealMilestoneDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 686271bf881..94c233527fa 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -97,4 +98,17 @@ public List GetEventsByFile(int id) } } + + public static class FileDaoExtention + { + public static DIHelper AddFileDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddFilesIntegrationService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index a93ea83a0aa..a81ccea7611 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -983,4 +984,20 @@ public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); } } + + public static class InvoiceDaoExtention + { + public static DIHelper AddFileDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddFactoryIndexerService() + .AddSettingsManagerService() + .AddInvoiceFormattedDataService() + .AddInvoiceSettingService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 5b46183b661..9680a69fd30 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -485,4 +486,18 @@ private IQueryable GetDbInvoiceItemByFilters( return sqlQuery; } } -} \ No newline at end of file + + public static class InvoiceItemDaoExtention + { + public static DIHelper AddInvoiceItemDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddTenantUtilService() + .AddCRMSecurityService(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index cd9045ef723..8dc383ef46a 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -283,4 +284,16 @@ private InvoiceLine ToInvoiceLine(DbInvoiceLine dbInvoiceLine) }; } } + + public static class InvoiceLineDaoExtention + { + public static DIHelper AddInvoiceLineDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index aa10d9be6c8..43a7b9e87ae 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -263,4 +264,16 @@ private InvoiceTax ToInvoiceTax(DbInvoiceTax dbInvoiceTax) return result; } } + + public static class InvoiceTaxDaoExtention + { + public static DIHelper AddInvoiceTaxDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index bb8194fe01f..5977a8dabde 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -24,6 +24,7 @@ */ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -597,4 +598,17 @@ public static ListItem ToListItem(DbListItem dbListItem) return result; } } + + + public static class ListItemDaoExtention + { + public static DIHelper AddListItemDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 9ea04224ed9..6d04e880786 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -715,4 +716,22 @@ private static string GetHistoryContentJson(JObject apiResponse) } } } -} + + public static class RelationshipEventDaoExtention + { + public static DIHelper AddListItemDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddFilesIntegrationService() + .AddCRMSecurityService() + .AddTenantUtilService() + .AddSetupInfo() + .AddCRMPathProviderService(); + } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 2ddbbf5b2b6..cfc279a7c66 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -47,6 +47,7 @@ using System.IO; using System.Linq; using Microsoft.Extensions.DependencyInjection; +using ASC.Common; #endregion @@ -2220,4 +2221,21 @@ public void SaveFile(int fileId, int reportType) //#endregion } + + public static class ReportDaoExtention + { + public static DIHelper AddReportDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddFilesIntegrationService() + .AddTenantUtilService() + .AddSettingsManagerService() + .AddGlobalService() + .AddUserManagerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index 4089ea9cfee..47f850a13d6 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Logging; using ASC.Common.Utils; using ASC.Core; @@ -463,4 +464,23 @@ private String GetPath(int contactID, int entityID, EntityType entityType) } } } + + public static class SearchDaoExtention + { + public static DIHelper AddSearchDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddCRMSecurityService() + .AddTenantUtilService() + .AddCRMPathProviderService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddWebImageSupplierService() + .AddBundleSearchService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 625ce62ac7b..a0e63340895 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -416,4 +417,16 @@ private static string CorrectTag(string tag) } } -} \ No newline at end of file + + public static class TagDaoExtention + { + public static DIHelper AddTagDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index db1090b01ac..00ff73498d4 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -1175,4 +1176,22 @@ public Task ToTask(DbTask dbTask) } } -} + + + public static class TaskDaoExtention + { + public static DIHelper AddTaskDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService() + .AddCRMSecurityService() + .AddTenantUtilService() + .AddFactoryIndexerService() + .AddUserDbContextService() + .AddCoreDbContextService(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 3f46a5c0275..06fa08eb264 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -23,6 +23,7 @@ * */ +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -279,4 +280,17 @@ protected TaskTemplate ToObject(DbTaskTemplate dbTaskTemplate) }; } } + + + public static class TaskTemplateDaoExtention + { + public static DIHelper AddTaskTemplateDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index 55752ccea50..bb8719f05e3 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -1,4 +1,5 @@ using System; +using ASC.Common; using ASC.Core.Common.EF; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; @@ -679,4 +680,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } + + + public static class CRMDbContextExtention + { + public static DIHelper AddCRMDbContextService(this DIHelper services) + { + return services.AddDbContextManagerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index cf2529ec7ad..e91084c14da 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -26,6 +26,7 @@ using System.Collections.Generic; using System.Linq; +using ASC.Common; using ASC.CRM.Core; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; @@ -70,7 +71,7 @@ public BundleSearch(FactoryIndexer contactsWrapperFactoryIndexe TasksWrapper = tasksWrapper; CasesWrapper = casesWrapper; InvoicesWrapper = invoicesWrapper; - + } public ContactsWrapper ContactsWrapper { get; } @@ -91,7 +92,7 @@ public BundleSearch(FactoryIndexer contactsWrapperFactoryIndexe public FactoryIndexer TasksWrapperFactoryIndexer { get; } public FactoryIndexer CasesWrapperFactoryIndexer { get; } public FactoryIndexer InvoicesWrapperFactoryIndexer { get; } - + public bool Support(EntityType entityType) { switch (entityType) @@ -174,7 +175,7 @@ public bool TrySelectContact(string text, out List result) IReadOnlyCollection personCustom; - if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] {0, 4, 5}), out personCustom)) + if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] { 0, 4, 5 }), out personCustom)) { result.AddRange(personCustom.Select(r => r.EntityId).ToList()); success = true; @@ -220,4 +221,28 @@ public bool TrySelectOpportunity(string text, out List result) return success; } } + + public static class BundleSearchExtention + { + public static DIHelper AddBundleSearchService(this DIHelper services) + { + return services.AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddFactoryIndexerService() + .AddFactoryIndexerHelperService() + .AddContactsWrapperService() + .AddInfoWrapperService() + .AddFieldsWrapperService() + .AddEventsWrapperService() + .AddDealsWrapperService() + .AddTasksWrapperService() + .AddCasesWrapperService() + .AddInvoicesWrapperService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs index d1880914576..20a51bba2f7 100644 --- a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs @@ -25,6 +25,7 @@ using System; +using ASC.Common; using ASC.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -55,4 +56,15 @@ public static CasesWrapper GetTasksWrapper(IServiceProvider serviceProvider, Cas }; } } + + public static class CasesWrapperExtention + { + public static DIHelper AddCasesWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs index dd778055b8f..a798e16b2f7 100644 --- a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs @@ -25,6 +25,7 @@ using System; +using ASC.Common; using ASC.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -95,4 +96,17 @@ public static ContactsWrapper FromPerson(int tenantId, Person d) }; } } + + public static class ContactsWrapperExtention + { + public static DIHelper AddContactsWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } + + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs b/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs index 3712fc18903..d1d26c2486f 100644 --- a/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs @@ -25,6 +25,7 @@ using System; +using ASC.Common; using ASC.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -58,4 +59,15 @@ public static DealsWrapper FromDeal(int tenantId, Deal deal) }; } } + + public static class DealsWrapperExtention + { + public static DIHelper AddDealsWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs b/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs index 124c4659762..27635a0388b 100644 --- a/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -116,4 +117,26 @@ public static EmailInfoWrapper FromContactInfo(int tenantId, ContactInfo cf) }; } } + + public static class EmailWrapperExtention + { + public static DIHelper AddEmailWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } + + public static class EmailInfoWrapperExtention + { + public static DIHelper AddEmailInfoWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs b/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs index a2a0f7511bc..f0efab17f7d 100644 --- a/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs @@ -25,6 +25,7 @@ using System; +using ASC.Common; using ASC.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -66,4 +67,15 @@ public static EventsWrapper FromEvent(int tenantId, RelationshipEvent relationsh }; } } + + public static class EventsWrapperExtention + { + public static DIHelper AddEventsWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs b/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs index 41adab8dd57..6ded7ae62cb 100644 --- a/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs @@ -25,6 +25,7 @@ using System; +using ASC.Common; using ASC.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -66,4 +67,15 @@ public static FieldsWrapper GetEventsWrapper(IServiceProvider serviceProvider, C }; } } + + public static class FieldsWrapperExtention + { + public static DIHelper AddFieldsWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs index 534a1eaf428..c4bc51a094c 100644 --- a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs @@ -35,6 +35,7 @@ using Newtonsoft.Json.Linq; using Microsoft.Extensions.DependencyInjection; +using ASC.Common; namespace ASC.Web.CRM.Core.Search { @@ -112,4 +113,15 @@ public static InfoWrapper FromCompany(IServiceProvider serviceProvider, ContactI }; } } + + public static class InfoWrapperExtention + { + public static DIHelper AddInfoWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs b/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs index 4ca0af304cd..321d32a8497 100644 --- a/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs @@ -25,6 +25,7 @@ using System; +using ASC.Common; using ASC.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -66,4 +67,15 @@ public static InvoicesWrapper FromInvoice(int tenantId, Invoice invoice) }; } } + + public static class InvoicesWrapperExtention + { + public static DIHelper AddInvoicesWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs b/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs index 9c0756e71c6..127815aab62 100644 --- a/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs @@ -25,6 +25,7 @@ using System; +using ASC.Common; using ASC.Core; using ASC.CRM.Core.Entities; using ASC.ElasticSearch; @@ -58,4 +59,16 @@ public static TasksWrapper FromTask(int tenantId, Task task) }; } } + + public static class TasksWrapperExtention + { + public static DIHelper AddTasksWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services + .AddFactoryIndexerService(); + } + } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 81378486d0f..a092a4beec7 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -24,11 +24,13 @@ */ +using ASC.Common; using ASC.Common.Security; using ASC.Common.Security.Authorizing; using ASC.Core; using ASC.Core.Users; using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; @@ -856,7 +858,23 @@ public bool CanGoToFeed(Task task) { return IsAdmin || task.ResponsibleID == SecurityContext.CurrentAccount.ID || task.CreateBy == SecurityContext.CurrentAccount.ID; } + } - + public static class CRMSecurityExtention + { + public static DIHelper AddCRMSecurityService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddSecurityContextService() + .AddAuthorizationManagerService() + .AddUserManagerService() + .AddDisplayUserSettingsService() + .AddDaoFactoryService() + .AddWebItemSecurity() + .AddPermissionContextService() + .AddCurrencyProviderService() + ; + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 8841e44c060..59650bedacf 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -2,6 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using ASC.Api.Core.Auth; +using ASC.Api.Core.Middleware; +using ASC.Common; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; @@ -26,6 +29,17 @@ public void ConfigureServices(IServiceCollection services) { services.AddHttpContextAccessor(); services.AddControllers(); + + var diHelper = new DIHelper(services); + + diHelper + .AddCookieAuthHandler() + .AddCultureMiddleware() + .AddIpSecurityFilter() + .AddPaymentFilter() + .AddProductSecurityFilter() + .AddTenantStatusFilter(); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -36,6 +50,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseDeveloperExceptionPage(); } + + app.UseRouting(); app.UseAuthorization(); diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index 315d6fd867a..774db165bd9 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Logging; using ASC.Core.Common.Settings; using ASC.CRM.Core; @@ -345,4 +346,15 @@ private void DownloadCurrencyPage(string currency, string filepath) } } -} + + public static class CurrencyProviderExtention + { + public static DIHelper AddCurrencyProviderService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddSettingsManagerService() + .AddDaoFactoryService(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index 1f4684cd595..cf579f8da88 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -45,7 +45,8 @@ using System.Xml; using Microsoft.Extensions.DependencyInjection; - +using ASC.Common; +using ASC.Web.Files.Classes; namespace ASC.Web.CRM.Classes { @@ -761,4 +762,19 @@ public class ConverterData public int InvoiceId { get; set; } public int FileId { get; set; } } -} \ No newline at end of file + + + public static class PdfCreatorExtention + { + public static DIHelper AddPdfCreatorService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddPathProviderService() + .AddDocumentServiceConnectorService() + .AddOrganisationLogoManagerService() + .AddDaoFactoryService() + .AddInvoiceFormattedDataService(); + } + } +} \ No newline at end of file From 35762e45eef3b315a5edde8519831a4c3946457f Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Thu, 16 Apr 2020 22:41:37 +0300 Subject: [PATCH 12/61] crm: migrate Api to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 15 + products/ASC.CRM/Server/Classes/Global.cs | 40 +- .../Server/Classes/InvoiceFormattedData.cs | 4 +- .../Server/Classes/OrganisationLogoManager.cs | 5 +- .../Server/Configuration/ProductEntryPoint.cs | 4 +- .../ASC.CRM/Server/Controllers/CRMApi.Voip.cs | 889 +++++++ products/ASC.CRM/Server/Controllers/CRMApi.cs | 65 + .../ASC.CRM/Server/Controllers/CRMApiBase.cs | 84 + .../Server/Controllers/CRMBootstrap.cs | 58 + .../ASC.CRM/Server/Controllers/CRMCalendar.cs | 122 + .../Server/Controllers/CRMController.Cases.cs | 758 ++++++ .../Controllers/CRMController.ContactInfo.cs | 534 ++++ .../Controllers/CRMController.Contacts.cs | 2333 +++++++++++++++++ .../CRMController.CurrencyRates.cs | 297 +++ .../Controllers/CRMController.CustomFields.cs | 415 +++ .../Server/Controllers/CRMController.Deals.cs | 969 +++++++ .../Controllers/CRMController.Invoices.cs | 1509 +++++++++++ .../Controllers/CRMController.ListItem.cs | 1098 ++++++++ .../CRMController.RelationshipEvent.cs | 846 ++++++ .../Controllers/CRMController.Reports.cs | 157 ++ .../Server/Controllers/CRMController.Tag.cs | 677 +++++ .../Controllers/CRMController.TaskTemplate.cs | 387 +++ .../Server/Controllers/CRMController.Tasks.cs | 699 +++++ .../Server/Controllers/CRMController.Utils.cs | 545 ++++ .../Server/Controllers/CRMController.cs | 138 + .../Controllers/CurrencyRateController.cs | 17 - .../Server/Controllers/TasksController.cs | 12 - .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 51 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 2 +- .../Server/Core/Dao/RelationshipEventDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 2 +- .../Core/Dao/TaskTemplateContainerDao.cs | 13 + .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 7 - .../Server/Core/Search/BundleSearch.cs | 5 +- .../Server/Core/Security/CRMSecutiry.cs | 2 +- products/ASC.CRM/Server/Model/CasesWrapper.cs | 145 + .../Server/Model/ContactInfoWrapper.cs | 200 ++ .../ASC.CRM/Server/Model/ContactWrapper.cs | 491 ++++ .../Server/Model/CurrencyInfoWrapper.cs | 104 + .../Server/Model/CurrencyRateWrapper.cs | 73 + .../Server/Model/CustomFieldWrapper.cs | 122 + .../ASC.CRM/Server/Model/InvoiceWrapper.cs | 423 +++ .../ASC.CRM/Server/Model/ListItemWrapper.cs | 420 +++ .../Server/Model/OpportunityWrapper.cs | 178 ++ .../Server/Model/RelationshipEventWrapper.cs | 154 ++ .../ASC.CRM/Server/Model/ReportWrapper.cs | 48 + products/ASC.CRM/Server/Model/Subject.cs | 37 + .../Model/TaskTemplateContainerWrapper.cs | 118 + products/ASC.CRM/Server/Model/TaskWrapper.cs | 236 ++ .../ASC.CRM/Server/Model/VoipCallWrapper.cs | 95 + products/ASC.CRM/Server/Program.cs | 25 +- .../Server/Properties/launchSettings.json | 10 +- .../Services/NotifyService/NotifyClient.cs | 91 +- products/ASC.CRM/Server/Startup.cs | 56 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 11 +- products/ASC.CRM/Server/Utils/PdfCreator.cs | 2 +- .../Server/appsettings.Development.json | 9 - products/ASC.CRM/Server/appsettings.json | 9 +- 58 files changed, 15670 insertions(+), 148 deletions(-) create mode 100644 products/ASC.CRM/Server/Controllers/CRMApi.Voip.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMApi.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMApiBase.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMBootstrap.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMCalendar.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Cases.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Deals.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Reports.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Tag.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.Utils.cs create mode 100644 products/ASC.CRM/Server/Controllers/CRMController.cs delete mode 100644 products/ASC.CRM/Server/Controllers/CurrencyRateController.cs delete mode 100644 products/ASC.CRM/Server/Controllers/TasksController.cs create mode 100644 products/ASC.CRM/Server/Model/CasesWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/ContactInfoWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/ContactWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/CustomFieldWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/InvoiceWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/ListItemWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/OpportunityWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/ReportWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/Subject.cs create mode 100644 products/ASC.CRM/Server/Model/TaskTemplateContainerWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/TaskWrapper.cs create mode 100644 products/ASC.CRM/Server/Model/VoipCallWrapper.cs delete mode 100644 products/ASC.CRM/Server/appsettings.Development.json diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 2996841ea95..ffe27ac80f6 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -14,12 +14,27 @@ + + + + + + + + + + + + + + + diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 8f47ee25047..8cfa564e1eb 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -57,8 +57,8 @@ public Global(StorageFactory storageFactory, CRMSecurity cRMSecurity, TenantManager tenantManager, SettingsManager settingsManager, - IConfiguration configuration, - PdfCreator pdfCreator + IConfiguration configuration + // PdfCreator pdfCreator ) { StorageFactory = storageFactory; @@ -69,10 +69,10 @@ PdfCreator pdfCreator TenantID = tenantManager.GetCurrentTenant().TenantId; SettingsManager = settingsManager; Configuration = configuration; - PdfCreator = pdfCreator; + // PdfCreator = pdfCreator; } - public PdfCreator PdfCreator { get; } +// public PdfCreator PdfCreator { get; } public IConfiguration Configuration { get; } public SettingsManager SettingsManager { get; } @@ -184,22 +184,22 @@ public void SaveDefaultCurrencySettings(CurrencyInfo currency) SettingsManager.Save(tenantSettings); } - public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) - { - var existingFile = invoice.GetInvoiceFile(factory); - if (existingFile != null) - { - return existingFile; - } - else - { - var newFile = PdfCreator.CreateFile(invoice, factory); - invoice.FileID = Int32.Parse(newFile.ID.ToString()); - factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); - return newFile; - } - } + //public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) + //{ + // var existingFile = invoice.GetInvoiceFile(factory); + // if (existingFile != null) + // { + // return existingFile; + // } + // else + // { + // var newFile = PdfCreator.CreateFile(invoice, factory); + // invoice.FileID = Int32.Parse(newFile.ID.ToString()); + // factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + // factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + // return newFile; + // } + //} //Code snippet diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 3191f939444..91d4b5962a7 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -689,8 +689,8 @@ public static DIHelper AddInvoiceFormattedDataService(this DIHelper services) { services.TryAddScoped(); - return services.AddOrganisationLogoManagerService() - .AddDaoFactoryService(); + return services.AddOrganisationLogoManagerService(); + // .AddDaoFactoryService(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs index 76a3382ba40..4d51ed47965 100644 --- a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -202,9 +202,8 @@ public static DIHelper AddOrganisationLogoManagerService(this DIHelper services) { services.TryAddScoped(); - return services.AddWebImageSupplierService() - .AddGlobalService() - .AddDaoFactoryService(); + return services.AddWebImageSupplierService(); + } } diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index 2ad652a1964..e419fc89b17 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -339,7 +339,7 @@ public void ConfigurePortal() //{ // if (registered) // { - // NotifyClient.Instance.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask); + // NotifyClient.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask); // } //} @@ -352,7 +352,7 @@ public void ConfigurePortal() // { // registered = true; - // NotifyClient.Instance.Client.RegisterSendMethod(NotifyClient.SendAutoReminderAboutTask, "0 * * ? * *"); + // NotifyClient.Client.RegisterSendMethod(NotifyClient.SendAutoReminderAboutTask, "0 * * ? * *"); // } // } diff --git a/products/ASC.CRM/Server/Controllers/CRMApi.Voip.cs b/products/ASC.CRM/Server/Controllers/CRMApi.Voip.cs new file mode 100644 index 00000000000..8a881e14926 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMApi.Voip.cs @@ -0,0 +1,889 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.CRM.Wrappers; +using ASC.Api.Utils; +using ASC.Core.Tenants; +using ASC.CRM.Core; +using ASC.Data.Storage; +using ASC.VoipService; +using ASC.VoipService.Dao; +using ASC.VoipService.Twilio; +using ASC.Web.CRM.Classes; +using ASC.Web.Studio.Utility; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Security; +using SecurityContext = ASC.Core.SecurityContext; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + #region Numbers + + /// + /// + /// + /// + /// Voip + /// + /// + /// + [Read(@"voip/numbers/available")] + public IEnumerable GetAvailablePhoneNumbers(PhoneNumberType numberType, string isoCountryCode) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException(); + return VoipProvider.GetAvailablePhoneNumbers(numberType, isoCountryCode); + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/unlinked")] + public IEnumerable GetUnlinkedPhoneNumbers() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var listPhones = VoipProvider.GetExistingPhoneNumbers(); + var buyedPhones = DaoFactory.VoipDao.GetNumbers(); + + return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList(); + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/existing")] + public IEnumerable GetExistingPhoneNumbers() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + return DaoFactory.VoipDao.GetNumbers(); + } + /// + /// + /// + /// + /// Voip + /// + /// + [Create(@"voip/numbers")] + public VoipPhone BuyNumber(string number) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var newPhone = VoipProvider.BuyNumber(number); + + VoipProvider.CreateQueue(newPhone); + SetDefaultAudio(newPhone); + + VoipProvider.UpdateSettings(newPhone); + return DaoFactory.VoipDao.SaveOrUpdateNumber(newPhone); + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Create(@"voip/numbers/link")] + public VoipPhone LinkNumber(string id) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var newPhone = VoipProvider.GetPhone(id); + + VoipProvider.CreateQueue(newPhone); + SetDefaultAudio(newPhone); + + VoipProvider.UpdateSettings(newPhone); + + return DaoFactory.VoipDao.SaveOrUpdateNumber(newPhone); + } + + public void SetDefaultAudio(VoipPhone newPhone) + { + var storage = StorageFactory.GetStorage("", "crm"); + const string path = "default/"; + var files = storage.ListFilesRelative("voip", path, "*.*", true) + .Select(filePath => new + { + path = CommonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()), + audioType = (AudioType)Enum.Parse(typeof (AudioType), Directory.GetParent(filePath).Name, true) + }).ToList(); + + var audio = files.Find(r => r.audioType == AudioType.Greeting); + newPhone.Settings.GreetingAudio = audio != null ? audio.path : ""; + + audio = files.Find(r => r.audioType == AudioType.HoldUp); + newPhone.Settings.HoldAudio = audio != null ? audio.path : ""; + + audio = files.Find(r => r.audioType == AudioType.VoiceMail); + newPhone.Settings.VoiceMail = audio != null ? audio.path : ""; + + audio = files.Find(r => r.audioType == AudioType.Queue); + newPhone.Settings.Queue.WaitUrl = audio != null ? audio.path : ""; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Delete(@"voip/numbers/{numberId:\w+}")] + public VoipPhone DeleteNumber(string numberId) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.VoipDao; + var phone = dao.GetNumber(numberId).NotFoundIfNull(); + + VoipProvider.DisablePhone(phone); + dao.DeleteNumber(numberId); + new SignalRHelper(phone.Number).Reload(); + + return phone; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/{numberId:\w+}")] + public VoipPhone GetNumber(string numberId) + { + return DaoFactory.VoipDao.GetNumber(numberId).NotFoundIfNull(); + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/numbers/current")] + public VoipPhone GetCurrentNumber() + { + return DaoFactory.VoipDao.GetCurrentNumber().NotFoundIfNull(); + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/token")] + public string GetToken() + { + return VoipProvider.GetToken(GetCurrentNumber().Caller); + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Update(@"voip/numbers/{numberId:\w+}/settings")] + public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.VoipDao; + var number = dao.GetNumber(numberId).NotFoundIfNull(); + + number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias); + number.Settings.GreetingAudio = Update.IfNotEmptyAndNotEquals(number.Settings.GreetingAudio, greeting); + number.Settings.HoldAudio = Update.IfNotEmptyAndNotEquals(number.Settings.HoldAudio, holdUp); + number.Settings.VoiceMail = Update.IfNotEmptyAndNotEquals(number.Settings.VoiceMail, voiceMail); + number.Settings.WorkingHours = Update.IfNotEmptyAndNotEquals(number.Settings.WorkingHours, workingHours); + + if (!string.IsNullOrEmpty(wait)) + { + number.Settings.Queue.WaitUrl = wait; + } + + if (allowOutgoingCalls.HasValue) + { + number.Settings.AllowOutgoingCalls = allowOutgoingCalls.Value; + if (!number.Settings.AllowOutgoingCalls) + { + number.Settings.Operators.ForEach(r => r.AllowOutgoingCalls = false); + } + } + + if (record.HasValue) + { + number.Settings.Record = record.Value; + if (!number.Settings.Record) + { + number.Settings.Operators.ForEach(r => r.Record = false); + } + } + + dao.SaveOrUpdateNumber(number); + + return number; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Update(@"voip/numbers/settings")] + public object UpdateSettings(Queue queue, bool pause) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.VoipDao; + var numbers = dao.GetNumbers(); + + if (queue != null) + { + foreach (var number in numbers) + { + if (number.Settings.Queue == null || string.IsNullOrEmpty(number.Settings.Queue.Id)) + { + var phone = number as TwilioPhone; + if (phone != null) + { + queue = phone.CreateQueue(phone.Number, queue.Size, queue.WaitUrl, queue.WaitTime * 60); + } + + queue.Name = number.Number; + number.Settings.Queue = queue; + } + else + { + var oldQueue = number.Settings.Queue; + oldQueue.Size = Update.IfNotEmptyAndNotEquals(oldQueue.Size, queue.Size); + oldQueue.WaitTime = Update.IfNotEmptyAndNotEquals(oldQueue.WaitTime, queue.WaitTime * 60); + oldQueue.WaitUrl = Update.IfNotEmptyAndNotEquals(oldQueue.WaitUrl, queue.WaitUrl); + } + + number.Settings.Pause = pause; + + dao.SaveOrUpdateNumber(number); + } + } + + return new {queue, pause}; + } + + /// + /// + /// + /// + /// Voip + /// + /// + + [Read(@"voip/numbers/settings")] + public object GetVoipSettings() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.VoipDao; + var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null); + if (number != null) + { + return new {queue = number.Settings.Queue, pause = number.Settings.Pause}; + } + + var files = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true); + var file = files.FirstOrDefault(); + return new { queue = new Queue(null, "Default", 5, file != null ? CommonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false }; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/uploads")] + public IEnumerable GetUploadedFilesUri() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var result = new List(); + + foreach (var audioType in Enum.GetNames(typeof (AudioType))) + { + var type = (AudioType)Enum.Parse(typeof (AudioType), audioType); + + var path = audioType.ToLower(); + var store = Global.GetStore(); + var filePaths = store.ListFilesRelative("voip", path, "*", true); + result.AddRange( + filePaths.Select(filePath => + GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type))); + + path = "default/" + audioType.ToLower(); + store = StorageFactory.GetStorage("", "crm"); + filePaths = store.ListFilesRelative("voip", path, "*.*", true); + result.AddRange( + filePaths.Select(filePath => + GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type, true))); + } + + return result; + } + + private static VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false) + { + return new VoipUpload + { + Path = CommonLinkUtility.GetFullAbsolutePath(link.ToString()), + Name = fileName, + AudioType = audioType, + IsDefault = isDefault + }; + } + + /// + /// + /// + /// + /// Voip + /// + /// + /// + [Delete(@"voip/uploads")] + public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var store = Global.GetStore(); + var path = Path.Combine(audioType.ToString().ToLower(), fileName); + var result = new VoipUpload + { + AudioType = audioType, + Name = fileName, + Path = CommonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString()) + }; + + if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); + store.Delete("voip", path); + + var dao = DaoFactory.VoipDao; + var numbers = dao.GetNumbers(); + + var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); + if (defAudio == null) return result; + + foreach (var number in numbers) + { + switch (audioType) + { + case AudioType.Greeting: + if (number.Settings.GreetingAudio == result.Path) + { + number.Settings.GreetingAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + case AudioType.HoldUp: + if (number.Settings.HoldAudio == result.Path) + { + number.Settings.HoldAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + case AudioType.Queue: + var queue = number.Settings.Queue; + if (queue != null && queue.WaitUrl == result.Path) + { + queue.WaitUrl = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + case AudioType.VoiceMail: + if (number.Settings.VoiceMail == result.Path) + { + number.Settings.VoiceMail = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + } + + dao.SaveOrUpdateNumber(number); + } + + return result; + } + + #endregion + + #region Operators + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/{numberId:\w+}/oper")] + public IEnumerable GetOperators(string numberId) + { + return DaoFactory.VoipDao.GetNumber(numberId).Settings.Operators.Select(r => r.Id); + } + + /// + /// + /// + /// + /// Voip + /// + /// + /// + [Update(@"voip/numbers/{numberId:\w+}/oper")] + public IEnumerable AddOperators(string numberId, IEnumerable operators) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + if (DaoFactory.VoipDao.GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) + { + throw new ArgumentException("Duplicate", "operators"); + } + + var dao = DaoFactory.VoipDao; + var phone = dao.GetNumber(numberId); + var lastOper = phone.Settings.Operators.LastOrDefault(); + var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100; + + var addedOperators = operators.Select(o => new Agent(o, AnswerType.Client, phone, (startOperId++).ToString(CultureInfo.InvariantCulture))).ToList(); + phone.Settings.Operators.AddRange(addedOperators); + + dao.SaveOrUpdateNumber(phone); + return addedOperators; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Delete(@"voip/numbers/{numberId:\w+}/oper")] + public Guid DeleteOperator(string numberId, Guid oper) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.VoipDao; + var phone = dao.GetNumber(numberId); + var startOperId = 100; + + phone.Settings.Operators.RemoveAll(r => r.Id == oper); + phone.Settings.Operators.ToList() + .ForEach(r => + { + r.PhoneNumber = phone.Number; + r.PostFix = startOperId.ToString(CultureInfo.InvariantCulture); + startOperId++; + }); + + dao.SaveOrUpdateNumber(phone); + return oper; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Update(@"voip/opers/{operatorId}")] + public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber) + { + if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.VoipDao; + var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); + + var oper = phone.Settings.Operators.Find(r => r.Id == operatorId); + + if (status.HasValue) + { + oper.Status = status.Value; + } + + if (allowOutgoingCalls.HasValue) + { + oper.AllowOutgoingCalls = phone.Settings.AllowOutgoingCalls && allowOutgoingCalls.Value; + } + + if (record.HasValue) + { + oper.Record = phone.Settings.Record && record.Value; + } + + if (answerType.HasValue) + { + oper.Answer = answerType.Value; + } + + if (!string.IsNullOrEmpty(redirectToNumber)) + { + oper.RedirectToNumber = redirectToNumber; + } + + dao.SaveOrUpdateNumber(phone); + + if (allowOutgoingCalls.HasValue) + { + new SignalRHelper(phone.Number).Reload(operatorId.ToString()); + } + + return oper; + } + + #endregion + + #region Calls + + /// + /// + /// + /// + /// Voip + /// + /// + [Create(@"voip/call")] + public VoipCallWrapper MakeCall(string to, string contactId) + { + var number = DaoFactory.VoipDao.GetCurrentNumber().NotFoundIfNull(); + if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); + + var contactPhone = to.TrimStart('+'); + var contact = string.IsNullOrEmpty(contactId) ? + GetContactsByContactInfo(ContactInfoType.Phone, contactPhone, null, null).FirstOrDefault() : + GetContactByID(Convert.ToInt32(contactId)); + + if (contact == null) + { + contact = ToContactWrapper(new VoipEngine(DaoFactory).CreateContact(contactPhone)); + } + + contact = GetContactWithFotos(contact); + var call = number.Call(to, contact.ID.ToString(CultureInfo.InvariantCulture)); + return new VoipCallWrapper(call, contact); + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:\w+}/answer")] + public VoipCallWrapper AnswerCall(string callId) + { + var dao = DaoFactory.VoipDao; + var call = dao.GetCall(callId).NotFoundIfNull(); + var number = dao.GetCurrentNumber().NotFoundIfNull(); + number.AnswerQueueCall(call.Id); + return new VoipCallWrapper(call); + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:\w+}/reject")] + public VoipCallWrapper RejectCall(string callId) + { + var dao = DaoFactory.VoipDao; + var call = dao.GetCall(callId).NotFoundIfNull(); + var number = dao.GetCurrentNumber().NotFoundIfNull(); + number.RejectQueueCall(call.Id); + return new VoipCallWrapper(call); + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:\w+}/redirect")] + public VoipCallWrapper ReditectCall(string callId, string to) + { + var dao = DaoFactory.VoipDao; + var call = dao.GetCall(callId).NotFoundIfNull(); + var number = dao.GetCurrentNumber().NotFoundIfNull(); + + if (call.ContactId != 0) + { + var contact = DaoFactory.ContactDao.GetByID(call.ContactId); + var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact); + + if (!managers.Contains(Guid.Parse(to))) + { + managers.Add(Guid.Parse(to)); + CRMSecurity.SetAccessTo(contact, managers); + } + } + + number.RedirectCall(call.Id, to); + return new VoipCallWrapper(call); + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:\w+}")] + public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) + { + var dao = DaoFactory.VoipDao; + + var call = dao.GetCall(callId) ?? new VoipCall(); + + call.Id = callId; + call.From = Update.IfNotEmptyAndNotEquals(call.From, from); + call.To = Update.IfNotEmptyAndNotEquals(call.To, to); + call.AnsweredBy = Update.IfNotEmptyAndNotEquals(call.AnsweredBy, answeredBy); + + try + { + if (call.ContactId == 0) + { + var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; + if (!string.IsNullOrEmpty(contactId)) + { + call.ContactId = Convert.ToInt32(contactId); + } + else + { + new VoipEngine(DaoFactory).GetContact(call); + } + + if (call.ContactId == 0) + { + contactPhone = contactPhone.TrimStart('+'); + var person = CreatePerson(contactPhone, TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), null, 0, null, ShareType.None, new List { SecurityContext.CurrentAccount.ID }, null, null); + DaoFactory.ContactInfoDao.Save(new ContactInfo { ContactID = person.ID, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); + call.ContactId = person.ID; + } + } + } + catch (Exception) + { + + } + + if (status.HasValue) + { + call.Status = status.Value; + } + + if (call.Price == 0 && price.HasValue) + { + call.Price = price.Value; + } + + call = dao.SaveOrUpdateCall(call); + + if (call.ContactId == 0) return new VoipCallWrapper(call); + try + { + var contact = GetContactByID(call.ContactId); + contact = GetContactWithFotos(contact); + + return new VoipCallWrapper(call, contact); + } + catch (Exception) + { + return new VoipCallWrapper(call); + } + + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/price/{callId:\w+}")] + public void SavePrice(string callId) + { + new VoipEngine(DaoFactory).SaveAdditionalInfo(callId); + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/call")] + public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) + { + var voipDao = DaoFactory.VoipDao; + + var filter = new VoipCallFilter + { + Type = callType, + FromDate = from != null ? from.UtcTime : (DateTime?)null, + ToDate = to != null ? to.UtcTime.AddDays(1).AddMilliseconds(-1) : (DateTime?)null, + Agent = agent, + Client = client, + ContactID = contactID, + SortBy = _context.SortBy, + SortOrder = !_context.SortDescending, + SearchText = _context.FilterValue, + Offset = _context.StartIndex, + Max = _context.Count, + }; + + _context.SetDataPaginated(); + _context.SetDataFiltered(); + _context.SetDataSorted(); + _context.TotalCount = voipDao.GetCallsCount(filter); + + var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); + var calls = voipDao.GetCalls(filter).Select( + r => + { + ContactWrapper contact; + if (r.ContactId != 0) + { + contact = r.ContactIsCompany + ? (ContactWrapper)new CompanyWrapper(r.ContactId) {DisplayName = r.ContactTitle} + : new PersonWrapper(r.ContactId) {DisplayName = r.ContactTitle}; + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany); + } + else + { + contact = new PersonWrapper(-1) { SmallFotoUrl = defaultSmallPhoto }; + } + return new VoipCallWrapper(r, contact); + }).ToList(); + return calls; + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/call/missed")] + public IEnumerable GetMissedCalls() + { + var voipDao = DaoFactory.VoipDao; + var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); + + var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( + r => + { + ContactWrapper contact; + if (r.ContactId != 0) + { + contact = r.ContactIsCompany + ? (ContactWrapper)new CompanyWrapper(r.ContactId) { DisplayName = r.ContactTitle } + : new PersonWrapper(r.ContactId) { DisplayName = r.ContactTitle }; + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany); + } + else + { + contact = new PersonWrapper(-1) { SmallFotoUrl = defaultSmallPhoto }; + } + return new VoipCallWrapper(r, contact); + }).ToList(); + + _context.SetDataPaginated(); + _context.SetDataFiltered(); + _context.SetDataSorted(); + _context.TotalCount = calls.Count; + + return calls; + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/call/{callId:\w+}")] + public VoipCallWrapper GetCall(string callId) + { + var call = DaoFactory.VoipDao.GetCall(callId); + + new VoipEngine(DaoFactory).GetContact(call); + + if (call.ContactId == 0) return new VoipCallWrapper(call); + + var contact = GetContactByID(call.ContactId); + contact = GetContactWithFotos(contact); + + return new VoipCallWrapper(call, contact); + } + + #endregion + + private static ContactWrapper GetContactWithFotos(ContactWrapper contact) + { + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany); + contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.ID, contact.IsCompany); + + return contact; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMApi.cs b/products/ASC.CRM/Server/Controllers/CRMApi.cs new file mode 100644 index 00000000000..34f1b1daff7 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMApi.cs @@ -0,0 +1,65 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Web; +using ASC.Api.Exceptions; +using ASC.Api.Impl; +using ASC.Api.Interfaces; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; + +namespace ASC.Api.CRM +{ + public partial class CRMApi : CRMApiBase, IApiEntryPoint + { + private readonly ApiContext _context; + + /// + /// Api name entry + /// + public string Name + { + get { return "crm"; } + } + + + /// + /// Constructor + /// + /// + public CRMApi(ApiContext context) + { + _context = context; + } + + private static HttpRequest Request + { + get { return HttpContext.Current.Request; } + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMApiBase.cs b/products/ASC.CRM/Server/Controllers/CRMApiBase.cs new file mode 100644 index 00000000000..a0587367e5c --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMApiBase.cs @@ -0,0 +1,84 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using ASC.Common.Web; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.Files.Core; +using ASC.VoipService; +using ASC.VoipService.Dao; +using ASC.Web.Projects.Core; +using Autofac; +using FilesGlobal = ASC.Web.Files.Classes.Global; + +namespace ASC.Api.CRM +{ + public class CRMApiBase : IDisposable + { + private IDaoFactory filesDaoFactory; + + private readonly ILifetimeScope scope; + private readonly ILifetimeScope crmScope; + + public CRMApiBase() + { + scope = DIHelper.Resolve(); + ProjectsDaoFactory = scope.Resolve(); + + crmScope = Web.CRM.Core.DIHelper.Resolve(); + DaoFactory = crmScope.Resolve(); + } + + protected DaoFactory DaoFactory { get; private set; } + + protected IVoipProvider VoipProvider + { + get { return VoipDao.GetProvider(); } + } + + protected Projects.Core.DataInterfaces.IDaoFactory ProjectsDaoFactory { get; private set; } + + protected IDaoFactory FilesDaoFactory + { + get { return filesDaoFactory ?? (filesDaoFactory = FilesGlobal.DaoFactory); } + } + + public void Dispose() + { + if (scope != null) + { + scope.Dispose(); + } + + if (crmScope != null) + { + crmScope.Dispose(); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMBootstrap.cs b/products/ASC.CRM/Server/Controllers/CRMBootstrap.cs new file mode 100644 index 00000000000..9106fcb5988 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMBootstrap.cs @@ -0,0 +1,58 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.Collections.Generic; +using ASC.Api.Interfaces; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.Web.Core; +using ASC.Web.Core.Calendars; +using ASC.Web.Files.Api; + +namespace ASC.Api.CRM +{ + public class CRMBootstrap : IApiBootstrapper + { + public void Configure() + { + if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) + { + FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider()); + } + + //Register prodjects' calendar events + CalendarManager.Instance.RegistryCalendarProvider(userid => + { + if (WebItemSecurity.IsAvailableForUser(WebItemManager.CRMProductID, userid)) + { + return new List {new CRMCalendar(userid)}; + } + return new List(); + }); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs new file mode 100644 index 00000000000..9db1a314cce --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs @@ -0,0 +1,122 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using ASC.Web.Core.Calendars; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core; +using ASC.Projects.Engine; +using ASC.Web.Core; +using ASC.Web.CRM.Core; +using Autofac; +using ASC.CRM.Resources; +using ASC.CRM.Core.Enums; +using ASC.Core.Tenants; + +namespace ASC.Api.CRM +{ + public sealed class CRMCalendar : BaseCalendar + { + [AllDayLongUTCAttribute] + private class Event : BaseEvent + { + } + + + public CRMCalendar(Guid userId) + { + Context.HtmlBackgroundColor = ""; + Context.HtmlTextColor = ""; + Context.CanChangeAlertType = false; + Context.CanChangeTimeZone = false; + Context.GetGroupMethod = () => CRMCommonResource.ProductName; + Id = "crm_calendar"; + EventAlertType = EventAlertType.Never; + Name = CRMCommonResource.ProductName; + Description = ""; + SharingOptions = new SharingOptions(); + SharingOptions.PublicItems.Add(new SharingOptions.PublicItem {Id = userId, IsGroup = false}); + } + + public override List LoadEvents(Guid userId, DateTime startDate, DateTime endDate) + { + using (var scope = DIHelper.Resolve()) + { + var _daoFactory = scope.Resolve(); + var events = new List(); + + if ( + !WebItemSecurity.IsAvailableForMe(WebItemManager.CRMProductID)) + { + return events; + } + + var tasks = _daoFactory.GetTaskDao().GetTasks(String.Empty, userId, 0, false, DateTime.MinValue, + DateTime.MinValue, EntityType.Any, 0, 0, 0, null); + + foreach (var t in tasks) + { + if (t.DeadLine == DateTime.MinValue) continue; + + var allDayEvent = t.DeadLine.Hour == 0 && t.DeadLine.Minute == 0; + var utcDate = allDayEvent ? t.DeadLine.Date : TenantUtil.DateTimeToUtc(t.DeadLine); + + var e = new Event + { + AlertType = EventAlertType.Never, + AllDayLong = allDayEvent, + CalendarId = Id, + UtcStartDate = utcDate, + UtcEndDate = utcDate, + Id = "crm_task_" + t.ID.ToString(CultureInfo.InvariantCulture), + Name = Web.CRM.Resources.CRMCommonResource.ProductName + ": " + t.Title, + Description = t.Description + }; + + if (IsVisibleEvent(startDate, endDate, e.UtcStartDate, e.UtcEndDate)) + events.Add(e); + } + + return events; + } + } + + public override TimeZoneInfo TimeZone + { + get { return TenantManager.GetCurrentTenant().TimeZone; } + } + + private bool IsVisibleEvent(DateTime startDate, DateTime endDate, DateTime eventStartDate, DateTime eventEndDate) + { + return (startDate <= eventStartDate && eventStartDate <= endDate) || + (startDate <= eventEndDate && eventEndDate <= endDate) || + (eventStartDate < startDate && eventEndDate > endDate); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs new file mode 100644 index 00000000000..de8d9ed8397 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs @@ -0,0 +1,758 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Collections; +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.Files.Services.WCFService; +using System; +using System.Collections.Generic; +using System.Linq; +using EnumExtension = ASC.Web.CRM.Classes.EnumExtension; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Close the case with the ID specified in the request + /// + /// Close case + /// Cases + /// Case ID + /// + /// + /// + /// Case + /// + [Update(@"case/{caseid:int}/close")] + public CasesWrapper CloseCases(int caseid) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().CloseCases(caseid); + if (cases == null) throw new ItemNotFoundException(); + + MessageService.Send( MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); + + return ToCasesWrapper(cases); + } + + /// + /// Resume the case with the ID specified in the request + /// + /// Resume case + /// Cases + /// Case ID + /// + /// + /// + /// Case + /// + [Update(@"case/{caseid:int}/reopen")] + public CasesWrapper ReOpenCases(int caseid) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid); + if (cases == null) throw new ItemNotFoundException(); + + MessageService.Send( MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); + + return ToCasesWrapper(cases); + } + + /// + /// Creates the case with the parameters specified in the request + /// + /// Create case + /// Case title + /// Participants + /// User field list + /// Case privacy: private or not + /// List of users with access to the case + /// Notify users in accessList about the case + /// Case + /// Cases + /// + /// + /// + /// + [Create(@"case")] + public CasesWrapper CreateCases( + string title, + IEnumerable members, + IEnumerable> customFieldList, + bool isPrivate, + IEnumerable accessList, + bool isNotify) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var casesID = DaoFactory.GetCasesDao().CreateCases(title); + + var cases = new Cases + { + ID = casesID, + Title = title, + CreateBy = SecurityContext.CurrentAccount.ID, + CreateOn = DateTime.UtcNow + }; + FactoryIndexer.IndexAsync(cases); + SetAccessToCases(cases, isPrivate, accessList, isNotify, false); + + var membersList = members != null ? members.ToList() : new List(); + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); + } + } + + return ToCasesWrapper(DaoFactory.GetCasesDao().GetByID(casesID)); + } + + /// + /// Updates the selected case with the parameters specified in the request + /// + /// Update case + /// Case ID + /// Case title + /// Participants + /// User field list + /// Case privacy: private or not + /// List of users with access to the case + /// Notify users in accessList about the case + /// Cases + /// Case + /// + /// + /// + /// + /// + [Update(@"case/{caseid:int}")] + public CasesWrapper UpdateCases( + int caseid, + string title, + IEnumerable members, + IEnumerable> customFieldList, + bool isPrivate, + IEnumerable accessList, + bool isNotify) + { + if ((caseid <= 0) || (string.IsNullOrEmpty(title))) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null) throw new ItemNotFoundException(); + + cases.Title = title; + + DaoFactory.GetCasesDao().UpdateCases(cases); + + if (CRMSecurity.IsAdmin || cases.CreateBy == Core.SecurityContext.CurrentAccount.ID) + { + SetAccessToCases(cases, isPrivate, accessList, isNotify, false); + } + + var membersList = members != null ? members.ToList() : new List(); + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); + } + } + + return ToCasesWrapper(cases); + } + + /// + /// Sets access rights for the selected case with the parameters specified in the request + /// + /// Case ID + /// Case privacy: private or not + /// List of users with access to the case + /// Set rights to case + /// Cases + /// + /// + /// + /// Case + /// + [Update(@"case/{caseid:int}/access")] + public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || cases.CreateBy == Core.SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + + return SetAccessToCases(cases, isPrivate, accessList, false, true); + } + + private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) + { + var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); + if (isPrivate && accessListLocal.Any()) + { + if (isNotify) + { + accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); + NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, DaoFactory, accessListLocal.ToArray()); + } + + if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) + { + accessListLocal.Add(SecurityContext.CurrentAccount.ID); + } + + CRMSecurity.SetAccessTo(cases, accessListLocal); + if (isMessageServicSende) + { + var users = GetUsersByIdList(accessListLocal); + MessageService.Send( MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false))); + } + } + else + { + CRMSecurity.MakePublic(cases); + if (isMessageServicSende) + { + MessageService.Send( MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title); + } + } + + return ToCasesWrapper(cases); + } + + /// + /// Sets access rights for other users to the list of cases with the IDs specified in the request + /// + /// Case ID list + /// Case privacy: private or not + /// List of users with access + /// Set case access rights + /// Cases + /// + /// + /// + /// Case list + /// + [Update(@"case/access")] + public IEnumerable SetAccessToBatchCases(IEnumerable casesid, bool isPrivate, IEnumerable accessList) + { + var result = new List(); + + var cases = DaoFactory.GetCasesDao().GetCases(casesid); + + if (!cases.Any()) return new List(); + + foreach (var c in cases) + { + if (c == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || c.CreateBy == Core.SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToCases(c, isPrivate, accessList, false, true); + result.Add(c); + } + + return ToListCasesWrappers(result); + } + + /// + /// Sets access rights for other users to the list of all cases matching the parameters specified in the request + /// + /// Contact ID + /// Case status + /// Tags + /// Case privacy: private or not + /// List of users with access + /// Set case access rights + /// Cases + /// + /// + /// + /// Case list + /// + [Update(@"case/filter/access")] + public IEnumerable SetAccessToBatchCases( + int contactid, + bool? isClosed, + IEnumerable tags, + bool isPrivate, + IEnumerable accessList + ) + { + var result = new List(); + + var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + + if (!caseses.Any()) return new List(); + + foreach (var casese in caseses) + { + if (casese == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || casese.CreateBy == Core.SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToCases(casese, isPrivate, accessList, false, true); + result.Add(casese); + } + + return ToListCasesWrappers(result); + } + + /// + /// Returns the detailed information about the case with the ID specified in the request + /// + /// Get case by ID + /// Cases + /// Case ID + /// + /// + [Read(@"case/{caseid:int}")] + public CasesWrapper GetCaseByID(int caseid) + { + if (caseid <= 0) throw new ItemNotFoundException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + + return ToCasesWrapper(cases); + } + + /// + /// Returns the list of all cases matching the parameters specified in the request + /// + /// Get case list + /// Contact ID + /// Case status + /// Tags + /// Cases + /// + /// Case list + /// + [Read(@"case/filter")] + public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable tags) + { + IEnumerable result; + SortedByType sortBy; + OrderBy casesOrderBy; + + var searchString = ApiContext.FilterValue; + + if (EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + { + casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (string.IsNullOrEmpty(ApiContext.SortBy)) + { + casesOrderBy = new OrderBy(SortedByType.Title, true); + } + else + { + casesOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (casesOrderBy != null) + { + result = ToListCasesWrappers( + DaoFactory + .GetCasesDao() + .GetCases( + searchString, + contactid, + isClosed, + tags, + fromIndex, + count, + casesOrderBy)).ToList(); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListCasesWrappers( + DaoFactory + .GetCasesDao() + .GetCases( + searchString, contactid, isClosed, + tags, + 0, + 0, + null)).ToList(); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); + } + + ApiContext.SetTotalCount(totalCount); + return result.ToSmartList(); + } + + /// + /// Deletes the case with the ID specified in the request + /// + /// Delete case + /// Case ID + /// Cases + /// + /// + /// + /// Case + /// + [Delete(@"case/{caseid:int}")] + public CasesWrapper DeleteCase(int caseid) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().DeleteCases(caseid); + if (cases == null) throw new ItemNotFoundException(); + + FactoryIndexer.DeleteAsync(cases); + + MessageService.Send( MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); + + return ToCasesWrapper(cases); + } + + /// + /// Deletes the group of cases with the IDs specified in the request + /// + /// Case ID list + /// + /// + /// Delete case group + /// Cases + /// + /// Case list + /// + [Update(@"case")] + public IEnumerable DeleteBatchCases(IEnumerable casesids) + { + if (casesids == null) throw new ArgumentException(); + + casesids = casesids.Distinct(); + var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); + + if (caseses == null || !caseses.Any()) return new List(); + + MessageService.Send( MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); + + return ToListCasesWrappers(caseses); + } + + /// + /// Deletes the list of all cases matching the parameters specified in the request + /// + /// Contact ID + /// Case status + /// Tags + /// + /// + /// Delete case group + /// Cases + /// + /// Case list + /// + [Delete(@"case/filter")] + public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) + { + var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + if (!caseses.Any()) return new List(); + + caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); + + MessageService.Send( MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); + + return ToListCasesWrappers(caseses); + } + + /// + /// Returns the list of all contacts associated with the case with the ID specified in the request + /// + /// Get all case contacts + /// Case ID + /// Cases + /// Contact list + /// + [Read(@"case/{caseid:int}/contact")] + public IEnumerable GetCasesMembers(int caseid) + { + var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); + return contactIDs == null + ? new ItemList() + : ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)); + } + + /// + /// Adds the selected contact to the case with the ID specified in the request + /// + /// Add case contact + /// Cases + /// Case ID + /// Contact ID + /// + /// + /// + /// Participant + /// + [Create(@"case/{caseid:int}/contact")] + public ContactWrapper AddMemberToCases(int caseid, int contactid) + { + if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + DaoFactory.GetCasesDao().AddMember(caseid, contactid); + + var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; + MessageService.Send( messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + + return ToContactWrapper(contact); + } + + /// + /// Delete the selected contact from the case with the ID specified in the request + /// + /// Delete case contact + /// Cases + /// Case ID + /// Contact ID + /// + /// + /// + /// Participant + /// + [Delete(@"case/{caseid:int}/contact/{contactid:int}")] + public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) + { + if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var result = ToContactWrapper(contact); + + DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); + + var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; + MessageService.Send( messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + + return result; + } + + /// + /// Returns the list of 30 cases in the CRM module with prefix + /// + /// + /// + /// Cases + /// + /// Cases list + /// + /// false + [Read(@"case/byprefix")] + public IEnumerable GetCasesByPrefix(string prefix, int contactID) + { + var result = new List(); + + if (contactID > 0) + { + var findedCases = DaoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null); + + foreach (var item in findedCases) + { + if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) + { + result.Add(ToCasesWrapper(item)); + } + } + + ApiContext.SetTotalCount(findedCases.Count); + } + else + { + const int maxItemCount = 30; + var findedCases = DaoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount); + + foreach (var item in findedCases) + { + result.Add(ToCasesWrapper(item)); + } + } + + return result; + } + + private IEnumerable ToListCasesWrappers(ICollection items) + { + if (items == null || items.Count == 0) return new List(); + + var result = new List(); + + var contactIDs = new List(); + var casesIDs = items.Select(item => item.ID).ToArray(); + + var customFields = DaoFactory.GetCustomFieldDao() + .GetEnityFields(EntityType.Case, casesIDs) + .GroupBy(item => item.EntityID) + .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + + var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); + + foreach (var value in casesMembers.Values) + { + contactIDs.AddRange(value); + } + + var contacts = DaoFactory + .ContactDao + .GetContacts(contactIDs.Distinct().ToArray()) + .ToDictionary(item => item.ID, ToContactBaseWrapper); + + foreach (var cases in items) + { + var casesWrapper = new CasesWrapper(cases) + { + CustomFields = customFields.ContainsKey(cases.ID) + ? customFields[cases.ID] + : new List(), + Members = casesMembers.ContainsKey(cases.ID) + ? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) + : new List() + }; + + result.Add(casesWrapper); + } + + return result; + } + + private CasesWrapper ToCasesWrapper(Cases cases) + { + var casesWrapper = new CasesWrapper(cases) + { + CustomFields = DaoFactory + .CustomFieldDao + .GetEnityFields(EntityType.Case, cases.ID, false) + .ConvertAll(item => new CustomFieldBaseWrapper(item)) + .ToSmartList(), + Members = new List() + }; + + var memberIDs = DaoFactory.GetCasesDao().GetMembers(cases.ID); + var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); + + var membersWrapperList = new List(); + + foreach (var member in membersList) + { + if (member == null) continue; + membersWrapperList.Add(ToContactBaseWrapper(member)); + } + + casesWrapper.Members = membersWrapperList; + return casesWrapper; + } + + private IEnumerable GetUsersByIdList(IEnumerable ids) + { + return UserManager.GetUsers().Where(x => ids.Contains(x.ID)); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs new file mode 100644 index 00000000000..f65209ff29a --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs @@ -0,0 +1,534 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Core.Search; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the list of all available contact categories + /// + /// + /// Contact information type + /// + /// Get all categories + /// Contacts + /// + /// List of all available contact categories + /// + [Read(@"contact/data/{infoType}/category")] + public IEnumerable GetContactInfoCategory(ContactInfoType infoType) + { + return Enum.GetNames(ContactInfo.GetCategory(infoType)).ToItemList(); + } + + /// + /// Returns the list of all available contact information types + /// + /// Get all contact info types + /// Contacts + /// + [Read(@"contact/data/infoType")] + public IEnumerable GetContactInfoType() + { + return Enum.GetNames(typeof(ContactInfoType)).ToItemList(); + } + + /// + /// Returns the detailed information for the contact + /// + /// Contact ID + /// Get contact information + /// Contacts + /// + /// Contact information + /// + [Read(@"contact/{contactid:int}/data")] + public IEnumerable GetContactInfo(int contactid) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + return DaoFactory.GetContactInfoDao().GetList(contactid, null, null, null) + .OrderByDescending(info => info.ID) + .ToList() + .ConvertAll(ToContactInfoWrapper); + } + + /// + /// Returns the detailed list of all information available for the contact with the ID specified in the request + /// + /// Contact ID + /// Contact information ID + /// Get contact info + /// Contacts + /// Contact information + /// + [Read(@"contact/{contactid:int}/data/{id:int}")] + public ContactInfoWrapper GetContactInfoByID(int contactid, int id) + { + if (contactid <= 0 || id <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + + if (contactInfo == null || contactInfo.ContactID != contactid) throw new ArgumentException(); + + return ToContactInfoWrapper(contactInfo); + } + + /// + /// Adds the information with the parameters specified in the request to the contact with the selected ID + /// + ///Contact ID + ///Contact information type + ///Data + ///Contact importance: primary or not + ///Category + /// Add contact info + ///Contacts + /// + /// + /// + /// Contact information + /// + /// + [Create(@"contact/{contactid:int}/data")] + public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoType, string data, bool isPrimary, string category) + { + if (string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null) throw new ItemNotFoundException(); + + if (infoType == ContactInfoType.Twitter) + { + if (!CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + } + else + { + if (!CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + } + + var categoryType = ContactInfo.GetCategory(infoType); + if (!Enum.IsDefined(categoryType, category)) throw new ArgumentException(); + + + var contactInfo = new ContactInfo + { + Data = data, + InfoType = infoType, + ContactID = contactid, + IsPrimary = isPrimary, + Category = (int)Enum.Parse(categoryType, category) + }; + + if (contactInfo.InfoType == ContactInfoType.Address) + { + Address res; + if (!Address.TryParse(contactInfo, out res)) + throw new ArgumentException(); + } + + var contactInfoID = DaoFactory.GetContactInfoDao().Save(contactInfo); + + var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + var contactInfoWrapper = ToContactInfoWrapper(contactInfo); + contactInfoWrapper.ID = contactInfoID; + return contactInfoWrapper; + } + + /// + /// Adds the address information to the contact with the selected ID + /// + /// Contact ID + /// Address data + /// Add address info + /// Contacts + /// + /// + /// + /// Contact information + /// + /// + /// + [Create(@"contact/{contactid:int}/addressdata")] + public ContactInfoWrapper CreateContactInfoAddress(int contactid, Address address) + { + if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid"); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + + if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + + if (address == null) throw new ArgumentException("Value cannot be null", "address"); + + if (!Enum.IsDefined(typeof(AddressCategory), address.Category)) throw new ArgumentException("Value does not fall within the expected range.", "address.Category"); + + address.CategoryName = ((AddressCategory)address.Category).ToLocalizedString(); + + var settings = new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { + NamingStrategy = new CamelCaseNamingStrategy() + }, + Formatting = Formatting.Indented + }; + + var contactInfo = new ContactInfo + { + InfoType = ContactInfoType.Address, + ContactID = contactid, + IsPrimary = address.IsPrimary, + Category = address.Category, + Data = JsonConvert.SerializeObject(address, settings) + }; + + contactInfo.ID = DaoFactory.GetContactInfoDao().Save(contactInfo); + + var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + return ToContactInfoWrapper(contactInfo); + } + + /// + /// Creates contact information (add new information to the old list) with the parameters specified in the request for the contact with the selected ID + /// + ///Group contact info + /// Contact ID + /// Contact information + /// + /// + /// + /// Contacts + /// + /// + /// Contact information + /// + /// false + [Create(@"contact/{contactid:int}/batch")] + public IEnumerable CreateBatchContactInfo(int contactid, IEnumerable items) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + + var itemsList = items != null ? items.ToList() : new List(); + var contactInfoList = itemsList.Select(FromContactInfoWrapper).ToList(); + + foreach (var contactInfo in contactInfoList) + { + if (contactInfo.InfoType == ContactInfoType.Address) + { + Address res; + if(!Address.TryParse(contactInfo, out res)) + throw new ArgumentException(); + } + contactInfo.ContactID = contactid; + } + + var ids = DaoFactory.GetContactInfoDao().SaveList(contactInfoList, contact); + + for (var index = 0; index < itemsList.Count; index++) + { + var infoWrapper = itemsList[index]; + infoWrapper.ID = ids[index]; + } + return itemsList; + } + + /// + /// Updates the information with the parameters specified in the request for the contact with the selected ID + /// + ///Contact information record ID + ///Contact ID + ///Contact information type + ///Data + ///Contact importance: primary or not + ///Contact information category + ///Update contact info + ///Contacts + /// + /// + /// Contact information + /// + [Update(@"contact/{contactid:int}/data/{id:int}")] + public ContactInfoWrapper UpdateContactInfo(int id, int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category) + { + if (id <= 0 || string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + + var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + + if (infoType != null) + { + var categoryType = ContactInfo.GetCategory(infoType.Value); + + if (!string.IsNullOrEmpty(category) && Enum.IsDefined(categoryType, category)) + { + contactInfo.Category = (int)Enum.Parse(categoryType, category); + } + + contactInfo.InfoType = infoType.Value; + } + + contactInfo.ContactID = contactid; + + if (isPrimary != null) + { + contactInfo.IsPrimary = isPrimary.Value; + } + + contactInfo.Data = data; + + if (contactInfo.InfoType == ContactInfoType.Address) + { + Address res; + if (!Address.TryParse(contactInfo, out res)) + throw new ArgumentException(); + } + + DaoFactory.GetContactInfoDao().Update(contactInfo); + + var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + var contactInfoWrapper = ToContactInfoWrapper(contactInfo); + return contactInfoWrapper; + } + + /// + /// Updates the address information with the parameters specified in the request for the contact with the selected ID + /// + /// Contact information record ID + /// Contact ID + /// Address data + /// Update address info + /// Contacts + /// + /// + /// + /// Contact information + /// + [Update(@"contact/{contactid:int}/addressdata/{id:int}")] + public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Address address) + { + if (id <= 0) throw new ArgumentException("Invalid value", "id"); + + var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + + if (contactInfo == null || contactInfo.InfoType != ContactInfoType.Address) throw new ItemNotFoundException(); + + if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid"); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + + if (contact == null || !CRMSecurity.CanEdit(contact) || contactInfo.ContactID != contactid) throw new ItemNotFoundException(); + + if (address == null) throw new ArgumentException("Value cannot be null", "address"); + + if (!Enum.IsDefined(typeof(AddressCategory), address.Category)) throw new ArgumentException("Value does not fall within the expected range.", "address.Category"); + + address.CategoryName = ((AddressCategory) address.Category).ToLocalizedString(); + + var settings = new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { + NamingStrategy = new CamelCaseNamingStrategy() + }, + Formatting = Formatting.Indented + }; + + contactInfo.IsPrimary = address.IsPrimary; + contactInfo.Category = address.Category; + contactInfo.Data = JsonConvert.SerializeObject(address, settings); + + DaoFactory.GetContactInfoDao().Update(contactInfo); + + var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + return ToContactInfoWrapper(contactInfo); + } + + /// + /// Updates contact information (delete old information and add new list) with the parameters specified in the request for the contact with the selected ID + /// + ///Group contact info update + ///Contact ID + ///Contact information + /// + ///Contacts + /// + /// + /// Contact information + /// + /// false + [Update(@"contact/{contactid:int}/batch")] + public IEnumerable UpdateBatchContactInfo(int contactid, IEnumerable items) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + + var itemsList = items != null ? items.ToList() : new List(); + var contactInfoList = itemsList.Select(FromContactInfoWrapper).ToList(); + + foreach (var contactInfo in contactInfoList) + { + if (contactInfo.InfoType == ContactInfoType.Address) + { + Address res; + if (!Address.TryParse(contactInfo, out res)) + throw new ArgumentException(); + } + contactInfo.ContactID = contactid; + } + + DaoFactory.GetContactInfoDao().DeleteByContact(contactid); + var ids = DaoFactory.GetContactInfoDao().SaveList(contactInfoList, contact); + + for (var index = 0; index < itemsList.Count; index++) + { + var infoWrapper = itemsList[index]; + infoWrapper.ID = ids[index]; + } + return itemsList; + } + + /// + /// Returns the detailed information for the contact with the selected ID by the information type specified in the request + /// + /// Contact ID + /// Contact information type + /// Get contact information by type + /// Contacts + /// + /// Contact information + /// + [Read(@"contact/{contactid:int}/data/{infoType}")] + public IEnumerable GetContactInfo(int contactid, ContactInfoType infoType) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + return DaoFactory.GetContactInfoDao().GetListData(contactid, infoType); + } + + + /// + /// Deletes the contact information for the contact with the ID specified in the request + /// + /// Contact ID + /// Contact information record ID + /// Delete contact info + /// Contacts + /// + /// + /// + /// Contact information + /// + [Delete(@"contact/{contactid:int}/data/{id:int}")] + public ContactInfoWrapper DeleteContactInfo(int contactid, int id) + { + if (id <= 0 || contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + + var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + if (contactInfo == null) throw new ItemNotFoundException(); + + var wrapper = ToContactInfoWrapper(contactInfo); + + DaoFactory.GetContactInfoDao().Delete(id); + + var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + if (contactInfo.InfoType == ContactInfoType.Email) + { + FactoryIndexer.DeleteAsync(EmailWrapper.ToEmailWrapper(contact, new List { contactInfo})); + } + FactoryIndexer.DeleteAsync(contactInfo); + + return wrapper; + } + + + private static ContactInfoWrapper ToContactInfoWrapper(ContactInfo contactInfo) + { + return new ContactInfoWrapper(contactInfo); + } + + private static ContactInfo FromContactInfoWrapper(ContactInfoWrapper contactInfoWrapper) + { + return new ContactInfo + { + ID = contactInfoWrapper.ID, + Category = contactInfoWrapper.Category, + Data = contactInfoWrapper.Data, + InfoType = contactInfoWrapper.InfoType, + IsPrimary = contactInfoWrapper.IsPrimary + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs new file mode 100644 index 00000000000..654b0d63d2c --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs @@ -0,0 +1,2333 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Collections; +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Common.Threading.Progress; +using ASC.Common.Web; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.Studio.Core; +using Autofac; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; +using System.Web; +using Contact = ASC.CRM.Core.Entities.Contact; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the detailed information about the contact with the ID specified in the request + /// + /// Contact ID + /// Contact + /// Get contact by ID + /// Contacts + /// + /// + [Read(@"contact/{contactid:int")] + public ContactWrapper GetContactByID(int contactid) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + return ToContactWrapper(contact); + } + + public IEnumerable GetContactsByID(IEnumerable contactid) + { + var contacts = DaoFactory.GetContactDao().GetContacts(contactid.ToArray()).Where(r => r != null && CRMSecurity.CanAccessTo(r)); + return ToListContactWrapper(contacts.ToList()); + } + + /// + /// Returns the contact list for the project with the ID specified in the request + /// + /// + /// Get contacts by project ID + /// + /// Project ID + /// Contacts + /// + /// Contact list + /// + /// + [Read(@"contact/project/{projectid:int}")] + public IEnumerable GetContactsByProjectID(int projectid) + { + if (projectid <= 0) throw new ArgumentException(); + + var contacts = DaoFactory.GetContactDao().GetContactsByProjectID(projectid); + return ToListContactWrapper(contacts.ToList()); + } + + /// + /// Links the selected contact to the project with the ID specified in the request + /// + /// Contact ID + /// Project ID + /// Contacts + /// Link contact with project + /// + /// + /// Contact Info + [Create(@"contact/{contactid:int}/project/{projectid:int}")] + public ContactWrapper SetRelativeContactToProject(int contactid, int projectid) + { + if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); + if (project == null) throw new ItemNotFoundException(); + + using (var scope = DIHelper.Resolve()) + { + if (!scope.Resolve().CanLinkContact(project)) throw CRMSecurity.CreateSecurityException(); + } + + DaoFactory.GetContactDao().SetRelativeContactProject(new List {contactid}, projectid); + + var messageAction = contact is Company ? MessageAction.ProjectLinkedCompany : MessageAction.ProjectLinkedPerson; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); + + return ToContactWrapper(contact); + } + + /// + /// Links the selected contacts to the project with the ID specified in the request + /// + /// Contact IDs array + /// Project ID + /// Contacts + /// Link contact list with project + /// + /// + /// + /// Contact list + /// + [Create(@"contact/project/{projectid:int}")] + public IEnumerable SetRelativeContactListToProject(IEnumerable contactid, int projectid) + { + if (contactid == null) throw new ArgumentException(); + + var contactIds = contactid.ToList(); + + if (!contactIds.Any() || projectid <= 0) throw new ArgumentException(); + + var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); + if (project == null) throw new ItemNotFoundException(); + + using (var scope = DIHelper.Resolve()) + { + if (!scope.Resolve().CanLinkContact(project)) + throw CRMSecurity.CreateSecurityException(); + } + + + var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + contactIds = contacts.Select(c => c.ID).ToList(); + + DaoFactory.GetContactDao().SetRelativeContactProject(contactIds, projectid); + + MessageService.Send( MessageAction.ProjectLinkedContacts, MessageTarget.Create(contactIds), project.Title, contacts.Select(x => x.GetTitle())); + + return contacts.ConvertAll(ToContactWrapper); + } + + /// + /// Removes the link with the selected project from the contact with the ID specified in the request + /// + /// Contact ID + /// Project ID + /// Contacts + /// Remove contact from project + /// + /// Contact info + /// + [Delete(@"contact/{contactid:int}/project/{projectid:int}")] + public ContactBaseWrapper RemoveRelativeContactToProject(int contactid, int projectid) + { + if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); + + using (var scope = DIHelper.Resolve()) + { + if (project == null || !scope.Resolve().CanLinkContact(project)) throw new ItemNotFoundException(); + } + + DaoFactory.GetContactDao().RemoveRelativeContactProject(contactid, projectid); + + var action = contact is Company ? MessageAction.ProjectUnlinkedCompany : MessageAction.ProjectUnlinkedPerson; + MessageService.Send( action, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); + + return ToContactBaseWrapper(contact); + } + + /// + /// Adds the selected opportunity to the contact with the ID specified in the request. The same as AddMemberToDeal + /// + /// Opportunity ID + /// Contact ID + /// Add contact opportunity + /// Contacts + /// + /// + /// Opportunity + /// + [Create(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] + public OpportunityWrapper AddDealToContact(int contactid, int opportunityid) + { + if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + DaoFactory.GetDealDao().AddMember(opportunityid, contactid); + + var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), opportunity.Title, contact.GetTitle()); + + return ToOpportunityWrapper(opportunity); + } + + /// + /// Deletes the selected opportunity from the contact with the ID specified in the request + /// + /// Opportunity ID + /// Contact ID + /// Delete contact opportunity + /// Contacts + /// + /// + /// Opportunity + /// + [Delete(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] + public OpportunityWrapper DeleteDealFromContact(int contactid, int opportunityid) + { + if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); + + return ToOpportunityWrapper(opportunity); + } + + /// + /// Returns the list of all contacts in the CRM module matching the parameters specified in the request + /// + /// Tag + /// Contact stage ID (warmth) + /// Contact type ID + /// + /// Start date + /// End date + /// Responsible ID + /// Responsible ID + /// Get contact list + /// Contacts + /// + /// Contact list + /// + [Read(@"contact/filter")] + public IEnumerable GetContacts( + IEnumerable tags, + int? contactStage, + int? contactType, + ContactListViewType contactListView, + Guid? responsibleid, + bool? isShared, + ApiDateTime fromDate, + ApiDateTime toDate) + { + IEnumerable result; + + OrderBy contactsOrderBy; + + ContactSortedByType sortBy; + + var searchString = ApiContext.FilterValue; + + if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + { + contactsOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (String.IsNullOrEmpty(ApiContext.SortBy)) + { + contactsOrderBy = new OrderBy(ContactSortedByType.Created, false); + } + else + { + contactsOrderBy = null; + } + + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + var contactStageInt = contactStage.HasValue ? contactStage.Value : -1; + var contactTypeInt = contactType.HasValue ? contactType.Value : -1; + + if (contactsOrderBy != null) + { + result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts( + searchString, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, + toDate, + fromIndex, + count, + contactsOrderBy, + responsibleid, + isShared)); + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts( + searchString, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, + toDate, + 0, + 0, + null, + responsibleid, + isShared)); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetContactDao().GetContactsCount( + searchString, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, + toDate, + responsibleid, + isShared); + } + + ApiContext.SetTotalCount(totalCount); + + return result; + } + + /// + /// Returns the list of the contacts for auto complete feature. + /// + /// String part of contact name, lastname or email. + /// Max result count + /// Search contact list + /// Contacts + /// + /// Contact list + /// + /// false + [Read(@"contact/simple/byEmail")] + public IEnumerable SearchContactsByEmail(string term, int maxCount) + { + var result = ToSimpleListContactWrapper(DaoFactory.GetContactDao().SearchContactsByEmail( + term, + maxCount)); + + return result; + } + + /// + /// Returns the list of all contacts in the CRM module matching the parameters specified in the request + /// + /// Tag + /// Contact stage ID (warmth) + /// Contact type ID + /// + /// Responsible ID + /// Responsible ID + /// Start date + /// End date + /// Get contact list + /// Contacts + /// + /// Contact list + /// + /// false + [Read(@"contact/simple/filter")] + public IEnumerable GetSimpleContacts( + IEnumerable tags, + int? contactStage, + int? contactType, + ContactListViewType contactListView, + Guid? responsibleid, + bool? isShared, + ApiDateTime fromDate, + ApiDateTime toDate) + { + IEnumerable result; + + OrderBy contactsOrderBy; + + ContactSortedByType sortBy; + + var searchString = ApiContext.FilterValue; + if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + { + contactsOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (String.IsNullOrEmpty(ApiContext.SortBy)) + { + contactsOrderBy = new OrderBy(ContactSortedByType.DisplayName, true); + } + else + { + contactsOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + var contactStageInt = contactStage.HasValue ? contactStage.Value : -1; + var contactTypeInt = contactType.HasValue ? contactType.Value : -1; + + if (contactsOrderBy != null) + { + result = ToSimpleListContactWrapper(DaoFactory.GetContactDao().GetContacts( + searchString, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, + toDate, + fromIndex, + count, + contactsOrderBy, + responsibleid, + isShared)); + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToSimpleListContactWrapper(DaoFactory.GetContactDao().GetContacts( + searchString, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, + toDate, + 0, + 0, + null, + responsibleid, + isShared)); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetContactDao().GetContactsCount( + searchString, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, + toDate, + responsibleid, + isShared); + } + + ApiContext.SetTotalCount(totalCount); + + return result; + } + + /// + /// Get the group of contacts with the IDs specified in the request + /// + /// Contact ID list + /// + /// + /// Get contact group + /// Contacts + /// + /// Contact list + /// + /// false + [Read(@"contact/mail")] + public IEnumerable GetContactsForMail(IEnumerable contactids) + { + if (contactids == null) throw new ArgumentException(); + + var contacts = DaoFactory.GetContactDao().GetContacts(contactids.ToArray()); + + var result = contacts.Select(ToContactBaseWithEmailWrapper); + return result; + } + + /// + /// Deletes the list of all contacts in the CRM module matching the parameters specified in the request + /// + /// Tag + /// Contact stage ID (warmth) + /// Contact type ID + /// + /// Start date + /// End date + /// + /// + /// Delete the list of all contacts + /// Contacts + /// + /// Contact list + /// + [Delete(@"contact/filter")] + public IEnumerable DeleteBatchContacts( + IEnumerable tags, + int? contactStage, + int? contactType, + ContactListViewType contactListView, + ApiDateTime fromDate, + ApiDateTime toDate) + { + int contactStageInt = contactStage.HasValue ? contactStage.Value : -1; + int contactTypeInt = contactType.HasValue ? contactType.Value : -1; + + + var contacts = DaoFactory.GetContactDao().GetContacts( + ApiContext.FilterValue, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, + toDate, + 0, + 0, + null); + + contacts = DaoFactory.GetContactDao().DeleteBatchContact(contacts); + + MessageService.Send( MessageAction.ContactsDeleted, MessageTarget.Create(contacts.Select(c => c.ID)), contacts.Select(c => c.GetTitle())); + + return contacts.Select(ToContactBaseWrapper); + } + + + /// + /// Returns the list of all the persons linked to the company with the ID specified in the request + /// + /// Company ID + /// + /// Get company linked persons list + /// Contacts + /// + /// Linked persons + /// + [Read(@"contact/company/{companyid:int}/person")] + public IEnumerable GetPeopleFromCompany(int companyid) + { + if (companyid <= 0) throw new ArgumentException(); + + var company = DaoFactory.GetContactDao().GetByID(companyid); + if (company == null || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + + return ToListContactWrapper(DaoFactory.GetContactDao().GetMembers(companyid).Where(CRMSecurity.CanAccessTo).ToList()); + } + + /// + /// Adds the selected person to the company with the ID specified in the request + /// + /// Company ID + /// Person ID + /// Add person to company + /// Contacts + /// + /// + /// + /// Person + /// + [Create(@"contact/company/{companyid:int}/person")] + public PersonWrapper AddPeopleToCompany(int companyid, int personid) + { + if ((companyid <= 0) || (personid <= 0)) throw new ArgumentException(); + + var company = DaoFactory.GetContactDao().GetByID(companyid); + var person = DaoFactory.GetContactDao().GetByID(personid); + + if (person == null || company == null || !CRMSecurity.CanAccessTo(person) || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + + DaoFactory.GetContactDao().AddMember(personid, companyid); + MessageService.Send( MessageAction.CompanyLinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); + + return (PersonWrapper)ToContactWrapper(person); + } + + /// + /// Deletes the selected person from the company with the ID specified in the request + /// + /// Company ID + /// Person ID + /// Delete person from company + /// Contacts + /// + /// + /// + /// Person + /// + [Delete(@"contact/company/{companyid:int}/person")] + public PersonWrapper DeletePeopleFromCompany(int companyid, int personid) + { + if ((companyid <= 0) || (personid <= 0)) throw new ArgumentException(); + + var company = DaoFactory.GetContactDao().GetByID(companyid); + var person = DaoFactory.GetContactDao().GetByID(personid); + if (person == null || company == null || !CRMSecurity.CanAccessTo(person) || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + + DaoFactory.GetContactDao().RemoveMember(personid); + + MessageService.Send( MessageAction.CompanyUnlinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); + + return (PersonWrapper)ToContactWrapper(person); + } + + /// + /// Creates the person with the parameters (first name, last name, description, etc.) specified in the request + /// + /// First name + /// Last name + /// Post + /// Company ID + /// Person description text + /// Person privacy: 0 - not shared, 1 - shared for read/write, 2 - shared for read only + /// List of managers for the person + /// User field list + /// Contact photo (upload using multipart/form-data) + /// Create person + /// Contacts + /// Person + /// + [Create(@"contact/person")] + public PersonWrapper CreatePerson( + string firstName, + string lastName, + string jobTitle, + int companyId, + string about, + ShareType shareType, + IEnumerable managerList, + IEnumerable> customFieldList, + IEnumerable photo) + { + if (companyId > 0) { + var company = DaoFactory.GetContactDao().GetByID(companyId); + if (company == null || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + } + + var peopleInst = new Person + { + FirstName = firstName, + LastName = lastName, + JobTitle = jobTitle, + CompanyID = companyId, + About = about, + ShareType = shareType + }; + + peopleInst.ID = DaoFactory.GetContactDao().SaveContact(peopleInst); + peopleInst.CreateBy = Core.SecurityContext.CurrentAccount.ID; + peopleInst.CreateOn = DateTime.UtcNow; + + var managerListLocal = managerList != null ? managerList.ToList() : new List(); + if (managerListLocal.Any()) + { + CRMSecurity.SetAccessTo(peopleInst, managerListLocal); + } + + if (customFieldList != null) + { + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Person, peopleInst.ID, field.Key, field.Value); + } + } + + var wrapper = (PersonWrapper)ToContactWrapper(peopleInst); + + var photoList = photo != null ? photo.ToList() : new List(); + if (photoList.Any()) + { + wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); + } + + MessageService.Send( MessageAction.PersonCreated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); + + return wrapper; + } + + /// + /// Changes the photo for the contact with the ID specified in the request + /// + /// Contact ID + /// Contact photo (upload using multipart/form-data) + /// Change contact photo + /// Contacts + /// + /// + /// Path to contact photo + /// + [Update(@"contact/{contactid:int}/changephoto")] + public string ChangeContactPhoto(int contactid, IEnumerable photo) + { + if (contactid <= 0) + throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) + throw new ItemNotFoundException(); + + var firstPhoto = photo != null ? photo.FirstOrDefault() : null; + if (firstPhoto == null) + throw new ArgumentException(); + + if (firstPhoto.ContentLength == 0 || + !firstPhoto.ContentType.StartsWith("image/") || + !firstPhoto.InputStream.CanRead) + throw new InvalidOperationException(CRMErrorsResource.InvalidFile); + + if (SetupInfo.MaxImageUploadSize > 0 && + SetupInfo.MaxImageUploadSize < firstPhoto.ContentLength) + throw new Exception(FileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false)); + + return ContactPhotoManager.UploadPhoto(firstPhoto.InputStream, contactid, false).Url; + } + + /// + /// Changes the photo for the contact with the ID specified in the request + /// + /// Contact ID + /// contact photo url + /// Change contact photo + /// Contacts + /// + /// + /// Path to contact photo + /// + [Update(@"contact/{contactid:int}/changephotobyurl")] + public string ChangeContactPhoto(int contactid, string photourl) + { + if (contactid <= 0 || string.IsNullOrEmpty(photourl)) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + return ContactPhotoManager.UploadPhoto(photourl, contactid, false).Url; + } + + /// + /// Merge two selected contacts + /// + /// the first contact ID for merge + /// the second contact ID for merge + /// Merge contacts + /// Contacts + /// + /// + /// + /// + /// Contact + /// + [Update(@"contact/merge")] + public ContactWrapper MergeContacts(int fromcontactid, int tocontactid) + { + if (fromcontactid <= 0 || tocontactid <= 0) throw new ArgumentException(); + + var fromContact = DaoFactory.GetContactDao().GetByID(fromcontactid); + var toContact = DaoFactory.GetContactDao().GetByID(tocontactid); + + if (fromContact == null || toContact == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanEdit(fromContact) || !CRMSecurity.CanEdit(toContact)) throw CRMSecurity.CreateSecurityException(); + + DaoFactory.GetContactDao().MergeDublicate(fromcontactid, tocontactid); + var resultContact = DaoFactory.GetContactDao().GetByID(tocontactid); + + var messageAction = resultContact is Person ? MessageAction.PersonsMerged : MessageAction.CompaniesMerged; + MessageService.Send( messageAction, MessageTarget.Create(new[] { fromContact.ID, toContact.ID }), fromContact.GetTitle(), toContact.GetTitle()); + + return ToContactWrapper(resultContact); + } + + /// + /// Updates the selected person with the parameters (first name, last name, description, etc.) specified in the request + /// + /// Person ID + /// First name + /// Last name + /// Post + /// Company ID + /// Person description text + /// Person privacy: 0 - not shared, 1 - shared for read/write, 2 - shared for read only + /// List of persons managers + /// User field list + /// Contact photo (upload using multipart/form-data) + /// Update person + /// Contacts + /// Person + /// + /// + [Update(@"contact/person/{personid:int}")] + public PersonWrapper UpdatePerson( + int personid, + string firstName, + string lastName, + string jobTitle, + int companyId, + string about, + ShareType shareType, + IEnumerable managerList, + IEnumerable> customFieldList, + IEnumerable photo) + { + if (personid <= 0 || string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) throw new ArgumentException(); + + var peopleInst = new Person + { + ID = personid, + FirstName = firstName, + LastName = lastName, + JobTitle = jobTitle, + CompanyID = companyId, + About = about, + ShareType = shareType + }; + + DaoFactory.GetContactDao().UpdateContact(peopleInst); + + peopleInst = (Person)DaoFactory.GetContactDao().GetByID(peopleInst.ID); + + var managerListLocal = managerList != null ? managerList.ToList() : new List(); + if (managerListLocal.Any()) + { + CRMSecurity.SetAccessTo(peopleInst, managerListLocal); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Person).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Person, peopleInst.ID, field.Key, field.Value); + } + } + + var wrapper = (PersonWrapper)ToContactWrapper(peopleInst); + + var photoList = photo != null ? photo.ToList() : new List(); + if (photoList.Any()) + { + wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); + } + + MessageService.Send( MessageAction.PersonUpdated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); + + return wrapper; + } + + /// + /// Creates the company with the parameters specified in the request + /// + /// Company name + /// Company description text + /// Linked person list + /// Company privacy: 0 - not shared, 1 - shared for read/write, 2 - shared for read only + /// List of managers for the company + /// User field list + /// Contact photo (upload using multipart/form-data) + /// Create company + /// Contacts + /// Company + /// + [Create(@"contact/company")] + public CompanyWrapper CreateCompany( + string companyName, + string about, + IEnumerable personList, + ShareType shareType, + IEnumerable managerList, + IEnumerable> customFieldList, + IEnumerable photo) + { + var companyInst = new Company + { + CompanyName = companyName, + About = about, + ShareType = shareType + }; + + companyInst.ID = DaoFactory.GetContactDao().SaveContact(companyInst); + companyInst.CreateBy = Core.SecurityContext.CurrentAccount.ID; + companyInst.CreateOn = DateTime.UtcNow; + + if (personList != null) + { + foreach (var personID in personList) + { + var person = DaoFactory.GetContactDao().GetByID(personID); + if (person == null || !CRMSecurity.CanAccessTo(person)) continue; + + AddPeopleToCompany(companyInst.ID, personID); + } + } + + var managerListLocal = managerList != null ? managerList.ToList() : new List(); + if (managerListLocal.Any()) + { + CRMSecurity.SetAccessTo(companyInst, managerListLocal); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Company).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Company, companyInst.ID, field.Key, field.Value); + } + } + + var wrapper = (CompanyWrapper)ToContactWrapper(companyInst); + + var photoList = photo != null ? photo.ToList() : new List(); + if (photoList.Any()) + { + wrapper.SmallFotoUrl = ChangeContactPhoto(companyInst.ID, photoList); + } + + MessageService.Send( MessageAction.CompanyCreated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + + return wrapper; + } + + /// + /// Quickly creates the list of companies + /// + /// + /// Quick company list creation + /// + /// Company name + /// Contacts + /// Contact list + /// + [Create(@"contact/company/quick")] + public IEnumerable CreateCompany(IEnumerable companyName) + { + if (companyName == null) throw new ArgumentException(); + + var contacts = new List(); + var recordIndex = 0; + + foreach (var item in companyName) + { + if (string.IsNullOrEmpty(item)) continue; + + contacts.Add(new Company + { + ID = recordIndex++, + CompanyName = item, + ShareType = ShareType.None + }); + } + + if (contacts.Count == 0) return null; + + DaoFactory.GetContactDao().SaveContactList(contacts); + + var selectedManagers = new List {Core.SecurityContext.CurrentAccount.ID}; + + foreach (var ct in contacts) + { + CRMSecurity.SetAccessTo(ct, selectedManagers); + } + + return contacts.ConvertAll(ToContactBaseWrapper); + } + + /// + /// Quickly creates the list of persons with the first and last names specified in the request + /// + /// + /// Quick person list creation + /// + /// Pairs: user first name, user last name + /// + /// + /// + /// Contacts + /// Contact list + /// + [Create(@"contact/person/quick")] + public IEnumerable CreatePerson(IEnumerable> data) + { + if (data == null) return null; + + var contacts = new List(); + var recordIndex = 0; + + foreach (var item in data) + { + if (string.IsNullOrEmpty(item.Key) || string.IsNullOrEmpty(item.Value)) continue; + + contacts.Add(new Person + { + ID = recordIndex++, + FirstName = item.Key, + LastName = item.Value, + ShareType = ShareType.None + }); + } + + if (contacts.Count == 0) return null; + + DaoFactory.GetContactDao().SaveContactList(contacts); + + var selectedManagers = new List {Core.SecurityContext.CurrentAccount.ID}; + + foreach (var ct in contacts) + { + CRMSecurity.SetAccessTo(ct, selectedManagers); + } + + MessageService.Send( MessageAction.PersonsCreated, MessageTarget.Create(contacts.Select(x => x.ID)), contacts.Select(x => x.GetTitle())); + + return contacts.ConvertAll(ToContactBaseWrapper); + } + + /// + /// Updates the selected company with the parameters specified in the request + /// + /// Company ID + /// Company name + /// Company description text + /// Company privacy: 0 - not shared, 1 - shared for read/write, 2 - shared for read only + /// List of company managers + /// User field list + /// Update company + /// Contacts + /// + /// + /// Company + /// + [Update(@"contact/company/{companyid:int}")] + public CompanyWrapper UpdateCompany( + int companyid, + string companyName, + string about, + ShareType shareType, + IEnumerable managerList, + IEnumerable> customFieldList) + { + var companyInst = new Company + { + ID = companyid, + CompanyName = companyName, + About = about, + ShareType = shareType + }; + + DaoFactory.GetContactDao().UpdateContact(companyInst); + + companyInst = (Company)DaoFactory.GetContactDao().GetByID(companyInst.ID); + + var managerListLocal = managerList != null ? managerList.ToList(): new List(); + if (managerListLocal.Any()) + { + CRMSecurity.SetAccessTo(companyInst, managerListLocal); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Company).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Company, companyInst.ID, field.Key, field.Value); + } + } + + MessageService.Send( MessageAction.CompanyUpdated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + + return (CompanyWrapper)ToContactWrapper(companyInst); + } + + /// + /// Updates the selected contact status + /// + /// Contact ID + /// Contact status ID + /// Update status in contact by id + /// Contacts + /// + /// + /// + /// Company + /// + [Update(@"contact/{contactid:int}/status")] + public ContactWrapper UpdateContactStatus(int contactid, int contactStatusid) + { + if (contactid <= 0 || contactStatusid < 0) throw new ArgumentException(); + + var dao = DaoFactory.GetContactDao(); + + if (contactStatusid > 0) + { + var curListItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); + if (curListItem == null) throw new ItemNotFoundException(); + } + + var companyInst = dao.GetByID(contactid); + if (companyInst == null || !CRMSecurity.CanAccessTo(companyInst)) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanEdit(companyInst)) throw CRMSecurity.CreateSecurityException(); + + dao.UpdateContactStatus(new List{companyInst.ID}, contactStatusid); + companyInst.StatusID = contactStatusid; + + var messageAction = companyInst is Company ? MessageAction.CompanyUpdatedTemperatureLevel : MessageAction.PersonUpdatedTemperatureLevel; + MessageService.Send( messageAction, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + + return ToContactWrapper(companyInst); + } + + /// + /// Updates status of the selected company and all its participants + /// + /// Company ID + /// Contact status ID + /// Update company and participants status + /// Contacts + /// + /// + /// + /// Company + /// + [Update(@"contact/company/{companyid:int}/status")] + public ContactWrapper UpdateCompanyAndParticipantsStatus(int companyid, int contactStatusid) + { + if (companyid <= 0 || contactStatusid < 0) throw new ArgumentException(); + + var dao = DaoFactory.GetContactDao(); + + if (contactStatusid > 0) + { + var curListItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); + if (curListItem == null) throw new ItemNotFoundException(); + } + + var companyInst = dao.GetByID(companyid); + if (companyInst == null || !CRMSecurity.CanAccessTo(companyInst)) throw new ItemNotFoundException(); + + if (companyInst is Person) throw new Exception(CRMErrorsResource.ContactIsNotCompany); + + var forUpdateStatus = new List(); + forUpdateStatus.Add(companyInst.ID); + + var members = dao.GetMembersIDsAndShareType(companyInst.ID); + foreach (var m in members) + { + if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + { + forUpdateStatus.Add(m.Key); + } + } + + dao.UpdateContactStatus(forUpdateStatus, contactStatusid); + + MessageService.Send( MessageAction.CompanyUpdatedTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + MessageService.Send( MessageAction.CompanyUpdatedPersonsTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + + return ToContactWrapper(companyInst); + } + + /// + /// Updates status of the selected person, related company and all its participants + /// + /// Person ID + /// Contact status ID + /// Update person, related company and participants status + /// Contacts + /// + /// + /// + /// Person + /// + [Update(@"contact/person/{personid:int}/status")] + public ContactWrapper UpdatePersonAndItsCompanyStatus(int personid, int contactStatusid) + { + if (personid <= 0 || contactStatusid < 0) throw new ArgumentException(); + + if (contactStatusid > 0) + { + var curListItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); + if (curListItem == null) throw new ItemNotFoundException(); + } + + var dao = DaoFactory.GetContactDao(); + + var personInst = dao.GetByID(personid); + if (personInst == null || !CRMSecurity.CanAccessTo(personInst)) throw new ItemNotFoundException(); + + if (personInst is Company) throw new Exception(CRMErrorsResource.ContactIsNotPerson); + + var forUpdateStatus = new List(); + + var companyID = ((Person)personInst).CompanyID; + if (companyID != 0) + { + var companyInst = dao.GetByID(companyID); + if (companyInst == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(companyInst)) + { + forUpdateStatus.Add(personInst.ID); + dao.UpdateContactStatus(forUpdateStatus, contactStatusid); + } + else + { + forUpdateStatus.Add(companyInst.ID); + + var members = dao.GetMembersIDsAndShareType(companyInst.ID); + foreach (var m in members) + { + if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + { + forUpdateStatus.Add(m.Key); + } + } + dao.UpdateContactStatus(forUpdateStatus, contactStatusid); + } + } + else + { + forUpdateStatus.Add(personInst.ID); + dao.UpdateContactStatus(forUpdateStatus, contactStatusid); + } + + MessageService.Send( MessageAction.PersonUpdatedTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); + MessageService.Send( MessageAction.PersonUpdatedCompanyTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); + + personInst = dao.GetByID(personInst.ID); + return ToContactWrapper(personInst); + } + + /// + /// Get access rights to the contact with the ID specified in the request + /// + /// Get contact access rights + /// Contacts + /// + /// + /// + /// User list + [Read(@"contact/{contactid:int}/access")] + public IEnumerable GetContactAccessList(int contactid) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + + if (contact == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(contact)) throw CRMSecurity.CreateSecurityException(); + + return CRMSecurity.IsPrivate(contact) + ? CRMSecurity.GetAccessSubjectTo(contact) + .Select(item => EmployeeWraper.Get(item.Key)) + : new List(); + } + + /// + /// Sets access rights for other users to the contact with the ID specified in the request + /// + /// Contact ID + /// Contact privacy: private or not + /// List of managers + /// Set contact access rights + /// Contacts + /// + /// + /// + /// + /// Contact + /// + [Update(@"contact/{contactid:int}/access")] + public ContactWrapper SetAccessToContact(int contactid, bool isShared, IEnumerable managerList) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanEdit(contact)) throw CRMSecurity.CreateSecurityException(); + + SetAccessToContact(contact, isShared, managerList, false); + + var wrapper = ToContactWrapper(contact); + return wrapper; + } + + private void SetAccessToContact(Contact contact, bool isShared, IEnumerable managerList, bool isNotify) + { + var managerListLocal = managerList != null ? managerList.Distinct().ToList() : new List(); + if (managerListLocal.Any()) + { + if (isNotify) + { + var notifyUsers = managerListLocal.Where(n => n != ASC.Core.SecurityContext.CurrentAccount.ID).ToArray(); + if (contact is Person) + ASC.Web.CRM.Services.NotifyService.NotifyClient.SendAboutSetAccess(EntityType.Person, contact.ID, DaoFactory, notifyUsers); + else + ASC.Web.CRM.Services.NotifyService.NotifyClient.SendAboutSetAccess(EntityType.Company, contact.ID, DaoFactory, notifyUsers); + + } + + CRMSecurity.SetAccessTo(contact, managerListLocal); + } + else + { + CRMSecurity.MakePublic(contact); + } + + DaoFactory.GetContactDao().MakePublic(contact.ID, isShared); + } + + /// + /// Sets access rights for other users to the list of contacts with the IDs specified in the request + /// + /// Contact ID list + /// Company privacy: shared or not + /// List of managers + /// Set contact access rights + /// Contacts + /// + /// + /// + /// Contact list + /// + [Update(@"contact/access")] + public IEnumerable SetAccessToBatchContact(IEnumerable contactid, bool isShared, IEnumerable managerList) + { + if (contactid == null) throw new ArgumentException(); + + var result = new List(); + + foreach (var id in contactid) + { + var contactWrapper = SetAccessToContact(id, isShared, managerList); + result.Add(contactWrapper); + } + + return result; + } + + /// + /// Sets access rights for the selected user to the list of contacts with the parameters specified in the request + /// + /// Contact privacy: private or not + /// List of managers + /// Tag + /// Contact stage ID (warmth) + /// Contact type ID + /// + /// Start date + /// End date + /// Set contact access rights + /// Contacts + /// + /// + /// + /// Contact list + /// + [Update(@"contact/filter/access")] + public IEnumerable SetAccessToBatchContact( + IEnumerable tags, + int? contactStage, + int? contactType, + ContactListViewType contactListView, + ApiDateTime fromDate, + ApiDateTime toDate, + bool isPrivate, + IEnumerable managerList + ) + { + int contactStageInt = contactStage.HasValue ? contactStage.Value : -1; + int contactTypeInt = contactType.HasValue ? contactType.Value : -1; + + var result = new List(); + + var contacts = DaoFactory.GetContactDao().GetContacts( + ApiContext.FilterValue, + tags, + contactStageInt, + contactTypeInt, + contactListView, + fromDate, toDate, + 0, 0, null); + + if (!contacts.Any()) + return Enumerable.Empty(); + + foreach (var contact in contacts) + { + if (contact == null) + throw new ItemNotFoundException(); + + if (!CRMSecurity.CanEdit(contact)) continue; + + SetAccessToContact(contact, isPrivate, managerList, false); + + result.Add(contact); + } + return ToListContactWrapper(result); + } + + /// + /// Deletes the contact with the ID specified in the request from the portal + /// + /// Delete contact + /// Contacts + /// Contact ID + /// + /// + /// + /// Contact + /// + [Delete(@"contact/{contactid:int}")] + public ContactWrapper DeleteContact(int contactid) + { + if (contactid <= 0) throw new ArgumentException(); + + var contact = DaoFactory.GetContactDao().DeleteContact(contactid); + if (contact == null) throw new ItemNotFoundException(); + + var messageAction = contact is Person ? MessageAction.PersonDeleted : MessageAction.CompanyDeleted; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + return ToContactWrapper(contact); + } + + /// + /// Deletes the group of contacts with the IDs specified in the request + /// + /// Contact ID list + /// + /// + /// Delete contact group + /// Contacts + /// + /// Contact list + /// + [Update(@"contact")] + public IEnumerable DeleteBatchContacts(IEnumerable contactids) + { + if (contactids == null) throw new ArgumentException(); + + var contacts = DaoFactory.GetContactDao().DeleteBatchContact(contactids.ToArray()); + MessageService.Send( MessageAction.ContactsDeleted, MessageTarget.Create(contactids), contacts.Select(c => c.GetTitle())); + + return contacts.Select(ToContactBaseWrapper); + } + + /// + /// Returns the list of 30 contacts in the CRM module with prefix + /// + /// + /// searchType + /// + /// + /// Contacts + /// + /// Contact list + /// + /// false + [Read(@"contact/byprefix")] + public IEnumerable GetContactsByPrefix(string prefix, int searchType, EntityType entityType, int entityID) + { + var result = new List(); + var allContacts = new List(); + + if (entityID > 0) + { + var findedContacts = new List(); + switch (entityType) + { + case EntityType.Opportunity: + allContacts = DaoFactory.GetContactDao().GetContacts(DaoFactory.GetDealDao().GetMembers(entityID)); + break; + case EntityType.Case: + allContacts = DaoFactory.GetContactDao().GetContacts(DaoFactory.GetCasesDao().GetMembers(entityID)); + break; + } + + foreach (var c in allContacts) + { + var person = c as Person; + if (person != null) + { + var people = person; + if (Core.Users.UserFormatter.GetUserName(people.FirstName, people.LastName).IndexOf(prefix, StringComparison.Ordinal) != -1) + { + findedContacts.Add(person); + } + } + else + { + var company = (Company)c; + if (company.CompanyName.IndexOf(prefix, StringComparison.Ordinal) != -1) + { + findedContacts.Add(c); + } + } + } + result.AddRange(findedContacts.Select(ToContactBaseWithPhoneWrapper)); + ApiContext.SetTotalCount(findedContacts.Count); + } + else + { + const int maxItemCount = 30; + if (searchType < -1 || searchType > 3) throw new ArgumentException(); + + allContacts = DaoFactory.GetContactDao().GetContactsByPrefix(prefix, searchType, 0, maxItemCount); + result.AddRange(allContacts.Select(ToContactBaseWithPhoneWrapper)); + } + + return result; + } + + + /// + /// Returns the list contacts in the CRM module with contact information + /// + /// Contact information type + /// Data + /// Category + /// Contact importance: primary or not + /// Contacts + /// + /// Contact list + /// + [Read(@"contact/bycontactinfo")] + public IEnumerable GetContactsByContactInfo(ContactInfoType? infoType, String data, int? category, bool? isPrimary) + { + if (!infoType.HasValue) throw new ArgumentException(); + + var ids = DaoFactory.GetContactDao().GetContactIDsByContactInfo(infoType.Value, data, category, isPrimary); + + var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(ToContactWrapper); + + return result; + } + + /// + /// + /// + /// + /// + /// Contacts + /// + [Read(@"contact/{contactid:int}/tweets")] + public List GetUserTweets(int contactid, int count) + { + var MessageCount = 10; + var twitterAccounts = DaoFactory.GetContactInfoDao().GetList(contactid, ContactInfoType.Twitter, null, null); + + if (twitterAccounts.Count == 0) + throw new ResourceNotFoundException( + Newtonsoft.Json.JsonConvert.SerializeObject( + new + { + message = "", + description = CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter + } + )); + + var apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); + TwitterDataProvider twitterProvider = new TwitterDataProvider(apiInfo); + + List messages = new List(); + + foreach (var twitterAccount in twitterAccounts) + { + try + { + messages.AddRange(twitterProvider.GetUserTweets(twitterAccount.ID, twitterAccount.Data, MessageCount)); + } + catch (ResourceNotFoundException ex) + { + throw new ResourceNotFoundException( + Newtonsoft.Json.JsonConvert.SerializeObject( + new + { + message = ex.Message, + description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) + } + )); + } + catch (Exception ex) + { + throw new Exception( + Newtonsoft.Json.JsonConvert.SerializeObject( + new + { + message = ex.Message, + description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) + } + )); + } + } + + + return messages.OrderByDescending(m => m.PostedOn).Take(MessageCount).ToList(); + + } + + + /// + /// + /// + /// + /// Contacts + /// + [Read(@"contact/twitterprofile")] + public List FindTwitterProfiles(string searchText) + { + try + { + TwitterApiInfo apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); + if (apiInfo == null) + throw new SocialMediaAccountNotFound(CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter); + + TwitterDataProvider provider = new TwitterDataProvider(apiInfo); + List users = provider.FindUsers(searchText); + /*List users = new List(); + users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); + users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); + users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 });*/ + return users; + } + catch (Exception ex) { + throw new SocialMediaUI(DaoFactory).ProcessError(ex, "ASC.Api.CRM.CRMApi.FindTwitterProfiles"); + } + } + + /// + /// + /// + /// + /// + /// + /// Contacts + /// + [Delete(@"contact/{contactid:int}/avatar")] + public string DeleteContactAvatar(int contactId, string contactType, bool uploadOnly) + { + bool isCompany; + + if (contactId != 0) + { + var contact = DaoFactory.GetContactDao().GetByID(contactId); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanEdit(contact)) throw CRMSecurity.CreateSecurityException(); + + isCompany = contact is Company; + } + else + { + isCompany = contactType != "people"; + } + + if (!uploadOnly) + { + ContactPhotoManager.DeletePhoto(contactId); + return ContactPhotoManager.GetBigSizePhoto(0, isCompany); + } + return ""; + } + + /// + /// + /// + /// + /// Contacts + /// + [Read(@"contact/{contactid:int}/socialmediaavatar")] + public List GetContactSMImages(int contactId) + { + return new SocialMediaUI(DaoFactory).GetContactSMImages(contactId); + } + + /// + /// + /// + /// + /// Contacts + /// + [Create(@"contact/socialmediaavatar")] + public List GetContactSMImagesByNetworks(List socialNetworks) + { + if (socialNetworks == null || socialNetworks.Count == 0){ + return new List(); + } + var twitter = new List(); + + foreach (var sn in socialNetworks) { + if (sn.InfoType == ContactInfoType.Twitter) twitter.Add(sn.Data); + } + + return new SocialMediaUI(DaoFactory).GetContactSMImages(twitter); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// Contacts + /// + [Update(@"contact/{contactid:int}/avatar")] + public ContactPhotoManager.PhotoData UploadUserAvatarFromSocialNetwork(int contactId, SocialNetworks socialNetwork, string userIdentity, bool uploadOnly, string tmpDirName) + { + if (socialNetwork != SocialNetworks.Twitter) + throw new ArgumentException(); + + if (contactId != 0) + { + var contact = DaoFactory.GetContactDao().GetByID(contactId); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanEdit(contact)) throw CRMSecurity.CreateSecurityException(); + } + + if (socialNetwork == SocialNetworks.Twitter) + { + var provider = new TwitterDataProvider(TwitterApiHelper.GetTwitterApiInfoForCurrentUser()); + var imageUrl = provider.GetUrlOfUserImage(userIdentity, TwitterDataProvider.ImageSize.Original); + return UploadAvatar(contactId, imageUrl, uploadOnly, tmpDirName, false); + } + + return null; + } + + /// false + [Create(@"contact/mailsmtp/send")] + public IProgressItem SendMailSMTPToContacts(List fileIDs, List contactIds, String subject, String body, bool storeInHistory) + { + if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); + + var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()); + MessageService.Send( MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); + + return MailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); + } + + /// false + [Create(@"contact/mailsmtp/preview")] + public string GetMailSMTPToContactsPreview(string template, int contactId) + { + if (contactId == 0 || String.IsNullOrEmpty(template)) throw new ArgumentException(); + + var manager = new MailTemplateManager(DaoFactory); + + return manager.Apply(template, contactId); + } + + /// false + [Read(@"contact/mailsmtp/status")] + public IProgressItem GetMailSMTPToContactsStatus() + { + return MailSender.GetStatus(); + } + + /// false + [Update(@"contact/mailsmtp/cancel")] + public IProgressItem CancelMailSMTPToContacts() + { + var progressItem = MailSender.GetStatus(); + MailSender.Cancel(); + return progressItem; + } + + /// false + [Update(@"contact/{contactid:int}/creationdate")] + public void SetContactCreationDate(int contactId, ApiDateTime creationDate) + { + var dao = DaoFactory.GetContactDao(); + var contact = dao.GetByID(contactId); + + if (contact == null || !CRMSecurity.CanAccessTo(contact)) + throw new ItemNotFoundException(); + + dao.SetContactCreationDate(contactId, creationDate); + } + + /// false + [Update(@"contact/{contactid:int}/lastmodifeddate")] + public void SetContactLastModifedDate(int contactId, ApiDateTime lastModifedDate) + { + var dao = DaoFactory.GetContactDao(); + var contact = dao.GetByID(contactId); + + if (contact == null || !CRMSecurity.CanAccessTo(contact)) + throw new ItemNotFoundException(); + + dao.SetContactLastModifedDate(contactId, lastModifedDate); + } + + + private static ContactPhotoManager.PhotoData UploadAvatar(int contactID, string imageUrl, bool uploadOnly, string tmpDirName, bool checkFormat = true) + { + if (contactID != 0) + { + return ContactPhotoManager.UploadPhoto(imageUrl, contactID, uploadOnly, checkFormat); + } + + if (string.IsNullOrEmpty(tmpDirName) || tmpDirName == "null") tmpDirName = null; + return ContactPhotoManager.UploadPhotoToTemp(imageUrl, tmpDirName, checkFormat); + } + + private IEnumerable ToSimpleListContactWrapper(IReadOnlyList itemList) + { + if (itemList.Count == 0) return new List(); + + var result = new List(); + + var personsIDs = new List(); + var companyIDs = new List(); + var contactIDs = new int[itemList.Count]; + + var peopleCompanyIDs = new List(); + var peopleCompanyList = new Dictionary(); + + var contactDao = DaoFactory.GetContactDao(); + + for (var index = 0; index < itemList.Count; index++) + { + var contact = itemList[index]; + + if (contact is Company) + { + companyIDs.Add(contact.ID); + } + else + { + var person = contact as Person; + if (person != null) + { + personsIDs.Add(person.ID); + + if (person.CompanyID > 0) + { + peopleCompanyIDs.Add(person.CompanyID); + } + } + } + + contactIDs[index] = itemList[index].ID; + } + + if (peopleCompanyIDs.Count > 0) + { + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ToContactBaseWrapperQuick(item)); + var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.ID).ToArray()); + + foreach (var contactBaseWrapperQuick in tmpList) + { + contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.ID]; + peopleCompanyList.Add(contactBaseWrapperQuick.ID, contactBaseWrapperQuick); + } + } + + var contactInfos = new Dictionary>(); + + var addresses = new Dictionary>(); + + DaoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( + item => + { + if (item.InfoType == ContactInfoType.Address) + { + if (!addresses.ContainsKey(item.ContactID)) + { + addresses.Add(item.ContactID, new List
    + { + new Address(item) + }); + } + else + { + addresses[item.ContactID].Add(new Address(item)); + } + } + else + { + if (!contactInfos.ContainsKey(item.ContactID)) + { + contactInfos.Add(item.ContactID, new List {new ContactInfoWrapper(item)}); + } + else + { + contactInfos[item.ContactID].Add(new ContactInfoWrapper(item)); + } + } + } + ); + + var nearestTasks = DaoFactory.GetTaskDao().GetNearestTask(contactIDs.ToArray()); + + IEnumerable taskCategories = new List(); + + if (nearestTasks.Any()) + { + taskCategories = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => new TaskCategoryBaseWrapper(item)); + } + + foreach (var contact in itemList) + { + ContactWrapper contactWrapper; + + var person = contact as Person; + if (person != null) + { + var people = person; + + var peopleWrapper = PersonWrapper.ToPersonWrapperQuick(people); + + if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) + { + peopleWrapper.Company = peopleCompanyList[people.CompanyID]; + } + + contactWrapper = peopleWrapper; + } + else + { + var company = contact as Company; + if (company != null) + { + contactWrapper = CompanyWrapper.ToCompanyWrapperQuick(company); + } + else + { + throw new ArgumentException(); + } + } + + contactWrapper.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); + + TaskBaseWrapper taskWrapper = null; + + if (nearestTasks.ContainsKey(contactWrapper.ID)) + { + var task = nearestTasks[contactWrapper.ID]; + taskWrapper = new TaskBaseWrapper(task); + + if (task.CategoryID > 0) + { + taskWrapper.Category = taskCategories.First(x => x.ID == task.CategoryID); + } + } + + result.Add(new ContactWithTaskWrapper + { + Contact = contactWrapper, + Task = taskWrapper + }); + } + + + #region CanDelete for main contacts + + if (result.Count > 0) + { + var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Contact.ID).ToArray()); + foreach (var contactBaseWrapperQuick in result) + { + contactBaseWrapperQuick.Contact.CanDelete = contactBaseWrapperQuick.Contact.CanEdit && resultListCanDelete[contactBaseWrapperQuick.Contact.ID]; + } + } + + #endregion + + return result; + } + + private IEnumerable ToListContactWrapper(IReadOnlyList itemList) + { + if (itemList.Count == 0) return new List(); + + var result = new List(); + + var personsIDs = new List(); + var companyIDs = new List(); + var contactIDs = new int[itemList.Count]; + + var peopleCompanyIDs = new List(); + var peopleCompanyList = new Dictionary(); + + + var contactDao = DaoFactory.GetContactDao(); + + + for (var index = 0; index < itemList.Count; index++) + { + var contact = itemList[index]; + + if (contact is Company) + { + companyIDs.Add(contact.ID); + } + else + { + var person = contact as Person; + if (person != null) + { + personsIDs.Add(person.ID); + + if (person.CompanyID > 0) + { + peopleCompanyIDs.Add(person.CompanyID); + } + } + } + + contactIDs[index] = itemList[index].ID; + } + + if (peopleCompanyIDs.Count > 0) + { + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ToContactBaseWrapperQuick(item)); + var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.ID).ToArray()); + + foreach (var contactBaseWrapperQuick in tmpList) { + contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.ID]; + peopleCompanyList.Add(contactBaseWrapperQuick.ID, contactBaseWrapperQuick); + } + } + + var companiesMembersCount = contactDao.GetMembersCount(companyIDs.Distinct().ToArray()); + + var contactStatusIDs = itemList.Select(item => item.StatusID).Distinct().ToArray(); + var contactInfos = new Dictionary>(); + + var haveLateTask = DaoFactory.GetTaskDao().HaveLateTask(contactIDs); + var contactStatus = DaoFactory.GetListItemDao() + .GetItems(contactStatusIDs) + .ToDictionary(item => item.ID, item => new ContactStatusBaseWrapper(item)); + + var personsCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Person, personsIDs.ToArray()); + var companyCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Company, companyIDs.ToArray()); + + var customFields = personsCustomFields.Union(companyCustomFields) + .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + + var addresses = new Dictionary>(); + var taskCount = DaoFactory.GetTaskDao().GetTasksCount(contactIDs); + + var contactTags = DaoFactory.GetTagDao().GetEntitiesTags(EntityType.Contact); + + DaoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( + item => + { + if (item.InfoType == ContactInfoType.Address) + { + if (!addresses.ContainsKey(item.ContactID)) + addresses.Add(item.ContactID, new List
    { new Address(item) }); + else + addresses[item.ContactID].Add(new Address(item)); + } + else + { + if (!contactInfos.ContainsKey(item.ContactID)) + contactInfos.Add(item.ContactID, new List {new ContactInfoWrapper(item)}); + else + contactInfos[item.ContactID].Add(new ContactInfoWrapper(item)); + } + } + ); + + + foreach (var contact in itemList) + { + ContactWrapper contactWrapper; + + var person = contact as Person; + if (person != null) + { + var people = person; + + var peopleWrapper = PersonWrapper.ToPersonWrapperQuick(people); + + if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) + { + peopleWrapper.Company = peopleCompanyList[people.CompanyID]; + } + + contactWrapper = peopleWrapper; + } + else + { + var company = contact as Company; + if (company != null) + { + contactWrapper = CompanyWrapper.ToCompanyWrapperQuick(company); + + if (companiesMembersCount.ContainsKey(contactWrapper.ID)) + { + ((CompanyWrapper)contactWrapper).PersonsCount = companiesMembersCount[contactWrapper.ID]; + } + } + else + { + throw new ArgumentException(); + } + } + + if (contactTags.ContainsKey(contact.ID)) + { + contactWrapper.Tags = contactTags[contact.ID].OrderBy(x => x); + } + + if (addresses.ContainsKey(contact.ID)) + { + contactWrapper.Addresses = addresses[contact.ID]; + } + + contactWrapper.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); + + if (contactStatus.ContainsKey(contact.StatusID)) + { + contactWrapper.ContactStatus = contactStatus[contact.StatusID]; + } + + contactWrapper.HaveLateTasks = haveLateTask.ContainsKey(contact.ID) && haveLateTask[contact.ID]; + + contactWrapper.CustomFields = customFields.ContainsKey(contact.ID) ? customFields[contact.ID] : new List(); + + contactWrapper.TaskCount = taskCount.ContainsKey(contact.ID) ? taskCount[contact.ID] : 0; + + result.Add(contactWrapper); + } + + #region CanDelete for main contacts + + if (result.Count > 0) + { + var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.ID).ToArray()); + foreach (var contactBaseWrapperQuick in result) + { + contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && resultListCanDelete[contactBaseWrapperQuick.ID]; + } + } + + #endregion + + return result; + } + + + private static ContactBaseWrapper ToContactBaseWrapper(Contact contact) + { + return contact == null ? null : new ContactBaseWrapper(contact); + } + + private static ContactBaseWrapper ToContactBaseWrapperQuick(Contact contact) + { + return contact == null ? null : ContactBaseWrapper.ToContactBaseWrapperQuick(contact); + } + + private ContactWrapper ToContactWrapper(Contact contact) + { + ContactWrapper result; + + var person = contact as Person; + if (person != null) + { + var peopleWrapper = new PersonWrapper(person); + if (person.CompanyID > 0) + { + peopleWrapper.Company = ToContactBaseWrapper(DaoFactory.GetContactDao().GetByID(person.CompanyID)); + } + + result = peopleWrapper; + } + else + { + var company = contact as Company; + if (company != null) + { + result = new CompanyWrapper(company); + ((CompanyWrapper)result).PersonsCount = DaoFactory.GetContactDao().GetMembersCount(result.ID); + } + else throw new ArgumentException(); + } + + if (contact.StatusID > 0) + { + var listItem = DaoFactory.GetListItemDao().GetByID(contact.StatusID); + if (listItem == null) throw new ItemNotFoundException(); + + result.ContactStatus = new ContactStatusBaseWrapper(listItem); + } + + result.TaskCount = DaoFactory.GetTaskDao().GetTasksCount(contact.ID); + result.HaveLateTasks = DaoFactory.GetTaskDao().HaveLateTask(contact.ID); + + var contactInfos = new List(); + var addresses = new List
    (); + + var data = DaoFactory.GetContactInfoDao().GetList(contact.ID, null, null, null); + + foreach (var contactInfo in data) + { + if (contactInfo.InfoType == ContactInfoType.Address) + { + addresses.Add(new Address(contactInfo)); + } + else + { + contactInfos.Add(new ContactInfoWrapper(contactInfo)); + } + } + + result.Addresses = addresses; + result.CommonData = contactInfos; + + if (contact is Person) + { + result.CustomFields = DaoFactory.GetCustomFieldDao() + .GetEnityFields(EntityType.Person, contact.ID, false) + .ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); + } + else + { + result.CustomFields = DaoFactory.GetCustomFieldDao() + .GetEnityFields(EntityType.Company, contact.ID, false) + .ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); + } + + return result; + } + + private ContactBaseWithEmailWrapper ToContactBaseWithEmailWrapper(Contact contact) + { + if (contact == null) return null; + + var result = new ContactBaseWithEmailWrapper(contact); + var primaryEmail = DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Email, null, true); + if (primaryEmail == null || primaryEmail.Count == 0) + { + result.Email = null; + } + else + { + result.Email = new ContactInfoWrapper(primaryEmail.FirstOrDefault()); + } + return result; + } + + private ContactBaseWithPhoneWrapper ToContactBaseWithPhoneWrapper(Contact contact) + { + if (contact == null) return null; + + var result = new ContactBaseWithPhoneWrapper(contact); + var primaryPhone = DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Phone, null, true); + if (primaryPhone == null || primaryPhone.Count == 0) + { + result.Phone = null; + } + else + { + result.Phone = new ContactInfoWrapper(primaryPhone.FirstOrDefault()); + } + return result; + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs b/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs new file mode 100644 index 00000000000..7c6e4172f34 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs @@ -0,0 +1,297 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core; +using ASC.CRM.Resources; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + //TABLE `crm_currency_rate` column `rate` DECIMAL(10,2) NOT NULL + public const decimal MaxRateValue = (decimal) 99999999.99; + + /// + /// Get the list of currency rates + /// + /// Get currency rates list + /// Common + /// + /// List of currency rates + /// + [Read(@"currency/rates")] + public IEnumerable GetCurrencyRates() + { + return DaoFactory.GetCurrencyRateDao().GetAll().ConvertAll(ToCurrencyRateWrapper); + } + + /// + /// Get currency rate by id + /// + /// Get currency rate + /// Common + /// + /// Currency rate + /// + /// + [Read(@"currency/rates/{id:int}")] + public CurrencyRateWrapper GetCurrencyRate(int id) + { + if (id <= 0) throw new ArgumentException(); + + var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); + + return ToCurrencyRateWrapper(currencyRate); + } + + /// + /// Get currency rate by currencies + /// + /// Get currency rate + /// Common + /// + /// Currency rate + /// + /// + [Read(@"currency/rates/{fromCurrency}/{toCurrency}")] + public CurrencyRateWrapper GetCurrencyRate(string fromCurrency, string toCurrency) + { + if (string.IsNullOrEmpty(fromCurrency) || string.IsNullOrEmpty(toCurrency)) + throw new ArgumentException(); + + var currencyRate = DaoFactory.GetCurrencyRateDao().GetByCurrencies(fromCurrency, toCurrency); + + return ToCurrencyRateWrapper(currencyRate); + } + + /// + /// Create new currency rate object + /// + /// + /// Common + /// + [Create(@"currency/rates")] + public CurrencyRateWrapper CreateCurrencyRate(string fromCurrency, string toCurrency, decimal rate) + { + ValidateRate(rate); + + ValidateCurrencies(new[] {fromCurrency, toCurrency}); + + var currencyRate = new CurrencyRate + { + FromCurrency = fromCurrency, + ToCurrency = toCurrency, + Rate = rate + }; + + currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); + MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); + + return ToCurrencyRateWrapper(currencyRate); + } + + /// + /// Update currency rate object + /// + /// + /// Common + /// + [Update(@"currency/rates/{id:int}")] + public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, string toCurrency, decimal rate) + { + if (id <= 0) + throw new ArgumentException(); + + ValidateRate(rate); + + ValidateCurrencies(new[] {fromCurrency, toCurrency}); + + var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); + + if (currencyRate == null) + throw new ArgumentException(); + + currencyRate.FromCurrency = fromCurrency; + currencyRate.ToCurrency = toCurrency; + currencyRate.Rate = rate; + + currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); + MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); + + return ToCurrencyRateWrapper(currencyRate); + } + + /// + /// Set currency rates + /// + /// + /// Common + /// + [Create(@"currency/setrates")] + public List SetCurrencyRates(String currency, List rates) + { + if (!CRMSecurity.IsAdmin) + throw CRMSecurity.CreateSecurityException(); + + if (string.IsNullOrEmpty(currency)) + throw new ArgumentException(); + + ValidateCurrencyRates(rates); + + currency = currency.ToUpper(); + + if (Global.TenantSettings.DefaultCurrency.Abbreviation != currency) + { + var cur = CurrencyProvider.Get(currency); + + if (cur == null) + throw new ArgumentException(); + + Global.SaveDefaultCurrencySettings(cur); + + MessageService.Send( MessageAction.CrmDefaultCurrencyUpdated); + } + + rates = DaoFactory.GetCurrencyRateDao().SetCurrencyRates(rates); + + foreach (var rate in rates) + { + MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + } + + return rates.Select(ToCurrencyRateWrapper).ToList(); + } + + /// + /// Add currency rates + /// + /// + /// Common + /// + [Create(@"currency/addrates")] + public List AddCurrencyRates(List rates) + { + if (!CRMSecurity.IsAdmin) + throw CRMSecurity.CreateSecurityException(); + + ValidateCurrencyRates(rates); + + var existingRates = DaoFactory.GetCurrencyRateDao().GetAll(); + + foreach (var rate in rates) + { + var exist = false; + + foreach (var existingRate in existingRates) + { + if (rate.FromCurrency != existingRate.FromCurrency || rate.ToCurrency != existingRate.ToCurrency) + continue; + + existingRate.Rate = rate.Rate; + DaoFactory.GetCurrencyRateDao().SaveOrUpdate(existingRate); + MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + exist = true; + break; + } + + if (exist) continue; + + rate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(rate); + MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + existingRates.Add(rate); + } + + return existingRates.Select(ToCurrencyRateWrapper).ToList(); + } + + /// + /// Delete currency rate object + /// + /// + /// Common + /// + [Delete(@"currency/rates/{id:int}")] + public CurrencyRateWrapper DeleteCurrencyRate(int id) + { + if (id <= 0) + throw new ArgumentException(); + + var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); + + if (currencyRate == null) + throw new ArgumentException(); + + DaoFactory.GetCurrencyRateDao().Delete(id); + + return ToCurrencyRateWrapper(currencyRate); + } + + private static void ValidateCurrencyRates(IEnumerable rates) + { + var currencies = new List(); + + foreach (var rate in rates) + { + ValidateRate(rate.Rate); + currencies.Add(rate.FromCurrency); + currencies.Add(rate.ToCurrency); + } + + ValidateCurrencies(currencies.ToArray()); + } + + private static void ValidateCurrencies(string[] currencies) + { + if (currencies.Any(string.IsNullOrEmpty)) + throw new ArgumentException(); + + var available = CurrencyProvider.GetAll().Select(x => x.Abbreviation); + + var unknown = currencies.Where(x => !available.Contains(x)).ToArray(); + + if (!unknown.Any()) return; + + throw new ArgumentException(string.Format(CRMErrorsResource.UnknownCurrency, string.Join(",", unknown))); + } + + private static void ValidateRate(decimal rate) + { + if (rate < 0 || rate > MaxRateValue) + throw new ArgumentException(string.Format(CRMErrorsResource.InvalidCurrencyRate, rate)); + } + + private static CurrencyRateWrapper ToCurrencyRateWrapper(CurrencyRate currencyRate) + { + return new CurrencyRateWrapper(currencyRate); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs new file mode 100644 index 00000000000..635cce3db46 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs @@ -0,0 +1,415 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Core.Search; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the list of descriptions for all existing user fields + /// + /// Type + /// Get user field list + /// User fields + /// + /// User field list + /// + /// + [Read(@"{entityType:(contact|person|company|opportunity|case)}/customfield/definitions")] + public IEnumerable GetCustomFieldDefinitions(string entityType) + { + return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldWrapper).ToSmartList(); + } + + /// + /// Returns the list of all user field values using the entity type and entity ID specified in the request + /// + /// Type + /// ID + /// Get user field values + /// User fields + /// + [Read(@"{entityType:(contact|person|company|opportunity|case)}/{entityid:int}/customfield")] + public IEnumerable GetCustomFieldForSubject(string entityType, int entityid) + { + return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseWrapper).ToItemList(); + } + + /// + /// Sets the new user field value using the entity type, ID, field ID and value specified in the request + /// + /// Type + /// ID + /// Field ID + /// Field Value + /// Set user field value + /// User fields + /// + /// User field + /// + [Create(@"{entityType:(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")] + public CustomFieldBaseWrapper SetEntityCustomFieldValue(string entityType, int entityid, int fieldid, string fieldValue) + { + var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); + + var entityTypeStr = ToEntityType(entityType); + + customField.EntityID = entityid; + customField.Value = fieldValue; + + DaoFactory.GetCustomFieldDao().SetFieldValue(entityTypeStr, entityid, fieldid, fieldValue); + + return ToCustomFieldBaseWrapper(customField); + } + + /// + /// Creates a new user field with the parameters (entity type, field title, type, etc.) specified in the request + /// + /// Entity type + /// Field title + /// + /// User field value + /// + /// Field position + /// Mask + /// Create user field + /// User fields + /// + /// User field + /// + /// + /// + /// + [Create(@"{entityType:(contact|person|company|opportunity|case)}/customfield")] + public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label, int fieldType, int position, string mask) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + var entityTypeObj = ToEntityType(entityType); + var fieldID = DaoFactory.GetCustomFieldDao().CreateField(entityTypeObj, label, (CustomFieldType)fieldType, mask); + var wrapper = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID); + + var messageAction = GetCustomFieldCreatedAction(entityTypeObj); + MessageService.Send( messageAction, MessageTarget.Create(wrapper.ID), wrapper.Label); + + return ToCustomFieldWrapper(DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); + } + + /// + /// Updates the selected user field with the parameters (entity type, field title, type, etc.) specified in the request + /// + /// User field id + /// Entity type + /// Field title + /// + /// User field value + /// + /// Field position + /// Mask + /// Updates the selected user field + /// User fields + /// + /// User field + /// + /// + /// + /// + /// + /// + [Update(@"{entityType:(contact|person|company|opportunity|case)}/customfield/{id:int}")] + public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, string label, int fieldType, int position, string mask) + { + if (id <= 0) throw new ArgumentException(); + if (!DaoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException(); + + var entityTypeObj = ToEntityType(entityType); + + var customField = new CustomField + { + EntityType = entityTypeObj, + FieldType = (CustomFieldType)fieldType, + ID = id, + Mask = mask, + Label = label, + Position = position + }; + + DaoFactory.GetCustomFieldDao().EditItem(customField); + + customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(id); + + var messageAction = GetCustomFieldUpdatedAction(entityTypeObj); + MessageService.Send( messageAction, MessageTarget.Create(customField.ID), customField.Label); + + return ToCustomFieldWrapper(customField); + } + + /// + /// Deletes the user field with the ID specified in the request + /// + /// Type + /// Field ID + /// Delete user field + /// User fields + /// + /// + /// + /// User field + /// + [Delete(@"{entityType:(contact|person|company|opportunity|case)}/customfield/{fieldid:int}")] + public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (fieldid <= 0) throw new ArgumentException(); + + var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); + if (customField == null) throw new ItemNotFoundException(); + + var result = ToCustomFieldWrapper(customField); + DaoFactory.GetCustomFieldDao().DeleteField(fieldid); + + FactoryIndexer.DeleteAsync(customField); + + var messageAction = GetCustomFieldDeletedAction(ToEntityType(entityType)); + MessageService.Send( messageAction, MessageTarget.Create(customField.ID), result.Label); + + return result; + } + + /// + /// Updates user fields order + /// + /// User field ID list + /// Entity type + /// User fields + /// + /// User fields + /// + /// + /// + /// + [Update(@"{entityType:(contact|person|company|opportunity|case)}/customfield/reorder")] + public IEnumerable UpdateCustomFieldsOrder(IEnumerable fieldids, string entityType) + { + if (fieldids == null) throw new ArgumentException(); + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + var customFields = new List(); + foreach (var id in fieldids) + { + if (!DaoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException(); + customFields.Add(DaoFactory.GetCustomFieldDao().GetFieldDescription(id)); + } + + DaoFactory.GetCustomFieldDao().ReorderFields(fieldids.ToArray()); + + var messageAction = GetCustomFieldsUpdatedOrderAction(ToEntityType(entityType)); + MessageService.Send( messageAction, MessageTarget.Create(fieldids), customFields.Select(x => x.Label)); + + return customFields.Select(ToCustomFieldBaseWrapper); + } + + private static CustomFieldBaseWrapper ToCustomFieldBaseWrapper(CustomField customField) + { + return new CustomFieldBaseWrapper(customField); + } + + private CustomFieldWrapper ToCustomFieldWrapper(CustomField customField) + { + var result = new CustomFieldWrapper(customField) + { + RelativeItemsCount = DaoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID) + }; + return result; + } + + private static MessageAction GetCustomFieldCreatedAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Contact: + return MessageAction.ContactUserFieldCreated; + case EntityType.Person: + return MessageAction.PersonUserFieldCreated; + case EntityType.Company: + return MessageAction.CompanyUserFieldCreated; + case EntityType.Opportunity: + return MessageAction.OpportunityUserFieldCreated; + case EntityType.Case: + return MessageAction.CaseUserFieldCreated; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private static MessageAction GetCustomFieldUpdatedAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Contact: + return MessageAction.ContactUserFieldUpdated; + case EntityType.Person: + return MessageAction.PersonUserFieldUpdated; + case EntityType.Company: + return MessageAction.CompanyUserFieldUpdated; + case EntityType.Opportunity: + return MessageAction.OpportunityUserFieldUpdated; + case EntityType.Case: + return MessageAction.CaseUserFieldUpdated; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private static MessageAction GetCustomFieldDeletedAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Contact: + return MessageAction.ContactUserFieldDeleted; + case EntityType.Person: + return MessageAction.PersonUserFieldDeleted; + case EntityType.Company: + return MessageAction.CompanyUserFieldDeleted; + case EntityType.Opportunity: + return MessageAction.OpportunityUserFieldDeleted; + case EntityType.Case: + return MessageAction.CaseUserFieldDeleted; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private static MessageAction GetCustomFieldsUpdatedOrderAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Contact: + return MessageAction.ContactUserFieldsUpdatedOrder; + case EntityType.Person: + return MessageAction.PersonUserFieldsUpdatedOrder; + case EntityType.Company: + return MessageAction.CompanyUserFieldsUpdatedOrder; + case EntityType.Opportunity: + return MessageAction.OpportunityUserFieldsUpdatedOrder; + case EntityType.Case: + return MessageAction.CaseUserFieldsUpdatedOrder; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs new file mode 100644 index 00000000000..e1d5b0b8e2b --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs @@ -0,0 +1,969 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Collections; +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.MessagingSystem; +using ASC.Web.Api.Models; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using ASC.Web.Files.Services.WCFService; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the detailed information about the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// + /// Opportunity + /// + /// Get opportunity by ID + /// Opportunities + /// + /// + [Read(@"opportunity/{opportunityid:int}")] + public OpportunityWrapper GetDealByID(int opportunityid) + { + if (opportunityid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); + + return ToOpportunityWrapper(deal); + } + + /// + /// Updates the selected opportunity to the stage with the ID specified in the request + /// + /// Opportunity ID + /// Opportunity stage ID + /// + /// Opportunity + /// + /// Update opportunity stage + /// Opportunities + /// + /// + [Update(@"opportunity/{opportunityid:int}/stage/{id:int}")] + public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) + { + if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null || !CRMSecurity.CanEdit(deal)) throw new ItemNotFoundException(); + + var stage = DaoFactory.GetDealMilestoneDao().GetByID(stageid); + if (stage == null) throw new ItemNotFoundException(); + + deal.DealMilestoneID = stageid; + deal.DealMilestoneProbability = stage.Probability; + + deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue; + DaoFactory.GetDealDao().EditDeal(deal); + MessageService.Send( MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); + + return ToOpportunityWrapper(deal); + } + + /// + /// Sets access rights for the selected opportunity with the parameters specified in the request + /// + /// Opportunity ID + /// Opportunity privacy: private or not + /// List of users with access + /// Set rights to opportunity + /// Opportunities + /// + /// + /// + /// Opportunity + /// + [Update(@"opportunity/{opportunityid:int}/access")] + public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) + { + if (opportunityid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + return SetAccessToDeal(deal, isPrivate, accessList, false, true); + } + + private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) + { + var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); + if (isPrivate && accessListLocal.Count > 0) + { + + if (isNotify) + { + accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); + NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, DaoFactory, accessListLocal.ToArray()); + } + + if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) + { + accessListLocal.Add(SecurityContext.CurrentAccount.ID); + } + + CRMSecurity.SetAccessTo(deal, accessListLocal); + + if (isMessageServicSende) + { + var users = GetUsersByIdList(accessListLocal); + MessageService.Send( MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false))); + } + } + else + { + CRMSecurity.MakePublic(deal); + if (isMessageServicSende) + { + MessageService.Send( MessageAction.OpportunityOpenedAccess, MessageTarget.Create(deal.ID), deal.Title); + } + } + + return ToOpportunityWrapper(deal); + } + + /// + /// Sets access rights for other users to the list of all opportunities matching the parameters specified in the request + /// + /// Opportunity responsible + /// Opportunity stage ID + /// Tags + /// Contact ID + /// Participation status: take into account opportunities where the contact is a participant or not + /// Start date + /// End date + /// Opportunity stage type + /// Opportunity privacy: private or not + /// List of users with access + /// Set opportunity access rights + /// Opportunities + /// + /// + /// + /// Opportunity list + /// + [Update(@"opportunity/filter/access")] + public IEnumerable SetAccessToBatchDeal( + Guid responsibleid, + int opportunityStagesid, + IEnumerable tags, + int contactid, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + ApiDateTime fromDate, + ApiDateTime toDate, + bool isPrivate, + IEnumerable accessList + ) + { + var result = new List(); + var deals = DaoFactory.GetDealDao() + .GetDeals(ApiContext.FilterValue, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, toDate, 0, 0, null); + if (!deals.Any()) return Enumerable.Empty(); + + foreach (var deal in deals) + { + if (deal == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToDeal(deal.ID, isPrivate, accessList); + result.Add(deal); + } + + return ToListOpportunityWrapper(result); + } + + /// + /// Sets access rights for other users to the list of opportunities with the IDs specified in the request + /// + /// Opportunity ID list + /// Opportunity privacy: private or not + /// List of users with access + /// Set opportunity access rights + /// Opportunities + /// + /// + /// + /// Opportunity list + /// + [Update(@"opportunity/access")] + public IEnumerable SetAccessToBatchDeal(IEnumerable opportunityid, bool isPrivate, IEnumerable accessList) + { + if(opportunityid == null) throw new ArgumentException(); + + var result = new List(); + + var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); + + if (!deals.Any()) return new List(); + + foreach (var d in deals) + { + if (d == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToDeal(d, isPrivate, accessList, false, true); + result.Add(d); + } + + return ToListOpportunityWrapper(result); + } + + + /// + /// Deletes the group of opportunities with the IDs specified in the request + /// + /// Opportunity ID list + /// + /// + /// Delete opportunity group + /// Opportunities + /// + /// Opportunity list + /// + [Update(@"opportunity")] + public IEnumerable DeleteBatchDeals(IEnumerable opportunityids) + { + if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); + + var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); + MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); + + return ToListOpportunityWrapper(opportunities); + } + + /// + /// Deletes the list of all opportunities matching the parameters specified in the request + /// + /// Opportunity responsible + /// Opportunity stage ID + /// Tags + /// Contact ID + /// Participation status: take into account opportunities where the contact is a participant or not + /// Start date + /// End date + /// Opportunity stage type + /// + /// + /// Delete opportunity group + /// Opportunities + /// + /// Opportunity list + /// + [Delete(@"opportunity/filter")] + public IEnumerable DeleteBatchDeals( + Guid responsibleid, + int opportunityStagesid, + IEnumerable tags, + int contactid, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + ApiDateTime fromDate, + ApiDateTime toDate) + { + var deals = DaoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, toDate, 0, 0, null); + + if (!deals.Any()) return Enumerable.Empty(); + + deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals); + MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); + + return ToListOpportunityWrapper(deals); + } + + /// + /// Returns the list of all opportunities matching the parameters specified in the request + /// + /// Opportunity responsible + /// Opportunity stage ID + /// Tags + /// Contact ID + /// Participation status: take into account opportunities where the contact is a participant or not + /// Start date + /// End date + /// Opportunity stage type + /// Get opportunity list + /// Opportunities + /// + /// Opportunity list + /// + [Read(@"opportunity/filter")] + public IEnumerable GetDeals( + Guid responsibleid, + int opportunityStagesid, + IEnumerable tags, + int contactid, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + ApiDateTime fromDate, + ApiDateTime toDate) + { + DealSortedByType dealSortedByType; + + IEnumerable result; + + var searchString = ApiContext.FilterValue; + + OrderBy dealsOrderBy; + + if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) + { + dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending); + } + else if (string.IsNullOrEmpty(ApiContext.SortBy)) + { + dealsOrderBy = new OrderBy(DealSortedByType.Stage, true); + } + else + { + dealsOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (dealsOrderBy != null) + { + result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( + searchString, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate, + fromIndex, + count, + dealsOrderBy)).ToList(); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( + searchString, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate, + 0, 0, null)).ToList(); + } + + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory + .DealDao + .GetDealsCount(searchString, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate); + } + + ApiContext.SetTotalCount(totalCount); + + return result.ToSmartList(); + } + + /// + /// Deletes the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Delete opportunity + /// Opportunities + /// + /// + /// + /// Opportunity + /// + [Delete(@"opportunity/{opportunityid:int}")] + public OpportunityWrapper DeleteDeal(int opportunityid) + { + if (opportunityid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().DeleteDeal(opportunityid); + if (deal == null) throw new ItemNotFoundException(); + + MessageService.Send( MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); + + return ToOpportunityWrapper(deal); + } + + /// + /// Creates the opportunity with the parameters specified in the request + /// + /// Create opportunity + /// Opportunity primary contact + /// Participants + /// Opportunity title + /// Opportunity description + /// Opportunity responsible + /// Bid + /// Amount of transaction + /// Currency (Abbreviation) + /// Period + /// Stage ID + /// Opportunity success probability + /// Actual opportunity closure date + /// Expected opportunity closure date + /// User field list + /// Opportunity privacy: private or not + /// List of users with access to the opportunity + /// Notify users in accessList about the opportunity + /// Opportunities + /// + /// Opportunity + /// + /// + [Create(@"opportunity")] + public OpportunityWrapper CreateDeal( + int contactid, + IEnumerable members, + string title, + string description, + Guid responsibleid, + BidType bidType, + decimal bidValue, + string bidCurrencyAbbr, + int perPeriodValue, + int stageid, + int successProbability, + ApiDateTime actualCloseDate, + ApiDateTime expectedCloseDate, + IEnumerable> customFieldList, + bool isPrivate, + IEnumerable accessList, + bool isNotify) + { + var deal = new Deal + { + Title = title, + Description = description, + ResponsibleID = responsibleid, + BidType = bidType, + BidValue = bidValue, + PerPeriodValue = perPeriodValue, + DealMilestoneID = stageid, + DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability), + ContactID = contactid, + ActualCloseDate = actualCloseDate, + ExpectedCloseDate = expectedCloseDate, + BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null, + }; + + CRMSecurity.DemandCreateOrUpdate(deal); + + deal.ID = DaoFactory.GetDealDao().CreateNewDeal(deal); + + deal.CreateBy = SecurityContext.CurrentAccount.ID; + deal.CreateOn = DateTime.UtcNow; + + SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); + + var membersList = members != null ? members.ToList() : new List(); + + if (deal.ContactID > 0) + membersList.Add(deal.ContactID); + + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); + } + } + + return ToOpportunityWrapper(deal); + } + + /// + /// Updates the selected opportunity with the parameters specified in the request + /// + /// Update opportunity + ///Opportunity ID + ///Opportunity primary contact + /// Participants + /// Opportunity title + /// Opportunity description + /// Opportunity responsible + /// Bid + /// Amount of transaction + /// Currency (Abbreviation) + /// Period + /// Stage ID + /// Opportunity success probability + /// Actual opportunity closure date + /// Expected opportunity closure date + /// User field list + /// Opportunity privacy: private or not + /// List of users with access to the opportunity + /// Notify users in accessList about the opportunity + /// Opportunities + /// + /// Opportunity + /// + /// + [Update(@"opportunity/{opportunityid:int}")] + public OpportunityWrapper UpdateDeal( + int opportunityid, + int contactid, + IEnumerable members, + string title, + string description, + Guid responsibleid, + BidType bidType, + decimal bidValue, + string bidCurrencyAbbr, + int perPeriodValue, + int stageid, + int successProbability, + ApiDateTime actualCloseDate, + ApiDateTime expectedCloseDate, + IEnumerable> customFieldList, + bool isPrivate, + IEnumerable accessList, + bool isNotify) + { + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null) throw new ItemNotFoundException(); + + deal.Title = title; + deal.Description = description; + deal.ResponsibleID = responsibleid; + deal.BidType = bidType; + deal.BidValue = bidValue; + deal.PerPeriodValue = perPeriodValue; + deal.DealMilestoneID = stageid; + deal.DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability); + deal.ContactID = contactid; + deal.ActualCloseDate = actualCloseDate; + deal.ExpectedCloseDate = expectedCloseDate; + deal.BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null; + + CRMSecurity.DemandCreateOrUpdate(deal); + + DaoFactory.GetDealDao().EditDeal(deal); + + deal = DaoFactory.GetDealDao().GetByID(opportunityid); + + var membersList = members != null ? members.ToList() : new List(); + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + + DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); + } + + + if (CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) + { + SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); + } + } + + return ToOpportunityWrapper(deal); + } + + /// + /// Returns the list of all contacts associated with the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Get all opportunity contacts + /// Opportunities + /// Contact list + /// + /// + [Read(@"opportunity/{opportunityid:int}/contact")] + public IEnumerable GetDealMembers(int opportunityid) + { + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); + if (contactIDs == null) return new ItemList(); + + var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); + + result.ForEach(item => { if (item.ID == opportunity.ContactID) item.CanEdit = false; }); + + return result; + } + + /// + /// Adds the selected contact to the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Contact ID + /// Add opportunity contact + /// Opportunities + /// + /// + /// Participant + /// + [Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] + public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) + { + if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); + + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var result = ToContactWrapper(contact); + + DaoFactory.GetDealDao().AddMember(opportunityid, contactid); + + var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; + MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + + return result; + } + + /// + /// Deletes the selected contact from the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Contact ID + /// Delete opportunity contact + /// Opportunities + /// + /// + /// + /// Participant + /// + [Delete(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] + public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) + { + if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var result = ToContactWrapper(contact); + + DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); + + var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson; + MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + + return result; + } + + /// + /// Returns the list of 30 opportunities in the CRM module with prefix + /// + /// + /// + /// + /// Opportunities + /// + /// Opportunities list + /// + /// false + [Read(@"opportunity/byprefix")] + public IEnumerable GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true) + { + var result = new List(); + + if (contactID > 0 && internalSearch) + { + var findedDeals = DaoFactory.GetDealDao().GetDealsByContactID(contactID); + foreach (var item in findedDeals) + { + if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) + { + result.Add(ToOpportunityWrapper(item)); + } + } + + ApiContext.SetTotalCount(result.Count); + } + else + { + const int maxItemCount = 30; + var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); + foreach (var item in findedDeals) + { + result.Add(ToOpportunityWrapper(item)); + } + } + + return result; + } + + /// + /// Returns the list of all contact opportunities + /// + /// Contact ID + /// Get opportunity list + /// Opportunities + /// + /// Opportunity list + /// + [Read(@"opportunity/bycontact/{contactid:int}")] + public IEnumerable GetDeals(int contactid) + { + var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid); + return ToListOpportunityWrapper(deals); + } + + /// false + [Update(@"opportunity/{opportunityid:int}/creationdate")] + public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate) + { + var dao = DaoFactory.GetDealDao(); + var opportunity = dao.GetByID(opportunityid); + + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) + throw new ItemNotFoundException(); + + dao.SetDealCreationDate(opportunityid, creationDate); + } + + /// false + [Update(@"opportunity/{opportunityid:int}/lastmodifeddate")] + public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDate) + { + var dao = DaoFactory.GetDealDao(); + var opportunity = dao.GetByID(opportunityid); + + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) + throw new ItemNotFoundException(); + + dao.SetDealLastModifedDate(opportunityid, lastModifedDate); + } + + + private IEnumerable ToListOpportunityWrapper(ICollection deals) + { + if (deals == null || deals.Count == 0) return new List(); + + var result = new List(); + + var contactIDs = new List(); + var dealIDs = new List(); + var dealMilestoneIDs = new List(); + + foreach (var deal in deals) + { + contactIDs.Add(deal.ContactID); + dealIDs.Add(deal.ID); + dealMilestoneIDs.Add(deal.DealMilestoneID); + } + + dealMilestoneIDs = dealMilestoneIDs.Distinct().ToList(); + + var contacts = new Dictionary(); + + var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) + .GroupBy(item => item.EntityID) + .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + + var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) + .ToDictionary(item => item.ID, item => new DealMilestoneBaseWrapper(item)); + + + var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); + + foreach (var value in dealMembers.Values) + { + contactIDs.AddRange(value); + } + + contactIDs = contactIDs.Distinct().ToList(); + + if (contactIDs.Count > 0) + { + DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item => + { + if (item == null) return; + contacts.Add(item.ID, ToContactBaseWrapper(item)); + }); + } + + foreach (var deal in deals) + { + var dealWrapper = new OpportunityWrapper(deal); + + if (contacts.ContainsKey(deal.ContactID)) + { + dealWrapper.Contact = contacts[deal.ContactID]; + } + + dealWrapper.CustomFields = customFields.ContainsKey(deal.ID) + ? customFields[deal.ID] + : new List(); + + dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.ID) + ? dealMembers[dealWrapper.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) + : new List(); + + if (dealMilestones.ContainsKey(deal.DealMilestoneID)) + { + dealWrapper.Stage = dealMilestones[deal.DealMilestoneID]; + } + + dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); + + if (dealWrapper.IsPrivate) + { + dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraper.Get(item.Key)).ToItemList(); + } + + if (!string.IsNullOrEmpty(deal.BidCurrency)) + { + dealWrapper.BidCurrency = ToCurrencyInfoWrapper(CurrencyProvider.Get(deal.BidCurrency)); + } + + result.Add(dealWrapper); + } + + return result; + } + + private OpportunityWrapper ToOpportunityWrapper(Deal deal) + { + var dealWrapper = new OpportunityWrapper(deal); + + if (deal.ContactID > 0) + dealWrapper.Contact = ToContactBaseWrapper(DaoFactory.GetContactDao().GetByID(deal.ContactID)); + + if (deal.DealMilestoneID > 0) + { + var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); + + if (dealMilestone == null) + throw new ItemNotFoundException(); + + dealWrapper.Stage = new DealMilestoneBaseWrapper(dealMilestone); + } + + dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal) + .Select(item => EmployeeWraper.Get(item.Key)).ToItemList(); + + dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); + + if (!string.IsNullOrEmpty(deal.BidCurrency)) + dealWrapper.BidCurrency = ToCurrencyInfoWrapper(CurrencyProvider.Get(deal.BidCurrency)); + + dealWrapper.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); + + dealWrapper.Members = new List(); + + var memberIDs = DaoFactory.GetDealDao().GetMembers(deal.ID); + var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); + var membersWrapperList = new List(); + + foreach (var member in membersList) + { + if (member == null) continue; + membersWrapperList.Add(ToContactBaseWrapper(member)); + } + + dealWrapper.Members = membersWrapperList; + + return dealWrapper; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs new file mode 100644 index 00000000000..1a39a4feb12 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs @@ -0,0 +1,1509 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the detailed information about the invoice with the ID specified in the request + /// + /// Invoice ID + /// Get invoice by ID + /// Invoices + /// Invoice + [Read(@"invoice/{invoiceid:int}")] + public InvoiceWrapper GetInvoiceByID(int invoiceid) + { + if (invoiceid <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) { + throw CRMSecurity.CreateSecurityException(); + } + + return ToInvoiceWrapper(invoice); + } + + /// + /// Returns the detailed information about the invoice sample + /// + /// Get invoice sample + /// Invoices + /// Invoice + [Read(@"invoice/sample")] + public InvoiceWrapper GetInvoiceSample() + { + var sample = InvoiceWrapper.GetSample(); + sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); + sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; + + sample.IssueDate = (ApiDateTime)DateTime.UtcNow; + sample.DueDate = (ApiDateTime)DateTime.UtcNow.AddDays(30); + sample.CreateOn = (ApiDateTime)DateTime.UtcNow; + + sample.Currency = new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); + + sample.InvoiceLines.First().Quantity = 1; + + return sample; + } + + /// + /// Returns the json data of the invoice with the ID specified in the request + /// + /// Invoice ID + /// Get invoice json data + /// Invoices + /// Json Data + [Read(@"invoice/jsondata/{invoiceid:int}")] + public string GetInvoiceJsonData(int invoiceid) + { + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) { + throw CRMSecurity.CreateSecurityException(); + } + + return invoice.JsonData; + } + + /// + /// Returns the list of invoices matching the creteria specified in the request + /// + /// Invoice status + /// Invoice issue date from + /// Invoice issue date to + /// Invoice due date from + /// Invoice due date to + /// Invoice entity type + /// Invoice entity ID + /// Invoice currency + /// Get invoice list + /// Invoices + /// Invoice list + [Read(@"invoice/filter")] + public IEnumerable GetInvoices( + InvoiceStatus? status, + ApiDateTime issueDateFrom, + ApiDateTime issueDateTo, + ApiDateTime dueDateFrom, + ApiDateTime dueDateTo, + String entityType, + int entityid, + String currency + ) + { + if (!String.IsNullOrEmpty(entityType) && !( + String.Compare(entityType, "contact", true) == 0 || + String.Compare(entityType, "opportunity", true) == 0 || + String.Compare(entityType, "case", true) == 0)) + throw new ArgumentException(); + + IEnumerable result; + + InvoiceSortedByType sortBy; + + OrderBy invoiceOrderBy; + + var searchString = ApiContext.FilterValue; + + if (InvoiceSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) + { + invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (String.IsNullOrEmpty(ApiContext.SortBy)) + { + invoiceOrderBy = new OrderBy(InvoiceSortedByType.Number, true); + } + else + { + invoiceOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (invoiceOrderBy != null) + { + result = ToListInvoiceBaseWrappers( + DaoFactory.GetInvoiceDao().GetInvoices( + searchString, + status, + issueDateFrom, issueDateTo, + dueDateFrom, dueDateTo, + ToEntityType(entityType), entityid, + currency, + fromIndex, count, + invoiceOrderBy)); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListInvoiceBaseWrappers( + DaoFactory.GetInvoiceDao().GetInvoices( + searchString, + status, + issueDateFrom, issueDateTo, + dueDateFrom, dueDateTo, + ToEntityType(entityType), entityid, + currency, + 0, + 0, + null)); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetInvoiceDao().GetInvoicesCount( + searchString, + status, + issueDateFrom, issueDateTo, + dueDateFrom, dueDateTo, + ToEntityType(entityType), entityid, + currency); + } + + ApiContext.SetTotalCount(totalCount); + + return result.ToSmartList(); + } + + /// + /// Returns the list of all invoices associated with the entity with the ID and type specified in the request + /// + /// Invoice entity type + /// Invoice entity ID + /// Get entity invoices + /// Invoices + /// Invoice list + [Read(@"{entityType:(contact|person|company|opportunity)}/invoicelist/{entityid:int}")] + public IEnumerable GetEntityInvoices(String entityType, int entityid) + { + if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); + + return ToListInvoiceBaseWrappers(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); + } + + /// + /// Updates the status of invoices with the IDs specified in the request + /// + /// Invoice ID list + /// Status + /// Update invoice group status + /// Invoices + /// KeyValuePair of Invoices and InvoiceItems + [Update(@"invoice/status/{status:[\w\d-]+}")] + public KeyValuePair,IEnumerable> UpdateInvoiceBatchStatus( + int[] invoiceids, + InvoiceStatus status + ) + { + if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); + + var oldInvoices = DaoFactory.GetInvoiceDao().GetByID(invoiceids).Where(CRMSecurity.CanAccessTo).ToList(); + + var updatedInvoices = DaoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status); + + // detect what really changed + var realUpdatedInvoices = updatedInvoices + .Select(t => oldInvoices.FirstOrDefault(x => x.ID == t.ID && x.Status != t.Status)) + .Where(inv => inv != null) + .ToList(); + + if (realUpdatedInvoices.Any()) + { + MessageService.Send( MessageAction.InvoicesUpdatedStatus, MessageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString()); + } + + var invoiceItemsUpdated = new List(); + + if (status == InvoiceStatus.Sent || status == InvoiceStatus.Rejected) + { + var invoiceItemsAll = DaoFactory.GetInvoiceItemDao().GetAll(); + var invoiceItemsWithTrackInventory = invoiceItemsAll.Where(item => item.TrackInventory).ToList(); + + if (status == InvoiceStatus.Sent && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) + { + foreach (var inv in updatedInvoices) + { + if (inv.Status == InvoiceStatus.Sent) + { + //could be changed + var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); + if (oldInv != null && oldInv.Status == InvoiceStatus.Draft) + { + //was changed to Sent + var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + + foreach (var line in invoiceLines) + { + var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); + if (item != null) + { + item.StockQuantity -= line.Quantity; + DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); + var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); + if (oldItem != null) + { + invoiceItemsUpdated.Remove(oldItem); + } + invoiceItemsUpdated.Add(item); + } + } + } + } + } + } + + if (status == InvoiceStatus.Rejected && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) + { + foreach (var inv in updatedInvoices) + { + if (inv.Status == InvoiceStatus.Rejected) + { + //could be changed + var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); + if (oldInv != null && oldInv.Status == InvoiceStatus.Sent) + { + //was changed from Sent to Rejectes + var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + + foreach (var line in invoiceLines) + { + var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); + if (item != null) + { + item.StockQuantity += line.Quantity; + DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); + var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); + if (oldItem != null) + { + invoiceItemsUpdated.Remove(oldItem); + } + invoiceItemsUpdated.Add(item); + } + } + } + } + } + } + } + + var listInvoiceBaseWrappers = ToListInvoiceBaseWrappers(updatedInvoices); + + return new KeyValuePair,IEnumerable>(listInvoiceBaseWrappers,invoiceItemsUpdated.ConvertAll(i => ToInvoiceItemWrapper(i))); + } + + /// + /// Delete the invoice with the ID specified in the request + /// + /// Invoice ID + /// Delete invoice + /// Invoices + /// Invoice + [Delete(@"invoice/{invoiceid:int}")] + public InvoiceBaseWrapper DeleteInvoice(int invoiceid) + { + if (invoiceid <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + MessageService.Send( MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); + return ToInvoiceBaseWrapper(invoice); + } + + /// + /// Deletes the group of invoices with the IDs specified in the request + /// + /// Invoice ID list + /// Delete invoice group + /// Invoices + /// Invoice list + [Delete(@"invoice")] + public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids) + { + if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); + + var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); + MessageService.Send( MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); + + return ToListInvoiceBaseWrappers(invoices); + } + + /// + /// Creates the invoice with the parameters (contactId, consigneeId, etc.) specified in the request + /// + /// Invoice number + /// Invoice issue date + /// Invoice template type + /// Invoice contact ID + /// Invoice consignee ID + /// Invoice entity ID + /// Invoice billing address ID + /// Invoice delivery address ID + /// Invoice due date + /// Invoice language + /// Invoice currency + /// Invoice exchange rate + /// Invoice purchase order number + /// Invoice terms + /// Invoice description + /// Invoice lines list + /// Create invoice + /// Invoices + /// Invoice + /// + /// + /// + [Create(@"invoice")] + public InvoiceWrapper CreateInvoice( + string number, + ApiDateTime issueDate, + int templateType, + int contactId, + int consigneeId, + int entityId, + int billingAddressID, + int deliveryAddressID, + ApiDateTime dueDate, + string language, + string currency, + decimal exchangeRate, + string purchaseOrderNumber, + string terms, + string description, + IEnumerable invoiceLines + ) + { + var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); + if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); + + var invoice = new Invoice + { + Status = InvoiceStatus.Draft, + Number = number, + IssueDate = issueDate, + TemplateType = (InvoiceTemplateType)templateType, + ContactID = contactId, + ConsigneeID = consigneeId, + EntityType = EntityType.Opportunity, + EntityID = entityId, + DueDate = dueDate, + Language = language, + Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null, + ExchangeRate = exchangeRate, + PurchaseOrderNumber = purchaseOrderNumber, + Terms = terms, + Description = description + }; + + CRMSecurity.DemandCreateOrUpdate(invoice); + + if (billingAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) + throw new ArgumentException(); + } + + if (deliveryAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) + throw new ArgumentException(); + } + + + invoice.ID = DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + + CreateInvoiceLines(invoiceLinesList, invoice); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + return ToInvoiceWrapper(invoice); + } + + + private bool IsLinesForInvoiceCorrect(List invoiceLines) + { + foreach (var line in invoiceLines) + { + if (line.InvoiceItemID <= 0 || + line.Quantity < 0 || line.Price < 0 || + line.Discount < 0 || line.Discount > 100 || + line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0) + return false; + if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) + return false; + + if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) + return false; + + if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) + return false; + } + return true; + } + + private List CreateInvoiceLines(List invoiceLines, Invoice invoice) + { + var result = new List(); + for (var i = 0; i < invoiceLines.Count; i++) + { + var line = new InvoiceLine + { + ID = 0, + InvoiceID = invoice.ID, + InvoiceItemID = invoiceLines[i].InvoiceItemID, + InvoiceTax1ID = invoiceLines[i].InvoiceTax1ID, + InvoiceTax2ID = invoiceLines[i].InvoiceTax2ID, + SortOrder = i, + Description = invoiceLines[i].Description, + Quantity = invoiceLines[i].Quantity, + Price = invoiceLines[i].Price, + Discount = Convert.ToInt32(invoiceLines[i].Discount) + }; + + line.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line); + result.Add(line); + } + return result; + } + + /// + /// Updates the selected invoice with the parameters (contactId, consigneeId, etc.) specified in the request + /// + /// Invoice ID + /// Invoice issue date + /// Invoice template type + /// Invoice contact ID + /// Invoice consignee ID + /// Invoice entity ID + /// Invoice billing address ID + /// Invoice delivery address ID + /// Invoice due date + /// Invoice language + /// Invoice currency + /// Invoice exchange rate + /// Invoice purchase order number + /// Invoice terms + /// Invoice description + /// Invoice lines list + /// Update invoice + /// Invoices + /// Invoice + /// + /// + /// + [Update(@"invoice/{id:int}")] + public InvoiceWrapper UpdateInvoice( + int id, + ApiDateTime issueDate, + int templateType, + int contactId, + int consigneeId, + int entityId, + int billingAddressID, + int deliveryAddressID, + ApiDateTime dueDate, + string language, + string currency, + decimal exchangeRate, + string purchaseOrderNumber, + string terms, + string description, + IEnumerable invoiceLines) + { + + var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); + if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(id); + if (invoice == null || !CRMSecurity.CanEdit(invoice)) throw new ItemNotFoundException(); + + invoice.IssueDate = issueDate; + invoice.TemplateType = (InvoiceTemplateType)templateType; + invoice.ContactID = contactId; + invoice.ConsigneeID = consigneeId; + invoice.EntityType = EntityType.Opportunity; + invoice.EntityID = entityId; + invoice.DueDate = dueDate; + invoice.Language = language; + invoice.Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null;; + invoice.ExchangeRate = exchangeRate; + invoice.PurchaseOrderNumber = purchaseOrderNumber; + invoice.Terms = terms; + invoice.Description = description; + invoice.JsonData = null; + + CRMSecurity.DemandCreateOrUpdate(invoice); + + if (billingAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) + throw new ArgumentException(); + } + + if (deliveryAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) + throw new ArgumentException(); + } + + DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + + + DaoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID); + CreateInvoiceLines(invoiceLinesList, invoice); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + + if (Global.CanDownloadInvoices) + { + PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return ToInvoiceWrapper(invoice); + } + + /// + /// Returns the pdf file associated with the invoice with the ID specified in the request + /// + /// Invoice ID + /// Get invoice pdf file + /// Invoices + /// File + [Read(@"invoice/{invoiceid:int}/pdf")] + public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) + { + if (invoiceid <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) { + throw CRMSecurity.CreateSecurityException(); + } + + return new FileWrapper(Global.GetInvoicePdfExistingOrCreate(invoice, DaoFactory)); + } + + /// + /// Returns information about the generation of the pdf file of the invoice + /// + /// Invoice ID + /// Storage Url + /// Revision ID + /// Check invoice pdf file + /// Invoices + /// ConverterData + [Create(@"invoice/converter/data")] + public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, string revisionId) + { + if (invoiceId <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) { + throw CRMSecurity.CreateSecurityException(); + } + + var converterData = new ConverterData + { + StorageUrl = storageUrl, + RevisionId = revisionId, + InvoiceId = invoiceId + }; + + var existingFile = invoice.GetInvoiceFile(DaoFactory); + if (existingFile != null) + { + converterData.FileId = invoice.FileID; + return converterData; + } + + if (string.IsNullOrEmpty(storageUrl) || string.IsNullOrEmpty(revisionId)) + { + return PdfCreator.StartCreationFileAsync(invoice); + } + else + { + var convertedFile = PdfCreator.GetConvertedFile(converterData, DaoFactory); + if (convertedFile != null) + { + invoice.FileID = Int32.Parse(convertedFile.ID.ToString()); + DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + + converterData.FileId = invoice.FileID; + return converterData; + } + else + { + return converterData; + } + } + } + + /// + /// Returns the existence of the invoice with the Number specified in the request + /// + /// Invoice number + /// Check invoice existence by number + /// Invoices + /// IsExist + [Read(@"invoice/bynumber/exist")] + public Boolean GetInvoiceByNumberExistence(string number) + { + if (String.IsNullOrEmpty(number)) throw new ArgumentException(); + return DaoFactory.GetInvoiceDao().IsExist(number); + } + + /// + /// Returns the detailed information about the invoice with the Number specified in the request + /// + /// Invoice number + /// Get invoice by number + /// Invoices + /// Invoice + [Read(@"invoice/bynumber")] + public InvoiceWrapper GetInvoiceByNumber(string number) + { + if (String.IsNullOrEmpty(number)) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number); + if (invoice == null) throw new ItemNotFoundException(); + if (!CRMSecurity.CanAccessTo(invoice)) { + throw CRMSecurity.CreateSecurityException(); + } + + return new InvoiceWrapper(invoice); + } + + /// + /// Returns the list of invoice items matching the creteria specified in the request + /// + /// Status + /// InventoryStock + /// Get invoice item list + /// Invoices + /// InvoiceItem list + [Read(@"invoiceitem/filter")] + public IEnumerable GetInvoiceItems(int status, bool? inventoryStock) + { + IEnumerable result; + + InvoiceItemSortedByType sortBy; + + OrderBy invoiceOrderBy; + + var searchString = ApiContext.FilterValue; + + if (InvoiceItemSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) + { + invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (String.IsNullOrEmpty(ApiContext.SortBy)) + { + invoiceOrderBy = new OrderBy(InvoiceItemSortedByType.Name, true); + } + else + { + invoiceOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (invoiceOrderBy != null) + { + result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( + searchString, + status, + inventoryStock, + fromIndex, count, + invoiceOrderBy) + .ConvertAll(ToInvoiceItemWrapper); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( + searchString, + status, + inventoryStock, + 0, 0, + null) + .ConvertAll(ToInvoiceItemWrapper); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetInvoiceItemDao().GetInvoiceItemsCount( + searchString, + status, + inventoryStock); + } + + ApiContext.SetTotalCount(totalCount); + + return result.ToSmartList(); + } + + /// + /// Returns the detailed information about the invoice item with the ID specified in the request + /// + /// Invoice Item ID + /// Get invoice item by ID + /// Invoices + /// Invoice Item + [Read(@"invoiceitem/{invoiceitemid:int}")] + public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) + { + if (invoiceitemid <= 0) throw new ArgumentException(); + + var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); + if (invoiceItem == null) throw new ItemNotFoundException(); + + return ToInvoiceItemWrapper(invoiceItem); + } + + /// + /// Creates the invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request + /// + /// Invoice ID + /// Invoice item ID + /// First invoice tax ID + /// Second invoice tax ID + /// Sort Order + /// Description + /// Quantity + /// Price + /// Discount + /// Create invoice line + /// Invoices + /// InvoiceLine + [Create(@"invoiceline")] + public InvoiceLineWrapper CreateInvoiceLine( + int invoiceId, + int invoiceItemId, + int invoiceTax1Id, + int invoiceTax2Id, + int sortOrder, + string description, + int quantity, + decimal price, + int discount + ) + { + var invoiceLine = new InvoiceLine + { + InvoiceID = invoiceId, + InvoiceItemID = invoiceItemId, + InvoiceTax1ID = invoiceTax1Id, + InvoiceTax2ID = invoiceTax2Id, + SortOrder = sortOrder, + Description = description, + Quantity = quantity, + Price = price, + Discount = discount + }; + + if (invoiceId <= 0) + throw new ArgumentException(); + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + + invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + if (Global.CanDownloadInvoices) + { + PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return ToInvoiceLineWrapper(invoiceLine); + } + + /// + /// Updates the selected invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request + /// + /// Line ID + /// Invoice ID + /// Invoice item ID + /// First invoice tax ID + /// Second invoice tax ID + /// Sort Order + /// Description + /// Quantity + /// Price + /// Discount + /// Update invoice line + /// Invoices + /// InvoiceLine + [Update(@"invoiceline/{id:int}")] + public InvoiceLineWrapper UpdateInvoiceLine( + int id, + int invoiceId, + int invoiceItemId, + int invoiceTax1Id, + int invoiceTax2Id, + int sortOrder, + string description, + int quantity, + decimal price, + int discount + ) + { + if (invoiceId <= 0) + throw new ArgumentException(); + + var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); + if (invoiceLine == null || invoiceLine.InvoiceID != invoiceId) throw new ItemNotFoundException(); + + + invoiceLine.InvoiceID = invoiceId; + invoiceLine.InvoiceItemID = invoiceItemId; + invoiceLine.InvoiceTax1ID = invoiceTax1Id; + invoiceLine.InvoiceTax2ID = invoiceTax2Id; + invoiceLine.SortOrder = sortOrder; + invoiceLine.Description = description; + invoiceLine.Quantity = quantity; + invoiceLine.Price = price; + invoiceLine.Discount = discount; + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + + DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + if (Global.CanDownloadInvoices) + { + PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return ToInvoiceLineWrapper(invoiceLine); + } + + /// + /// Deletes the invoice line with the ID specified in the request + /// + /// Line ID + /// Delete invoice line + /// Invoices + /// Line ID + [Delete(@"invoiceline/{id:int}")] + public int DeleteInvoiceLine(int id) + { + var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); + if (invoiceLine == null) throw new ItemNotFoundException(); + if (!DaoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line"); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID); + if (invoice == null) throw new ItemNotFoundException(); + if (!CRMSecurity.CanEdit(invoice)) throw CRMSecurity.CreateSecurityException(); + + DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + if (Global.CanDownloadInvoices) + { + PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return id; + } + + private InvoiceBaseWrapper ToInvoiceBaseWrapper(Invoice invoice) + { + var result = new InvoiceBaseWrapper(invoice); + + if (invoice.ContactID > 0) + { + result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + } + + if (invoice.ConsigneeID > 0) + { + result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + } + + if (invoice.EntityID > 0) + { + result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); + } + + result.Cost = invoice.GetInvoiceCost(DaoFactory); + + return result; + } + + /// + /// Creates the invoice item with the parameters (title, description, price, etc.) specified in the request + /// + /// Item title + /// Item description + /// Item price + /// Item stock keeping unit + /// Item quantity + /// Item stock quantity + /// Track inventory + /// Item first invoice tax ID + /// Item second invoice tax ID + /// Create invoice item + /// Invoices + /// InvoiceItem + [Create(@"invoiceitem")] + public InvoiceItemWrapper CreateInvoiceItem( + string title, + string description, + decimal price, + string sku, + int quantity, + int stockQuantity, + bool trackInventory, + int invoiceTax1id, + int invoiceTax2id) + { + if (!CRMSecurity.IsAdmin) { + throw CRMSecurity.CreateSecurityException(); + } + + if (String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); + + var invoiceItem = new InvoiceItem + { + Title = title, + Description = description, + Price = price, + StockKeepingUnit = sku, + Quantity = quantity, + StockQuantity = stockQuantity, + TrackInventory = trackInventory, + InvoiceTax1ID = invoiceTax1id, + InvoiceTax2ID = invoiceTax2id + }; + + invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + MessageService.Send( MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + + return ToInvoiceItemWrapper(invoiceItem); + } + + /// + /// Updates the selected invoice item with the parameters (title, description, price, etc.) specified in the request + /// + /// Item ID + /// Item title + /// Item description + /// Item price + /// Item stock keeping unit + /// Item quantity + /// Item stock quantity + /// Track inventory + /// Item first invoice tax ID + /// Item second invoice tax ID + /// Update invoice item + /// Invoices + /// InvoiceItem + [Update(@"invoiceitem/{id:int}")] + public InvoiceItemWrapper UpdateInvoiceItem(int id, + string title, + string description, + decimal price, + string sku, + int quantity, + int stockQuantity, + bool trackInventory, + int invoiceTax1id, + int invoiceTax2id) + { + if (!CRMSecurity.IsAdmin) { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0 || String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); + + if (!DaoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException(); + + var invoiceItem = new InvoiceItem + { + ID = id, + Title = title, + Description = description, + Price = price, + StockKeepingUnit = sku, + Quantity = quantity, + StockQuantity = stockQuantity, + TrackInventory = trackInventory, + InvoiceTax1ID = invoiceTax1id, + InvoiceTax2ID = invoiceTax2id + }; + + invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + MessageService.Send( MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + + return ToInvoiceItemWrapper(invoiceItem); + } + + /// + /// Deletes the invoice item with the ID specified in the request + /// + /// Item ID + /// Delete invoice item + /// Invoices + /// InvoiceItem + [Delete(@"invoiceitem/{id:int}")] + public InvoiceItemWrapper DeleteInvoiceItem(int id) + { + if (!CRMSecurity.IsAdmin) { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0) throw new ArgumentException(); + + var invoiceItem = DaoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id); + if (invoiceItem == null) throw new ItemNotFoundException(); + + MessageService.Send( MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + return ToInvoiceItemWrapper(invoiceItem); + } + + /// + /// Deletes the group of invoice items with the IDs specified in the request + /// + /// Item ID list + /// Delete Invoice item group + /// Invoices + /// InvoiceItem list + [Delete(@"invoiceitem")] + public IEnumerable DeleteBatchItems(IEnumerable ids) + { + if (!CRMSecurity.IsAdmin) { + throw CRMSecurity.CreateSecurityException(); + } + + if (ids == null) throw new ArgumentException(); + ids = ids.Distinct(); + + var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); + MessageService.Send( MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); + + return items.ConvertAll(ToInvoiceItemWrapper); + } + + /// + /// Returns the list of invoice taxes + /// + /// Get invoice taxes list + /// Invoices + /// InvoiceTax list + [Read(@"invoice/tax")] + public IEnumerable GetInvoiceTaxes() + { + return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(ToInvoiceTaxWrapper); + } + + /// + /// Creates the invoice tax with the parameters (name, description, rate) specified in the request + /// + /// Tax name + /// Tax description + /// Tax rate + /// Create invoice tax + /// Invoices + /// InvoiceTax + [Create(@"invoice/tax")] + public InvoiceTaxWrapper CreateInvoiceTax( + string name, + string description, + decimal rate) + { + if (!CRMSecurity.IsAdmin) { + throw CRMSecurity.CreateSecurityException(); + } + + if (String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); + if (DaoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError); + + var invoiceTax = new InvoiceTax + { + Name = name, + Description = description, + Rate = rate + }; + + invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); + MessageService.Send( MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + + return ToInvoiceTaxWrapper(invoiceTax); + } + + /// + /// Updates the selected invoice tax with the parameters (name, description, rate) specified in the request + /// + /// Tax ID + /// Tax name + /// Tax description + /// Tax rate + /// Update invoice tax + /// Invoices + /// InvoiceTax + [Update(@"invoice/tax/{id:int}")] + public InvoiceTaxWrapper UpdateInvoiceTax( + int id, + string name, + string description, + decimal rate) + { + if (!CRMSecurity.IsAdmin) { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0 || String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); + + if (!DaoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException(); + + var invoiceTax = new InvoiceTax + { + ID = id, + Name = name, + Description = description, + Rate = rate + }; + + invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); + MessageService.Send( MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + + return ToInvoiceTaxWrapper(invoiceTax); + } + + /// + /// Delete the invoice tax with the ID specified in the request + /// + /// Tax ID + /// Delete invoice tax + /// Invoices + /// InvoiceTax + [Delete(@"invoice/tax/{id:int}")] + public InvoiceTaxWrapper DeleteInvoiceTax(int id) + { + if (!CRMSecurity.IsAdmin) { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0) throw new ArgumentException(); + + var invoiceTax = DaoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id); + if (invoiceTax == null) throw new ItemNotFoundException(); + + MessageService.Send( MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + return ToInvoiceTaxWrapper(invoiceTax); + } + + /// + /// Get default invoice settings + /// + /// Get default invoice settings + /// Invoices + /// InvoiceSetting + [Read(@"invoice/settings")] + public InvoiceSetting GetSettings() + { + return DaoFactory.GetInvoiceDao().GetSettings(); + } + + /// + /// Save default invoice number + /// + /// Is autogenerated + /// Prefix + /// Number + /// Save default invoice number + /// Invoices + /// InvoiceSetting + [Update(@"invoice/settings/name")] + public InvoiceSetting SaveNumberSettings(bool autogenerated, string prefix, string number) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + if (autogenerated && string.IsNullOrEmpty(number)) + throw new ArgumentException(); + + if (autogenerated && DaoFactory.GetInvoiceDao().IsExist(prefix + number)) + throw new ArgumentException(); + + var invoiceSetting = GetSettings(); + + invoiceSetting.Autogenerated = autogenerated; + invoiceSetting.Prefix = prefix; + invoiceSetting.Number = number; + + var settings = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); + MessageService.Send( MessageAction.InvoiceNumberFormatUpdated); + + return settings; + } + + /// + /// Save default invoice terms + /// + /// Terms + /// Save default invoice terms + /// Invoices + /// InvoiceSetting + [Update(@"invoice/settings/terms")] + public InvoiceSetting SaveTermsSettings(string terms) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var invoiceSetting = GetSettings(); + + invoiceSetting.Terms = terms; + + var result = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); + MessageService.Send( MessageAction.InvoiceDefaultTermsUpdated); + + return result; + } + + /// false + [Update(@"invoice/{invoiceid:int}/creationdate")] + public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate) + { + var dao = DaoFactory.GetInvoiceDao(); + var invoice = dao.GetByID(invoiceid); + + if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) + throw new ItemNotFoundException(); + + dao.SetInvoiceCreationDate(invoiceid, creationDate); + } + + /// false + [Update(@"invoice/{invoiceid:int}/lastmodifeddate")] + public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate) + { + var dao = DaoFactory.GetInvoiceDao(); + var invoice = dao.GetByID(invoiceid); + + if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) + throw new ItemNotFoundException(); + + dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); + } + + private InvoiceWrapper ToInvoiceWrapper(Invoice invoice) + { + var result = new InvoiceWrapper(invoice); + + if (invoice.ContactID > 0) + { + result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + } + + if (invoice.ConsigneeID > 0) + { + result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + } + + if (invoice.EntityID > 0) + { + result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); + } + + result.Cost = invoice.GetInvoiceCost(DaoFactory); + + result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(ToInvoiceLineWrapper).ToList(); + + return result; + } + + private InvoiceItemWrapper ToInvoiceItemWrapper(InvoiceItem invoiceItem) + { + var result = new InvoiceItemWrapper(invoiceItem); + + if (invoiceItem.InvoiceTax1ID > 0) + { + result.InvoiceTax1 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); + } + if (invoiceItem.InvoiceTax2ID > 0) + { + result.InvoiceTax2 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); + } + + return result; + } + + private InvoiceTaxWrapper ToInvoiceTaxWrapper(InvoiceTax invoiceTax) + { + return new InvoiceTaxWrapper(invoiceTax); + } + + private InvoiceLineWrapper ToInvoiceLineWrapper(InvoiceLine invoiceLine) + { + return new InvoiceLineWrapper(invoiceLine); + } + + private IEnumerable ToListInvoiceBaseWrappers(ICollection items) + { + if (items == null || items.Count == 0) return new List(); + + var result = new List(); + + + var contactIDs = items.Select(item => item.ContactID); + contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID)); + + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) + .ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper); + + + foreach (var invoice in items) + { + var invoiceWrapper = new InvoiceBaseWrapper(invoice); + + if (contacts.ContainsKey(invoice.ContactID)) + { + invoiceWrapper.Contact = contacts[invoice.ContactID]; + } + + if (contacts.ContainsKey(invoice.ConsigneeID)) + { + invoiceWrapper.Consignee = contacts[invoice.ContactID]; + } + + if (invoice.EntityID > 0) + { + invoiceWrapper.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); //Need to optimize + } + + invoiceWrapper.Cost = invoice.GetInvoiceCost(DaoFactory); + + result.Add(invoiceWrapper); + } + + return result; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs b/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs new file mode 100644 index 00000000000..533f8db03ca --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs @@ -0,0 +1,1098 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Creates an opportunity stage with the parameters (title, description, success probability, etc.) specified in the request + /// + /// Title + /// Description + /// Color + /// Success probability + /// Stage type + /// Create opportunity stage + /// Opportunities + /// + /// + /// Opportunity stage + /// + [Create(@"opportunity/stage")] + public DealMilestoneWrapper CreateDealMilestone( + string title, + string description, + string color, + int successProbability, + DealMilestoneStatus stageType) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (string.IsNullOrEmpty(title)) throw new ArgumentException(); + + if (successProbability < 0) successProbability = 0; + + var dealMilestone = new DealMilestone + { + Title = title, + Color = color, + Description = description, + Probability = successProbability, + Status = stageType + }; + + dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone); + MessageService.Send( MessageAction.OpportunityStageCreated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + + return ToDealMilestoneWrapper(dealMilestone); + } + + /// + /// Updates the selected opportunity stage with the parameters (title, description, success probability, etc.) specified in the request + /// + /// Opportunity stage ID + /// Title + /// Description + /// Color + /// Success probability + /// Stage type + /// Update opportunity stage + /// Opportunities + /// + /// + /// + /// Opportunity stage + /// + [Update(@"opportunity/stage/{id:int}")] + public DealMilestoneWrapper UpdateDealMilestone( + int id, + string title, + string description, + string color, + int successProbability, + DealMilestoneStatus stageType) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); + + if (successProbability < 0) successProbability = 0; + + var curDealMilestoneExist = DaoFactory.GetDealMilestoneDao().IsExist(id); + if (!curDealMilestoneExist) throw new ItemNotFoundException(); + + var dealMilestone = new DealMilestone + { + Title = title, + Color = color, + Description = description, + Probability = successProbability, + Status = stageType, + ID = id + }; + + DaoFactory.GetDealMilestoneDao().Edit(dealMilestone); + MessageService.Send( MessageAction.OpportunityStageUpdated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + + return ToDealMilestoneWrapper(dealMilestone); + } + + /// + /// Updates the selected opportunity stage with the color specified in the request + /// + /// Opportunity stage ID + /// Color + /// Update opportunity stage color + /// Opportunities + /// + /// + /// + /// Opportunity stage + /// + [Update(@"opportunity/stage/{id:int}/color")] + public DealMilestoneWrapper UpdateDealMilestoneColor(int id, string color) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0) throw new ArgumentException(); + + var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(id); + if (dealMilestone == null) throw new ItemNotFoundException(); + + dealMilestone.Color = color; + + DaoFactory.GetDealMilestoneDao().ChangeColor(id, color); + MessageService.Send( MessageAction.OpportunityStageUpdatedColor, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + + return ToDealMilestoneWrapper(dealMilestone); + } + + /// + /// Updates the available opportunity stages order with the list specified in the request + /// + /// + /// Update opportunity stages order + /// + /// Opportunity stage ID list + /// Opportunities + /// + /// Opportunity stages + /// + /// + /// + /// + [Update(@"opportunity/stage/reorder")] + public IEnumerable UpdateDealMilestonesOrder(IEnumerable ids) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (ids == null) throw new ArgumentException(); + + var idsList = ids.ToList(); + + var result = idsList.Select(id => DaoFactory.GetDealMilestoneDao().GetByID(id)).ToList(); + + DaoFactory.GetDealMilestoneDao().Reorder(idsList.ToArray()); + MessageService.Send( MessageAction.OpportunityStagesUpdatedOrder, MessageTarget.Create(idsList), result.Select(x => x.Title)); + + return result.Select(ToDealMilestoneWrapper); + } + + /// + /// Deletes the opportunity stage with the ID specified in the request + /// + /// Delete opportunity stage + /// Opportunities + /// Opportunity stage ID + /// + /// + /// + /// Opportunity stage + /// + [Delete(@"opportunity/stage/{id:int}")] + public DealMilestoneWrapper DeleteDealMilestone(int id) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0) throw new ArgumentException(); + + var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(id); + if (dealMilestone == null) throw new ItemNotFoundException(); + + var result = ToDealMilestoneWrapper(dealMilestone); + + DaoFactory.GetDealMilestoneDao().Delete(id); + MessageService.Send( MessageAction.OpportunityStageDeleted, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + + return result; + } + + /// + /// Creates a new history category with the parameters (title, description, etc.) specified in the request + /// + ///Title + ///Description + ///Order + ///Image name + ///Create history category + /// History + ///History category + /// + [Create(@"history/category")] + public HistoryCategoryWrapper CreateHistoryCategory(string title, string description, string imageName, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var listItem = new ListItem + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName + }; + + listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.HistoryCategory, listItem); + MessageService.Send( MessageAction.HistoryEventCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToHistoryCategoryWrapper(listItem); + } + + /// + /// Updates the selected history category with the parameters (title, description, etc.) specified in the request + /// + ///History category ID + ///Title + ///Description + ///Order + ///Image name + ///Update history category + ///History + ///History category + /// + /// + [Update(@"history/category/{id:int}")] + public HistoryCategoryWrapper UpdateHistoryCategory(int id, string title, string description, string imageName, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var curHistoryCategoryExist = DaoFactory.GetListItemDao().IsExist(id); + if (!curHistoryCategoryExist) throw new ItemNotFoundException(); + + var listItem = new ListItem + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName, + ID = id + }; + + DaoFactory.GetListItemDao().EditItem(ListType.HistoryCategory, listItem); + MessageService.Send( MessageAction.HistoryEventCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToHistoryCategoryWrapper(listItem); + } + + /// + /// Updates the icon of the selected history category + /// + /// History category ID + /// icon name + /// Update history category icon + /// History + /// + /// + /// + /// History category + /// + [Update(@"history/category/{id:int}/icon")] + public HistoryCategoryWrapper UpdateHistoryCategoryIcon(int id, string imageName) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0) throw new ArgumentException(); + + var historyCategory = DaoFactory.GetListItemDao().GetByID(id); + if (historyCategory == null) throw new ItemNotFoundException(); + + historyCategory.AdditionalParams = imageName; + + DaoFactory.GetListItemDao().ChangePicture(id, imageName); + MessageService.Send( MessageAction.HistoryEventCategoryUpdatedIcon, MessageTarget.Create(historyCategory.ID), historyCategory.Title); + + return ToHistoryCategoryWrapper(historyCategory); + } + + /// + /// Updates the history categories order with the list specified in the request + /// + /// + /// Update history categories order + /// + /// History category title list + /// History + /// + /// History categories + /// + /// + /// + /// + [Update(@"history/category/reorder")] + public IEnumerable UpdateHistoryCategoriesOrder(IEnumerable titles) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (titles == null) throw new ArgumentException(); + + var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.HistoryCategory, title)).ToList(); + + DaoFactory.GetListItemDao().ReorderItems(ListType.HistoryCategory, titles.ToArray()); + MessageService.Send( MessageAction.HistoryEventCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + + return result.ConvertAll(ToHistoryCategoryWrapper); + } + + /// + /// Deletes the selected history category with the ID specified in the request + /// + /// Delete history category + /// History + /// History category ID + /// + /// + /// + /// History category + [Delete(@"history/category/{id:int}")] + public HistoryCategoryWrapper DeleteHistoryCategory(int id) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0) throw new ArgumentException(); + + var dao = DaoFactory.GetListItemDao(); + var listItem = dao.GetByID(id); + if (listItem == null) throw new ItemNotFoundException(); + + if (dao.GetItemsCount(ListType.HistoryCategory) < 2) { + throw new ArgumentException("The last history category cannot be deleted"); + } + + var result = ToHistoryCategoryWrapper(listItem); + + dao.DeleteItem(ListType.HistoryCategory, id, 0); + MessageService.Send( MessageAction.HistoryEventCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + + return result; + } + + /// + /// Creates a new task category with the parameters (title, description, etc.) specified in the request + /// + ///Title + ///Description + ///Order + ///Image name + ///Create task category + ///Tasks + ///Task category + /// + /// + /// Task category + /// + [Create(@"task/category")] + public TaskCategoryWrapper CreateTaskCategory(string title, string description, string imageName, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + var listItem = new ListItem + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName + }; + + listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.TaskCategory, listItem); + MessageService.Send( MessageAction.CrmTaskCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToTaskCategoryWrapper(listItem); + } + + /// + /// Updates the selected task category with the parameters (title, description, etc.) specified in the request + /// + ///Task category ID + ///Title + ///Description + ///Order + ///Image name + ///Update task category + ///Tasks + ///Task category + /// + /// + /// + /// + /// Task category + /// + [Update(@"task/category/{id:int}")] + public TaskCategoryWrapper UpdateTaskCategory(int id, string title, string description, string imageName, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var curTaskCategoryExist = DaoFactory.GetListItemDao().IsExist(id); + if (!curTaskCategoryExist) throw new ItemNotFoundException(); + + var listItem = new ListItem + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName, + ID = id + }; + + DaoFactory.GetListItemDao().EditItem(ListType.TaskCategory, listItem); + MessageService.Send( MessageAction.CrmTaskCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToTaskCategoryWrapper(listItem); + } + + /// + /// Updates the icon of the task category with the ID specified in the request + /// + /// Task category ID + /// icon name + /// Update task category icon + /// Tasks + /// + /// + /// + /// Task category + /// + [Update(@"task/category/{id:int}/icon")] + public TaskCategoryWrapper UpdateTaskCategoryIcon(int id, string imageName) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0) throw new ArgumentException(); + + var taskCategory = DaoFactory.GetListItemDao().GetByID(id); + if (taskCategory == null) throw new ItemNotFoundException(); + + taskCategory.AdditionalParams = imageName; + + DaoFactory.GetListItemDao().ChangePicture(id, imageName); + MessageService.Send( MessageAction.CrmTaskCategoryUpdatedIcon, MessageTarget.Create(taskCategory.ID), taskCategory.Title); + + return ToTaskCategoryWrapper(taskCategory); + } + + /// + /// Updates the task categories order with the list specified in the request + /// + /// + /// Update task categories order + /// + /// Task category title list + /// Tasks + /// + /// Task categories + /// + /// + /// + /// + [Update(@"task/category/reorder")] + public IEnumerable UpdateTaskCategoriesOrder(IEnumerable titles) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (titles == null) throw new ArgumentException(); + + var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.TaskCategory, title)).ToList(); + + DaoFactory.GetListItemDao().ReorderItems(ListType.TaskCategory, titles.ToArray()); + MessageService.Send( MessageAction.CrmTaskCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + + return result.ConvertAll(ToTaskCategoryWrapper); + } + + /// + /// Deletes the task category with the ID specified in the request + /// + /// Delete task category + /// Tasks + /// Task category ID + /// Task category ID for replace in task with current category stage + /// + /// + /// + [Delete(@"task/category/{categoryid:int}")] + public TaskCategoryWrapper DeleteTaskCategory(int categoryid, int newcategoryid) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (categoryid <= 0 || newcategoryid < 0) throw new ArgumentException(); + + var dao = DaoFactory.GetListItemDao(); + var listItem = dao.GetByID(categoryid); + if (listItem == null) throw new ItemNotFoundException(); + + if (dao.GetItemsCount(ListType.TaskCategory) < 2) { + throw new ArgumentException("The last task category cannot be deleted"); + } + + dao.DeleteItem(ListType.TaskCategory, categoryid, newcategoryid); + MessageService.Send( MessageAction.CrmTaskCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToTaskCategoryWrapper(listItem); + } + + /// + /// Creates a new contact status with the parameters (title, description, etc.) specified in the request + /// + ///Title + ///Description + ///Color + ///Order + ///Contact status + /// Create contact status + /// Contacts + /// + /// + /// Contact status + /// + [Create(@"contact/status")] + public ContactStatusWrapper CreateContactStatus(string title, string description, string color, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + var listItem = new ListItem + { + Title = title, + Description = description, + Color = color, + SortOrder = sortOrder + }; + + listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.ContactStatus, listItem); + MessageService.Send( MessageAction.ContactTemperatureLevelCreated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToContactStatusWrapper(listItem); + } + + /// + /// Updates the selected contact status with the parameters (title, description, etc.) specified in the request + /// + ///Contact status ID + ///Title + ///Description + ///Color + ///Order + ///Contact status + /// Update contact status + /// Contacts + /// + /// + /// + /// + /// Contact status + /// + [Update(@"contact/status/{id:int}")] + public ContactStatusWrapper UpdateContactStatus(int id, string title, string description, string color, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var curListItemExist = DaoFactory.GetListItemDao().IsExist(id); + if (!curListItemExist) throw new ItemNotFoundException(); + + var listItem = new ListItem + { + ID = id, + Title = title, + Description = description, + Color = color, + SortOrder = sortOrder + }; + + DaoFactory.GetListItemDao().EditItem(ListType.ContactStatus, listItem); + MessageService.Send( MessageAction.ContactTemperatureLevelUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToContactStatusWrapper(listItem); + } + + /// + /// Updates the color of the selected contact status with the new color specified in the request + /// + /// Contact status ID + /// Color + /// Update contact status color + /// Contacts + /// + /// + /// + /// Contact status + /// + [Update(@"contact/status/{id:int}/color")] + public ContactStatusWrapper UpdateContactStatusColor(int id, string color) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0) throw new ArgumentException(); + + var contactStatus = DaoFactory.GetListItemDao().GetByID(id); + if (contactStatus == null) throw new ItemNotFoundException(); + + contactStatus.Color = color; + + DaoFactory.GetListItemDao().ChangeColor(id, color); + MessageService.Send( MessageAction.ContactTemperatureLevelUpdatedColor, MessageTarget.Create(contactStatus.ID), contactStatus.Title); + + return ToContactStatusWrapper(contactStatus); + } + + /// + /// Updates the contact statuses order with the list specified in the request + /// + /// + /// Update contact statuses order + /// + /// Contact status title list + /// Contacts + /// + /// Contact statuses + /// + /// + /// + /// + [Update(@"contact/status/reorder")] + public IEnumerable UpdateContactStatusesOrder(IEnumerable titles) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (titles == null) throw new ArgumentException(); + + var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.ContactStatus, title)).ToList(); + + DaoFactory.GetListItemDao().ReorderItems(ListType.ContactStatus, titles.ToArray()); + MessageService.Send( MessageAction.ContactTemperatureLevelsUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + + return result.ConvertAll(ToContactStatusWrapper); + } + + /// + /// Deletes the contact status with the ID specified in the request + /// + /// Delete contact status + /// Contacts + /// Contact status ID + /// + /// + /// + /// + /// Contact status + /// + [Delete(@"contact/status/{contactStatusid:int}")] + public ContactStatusWrapper DeleteContactStatus(int contactStatusid) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (contactStatusid <= 0) throw new ArgumentException(); + + var dao = DaoFactory.GetListItemDao(); + var listItem = dao.GetByID(contactStatusid); + if (listItem == null) throw new ItemNotFoundException(); + + if (dao.GetItemsCount(ListType.ContactStatus) < 2) { + throw new ArgumentException("The last contact status cannot be deleted"); + } + + var contactStatus = ToContactStatusWrapper(listItem); + + dao.DeleteItem(ListType.ContactStatus, contactStatusid, 0); + MessageService.Send( MessageAction.ContactTemperatureLevelDeleted, MessageTarget.Create(contactStatus.ID), contactStatus.Title); + + return contactStatus; + } + + /// + /// Returns the status of the contact for the ID specified in the request + /// + /// Contact status ID + /// Contact status + /// Get contact status + /// Contacts + /// + /// + [Read(@"contact/status/{contactStatusid:int}")] + public ContactStatusWrapper GetContactStatusByID(int contactStatusid) + { + if (contactStatusid <= 0) throw new ArgumentException(); + + var listItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); + if (listItem == null) throw new ItemNotFoundException(); + + return ToContactStatusWrapper(listItem); + } + + /// + /// Creates a new contact type with the parameters (title, etc.) specified in the request + /// + ///Title + ///Order + ///Contact type + /// Create contact type + /// Contacts + /// + /// + /// Contact type + /// + [Create(@"contact/type")] + public ContactTypeWrapper CreateContactType(string title, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + var listItem = new ListItem + { + Title = title, + Description = string.Empty, + SortOrder = sortOrder + }; + + listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.ContactType, listItem); + MessageService.Send( MessageAction.ContactTypeCreated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToContactTypeWrapper(listItem); + } + + /// + /// Updates the selected contact type with the parameters (title, description, etc.) specified in the request + /// + ///Contact type ID + ///Title + ///Order + ///Contact type + /// Update contact type + /// Contacts + /// + /// + /// + /// + /// Contact type + /// + [Update(@"contact/type/{id:int}")] + public ContactTypeWrapper UpdateContactType(int id, string title, int sortOrder) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var curListItemExist = DaoFactory.GetListItemDao().IsExist(id); + if (!curListItemExist) throw new ItemNotFoundException(); + + var listItem = new ListItem + { + ID = id, + Title = title, + SortOrder = sortOrder + }; + + DaoFactory.GetListItemDao().EditItem(ListType.ContactType, listItem); + MessageService.Send( MessageAction.ContactTypeUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + + return ToContactTypeWrapper(listItem); + } + + /// + /// Updates the contact types order with the list specified in the request + /// + /// + /// Update contact types order + /// + /// Contact type title list + /// Contacts + /// + /// Contact types + /// + /// + /// + /// + [Update(@"contact/type/reorder")] + public IEnumerable UpdateContactTypesOrder(IEnumerable titles) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (titles == null) throw new ArgumentException(); + + var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.ContactType, title)).ToList(); + + DaoFactory.GetListItemDao().ReorderItems(ListType.ContactType, titles.ToArray()); + MessageService.Send( MessageAction.ContactTypesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + + return result.ConvertAll(ToContactTypeWrapper); + } + + /// + /// Deletes the contact type with the ID specified in the request + /// + /// Delete contact type + /// Contacts + /// Contact type ID + /// + /// + /// + /// + /// Contact type + /// + [Delete(@"contact/type/{contactTypeid:int}")] + public ContactTypeWrapper DeleteContactType(int contactTypeid) + { + if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + + if (contactTypeid <= 0) throw new ArgumentException(); + var dao = DaoFactory.GetListItemDao(); + + var listItem = dao.GetByID(contactTypeid); + if (listItem == null) throw new ItemNotFoundException(); + + if (dao.GetItemsCount(ListType.ContactType) < 2) { + throw new ArgumentException("The last contact type cannot be deleted"); + } + + var contactType = ToContactTypeWrapper(listItem); + + dao.DeleteItem(ListType.ContactType, contactTypeid, 0); + MessageService.Send( MessageAction.ContactTypeDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + + return contactType; + } + + /// + /// Returns the type of the contact for the ID specified in the request + /// + /// Contact type ID + /// Contact type + /// Get contact type + /// Contacts + /// + /// + [Read(@"contact/type/{contactTypeid:int}")] + public ContactTypeWrapper GetContactTypeByID(int contactTypeid) + { + if (contactTypeid <= 0) throw new ArgumentException(); + + var listItem = DaoFactory.GetListItemDao().GetByID(contactTypeid); + if (listItem == null) throw new ItemNotFoundException(); + + return ToContactTypeWrapper(listItem); + } + + /// + /// Returns the stage of the opportunity with the ID specified in the request + /// + /// Opportunity stage ID + /// Opportunity stage + /// Get opportunity stage + /// Opportunities + /// + /// + [Read(@"opportunity/stage/{stageid:int}")] + public DealMilestoneWrapper GetDealMilestoneByID(int stageid) + { + if (stageid <= 0) throw new ArgumentException(); + + var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(stageid); + if (dealMilestone == null) throw new ItemNotFoundException(); + + return ToDealMilestoneWrapper(dealMilestone); + } + + /// + /// Returns the category of the task with the ID specified in the request + /// + /// Task category ID + /// Task category + /// Get task category + /// Tasks + /// + /// + [Read(@"task/category/{categoryid:int}")] + public TaskCategoryWrapper GetTaskCategoryByID(int categoryid) + { + if (categoryid <= 0) throw new ArgumentException(); + + var listItem = DaoFactory.GetListItemDao().GetByID(categoryid); + if (listItem == null) throw new ItemNotFoundException(); + + return ToTaskCategoryWrapper(listItem); + } + + /// + /// Returns the list of all history categories available on the portal + /// + /// Get all history categories + /// History + /// + /// List of all history categories + /// + [Read(@"history/category")] + public IEnumerable GetHistoryCategoryWrapper() + { + var result = DaoFactory.GetListItemDao().GetItems(ListType.HistoryCategory).ConvertAll(item => new HistoryCategoryWrapper(item)); + + var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory); + + result.ForEach(x => + { + if (relativeItemsCount.ContainsKey(x.ID)) + x.RelativeItemsCount = relativeItemsCount[x.ID]; + }); + return result; + } + + /// + /// Returns the list of all task categories available on the portal + /// + /// Get all task categories + /// Tasks + /// + /// List of all task categories + /// + [Read(@"task/category")] + public IEnumerable GetTaskCategories() + { + var result = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => new TaskCategoryWrapper(item)); + + var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory); + + result.ForEach(x => + { + if (relativeItemsCount.ContainsKey(x.ID)) + x.RelativeItemsCount = relativeItemsCount[x.ID]; + }); + return result; + } + + /// + /// Returns the list of all contact statuses available on the portal + /// + /// Get all contact statuses + /// Contacts + /// + /// List of all contact statuses + /// + [Read(@"contact/status")] + public IEnumerable GetContactStatuses() + { + var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactStatus).ConvertAll(item => new ContactStatusWrapper(item)); + + var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus); + + result.ForEach(x => + { + if (relativeItemsCount.ContainsKey(x.ID)) + x.RelativeItemsCount = relativeItemsCount[x.ID]; + }); + return result; + } + + /// + /// Returns the list of all contact types available on the portal + /// + /// Get all contact types + /// Contacts + /// + /// List of all contact types + /// + [Read(@"contact/type")] + public IEnumerable GetContactTypes() + { + var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactType).ConvertAll(item => new ContactTypeWrapper(item)); + + var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType); + + result.ForEach(x => + { + if (relativeItemsCount.ContainsKey(x.ID)) + x.RelativeItemsCount = relativeItemsCount[x.ID]; + }); + + return result; + } + + /// + /// Returns the list of all opportunity stages available on the portal + /// + /// Get all opportunity stages + /// Opportunities + /// + /// List of all opportunity stages + /// + [Read(@"opportunity/stage")] + public IEnumerable GetDealMilestones() + { + var result = DaoFactory.GetDealMilestoneDao().GetAll().ConvertAll(item => new DealMilestoneWrapper(item)); + + var relativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(); + + result.ForEach(x => + { + if (relativeItemsCount.ContainsKey(x.ID)) + x.RelativeItemsCount = relativeItemsCount[x.ID]; + }); + + return result; + } + + public ContactStatusWrapper ToContactStatusWrapper(ListItem listItem) + { + var result = new ContactStatusWrapper(listItem) + { + RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, listItem.ID) + }; + + return result; + } + + public ContactTypeWrapper ToContactTypeWrapper(ListItem listItem) + { + var result = new ContactTypeWrapper(listItem) + { + RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, listItem.ID) + }; + + return result; + } + + public HistoryCategoryWrapper ToHistoryCategoryWrapper(ListItem listItem) + { + var result = new HistoryCategoryWrapper(listItem) + { + RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID) + }; + return result; + } + + public TaskCategoryWrapper ToTaskCategoryWrapper(ListItem listItem) + { + var result = new TaskCategoryWrapper(listItem) + { + RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID) + }; + return result; + } + + private DealMilestoneWrapper ToDealMilestoneWrapper(DealMilestone dealMilestone) + { + var result = new DealMilestoneWrapper(dealMilestone) + { + RelativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(dealMilestone.ID) + }; + return result; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs new file mode 100644 index 00000000000..9fc89c5010f --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs @@ -0,0 +1,846 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Classes; +using ASC.Web.Files.Utils; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Mime; +using System.Text; +using System.Text.RegularExpressions; +using OrderBy = ASC.CRM.Core.Entities.OrderBy; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the list of all events matching the parameters specified in the request + /// + /// + /// Get event list + /// + /// History + /// Related entity type + /// Related entity ID + /// Task category ID + /// Event author + /// Earliest task due date + /// Latest task due date + /// + /// Event list + /// + [Read(@"history/filter")] + public IEnumerable GetHistory( + string entityType, + int entityId, + int categoryId, + Guid createBy, + ApiDateTime fromDate, + ApiDateTime toDate) + { + var entityTypeObj = ToEntityType(entityType); + + switch (entityTypeObj) { + case EntityType.Contact: + var contact = DaoFactory.GetContactDao().GetByID(entityId); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) + throw new ItemNotFoundException(); + break; + case EntityType.Case: + var cases = DaoFactory.GetCasesDao().GetByID(entityId); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) + throw new ItemNotFoundException(); + break; + case EntityType.Opportunity: + var deal = DaoFactory.GetDealDao().GetByID(entityId); + if (deal == null || !CRMSecurity.CanAccessTo(deal)) + throw new ItemNotFoundException(); + break; + default: + if (entityId != 0) + { + throw new ArgumentException(); + } + break; + } + + RelationshipEventByType eventByType; + + IEnumerable result; + + OrderBy eventOrderBy; + + if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out eventByType)) + { + eventOrderBy = new OrderBy(eventByType, !ApiContext.SortDescending); + } + else if (string.IsNullOrEmpty(ApiContext.SortBy)) + { + eventOrderBy = new OrderBy(RelationshipEventByType.Created, false); + } + else + { + eventOrderBy = null; + } + + if (eventOrderBy != null) + { + result = ToListRelationshipEventWrapper(DaoFactory.GetRelationshipEventDao().GetItems( + ApiContext.FilterValue, + entityTypeObj, + entityId, + createBy, + categoryId, + fromDate, + toDate, + (int)ApiContext.StartIndex, + (int)ApiContext.Count, + eventOrderBy)); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListRelationshipEventWrapper(DaoFactory.GetRelationshipEventDao().GetItems( + ApiContext.FilterValue, + entityTypeObj, + entityId, + createBy, + categoryId, + fromDate, + toDate, + 0, + 0, + null)); + } + + return result.ToSmartList(); + } + + /// + /// Deletes the event with the ID specified in the request and all the files associated with this event + /// + /// + /// Delete event and related files + /// + /// History + /// Event ID + /// + /// + /// + /// Event + /// + [Delete(@"history/{id:int}")] + public RelationshipEventWrapper DeleteHistory(int id) + { + if (id <= 0) throw new ArgumentException(); + + var item = DaoFactory.GetRelationshipEventDao().GetByID(id); + if (item == null) throw new ItemNotFoundException(); + var wrapper = ToRelationshipEventWrapper(item); + + DaoFactory.GetRelationshipEventDao().DeleteItem(id); + + var messageAction = GetHistoryDeletedAction(item.EntityType, item.ContactID); + var entityTitle = wrapper.Contact == null ? wrapper.Entity.EntityTitle : wrapper.Contact.DisplayName; + MessageService.Send( messageAction, MessageTarget.Create(item.ID), entityTitle, wrapper.Category.Title); + + return wrapper; + } + + /// + /// Creates a text (.txt) file in the selected folder with the title and contents sent in the request + /// + /// Create txt + /// Files + /// Entity type + /// Entity ID + /// File title + /// File contents + /// + /// File info + /// + [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/text")] + public FileWrapper CreateTextFile(string entityType, int entityid, string title, string content) + { + if (title == null) throw new ArgumentNullException("title"); + if (content == null) throw new ArgumentNullException("content"); + + var folderid = GetRootFolderID(); + + FileWrapper result; + + var extension = ".txt"; + if (!string.IsNullOrEmpty(content)) + { + if (Regex.IsMatch(content, @"<([^\s>]*)(\s[^<]*)>")) + { + extension = ".html"; + } + } + + using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(content))) + { + title = title.EndsWith(extension, StringComparison.OrdinalIgnoreCase) ? title : (title + extension); + result = SaveFile(folderid, memStream, title); + } + + AttachFiles(entityType, entityid, new List {(int)result.Id}); + + return result; + } + + /// + /// Upload file + /// + /// Upload file + /// Files + /// + /// + ///
  • Single file upload. You should set Content-Type & Content-Disposition header to specify filename and content type, and send file in request body
  • + ///
  • Using standart multipart/form-data method
  • + /// ]]> + ///
    + /// Entity type + /// Entity ID + /// Request Input stream + /// Content-Type Header + /// Content-Disposition Header + /// List of files when posted as multipart/form-data + /// If True, upload documents in original formats as well + /// + /// File info + /// + [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/upload")] + public FileWrapper UploadFileInCRM( + string entityType, + int entityid, + Stream file, + ContentType contentType, + ContentDisposition contentDisposition, + IEnumerable files, + bool storeOriginalFileFlag + ) + { + FilesSettings.StoreOriginalFiles = storeOriginalFileFlag; + + var folderid = GetRootFolderID(); + + var fileNames = new List(); + + FileWrapper uploadedFile = null; + if (files != null && files.Any()) + { + //For case with multiple files + foreach (var postedFile in files) + { + uploadedFile = SaveFile(folderid, postedFile.InputStream, postedFile.FileName); + fileNames.Add(uploadedFile.Title); + } + } + else if (file != null) + { + uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); + fileNames.Add(uploadedFile.Title); + } + + return uploadedFile; + } + + private static FileWrapper SaveFile(object folderid, Stream file, string fileName) + { + var resultFile = FileUploader.Exec(folderid.ToString(), fileName, file.Length, file); + return new FileWrapper(resultFile); + } + + /// + /// Creates the event with the parameters specified in the request + /// + /// + /// Create event + /// + /// History + /// Contact ID + /// Related entity type + /// Related entity ID + /// + /// + /// + /// Contents + /// Category ID + /// Event creation date + /// List of IDs of the files associated with the event + /// User field list + /// + /// Created event + /// + [Create(@"history")] + public RelationshipEventWrapper AddHistoryTo( + string entityType, + int entityId, + int contactId, + string content, + int categoryId, + ApiDateTime created, + IEnumerable fileId, + IEnumerable notifyUserList) + { + if (!string.IsNullOrEmpty(entityType) && + !( + string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || + string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0) + ) + throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + + var entityTitle = ""; + if (contactId > 0) { + var contact = DaoFactory.GetContactDao().GetByID(contactId); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) + throw new ArgumentException(); + entityTitle = contact.GetTitle(); + } + + if (entityTypeObj == EntityType.Case) { + var cases = DaoFactory.GetCasesDao().GetByID(entityId); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) + throw new ArgumentException(); + if (contactId <= 0) + { + entityTitle = cases.Title; + } + } + if (entityTypeObj == EntityType.Opportunity) + { + var deal = DaoFactory.GetDealDao().GetByID(entityId); + if (deal == null || !CRMSecurity.CanAccessTo(deal)) + throw new ArgumentException(); + if (contactId <= 0) + { + entityTitle = deal.Title; + } + } + + var relationshipEvent = new RelationshipEvent + { + CategoryID = categoryId, + EntityType = entityTypeObj, + EntityID = entityId, + Content = content, + ContactID = contactId, + CreateOn = created, + CreateBy = Core.SecurityContext.CurrentAccount.ID + }; + + var category = DaoFactory.GetListItemDao().GetByID(categoryId); + if (category == null) throw new ArgumentException(); + + var item = DaoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent); + + + notifyUserList = notifyUserList != null ? notifyUserList.ToList() : new List(); + var needNotify = notifyUserList.Any(); + + var fileListInfoHashtable = new Hashtable(); + + if (fileId != null) + { + var fileIds = fileId.ToList(); + var files = FilesDaoFactory.GetFileDao().GetFiles(fileIds.Cast().ToArray()); + + if (needNotify) + { + foreach (var file in files) + { + var extension = Path.GetExtension(file.Title); + if (extension == null) continue; + + var fileInfo = string.Format("{0} ({1})", file.Title, extension.ToUpper()); + if (!fileListInfoHashtable.ContainsKey(fileInfo)) + { + fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); + } + else + { + fileInfo = string.Format("{0} ({1}, {2})", file.Title, extension.ToUpper(), file.UniqID); + fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); + } + } + } + + DaoFactory.GetRelationshipEventDao().AttachFiles(item.ID, fileIds.ToArray()); + + if (files.Any()) + { + var fileAttachAction = GetFilesAttachAction(entityTypeObj, contactId); + MessageService.Send( fileAttachAction, MessageTarget.Create(item.ID), entityTitle, files.Select(x => x.Title)); + } + } + + if (needNotify) + { + NotifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, DaoFactory, notifyUserList.ToArray()); + } + + var wrapper = ToRelationshipEventWrapper(item); + + var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); + MessageService.Send( historyCreatedAction, MessageTarget.Create(item.ID), entityTitle, category.Title); + + return wrapper; + } + + /// + /// Associates the selected file(s) with the entity with the ID or type specified in the request + /// + /// + /// Associate file with entity + /// + /// Entity type + /// Entity ID + /// List of IDs of the files + /// Files + /// Entity with the file attached + [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files")] + public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEnumerable fileids) + { + if (entityid <= 0 || fileids == null) throw new ArgumentException(); + + var files = FilesDaoFactory.GetFileDao().GetFiles(fileids.Cast().ToArray()); + + var folderid = GetRootFolderID(); + + if (files.Exists(file => file.FolderID.ToString() != folderid.ToString())) + throw new ArgumentException("invalid file folder"); + + var entityTypeObj = ToEntityType(entityType); + + DomainObject entityObj; + + var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj); + + switch (entityTypeObj) + { + case EntityType.Contact: + var relationshipEvent1 = DaoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray()); + var messageAction = entityObj is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; + MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + return ToRelationshipEventWrapper(relationshipEvent1); + case EntityType.Opportunity: + var relationshipEvent2 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); + MessageService.Send( MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + return ToRelationshipEventWrapper(relationshipEvent2); + case EntityType.Case: + var relationshipEvent3 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); + MessageService.Send( MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + return ToRelationshipEventWrapper(relationshipEvent3); + default: + throw new ArgumentException(); + } + } + + /// + /// Returns the ID for the root folder used to store the files for the CRM module + /// + /// Get root folder ID + /// Files + /// + /// Root folder ID + /// + [Read(@"files/root")] + public object GetRootFolderID() + { + return DaoFactory.GetFileDao().GetRoot(); + } + + /// + /// Returns the list of all files for the entity with the ID or type specified in the request + /// + /// Entity type + /// Entity ID + /// Get file list + /// Files + /// + /// File list + /// + [Read(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files")] + public IEnumerable GetFiles(string entityType, int entityid) + { + if (entityid <= 0) throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + + switch (entityTypeObj) + { + case EntityType.Contact: + return DaoFactory.GetRelationshipEventDao().GetAllFiles(new[] {entityid}, EntityType.Any, 0).ConvertAll(file => new FileWrapper(file)); + case EntityType.Opportunity: + case EntityType.Case: + return DaoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => new FileWrapper(file)); + default: + throw new ArgumentException(); + } + } + + /// + /// Deletes the file with the ID specified in the request + /// + /// Delete file + /// Files + /// File ID + /// + /// + /// + /// File Info + /// + [Delete(@"files/{fileid:int}")] + public FileWrapper DeleteCRMFile(int fileid) + { + if (fileid < 0) throw new ArgumentException(); + + var file = FilesDaoFactory.GetFileDao().GetFile(fileid); + if (file == null) throw new ItemNotFoundException(); + var result = new FileWrapper(file); + + var _eventsDao = DaoFactory.GetRelationshipEventDao(); + var eventIDs = _eventsDao.RemoveFile(file); + var events = new List(); + + eventIDs.ForEach(id => events.Add(_eventsDao.GetByID(id))); + + foreach (var evt in events) + { + DomainObject entityObj; + var entityTitle = evt.ContactID > 0 + ? GetEntityTitle(EntityType.Contact, evt.ContactID, false, out entityObj) + : GetEntityTitle(evt.EntityType, evt.EntityID, false, out entityObj); + var messageAction = GetFilesDetachAction(evt.EntityType, evt.ContactID); + + MessageService.Send( messageAction, MessageTarget.Create(file.ID), entityTitle, file.Title); + } + + return result; + } + + private IEnumerable ToListRelationshipEventWrapper(List itemList) + { + if (itemList.Count == 0) return new List(); + + var result = new List(); + + var contactIDs = new List(); + var eventIDs = new List(); + var categoryIDs = new List(); + var entityWrappersIDs = new Dictionary>(); + + + foreach (var item in itemList) + { + eventIDs.Add(item.ID); + + if (!categoryIDs.Contains(item.CategoryID)) + { + categoryIDs.Add(item.CategoryID); + } + + if (item.ContactID > 0 && !contactIDs.Contains(item.ContactID)) + { + contactIDs.Add(item.ContactID); + } + + if (item.EntityID <= 0) continue; + + if (!entityWrappersIDs.ContainsKey(item.EntityType)) + { + entityWrappersIDs.Add(item.EntityType, new List + { + item.EntityID + }); + } + else if (!entityWrappersIDs[item.EntityType].Contains(item.EntityID)) + { + entityWrappersIDs[item.EntityType].Add(item.EntityID); + } + } + + var entityWrappers = new Dictionary(); + + foreach (var entityType in entityWrappersIDs.Keys) + { + switch (entityType) + { + case EntityType.Opportunity: + DaoFactory.GetDealDao().GetDeals(entityWrappersIDs[entityType].Distinct().ToArray()) + .ForEach(item => + { + if (item == null) return; + + entityWrappers.Add( + string.Format("{0}_{1}", (int)entityType, item.ID), + new EntityWrapper + { + EntityId = item.ID, + EntityTitle = item.Title, + EntityType = "opportunity" + }); + }); + break; + case EntityType.Case: + DaoFactory.GetCasesDao().GetByID(entityWrappersIDs[entityType].ToArray()) + .ForEach(item => + { + if (item == null) return; + + entityWrappers.Add( + string.Format("{0}_{1}", (int)entityType, item.ID), + new EntityWrapper + { + EntityId = item.ID, + EntityTitle = item.Title, + EntityType = "case" + }); + }); + break; + default: + throw new ArgumentException(); + } + } + + var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => new HistoryCategoryBaseWrapper(x)); + + var files = DaoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray()); + + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWrapper); + + foreach (var item in itemList) + { + var eventObjWrap = new RelationshipEventWrapper(item); + + if (contacts.ContainsKey(item.ContactID)) + { + eventObjWrap.Contact = contacts[item.ContactID]; + } + + if (item.EntityID > 0) + { + var entityStrKey = string.Format("{0}_{1}", (int)item.EntityType, item.EntityID); + + if (entityWrappers.ContainsKey(entityStrKey)) + { + eventObjWrap.Entity = entityWrappers[entityStrKey]; + } + } + + eventObjWrap.Files = files.ContainsKey(item.ID) ? files[item.ID].ConvertAll(file => new FileWrapper(file)) : new List(); + + if (categories.ContainsKey(item.CategoryID)) + { + eventObjWrap.Category = categories[item.CategoryID]; + } + + result.Add(eventObjWrap); + } + + return result; + } + + private RelationshipEventWrapper ToRelationshipEventWrapper(RelationshipEvent relationshipEvent) + { + var result = new RelationshipEventWrapper(relationshipEvent); + + var historyCategory = DaoFactory.GetListItemDao().GetByID(relationshipEvent.CategoryID); + + if (historyCategory != null) + { + result.Category = new HistoryCategoryBaseWrapper(historyCategory); + } + + if (relationshipEvent.EntityID > 0) + { + result.Entity = ToEntityWrapper(relationshipEvent.EntityType, relationshipEvent.EntityID); + } + + result.Files = DaoFactory.GetRelationshipEventDao().GetFiles(relationshipEvent.ID).ConvertAll(file => new FileWrapper(file)); + + if (relationshipEvent.ContactID > 0) + { + var relativeContact = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); + if (relativeContact != null) + { + result.Contact = ToContactBaseWrapper(relativeContact); + } + } + + result.CanEdit = CRMSecurity.CanAccessTo(relationshipEvent); + + return result; + } + + private EntityWrapper ToEntityWrapper(EntityType entityType, int entityID) + { + if (entityID == 0) return null; + + var result = new EntityWrapper + { + EntityId = entityID + }; + + switch (entityType) + { + case EntityType.Case: + var caseObj = DaoFactory.GetCasesDao().GetByID(entityID); + if (caseObj == null) + return null; + + result.EntityType = "case"; + result.EntityTitle = caseObj.Title; + + break; + case EntityType.Opportunity: + var dealObj = DaoFactory.GetDealDao().GetByID(entityID); + if (dealObj == null) + return null; + + result.EntityType = "opportunity"; + result.EntityTitle = dealObj.Title; + + break; + default: + return null; + } + + return result; + } + + + private MessageAction GetHistoryCreatedAction(EntityType entityType, int contactId) + { + if (contactId > 0) + { + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyCreatedHistoryEvent : MessageAction.PersonCreatedHistoryEvent; + } + + switch (entityType) + { + case EntityType.Opportunity: + return MessageAction.OpportunityCreatedHistoryEvent; + case EntityType.Case: + return MessageAction.CaseCreatedHistoryEvent; + case EntityType.Any: + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyCreatedHistoryEvent : MessageAction.PersonCreatedHistoryEvent; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private MessageAction GetHistoryDeletedAction(EntityType entityType, int contactId) + { + if (contactId > 0) + { + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyDeletedHistoryEvent : MessageAction.PersonDeletedHistoryEvent; + } + + switch (entityType) + { + case EntityType.Opportunity: + return MessageAction.OpportunityDeletedHistoryEvent; + case EntityType.Case: + return MessageAction.CaseDeletedHistoryEvent; + case EntityType.Any: + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyDeletedHistoryEvent : MessageAction.PersonDeletedHistoryEvent; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private MessageAction GetFilesAttachAction(EntityType entityType, int contactId) + { + if (contactId > 0) + { + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; + } + + switch (entityType) + { + case EntityType.Opportunity: + return MessageAction.OpportunityAttachedFiles; + case EntityType.Case: + return MessageAction.CaseAttachedFiles; + case EntityType.Any: + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private MessageAction GetFilesDetachAction(EntityType entityType, int contactId) + { + if (contactId > 0) + { + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyDetachedFile : MessageAction.PersonDetachedFile; + } + + switch (entityType) + { + case EntityType.Opportunity: + return MessageAction.OpportunityDetachedFile; + case EntityType.Case: + return MessageAction.CaseDetachedFile; + case EntityType.Any: + var contact = DaoFactory.GetContactDao().GetByID(contactId); + return contact is Company ? MessageAction.CompanyDetachedFile : MessageAction.PersonAttachedFiles; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs b/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs new file mode 100644 index 00000000000..d33f7a1f60a --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs @@ -0,0 +1,157 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using ASC.Web.Files.Services.DocumentService; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// Returns a list of all user report files + /// Get report files + /// Reports + /// Report files + /// if user can't create reports + [Read(@"report/files")] + public IEnumerable GetFiles() + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + var reportDao = DaoFactory.ReportDao; + + var files = reportDao.GetFiles(); + + if (!files.Any()) + { + var sampleSettings = CRMReportSampleSettings.LoadForCurrentUser(); + + if (sampleSettings.NeedToGenerate) + { + files = reportDao.SaveSampleReportFiles(); + sampleSettings.NeedToGenerate = false; + sampleSettings.SaveForCurrentUser(); + } + } + + return files.ConvertAll(file => new FileWrapper(file)).OrderByDescending(file => file.Id); + } + + /// Delete the report file with the ID specified in the request + /// File ID + /// Delete report file + /// Reports + /// if user can't create reports + /// if fileid les than 0 + /// if file not found + [Delete(@"report/file/{fileid:int}")] + public void DeleteFile(int fileid) + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + if (fileid < 0) throw new ArgumentException(); + + var file = DaoFactory.ReportDao.GetFile(fileid); + + if (file == null) throw new ItemNotFoundException("File not found"); + + DaoFactory.ReportDao.DeleteFile(fileid); + } + + /// Get the state of the report generation task + /// Get report generation state + /// Reports + /// Report state + /// if user can't create reports + [Read(@"report/status")] + public ReportState GetStatus() + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + return DocbuilderReportsUtility.Status(ReportOrigin.CRM); + } + + /// Terminate the report generation task + /// Terminate report generation + /// Reports + /// if user can't create reports + [Read(@"report/terminate")] + public void Terminate() + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + DocbuilderReportsUtility.Terminate(ReportOrigin.CRM); + } + + /// Check data availability for a report + /// Report type + /// Time period + /// Managers + /// Check report data + /// Reports + /// Object + /// if user can't create reports + [Create(@"report/check")] + public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + return new + { + hasData = ReportHelper.CheckReportData(type, timePeriod, managers), + missingRates = ReportHelper.GetMissingRates(type) + }; + } + + /// Run the report generation task + /// Report type + /// Time period + /// Managers + /// Generate report + /// Reports + /// Report state + /// if user can't create reports + [Create(@"report/generate")] + public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + return ReportHelper.RunGenareteReport(type, timePeriod, managers); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs b/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs new file mode 100644 index 00000000000..3aafdd10495 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs @@ -0,0 +1,677 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the list of all tags associated with the entity with the ID and type specified in the request + /// + /// Entity type + /// Entity ID + /// Get entity tags + /// Tags + /// + /// Tag + /// + /// + [Read(@"{entityType:(contact|opportunity|case)}/tag/{entityid:int}")] + public IEnumerable GetEntityTags(string entityType, int entityid) + { + if (string.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + + switch (entityTypeObj) { + case EntityType.Contact: + case EntityType.Person: + case EntityType.Company: + var contact = DaoFactory.GetContactDao().GetByID(entityid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) + throw new ItemNotFoundException(); + break; + case EntityType.Case: + var cases = DaoFactory.GetCasesDao().GetByID(entityid); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) + throw new ItemNotFoundException(); + break; + case EntityType.Opportunity: + var deal = DaoFactory.GetDealDao().GetByID(entityid); + if (deal == null || !CRMSecurity.CanAccessTo(deal)) + throw new ItemNotFoundException(); + break; + } + + return DaoFactory.GetTagDao().GetEntityTags(entityTypeObj, entityid); + } + + /// + /// Returns the list of all tags for the contact with the ID specified in the request + /// + /// Contact ID + /// Get all contact tags + /// Tags + /// + /// List of contact tags + /// + /// + [Read(@"contact/{contactid:int}/tag")] + public IEnumerable GetContactTags(int contactid) + { + if (contactid <= 0) throw new ArgumentException(); + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) + throw new ItemNotFoundException(); + return DaoFactory.GetTagDao().GetEntityTags(EntityType.Contact, contactid).ToItemList(); + } + + /// + /// Creates the tag for the selected entity with the tag name specified in the request + /// + /// Entity type + /// Tag name + /// Create tag + /// Tags + /// + /// Tag + /// + /// + [Create(@"{entityType:(contact|opportunity|case)}/tag")] + public string CreateTag(string entityType, string tagName) + { + if (string.IsNullOrEmpty(tagName)) throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + + var messageAction = GetEntityTagCreatedAction(entityTypeObj); + DaoFactory.GetTagDao().AddTag(entityTypeObj, tagName); + + MessageService.Send( messageAction, tagName); + + return tagName; + } + + /// + /// Returns the list of all tags associated with the entity type specified in the request + /// + /// Entity type + /// Get tags for entity type + /// Tags + /// + /// Tag + /// + /// + [Read(@"{entityType:(contact|opportunity|case)}/tag")] + public IEnumerable GetAllTags(string entityType) + { + if (string.IsNullOrEmpty(entityType)) throw new ArgumentException(); + var entType = ToEntityType(entityType); + + var tagTitles = DaoFactory.GetTagDao().GetAllTags(entType).ToList(); + var relativeItemsCountArrayJSON = DaoFactory.GetTagDao().GetTagsLinkCount(entType).ToList(); + if (tagTitles.Count != relativeItemsCountArrayJSON.Count) throw new ArgumentException(); + + var result = new List(); + for (var i = 0; i < tagTitles.Count; i++) { + result.Add(new TagWrapper(tagTitles[i], relativeItemsCountArrayJSON[i])); + } + return result.OrderBy(x => x.Title.Trim(), StringComparer.OrdinalIgnoreCase).ToList(); + } + + /// + /// Adds a group of tags to the entity with the ID specified in the request + /// + /// Add tag group to entity + /// Tags + /// Tag type + /// Entity ID + /// Tag name + /// + /// + /// Tag + /// + [Create(@"{entityType:(contact|opportunity|case)}/taglist")] + public string AddTagToBatch(string entityType, IEnumerable entityid, string tagName) + { + var ids = entityid.ToList(); + if (entityid == null || !ids.Any()) throw new ArgumentException(); + + foreach (var entityID in ids) + { + AddTagTo(entityType, entityID, tagName); + } + return tagName; + } + + /// + /// Adds the selected tag to the group of contacts with the parameters specified in the request + /// + /// Add tag to contact group + /// Tags + /// Tag + /// Contact stage ID (warmth) + /// Contact type ID + /// + /// Start date + /// End date + /// Tag name + /// + /// + /// Tag + /// + [Create(@"contact/filter/taglist")] + public string AddTagToBatchContacts( + IEnumerable tags, + int contactStage, + int contactType, + ContactListViewType contactListView, + ApiDateTime fromDate, + ApiDateTime toDate, + string tagName) + { + var contacts = DaoFactory + .ContactDao + .GetContacts(ApiContext.FilterValue, + tags, + contactStage, + contactType, + contactListView, + fromDate, + toDate, + 0, + 0, + null).Where(CRMSecurity.CanEdit).ToList(); + + foreach (var contact in contacts) + { + AddTagTo("contact", contact.ID, tagName); + } + + return tagName; + } + + /// + /// Adds the selected tag to the group of opportunities with the parameters specified in the request + /// + /// Add tag to opportunity group + /// Tags + /// Opportunity responsible + /// Opportunity stage ID + /// Tags + /// Contact ID + /// Participation status: take into account opportunities where the contact is a participant or not + /// Start date + /// End date + /// Opportunity stage type + /// Tag name + /// + /// + /// Tag + /// + [Create(@"opportunity/filter/taglist")] + public string AddTagToBatchDeals( + Guid responsibleid, + int opportunityStagesid, + IEnumerable tags, + int contactid, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + ApiDateTime fromDate, + ApiDateTime toDate, + string tagName) + { + var deals = DaoFactory + .DealDao + .GetDeals( + ApiContext.FilterValue, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, toDate, 0, 0, null).Where(CRMSecurity.CanAccessTo).ToList(); + + foreach (var deal in deals) + { + AddTagTo("opportunity", deal.ID, tagName); + } + return tagName; + } + + /// + /// Adds the selected tag to the group of cases with the parameters specified in the request + /// + /// Add tag to case group + /// Tags + /// Contact ID + /// Case status + /// Tags + /// Tag name + /// + /// + /// Tag + /// + [Create(@"case/filter/taglist")] + public string AddTagToBatchCases(int contactid, bool? isClosed, IEnumerable tags, string tagName) + { + var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null) + .Where(CRMSecurity.CanAccessTo).ToList(); + + if (!caseses.Any()) return tagName; + + foreach (var casese in caseses) + { + AddTagTo("case", casese.ID, tagName); + } + + return tagName; + } + + /// + /// Deletes all the unused tags from the entities with the type specified in the request + /// + /// Delete unused tags + /// Tags + /// Entity type + /// Tags + [Delete(@"{entityType:(contact|opportunity|case)}/tag/unused")] + public IEnumerable DeleteUnusedTag(string entityType) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var entityTypeObj = ToEntityType(entityType); + + var result = DaoFactory.GetTagDao().GetUnusedTags(entityTypeObj); + + DaoFactory.GetTagDao().DeleteUnusedTags(entityTypeObj); + + return new List(result); + } + + /// + /// Adds the selected tag to the entity with the type and ID specified in the request + /// + /// Add tag + /// Tags + /// Entity type + /// Entity ID + /// Tag name + /// + /// + /// Tag + /// + [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/tag")] + public string AddTagTo(string entityType, int entityid, string tagName) + { + if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + DomainObject entityObj; + var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj); + + if (entityTypeObj == EntityType.Contact && !CRMSecurity.CanEdit(entityObj as Contact)) throw CRMSecurity.CreateSecurityException(); + + DaoFactory.GetTagDao().AddTagToEntity(entityTypeObj, entityid, tagName); + + var messageAction = GetTagCreatedAction(entityTypeObj, entityid); + MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, tagName); + + return tagName; + } + + /// + /// Adds the selected tag to the entity (company or person) specified in the request and to all related contacts + /// + /// Add tag + /// Entity type + /// Entity ID + /// Tag name + /// Tags + /// + /// + /// + /// + /// Tag + /// + [Create(@"{entityType:(company|person)}/{entityid:int}/tag/group")] + public string AddContactTagToGroup(string entityType, int entityid, string tagName) + { + if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + if (entityTypeObj != EntityType.Company && entityTypeObj != EntityType.Person) throw new ArgumentException(); + + var contactInst = DaoFactory.GetContactDao().GetByID(entityid); + if (contactInst == null || !CRMSecurity.CanAccessTo(contactInst)) throw new ItemNotFoundException(); + + if (contactInst is Person && entityTypeObj == EntityType.Company) throw new Exception(CRMErrorsResource.ContactIsNotCompany); + if (contactInst is Company && entityTypeObj == EntityType.Person) throw new Exception(CRMErrorsResource.ContactIsNotPerson); + + + var contactIDsToAddTag = new List(); + + + if (contactInst is Company) + { + contactIDsToAddTag.Add(contactInst.ID); + + var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID); + + foreach (var m in members) + { + if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + { + contactIDsToAddTag.Add(m.Key); + } + } + } + else + { + var CompanyID = ((Person)contactInst).CompanyID; + if (CompanyID != 0) + { + var cnt = DaoFactory.GetContactDao().GetByID(CompanyID); + if (cnt != null && cnt is Company && CRMSecurity.CanAccessTo(cnt)) + { + contactIDsToAddTag.Add(CompanyID); + + var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID); + + foreach (var m in members) + { + if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + { + contactIDsToAddTag.Add(m.Key); + } + } + } + else + { + contactIDsToAddTag.Add(contactInst.ID); + } + } + else + { + contactIDsToAddTag.Add(contactInst.ID); + } + } + + DaoFactory.GetTagDao().AddTagToContacts(contactIDsToAddTag.ToArray(), tagName); + + + var entityTitle = contactInst.GetTitle(); + var messageActions = GetTagCreatedGroupAction(entityTypeObj); + foreach (var messageAction in messageActions) + { + MessageService.Send( messageAction, MessageTarget.Create(contactInst.ID), entityTitle, tagName); + } + + return tagName; + } + + /// + /// Deletes the selected tag from the entity with the type specified in the request + /// + /// Delete tag + /// Entity type + /// Tag name + /// Tags + /// + /// + /// + /// Tag + /// + [Delete(@"{entityType:(contact|opportunity|case)}/tag")] + public string DeleteTag(string entityType, string tagName) + { + if (string.IsNullOrEmpty(entityType) || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); + + + var entityTypeObj = ToEntityType(entityType); + + if (!DaoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException(); + + DaoFactory.GetTagDao().DeleteTag(entityTypeObj, tagName); + + var messageAction = GetEntityTagDeletedAction(entityTypeObj); + MessageService.Send( messageAction, tagName); + + return tagName; + } + + /// + /// Deletes the selected tag from the entity with the type and ID specified in the request + /// + /// Remove tag + /// Tags + /// Entity type + /// Entity ID + /// Tag name + /// + /// + /// Tag + /// + [Delete(@"{entityType:(contact|opportunity|case)}/{entityid:int}/tag")] + public string DeleteTagFrom(string entityType, int entityid, string tagName) + { + if (string.IsNullOrEmpty(entityType) || entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + DomainObject entityObj; + var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj); + + if (entityTypeObj == EntityType.Contact && !CRMSecurity.CanEdit(entityObj as Contact)) throw CRMSecurity.CreateSecurityException(); + + if (!DaoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException(); + + DaoFactory.GetTagDao().DeleteTagFromEntity(entityTypeObj, entityid, tagName); + + var messageAction = GetTagDeletedAction(entityTypeObj, entityid); + MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, tagName); + + return tagName; + } + + /// + /// Deletes the selected tag from the entity (company or person) specified in the request and from all related contacts + /// + /// Delete tag + /// Entity type + /// Entity ID + /// Tag name + /// Tags + /// + /// + /// + /// + /// Tag + /// + [Delete(@"{entityType:(company|person)}/{entityid:int}/tag/group")] + public string DeleteContactTagFromGroup(string entityType, int entityid, string tagName) + { + if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + if (entityTypeObj != EntityType.Company && entityTypeObj != EntityType.Person) throw new ArgumentException(); + + var contactInst = DaoFactory.GetContactDao().GetByID(entityid); + if (contactInst == null) throw new ItemNotFoundException(); + + if (contactInst is Person && entityTypeObj == EntityType.Company) throw new Exception(CRMErrorsResource.ContactIsNotCompany); + if (contactInst is Company && entityTypeObj == EntityType.Person) throw new Exception(CRMErrorsResource.ContactIsNotPerson); + + + + var contactIDsForDeleteTag = new List(); + + if (contactInst is Company) + { + contactIDsForDeleteTag.Add(contactInst.ID); + + var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID); + + foreach (var m in members) + { + if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + { + contactIDsForDeleteTag.Add(m.Key); + } + } + } + else + { + var CompanyID = ((Person)contactInst).CompanyID; + if (CompanyID != 0) + { + var cnt = DaoFactory.GetContactDao().GetByID(CompanyID); + if (cnt != null && cnt is Company && CRMSecurity.CanAccessTo(cnt)) + { + contactIDsForDeleteTag.Add(CompanyID); + + var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID); + + foreach (var m in members) + { + if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + { + contactIDsForDeleteTag.Add(m.Key); + } + } + } + else + { + contactIDsForDeleteTag.Add(contactInst.ID); + } + } + else + { + contactIDsForDeleteTag.Add(contactInst.ID); + } + } + + DaoFactory.GetTagDao().DeleteTagFromContacts(contactIDsForDeleteTag.ToArray(), tagName); + + return tagName; + } + + + private static MessageAction GetEntityTagCreatedAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Contact: + return MessageAction.ContactsCreatedTag; + case EntityType.Opportunity: + return MessageAction.OpportunitiesCreatedTag; + case EntityType.Case: + return MessageAction.CasesCreatedTag; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private static MessageAction GetEntityTagDeletedAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Contact: + return MessageAction.ContactsDeletedTag; + case EntityType.Opportunity: + return MessageAction.OpportunitiesDeletedTag; + case EntityType.Case: + return MessageAction.CasesDeletedTag; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private MessageAction GetTagCreatedAction(EntityType entityType, int entityId) + { + switch (entityType) + { + case EntityType.Contact: + var entity = DaoFactory.GetContactDao().GetByID(entityId); + return entity is Company ? MessageAction.CompanyCreatedTag : MessageAction.PersonCreatedTag; + case EntityType.Company: + return MessageAction.CompanyCreatedTag; + case EntityType.Person: + return MessageAction.PersonCreatedTag; + case EntityType.Opportunity: + return MessageAction.OpportunityCreatedTag; + case EntityType.Case: + return MessageAction.CaseCreatedTag; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private static IEnumerable GetTagCreatedGroupAction(EntityType entityType) + { + switch (entityType) + { + case EntityType.Company: + return new List {MessageAction.CompanyCreatedTag, MessageAction.CompanyCreatedPersonsTag}; + case EntityType.Person: + return new List {MessageAction.PersonCreatedTag, MessageAction.PersonCreatedCompanyTag}; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + private MessageAction GetTagDeletedAction(EntityType entityType, int entityId) + { + switch (entityType) + { + case EntityType.Contact: + var entity = DaoFactory.GetContactDao().GetByID(entityId); + return entity is Company ? MessageAction.CompanyDeletedTag : MessageAction.PersonDeletedTag; + case EntityType.Company: + return MessageAction.CompanyDeletedTag; + case EntityType.Person: + return MessageAction.PersonDeletedTag; + case EntityType.Opportunity: + return MessageAction.OpportunityDeletedTag; + case EntityType.Case: + return MessageAction.CaseDeletedTag; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs b/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs new file mode 100644 index 00000000000..289c630a6a9 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs @@ -0,0 +1,387 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Routing; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Creates a new task template container with the type and title specified in the request + /// + /// Type + /// Title + /// Create task template container + /// Task Templates + /// + /// Task template container + /// + /// + /// false + [Create(@"{entityType:(contact|person|company|opportunity|case)}/tasktemplatecontainer")] + public TaskTemplateContainerWrapper CreateTaskTemplateContainer(string entityType, string title) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var taskTemplateContainer = new TaskTemplateContainer + { + EntityType = ToEntityType(entityType), + Title = title + }; + + taskTemplateContainer.ID = DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(taskTemplateContainer); + return ToTaskTemplateContainerWrapper(taskTemplateContainer); + } + + /// + /// Returns the complete list of all the task template containers available on the portal + /// + /// Type + /// Get task template container list + /// Task Templates + /// + /// Task template container list + /// + /// false + [Read(@"{entityType:(contact|person|company|opportunity|case)}/tasktemplatecontainer")] + public IEnumerable GetTaskTemplateContainers(string entityType) + { + return ToTaskListTemplateContainerWrapper(DaoFactory.GetTaskTemplateContainerDao().GetItems(ToEntityType(entityType))); + } + + /// + /// Deletes the task template container with the ID specified in the request + /// + /// Task template container ID + /// Delete task template container + /// Task Templates + /// + /// Deleted task template container + /// + /// + /// + /// false + [Delete(@"tasktemplatecontainer/{containerid:int}")] + public TaskTemplateContainerWrapper DeleteTaskTemplateContainer(int containerid) + { + if (containerid <= 0) throw new ArgumentException(); + + var result = ToTaskTemplateContainerWrapper(DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid)); + if (result == null) throw new ItemNotFoundException(); + + DaoFactory.GetTaskTemplateContainerDao().Delete(containerid); + + return result; + } + + /// + /// Updates the task template container with the ID specified in the request + /// + /// Task template container ID + /// Title + /// Update task template container + /// Task Templates + /// + /// Task template container + /// + /// + /// + /// false + [Update(@"tasktemplatecontainer/{containerid:int}")] + public TaskTemplateContainerWrapper UpdateTaskTemplateContainer(int containerid, string title) + { + if (containerid <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var result = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + if (result == null) throw new ItemNotFoundException(); + + result.Title = title; + + DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(result); + + return ToTaskTemplateContainerWrapper(result); + } + + /// + /// Returns the detailed information on the task template container with the ID specified in the request + /// + /// Task template container ID + /// Get task template container by ID + /// Task Templates + /// + /// Task template container + /// + /// + /// + /// false + [Read(@"tasktemplatecontainer/{containerid:int}")] + public TaskTemplateContainerWrapper GetTaskTemplateContainerByID(int containerid) + { + if (containerid <= 0) throw new ArgumentException(); + + var item = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + if (item == null) throw new ItemNotFoundException(); + + return ToTaskTemplateContainerWrapper(item); + } + + /// + /// Returns the list of all tasks in the container with the ID specified in the request + /// + /// Task template container ID + /// Get task template list by contaier ID + /// Task Templates + /// + /// Task template list + /// + /// + /// + /// false + [Read(@"tasktemplatecontainer/{containerid:int}/tasktemplate")] + public IEnumerable GetTaskTemplates(int containerid) + { + if (containerid <= 0) throw new ArgumentException(); + + var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + if (container == null) throw new ItemNotFoundException(); + + return DaoFactory.GetTaskTemplateDao().GetList(containerid).ConvertAll(ToTaskTemplateWrapper); + } + + /// + /// Creates a new task template with the parameters specified in the request in the container with the selected ID + /// + /// Task template container ID + /// Title + /// Description + /// Responsible ID + /// Category ID + /// Responsible notification: notify or not + /// Ticks offset + /// + /// Create task template + /// Task Templates + /// Task template + /// + /// + /// false + [Create(@"tasktemplatecontainer/{containerid:int}/tasktemplate")] + public TaskTemplateWrapper CreateTaskTemplate( + int containerid, + string title, + string description, + Guid responsibleid, + int categoryid, + bool isNotify, + long offsetTicks, + bool deadLineIsFixed + ) + { + if (containerid <= 0 || string.IsNullOrEmpty(title) || categoryid <= 0) throw new ArgumentException(); + + var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + if (container == null) throw new ItemNotFoundException(); + + var item = new TaskTemplate + { + CategoryID = categoryid, + ContainerID = containerid, + DeadLineIsFixed = deadLineIsFixed, + Description = description, + isNotify = isNotify, + ResponsibleID = responsibleid, + Title = title, + Offset = TimeSpan.FromTicks(offsetTicks) + }; + + item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); + + return ToTaskTemplateWrapper(item); + } + + /// + /// Updates the selected task template with the parameters specified in the request in the container with the selected ID + /// + /// Task template ID + /// Task template container ID + /// Title + /// Description + /// Responsible ID + /// Category ID + /// Responsible notification: notify or not + /// Ticks offset + /// + /// Update task template + /// Task Templates + /// Task template + /// + /// + /// false + [Update(@"tasktemplatecontainer/{containerid:int}/tasktemplate")] + public TaskTemplateWrapper UpdateTaskTemplate( + int id, + int containerid, + string title, + string description, + Guid responsibleid, + int categoryid, + bool isNotify, + long offsetTicks, + bool deadLineIsFixed + ) + { + if (containerid <= 0 || string.IsNullOrEmpty(title) || categoryid <= 0) throw new ArgumentException(); + + var updatingItem = DaoFactory.GetTaskTemplateDao().GetByID(id); + if (updatingItem == null) throw new ItemNotFoundException(); + + var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + if (container == null) throw new ItemNotFoundException(); + + var item = new TaskTemplate + { + CategoryID = categoryid, + ContainerID = containerid, + DeadLineIsFixed = deadLineIsFixed, + Description = description, + isNotify = isNotify, + ResponsibleID = responsibleid, + Title = title, + ID = id, + Offset = TimeSpan.FromTicks(offsetTicks) + }; + + item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); + + return ToTaskTemplateWrapper(item); + } + + /// + /// Deletes the task template with the ID specified in the request + /// + /// Task template ID + /// Delete task template + /// Task Templates + /// Task template + /// + /// + /// false + [Delete(@"tasktemplatecontainer/tasktemplate/{id:int}")] + public TaskTemplateWrapper DeleteTaskTemplate(int id) + { + if (id <= 0) throw new ArgumentException(); + + var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id); + if (taskTemplate == null) throw new ItemNotFoundException(); + + var result = ToTaskTemplateWrapper(taskTemplate); + + DaoFactory.GetTaskTemplateDao().Delete(id); + + return result; + } + + /// + /// Return the task template with the ID specified in the request + /// + /// Task template ID + /// Get task template by ID + /// Task Templates + /// Task template + /// + /// + /// false + [Read(@"tasktemplatecontainer/tasktemplate/{id:int}")] + public TaskTemplateWrapper GetTaskTemplateByID(int id) + { + if (id <= 0) throw new ArgumentException(); + + var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id); + if (taskTemplate == null) throw new ItemNotFoundException(); + + return ToTaskTemplateWrapper(taskTemplate); + } + + protected TaskTemplateWrapper ToTaskTemplateWrapper(TaskTemplate taskTemplate) + { + return new TaskTemplateWrapper + { + Category = GetTaskCategoryByID(taskTemplate.CategoryID), + ContainerID = taskTemplate.ContainerID, + DeadLineIsFixed = taskTemplate.DeadLineIsFixed, + Description = taskTemplate.Description, + ID = taskTemplate.ID, + isNotify = taskTemplate.isNotify, + Title = taskTemplate.Title, + OffsetTicks = taskTemplate.Offset.Ticks, + Responsible = EmployeeWraper.Get(taskTemplate.ResponsibleID) + }; + } + + protected IEnumerable ToTaskListTemplateContainerWrapper(IEnumerable items) + { + var result = new List(); + + var taskTemplateDictionary = DaoFactory.GetTaskTemplateDao().GetAll() + .GroupBy(item => item.ContainerID) + .ToDictionary(x => x.Key, y => y.Select(ToTaskTemplateWrapper)); + + foreach (var item in items) + { + var taskTemplateContainer = new TaskTemplateContainerWrapper + { + Title = item.Title, + EntityType = item.EntityType.ToString(), + ID = item.ID + }; + + if (taskTemplateDictionary.ContainsKey(taskTemplateContainer.ID)) + { + taskTemplateContainer.Items = taskTemplateDictionary[taskTemplateContainer.ID]; + } + + result.Add(taskTemplateContainer); + } + + return result; + } + + protected TaskTemplateContainerWrapper ToTaskTemplateContainerWrapper(TaskTemplateContainer item) + { + return ToTaskListTemplateContainerWrapper(new List + { + item + }).FirstOrDefault(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs new file mode 100644 index 00000000000..995a356e56c --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs @@ -0,0 +1,699 @@ +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Common; +using ASC.Common.Web; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Services.WCFService; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + + /// + /// Returns the detailed information about the task with the ID specified in the request + /// + /// Task ID + /// Task + /// Get task by ID + /// Tasks + /// + /// + [Read(@"task/{taskid:int}")] + public TaskWrapper GetTaskByID(int taskid) + { + if (taskid <= 0) throw new ArgumentException(); + + var task = DaoFactory.GetTaskDao().GetByID(taskid); + if (task == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(task)) + { + throw CRMSecurity.CreateSecurityException(); + } + + return TaskWrapperHelper.Get(task); + } + + /// + /// Returns the list of tasks matching the creteria specified in the request + /// + /// Task responsible + /// Task category ID + /// Show open or closed tasks only + /// Earliest task due date + /// Latest task due date + /// Related entity type + /// Related entity ID + /// + /// Get task list + /// Tasks + /// + /// Task list + /// + [Read(@"task/filter")] + public IEnumerable GetAllTasks( + Guid responsibleid, + int categoryid, + bool? isClosed, + ApiDateTime fromDate, + ApiDateTime toDate, + string entityType, + int entityid) + { + TaskSortedByType taskSortedByType; + + if (!string.IsNullOrEmpty(entityType) && + !( + string.Compare(entityType, "contact", StringComparison.OrdinalIgnoreCase) == 0 || + string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || + string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0) + ) + throw new ArgumentException(); + + var searchText = ApiContext.FilterValue; + + IEnumerable result; + + OrderBy taskOrderBy; + + if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out taskSortedByType)) + { + taskOrderBy = new OrderBy(taskSortedByType, !ApiContext.SortDescending); + } + else if (string.IsNullOrEmpty(ApiContext.SortBy)) + { + taskOrderBy = new OrderBy(TaskSortedByType.DeadLine, true); + } + else + { + taskOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (taskOrderBy != null) + { + result = ToTaskListWrapper( + DaoFactory.GetTaskDao() + .GetTasks( + searchText, + responsibleid, + categoryid, + isClosed, + fromDate, + toDate, + ToEntityType(entityType), + entityid, + fromIndex, + count, + taskOrderBy)).ToList(); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + result = ToTaskListWrapper( + DaoFactory + .GetTaskDao() + .GetTasks( + searchText, + responsibleid, + categoryid, + isClosed, + fromDate, + toDate, + ToEntityType(entityType), + entityid, + 0, + 0, null)).ToList(); + + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory + .GetTaskDao() + .GetTasksCount( + searchText, + responsibleid, + categoryid, + isClosed, + fromDate, + toDate, + ToEntityType(entityType), + entityid); + } + + ApiContext.SetTotalCount(totalCount); + + return result; + } + + /// + /// Open anew the task with the ID specified in the request + /// + /// Resume task + /// Tasks + /// Task ID + /// + /// + /// Task + /// + [Update(@"task/{taskid:int}/reopen")] + public TaskWrapper ReOpenTask(int taskid) + { + if (taskid <= 0) throw new ArgumentException(); + + DaoFactory.GetTaskDao().OpenTask(taskid); + + var task = DaoFactory.GetTaskDao().GetByID(taskid); + + MessageService.Send(MessageAction.CrmTaskOpened, MessageTarget.Create(task.ID), task.Title); + + return TaskWrapperHelper.Get(task); + + } + + /// + /// Close the task with the ID specified in the request + /// + /// Close task + /// Tasks + /// Task ID + /// + /// + /// Task + /// + [Update(@"task/{taskid:int}/close")] + public TaskWrapper CloseTask(int taskid) + { + if (taskid <= 0) throw new ArgumentException(); + + DaoFactory.GetTaskDao().CloseTask(taskid); + + var task = DaoFactory.GetTaskDao().GetByID(taskid); + MessageService.Send(MessageAction.CrmTaskClosed, MessageTarget.Create(task.ID), task.Title); + + return TaskWrapperHelper.Get(task); + + } + + /// + /// Delete the task with the ID specified in the request + /// + /// Delete task + /// Tasks + /// Task ID + /// + /// + /// + /// Deleted task + /// + [Delete(@"task/{taskid:int}")] + public TaskWrapper DeleteTask(int taskid) + { + if (taskid <= 0) throw new ArgumentException(); + + var task = DaoFactory.GetTaskDao().GetByID(taskid); + if (task == null) throw new ItemNotFoundException(); + + DaoFactory.GetTaskDao().DeleteTask(taskid); + MessageService.Send(MessageAction.CrmTaskDeleted, MessageTarget.Create(task.ID), task.Title); + + return TaskWrapperHelper.Get(task); + + } + + /// + /// Creates the task with the parameters (title, description, due date, etc.) specified in the request + /// + /// Task title + /// Task description + /// Task due date + /// Task responsible ID + /// Task category ID + /// Contact ID + /// Related entity type + /// Related entity ID + /// Notify the responsible about the task + /// Time period in minutes for reminder to the responsible about the task + /// + /// Create task + /// Tasks + /// Task + [Create(@"task")] + public TaskWrapper CreateTask( + string title, + string description, + ApiDateTime deadline, + Guid responsibleId, + int categoryId, + int contactId, + string entityType, + int entityId, + bool isNotify, + int alertValue + ) + { + if (!string.IsNullOrEmpty(entityType) && + !( + string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || + string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0 + ) + || categoryId <= 0) + throw new ArgumentException(); + + var listItem = DaoFactory.GetListItemDao().GetByID(categoryId); + if (listItem == null) throw new ItemNotFoundException(CRMErrorsResource.TaskCategoryNotFound); + + var task = new Task + { + Title = title, + Description = description, + ResponsibleID = responsibleId, + CategoryID = categoryId, + DeadLine = deadline, + ContactID = contactId, + EntityType = ToEntityType(entityType), + EntityID = entityId, + IsClosed = false, + AlertValue = alertValue + }; + + task = DaoFactory.GetTaskDao().SaveOrUpdateTask(task); + + if (isNotify) + { + Contact taskContact = null; + Cases taskCase = null; + Deal taskDeal = null; + + if (task.ContactID > 0) + { + taskContact = DaoFactory.GetContactDao().GetByID(task.ContactID); + } + + if (task.EntityID > 0) + { + switch (task.EntityType) + { + case EntityType.Case: + taskCase = DaoFactory.GetCasesDao().GetByID(task.EntityID); + break; + case EntityType.Opportunity: + taskDeal = DaoFactory.GetDealDao().GetByID(task.EntityID); + break; + } + } + + NotifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null); + } + + MessageService.Send(MessageAction.CrmTaskCreated, MessageTarget.Create(task.ID), task.Title); + + return TaskWrapperHelper.Get(task); + } + + /// + /// Creates the group of the same task with the parameters (title, description, due date, etc.) specified in the request for several contacts + /// + /// Task title + /// Task description + /// Task due date + /// Task responsible ID + /// Task category ID + /// contact ID list + /// Related entity type + /// Related entity ID + /// Notify the responsible about the task + /// Time period in minutes for reminder to the responsible about the task + /// + /// Create task list + /// Tasks + /// Tasks + /// false + [Create(@"contact/task/group")] + public IEnumerable CreateTaskGroup( + string title, + string description, + ApiDateTime deadline, + Guid responsibleId, + int categoryId, + int[] contactId, + string entityType, + int entityId, + bool isNotify, + int alertValue) + { + var tasks = new List(); + + if ( + !string.IsNullOrEmpty(entityType) && + !(string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || + string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0) + ) + throw new ArgumentException(); + + foreach (var cid in contactId) + { + tasks.Add(new Task + { + Title = title, + Description = description, + ResponsibleID = responsibleId, + CategoryID = categoryId, + DeadLine = deadline, + ContactID = cid, + EntityType = ToEntityType(entityType), + EntityID = entityId, + IsClosed = false, + AlertValue = alertValue + }); + } + + tasks = DaoFactory.GetTaskDao().SaveOrUpdateTaskList(tasks).ToList(); + + string taskCategory = null; + if (isNotify) + { + if (categoryId > 0) + { + var listItem = DaoFactory.GetListItemDao().GetByID(categoryId); + if (listItem == null) throw new ItemNotFoundException(); + + taskCategory = listItem.Title; + } + } + + for (var i = 0; i < tasks.Count; i++) + { + if (!isNotify) continue; + + Contact taskContact = null; + Cases taskCase = null; + Deal taskDeal = null; + + if (tasks[i].ContactID > 0) + { + taskContact = DaoFactory.GetContactDao().GetByID(tasks[i].ContactID); + } + + if (tasks[i].EntityID > 0) + { + switch (tasks[i].EntityType) + { + case EntityType.Case: + taskCase = DaoFactory.GetCasesDao().GetByID(tasks[i].EntityID); + break; + case EntityType.Opportunity: + taskDeal = DaoFactory.GetDealDao().GetByID(tasks[i].EntityID); + break; + } + } + + NotifyClient.SendAboutResponsibleByTask(tasks[i], taskCategory, taskContact, taskCase, taskDeal, null); + } + + if (tasks.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(contactId); + var task = tasks.First(); + MessageService.Send( MessageAction.ContactsCreatedCrmTasks, MessageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title); + } + + return ToTaskListWrapper(tasks); + } + + + /// + /// Updates the selected task with the parameters (title, description, due date, etc.) specified in the request + /// + /// Task ID + /// Task title + /// Task description + /// Task due date + /// Task responsible ID + /// Task category ID + /// Contact ID + /// Related entity type + /// Related entity ID + /// Notify or not + /// Time period in minutes for reminder to the responsible about the task + /// Update task + /// Tasks + /// Task + [Update(@"task/{taskid:int}")] + public TaskWrapper UpdateTask( + int taskid, + string title, + string description, + ApiDateTime deadline, + Guid responsibleid, + int categoryid, + int contactid, + string entityType, + int entityid, + bool isNotify, + int alertValue) + { + if (!string.IsNullOrEmpty(entityType) && + !(string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || + string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0 + ) || categoryid <= 0) + throw new ArgumentException(); + + var listItem = DaoFactory.GetListItemDao().GetByID(categoryid); + if (listItem == null) throw new ItemNotFoundException(CRMErrorsResource.TaskCategoryNotFound); + + var task = new Task + { + ID = taskid, + Title = title, + Description = description, + DeadLine = deadline, + AlertValue = alertValue, + ResponsibleID = responsibleid, + CategoryID = categoryid, + ContactID = contactid, + EntityID = entityid, + EntityType = ToEntityType(entityType) + }; + + + task = DaoFactory.GetTaskDao().SaveOrUpdateTask(task); + + if (isNotify) + { + Contact taskContact = null; + Cases taskCase = null; + Deal taskDeal = null; + + if (task.ContactID > 0) + { + taskContact = DaoFactory.GetContactDao().GetByID(task.ContactID); + } + + if (task.EntityID > 0) + { + switch (task.EntityType) + { + case EntityType.Case: + taskCase = DaoFactory.GetCasesDao().GetByID(task.EntityID); + break; + case EntityType.Opportunity: + taskDeal = DaoFactory.GetDealDao().GetByID(task.EntityID); + break; + } + } + + NotifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null); + } + + MessageService.Send(MessageAction.CrmTaskUpdated, MessageTarget.Create(task.ID), task.Title); + + return TaskWrapperHelper.Get(task); + } + + /// false + [Update(@"task/{taskid:int}/creationdate")] + public void SetTaskCreationDate(int taskId, ApiDateTime creationDate) + { + var dao = DaoFactory.GetTaskDao(); + var task = dao.GetByID(taskId); + + if (task == null || !CRMSecurity.CanAccessTo(task)) + throw new ItemNotFoundException(); + + dao.SetTaskCreationDate(taskId, creationDate); + } + + /// false + [Update(@"task/{taskid:int}/lastmodifeddate")] + public void SetTaskLastModifedDate(int taskId, ApiDateTime lastModifedDate) + { + var dao = DaoFactory.GetTaskDao(); + var task = dao.GetByID(taskId); + + if (task == null || !CRMSecurity.CanAccessTo(task)) + throw new ItemNotFoundException(); + + dao.SetTaskLastModifedDate(taskId, lastModifedDate); + } + + private IEnumerable ToTaskListWrapper(IEnumerable itemList) + { + var result = new List(); + + var contactIDs = new List(); + var taskIDs = new List(); + var categoryIDs = new List(); + var entityWrappersIDs = new Dictionary>(); + + foreach (var item in itemList) + { + taskIDs.Add(item.ID); + + if (!categoryIDs.Contains(item.CategoryID)) + { + categoryIDs.Add(item.CategoryID); + } + + if (item.ContactID > 0 && !contactIDs.Contains(item.ContactID)) + { + contactIDs.Add(item.ContactID); + } + + if (item.EntityID > 0) + { + if (item.EntityType != EntityType.Opportunity && item.EntityType != EntityType.Case) continue; + + if (!entityWrappersIDs.ContainsKey(item.EntityType)) + { + entityWrappersIDs.Add(item.EntityType, new List + { + item.EntityID + }); + } + else if (!entityWrappersIDs[item.EntityType].Contains(item.EntityID)) + { + entityWrappersIDs[item.EntityType].Add(item.EntityID); + } + } + } + + var entityWrappers = new Dictionary(); + + foreach (var entityType in entityWrappersIDs.Keys) + { + switch (entityType) + { + case EntityType.Opportunity: + DaoFactory.GetDealDao().GetDeals(entityWrappersIDs[entityType].Distinct().ToArray()) + .ForEach(item => + { + if (item == null) return; + + entityWrappers.Add( + string.Format("{0}_{1}", (int)entityType, item.ID), + new EntityWrapper + { + EntityId = item.ID, + EntityTitle = item.Title, + EntityType = "opportunity" + }); + }); + break; + case EntityType.Case: + DaoFactory.GetCasesDao().GetByID(entityWrappersIDs[entityType].ToArray()) + .ForEach(item => + { + if (item == null) return; + + entityWrappers.Add( + string.Format("{0}_{1}", (int)entityType, item.ID), + new EntityWrapper + { + EntityId = item.ID, + EntityTitle = item.Title, + EntityType = "case" + }); + }); + break; + } + } + + var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => new TaskCategoryBaseWrapper(x)); + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper); + var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper); + + foreach (var item in itemList) + { + var taskWrapper = new TaskWrapper(item) { CanEdit = CRMSecurity.CanEdit(item) }; + + if (contacts.ContainsKey(item.ContactID)) + { + taskWrapper.Contact = contacts[item.ContactID]; + } + if (restrictedContacts.ContainsKey(item.ContactID)) + { + taskWrapper.Contact = restrictedContacts[item.ContactID]; + /*Hide some fields. Should be refactored! */ + taskWrapper.Contact.Currency = null; + taskWrapper.Contact.Email = null; + taskWrapper.Contact.AccessList = null; + } + + if (item.EntityID > 0) + { + var entityStrKey = string.Format("{0}_{1}", (int)item.EntityType, item.EntityID); + + if (entityWrappers.ContainsKey(entityStrKey)) + { + taskWrapper.Entity = entityWrappers[entityStrKey]; + } + } + + if (categories.ContainsKey(item.CategoryID)) + { + taskWrapper.Category = categories[item.CategoryID]; + } + + result.Add(taskWrapper); + } + + return result; + } + + + } + + + + //public CRMController(CRMSecurity cRMSecurity, + // DaoFactory daoFactory, + // ApiContext apiContext, + // MessageTarget messageTarget, + // NotifyClient notifyClient, + // TaskWrapperHelper taskWrapperHelper) + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs new file mode 100644 index 00000000000..06dda4d12f7 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs @@ -0,0 +1,545 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common.Threading.Progress; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.Core.Utility; +using ASC.Web.CRM.Classes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the list of all currencies currently available on the portal + /// + /// Get currency list + /// Common + /// + /// List of available currencies + /// + [Read(@"settings/currency")] + public IEnumerable GetAvaliableCurrency() + { + return CurrencyProvider.GetAll().ConvertAll(item => new CurrencyInfoWrapper(item)).ToItemList(); + } + + /// + /// Returns the result of convertation from one currency to another + /// + /// Amount to convert + /// Old currency key + /// New currency key + /// Get the result of convertation + /// Common + /// + /// Decimal result of convertation + /// + [Read(@"settings/currency/convert")] + public Decimal ConvertAmount(Decimal amount, String fromcurrency, String tocurrency) + { + return CurrencyProvider.MoneyConvert(amount, fromcurrency, tocurrency); + } + + /// + /// Returns the summary table with rates for selected currency + /// + /// Currency (Abbreviation) + /// Get the summary table + /// Common + /// + /// Dictionary of currencies and rates + /// + /// + [Read(@"settings/currency/summarytable")] + public IEnumerable GetSummaryTable(String currency) + { + var result = new List(); + + if (string.IsNullOrEmpty(currency)) + { + throw new ArgumentException(); + } + + var cur = CurrencyProvider.Get(currency.ToUpper()); + if (cur == null) throw new ArgumentException(); + + var table = CurrencyProvider.MoneyConvert(cur); + table.ToList().ForEach(tableItem => result.Add(ToCurrencyRateInfoWrapper(tableItem.Key, tableItem.Value))); + return result; + } + + /// + /// + /// + /// Change contact status group auto + /// + /// Contacts + /// + /// ChangeContactStatusGroupAuto setting value (true, false or null) + /// + /// + [Update(@"contact/status/settings")] + public Boolean? UpdateCRMContactStatusSettings(Boolean? changeContactStatusGroupAuto) + { + var tenantSettings = Global.TenantSettings; + tenantSettings.ChangeContactStatusGroupAuto = changeContactStatusGroupAuto; + tenantSettings.Save(); + + MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated); + + return changeContactStatusGroupAuto; + } + + /// + /// + /// + /// Write mail to history auto + /// + /// Contacts + /// + /// WriteMailToHistoryAuto setting value (true or false) + /// + /// + [Update(@"contact/mailtohistory/settings")] + public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAuto) + { + var tenantSettings = Global.TenantSettings; + tenantSettings.WriteMailToHistoryAuto = writeMailToHistoryAuto; + tenantSettings.Save(); + //MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated); + + return writeMailToHistoryAuto; + } + + /// + /// + /// + /// add tag to contact group auto + /// + /// Contacts + /// + /// AddTagToContactGroupAuto setting value (true, false or null) + /// + /// + [Update(@"contact/tag/settings")] + public Boolean? UpdateCRMContactTagSettings(Boolean? addTagToContactGroupAuto) + { + var tenantSettings = Global.TenantSettings; + tenantSettings.AddTagToContactGroupAuto = addTagToContactGroupAuto; + tenantSettings.Save(); + + MessageService.Send( MessageAction.ContactsTagSettingsUpdated); + + return addTagToContactGroupAuto; + } + + + /// + /// Set IsConfiguredPortal tenant setting and website contact form key specified in the request + /// + /// Set tenant settings + /// Common + /// + /// IsConfiguredPortal setting value (true or false) + /// + [Update(@"settings")] + public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + var tenantSettings = Global.TenantSettings; + tenantSettings.IsConfiguredPortal = configured ?? true; + tenantSettings.WebFormKey = webFormKey ?? Guid.NewGuid(); + tenantSettings.Save(); + return tenantSettings.IsConfiguredPortal; + } + + /// + /// Save organisation company name + /// + /// Organisation company name + /// Save organisation company name + /// Organisation + /// Organisation company name + /// + [Update(@"settings/organisation/base")] + public String UpdateOrganisationSettingsCompanyName(String companyName) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + var tenantSettings = Global.TenantSettings; + if (tenantSettings.InvoiceSetting == null) + { + tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; + } + tenantSettings.InvoiceSetting.CompanyName = companyName; + + tenantSettings.Save(); + + MessageService.Send( MessageAction.OrganizationProfileUpdatedCompanyName, companyName); + + return companyName; + } + + /// + /// Save organisation company address + /// + /// Organisation company street/building/apartment address + /// City + /// State + /// Zip + /// Country + /// Save organisation company address + /// Organisation + /// Returns a JSON object with the organization company address details + /// + [Update(@"settings/organisation/address")] + public String UpdateOrganisationSettingsCompanyAddress(String street, String city, String state, String zip, String country) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var tenantSettings = Global.TenantSettings; + + if (tenantSettings.InvoiceSetting == null) + { + tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; + } + + var companyAddress = Newtonsoft.Json.JsonConvert.SerializeObject(new + { + type = AddressCategory.Billing.ToString(), + street, + city, + state, + zip, + country + }); + + tenantSettings.InvoiceSetting.CompanyAddress = companyAddress; + + tenantSettings.Save(); + + MessageService.Send( MessageAction.OrganizationProfileUpdatedAddress); + + return companyAddress; + } + + /// + /// Save organisation logo + /// + /// Reset organisation logo + /// Save organisation logo + /// Organisation + /// Organisation logo ID + /// + /// + [Update(@"settings/organisation/logo")] + public Int32 UpdateOrganisationSettingsLogo(bool reset) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + int companyLogoID; + if (!reset) + { + companyLogoID = OrganisationLogoManager.TryUploadOrganisationLogoFromTmp(DaoFactory); + if (companyLogoID == 0) + { + throw new Exception("Downloaded image not found"); + } + } + else + { + companyLogoID = 0; + } + + var tenantSettings = Global.TenantSettings; + if (tenantSettings.InvoiceSetting == null) + { + tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; + } + tenantSettings.InvoiceSetting.CompanyLogoID = companyLogoID; + + tenantSettings.Save(); + MessageService.Send( MessageAction.OrganizationProfileUpdatedInvoiceLogo); + + return companyLogoID; + } + + /// + /// Get organisation logo in base64 format (if 'id' is 0 then take current logo) + /// + /// organisation logo id + /// Get organisation logo + /// Organisation + /// Organisation logo content in base64 + /// + [Read(@"settings/organisation/logo")] + public String GetOrganisationSettingsLogo(int id) + { + if (id != 0) + { + return OrganisationLogoManager.GetOrganisationLogoBase64(id); + } + else + { + var tenantSettings = Global.TenantSettings; + if (tenantSettings.InvoiceSetting == null) + { + return string.Empty; + } + + return OrganisationLogoManager.GetOrganisationLogoBase64(tenantSettings.InvoiceSetting.CompanyLogoID); + } + } + + /// + /// Change Website Contact Form key + /// + /// Change web form key + /// Common + /// Web form key + /// + [Update(@"settings/webformkey/change")] + public string ChangeWebToLeadFormKey() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var tenantSettings = Global.TenantSettings; + tenantSettings.WebFormKey = Guid.NewGuid(); + + tenantSettings.Save(); + MessageService.Send( MessageAction.WebsiteContactFormUpdatedKey); + + return tenantSettings.WebFormKey.ToString(); + } + + /// + /// Change default CRM currency + /// + /// Currency (Abbreviation) + /// Change currency + /// Common + /// currency + /// + /// + [Update(@"settings/currency")] + public CurrencyInfoWrapper UpdateCRMCurrency(String currency) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + if (string.IsNullOrEmpty(currency)) + { + throw new ArgumentException(); + } + currency = currency.ToUpper(); + var cur = CurrencyProvider.Get(currency); + if (cur == null) throw new ArgumentException(); + + Global.SaveDefaultCurrencySettings(cur); + MessageService.Send( MessageAction.CrmDefaultCurrencyUpdated); + + return ToCurrencyInfoWrapper(cur); + } + + /// false + [Create(@"{entityType:(contact|opportunity|case|task)}/import/start")] + public string StartImportFromCSV(string entityType, string csvFileURI, string jsonSettings) + { + EntityType entityTypeObj; + + if (string.IsNullOrEmpty(entityType) || string.IsNullOrEmpty(csvFileURI) || string.IsNullOrEmpty(jsonSettings)) throw new ArgumentException(); + switch (entityType.ToLower()) + { + case "contact": + entityTypeObj = EntityType.Contact; + break; + case "opportunity": + entityTypeObj = EntityType.Opportunity; + break; + case "case": + entityTypeObj = EntityType.Case; + break; + case "task": + entityTypeObj = EntityType.Task; + break; + default: + throw new ArgumentException(); + } + + new ImportFromCSVManager().StartImport(entityTypeObj, csvFileURI, jsonSettings); + return ""; + } + + /// false + [Read(@"{entityType:(contact|opportunity|case|task)}/import/status")] + public IProgressItem GetImportFromCSVStatus(string entityType) + { + EntityType entityTypeObj; + + if (string.IsNullOrEmpty(entityType)) throw new ArgumentException(); + switch (entityType.ToLower()) + { + case "contact": + entityTypeObj = EntityType.Contact; + break; + case "opportunity": + entityTypeObj = EntityType.Opportunity; + break; + case "case": + entityTypeObj = EntityType.Case; + break; + case "task": + entityTypeObj = EntityType.Task; + break; + default: + throw new ArgumentException(); + } + + return ImportFromCSV.GetStatus(entityTypeObj); + } + + /// false + [Read(@"import/samplerow")] + public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string jsonSettings) + { + if (String.IsNullOrEmpty(csvFileURI) || indexRow < 0) throw new ArgumentException(); + + if (!Global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException(); + + var CSVFileStream = Global.GetStore().GetReadStream("temp", csvFileURI); + + return ImportFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings); + } + + /// false + [Create(@"import/uploadfake")] + public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings) + { + return new ImportFromCSVManager().ProcessUploadFake(csvFileURI, jsonSettings); + } + + /// false + [Read(@"export/status")] + public IProgressItem GetExportStatus() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + return ExportToCsv.GetStatus(false); + } + + /// false + [Update(@"export/cancel")] + public IProgressItem CancelExport() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + ExportToCsv.Cancel(false); + return ExportToCsv.GetStatus(false); + } + + /// false + [Create(@"export/start")] + public IProgressItem StartExport() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + MessageService.Send( MessageAction.CrmAllDataExported); + + return ExportToCsv.Start(null, CRMSettingResource.Export + ".zip"); + } + + /// false + [Read(@"export/partial/status")] + public IProgressItem GetPartialExportStatus() + { + return ExportToCsv.GetStatus(true); + } + + /// false + [Update(@"export/partial/cancel")] + public IProgressItem CancelPartialExport() + { + ExportToCsv.Cancel(true); + return ExportToCsv.GetStatus(true); + } + + /// false + [Create(@"export/partial/{entityType:(contact|opportunity|case|task|invoiceitem)}/start")] + public IProgressItem StartPartialExport(string entityType, string base64FilterString) + { + if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException(); + + FilterObject filterObject; + String fileName; + + switch (entityType.ToLower()) + { + case "contact": + filterObject = new ContactFilterObject(base64FilterString); + fileName = CRMContactResource.Contacts + ".csv"; + MessageService.Send( MessageAction.ContactsExportedToCsv); + break; + case "opportunity": + filterObject = new DealFilterObject(base64FilterString); + fileName = CRMCommonResource.DealModuleName + ".csv"; + MessageService.Send( MessageAction.OpportunitiesExportedToCsv); + break; + case "case": + filterObject = new CasesFilterObject(base64FilterString); + fileName = CRMCommonResource.CasesModuleName + ".csv"; + MessageService.Send( MessageAction.CasesExportedToCsv); + break; + case "task": + filterObject = new TaskFilterObject(base64FilterString); + fileName = CRMCommonResource.TaskModuleName + ".csv"; + MessageService.Send( MessageAction.CrmTasksExportedToCsv); + break; + case "invoiceitem": + fileName = CRMCommonResource.ProductsAndServices + ".csv"; + filterObject = new InvoiceItemFilterObject(base64FilterString); + break; + default: + throw new ArgumentException(); + } + + return ExportToCsv.Start(filterObject, fileName); + } + + + protected CurrencyInfoWrapper ToCurrencyInfoWrapper(CurrencyInfo currencyInfo) + { + return currencyInfo == null ? null : new CurrencyInfoWrapper(currencyInfo); + } + + protected CurrencyRateInfoWrapper ToCurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate) + { + return currencyInfo == null ? null : new CurrencyRateInfoWrapper(currencyInfo, rate); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Controllers/CRMController.cs new file mode 100644 index 00000000000..6311a2b37a0 --- /dev/null +++ b/products/ASC.CRM/Server/Controllers/CRMController.cs @@ -0,0 +1,138 @@ +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Common; +using ASC.Common.Web; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Services.WCFService; +using Microsoft.AspNetCore.Mvc; +using System; + +namespace ASC.Api.CRM +{ + [DefaultRoute] + [ApiController] + public partial class CRMController : ControllerBase + { + public CRMController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + NotifyClient notifyClient, + TaskWrapperHelper taskWrapperHelper, + SecurityContext securityContext, + UserManager userManager, + CurrencyProvider currencyProvider) + { + DaoFactory = daoFactory; + ApiContext = apiContext; + CRMSecurity = cRMSecurity; + MessageTarget = messageTarget; + MessageService = messageService; + NotifyClient = notifyClient; + TaskWrapperHelper = taskWrapperHelper; + SecurityContext = securityContext; + UserManager = userManager; + CurrencyProvider = currencyProvider; + } + + public CurrencyProvider CurrencyProvider { get; } + public UserManager UserManager { get; } + public SecurityContext SecurityContext { get; } + public TaskWrapperHelper TaskWrapperHelper { get; } + public NotifyClient NotifyClient { get; } + + private readonly ApiContext ApiContext; + + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + public CRMSecurity CRMSecurity { get; } + public DaoFactory DaoFactory { get; } + + + private static EntityType ToEntityType(string entityTypeStr) + { + EntityType entityType; + + if (string.IsNullOrEmpty(entityTypeStr)) return EntityType.Any; + + switch (entityTypeStr.ToLower()) + { + case "person": + entityType = EntityType.Person; + break; + case "company": + entityType = EntityType.Company; + break; + case "contact": + entityType = EntityType.Contact; + break; + case "opportunity": + entityType = EntityType.Opportunity; + break; + case "case": + entityType = EntityType.Case; + break; + default: + entityType = EntityType.Any; + break; + } + + return entityType; + } + + private string GetEntityTitle(EntityType entityType, int entityId, bool checkAccess, out DomainObject entity) + { + switch (entityType) + { + case EntityType.Contact: + case EntityType.Company: + case EntityType.Person: + var conatct = (entity = DaoFactory.GetContactDao().GetByID(entityId)) as Contact; + if (conatct == null || (checkAccess && !CRMSecurity.CanAccessTo(conatct))) + throw new ItemNotFoundException(); + return conatct.GetTitle(); + case EntityType.Opportunity: + var deal = (entity = DaoFactory.GetDealDao().GetByID(entityId)) as Deal; + if (deal == null || (checkAccess && !CRMSecurity.CanAccessTo(deal))) + throw new ItemNotFoundException(); + return deal.Title; + case EntityType.Case: + var cases = (entity = DaoFactory.GetCasesDao().GetByID(entityId)) as Cases; + if (cases == null || (checkAccess && !CRMSecurity.CanAccessTo(cases))) + throw new ItemNotFoundException(); + return cases.Title; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + } + + public static class CRMControllerExtention + { + public static DIHelper AddCRMControllerService(this DIHelper services) + { + return services.AddCRMSecurityService() + .AddDaoFactoryService() + .AddApiContextService() + .AddGlobalService() + .AddMessageTargetService() + .AddTaskWrapperHelperService() + .AddFileStorageService() + .AddNotifyClientService() + .AddSecurityContextService() + .AddUserManagerService() + .AddCurrencyProviderService(); + + } + } + +} diff --git a/products/ASC.CRM/Server/Controllers/CurrencyRateController.cs b/products/ASC.CRM/Server/Controllers/CurrencyRateController.cs deleted file mode 100644 index 428496637eb..00000000000 --- a/products/ASC.CRM/Server/Controllers/CurrencyRateController.cs +++ /dev/null @@ -1,17 +0,0 @@ -using ASC.Web.Api.Routing; -using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace ASC.Api.CRM -{ - [DefaultRoute] - [ApiController] - public class CurrencyRateController : ControllerBase - { - - - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/TasksController.cs b/products/ASC.CRM/Server/Controllers/TasksController.cs deleted file mode 100644 index 50e23c9cf23..00000000000 --- a/products/ASC.CRM/Server/Controllers/TasksController.cs +++ /dev/null @@ -1,12 +0,0 @@ -using ASC.Web.Api.Routing; -using Microsoft.AspNetCore.Mvc; - -namespace ASC.Api.CRM -{ - [DefaultRoute] - [ApiController] - public class TasksController : ControllerBase - { - - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 5e78a6d7763..78652faaa53 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -164,7 +164,56 @@ public static DIHelper AddDaoFactoryService(this DIHelper services) { services.TryAddScoped(); - return services; + // return services; + return services.AddTaskDaoService() + .AddListItemDaoService() + .AddContactDaoService() + .AddCustomFieldDaoService() + .AddDealDaoService() + .AddDealMilestoneDaoService() + .AddTagDaoService() + .AddSearchDaoService() + .AddRelationshipEventDaoService() + .AddFileDaoService() + .AddCasesDaoService() + .AddTaskTemplateDaoService() + .AddTaskTemplateContainerDaoService() + // .AddReportDaoService() + .AddCurrencyRateDaoService() + .AddCurrencyInfoDaoService() + .AddContactInfoDaoService() + .AddInvoiceDaoService() + .AddInvoiceLineDaoService() + .AddInvoiceTaxDaoService() + .AddInvoiceLineDaoService(); } } } + +//TaskDao +//ListItemDao +//ContactDao +//CustomFieldDao +//DealDao +//DealMilestoneDao + +//TagDao +//SearchDao +//RelationshipEventDao +//FileDao +//CasesDao +//TaskTemplateContainerDao +//TaskTemplateDao + + +//ReportDao +//CurrencyRateDao +//CurrencyInfoDao +//ContactInfoDao + + +//InvoiceDao +//InvoiceItemDao +//InvoiceTaxDao +//InvoiceLineDao +//VoipDao \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index a81ccea7611..16270ef7ab5 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -987,7 +987,7 @@ public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) public static class InvoiceDaoExtention { - public static DIHelper AddFileDaoService(this DIHelper services) + public static DIHelper AddInvoiceDaoService(this DIHelper services) { services.TryAddScoped(); diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 6d04e880786..f738a73fc1e 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -719,7 +719,7 @@ private static string GetHistoryContentJson(JObject apiResponse) public static class RelationshipEventDaoExtention { - public static DIHelper AddListItemDaoService(this DIHelper services) + public static DIHelper AddRelationshipEventDaoService(this DIHelper services) { services.TryAddScoped(); diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index cfc279a7c66..1bd621e62f0 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -2234,7 +2234,7 @@ public static DIHelper AddReportDaoService(this DIHelper services) .AddFilesIntegrationService() .AddTenantUtilService() .AddSettingsManagerService() - .AddGlobalService() + // .AddGlobalService() .AddUserManagerService(); } } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 06fa08eb264..37ac5371460 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -293,4 +293,17 @@ public static DIHelper AddTaskTemplateDaoService(this DIHelper services) .AddSecurityContextService(); } } + + public static class TaskTemplateContainerDaoExtention + { + public static DIHelper AddTaskTemplateContainerDaoService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCRMDbContextService() + .AddTenantManagerService() + .AddSecurityContextService(); + } + } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index bb8719f05e3..989362d32ce 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -36,13 +36,6 @@ public partial class CRMDbContext : BaseDbContext public virtual DbSet VoipCalls { get; set; } public virtual DbSet VoipNumber { get; set; } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - if (!optionsBuilder.IsConfigured) - { - } - } - protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity(entity => diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index e91084c14da..9ffff1cd6ca 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -225,7 +225,10 @@ public bool TrySelectOpportunity(string text, out List result) public static class BundleSearchExtention { public static DIHelper AddBundleSearchService(this DIHelper services) - { + { + services.TryAddScoped(); + + return services.AddFactoryIndexerService() .AddFactoryIndexerService() .AddFactoryIndexerService() diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index a092a4beec7..8d5511c8562 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -870,7 +870,7 @@ public static DIHelper AddCRMSecurityService(this DIHelper services) .AddAuthorizationManagerService() .AddUserManagerService() .AddDisplayUserSettingsService() - .AddDaoFactoryService() + // .AddDaoFactoryService() .AddWebItemSecurity() .AddPermissionContextService() .AddCurrencyProviderService() diff --git a/products/ASC.CRM/Server/Model/CasesWrapper.cs b/products/ASC.CRM/Server/Model/CasesWrapper.cs new file mode 100644 index 00000000000..f493def6d5b --- /dev/null +++ b/products/ASC.CRM/Server/Model/CasesWrapper.cs @@ -0,0 +1,145 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Common; +using ASC.Core.Users; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + [DataContract(Name = "case", Namespace = "")] + public class CasesWrapper + { + public CasesWrapper() + { + } + + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable Members { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool IsClosed { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool IsPrivate { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable AccessList { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanEdit { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable CustomFields { get; set; } + public static CasesWrapper GetSample() + { + return new CasesWrapper + { + IsClosed = false, + Title = "Exhibition organization", + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + IsPrivate = false, + CustomFields = new[] { CustomFieldBaseWrapper.GetSample() }, + CanEdit = true + }; + } + } + + public class CasesWrapperHelper + { + public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + } + + public CRMSecurity CRMSecurity { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + + public CasesWrapper Get(Cases cases) + { + var result = new CasesWrapper + { + Title = cases.Title, + IsClosed = cases.IsClosed, + IsPrivate = CRMSecurity.IsPrivate(cases), + Created = ApiDateTimeHelper.Get(cases.CreateOn), + CreateBy = EmployeeWraperHelper.Get(cases.CreateBy), + CanEdit = CRMSecurity.CanEdit(cases) + }; + + if (result.IsPrivate) + { + result.AccessList = CRMSecurity.GetAccessSubjectTo(cases) + .SkipWhile(item => item.Key == Constants.GroupEveryone.ID) + .Select(item => EmployeeWraperHelper.Get(item.Key)); + } + + return result; + + } + } + + public static class CasesWrapperHelperExtension + { + public static DIHelper AddCasesWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService(); + } + } +} + + diff --git a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs new file mode 100644 index 00000000000..fd0ed85e4a3 --- /dev/null +++ b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs @@ -0,0 +1,200 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Common; +using ASC.CRM.Classes; +using ASC.CRM.Core; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; +using Newtonsoft.Json.Linq; +using System; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + /// + /// Address + /// + [DataContract(Name = "address", Namespace = "")] + public class Address + { + public Address() + { + } + + public Address(ContactInfo contactInfo) + { + if (contactInfo.InfoType != ContactInfoType.Address) throw new ArgumentException(); + + City = JObject.Parse(contactInfo.Data)["city"].Value(); + Country = JObject.Parse(contactInfo.Data)["country"].Value(); + State = JObject.Parse(contactInfo.Data)["state"].Value(); + Street = JObject.Parse(contactInfo.Data)["street"].Value(); + Zip = JObject.Parse(contactInfo.Data)["zip"].Value(); + Category = contactInfo.Category; + CategoryName = contactInfo.CategoryToString(); + IsPrimary = contactInfo.IsPrimary; + } + + public static bool TryParse(ContactInfo contactInfo, out Address res) + { + if (contactInfo.InfoType != ContactInfoType.Address) + { + res = null; + return false; + } + + try + { + res = Newtonsoft.Json.JsonConvert.DeserializeObject
    (contactInfo.Data); + res.Category = contactInfo.Category; + res.CategoryName = contactInfo.CategoryToString(); + res.IsPrimary = contactInfo.IsPrimary; + return true; + } + catch (Exception) + { + res = null; + return false; + } + } + + [DataMember(Order = 1, IsRequired = false, EmitDefaultValue = false)] + public String Street { get; set; } + + [DataMember(Order = 2, IsRequired = false, EmitDefaultValue = false)] + public String City { get; set; } + + [DataMember(Order = 3, IsRequired = false, EmitDefaultValue = false)] + public String State { get; set; } + + [DataMember(Order = 4, IsRequired = false, EmitDefaultValue = false)] + public String Zip { get; set; } + + [DataMember(Order = 5, IsRequired = false, EmitDefaultValue = false)] + public String Country { get; set; } + + [DataMember(Order = 6, IsRequired = false, EmitDefaultValue = false)] + public int Category { get; set; } + + [DataMember(Order = 7, IsRequired = false, EmitDefaultValue = false)] + public String CategoryName { get; set; } + + [DataMember(Order = 8, IsRequired = false, EmitDefaultValue = false)] + public Boolean IsPrimary { get; set; } + + + public static Address GetSample() + { + return new Address + { + Country = "Latvia", + Zip = "LV-1021", + Street = "Lubanas st. 125a-25", + State = "", + City = "Riga", + IsPrimary = true, + Category = (int)ContactInfoBaseCategory.Work, + CategoryName = ((AddressCategory)ContactInfoBaseCategory.Work).ToLocalizedString() + }; + } + } + + /// + /// Contact information + /// + [DataContract(Name = "commonDataItem", Namespace = "")] + public class ContactInfoWrapper + { + public ContactInfoWrapper() + { + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(Order = 1)] + public ContactInfoType InfoType { get; set; } + + [DataMember(Order = 2)] + public int Category { get; set; } + + [DataMember(Order = 3)] + public String Data { get; set; } + + [DataMember(Order = 4)] + public String CategoryName { get; set; } + + [DataMember(Order = 5)] + public bool IsPrimary { get; set; } + + public static ContactInfoWrapper GetSample() + { + return new ContactInfoWrapper + { + IsPrimary = true, + Category = (int)ContactInfoBaseCategory.Home, + CategoryName = ContactInfoBaseCategory.Home.ToLocalizedString(), + Data = "support@onlyoffice.com", + InfoType = ContactInfoType.Email + }; + } + } + + public class ContactInfoWrapperHelper + { + public ContactInfoWrapperHelper() + { + } + + public ContactInfoWrapper Get(ContactInfo contactInfo) + { + + return new ContactInfoWrapper + { + InfoType = contactInfo.InfoType, + Category = contactInfo.Category, + CategoryName = contactInfo.CategoryToString(), + Data = contactInfo.Data, + IsPrimary = contactInfo.IsPrimary, + Id = contactInfo.ID + }; + } + + } + + public static class ContactInfoWrapperHelperExtension + { + public static DIHelper AddContactInfoWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/ContactWrapper.cs b/products/ASC.CRM/Server/Model/ContactWrapper.cs new file mode 100644 index 00000000000..00a4738d3dd --- /dev/null +++ b/products/ASC.CRM/Server/Model/ContactWrapper.cs @@ -0,0 +1,491 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; +using ASC.Web.CRM; +using ASC.Web.CRM.Classes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using Contact = ASC.CRM.Core.Entities.Contact; + +namespace ASC.Api.CRM.Wrappers +{ + /// + /// Person + /// + [DataContract(Name = "person", Namespace = "")] + public class PersonWrapper : ContactWrapper + { + public PersonWrapper(int id) : + base(id) + { + } + + public PersonWrapper(Person person) + : base(person) + { + FirstName = person.FirstName; + LastName = person.LastName; + Title = person.JobTitle; + } + + public static PersonWrapper ToPersonWrapperQuick(Person person) + { + var result = new PersonWrapper(person.ID); + + result.DisplayName = person.GetTitle(); + result.IsPrivate = CRMSecurity.IsPrivate(person); + result.IsShared = person.ShareType == ShareType.ReadWrite || person.ShareType == ShareType.Read; + result.ShareType = person.ShareType; + + if (result.IsPrivate) + { + result.AccessList = CRMSecurity.GetAccessSubjectTo(person) + .Select(item => EmployeeWraper.Get(item.Key)); + } + result.Currency = !String.IsNullOrEmpty(person.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(person.Currency)) : + null; + + result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, person.ID, false).ToLower(); + result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, person.ID, false).ToLower(); + result.IsCompany = false; + result.CanEdit = CRMSecurity.CanEdit(person); + //result.CanDelete = CRMSecurity.CanDelete(contact); + + result.CreateBy = EmployeeWraper.Get(person.CreateBy); + result.Created = (ApiDateTime)person.CreateOn; + result.About = person.About; + result.Industry = person.Industry; + + + result.FirstName = person.FirstName; + result.LastName = person.LastName; + result.Title = person.JobTitle; + + return result; + } + + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String FirstName { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String LastName { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactBaseWrapper Company { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } + + public new static PersonWrapper GetSample() + { + return new PersonWrapper(0) + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + FirstName = "Tadjeddine", + LastName = "Bachir", + Company = CompanyWrapper.GetSample(), + Title = "Programmer", + About = "", + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + ShareType = ShareType.None + }; + } + } + + /// + /// Company + /// + [DataContract(Name = "company", Namespace = "")] + public class CompanyWrapper : ContactWrapper + { + public CompanyWrapper(int id) : + base(id) + { + } + + public CompanyWrapper(Company company) + : base(company) + { + CompanyName = company.CompanyName; + // PersonsCount = Global.DaoFactory.ContactDao.GetMembersCount(company.ID); + } + + + public static CompanyWrapper ToCompanyWrapperQuick(Company company) + { + var result = new CompanyWrapper(company.ID); + + result.DisplayName = company.GetTitle(); + result.IsPrivate = CRMSecurity.IsPrivate(company); + result.IsShared = company.ShareType == ShareType.ReadWrite || company.ShareType == ShareType.Read; + result.ShareType = company.ShareType; + + if (result.IsPrivate) + { + result.AccessList = CRMSecurity.GetAccessSubjectTo(company) + .Select(item => EmployeeWraper.Get(item.Key)); + } + result.Currency = !String.IsNullOrEmpty(company.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(company.Currency)) : + null; + + result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, company.ID, true).ToLower(); + result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, company.ID, true).ToLower(); + result.IsCompany = true; + result.CanEdit = CRMSecurity.CanEdit(company); + //result.CanDelete = CRMSecurity.CanDelete(contact); + + + result.CompanyName = company.CompanyName; + + result.CreateBy = EmployeeWraper.Get(company.CreateBy); + result.Created = (ApiDateTime)company.CreateOn; + result.About = company.About; + result.Industry = company.Industry; + + return result; + } + + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String CompanyName { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public IEnumerable Persons { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public int PersonsCount { get; set; } + + public new static CompanyWrapper GetSample() + { + return new CompanyWrapper(0) + { + IsPrivate = true, + IsShared = false, + IsCompany = true, + About = "", + CompanyName = "Food and Culture Project", + PersonsCount = 0 + }; + } + } + + [DataContract(Name = "contact", Namespace = "")] + [KnownType(typeof(PersonWrapper))] + [KnownType(typeof(CompanyWrapper))] + public abstract class ContactWrapper : ContactBaseWrapper + { + protected ContactWrapper(int id) + : base(id) + { + } + + protected ContactWrapper(Contact contact) + : base(contact) + { + CreateBy = EmployeeWraper.Get(contact.CreateBy); + Created = (ApiDateTime)contact.CreateOn; + About = contact.About; + Industry = contact.Industry; + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable
    Addresses { get; set; } + + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String About { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Industry { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactStatusBaseWrapper ContactStatus { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactTypeBaseWrapper ContactType { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable CommonData { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable CustomFields { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable Tags { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int TaskCount { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool HaveLateTasks { get; set; } + + public new static ContactWrapper GetSample() + { + return new PersonWrapper(0) + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + FirstName = "Tadjeddine", + LastName = "Bachir", + Company = CompanyWrapper.GetSample(), + Title = "Programmer", + About = "", + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + CommonData = new List(){ContactInfoWrapper.GetSample()}, + CustomFields = new List(){CustomFieldBaseWrapper.GetSample()}, + ShareType = ShareType.None, + CanDelete = true, + CanEdit = true, + TaskCount = 0, + HaveLateTasks = false + }; + } + } + + [DataContract(Name = "contactBase", Namespace = "")] + public class ContactBaseWithEmailWrapper : ContactBaseWrapper + { + protected ContactBaseWithEmailWrapper(int id) + : base(id) + { + } + + public ContactBaseWithEmailWrapper(Contact contact) + : base(contact) + { + } + + public ContactBaseWithEmailWrapper(ContactWrapper contactWrapper) : base(contactWrapper.ID) + { + AccessList = contactWrapper.AccessList; + CanEdit = contactWrapper.CanEdit; + DisplayName = contactWrapper.DisplayName; + IsCompany = contactWrapper.IsCompany; + IsPrivate = contactWrapper.IsPrivate; + IsShared = contactWrapper.IsShared; + ShareType = contactWrapper.ShareType; + MediumFotoUrl = contactWrapper.MediumFotoUrl; + SmallFotoUrl = contactWrapper.SmallFotoUrl; + + if (contactWrapper.CommonData != null && contactWrapper.CommonData.Count() != 0) + { + Email = contactWrapper.CommonData.FirstOrDefault(item => item.InfoType == ContactInfoType.Email && item.IsPrimary); + } + else + { + Email = null; + } + } + + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactInfoWrapper Email { get; set; } + } + + + [DataContract(Name = "contactBase", Namespace = "")] + public class ContactBaseWithPhoneWrapper : ContactBaseWrapper + { + protected ContactBaseWithPhoneWrapper(int id) + : base(id) + { + } + + public ContactBaseWithPhoneWrapper(Contact contact) + : base(contact) + { + } + + public ContactBaseWithPhoneWrapper(ContactWrapper contactWrapper) + : base(contactWrapper.ID) + { + AccessList = contactWrapper.AccessList; + CanEdit = contactWrapper.CanEdit; + DisplayName = contactWrapper.DisplayName; + IsCompany = contactWrapper.IsCompany; + IsPrivate = contactWrapper.IsPrivate; + IsShared = contactWrapper.IsShared; + ShareType = contactWrapper.ShareType; + MediumFotoUrl = contactWrapper.MediumFotoUrl; + SmallFotoUrl = contactWrapper.SmallFotoUrl; + + if (contactWrapper.CommonData != null && contactWrapper.CommonData.Count() != 0) + { + Phone = contactWrapper.CommonData.FirstOrDefault(item => item.InfoType == ContactInfoType.Phone && item.IsPrimary); + } + else + { + Phone = null; + } + } + + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactInfoWrapper Phone { get; set; } + } + + + /// + /// Contact base information + /// + [DataContract(Name = "contactBase", Namespace = "")] + public class ContactBaseWrapper + { + public ContactBaseWrapper(Contact contact) + : base(contact.ID) + { + DisplayName = contact.GetTitle(); + IsPrivate = CRMSecurity.IsPrivate(contact); + IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read; + ShareType = contact.ShareType; + + if (IsPrivate) + { + AccessList = CRMSecurity.GetAccessSubjectTo(contact) + .Select(item => EmployeeWraper.Get(item.Key)); + } + Currency = !String.IsNullOrEmpty(contact.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(contact.Currency)) : + null; + + SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); + MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); + IsCompany = contact is Company; + CanEdit = CRMSecurity.CanEdit(contact); + CanDelete = CRMSecurity.CanDelete(contact); + } + + + public static ContactBaseWrapper ToContactBaseWrapperQuick(Contact contact) + { + var result = new ContactBaseWrapper(contact.ID); + + result.DisplayName = contact.GetTitle(); + result.IsPrivate = CRMSecurity.IsPrivate(contact); + result.IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read; + result.ShareType = contact.ShareType; + + if (result.IsPrivate) + { + result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) + .Select(item => EmployeeWraper.Get(item.Key)); + } + result.Currency = !String.IsNullOrEmpty(contact.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(contact.Currency)) : + null; + + result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); + result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); + result.IsCompany = contact is Company; + result.CanEdit = CRMSecurity.CanEdit(contact); + //result.CanDelete = CRMSecurity.CanDelete(contact); + + return result; + } + + protected ContactBaseWrapper(int contactID) + : base(contactID) + { + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String SmallFotoUrl { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String MediumFotoUrl { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public String DisplayName { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool IsCompany { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable AccessList { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool IsPrivate { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool IsShared { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public ShareType ShareType { get; set; } + + [DataMember] + public CurrencyInfoWrapper Currency { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanEdit { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanDelete { get; set; } + + public static ContactBaseWrapper GetSample() + { + return new ContactBaseWrapper(0) + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + DisplayName = "Tadjeddine Bachir", + SmallFotoUrl = "url to foto" + }; + } + } + + + [DataContract(Name = "contact_task", Namespace = "")] + public class ContactWithTaskWrapper + { + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public TaskBaseWrapper Task { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactWrapper Contact { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs new file mode 100644 index 00000000000..56fad5119ff --- /dev/null +++ b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs @@ -0,0 +1,104 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Runtime.Serialization; +using ASC.CRM.Core; + +namespace ASC.Api.CRM +{ + /// + /// Currency information + /// + [DataContract(Name = "currencyInfo", Namespace = "")] + public class CurrencyInfoWrapper + { + public CurrencyInfoWrapper() + { + } + + public CurrencyInfoWrapper(CurrencyInfo currencyInfo) + { + Abbreviation = currencyInfo.Abbreviation; + CultureName = currencyInfo.CultureName; + Symbol = currencyInfo.Symbol; + Title = currencyInfo.Title; + IsConvertable = currencyInfo.IsConvertable; + IsBasic = currencyInfo.IsBasic; + } + + [DataMember] + public String Title { get; set; } + + [DataMember] + public String Symbol { get; set; } + + [DataMember] + public String Abbreviation { get; set; } + + [DataMember] + public String CultureName { get; set; } + + [DataMember] + public bool IsConvertable { get; set; } + + [DataMember] + public bool IsBasic { get; set; } + + public static CurrencyInfoWrapper GetSample() + { + return new CurrencyInfoWrapper + { + Title = "Chinese Yuan", + Abbreviation = "CNY", + Symbol = "¥", + CultureName = "CN", + IsConvertable = true, + IsBasic = false + }; + } + } + + + /// + /// Currency rate information + /// + [DataContract(Name = "currencyRateInfo", Namespace = "")] + public class CurrencyRateInfoWrapper : CurrencyInfoWrapper + { + public CurrencyRateInfoWrapper() + { + } + + public CurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate) : base(currencyInfo) + { + Rate = rate; + } + + [DataMember] + public Decimal Rate { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs new file mode 100644 index 00000000000..72b0d2b7864 --- /dev/null +++ b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs @@ -0,0 +1,73 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Runtime.Serialization; +using ASC.Api.CRM.Wrappers; +using ASC.CRM.Core; + +namespace ASC.Api.CRM +{ + /// + /// Currency rate + /// + [DataContract(Name = "currencyRate", Namespace = "")] + public class CurrencyRateWrapper + { + public CurrencyRateWrapper(int id) + { + } + + public CurrencyRateWrapper(CurrencyRate currencyRate) + { + FromCurrency = currencyRate.FromCurrency; + ToCurrency = currencyRate.ToCurrency; + Rate = currencyRate.Rate; + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember] + public String FromCurrency { get; set; } + + [DataMember] + public String ToCurrency { get; set; } + + [DataMember] + public decimal Rate { get; set; } + + public static CurrencyRateWrapper GetSample() + { + return new CurrencyRateWrapper(1) + { + FromCurrency = "EUR", + ToCurrency = "USD", + Rate = (decimal)1.1 + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CustomFieldWrapper.cs b/products/ASC.CRM/Server/Model/CustomFieldWrapper.cs new file mode 100644 index 00000000000..b3576768ad5 --- /dev/null +++ b/products/ASC.CRM/Server/Model/CustomFieldWrapper.cs @@ -0,0 +1,122 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using System; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + [DataContract(Name = "customField", Namespace = "")] + public class CustomFieldWrapper : CustomFieldBaseWrapper + { + public CustomFieldWrapper(int id) + : base(id) + { + } + + public CustomFieldWrapper(CustomField customField) + : base(customField) + { + } + + + + [DataMember] + public int RelativeItemsCount { get; set; } + + public new static CustomFieldWrapper GetSample() + { + return new CustomFieldWrapper(0) + { + Position = 10, + EntityId = 14523423, + FieldType = CustomFieldType.Date, + FieldValue = ApiDateTime.GetSample().ToString(), + Label = "Birthdate", + Mask = "", + RelativeItemsCount = 0 + }; + } + } + + /// + /// User custom fields + /// + [DataContract(Name = "customField", Namespace = "")] + public class CustomFieldBaseWrapper + { + public CustomFieldBaseWrapper(int id) + { + } + + public CustomFieldBaseWrapper(CustomField customField) + { + EntityId = customField.EntityID; + Label = customField.Label; + FieldValue = customField.Value; + FieldType = customField.FieldType; + Position = customField.Position; + Mask = customField.Mask; + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember] + public int EntityId { get; set; } + + [DataMember] + public String Label { get; set; } + + [DataMember] + public String FieldValue { get; set; } + + [DataMember] + public CustomFieldType FieldType { get; set; } + + [DataMember] + public int Position { get; set; } + + [DataMember] + public String Mask { get; set; } + + public static CustomFieldBaseWrapper GetSample() + { + return new CustomFieldBaseWrapper(0) + { + Position = 10, + EntityId = 14523423, + FieldType = CustomFieldType.Date, + FieldValue = ApiDateTime.GetSample().ToString(), + Label = "Birthdate", + Mask = "" + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs new file mode 100644 index 00000000000..648a7da85f9 --- /dev/null +++ b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs @@ -0,0 +1,423 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Api.Core; +using ASC.CRM.Classes; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + + /// + /// Invoice + /// + [DataContract(Name = "invoiceBase", Namespace = "")] + public class InvoiceBaseWrapper + { + public InvoiceBaseWrapper(int id) + { + } + + public InvoiceBaseWrapper(Invoice invoice) + { + Status = new InvoiceStatusWrapper(invoice.Status); + Number = invoice.Number; + IssueDate = (ApiDateTime) invoice.IssueDate; + TemplateType = invoice.TemplateType; + DueDate = (ApiDateTime) invoice.DueDate; + Currency = !String.IsNullOrEmpty(invoice.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) : + new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); + ExchangeRate = invoice.ExchangeRate; + Language = invoice.Language; + PurchaseOrderNumber = invoice.PurchaseOrderNumber; + Terms = invoice.Terms; + Description = invoice.Description; + FileID = invoice.FileID; + CreateOn = (ApiDateTime)invoice.CreateOn; + CreateBy = EmployeeWraper.Get(invoice.CreateBy); + CanEdit = CRMSecurity.CanEdit(invoice); + CanDelete = CRMSecurity.CanDelete(invoice); + } + + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember] + public InvoiceStatusWrapper Status { get; set; } + + [DataMember] + public string Number { get; set; } + + [DataMember] + public ApiDateTime IssueDate { get; set; } + + [DataMember] + public InvoiceTemplateType TemplateType { get; set; } + + [DataMember] + public ContactBaseWithEmailWrapper Contact { get; set; } + + [DataMember] + public ContactBaseWithEmailWrapper Consignee { get; set; } + + [DataMember] + public EntityWrapper Entity { get; set; } + + [DataMember] + public ApiDateTime DueDate { get; set; } + + [DataMember] + public string Language { get; set; } + + [DataMember] + public CurrencyInfoWrapper Currency { get; set; } + + [DataMember] + public decimal ExchangeRate { get; set; } + + [DataMember] + public string PurchaseOrderNumber { get; set; } + + [DataMember] + public string Terms { get; set; } + + [DataMember] + public string Description { get; set; } + + [DataMember] + public int FileID { get; set; } + + [DataMember] + public ApiDateTime CreateOn { get; set; } + + [DataMember] + public EmployeeWraper CreateBy { get; set; } + + [DataMember] + public decimal Cost { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanEdit { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanDelete { get; set; } + } + + /// + /// Invoice + /// + [DataContract(Name = "invoice", Namespace = "")] + public class InvoiceWrapper : InvoiceBaseWrapper + { + public InvoiceWrapper(int id) + : base(id) + { + } + + public InvoiceWrapper(Invoice invoice) + : base(invoice.ID) + { + Status = new InvoiceStatusWrapper(invoice.Status); + Number = invoice.Number; + IssueDate = (ApiDateTime) invoice.IssueDate; + TemplateType = invoice.TemplateType; + DueDate = (ApiDateTime) invoice.DueDate; + Currency = !String.IsNullOrEmpty(invoice.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) : + new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); + ExchangeRate = invoice.ExchangeRate; + Language = invoice.Language; + PurchaseOrderNumber = invoice.PurchaseOrderNumber; + Terms = invoice.Terms; + Description = invoice.Description; + FileID = invoice.FileID; + CreateOn = (ApiDateTime)invoice.CreateOn; + CreateBy = EmployeeWraper.Get(invoice.CreateBy); + CanEdit = CRMSecurity.CanEdit(invoice); + CanDelete = CRMSecurity.CanDelete(invoice); + } + + [DataMember] + public List InvoiceLines { get; set; } + + public static InvoiceWrapper GetSample() + { + return new InvoiceWrapper(0) + { + Status = new InvoiceStatusWrapper(InvoiceStatus.Draft), + Number = string.Empty, + IssueDate = ApiDateTime.GetSample(), + TemplateType = InvoiceTemplateType.Eur, + Language = string.Empty, + DueDate = ApiDateTime.GetSample(), + Currency = CurrencyInfoWrapper.GetSample(), + ExchangeRate = (decimal)1.00, + PurchaseOrderNumber = string.Empty, + Terms = string.Empty, + Description = string.Empty, + FileID = -1, + CreateOn = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + CanEdit = true, + CanDelete = true, + Cost = 0, + InvoiceLines = new List{ InvoiceLineWrapper.GetSample() } + }; + } + } + + /// + /// Invoice Item + /// + [DataContract(Name = "invoiceItem", Namespace = "")] + public class InvoiceItemWrapper + { + public InvoiceItemWrapper(int id) + { + } + + public InvoiceItemWrapper(InvoiceItem invoiceItem) + { + Title = invoiceItem.Title; + StockKeepingUnit = invoiceItem.StockKeepingUnit; + Description = invoiceItem.Description; + Price = invoiceItem.Price; + Quantity = invoiceItem.Quantity; + StockQuantity = invoiceItem.StockQuantity; + TrackInvenory = invoiceItem.TrackInventory; + + CreateOn = (ApiDateTime)invoiceItem.CreateOn; + CreateBy = EmployeeWraper.Get(invoiceItem.CreateBy); + Currency = !String.IsNullOrEmpty(invoiceItem.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(invoiceItem.Currency)) : + new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); + CanEdit = CRMSecurity.CanEdit(invoiceItem); + CanDelete = CRMSecurity.CanDelete(invoiceItem); + } + + + [DataMember] + public string Title { get; set; } + + [DataMember] + public string StockKeepingUnit { get; set; } + + [DataMember] + public string Description { get; set; } + + [DataMember] + public decimal Price { get; set; } + + [DataMember] + public CurrencyInfoWrapper Currency { get; set; } + + [DataMember] + public int Quantity { get; set; } + + [DataMember] + public int StockQuantity { get; set; } + + [DataMember] + public bool TrackInvenory { get; set; } + + [DataMember] + public InvoiceTaxWrapper InvoiceTax1 { get; set; } + + [DataMember] + public InvoiceTaxWrapper InvoiceTax2 { get; set; } + + [DataMember] + public ApiDateTime CreateOn { get; set; } + + [DataMember] + public EmployeeWraper CreateBy { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanEdit { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanDelete { get; set; } + } + + /// + /// Invoice Tax + /// + [DataContract(Name = "invoiceTax", Namespace = "")] + public class InvoiceTaxWrapper + { + + public InvoiceTaxWrapper() + { + } + + public InvoiceTaxWrapper(InvoiceTax invoiceTax) + : base(invoiceTax.ID) + { + Name = invoiceTax.Name; + Description = invoiceTax.Description; + Rate = invoiceTax.Rate; + CreateOn = (ApiDateTime)invoiceTax.CreateOn; + CreateBy = EmployeeWraper.Get(invoiceTax.CreateBy); + CanEdit = CRMSecurity.CanEdit(invoiceTax); + CanDelete = CRMSecurity.CanDelete(invoiceTax); + } + + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember] + public string Name { get; set; } + + [DataMember] + public string Description { get; set; } + + [DataMember] + public decimal Rate { get; set; } + + [DataMember] + public ApiDateTime CreateOn { get; set; } + + [DataMember] + public EmployeeWraper CreateBy { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanEdit { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanDelete { get; set; } + } + + /// + /// Invoice Line + /// + [DataContract(Name = "invoiceLine", Namespace = "")] + public class InvoiceLineWrapper + { + public InvoiceLineWrapper(int id) + : base(id) + { + } + + public InvoiceLineWrapper(InvoiceLine invoiceLine) + : base(invoiceLine.ID) + { + InvoiceID = invoiceLine.InvoiceID; + InvoiceItemID = invoiceLine.InvoiceItemID; + InvoiceTax1ID = invoiceLine.InvoiceTax1ID; + InvoiceTax2ID = invoiceLine.InvoiceTax2ID; + SortOrder = invoiceLine.SortOrder; + Description = invoiceLine.Description; + Quantity = invoiceLine.Quantity; + Price = invoiceLine.Price; + Discount = invoiceLine.Discount; + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember] + public int InvoiceID { get; set; } + + [DataMember] + public int InvoiceItemID { get; set; } + + [DataMember] + public int InvoiceTax1ID { get; set; } + + [DataMember] + public int InvoiceTax2ID { get; set; } + + [DataMember] + public int SortOrder { get; set; } + + [DataMember] + public string Description { get; set; } + + [DataMember] + public int Quantity { get; set; } + + [DataMember] + public decimal Price { get; set; } + + [DataMember] + public decimal Discount { get; set; } + + public static InvoiceLineWrapper GetSample() + { + return new InvoiceLineWrapper(0) + { + Description = string.Empty, + Discount = (decimal)0.00, + InvoiceID = 0, + InvoiceItemID = 0, + InvoiceTax1ID = 0, + InvoiceTax2ID = 0, + Price = (decimal)0.00, + Quantity = 0 + }; + } + } + + /// + /// Invoice Status + /// + [DataContract(Name = "invoiceStatus", Namespace = "")] + public class InvoiceStatusWrapper + { + public InvoiceStatusWrapper() + { + + } + + public InvoiceStatusWrapper(int id) + : base(id) + { + Title = ((InvoiceStatus)id).ToLocalizedString(); + } + + public InvoiceStatusWrapper(InvoiceStatus status) + : base((int)status) + { + Title = status.ToLocalizedString(); + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember] + public string Title { get; set; } + } + +} diff --git a/products/ASC.CRM/Server/Model/ListItemWrapper.cs b/products/ASC.CRM/Server/Model/ListItemWrapper.cs new file mode 100644 index 00000000000..bed1051a6bc --- /dev/null +++ b/products/ASC.CRM/Server/Model/ListItemWrapper.cs @@ -0,0 +1,420 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.CRM.Core.Entities; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM.Configuration; +using System; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + + #region History Category + + [DataContract(Name = "historyCategoryBase", Namespace = "")] + public class HistoryCategoryBaseWrapper : ListItemWrapper + { + public HistoryCategoryBaseWrapper() : base(0) + { + } + + public HistoryCategoryBaseWrapper(ListItem listItem) + : base(listItem) + { + if (!String.IsNullOrEmpty(listItem.AdditionalParams)) + ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID); + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember] + public String ImagePath { get; set; } + + public static HistoryCategoryBaseWrapper GetSample() + { + return new HistoryCategoryBaseWrapper + { + ID = 30, + Title = "Lunch", + SortOrder = 10, + Color = String.Empty, + Description = "", + ImagePath = "path to image" + }; + } + } + + [DataContract(Name = "historyCategory", Namespace = "")] + public class HistoryCategoryWrapper : HistoryCategoryBaseWrapper + { + public HistoryCategoryWrapper() + { + } + + public HistoryCategoryWrapper(ListItem listItem) + : base(listItem) + { + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } + + public new static HistoryCategoryWrapper GetSample() + { + return new HistoryCategoryWrapper + { + ID = 30, + Title = "Lunch", + SortOrder = 10, + Color = String.Empty, + Description = "", + ImagePath = "path to image", + RelativeItemsCount = 1 + }; + } + } + + #endregion + + #region Deal Milestone + + [DataContract(Name = "opportunityStagesBase", Namespace = "")] + public class DealMilestoneBaseWrapper : ListItemWrapper + { + public DealMilestoneBaseWrapper() + : base(0) + { + } + + public DealMilestoneBaseWrapper(DealMilestone dealMilestone) + : base(dealMilestone.ID) + { + SuccessProbability = dealMilestone.Probability; + StageType = dealMilestone.Status; + Color = dealMilestone.Color; + Description = dealMilestone.Description; + Title = dealMilestone.Title; + } + + [DataMember] + public int SuccessProbability { get; set; } + + [DataMember] + public DealMilestoneStatus StageType { get; set; } + + public static DealMilestoneBaseWrapper GetSample() + { + return new DealMilestoneBaseWrapper + { + ID = 30, + Title = "Discussion", + SortOrder = 2, + Color = "#B9AFD3", + Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal", + StageType = DealMilestoneStatus.Open, + SuccessProbability = 20 + }; + } + } + + [DataContract(Name = "opportunityStages", Namespace = "")] + public class DealMilestoneWrapper : DealMilestoneBaseWrapper + { + public DealMilestoneWrapper() + { + } + + public DealMilestoneWrapper(DealMilestone dealMilestone) + : base(dealMilestone) + { + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } + + public new static DealMilestoneWrapper GetSample() + { + return new DealMilestoneWrapper + { + ID = 30, + Title = "Discussion", + SortOrder = 2, + Color = "#B9AFD3", + Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal", + StageType = DealMilestoneStatus.Open, + SuccessProbability = 20, + RelativeItemsCount = 1 + }; + } + } + + #endregion + + #region Task Category + + [DataContract(Name = "taskCategoryBase", Namespace = "")] + public class TaskCategoryBaseWrapper : ListItemWrapper + { + public TaskCategoryBaseWrapper() + : base(0) + { + } + + public TaskCategoryBaseWrapper(ListItem listItem) + : base(listItem) + { + ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID); + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String ImagePath { get; set; } + + public static TaskCategoryBaseWrapper GetSample() + { + return new TaskCategoryBaseWrapper + { + ID = 30, + Title = "Appointment", + SortOrder = 2, + Description = "", + ImagePath = "path to image" + }; + } + } + + [DataContract(Name = "taskCategory", Namespace = "")] + public class TaskCategoryWrapper : TaskCategoryBaseWrapper + { + public TaskCategoryWrapper() + { + } + + public TaskCategoryWrapper(ListItem listItem) + : base(listItem) + { + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } + + public new static TaskCategoryWrapper GetSample() + { + return new TaskCategoryWrapper + { + ID = 30, + Title = "Appointment", + SortOrder = 2, + Description = "", + ImagePath = "path to image", + RelativeItemsCount = 1 + }; + } + } + + #endregion + + #region Contact Status + + [DataContract(Name = "contactStatusBase", Namespace = "")] + public class ContactStatusBaseWrapper : ListItemWrapper + { + public ContactStatusBaseWrapper() : + base(0) + { + } + + public ContactStatusBaseWrapper(ListItem listItem) + : base(listItem) + { + } + + public static ContactStatusBaseWrapper GetSample() + { + return new ContactStatusBaseWrapper + { + ID = 30, + Title = "Cold", + SortOrder = 2, + Description = "" + }; + } + } + + [DataContract(Name = "contactStatus", Namespace = "")] + public class ContactStatusWrapper : ContactStatusBaseWrapper + { + public ContactStatusWrapper() + { + } + + public ContactStatusWrapper(ListItem listItem) + : base(listItem) + { + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } + + public new static ContactStatusWrapper GetSample() + { + return new ContactStatusWrapper + { + ID = 30, + Title = "Cold", + SortOrder = 2, + Description = "", + RelativeItemsCount = 1 + }; + } + } + + #endregion + + #region Contact Type + + [DataContract(Name = "contactTypeBase", Namespace = "")] + public class ContactTypeBaseWrapper : ListItemWrapper + { + public ContactTypeBaseWrapper() : + base(0) + { + } + + public ContactTypeBaseWrapper(ListItem listItem) + : base(listItem) + { + } + + public static ContactTypeBaseWrapper GetSample() + { + return new ContactTypeBaseWrapper + { + ID = 30, + Title = "Client", + SortOrder = 2, + Description = "" + }; + } + } + + [DataContract(Name = "contactType", Namespace = "")] + public class ContactTypeWrapper : ContactTypeBaseWrapper + { + public ContactTypeWrapper() + { + } + + public ContactTypeWrapper(ListItem listItem) + : base(listItem) + { + } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } + + public new static ContactTypeWrapper GetSample() + { + return new ContactTypeWrapper + { + ID = 30, + Title = "Client", + SortOrder = 2, + Description = "", + RelativeItemsCount = 1 + }; + } + } + + #endregion + + #region Tags + + [DataContract(Name = "tagWrapper", Namespace = "")] + public class TagWrapper + { + public TagWrapper() + { + Title = String.Empty; + RelativeItemsCount = 0; + } + + public TagWrapper(String tag, int relativeItemsCount = 0) + { + Title = tag; + RelativeItemsCount = relativeItemsCount; + } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String Title { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } + + public static TagWrapper GetSample() + { + return new TagWrapper + { + Title = "Tag", + RelativeItemsCount = 1 + }; + } + } + + #endregion + + [DataContract(Name = "listItem", Namespace = "")] + public abstract class ListItemWrapper + { + protected ListItemWrapper(int id) + { + } + + protected ListItemWrapper(ListItem listItem) + { + Title = listItem.Title; + Description = listItem.Description; + Color = listItem.Color; + SortOrder = listItem.SortOrder; + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Color { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int SortOrder { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs new file mode 100644 index 00000000000..eacb2244dd2 --- /dev/null +++ b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs @@ -0,0 +1,178 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Common; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + /// + /// Opportunity + /// + [DataContract(Name = "opportunity", Namespace = "")] + public class OpportunityWrapper + { + + public OpportunityWrapper() + { + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable Members { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactBaseWrapper Contact { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String Title { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper Responsible { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public BidType BidType { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public decimal BidValue { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public CurrencyInfoWrapper BidCurrency { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int PerPeriodValue { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public DealMilestoneBaseWrapper Stage { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int SuccessProbability { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime ActualCloseDate { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime ExpectedCloseDate { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool IsPrivate { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable AccessList { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool CanEdit { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable CustomFields { get; set; } + + public static OpportunityWrapper GetSample() + { + return new OpportunityWrapper + { + CreateBy = EmployeeWraper.GetSample(), + Created = ApiDateTime.GetSample(), + Responsible = EmployeeWraper.GetSample(), + Title = "Hotel catalogue", + Description = "", + ExpectedCloseDate = ApiDateTime.GetSample(), + Contact = ContactBaseWrapper.GetSample(), + IsPrivate = false, + SuccessProbability = 65, + BidType = BidType.FixedBid, + Stage = DealMilestoneBaseWrapper.GetSample() + }; + } + } + + + public class OpportunityWrapperHelper + { + public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + } + + public CRMSecurity CRMSecurity { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + + public OpportunityWrapper Get(Deal deal) + { + return new OpportunityWrapper + { + Id = deal.ID, + CreateBy = EmployeeWraperHelper.Get(deal.CreateBy), + Created = ApiDateTimeHelper.Get(deal.CreateOn), + Title = deal.Title, + Description = deal.Description, + Responsible = EmployeeWraperHelper.Get(deal.ResponsibleID), + BidType = deal.BidType, + BidValue = deal.BidValue, + PerPeriodValue = deal.PerPeriodValue, + SuccessProbability = deal.DealMilestoneProbability, + ActualCloseDate = ApiDateTimeHelper.Get(deal.ActualCloseDate), + ExpectedCloseDate = ApiDateTimeHelper.Get(deal.ExpectedCloseDate), + CanEdit = CRMSecurity.CanEdit(deal) + }; + } + } + + public static class OpportunityWrapperHelperExtension + { + public static DIHelper AddOpportunityWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService(); + } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs new file mode 100644 index 00000000000..85bffeac0eb --- /dev/null +++ b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs @@ -0,0 +1,154 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Api.Documents; +using ASC.Common; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + [DataContract(Name = "entity", Namespace = "")] + public class EntityWrapper + { + [DataMember] + public String EntityType { get; set; } + + [DataMember] + public int EntityId { get; set; } + + [DataMember] + public String EntityTitle { get; set; } + + public static EntityWrapper GetSample() + { + return new EntityWrapper + { + EntityId = 123445, + EntityType = "opportunity", + EntityTitle = "Household appliances internet shop" + }; + } + } + + + [DataContract(Name = "historyEvent", Namespace = "")] + public class RelationshipEventWrapper + { + public RelationshipEventWrapper() + { + + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String Content { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public HistoryCategoryBaseWrapper Category { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactBaseWrapper Contact { get; set; } + + [DataMember] + public EntityWrapper Entity { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool CanEdit { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable> Files { get; set; } + + public static RelationshipEventWrapper GetSample() + { + return new RelationshipEventWrapper + { + CanEdit = true, + Category = HistoryCategoryBaseWrapper.GetSample(), + Entity = EntityWrapper.GetSample(), + Contact = ContactBaseWrapper.GetSample(), + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + Files = new[] { FileWrapper.GetSample() }, + Content = @"Agreed to meet at lunch and discuss the client commercial offer" + }; + } + } + + public class RelationshipEventWrapperHelper + { + public RelationshipEventWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + } + + public CRMSecurity CRMSecurity { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + + public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) + { + return new RelationshipEventWrapper + { + Id = relationshipEvent.ID, + CreateBy = EmployeeWraperHelper.Get(relationshipEvent.CreateBy), + Created = ApiDateTimeHelper.Get(relationshipEvent.CreateOn), + Content = relationshipEvent.Content, + Files = new List>(), + CanEdit = CRMSecurity.CanEdit(relationshipEvent) + }; + } + } + + public static class RelationshipEventWrapperHelperExtension + { + public static DIHelper AddRelationshipEventWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService(); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/ReportWrapper.cs b/products/ASC.CRM/Server/Model/ReportWrapper.cs new file mode 100644 index 00000000000..fece76b7da0 --- /dev/null +++ b/products/ASC.CRM/Server/Model/ReportWrapper.cs @@ -0,0 +1,48 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + [DataContract] + public class ReportWrapper + { + [DataMember] + public String ReportTitle { get; set; } + + [DataMember] + public String ReportDescription { get; set; } + + [DataMember] + public IEnumerable Lables { get; set; } + + [DataMember] + public Object Data { get; set; } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/Subject.cs b/products/ASC.CRM/Server/Model/Subject.cs new file mode 100644 index 00000000000..81a8dee81f0 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Subject.cs @@ -0,0 +1,37 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +namespace ASC.Api.CRM.Wrappers +{ + public enum SubjectEnum + { + Contact, + Person, + Company, + Case, + Opportunity + } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/TaskTemplateContainerWrapper.cs b/products/ASC.CRM/Server/Model/TaskTemplateContainerWrapper.cs new file mode 100644 index 00000000000..52a286131b5 --- /dev/null +++ b/products/ASC.CRM/Server/Model/TaskTemplateContainerWrapper.cs @@ -0,0 +1,118 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Web.Api.Models; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + [DataContract(Namespace = "taskTemplateContainer")] + public class TaskTemplateContainerWrapper + { + public TaskTemplateContainerWrapper() + { + + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = true)] + public String Title { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = true)] + public String EntityType { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable Items { get; set; } + + public static TaskTemplateContainerWrapper GetSample() + { + return new TaskTemplateContainerWrapper + { + EntityType = "contact", + Title = "Birthday greetings", + Items = new List + { + TaskTemplateWrapper.GetSample() + } + }; + } + } + + [DataContract(Namespace = "taskTemplate")] + public class TaskTemplateWrapper + { + public TaskTemplateWrapper() + { + + } + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public int ContainerID { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String Title { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public EmployeeWraper Responsible { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public TaskCategoryWrapper Category { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool isNotify { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public long OffsetTicks { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool DeadLineIsFixed { get; set; } + + public static TaskTemplateWrapper GetSample() + { + return new TaskTemplateWrapper + { + Title = "Send an Email", + Category = TaskCategoryWrapper.GetSample(), + isNotify = true, + Responsible = EmployeeWraper.GetSample(), + ContainerID = 12, + DeadLineIsFixed = false, + OffsetTicks = TimeSpan.FromDays(10).Ticks, + Description = "" + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/TaskWrapper.cs b/products/ASC.CRM/Server/Model/TaskWrapper.cs new file mode 100644 index 00000000000..1386d2c6055 --- /dev/null +++ b/products/ASC.CRM/Server/Model/TaskWrapper.cs @@ -0,0 +1,236 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Common; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using System; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + /// + /// Task + /// + [DataContract(Name = "task", Namespace = "")] + public class TaskWrapper + { + //public TaskWrapper(Task task) + //{ + // CreateBy = EmployeeWraper.Get(task.CreateBy); + // Created = (ApiDateTime)task.CreateOn; + // Title = task.Title; + // Description = task.Description; + // DeadLine = (ApiDateTime)task.DeadLine; + // Responsible = EmployeeWraper.Get(task.ResponsibleID); + // IsClosed = task.IsClosed; + // AlertValue = task.AlertValue; + //} + + [DataMember(Name = "id")] + public int Id { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactBaseWithEmailWrapper Contact { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime DeadLine { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int AlertValue { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper Responsible { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool IsClosed { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public TaskCategoryBaseWrapper Category { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EntityWrapper Entity { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool CanEdit { get; set; } + + public static TaskWrapper GetSample() + { + return new TaskWrapper + { + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + DeadLine = ApiDateTime.GetSample(), + IsClosed = false, + Responsible = EmployeeWraper.GetSample(), + // Category = TaskCategoryBaseWrapper.GetSample(), + CanEdit = true, + Title = "Send a commercial offer", + AlertValue = 0 + }; + } + } + + [DataContract(Name = "taskBase", Namespace = "")] + public class TaskBaseWrapper + { + [DataMember(Name = "id")] + public int Id { get; set; } + + public TaskBaseWrapper() + { + + } + + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime DeadLine { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int AlertValue { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper Responsible { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool IsClosed { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public TaskCategoryBaseWrapper Category { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EntityWrapper Entity { get; set; } + + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool CanEdit { get; set; } + + public static TaskBaseWrapper GetSample() + { + return new TaskBaseWrapper + { + DeadLine = ApiDateTime.GetSample(), + IsClosed = false, + Responsible = EmployeeWraper.GetSample(), + Category = TaskCategoryBaseWrapper.GetSample(), + CanEdit = true, + Title = "Send a commercial offer", + AlertValue = 0 + }; + } + } + + public class TaskWrapperHelper + { + + public TaskWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + DaoFactory daoFactory) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + DaoFactory = daoFactory; + } + + public CRMSecurity CRMSecurity { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public DaoFactory DaoFactory { get; } + + public TaskWrapper Get(Task task) + { + var result = new TaskWrapper + { + Title = task.Title, + Description = task.Description, + DeadLine = ApiDateTimeHelper.Get(task.DeadLine), + Responsible = EmployeeWraperHelper.Get(task.ResponsibleID), + IsClosed = task.IsClosed, + AlertValue = task.AlertValue + }; + + if (task.CategoryID > 0) + { + result.Category = GetTaskCategoryByID(task.CategoryID); + } + + if (task.ContactID > 0) + { + result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(task.ContactID)); + } + + if (task.EntityID > 0) + { + result.Entity = ToEntityWrapper(task.EntityType, task.EntityID); + } + + result.CanEdit = CRMSecurity.CanEdit(task); + + return result; + } + } + + public static class TaskWrapperHelperExtension + { + public static DIHelper AddTaskWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService(); + } + } +} + +//private TaskWrapper ToTaskWrapper(Task task) +//{ +// var result = new TaskWrapper(task); + +// return result; +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/VoipCallWrapper.cs b/products/ASC.CRM/Server/Model/VoipCallWrapper.cs new file mode 100644 index 00000000000..e260ef9cfe8 --- /dev/null +++ b/products/ASC.CRM/Server/Model/VoipCallWrapper.cs @@ -0,0 +1,95 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.VoipService; +using ASC.Web.Api.Models; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; + +namespace ASC.Api.CRM.Wrappers +{ + [DataContract(Name = "voipCall", Namespace = "")] + public class VoipCallWrapper + { + [DataMember(Order = 1)] + public string Id { get; set; } + + [DataMember(Order = 2)] + public string From { get; set; } + + [DataMember(Order = 3)] + public string To { get; set; } + + [DataMember(Order = 4)] + public VoipCallStatus? Status { get; set; } + + [DataMember(Order = 5)] + public EmployeeWraper AnsweredBy { get; set; } + + [DataMember(Order = 6)] + public ApiDateTime DialDate { get; set; } + + [DataMember(Order = 7)] + public int DialDuration { get; set; } + + [DataMember(Order = 10)] + public decimal Cost { get; set; } + + [DataMember(Order = 11)] + public ContactWrapper Contact { get; set; } + + [DataMember(Order = 11, EmitDefaultValue = false)] + public IEnumerable Calls { get; set; } + + [DataMember(Order = 13)] + public string RecordUrl { get; set; } + + [DataMember(Order = 14)] + public int RecordDuration { get; set; } + + public VoipCallWrapper(VoipCall call, ContactWrapper contact = null) + { + Id = call.Id; + From = call.From; + To = call.To; + Status = call.Status; + AnsweredBy = EmployeeWraper.Get(call.AnsweredBy); + DialDate = new ApiDateTime(call.DialDate); + DialDuration = call.DialDuration; + Cost = call.Price + call.ChildCalls.Sum(r=> r.Price) + call.VoipRecord.Price; + Contact = contact; + RecordUrl = call.VoipRecord.Uri; + RecordDuration = call.VoipRecord.Duration; + + if (call.ChildCalls.Any()) + { + Calls = call.ChildCalls.Select(childCall => new VoipCallWrapper(childCall)); + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index a084cb2dfde..0127db12fff 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; @@ -21,6 +22,28 @@ public static IHostBuilder CreateHostBuilder(string[] args) => .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); - }); + }) + .ConfigureAppConfiguration((hostingContext, config) => + { + var buided = config.Build(); + var path = buided["pathToConf"]; + if (!Path.IsPathRooted(path)) + { + path = Path.GetFullPath(Path.Combine(hostingContext.HostingEnvironment.ContentRootPath, path)); + } + + config.SetBasePath(path); + config + .AddInMemoryCollection(new Dictionary + { + {"pathToConf", path} + }) + .AddJsonFile("appsettings.json") + .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true) + .AddJsonFile("storage.json") + .AddJsonFile("kafka.json") + .AddJsonFile($"kafka.{hostingContext.HostingEnvironment.EnvironmentName}.json", true) + .AddEnvironmentVariables(); + }); } } diff --git a/products/ASC.CRM/Server/Properties/launchSettings.json b/products/ASC.CRM/Server/Properties/launchSettings.json index 710e91144ba..bc2f01e903f 100644 --- a/products/ASC.CRM/Server/Properties/launchSettings.json +++ b/products/ASC.CRM/Server/Properties/launchSettings.json @@ -1,5 +1,4 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", +{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, @@ -8,6 +7,7 @@ "sslPort": 0 } }, + "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { "IIS Express": { "commandName": "IISExpress", @@ -20,11 +20,11 @@ "Kestrel WebServer": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "weatherforecast", - "applicationUrl": "http://localhost:5000", + "launchUrl": "api/2.0/crm/task/10", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "applicationUrl": "http://localhost:5000" } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index 9bd79f9c996..d997536425e 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -23,6 +23,7 @@ * */ +using ASC.Common; using ASC.Core; using ASC.Core.Billing; using ASC.Core.Tenants; @@ -54,11 +55,11 @@ public NotifyClient(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; } - + public IServiceProvider ServiceProvider { get; } - public void SendAboutCreateNewContact(List recipientID, - int contactID, + public void SendAboutCreateNewContact(List recipientID, + int contactID, string contactTitle, NameValueCollection fields) { if ((recipientID.Count == 0) || String.IsNullOrEmpty(contactTitle)) return; @@ -114,26 +115,26 @@ private NameValueCollection ExtractBaseDataFrom(EntityType entityType, int entit case EntityType.Person: case EntityType.Company: case EntityType.Contact: - { - var contact = daoFactory.GetContactDao().GetByID(entityID); - title = contact != null ? contact.GetTitle() : string.Empty; - relativeURL = "default.aspx?id=" + entityID; - break; - } + { + var contact = daoFactory.GetContactDao().GetByID(entityID); + title = contact != null ? contact.GetTitle() : string.Empty; + relativeURL = "default.aspx?id=" + entityID; + break; + } case EntityType.Opportunity: - { - var deal = daoFactory.GetDealDao().GetByID(entityID); - title = deal != null ? deal.Title : string.Empty; - relativeURL = "deals.aspx?id=" + entityID; - break; - } + { + var deal = daoFactory.GetDealDao().GetByID(entityID); + title = deal != null ? deal.Title : string.Empty; + relativeURL = "deals.aspx?id=" + entityID; + break; + } case EntityType.Case: - { - var cases = daoFactory.GetCasesDao().GetByID(entityID); - title = cases != null ? cases.Title : string.Empty; - relativeURL = "cases.aspx?id=" + entityID; - break; - } + { + var cases = daoFactory.GetCasesDao().GetByID(entityID); + title = cases != null ? cases.Title : string.Empty; + relativeURL = "cases.aspx?id=" + entityID; + break; + } default: throw new ArgumentException(); @@ -156,7 +157,7 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable var securityContext = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); - + NameValueCollection baseEntityData; if (entity.EntityID != 0) @@ -197,7 +198,7 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable new TagValue(NotifyConstants.Tag_EntityID, baseEntityData["id"]), new TagValue(NotifyConstants.Tag_EntityRelativeURL, baseEntityData["entityRelativeURL"]), new TagValue(NotifyConstants.Tag_AdditionalData, - new Hashtable { + new Hashtable { { "Files", fileListInfoHashtable }, {"EventContent", entity.Content}})); @@ -220,7 +221,7 @@ public void SendAboutExportCompleted(Guid recipientID, String fileName, String f var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); - var recipient = notifySource.GetRecipientsProvider().GetRecipient(recipientID.ToString()); + var recipient = notifySource.GetRecipientsProvider().GetRecipient(recipientID.ToString()); client.SendNoticeToAsync(coreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, null, @@ -353,9 +354,9 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) // } // } - // var listItem = dao.ListItemDao.GetByID(task.CategoryID); + // var listItem = dao.GetListItemDao().GetByID(task.CategoryID); - // NotifyClient.Instance.SendTaskReminder(task, + // NotifyClient.SendTaskReminder(task, // listItem != null ? listItem.Title : string.Empty, // taskContact, taskCase, taskDeal); // } @@ -371,11 +372,11 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) //} public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal) - { + { using var scope = ServiceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); - + var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString()); if (recipient == null) return; @@ -420,7 +421,7 @@ public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskCo true, new TagValue(NotifyConstants.Tag_EntityTitle, task.Title), new TagValue(NotifyConstants.Tag_AdditionalData, - new Hashtable { + new Hashtable { { "TaskDescription", HttpUtility.HtmlEncode(task.Description) }, { "TaskCategory", taskCategoryTitle }, @@ -439,13 +440,13 @@ public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskCo } public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Contact taskContact, Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal, Hashtable fileListInfoHashtable) - { + { using var scope = ServiceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); var tenantUtil = scope.ServiceProvider.GetService(); - var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString()); + var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString()); if (recipient == null) return; @@ -482,7 +483,7 @@ public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Cont taskDealRelativeUrl = String.Format("products/crm/deals.aspx?id={0}", taskDeal.ID); taskDealTitle = taskDeal.Title.HtmlEncode(); } - + client.SendNoticeToAsync( NotifyConstants.Event_ResponsibleForTask, null, @@ -490,7 +491,7 @@ public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Cont true, new TagValue(NotifyConstants.Tag_EntityTitle, task.Title), new TagValue(NotifyConstants.Tag_AdditionalData, - new Hashtable { + new Hashtable { { "TaskDescription", HttpUtility.HtmlEncode(task.Description) }, { "Files", fileListInfoHashtable }, { "TaskCategory", taskCategoryTitle }, @@ -515,7 +516,7 @@ public void SendAboutResponsibleForOpportunity(Deal deal) var notifySource = scope.ServiceProvider.GetService(); var securityContext = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); - + var recipient = notifySource.GetRecipientsProvider().GetRecipient(deal.ResponsibleID.ToString()); if (recipient == null) return; @@ -528,22 +529,22 @@ public void SendAboutResponsibleForOpportunity(Deal deal) new TagValue(NotifyConstants.Tag_EntityTitle, deal.Title), new TagValue(NotifyConstants.Tag_EntityID, deal.ID), new TagValue(NotifyConstants.Tag_AdditionalData, - new Hashtable { + new Hashtable { { "OpportunityDescription", HttpUtility.HtmlEncode(deal.Description) } }) ); } + } - //public INotifyClient Client - //{ - // get { return client; } - //} - //private NotifyClient(INotifyClient client, INotifySource source) - //{ - // this.client = client; - // this.source = source; - //} + public static class NotifyClientExtention + { + public static DIHelper AddNotifyClientService(this DIHelper services) + { + services.TryAddScoped(); + return services; + + } } -} \ No newline at end of file +} diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 59650bedacf..91e8f3c453f 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using ASC.Api.Core.Auth; +using ASC.Api.Core.Core; using ASC.Api.Core.Middleware; using ASC.Common; using Microsoft.AspNetCore.Builder; @@ -12,26 +13,66 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using ASC.Common.Logging; +using Autofac.Extensions.DependencyInjection; +using ASC.Common.DependencyInjection; +using ASC.Api.CRM; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc.Authorization; +using Microsoft.AspNetCore.Mvc.Formatters; +using System.Text; namespace ASC.CRM { public class Startup { - public Startup(IConfiguration configuration) + public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) { Configuration = configuration; + HostEnvironment = hostEnvironment; } + public IHostEnvironment HostEnvironment { get; } + public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + services.AddHttpContextAccessor(); - services.AddControllers(); + + services.AddControllers() + .AddNewtonsoftJson() + .AddXmlSerializerFormatters(); + + services.AddTransient, CustomJsonOptionsWrapper>(); + + services.AddMemoryCache(); + + services.AddAuthentication("cookie") + .AddScheme("cookie", a => { }); + + var builder = services.AddMvcCore(config => + { + //var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); + //config.Filters.Add(new AuthorizeFilter(policy)); + //config.Filters.Add(new TypeFilterAttribute(typeof(TenantStatusFilter))); + //config.Filters.Add(new TypeFilterAttribute(typeof(PaymentFilter))); + //config.Filters.Add(new TypeFilterAttribute(typeof(IpSecurityFilter))); + //config.Filters.Add(new TypeFilterAttribute(typeof(ProductSecurityFilter))); + //config.Filters.Add(new CustomResponseFilterAttribute()); + //config.Filters.Add(new CustomExceptionFilterAttribute()); + //config.Filters.Add(new TypeFilterAttribute(typeof(FormatFilter))); + + config.OutputFormatters.RemoveType(); + config.OutputFormatters.Add(new XmlOutputFormatter()); + }); var diHelper = new DIHelper(services); - diHelper .AddCookieAuthHandler() .AddCultureMiddleware() @@ -40,6 +81,13 @@ public void ConfigureServices(IServiceCollection services) .AddProductSecurityFilter() .AddTenantStatusFilter(); + + diHelper.AddNLogManager("ASC.CRM"); + + diHelper.AddCRMControllerService(); + + services.AddAutofac(Configuration, HostEnvironment.ContentRootPath); + } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -50,8 +98,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseDeveloperExceptionPage(); } - - app.UseRouting(); app.UseAuthorization(); diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index 774db165bd9..a9d10a93de0 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -61,7 +61,8 @@ public CurrencyProvider(IOptionsMonitor logger, Configuration = configuration; SettingsManager = settingsManager; - var currencies = daoFactory.GetCurrencyInfoDao().GetAll(); + var daocur = daoFactory.GetCurrencyInfoDao(); + var currencies = daocur.GetAll(); if (currencies == null || currencies.Count == 0) { @@ -351,10 +352,10 @@ public static class CurrencyProviderExtention { public static DIHelper AddCurrencyProviderService(this DIHelper services) { - services.TryAddScoped(); + services.TryAddScoped(); - return services.AddSettingsManagerService() - .AddDaoFactoryService(); + return services.AddSettingsManagerService(); + // .AddDaoFactoryService(); } } -} \ No newline at end of file +} diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index cf579f8da88..3aec6ba17f5 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -773,7 +773,7 @@ public static DIHelper AddPdfCreatorService(this DIHelper services) return services.AddPathProviderService() .AddDocumentServiceConnectorService() .AddOrganisationLogoManagerService() - .AddDaoFactoryService() + // .AddDaoFactoryService() .AddInvoiceFormattedDataService(); } } diff --git a/products/ASC.CRM/Server/appsettings.Development.json b/products/ASC.CRM/Server/appsettings.Development.json deleted file mode 100644 index 8983e0fc1c5..00000000000 --- a/products/ASC.CRM/Server/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - } -} diff --git a/products/ASC.CRM/Server/appsettings.json b/products/ASC.CRM/Server/appsettings.json index d9d9a9bff6f..9bf702e3108 100644 --- a/products/ASC.CRM/Server/appsettings.json +++ b/products/ASC.CRM/Server/appsettings.json @@ -1,10 +1,3 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*" + "pathToConf": "..\\..\\..\\config" } From dda75ec8a3aac4e02bc6f7f58c2586d1eab3d83d Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Sat, 18 Apr 2020 20:49:09 +0300 Subject: [PATCH 13/61] crm: migrate Api to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 6 +- .../Server/Classes/TwilioController.cs | 288 ++++++---- products/ASC.CRM/Server/Classes/VoipEngine.cs | 36 +- products/ASC.CRM/Server/Controllers/CRMApi.cs | 65 --- .../ASC.CRM/Server/Controllers/CRMApiBase.cs | 84 --- .../ASC.CRM/Server/Controllers/CRMCalendar.cs | 118 ++-- .../Server/Controllers/CRMController.Cases.cs | 113 ++-- .../Controllers/CRMController.ContactInfo.cs | 20 +- .../Controllers/CRMController.Contacts.cs | 364 +++++------- .../CRMController.CurrencyRates.cs | 31 +- .../Controllers/CRMController.CustomFields.cs | 6 +- .../Server/Controllers/CRMController.Deals.cs | 83 +-- .../Controllers/CRMController.Invoices.cs | 160 ++---- .../Controllers/CRMController.ListItem.cs | 22 +- .../CRMController.RelationshipEvent.cs | 200 +++---- .../Controllers/CRMController.Reports.cs | 28 +- .../Server/Controllers/CRMController.Tag.cs | 11 +- .../Server/Controllers/CRMController.Utils.cs | 83 +-- .../{CRMApi.Voip.cs => CRMController.Voip.cs} | 127 ++--- .../Server/Controllers/CRMController.cs | 148 ++++- .../Server/Core/Search/CasesWrapper.cs | 2 +- products/ASC.CRM/Server/Model/CasesWrapper.cs | 31 +- .../ASC.CRM/Server/Model/ContactWrapper.cs | 321 +++++++---- .../Server/Model/CurrencyInfoWrapper.cs | 108 +++- .../Server/Model/CurrencyRateWrapper.cs | 46 +- .../ASC.CRM/Server/Model/InvoiceWrapper.cs | 532 +++++++++++++----- .../ASC.CRM/Server/Model/ListItemWrapper.cs | 4 +- .../Server/Model/OpportunityWrapper.cs | 64 ++- .../Server/Model/RelationshipEventWrapper.cs | 51 +- products/ASC.CRM/Server/Model/TaskWrapper.cs | 7 +- 30 files changed, 1833 insertions(+), 1326 deletions(-) delete mode 100644 products/ASC.CRM/Server/Controllers/CRMApi.cs delete mode 100644 products/ASC.CRM/Server/Controllers/CRMApiBase.cs rename products/ASC.CRM/Server/Controllers/{CRMApi.Voip.cs => CRMController.Voip.cs} (90%) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index ffe27ac80f6..cc863371c15 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -6,14 +6,11 @@ - - - @@ -34,7 +31,6 @@ - @@ -48,11 +44,13 @@ + + diff --git a/products/ASC.CRM/Server/Classes/TwilioController.cs b/products/ASC.CRM/Server/Classes/TwilioController.cs index 5ebaa54891b..6ecd3635bd3 100644 --- a/products/ASC.CRM/Server/Classes/TwilioController.cs +++ b/products/ASC.CRM/Server/Classes/TwilioController.cs @@ -24,17 +24,22 @@ */ +using ASC.Common; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.Configuration; +using ASC.Core.Notify.Signalr; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.VoipService; using ASC.VoipService.Twilio; -using ASC.Web.CRM.Core; using ASC.Web.Studio.Utility; using Autofac; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; @@ -42,14 +47,36 @@ using System.Net.Http; using System.Text; using System.Web; +using System.Web.Http; +using Twilio.AspNet.Common; +using Twilio.AspNet.Core; using Twilio.TwiML; namespace ASC.Web.CRM.Classes { - [ValidateRequest] + + [ServiceFilter(typeof(ValidateRequestAttribute))] public class TwilioController : ApiController { - private static readonly ILog Log = LogManager.GetLogger("ASC"); + public TwilioController(IOptionsMonitor logger, + DaoFactory daoFactory, + VoipEngine voipEngine, + TenantManager tenantManager, + SecurityContext securityContext) + { + TenantManager = tenantManager; + Log = logger.Get("ASC"); + DaoFactory = daoFactory; + VoipEngine = voipEngine; + SecurityContext = securityContext; + } + + public SecurityContext SecurityContext { get; } + public TenantManager TenantManager { get; } + public VoipEngine VoipEngine { get; } + public DaoFactory DaoFactory { get; } + + private readonly ILog Log; private static readonly object LockObj = new object(); [System.Web.Http.HttpPost] @@ -59,13 +86,12 @@ public HttpResponseMessage Index(TwilioVoiceRequest request, [FromUri]Guid? call { lock (LockObj) { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - request.AddAdditionalFields(callerId, contactId); - var response = request.IsInbound ? Inbound(request, daoFactory) : Outbound(request, daoFactory); - return GetHttpResponse(response); - } + request.AddAdditionalFields(callerId, contactId); + + var response = request.IsInbound ? Inbound(request, DaoFactory) : Outbound(request, DaoFactory); + + return GetHttpResponse(response); + } } catch (Exception e) @@ -80,14 +106,11 @@ public HttpResponseMessage Client(TwilioVoiceRequest request, [FromUri]Guid call { try { - using (var scope = DIHelper.Resolve()) - { - request.AddAdditionalFields(callerId); + request.AddAdditionalFields(callerId); - new VoipEngine(scope.Resolve()).SaveOrUpdateCall(CallFromTwilioRequest(request)); + VoipEngine.SaveOrUpdateCall(CallFromTwilioRequest(request)); - return GetHttpResponse(new VoiceResponse()); - } + return GetHttpResponse(new VoiceResponse()); } catch (Exception e) { @@ -101,32 +124,27 @@ public HttpResponseMessage Dial(TwilioVoiceRequest request, [FromUri]Guid caller { try { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var voipEngine = new VoipEngine(daoFactory); + request.AddAdditionalFields(callerId, contactId, reject); - request.AddAdditionalFields(callerId, contactId, reject); + var call = CallFromTwilioRequest(request); + call = VoipEngine.SaveOrUpdateCall(call); - var call = CallFromTwilioRequest(request); - call = voipEngine.SaveOrUpdateCall(call); + var parentCall = DaoFactory.GetVoipDao().GetCall(call.ParentID); - var parentCall = daoFactory.VoipDao.GetCall(call.ParentID); - - if (!string.IsNullOrEmpty(request.RecordingSid)) + if (!string.IsNullOrEmpty(request.RecordingSid)) + { + if (parentCall.VoipRecord == null || string.IsNullOrEmpty(parentCall.VoipRecord.Id)) { - if (parentCall.VoipRecord == null || string.IsNullOrEmpty(parentCall.VoipRecord.Id)) - { - parentCall.VoipRecord = new VoipRecord {Id = request.RecordingSid}; - } - - daoFactory.VoipDao.SaveOrUpdateCall(parentCall); + parentCall.VoipRecord = new VoipRecord { Id = request.RecordingSid }; } - voipEngine.SaveAdditionalInfo(parentCall.Id); - - return GetHttpResponse(request.Dial()); + DaoFactory.GetVoipDao().SaveOrUpdateCall(parentCall); } + + VoipEngine.SaveAdditionalInfo(parentCall.Id); + + return GetHttpResponse(request.Dial()); + } catch (Exception e) { @@ -140,19 +158,15 @@ public HttpResponseMessage Enqueue(TwilioVoiceRequest request, [FromUri]Guid? ca { try { - using (var scope = DIHelper.Resolve()) + request.AddAdditionalFields(callerId, contactId); + + if (request.QueueResult != "bridged" && request.QueueResult != "redirected") { - var daoFactory = scope.Resolve(); - var voipEngine = new VoipEngine(daoFactory); + MissCall(request, VoipEngine); + } - request.AddAdditionalFields(callerId, contactId); - if (request.QueueResult != "bridged" && request.QueueResult != "redirected") - { - MissCall(request, voipEngine); - } + return GetHttpResponse(request.Enqueue(request.QueueResult)); - return GetHttpResponse(request.Enqueue(request.QueueResult)); - } } catch (Exception e) { @@ -181,22 +195,18 @@ public HttpResponseMessage Dequeue(TwilioVoiceRequest request, [FromUri]Guid? ca { try { - using (var scope = DIHelper.Resolve()) - { - var voipEngine = new VoipEngine(scope.Resolve()); - request.AddAdditionalFields(callerId, contactId, reject); + request.AddAdditionalFields(callerId, contactId, reject); - if (Convert.ToBoolean(request.Reject)) - { - MissCall(request, voipEngine); - return GetHttpResponse(request.Leave()); - } + if (Convert.ToBoolean(request.Reject)) + { + MissCall(request, VoipEngine); + return GetHttpResponse(request.Leave()); + } + VoipEngine.AnswerCall(CallFromTwilioRequest(request)); - voipEngine.AnswerCall(CallFromTwilioRequest(request)); + return GetHttpResponse(request.Dequeue()); - return GetHttpResponse(request.Dequeue()); - } } catch (Exception e) { @@ -210,32 +220,30 @@ public HttpResponseMessage Wait(TwilioVoiceRequest request, [FromUri]Guid? calle { try { - using (var scope = DIHelper.Resolve()) + + request.AddAdditionalFields(callerId, contactId, redirectTo: redirectTo); + if (Convert.ToInt32(request.QueueTime) == 0) { - var daoFactory = scope.Resolve(); - var voipEngine = new VoipEngine(daoFactory); + var history = CallFromTwilioRequest(request); + + history.ParentID = history.Id; - request.AddAdditionalFields(callerId, contactId, redirectTo: redirectTo); - if (Convert.ToInt32(request.QueueTime) == 0) + VoipEngine.SaveOrUpdateCall(history); + + var to = request.RedirectTo; + if (string.IsNullOrEmpty(to)) { - var history = CallFromTwilioRequest(request); - history.ParentID = history.Id; - voipEngine.SaveOrUpdateCall(history); - - var to = request.RedirectTo; - if (string.IsNullOrEmpty(to)) - { - request.GetSignalRHelper() - .Enqueue(request.CallSid, callerId.HasValue ? callerId.Value.ToString() : ""); - } - else - { - request.GetSignalRHelper().Incoming(request.CallSid, to); - } + request.GetSignalRHelper() + .Enqueue(request.CallSid, callerId.HasValue ? callerId.Value.ToString() : ""); + } + else + { + request.GetSignalRHelper().Incoming(request.CallSid, to); } - - return GetHttpResponse(request.Wait()); } + + return GetHttpResponse(request.Wait()); + } catch (Exception e) { @@ -279,16 +287,12 @@ public HttpResponseMessage VoiceMail(TwilioVoiceRequest request, [FromUri]Guid? { try { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var voipEngine = new VoipEngine(daoFactory); - request.AddAdditionalFields(callerId, contactId); + request.AddAdditionalFields(callerId, contactId); - MissCall(request, voipEngine); + MissCall(request, VoipEngine); + + return GetHttpResponse(request.VoiceMail()); - return GetHttpResponse(request.VoiceMail()); - } } catch (Exception e) { @@ -299,7 +303,7 @@ public HttpResponseMessage VoiceMail(TwilioVoiceRequest request, [FromUri]Guid? private VoiceResponse Inbound(TwilioVoiceRequest request, DaoFactory daoFactory) { - SecurityContext.AuthenticateMe(CoreContext.TenantManager.GetCurrentTenant().OwnerId); + SecurityContext.AuthenticateMe(TenantManager.GetCurrentTenant().OwnerId); var call = SaveCall(request, VoipCallStatus.Incoming, daoFactory); return request.Inbound(call, daoFactory); @@ -311,7 +315,8 @@ private VoiceResponse Outbound(TwilioVoiceRequest request, DaoFactory daoFactory var history = CallFromTwilioRequest(request); history.ParentID = history.Id; - new VoipEngine(daoFactory).SaveOrUpdateCall(history); + + VoipEngine.SaveOrUpdateCall(history); return request.Outbound(); } @@ -320,7 +325,8 @@ private VoipCall SaveCall(TwilioVoiceRequest request, VoipCallStatus status, Dao { var call = CallFromTwilioRequest(request); call.Status = status; - return daoFactory.VoipDao.SaveOrUpdateCall(call); + + return DaoFactory.GetVoipDao().SaveOrUpdateCall(call); } private void MissCall(TwilioVoiceRequest request, VoipEngine voipEngine) @@ -369,7 +375,7 @@ private VoipCall CallFromTwilioRequest(TwilioVoiceRequest request) } - private static HttpResponseMessage GetHttpResponse(VoiceResponse response) + private HttpResponseMessage GetHttpResponse(VoiceResponse response) { Log.Info(response); return new HttpResponseMessage { Content = new StringContent(response.ToString(), Encoding.UTF8, "application/xml") }; @@ -378,6 +384,33 @@ private static HttpResponseMessage GetHttpResponse(VoiceResponse response) public class TwilioVoiceRequest : VoiceRequest { + public TwilioVoiceRequest(TwilioResponseHelper twilioResponseHelper, + CommonLinkUtility commonLinkUtility, + DaoFactory daoFactory, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + VoipEngine voipEngine, + SignalrServiceClient signalrServiceClient) + { + + DaoFactory = daoFactory; + CommonLinkUtility = commonLinkUtility; + TwilioResponseHelper = twilioResponseHelper; + SecurityContext = securityContext; + CRMSecurity = cRMSecurity; + VoipEngine = voipEngine; + SignalrServiceClient = signalrServiceClient; + + } + + public SignalrServiceClient SignalrServiceClient { get; } + + public VoipEngine VoipEngine { get; } + public CRMSecurity CRMSecurity { get; } + public TwilioResponseHelper TwilioResponseHelper { get; } + public CommonLinkUtility CommonLinkUtility { get; } + public DaoFactory DaoFactory { get; } + public SecurityContext SecurityContext { get; } public Guid CallerId { get; set; } public int ContactId { get; set; } public string ParentCallSid { get; set; } @@ -390,25 +423,21 @@ public class TwilioVoiceRequest : VoiceRequest public bool Pause { get { return GetSettings().Pause; } } - private TwilioResponseHelper twilioResponseHelper; private TwilioResponseHelper GetTwilioResponseHelper() { - return twilioResponseHelper ?? (twilioResponseHelper = new TwilioResponseHelper(GetSettings(), CommonLinkUtility.GetFullAbsolutePath(""))); + return TwilioResponseHelper; } private VoipSettings settings; private VoipSettings GetSettings() { - using (var scope = DIHelper.Resolve()) - { - return settings ?? (settings = scope.Resolve().VoipDao.GetNumber(IsInbound ? To : From).Settings); - } + return settings ?? (settings = DaoFactory.GetVoipDao().GetNumber(IsInbound ? To : From).Settings); } private SignalRHelper signalRHelper; public SignalRHelper GetSignalRHelper() { - return signalRHelper ?? (signalRHelper = new SignalRHelper(IsInbound ? To : From)); + return signalRHelper ?? (signalRHelper = new SignalRHelper(IsInbound ? To : From, SignalrServiceClient)); } public bool IsInbound @@ -446,7 +475,7 @@ internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) : call.To; Contact contact; - var contacts = new VoipEngine(daoFactory).GetContacts(contactPhone, daoFactory); + var contacts = VoipEngine.GetContacts(contactPhone, daoFactory); var managers = contacts.SelectMany(CRMSecurity.GetAccessSubjectGuidsTo).ToList(); var agent = GetSignalRHelper().GetAgent(managers); @@ -458,7 +487,7 @@ internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) contact = contacts.FirstOrDefault(CRMSecurity.CanAccessTo); - daoFactory.VoipDao.SaveOrUpdateCall(call); + DaoFactory.GetVoipDao().SaveOrUpdateCall(call); } else { @@ -467,9 +496,9 @@ internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) if (contact == null) { - contact = new VoipEngine(daoFactory).CreateContact(call.From.TrimStart('+')); + contact = VoipEngine.CreateContact(call.From.TrimStart('+')); call.ContactId = contact.ID; - daoFactory.VoipDao.SaveOrUpdateCall(call); + DaoFactory.GetVoipDao().SaveOrUpdateCall(call); } return GetTwilioResponseHelper().Inbound(agent); @@ -488,11 +517,64 @@ internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) public class ValidateRequestAttribute : ActionFilterAttribute { + public ValidateRequestAttribute(ConsumerFactory consumerFactory, IHttpContextAccessor httpContextAccessor) + { + ConsumerFactory = consumerFactory; + HttpContext = httpContextAccessor?.HttpContext; + } + + public HttpContext HttpContext { get; } + public ConsumerFactory ConsumerFactory { get; } + public override void OnActionExecuting(ActionExecutingContext filterContext) { - if (!new RequestValidationHelper().IsValidRequest(filterContext.HttpContext, ConsumerFactory.Get()["twilioAuthToken"], HttpContext.Current.Request.GetUrlRewriter().AbsoluteUri)) - filterContext.Result = new Twilio.AspNet.Mvc.HttpStatusCodeResult(HttpStatusCode.Forbidden); + if (!new RequestValidationHelper().IsValidRequest(filterContext.HttpContext, ConsumerFactory.Get()["twilioAuthToken"], HttpContext.Request.GetUrlRewriter().AbsoluteUri)) + filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden); + base.OnActionExecuting(filterContext); + } } + + public static class TwilioControllerExtension + { + public static DIHelper AddTwilioControllerService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddDaoFactoryService() + .AddVoipEngineService() + .AddTenantManagerService() + .AddSecurityContextService(); + + } + } + + public static class TwilioVoiceRequestExtension + { + public static DIHelper AddTwilioVoiceRequestService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddCommonLinkUtilityService() + .AddDaoFactoryService() + .AddSecurityContextService() + .AddCRMSecurityService() + .AddSignalrServiceClient(); + + } + } + + + public static class ValidateRequestAttributeExtension + { + public static DIHelper AddValidateRequestAttributeService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddConsumerFactoryService(); + + } + } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index c397f1da833..fab91061302 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Logging; using ASC.Common.Threading.Workers; using ASC.Core; @@ -240,9 +241,9 @@ private void SaveAdditionalInfoAction(QueueItem queueItem) var voipEngine = new VoipEngine(DaoFactory, CRMSecurity, - TenantUtil, - SecurityContext, - null, + TenantUtil, + SecurityContext, + null, TenantManager, VoipDao); @@ -327,4 +328,33 @@ private class QueueItem public string CallID { get; set; } } } + + + + public static class VoipEngineExtension + { + public static DIHelper AddVoipEngineService(this DIHelper services) + { + services.TryAddScoped(); + + return services.AddDaoFactoryService() + .AddCRMSecurityService() + .AddTenantUtilService() + .AddSecurityContextService() + .AddTenantManagerService(); + } + } + + //public VoipEngine(DaoFactory daoFactory, + // CRMSecurity cRMSecurity, + // TenantUtil tenantUtil, + // SecurityContext securityContext, + // IOptionsMonitor logger, + // TenantManager tenantManager, + // VoipDao voipDao) + + + + + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMApi.cs b/products/ASC.CRM/Server/Controllers/CRMApi.cs deleted file mode 100644 index 34f1b1daff7..00000000000 --- a/products/ASC.CRM/Server/Controllers/CRMApi.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using System.Web; -using ASC.Api.Exceptions; -using ASC.Api.Impl; -using ASC.Api.Interfaces; -using ASC.CRM.Core; -using ASC.CRM.Core.Entities; - -namespace ASC.Api.CRM -{ - public partial class CRMApi : CRMApiBase, IApiEntryPoint - { - private readonly ApiContext _context; - - /// - /// Api name entry - /// - public string Name - { - get { return "crm"; } - } - - - /// - /// Constructor - /// - /// - public CRMApi(ApiContext context) - { - _context = context; - } - - private static HttpRequest Request - { - get { return HttpContext.Current.Request; } - } - - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMApiBase.cs b/products/ASC.CRM/Server/Controllers/CRMApiBase.cs deleted file mode 100644 index a0587367e5c..00000000000 --- a/products/ASC.CRM/Server/Controllers/CRMApiBase.cs +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common.Web; -using ASC.Core; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.Files.Core; -using ASC.VoipService; -using ASC.VoipService.Dao; -using ASC.Web.Projects.Core; -using Autofac; -using FilesGlobal = ASC.Web.Files.Classes.Global; - -namespace ASC.Api.CRM -{ - public class CRMApiBase : IDisposable - { - private IDaoFactory filesDaoFactory; - - private readonly ILifetimeScope scope; - private readonly ILifetimeScope crmScope; - - public CRMApiBase() - { - scope = DIHelper.Resolve(); - ProjectsDaoFactory = scope.Resolve(); - - crmScope = Web.CRM.Core.DIHelper.Resolve(); - DaoFactory = crmScope.Resolve(); - } - - protected DaoFactory DaoFactory { get; private set; } - - protected IVoipProvider VoipProvider - { - get { return VoipDao.GetProvider(); } - } - - protected Projects.Core.DataInterfaces.IDaoFactory ProjectsDaoFactory { get; private set; } - - protected IDaoFactory FilesDaoFactory - { - get { return filesDaoFactory ?? (filesDaoFactory = FilesGlobal.DaoFactory); } - } - - public void Dispose() - { - if (scope != null) - { - scope.Dispose(); - } - - if (crmScope != null) - { - crmScope.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs index 9db1a314cce..e22e7c38446 100644 --- a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs +++ b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs @@ -24,20 +24,18 @@ */ -using System; -using System.Collections.Generic; -using System.Globalization; -using ASC.Web.Core.Calendars; +using ASC.Common; +using ASC.Common.Utils; using ASC.Core; +using ASC.Core.Tenants; using ASC.CRM.Core.Dao; -using ASC.CRM.Core; -using ASC.Projects.Engine; -using ASC.Web.Core; -using ASC.Web.CRM.Core; -using Autofac; -using ASC.CRM.Resources; using ASC.CRM.Core.Enums; -using ASC.Core.Tenants; +using ASC.CRM.Resources; +using ASC.Web.Core; +using ASC.Web.Core.Calendars; +using System; +using System.Collections.Generic; +using System.Globalization; namespace ASC.Api.CRM { @@ -48,9 +46,24 @@ private class Event : BaseEvent { } + public WebItemSecurity WebItemSecurity { get; } + public DaoFactory DaoFactory { get; } + public TenantManager TenantManager { get; } + public TenantUtil TenantUtil { get; } - public CRMCalendar(Guid userId) + public CRMCalendar(WebItemSecurity webItemSecurity, + DaoFactory daoFactory, + AuthContext authContext, + TimeZoneConverter timeZoneConverter, + TenantManager tenantManager, + TenantUtil tenantUtil + ) : base(authContext, timeZoneConverter) { + TenantUtil = tenantUtil; + TenantManager = tenantManager; + WebItemSecurity = webItemSecurity; + DaoFactory = daoFactory; + Context.HtmlBackgroundColor = ""; Context.HtmlTextColor = ""; Context.CanChangeAlertType = false; @@ -61,55 +74,52 @@ public CRMCalendar(Guid userId) Name = CRMCommonResource.ProductName; Description = ""; SharingOptions = new SharingOptions(); - SharingOptions.PublicItems.Add(new SharingOptions.PublicItem {Id = userId, IsGroup = false}); +// SharingOptions.PublicItems.Add(new SharingOptions.PublicItem { Id = userId, IsGroup = false }); } public override List LoadEvents(Guid userId, DateTime startDate, DateTime endDate) { - using (var scope = DIHelper.Resolve()) + var events = new List(); + + if ( + !WebItemSecurity.IsAvailableForMe(WebItemManager.CRMProductID)) { - var _daoFactory = scope.Resolve(); - var events = new List(); + return events; + } - if ( - !WebItemSecurity.IsAvailableForMe(WebItemManager.CRMProductID)) - { - return events; - } + var tasks = DaoFactory.GetTaskDao().GetTasks(String.Empty, userId, 0, false, DateTime.MinValue, + DateTime.MinValue, EntityType.Any, 0, 0, 0, null); + + foreach (var t in tasks) + { + if (t.DeadLine == DateTime.MinValue) continue; - var tasks = _daoFactory.GetTaskDao().GetTasks(String.Empty, userId, 0, false, DateTime.MinValue, - DateTime.MinValue, EntityType.Any, 0, 0, 0, null); + var allDayEvent = t.DeadLine.Hour == 0 && t.DeadLine.Minute == 0; + var utcDate = allDayEvent ? t.DeadLine.Date : TenantUtil.DateTimeToUtc(t.DeadLine); - foreach (var t in tasks) + var e = new Event { - if (t.DeadLine == DateTime.MinValue) continue; - - var allDayEvent = t.DeadLine.Hour == 0 && t.DeadLine.Minute == 0; - var utcDate = allDayEvent ? t.DeadLine.Date : TenantUtil.DateTimeToUtc(t.DeadLine); - - var e = new Event - { - AlertType = EventAlertType.Never, - AllDayLong = allDayEvent, - CalendarId = Id, - UtcStartDate = utcDate, - UtcEndDate = utcDate, - Id = "crm_task_" + t.ID.ToString(CultureInfo.InvariantCulture), - Name = Web.CRM.Resources.CRMCommonResource.ProductName + ": " + t.Title, - Description = t.Description - }; - - if (IsVisibleEvent(startDate, endDate, e.UtcStartDate, e.UtcEndDate)) - events.Add(e); - } + AlertType = EventAlertType.Never, + AllDayLong = allDayEvent, + CalendarId = Id, + UtcStartDate = utcDate, + UtcEndDate = utcDate, + Id = "crm_task_" + t.ID.ToString(CultureInfo.InvariantCulture), + Name = CRMCommonResource.ProductName + ": " + t.Title, + Description = t.Description + }; - return events; + if (IsVisibleEvent(startDate, endDate, e.UtcStartDate, e.UtcEndDate)) + events.Add(e); } + + return events; + } public override TimeZoneInfo TimeZone { - get { return TenantManager.GetCurrentTenant().TimeZone; } + get { return TimeZoneInfo.FindSystemTimeZoneById(TenantManager.GetCurrentTenant().TimeZone); } } private bool IsVisibleEvent(DateTime startDate, DateTime endDate, DateTime eventStartDate, DateTime eventEndDate) @@ -119,4 +129,20 @@ private bool IsVisibleEvent(DateTime startDate, DateTime endDate, DateTime event (eventStartDate < startDate && eventEndDate > endDate); } } + + + public static class CRMCalendarDaoExtention + { + public static DIHelper AddCRMCalendarService(this DIHelper services) + { + services.TryAddScoped(); + services.TryAddScoped(); + + return services.AddWebItemManagerSecurity() + .AddDaoFactoryService() + .AddAuthContextService() + .AddTenantManagerService() + .AddTenantUtilService(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs index de8d9ed8397..4137a587bed 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs @@ -39,7 +39,6 @@ using System; using System.Collections.Generic; using System.Linq; -using EnumExtension = ASC.Web.CRM.Classes.EnumExtension; namespace ASC.Api.CRM { @@ -64,9 +63,9 @@ public CasesWrapper CloseCases(int caseid) var cases = DaoFactory.GetCasesDao().CloseCases(caseid); if (cases == null) throw new ItemNotFoundException(); - MessageService.Send( MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); + MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); - return ToCasesWrapper(cases); + return CasesWrapperHelper.Get(cases); } /// @@ -88,9 +87,9 @@ public CasesWrapper ReOpenCases(int caseid) var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid); if (cases == null) throw new ItemNotFoundException(); - MessageService.Send( MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); + MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); - return ToCasesWrapper(cases); + return CasesWrapperHelper.Get(cases); } /// @@ -133,13 +132,15 @@ public CasesWrapper CreateCases( var casesID = DaoFactory.GetCasesDao().CreateCases(title); var cases = new Cases - { - ID = casesID, - Title = title, - CreateBy = SecurityContext.CurrentAccount.ID, - CreateOn = DateTime.UtcNow - }; - FactoryIndexer.IndexAsync(cases); + { + ID = casesID, + Title = title, + CreateBy = SecurityContext.CurrentAccount.ID, + CreateOn = DateTime.UtcNow + }; + + FactoryIndexerCasesWrapper.IndexAsync(Web.CRM.Core.Search.CasesWrapper.GetCasesWrapper(ServiceProvider, cases)); + SetAccessToCases(cases, isPrivate, accessList, isNotify, false); var membersList = members != null ? members.ToList() : new List(); @@ -160,7 +161,7 @@ public CasesWrapper CreateCases( } } - return ToCasesWrapper(DaoFactory.GetCasesDao().GetByID(casesID)); + return CasesWrapperHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); } /// @@ -211,7 +212,7 @@ public CasesWrapper UpdateCases( DaoFactory.GetCasesDao().UpdateCases(cases); - if (CRMSecurity.IsAdmin || cases.CreateBy == Core.SecurityContext.CurrentAccount.ID) + if (CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) { SetAccessToCases(cases, isPrivate, accessList, isNotify, false); } @@ -234,7 +235,7 @@ public CasesWrapper UpdateCases( } } - return ToCasesWrapper(cases); + return CasesWrapperHelper.Get(cases); } /// @@ -258,7 +259,7 @@ public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable x.DisplayUserName(false))); + MessageService.Send(MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); } } else @@ -291,11 +292,11 @@ private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable @@ -324,7 +325,7 @@ public IEnumerable SetAccessToBatchCases(IEnumerable casesid, { if (c == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || c.CreateBy == Core.SecurityContext.CurrentAccount.ID)) continue; + if (!(CRMSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; SetAccessToCases(c, isPrivate, accessList, false, true); result.Add(c); @@ -367,7 +368,7 @@ IEnumerable accessList { if (casese == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || casese.CreateBy == Core.SecurityContext.CurrentAccount.ID)) continue; + if (!(CRMSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; SetAccessToCases(casese, isPrivate, accessList, false, true); result.Add(casese); @@ -392,7 +393,7 @@ public CasesWrapper GetCaseByID(int caseid) var cases = DaoFactory.GetCasesDao().GetByID(caseid); if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - return ToCasesWrapper(cases); + return CasesWrapperHelper.Get(cases); } /// @@ -415,7 +416,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumer var searchString = ApiContext.FilterValue; - if (EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) { casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); } @@ -474,7 +475,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumer } ApiContext.SetTotalCount(totalCount); - return result.ToSmartList(); + return result; } /// @@ -494,13 +495,14 @@ public CasesWrapper DeleteCase(int caseid) if (caseid <= 0) throw new ArgumentException(); var cases = DaoFactory.GetCasesDao().DeleteCases(caseid); + if (cases == null) throw new ItemNotFoundException(); - FactoryIndexer.DeleteAsync(cases); + FactoryIndexerCasesWrapper.DeleteAsync(Web.CRM.Core.Search.CasesWrapper.GetCasesWrapper(ServiceProvider, cases)); - MessageService.Send( MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); + MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); - return ToCasesWrapper(cases); + return CasesWrapperHelper.Get(cases); } /// @@ -524,7 +526,7 @@ public IEnumerable DeleteBatchCases(IEnumerable casesids) if (caseses == null || !caseses.Any()) return new List(); - MessageService.Send( MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); + MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); return ToListCasesWrappers(caseses); } @@ -550,7 +552,7 @@ public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); - MessageService.Send( MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); + MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); return ToListCasesWrappers(caseses); } @@ -598,7 +600,7 @@ public ContactWrapper AddMemberToCases(int caseid, int contactid) DaoFactory.GetCasesDao().AddMember(caseid, contactid); var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; - MessageService.Send( messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); return ToContactWrapper(contact); } @@ -631,7 +633,7 @@ public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; - MessageService.Send( messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); return result; } @@ -659,7 +661,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) { if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) { - result.Add(ToCasesWrapper(item)); + result.Add(CasesWrapperHelper.Get(item)); } } @@ -672,7 +674,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) foreach (var item in findedCases) { - result.Add(ToCasesWrapper(item)); + result.Add(CasesWrapperHelper.Get(item)); } } @@ -701,21 +703,21 @@ private IEnumerable ToListCasesWrappers(ICollection items) } var contacts = DaoFactory - .ContactDao + .GetContactDao() .GetContacts(contactIDs.Distinct().ToArray()) .ToDictionary(item => item.ID, ToContactBaseWrapper); foreach (var cases in items) { - var casesWrapper = new CasesWrapper(cases) - { - CustomFields = customFields.ContainsKey(cases.ID) - ? customFields[cases.ID] - : new List(), - Members = casesMembers.ContainsKey(cases.ID) + var casesWrapper = CasesWrapperHelper.Get(cases); + + casesWrapper.CustomFields = customFields.ContainsKey(cases.ID) + ? customFields[cases.ID] + : new List(); + + casesWrapper.Members = casesMembers.ContainsKey(cases.ID) ? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) - : new List() - }; + : new List(); result.Add(casesWrapper); } @@ -723,33 +725,6 @@ private IEnumerable ToListCasesWrappers(ICollection items) return result; } - private CasesWrapper ToCasesWrapper(Cases cases) - { - var casesWrapper = new CasesWrapper(cases) - { - CustomFields = DaoFactory - .CustomFieldDao - .GetEnityFields(EntityType.Case, cases.ID, false) - .ConvertAll(item => new CustomFieldBaseWrapper(item)) - .ToSmartList(), - Members = new List() - }; - - var memberIDs = DaoFactory.GetCasesDao().GetMembers(cases.ID); - var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); - - var membersWrapperList = new List(); - - foreach (var member in membersList) - { - if (member == null) continue; - membersWrapperList.Add(ToContactBaseWrapper(member)); - } - - casesWrapper.Members = membersWrapperList; - return casesWrapper; - } - private IEnumerable GetUsersByIdList(IEnumerable ids) { return UserManager.GetUsers().Where(x => ids.Contains(x.ID)); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs index f65209ff29a..622b4a8875b 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs @@ -26,6 +26,7 @@ using ASC.Api.CRM.Wrappers; using ASC.Common.Web; +using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -57,7 +58,7 @@ public partial class CRMController [Read(@"contact/data/{infoType}/category")] public IEnumerable GetContactInfoCategory(ContactInfoType infoType) { - return Enum.GetNames(ContactInfo.GetCategory(infoType)).ToItemList(); + return Enum.GetNames(ContactInfo.GetCategory(infoType)); } /// @@ -69,7 +70,7 @@ public IEnumerable GetContactInfoCategory(ContactInfoType infoType) [Read(@"contact/data/infoType")] public IEnumerable GetContactInfoType() { - return Enum.GetNames(typeof(ContactInfoType)).ToItemList(); + return Enum.GetNames(typeof(ContactInfoType)); } /// @@ -177,7 +178,8 @@ public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoT MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); var contactInfoWrapper = ToContactInfoWrapper(contactInfo); - contactInfoWrapper.ID = contactInfoID; + contactInfoWrapper.Id = contactInfoID; + return contactInfoWrapper; } @@ -281,7 +283,7 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEn for (var index = 0; index < itemsList.Count; index++) { var infoWrapper = itemsList[index]; - infoWrapper.ID = ids[index]; + infoWrapper.Id = ids[index]; } return itemsList; } @@ -447,7 +449,7 @@ public IEnumerable UpdateBatchContactInfo(int contactid, IEn for (var index = 0; index < itemsList.Count; index++) { var infoWrapper = itemsList[index]; - infoWrapper.ID = ids[index]; + infoWrapper.Id = ids[index]; } return itemsList; } @@ -508,22 +510,18 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) { FactoryIndexer.DeleteAsync(EmailWrapper.ToEmailWrapper(contact, new List { contactInfo})); } + FactoryIndexer.DeleteAsync(contactInfo); return wrapper; } - private static ContactInfoWrapper ToContactInfoWrapper(ContactInfo contactInfo) - { - return new ContactInfoWrapper(contactInfo); - } - private static ContactInfo FromContactInfoWrapper(ContactInfoWrapper contactInfoWrapper) { return new ContactInfo { - ID = contactInfoWrapper.ID, + ID = contactInfoWrapper.Id, Category = contactInfoWrapper.Category, Data = contactInfoWrapper.Data, InfoType = contactInfoWrapper.InfoType, diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs index 654b0d63d2c..751e1b552c0 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs @@ -34,7 +34,9 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.MessagingSystem; +using ASC.Web.Api.Models; using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; using ASC.Web.Studio.Core; using Autofac; using System; @@ -71,7 +73,9 @@ public ContactWrapper GetContactByID(int contactid) public IEnumerable GetContactsByID(IEnumerable contactid) { var contacts = DaoFactory.GetContactDao().GetContacts(contactid.ToArray()).Where(r => r != null && CRMSecurity.CanAccessTo(r)); + return ToListContactWrapper(contacts.ToList()); + } /// @@ -95,113 +99,113 @@ public IEnumerable GetContactsByProjectID(int projectid) return ToListContactWrapper(contacts.ToList()); } - /// - /// Links the selected contact to the project with the ID specified in the request - /// - /// Contact ID - /// Project ID - /// Contacts - /// Link contact with project - /// - /// - /// Contact Info - [Create(@"contact/{contactid:int}/project/{projectid:int}")] - public ContactWrapper SetRelativeContactToProject(int contactid, int projectid) - { - if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); - - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - - var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); - if (project == null) throw new ItemNotFoundException(); - - using (var scope = DIHelper.Resolve()) - { - if (!scope.Resolve().CanLinkContact(project)) throw CRMSecurity.CreateSecurityException(); - } - - DaoFactory.GetContactDao().SetRelativeContactProject(new List {contactid}, projectid); - - var messageAction = contact is Company ? MessageAction.ProjectLinkedCompany : MessageAction.ProjectLinkedPerson; - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); - - return ToContactWrapper(contact); - } - - /// - /// Links the selected contacts to the project with the ID specified in the request - /// - /// Contact IDs array - /// Project ID - /// Contacts - /// Link contact list with project - /// - /// - /// - /// Contact list - /// - [Create(@"contact/project/{projectid:int}")] - public IEnumerable SetRelativeContactListToProject(IEnumerable contactid, int projectid) - { - if (contactid == null) throw new ArgumentException(); + ///// + ///// Links the selected contact to the project with the ID specified in the request + ///// + ///// Contact ID + ///// Project ID + ///// Contacts + ///// Link contact with project + ///// + ///// + ///// Contact Info + //[Create(@"contact/{contactid:int}/project/{projectid:int}")] + //public ContactWrapper SetRelativeContactToProject(int contactid, int projectid) + //{ + // if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); + + // var contact = DaoFactory.GetContactDao().GetByID(contactid); + // if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + // var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); + // if (project == null) throw new ItemNotFoundException(); + + // using (var scope = DIHelper.Resolve()) + // { + // if (!scope.Resolve().CanLinkContact(project)) throw CRMSecurity.CreateSecurityException(); + // } + + // DaoFactory.GetContactDao().SetRelativeContactProject(new List {contactid}, projectid); + + // var messageAction = contact is Company ? MessageAction.ProjectLinkedCompany : MessageAction.ProjectLinkedPerson; + // MessageService.Send( messageAction, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); + + // return ToContactWrapper(contact); + //} + + ///// + ///// Links the selected contacts to the project with the ID specified in the request + ///// + ///// Contact IDs array + ///// Project ID + ///// Contacts + ///// Link contact list with project + ///// + ///// + ///// + ///// Contact list + ///// + //[Create(@"contact/project/{projectid:int}")] + //public IEnumerable SetRelativeContactListToProject(IEnumerable contactid, int projectid) + //{ + // if (contactid == null) throw new ArgumentException(); - var contactIds = contactid.ToList(); + // var contactIds = contactid.ToList(); - if (!contactIds.Any() || projectid <= 0) throw new ArgumentException(); + // if (!contactIds.Any() || projectid <= 0) throw new ArgumentException(); - var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); - if (project == null) throw new ItemNotFoundException(); + // var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); + // if (project == null) throw new ItemNotFoundException(); - using (var scope = DIHelper.Resolve()) - { - if (!scope.Resolve().CanLinkContact(project)) - throw CRMSecurity.CreateSecurityException(); - } + // using (var scope = DIHelper.Resolve()) + // { + // if (!scope.Resolve().CanLinkContact(project)) + // throw CRMSecurity.CreateSecurityException(); + // } - var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); - contactIds = contacts.Select(c => c.ID).ToList(); + // var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + // contactIds = contacts.Select(c => c.ID).ToList(); - DaoFactory.GetContactDao().SetRelativeContactProject(contactIds, projectid); + // DaoFactory.GetContactDao().SetRelativeContactProject(contactIds, projectid); - MessageService.Send( MessageAction.ProjectLinkedContacts, MessageTarget.Create(contactIds), project.Title, contacts.Select(x => x.GetTitle())); + // MessageService.Send( MessageAction.ProjectLinkedContacts, MessageTarget.Create(contactIds), project.Title, contacts.Select(x => x.GetTitle())); - return contacts.ConvertAll(ToContactWrapper); - } + // return contacts.ConvertAll(ToContactWrapper); + //} - /// - /// Removes the link with the selected project from the contact with the ID specified in the request - /// - /// Contact ID - /// Project ID - /// Contacts - /// Remove contact from project - /// - /// Contact info - /// - [Delete(@"contact/{contactid:int}/project/{projectid:int}")] - public ContactBaseWrapper RemoveRelativeContactToProject(int contactid, int projectid) - { - if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); + ///// + ///// Removes the link with the selected project from the contact with the ID specified in the request + ///// + ///// Contact ID + ///// Project ID + ///// Contacts + ///// Remove contact from project + ///// + ///// Contact info + ///// + //[Delete(@"contact/{contactid:int}/project/{projectid:int}")] + //public ContactBaseWrapper RemoveRelativeContactToProject(int contactid, int projectid) + //{ + // if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + // var contact = DaoFactory.GetContactDao().GetByID(contactid); + // if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); + // var project = ProjectsDaoFactory.ProjectDao.GetById(projectid); - using (var scope = DIHelper.Resolve()) - { - if (project == null || !scope.Resolve().CanLinkContact(project)) throw new ItemNotFoundException(); - } + // using (var scope = DIHelper.Resolve()) + // { + // if (project == null || !scope.Resolve().CanLinkContact(project)) throw new ItemNotFoundException(); + // } - DaoFactory.GetContactDao().RemoveRelativeContactProject(contactid, projectid); + // DaoFactory.GetContactDao().RemoveRelativeContactProject(contactid, projectid); - var action = contact is Company ? MessageAction.ProjectUnlinkedCompany : MessageAction.ProjectUnlinkedPerson; - MessageService.Send( action, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); + // var action = contact is Company ? MessageAction.ProjectUnlinkedCompany : MessageAction.ProjectUnlinkedPerson; + // MessageService.Send( action, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); - return ToContactBaseWrapper(contact); - } + // return ToContactBaseWrapper(contact); + //} /// /// Adds the selected opportunity to the contact with the ID specified in the request. The same as AddMemberToDeal @@ -230,7 +234,7 @@ public OpportunityWrapper AddDealToContact(int contactid, int opportunityid) var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; MessageService.Send( messageAction, MessageTarget.Create(contact.ID), opportunity.Title, contact.GetTitle()); - return ToOpportunityWrapper(opportunity); + return OpportunityWrapperHelper.Get(opportunity); } /// @@ -257,7 +261,7 @@ public OpportunityWrapper DeleteDealFromContact(int contactid, int opportunityid DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); - return ToOpportunityWrapper(opportunity); + return OpportunityWrapperHelper.Get(opportunity); } /// @@ -295,7 +299,7 @@ public IEnumerable GetContacts( var searchString = ApiContext.FilterValue; - if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) { contactsOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); } @@ -431,7 +435,7 @@ public IEnumerable GetSimpleContacts( ContactSortedByType sortBy; var searchString = ApiContext.FilterValue; - if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) { contactsOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); } @@ -626,6 +630,7 @@ public PersonWrapper AddPeopleToCompany(int companyid, int personid) if (person == null || company == null || !CRMSecurity.CanAccessTo(person) || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); DaoFactory.GetContactDao().AddMember(personid, companyid); + MessageService.Send( MessageAction.CompanyLinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); return (PersonWrapper)ToContactWrapper(person); @@ -703,7 +708,7 @@ public PersonWrapper CreatePerson( }; peopleInst.ID = DaoFactory.GetContactDao().SaveContact(peopleInst); - peopleInst.CreateBy = Core.SecurityContext.CurrentAccount.ID; + peopleInst.CreateBy = SecurityContext.CurrentAccount.ID; peopleInst.CreateOn = DateTime.UtcNow; var managerListLocal = managerList != null ? managerList.ToList() : new List(); @@ -936,7 +941,7 @@ public CompanyWrapper CreateCompany( }; companyInst.ID = DaoFactory.GetContactDao().SaveContact(companyInst); - companyInst.CreateBy = Core.SecurityContext.CurrentAccount.ID; + companyInst.CreateBy = SecurityContext.CurrentAccount.ID; companyInst.CreateOn = DateTime.UtcNow; if (personList != null) @@ -1013,7 +1018,7 @@ public IEnumerable CreateCompany(IEnumerable company DaoFactory.GetContactDao().SaveContactList(contacts); - var selectedManagers = new List {Core.SecurityContext.CurrentAccount.ID}; + var selectedManagers = new List {SecurityContext.CurrentAccount.ID}; foreach (var ct in contacts) { @@ -1064,7 +1069,7 @@ public IEnumerable CreatePerson(IEnumerable {Core.SecurityContext.CurrentAccount.ID}; + var selectedManagers = new List {SecurityContext.CurrentAccount.ID}; foreach (var ct in contacts) { @@ -1315,7 +1320,7 @@ public IEnumerable GetContactAccessList(int contactid) return CRMSecurity.IsPrivate(contact) ? CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeWraper.Get(item.Key)) + .Select(item => EmployeeWraperHelper.Get(item.Key)) : new List(); } @@ -1356,11 +1361,12 @@ private void SetAccessToContact(Contact contact, bool isShared, IEnumerable n != ASC.Core.SecurityContext.CurrentAccount.ID).ToArray(); + var notifyUsers = managerListLocal.Where(n => n != SecurityContext.CurrentAccount.ID).ToArray(); + if (contact is Person) - ASC.Web.CRM.Services.NotifyService.NotifyClient.SendAboutSetAccess(EntityType.Person, contact.ID, DaoFactory, notifyUsers); + NotifyClient.SendAboutSetAccess(EntityType.Person, contact.ID, DaoFactory, notifyUsers); else - ASC.Web.CRM.Services.NotifyService.NotifyClient.SendAboutSetAccess(EntityType.Company, contact.ID, DaoFactory, notifyUsers); + NotifyClient.SendAboutSetAccess(EntityType.Company, contact.ID, DaoFactory, notifyUsers); } @@ -1548,7 +1554,8 @@ public IEnumerable GetContactsByPrefix(string prefi if (person != null) { var people = person; - if (Core.Users.UserFormatter.GetUserName(people.FirstName, people.LastName).IndexOf(prefix, StringComparison.Ordinal) != -1) + + if (AuthManager.UserFormatter.GetUserName(people.FirstName, people.LastName).IndexOf(prefix, StringComparison.Ordinal) != -1) { findedContacts.Add(person); } @@ -1749,12 +1756,14 @@ public List GetContactSMImages(int contactId) [Create(@"contact/socialmediaavatar")] public List GetContactSMImagesByNetworks(List socialNetworks) { - if (socialNetworks == null || socialNetworks.Count == 0){ + if (socialNetworks == null || socialNetworks.Count == 0) + { return new List(); } var twitter = new List(); - foreach (var sn in socialNetworks) { + foreach (var sn in socialNetworks) + { if (sn.InfoType == ContactInfoType.Twitter) twitter.Add(sn.Data); } @@ -1802,7 +1811,7 @@ public IProgressItem SendMailSMTPToContacts(List fileIDs, List contact if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()); - MessageService.Send( MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); + MessageService.Send(MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); return MailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); } @@ -1861,7 +1870,7 @@ public void SetContactLastModifedDate(int contactId, ApiDateTime lastModifedDate } - private static ContactPhotoManager.PhotoData UploadAvatar(int contactID, string imageUrl, bool uploadOnly, string tmpDirName, bool checkFormat = true) + private ContactPhotoManager.PhotoData UploadAvatar(int contactID, string imageUrl, bool uploadOnly, string tmpDirName, bool checkFormat = true) { if (contactID != 0) { @@ -1915,12 +1924,12 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly if (peopleCompanyIDs.Count > 0) { var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ToContactBaseWrapperQuick(item)); - var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.ID).ToArray()); + var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); foreach (var contactBaseWrapperQuick in tmpList) { contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.ID]; - peopleCompanyList.Add(contactBaseWrapperQuick.ID, contactBaseWrapperQuick); + peopleCompanyList.Add(contactBaseWrapperQuick.Id, contactBaseWrapperQuick); } } @@ -2003,9 +2012,9 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly TaskBaseWrapper taskWrapper = null; - if (nearestTasks.ContainsKey(contactWrapper.ID)) + if (nearestTasks.ContainsKey(contactWrapper.Id)) { - var task = nearestTasks[contactWrapper.ID]; + var task = nearestTasks[contactWrapper.Id]; taskWrapper = new TaskBaseWrapper(task); if (task.CategoryID > 0) @@ -2026,7 +2035,7 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly if (result.Count > 0) { - var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Contact.ID).ToArray()); + var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Contact.Id).ToArray()); foreach (var contactBaseWrapperQuick in result) { contactBaseWrapperQuick.Contact.CanDelete = contactBaseWrapperQuick.Contact.CanEdit && resultListCanDelete[contactBaseWrapperQuick.Contact.ID]; @@ -2083,11 +2092,11 @@ private IEnumerable ToListContactWrapper(IReadOnlyList if (peopleCompanyIDs.Count > 0) { var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ToContactBaseWrapperQuick(item)); - var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.ID).ToArray()); + var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); foreach (var contactBaseWrapperQuick in tmpList) { contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.ID]; - peopleCompanyList.Add(contactBaseWrapperQuick.ID, contactBaseWrapperQuick); + peopleCompanyList.Add(contactBaseWrapperQuick.Id, contactBaseWrapperQuick); } } @@ -2158,9 +2167,9 @@ private IEnumerable ToListContactWrapper(IReadOnlyList { contactWrapper = CompanyWrapper.ToCompanyWrapperQuick(company); - if (companiesMembersCount.ContainsKey(contactWrapper.ID)) + if (companiesMembersCount.ContainsKey(contactWrapper.Id)) { - ((CompanyWrapper)contactWrapper).PersonsCount = companiesMembersCount[contactWrapper.ID]; + ((CompanyWrapper)contactWrapper).PersonsCount = companiesMembersCount[contactWrapper.Id]; } } else @@ -2199,7 +2208,7 @@ private IEnumerable ToListContactWrapper(IReadOnlyList if (result.Count > 0) { - var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.ID).ToArray()); + var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Id).ToArray()); foreach (var contactBaseWrapperQuick in result) { contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && resultListCanDelete[contactBaseWrapperQuick.ID]; @@ -2210,124 +2219,5 @@ private IEnumerable ToListContactWrapper(IReadOnlyList return result; } - - - private static ContactBaseWrapper ToContactBaseWrapper(Contact contact) - { - return contact == null ? null : new ContactBaseWrapper(contact); - } - - private static ContactBaseWrapper ToContactBaseWrapperQuick(Contact contact) - { - return contact == null ? null : ContactBaseWrapper.ToContactBaseWrapperQuick(contact); - } - - private ContactWrapper ToContactWrapper(Contact contact) - { - ContactWrapper result; - - var person = contact as Person; - if (person != null) - { - var peopleWrapper = new PersonWrapper(person); - if (person.CompanyID > 0) - { - peopleWrapper.Company = ToContactBaseWrapper(DaoFactory.GetContactDao().GetByID(person.CompanyID)); - } - - result = peopleWrapper; - } - else - { - var company = contact as Company; - if (company != null) - { - result = new CompanyWrapper(company); - ((CompanyWrapper)result).PersonsCount = DaoFactory.GetContactDao().GetMembersCount(result.ID); - } - else throw new ArgumentException(); - } - - if (contact.StatusID > 0) - { - var listItem = DaoFactory.GetListItemDao().GetByID(contact.StatusID); - if (listItem == null) throw new ItemNotFoundException(); - - result.ContactStatus = new ContactStatusBaseWrapper(listItem); - } - - result.TaskCount = DaoFactory.GetTaskDao().GetTasksCount(contact.ID); - result.HaveLateTasks = DaoFactory.GetTaskDao().HaveLateTask(contact.ID); - - var contactInfos = new List(); - var addresses = new List
    (); - - var data = DaoFactory.GetContactInfoDao().GetList(contact.ID, null, null, null); - - foreach (var contactInfo in data) - { - if (contactInfo.InfoType == ContactInfoType.Address) - { - addresses.Add(new Address(contactInfo)); - } - else - { - contactInfos.Add(new ContactInfoWrapper(contactInfo)); - } - } - - result.Addresses = addresses; - result.CommonData = contactInfos; - - if (contact is Person) - { - result.CustomFields = DaoFactory.GetCustomFieldDao() - .GetEnityFields(EntityType.Person, contact.ID, false) - .ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); - } - else - { - result.CustomFields = DaoFactory.GetCustomFieldDao() - .GetEnityFields(EntityType.Company, contact.ID, false) - .ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); - } - - return result; - } - - private ContactBaseWithEmailWrapper ToContactBaseWithEmailWrapper(Contact contact) - { - if (contact == null) return null; - - var result = new ContactBaseWithEmailWrapper(contact); - var primaryEmail = DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Email, null, true); - if (primaryEmail == null || primaryEmail.Count == 0) - { - result.Email = null; - } - else - { - result.Email = new ContactInfoWrapper(primaryEmail.FirstOrDefault()); - } - return result; - } - - private ContactBaseWithPhoneWrapper ToContactBaseWithPhoneWrapper(Contact contact) - { - if (contact == null) return null; - - var result = new ContactBaseWithPhoneWrapper(contact); - var primaryPhone = DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Phone, null, true); - if (primaryPhone == null || primaryPhone.Count == 0) - { - result.Phone = null; - } - else - { - result.Phone = new ContactInfoWrapper(primaryPhone.FirstOrDefault()); - } - return result; - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs b/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs index 7c6e4172f34..b714b38c53b 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs @@ -24,6 +24,7 @@ */ +using ASC.Core.Common.Settings; using ASC.CRM.Core; using ASC.CRM.Resources; using ASC.MessagingSystem; @@ -51,7 +52,7 @@ public partial class CRMController [Read(@"currency/rates")] public IEnumerable GetCurrencyRates() { - return DaoFactory.GetCurrencyRateDao().GetAll().ConvertAll(ToCurrencyRateWrapper); + return DaoFactory.GetCurrencyRateDao().GetAll().ConvertAll(x => CurrencyRateWrapperHelper.Get(x)); } /// @@ -70,7 +71,7 @@ public CurrencyRateWrapper GetCurrencyRate(int id) var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); - return ToCurrencyRateWrapper(currencyRate); + return CurrencyRateWrapperHelper.Get(currencyRate); } /// @@ -90,7 +91,7 @@ public CurrencyRateWrapper GetCurrencyRate(string fromCurrency, string toCurrenc var currencyRate = DaoFactory.GetCurrencyRateDao().GetByCurrencies(fromCurrency, toCurrency); - return ToCurrencyRateWrapper(currencyRate); + return CurrencyRateWrapperHelper.Get(currencyRate); } /// @@ -116,7 +117,7 @@ public CurrencyRateWrapper CreateCurrencyRate(string fromCurrency, string toCurr currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); - return ToCurrencyRateWrapper(currencyRate); + return CurrencyRateWrapperHelper.Get(currencyRate); } /// @@ -147,7 +148,7 @@ public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, strin currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); - return ToCurrencyRateWrapper(currencyRate); + return CurrencyRateWrapperHelper.Get(currencyRate); } /// @@ -168,8 +169,8 @@ public List SetCurrencyRates(String currency, List().DefaultCurrency.Abbreviation != currency) { var cur = CurrencyProvider.Get(currency); @@ -188,7 +189,7 @@ public List SetCurrencyRates(String currency, List CurrencyRateWrapperHelper.Get(x)).ToList(); } /// @@ -230,7 +231,7 @@ public List AddCurrencyRates(List rates) existingRates.Add(rate); } - return existingRates.Select(ToCurrencyRateWrapper).ToList(); + return existingRates.Select(x => CurrencyRateWrapperHelper.Get(x)).ToList(); } /// @@ -252,10 +253,10 @@ public CurrencyRateWrapper DeleteCurrencyRate(int id) DaoFactory.GetCurrencyRateDao().Delete(id); - return ToCurrencyRateWrapper(currencyRate); + return CurrencyRateWrapperHelper.Get(currencyRate); } - private static void ValidateCurrencyRates(IEnumerable rates) + private void ValidateCurrencyRates(IEnumerable rates) { var currencies = new List(); @@ -269,7 +270,7 @@ private static void ValidateCurrencyRates(IEnumerable rates) ValidateCurrencies(currencies.ToArray()); } - private static void ValidateCurrencies(string[] currencies) + private void ValidateCurrencies(string[] currencies) { if (currencies.Any(string.IsNullOrEmpty)) throw new ArgumentException(); @@ -288,10 +289,6 @@ private static void ValidateRate(decimal rate) if (rate < 0 || rate > MaxRateValue) throw new ArgumentException(string.Format(CRMErrorsResource.InvalidCurrencyRate, rate)); } - - private static CurrencyRateWrapper ToCurrencyRateWrapper(CurrencyRate currencyRate) - { - return new CurrencyRateWrapper(currencyRate); - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs index 635cce3db46..2519846f5b3 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs @@ -55,7 +55,7 @@ public partial class CRMController [Read(@"{entityType:(contact|person|company|opportunity|case)}/customfield/definitions")] public IEnumerable GetCustomFieldDefinitions(string entityType) { - return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldWrapper).ToSmartList(); + return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldWrapper); } /// @@ -69,7 +69,7 @@ public IEnumerable GetCustomFieldDefinitions(string entityTy [Read(@"{entityType:(contact|person|company|opportunity|case)}/{entityid:int}/customfield")] public IEnumerable GetCustomFieldForSubject(string entityType, int entityid) { - return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseWrapper).ToItemList(); + return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseWrapper); } /// @@ -281,7 +281,7 @@ public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) var result = ToCustomFieldWrapper(customField); DaoFactory.GetCustomFieldDao().DeleteField(fieldid); - FactoryIndexer.DeleteAsync(customField); + FactoryIndexerFieldsWrapper.DeleteAsync(Web.CRM.Core.Search.FieldsWrapper.GetEventsWrapper(ServiceProvider, customField)); var messageAction = GetCustomFieldDeletedAction(ToEntityType(entityType)); MessageService.Send( messageAction, MessageTarget.Create(customField.ID), result.Label); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs index e1d5b0b8e2b..83ff577ea4d 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs @@ -41,6 +41,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.CRM.Classes; namespace ASC.Api.CRM { @@ -65,7 +66,7 @@ public OpportunityWrapper GetDealByID(int opportunityid) var deal = DaoFactory.GetDealDao().GetByID(opportunityid); if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); - return ToOpportunityWrapper(deal); + return OpportunityWrapperHelper.Get(deal); } /// @@ -98,7 +99,7 @@ public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) DaoFactory.GetDealDao().EditDeal(deal); MessageService.Send( MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); - return ToOpportunityWrapper(deal); + return OpportunityWrapperHelper.Get(deal); } /// @@ -118,7 +119,7 @@ public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) { if (opportunityid <= 0) throw new ArgumentException(); - + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); if (deal == null) throw new ItemNotFoundException(); @@ -148,7 +149,7 @@ private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerabl if (isMessageServicSende) { var users = GetUsersByIdList(accessListLocal); - MessageService.Send( MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false))); + MessageService.Send( MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); } } else @@ -160,7 +161,7 @@ private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerabl } } - return ToOpportunityWrapper(deal); + return OpportunityWrapperHelper.Get(deal); } /// @@ -363,7 +364,7 @@ public IEnumerable GetDeals( OrderBy dealsOrderBy; - if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) { dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending); } @@ -424,7 +425,7 @@ public IEnumerable GetDeals( else { totalCount = DaoFactory - .DealDao + .GetDealDao() .GetDealsCount(searchString, responsibleid, opportunityStagesid, @@ -438,7 +439,7 @@ public IEnumerable GetDeals( ApiContext.SetTotalCount(totalCount); - return result.ToSmartList(); + return result; } /// @@ -462,7 +463,7 @@ public OpportunityWrapper DeleteDeal(int opportunityid) MessageService.Send( MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); - return ToOpportunityWrapper(deal); + return OpportunityWrapperHelper.Get(deal); } /// @@ -558,7 +559,7 @@ public OpportunityWrapper CreateDeal( } } - return ToOpportunityWrapper(deal); + return OpportunityWrapperHelper.Get(deal); } /// @@ -656,7 +657,7 @@ public OpportunityWrapper UpdateDeal( } } - return ToOpportunityWrapper(deal); + return OpportunityWrapperHelper.Get(deal); } /// @@ -680,7 +681,7 @@ public IEnumerable GetDealMembers(int opportunityid) var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); - result.ForEach(item => { if (item.ID == opportunity.ContactID) item.CanEdit = false; }); + result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); return result; } @@ -773,7 +774,7 @@ public IEnumerable GetDealsByPrefix(string prefix, int conta { if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) { - result.Add(ToOpportunityWrapper(item)); + result.Add(OpportunityWrapperHelper.Get(item)); } } @@ -785,7 +786,7 @@ public IEnumerable GetDealsByPrefix(string prefix, int conta var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); foreach (var item in findedDeals) { - result.Add(ToOpportunityWrapper(item)); + result.Add(OpportunityWrapperHelper.Get(item)); } } @@ -884,7 +885,7 @@ private IEnumerable ToListOpportunityWrapper(ICollection ToListOpportunityWrapper(ICollection(); - dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.ID) - ? dealMembers[dealWrapper.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) + dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.Id) + ? dealMembers[dealWrapper.Id].Where(contacts.ContainsKey).Select(item => contacts[item]) : new List(); if (dealMilestones.ContainsKey(deal.DealMilestoneID)) @@ -908,7 +909,7 @@ private IEnumerable ToListOpportunityWrapper(ICollection EmployeeWraper.Get(item.Key)).ToItemList(); + dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); } if (!string.IsNullOrEmpty(deal.BidCurrency)) @@ -920,50 +921,6 @@ private IEnumerable ToListOpportunityWrapper(ICollection 0) - dealWrapper.Contact = ToContactBaseWrapper(DaoFactory.GetContactDao().GetByID(deal.ContactID)); - - if (deal.DealMilestoneID > 0) - { - var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); - - if (dealMilestone == null) - throw new ItemNotFoundException(); - - dealWrapper.Stage = new DealMilestoneBaseWrapper(dealMilestone); - } - - dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal) - .Select(item => EmployeeWraper.Get(item.Key)).ToItemList(); - - dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); - - if (!string.IsNullOrEmpty(deal.BidCurrency)) - dealWrapper.BidCurrency = ToCurrencyInfoWrapper(CurrencyProvider.Get(deal.BidCurrency)); - - dealWrapper.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); - - dealWrapper.Members = new List(); - - var memberIDs = DaoFactory.GetDealDao().GetMembers(deal.ID); - var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); - var membersWrapperList = new List(); - - foreach (var member in membersList) - { - if (member == null) continue; - membersWrapperList.Add(ToContactBaseWrapper(member)); - } - - dealWrapper.Members = membersWrapperList; - - return dealWrapper; - } + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs index 1a39a4feb12..b9d65cd5535 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs @@ -26,8 +26,10 @@ using ASC.Api.Core; using ASC.Api.CRM.Wrappers; +using ASC.Api.Documents; using ASC.Common.Web; using ASC.Core; +using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -62,7 +64,7 @@ public InvoiceWrapper GetInvoiceByID(int invoiceid) throw CRMSecurity.CreateSecurityException(); } - return ToInvoiceWrapper(invoice); + return InvoiceWrapperHelper.Get(invoice); } /// @@ -78,11 +80,11 @@ public InvoiceWrapper GetInvoiceSample() sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; - sample.IssueDate = (ApiDateTime)DateTime.UtcNow; - sample.DueDate = (ApiDateTime)DateTime.UtcNow.AddDays(30); - sample.CreateOn = (ApiDateTime)DateTime.UtcNow; + sample.IssueDate = ApiDateTimeHelper.Get(DateTime.UtcNow); + sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); + sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow); - sample.Currency = new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); + sample.Currency = CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency); sample.InvoiceLines.First().Quantity = 1; @@ -216,7 +218,7 @@ String currency ApiContext.SetTotalCount(totalCount); - return result.ToSmartList(); + return result; } /// @@ -342,7 +344,7 @@ InvoiceStatus status var listInvoiceBaseWrappers = ToListInvoiceBaseWrappers(updatedInvoices); - return new KeyValuePair,IEnumerable>(listInvoiceBaseWrappers,invoiceItemsUpdated.ConvertAll(i => ToInvoiceItemWrapper(i))); + return new KeyValuePair,IEnumerable>(listInvoiceBaseWrappers,invoiceItemsUpdated.ConvertAll(i => InvoiceItemWrapperHelper.Get(i))); } /// @@ -361,7 +363,9 @@ public InvoiceBaseWrapper DeleteInvoice(int invoiceid) if (invoice == null) throw new ItemNotFoundException(); MessageService.Send( MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); - return ToInvoiceBaseWrapper(invoice); + + return InvoiceBaseWrapperHelper.Get(invoice); + } /// @@ -499,7 +503,8 @@ IEnumerable invoiceLines CreateInvoiceLines(invoiceLinesList, invoice); DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - return ToInvoiceWrapper(invoice); + + return InvoiceWrapperHelper.Get(invoice); } @@ -669,10 +674,10 @@ public InvoiceWrapper UpdateInvoice( if (Global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); } - return ToInvoiceWrapper(invoice); + return InvoiceWrapperHelper.Get(invoice); } /// @@ -683,7 +688,7 @@ public InvoiceWrapper UpdateInvoice( /// Invoices /// File [Read(@"invoice/{invoiceid:int}/pdf")] - public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) + public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) { if (invoiceid <= 0) throw new ArgumentException(); @@ -766,7 +771,9 @@ public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, s public Boolean GetInvoiceByNumberExistence(string number) { if (String.IsNullOrEmpty(number)) throw new ArgumentException(); + return DaoFactory.GetInvoiceDao().IsExist(number); + } /// @@ -783,11 +790,12 @@ public InvoiceWrapper GetInvoiceByNumber(string number) var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number); if (invoice == null) throw new ItemNotFoundException(); + if (!CRMSecurity.CanAccessTo(invoice)) { throw CRMSecurity.CreateSecurityException(); } - return new InvoiceWrapper(invoice); + return InvoiceWrapperHelper.Get(invoice); } /// @@ -833,7 +841,7 @@ public IEnumerable GetInvoiceItems(int status, bool? invento inventoryStock, fromIndex, count, invoiceOrderBy) - .ConvertAll(ToInvoiceItemWrapper); + .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); ApiContext.SetDataPaginated(); ApiContext.SetDataFiltered(); @@ -847,7 +855,7 @@ public IEnumerable GetInvoiceItems(int status, bool? invento inventoryStock, 0, 0, null) - .ConvertAll(ToInvoiceItemWrapper); + .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); } int totalCount; @@ -866,7 +874,7 @@ public IEnumerable GetInvoiceItems(int status, bool? invento ApiContext.SetTotalCount(totalCount); - return result.ToSmartList(); + return result; } /// @@ -884,7 +892,7 @@ public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); if (invoiceItem == null) throw new ItemNotFoundException(); - return ToInvoiceItemWrapper(invoiceItem); + return InvoiceItemWrapperHelper.Get(invoiceItem); } /// @@ -930,7 +938,9 @@ int discount if (invoiceId <= 0) throw new ArgumentException(); + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); @@ -938,10 +948,10 @@ int discount DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); if (Global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); } - return ToInvoiceLineWrapper(invoiceLine); + return InvoiceLineWrapperHelper.Get(invoiceLine); } /// @@ -997,12 +1007,13 @@ int discount DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + if (Global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); } - return ToInvoiceLineWrapper(invoiceLine); + return InvoiceLineWrapperHelper.Get(invoiceLine); } /// @@ -1026,38 +1037,15 @@ public int DeleteInvoiceLine(int id) DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + if (Global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(HttpContext.Current, TenantProvider.CurrentTenantID, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); } return id; } - private InvoiceBaseWrapper ToInvoiceBaseWrapper(Invoice invoice) - { - var result = new InvoiceBaseWrapper(invoice); - - if (invoice.ContactID > 0) - { - result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); - } - - if (invoice.ConsigneeID > 0) - { - result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); - } - - if (invoice.EntityID > 0) - { - result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); - } - - result.Cost = invoice.GetInvoiceCost(DaoFactory); - - return result; - } - /// /// Creates the invoice item with the parameters (title, description, price, etc.) specified in the request /// @@ -1097,7 +1085,6 @@ public InvoiceItemWrapper CreateInvoiceItem( Description = description, Price = price, StockKeepingUnit = sku, - Quantity = quantity, StockQuantity = stockQuantity, TrackInventory = trackInventory, InvoiceTax1ID = invoiceTax1id, @@ -1105,9 +1092,10 @@ public InvoiceItemWrapper CreateInvoiceItem( }; invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + MessageService.Send( MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return ToInvoiceItemWrapper(invoiceItem); + return InvoiceItemWrapperHelper.Get(invoiceItem); } /// @@ -1153,7 +1141,6 @@ public InvoiceItemWrapper UpdateInvoiceItem(int id, Description = description, Price = price, StockKeepingUnit = sku, - Quantity = quantity, StockQuantity = stockQuantity, TrackInventory = trackInventory, InvoiceTax1ID = invoiceTax1id, @@ -1163,7 +1150,7 @@ public InvoiceItemWrapper UpdateInvoiceItem(int id, invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); MessageService.Send( MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return ToInvoiceItemWrapper(invoiceItem); + return InvoiceItemWrapperHelper.Get(invoiceItem); } /// @@ -1186,7 +1173,9 @@ public InvoiceItemWrapper DeleteInvoiceItem(int id) if (invoiceItem == null) throw new ItemNotFoundException(); MessageService.Send( MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return ToInvoiceItemWrapper(invoiceItem); + + return InvoiceItemWrapperHelper.Get(invoiceItem); + } /// @@ -1208,8 +1197,8 @@ public IEnumerable DeleteBatchItems(IEnumerable ids) var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); MessageService.Send( MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); - - return items.ConvertAll(ToInvoiceItemWrapper); + + return items.ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); } /// @@ -1221,7 +1210,7 @@ public IEnumerable DeleteBatchItems(IEnumerable ids) [Read(@"invoice/tax")] public IEnumerable GetInvoiceTaxes() { - return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(ToInvoiceTaxWrapper); + return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxWrapperHelper.Get(x)); } /// @@ -1256,7 +1245,7 @@ public InvoiceTaxWrapper CreateInvoiceTax( invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); MessageService.Send( MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return ToInvoiceTaxWrapper(invoiceTax); + return InvoiceTaxWrapperHelper.Get(invoiceTax); } /// @@ -1295,7 +1284,7 @@ public InvoiceTaxWrapper UpdateInvoiceTax( invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); MessageService.Send( MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return ToInvoiceTaxWrapper(invoiceTax); + return InvoiceTaxWrapperHelper.Get(invoiceTax); } /// @@ -1318,7 +1307,8 @@ public InvoiceTaxWrapper DeleteInvoiceTax(int id) if (invoiceTax == null) throw new ItemNotFoundException(); MessageService.Send( MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return ToInvoiceTaxWrapper(invoiceTax); + + return InvoiceTaxWrapperHelper.Get(invoiceTax); } /// @@ -1412,59 +1402,7 @@ public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); } - - private InvoiceWrapper ToInvoiceWrapper(Invoice invoice) - { - var result = new InvoiceWrapper(invoice); - - if (invoice.ContactID > 0) - { - result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); - } - - if (invoice.ConsigneeID > 0) - { - result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); - } - - if (invoice.EntityID > 0) - { - result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); - } - - result.Cost = invoice.GetInvoiceCost(DaoFactory); - - result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(ToInvoiceLineWrapper).ToList(); - - return result; - } - - private InvoiceItemWrapper ToInvoiceItemWrapper(InvoiceItem invoiceItem) - { - var result = new InvoiceItemWrapper(invoiceItem); - - if (invoiceItem.InvoiceTax1ID > 0) - { - result.InvoiceTax1 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); - } - if (invoiceItem.InvoiceTax2ID > 0) - { - result.InvoiceTax2 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); - } - - return result; - } - - private InvoiceTaxWrapper ToInvoiceTaxWrapper(InvoiceTax invoiceTax) - { - return new InvoiceTaxWrapper(invoiceTax); - } - - private InvoiceLineWrapper ToInvoiceLineWrapper(InvoiceLine invoiceLine) - { - return new InvoiceLineWrapper(invoiceLine); - } - + private IEnumerable ToListInvoiceBaseWrappers(ICollection items) { if (items == null || items.Count == 0) return new List(); @@ -1481,7 +1419,7 @@ private IEnumerable ToListInvoiceBaseWrappers(ICollection GetHistoryCategoryWrapper() result.ForEach(x => { - if (relativeItemsCount.ContainsKey(x.ID)) - x.RelativeItemsCount = relativeItemsCount[x.ID]; + if (relativeItemsCount.ContainsKey(x.Id)) + x.RelativeItemsCount = relativeItemsCount[x.Id]; }); return result; } @@ -971,8 +971,8 @@ public IEnumerable GetTaskCategories() result.ForEach(x => { - if (relativeItemsCount.ContainsKey(x.ID)) - x.RelativeItemsCount = relativeItemsCount[x.ID]; + if (relativeItemsCount.ContainsKey(x.Id)) + x.RelativeItemsCount = relativeItemsCount[x.Id]; }); return result; } @@ -994,8 +994,8 @@ public IEnumerable GetContactStatuses() result.ForEach(x => { - if (relativeItemsCount.ContainsKey(x.ID)) - x.RelativeItemsCount = relativeItemsCount[x.ID]; + if (relativeItemsCount.ContainsKey(x.Id)) + x.RelativeItemsCount = relativeItemsCount[x.Id]; }); return result; } @@ -1017,8 +1017,8 @@ public IEnumerable GetContactTypes() result.ForEach(x => { - if (relativeItemsCount.ContainsKey(x.ID)) - x.RelativeItemsCount = relativeItemsCount[x.ID]; + if (relativeItemsCount.ContainsKey(x.Id)) + x.RelativeItemsCount = relativeItemsCount[x.Id]; }); return result; @@ -1041,8 +1041,8 @@ public IEnumerable GetDealMilestones() result.ForEach(x => { - if (relativeItemsCount.ContainsKey(x.ID)) - x.RelativeItemsCount = relativeItemsCount[x.ID]; + if (relativeItemsCount.ContainsKey(x.Id)) + x.RelativeItemsCount = relativeItemsCount[x.Id]; }); return result; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs index 9fc89c5010f..6879fe1bef2 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs @@ -24,7 +24,9 @@ */ +using ASC.Api.Core; using ASC.Api.CRM.Wrappers; +using ASC.Api.Documents; using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Entities; @@ -105,7 +107,7 @@ public IEnumerable GetHistory( OrderBy eventOrderBy; - if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out eventByType)) + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out eventByType)) { eventOrderBy = new OrderBy(eventByType, !ApiContext.SortDescending); } @@ -151,7 +153,7 @@ public IEnumerable GetHistory( null)); } - return result.ToSmartList(); + return result; } /// @@ -174,7 +176,7 @@ public RelationshipEventWrapper DeleteHistory(int id) var item = DaoFactory.GetRelationshipEventDao().GetByID(id); if (item == null) throw new ItemNotFoundException(); - var wrapper = ToRelationshipEventWrapper(item); + var wrapper = RelationshipEventWrapperHelper.Get(item); DaoFactory.GetRelationshipEventDao().DeleteItem(id); @@ -198,14 +200,14 @@ public RelationshipEventWrapper DeleteHistory(int id) /// File info /// [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/text")] - public FileWrapper CreateTextFile(string entityType, int entityid, string title, string content) + public FileWrapper CreateTextFile(string entityType, int entityid, string title, string content) { if (title == null) throw new ArgumentNullException("title"); if (content == null) throw new ArgumentNullException("content"); var folderid = GetRootFolderID(); - FileWrapper result; + FileWrapper result; var extension = ".txt"; if (!string.IsNullOrEmpty(content)) @@ -227,69 +229,70 @@ public FileWrapper CreateTextFile(string entityType, int entityid, string title, return result; } - /// - /// Upload file - /// - /// Upload file - /// Files - /// - /// - ///
  • Single file upload. You should set Content-Type & Content-Disposition header to specify filename and content type, and send file in request body
  • - ///
  • Using standart multipart/form-data method
  • - /// ]]> - ///
    - /// Entity type - /// Entity ID - /// Request Input stream - /// Content-Type Header - /// Content-Disposition Header - /// List of files when posted as multipart/form-data - /// If True, upload documents in original formats as well - /// - /// File info - /// - [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/upload")] - public FileWrapper UploadFileInCRM( - string entityType, - int entityid, - Stream file, - ContentType contentType, - ContentDisposition contentDisposition, - IEnumerable files, - bool storeOriginalFileFlag - ) + ///// + ///// Upload file + ///// + ///// Upload file + ///// Files + ///// + ///// + /////
  • Single file upload. You should set Content-Type & Content-Disposition header to specify filename and content type, and send file in request body
  • + /////
  • Using standart multipart/form-data method
  • + ///// ]]> + /////
    + ///// Entity type + ///// Entity ID + ///// Request Input stream + ///// Content-Type Header + ///// Content-Disposition Header + ///// List of files when posted as multipart/form-data + ///// If True, upload documents in original formats as well + ///// + ///// File info + ///// + //[Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/upload")] + //public FileWrapper UploadFileInCRM( + // string entityType, + // int entityid, + // Stream file, + // ContentType contentType, + // ContentDisposition contentDisposition, + // IEnumerable files, + // bool storeOriginalFileFlag + // ) + //{ + // FilesSettings.StoreOriginalFilesSetting = storeOriginalFileFlag; + + // var folderid = GetRootFolderID(); + + // var fileNames = new List(); + + // FileWrapper uploadedFile = null; + // if (files != null && files.Any()) + // { + // //For case with multiple files + // foreach (var postedFile in files) + // { + // uploadedFile = SaveFile(folderid, postedFile.InputStream, postedFile.FileName); + // fileNames.Add(uploadedFile.Title); + // } + // } + // else if (file != null) + // { + // uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); + // fileNames.Add(uploadedFile.Title); + // } + + // return uploadedFile; + //} + + private FileWrapper SaveFile(int folderid, Stream file, string fileName) { - FilesSettings.StoreOriginalFiles = storeOriginalFileFlag; - - var folderid = GetRootFolderID(); - - var fileNames = new List(); - - FileWrapper uploadedFile = null; - if (files != null && files.Any()) - { - //For case with multiple files - foreach (var postedFile in files) - { - uploadedFile = SaveFile(folderid, postedFile.InputStream, postedFile.FileName); - fileNames.Add(uploadedFile.Title); - } - } - else if (file != null) - { - uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); - fileNames.Add(uploadedFile.Title); - } + var resultFile = FileUploader.Exec(folderid, fileName, file.Length, file); - return uploadedFile; - } - - private static FileWrapper SaveFile(object folderid, Stream file, string fileName) - { - var resultFile = FileUploader.Exec(folderid.ToString(), fileName, file.Length, file); - return new FileWrapper(resultFile); + return FileWrapperHelper.Get(resultFile); } /// @@ -371,7 +374,7 @@ public RelationshipEventWrapper AddHistoryTo( Content = content, ContactID = contactId, CreateOn = created, - CreateBy = Core.SecurityContext.CurrentAccount.ID + CreateBy = SecurityContext.CurrentAccount.ID }; var category = DaoFactory.GetListItemDao().GetByID(categoryId); @@ -388,7 +391,7 @@ public RelationshipEventWrapper AddHistoryTo( if (fileId != null) { var fileIds = fileId.ToList(); - var files = FilesDaoFactory.GetFileDao().GetFiles(fileIds.Cast().ToArray()); + var files = FilesDaoFactory.GetFileDao().GetFiles(fileIds.ToArray()); if (needNotify) { @@ -424,7 +427,7 @@ public RelationshipEventWrapper AddHistoryTo( NotifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, DaoFactory, notifyUserList.ToArray()); } - var wrapper = ToRelationshipEventWrapper(item); + var wrapper = RelationshipEventWrapperHelper.Get(item); var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); MessageService.Send( historyCreatedAction, MessageTarget.Create(item.ID), entityTitle, category.Title); @@ -448,7 +451,7 @@ public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEn { if (entityid <= 0 || fileids == null) throw new ArgumentException(); - var files = FilesDaoFactory.GetFileDao().GetFiles(fileids.Cast().ToArray()); + var files = FilesDaoFactory.GetFileDao().GetFiles(fileids.ToArray()); var folderid = GetRootFolderID(); @@ -467,15 +470,15 @@ public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEn var relationshipEvent1 = DaoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray()); var messageAction = entityObj is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return ToRelationshipEventWrapper(relationshipEvent1); + return RelationshipEventWrapperHelper.Get(relationshipEvent1); case EntityType.Opportunity: var relationshipEvent2 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); MessageService.Send( MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return ToRelationshipEventWrapper(relationshipEvent2); + return RelationshipEventWrapperHelper.Get(relationshipEvent2); case EntityType.Case: var relationshipEvent3 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); MessageService.Send( MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return ToRelationshipEventWrapper(relationshipEvent3); + return RelationshipEventWrapperHelper.Get(relationshipEvent3); default: throw new ArgumentException(); } @@ -490,7 +493,7 @@ public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEn /// Root folder ID /// [Read(@"files/root")] - public object GetRootFolderID() + public int GetRootFolderID() { return DaoFactory.GetFileDao().GetRoot(); } @@ -506,7 +509,7 @@ public object GetRootFolderID() /// File list /// [Read(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files")] - public IEnumerable GetFiles(string entityType, int entityid) + public IEnumerable> GetFiles(string entityType, int entityid) { if (entityid <= 0) throw new ArgumentException(); @@ -515,10 +518,10 @@ public IEnumerable GetFiles(string entityType, int entityid) switch (entityTypeObj) { case EntityType.Contact: - return DaoFactory.GetRelationshipEventDao().GetAllFiles(new[] {entityid}, EntityType.Any, 0).ConvertAll(file => new FileWrapper(file)); + return DaoFactory.GetRelationshipEventDao().GetAllFiles(new[] {entityid}, EntityType.Any, 0).ConvertAll(file => FileWrapperHelper.Get(file)); case EntityType.Opportunity: case EntityType.Case: - return DaoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => new FileWrapper(file)); + return DaoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => FileWrapperHelper.Get(file)); default: throw new ArgumentException(); } @@ -536,13 +539,13 @@ public IEnumerable GetFiles(string entityType, int entityid) /// File Info /// [Delete(@"files/{fileid:int}")] - public FileWrapper DeleteCRMFile(int fileid) + public FileWrapper DeleteCRMFile(int fileid) { if (fileid < 0) throw new ArgumentException(); - var file = FilesDaoFactory.GetFileDao().GetFile(fileid); + var file = FilesDaoFactory.GetFileDao().GetFile(fileid); if (file == null) throw new ItemNotFoundException(); - var result = new FileWrapper(file); + var result = FileWrapperHelper.Get(file); var _eventsDao = DaoFactory.GetRelationshipEventDao(); var eventIDs = _eventsDao.RemoveFile(file); @@ -656,7 +659,7 @@ private IEnumerable ToListRelationshipEventWrapper(Lis foreach (var item in itemList) { - var eventObjWrap = new RelationshipEventWrapper(item); + var eventObjWrap = RelationshipEventWrapperHelper.Get(item); if (contacts.ContainsKey(item.ContactID)) { @@ -673,7 +676,8 @@ private IEnumerable ToListRelationshipEventWrapper(Lis } } - eventObjWrap.Files = files.ContainsKey(item.ID) ? files[item.ID].ConvertAll(file => new FileWrapper(file)) : new List(); + eventObjWrap.Files = files.ContainsKey(item.ID) ? files[item.ID].ConvertAll(file => + FileWrapperHelper.Get(file)) : new List>(); if (categories.ContainsKey(item.CategoryID)) { @@ -686,38 +690,6 @@ private IEnumerable ToListRelationshipEventWrapper(Lis return result; } - private RelationshipEventWrapper ToRelationshipEventWrapper(RelationshipEvent relationshipEvent) - { - var result = new RelationshipEventWrapper(relationshipEvent); - - var historyCategory = DaoFactory.GetListItemDao().GetByID(relationshipEvent.CategoryID); - - if (historyCategory != null) - { - result.Category = new HistoryCategoryBaseWrapper(historyCategory); - } - - if (relationshipEvent.EntityID > 0) - { - result.Entity = ToEntityWrapper(relationshipEvent.EntityType, relationshipEvent.EntityID); - } - - result.Files = DaoFactory.GetRelationshipEventDao().GetFiles(relationshipEvent.ID).ConvertAll(file => new FileWrapper(file)); - - if (relationshipEvent.ContactID > 0) - { - var relativeContact = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); - if (relativeContact != null) - { - result.Contact = ToContactBaseWrapper(relativeContact); - } - } - - result.CanEdit = CRMSecurity.CanAccessTo(relationshipEvent); - - return result; - } - private EntityWrapper ToEntityWrapper(EntityType entityType, int entityID) { if (entityID == 0) return null; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs b/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs index d33f7a1f60a..2bb480f2fa8 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs @@ -24,7 +24,10 @@ */ +using ASC.Api.Documents; +using ASC.Common.Web; using ASC.CRM.Core; +using ASC.CRM.Core.Enums; using ASC.Web.Api.Routing; using ASC.Web.CRM.Classes; using ASC.Web.Files.Services.DocumentService; @@ -43,28 +46,30 @@ public partial class CRMController /// Report files /// if user can't create reports [Read(@"report/files")] - public IEnumerable GetFiles() + public IEnumerable> GetFiles() { if (!Global.CanCreateReports) throw CRMSecurity.CreateSecurityException(); - var reportDao = DaoFactory.ReportDao; + var reportDao = DaoFactory.GetReportDao(); var files = reportDao.GetFiles(); if (!files.Any()) { - var sampleSettings = CRMReportSampleSettings.LoadForCurrentUser(); + var settings = SettingsManager.Load(); - if (sampleSettings.NeedToGenerate) + if (settings.NeedToGenerate) { files = reportDao.SaveSampleReportFiles(); - sampleSettings.NeedToGenerate = false; - sampleSettings.SaveForCurrentUser(); + + settings.NeedToGenerate = false; + + SettingsManager.Save(settings); } } - return files.ConvertAll(file => new FileWrapper(file)).OrderByDescending(file => file.Id); + return files.ConvertAll(file => FileWrapperHelper.Get(file)).OrderByDescending(file => file.Id); } /// Delete the report file with the ID specified in the request @@ -82,11 +87,11 @@ public void DeleteFile(int fileid) if (fileid < 0) throw new ArgumentException(); - var file = DaoFactory.ReportDao.GetFile(fileid); + var file = DaoFactory.GetReportDao().GetFile(fileid); if (file == null) throw new ItemNotFoundException("File not found"); - DaoFactory.ReportDao.DeleteFile(fileid); + DaoFactory.GetReportDao().DeleteFile(fileid); } /// Get the state of the report generation task @@ -100,7 +105,8 @@ public ReportState GetStatus() if (!Global.CanCreateReports) throw CRMSecurity.CreateSecurityException(); - return DocbuilderReportsUtility.Status(ReportOrigin.CRM); + return DocbuilderReportsUtility.Status(ReportOrigin.CRM, HttpContextAccessor, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); + } /// Terminate the report generation task @@ -113,7 +119,7 @@ public void Terminate() if (!Global.CanCreateReports) throw CRMSecurity.CreateSecurityException(); - DocbuilderReportsUtility.Terminate(ReportOrigin.CRM); + DocbuilderReportsUtility.Terminate(ReportOrigin.CRM, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); } /// Check data availability for a report diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs b/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs index 3aafdd10495..28ba0813fb2 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs @@ -26,9 +26,11 @@ using ASC.Api.Core; using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; using System; @@ -97,7 +99,7 @@ public IEnumerable GetContactTags(int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return DaoFactory.GetTagDao().GetEntityTags(EntityType.Contact, contactid).ToItemList(); + return DaoFactory.GetTagDao().GetEntityTags(EntityType.Contact, contactid); } /// @@ -205,7 +207,7 @@ public string AddTagToBatchContacts( string tagName) { var contacts = DaoFactory - .ContactDao + .GetContactDao() .GetContacts(ApiContext.FilterValue, tags, contactStage, @@ -256,7 +258,7 @@ public string AddTagToBatchDeals( string tagName) { var deals = DaoFactory - .DealDao + .GetDealDao() .GetDeals( ApiContext.FilterValue, responsibleid, @@ -503,6 +505,7 @@ public string DeleteTagFrom(string entityType, int entityid, string tagName) DaoFactory.GetTagDao().DeleteTagFromEntity(entityTypeObj, entityid, tagName); var messageAction = GetTagDeletedAction(entityTypeObj, entityid); + MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, tagName); return tagName; @@ -536,8 +539,6 @@ public string DeleteContactTagFromGroup(string entityType, int entityid, string if (contactInst is Person && entityTypeObj == EntityType.Company) throw new Exception(CRMErrorsResource.ContactIsNotCompany); if (contactInst is Company && entityTypeObj == EntityType.Person) throw new Exception(CRMErrorsResource.ContactIsNotPerson); - - var contactIDsForDeleteTag = new List(); if (contactInst is Company) diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs index 06dda4d12f7..76b1955bfc1 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs @@ -27,6 +27,8 @@ using ASC.Common.Threading.Progress; using ASC.CRM.Core; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.Core.Utility; @@ -51,7 +53,7 @@ public partial class CRMController [Read(@"settings/currency")] public IEnumerable GetAvaliableCurrency() { - return CurrencyProvider.GetAll().ConvertAll(item => new CurrencyInfoWrapper(item)).ToItemList(); + return CurrencyProvider.GetAll().ConvertAll(item => CurrencyInfoWrapperHelper.Get(item)); } /// @@ -95,7 +97,7 @@ public IEnumerable GetSummaryTable(String currency) if (cur == null) throw new ArgumentException(); var table = CurrencyProvider.MoneyConvert(cur); - table.ToList().ForEach(tableItem => result.Add(ToCurrencyRateInfoWrapper(tableItem.Key, tableItem.Value))); + table.ToList().ForEach(tableItem => result.Add(CurrencyRateInfoWrapperHelper.Get(tableItem.Key, tableItem.Value))); return result; } @@ -111,10 +113,12 @@ public IEnumerable GetSummaryTable(String currency) /// [Update(@"contact/status/settings")] public Boolean? UpdateCRMContactStatusSettings(Boolean? changeContactStatusGroupAuto) - { - var tenantSettings = Global.TenantSettings; + { + var tenantSettings = SettingsManager.Load(); + tenantSettings.ChangeContactStatusGroupAuto = changeContactStatusGroupAuto; - tenantSettings.Save(); + + SettingsManager.Save(tenantSettings); MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated); @@ -134,9 +138,11 @@ public IEnumerable GetSummaryTable(String currency) [Update(@"contact/mailtohistory/settings")] public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAuto) { - var tenantSettings = Global.TenantSettings; + var tenantSettings = SettingsManager.Load(); + tenantSettings.WriteMailToHistoryAuto = writeMailToHistoryAuto; - tenantSettings.Save(); + + SettingsManager.Save(tenantSettings); //MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated); return writeMailToHistoryAuto; @@ -155,9 +161,10 @@ public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAut [Update(@"contact/tag/settings")] public Boolean? UpdateCRMContactTagSettings(Boolean? addTagToContactGroupAuto) { - var tenantSettings = Global.TenantSettings; + var tenantSettings = SettingsManager.Load(); tenantSettings.AddTagToContactGroupAuto = addTagToContactGroupAuto; - tenantSettings.Save(); + + SettingsManager.Save(tenantSettings); MessageService.Send( MessageAction.ContactsTagSettingsUpdated); @@ -177,10 +184,14 @@ public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAut public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var tenantSettings = Global.TenantSettings; + + var tenantSettings = SettingsManager.Load(); + tenantSettings.IsConfiguredPortal = configured ?? true; tenantSettings.WebFormKey = webFormKey ?? Guid.NewGuid(); - tenantSettings.Save(); + + SettingsManager.Save(tenantSettings); + return tenantSettings.IsConfiguredPortal; } @@ -196,14 +207,16 @@ public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey) public String UpdateOrganisationSettingsCompanyName(String companyName) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var tenantSettings = Global.TenantSettings; + + var tenantSettings = SettingsManager.Load(); + if (tenantSettings.InvoiceSetting == null) { tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; } tenantSettings.InvoiceSetting.CompanyName = companyName; - tenantSettings.Save(); + SettingsManager.Save(tenantSettings); MessageService.Send( MessageAction.OrganizationProfileUpdatedCompanyName, companyName); @@ -227,7 +240,7 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var tenantSettings = Global.TenantSettings; + var tenantSettings = SettingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { @@ -246,7 +259,7 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit tenantSettings.InvoiceSetting.CompanyAddress = companyAddress; - tenantSettings.Save(); + SettingsManager.Save(tenantSettings); MessageService.Send( MessageAction.OrganizationProfileUpdatedAddress); @@ -266,7 +279,9 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit public Int32 UpdateOrganisationSettingsLogo(bool reset) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + int companyLogoID; + if (!reset) { companyLogoID = OrganisationLogoManager.TryUploadOrganisationLogoFromTmp(DaoFactory); @@ -280,14 +295,16 @@ public Int32 UpdateOrganisationSettingsLogo(bool reset) companyLogoID = 0; } - var tenantSettings = Global.TenantSettings; + var tenantSettings = SettingsManager.Load(); + if (tenantSettings.InvoiceSetting == null) { tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; } tenantSettings.InvoiceSetting.CompanyLogoID = companyLogoID; - tenantSettings.Save(); + SettingsManager.Save(tenantSettings); + MessageService.Send( MessageAction.OrganizationProfileUpdatedInvoiceLogo); return companyLogoID; @@ -310,7 +327,8 @@ public String GetOrganisationSettingsLogo(int id) } else { - var tenantSettings = Global.TenantSettings; + var tenantSettings = SettingsManager.Load(); + if (tenantSettings.InvoiceSetting == null) { return string.Empty; @@ -332,10 +350,12 @@ public string ChangeWebToLeadFormKey() { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var tenantSettings = Global.TenantSettings; + var tenantSettings = SettingsManager.Load(); + tenantSettings.WebFormKey = Guid.NewGuid(); - tenantSettings.Save(); + SettingsManager.Save(tenantSettings); + MessageService.Send( MessageAction.WebsiteContactFormUpdatedKey); return tenantSettings.WebFormKey.ToString(); @@ -366,7 +386,7 @@ public CurrencyInfoWrapper UpdateCRMCurrency(String currency) Global.SaveDefaultCurrencySettings(cur); MessageService.Send( MessageAction.CrmDefaultCurrencyUpdated); - return ToCurrencyInfoWrapper(cur); + return CurrencyInfoWrapperHelper.Get(cur); } /// false @@ -395,7 +415,9 @@ public string StartImportFromCSV(string entityType, string csvFileURI, string js } new ImportFromCSVManager().StartImport(entityTypeObj, csvFileURI, jsonSettings); + return ""; + } /// false @@ -451,7 +473,9 @@ public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings public IProgressItem GetExportStatus() { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + return ExportToCsv.GetStatus(false); + } /// false @@ -459,8 +483,11 @@ public IProgressItem GetExportStatus() public IProgressItem CancelExport() { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + ExportToCsv.Cancel(false); + return ExportToCsv.GetStatus(false); + } /// false @@ -485,8 +512,11 @@ public IProgressItem GetPartialExportStatus() [Update(@"export/partial/cancel")] public IProgressItem CancelPartialExport() { + ExportToCsv.Cancel(true); + return ExportToCsv.GetStatus(true); + } /// false @@ -530,16 +560,5 @@ public IProgressItem StartPartialExport(string entityType, string base64FilterSt return ExportToCsv.Start(filterObject, fileName); } - - - protected CurrencyInfoWrapper ToCurrencyInfoWrapper(CurrencyInfo currencyInfo) - { - return currencyInfo == null ? null : new CurrencyInfoWrapper(currencyInfo); - } - - protected CurrencyRateInfoWrapper ToCurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate) - { - return currencyInfo == null ? null : new CurrencyRateInfoWrapper(currencyInfo, rate); - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMApi.Voip.cs b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs similarity index 90% rename from products/ASC.CRM/Server/Controllers/CRMApi.Voip.cs rename to products/ASC.CRM/Server/Controllers/CRMController.Voip.cs index 8a881e14926..7de012935ca 100644 --- a/products/ASC.CRM/Server/Controllers/CRMApi.Voip.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs @@ -24,14 +24,19 @@ */ +using ASC.Api.Core; using ASC.Api.CRM.Wrappers; using ASC.Api.Utils; +using ASC.Common.Web; using ASC.Core.Tenants; using ASC.CRM.Core; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.VoipService; using ASC.VoipService.Dao; using ASC.VoipService.Twilio; +using ASC.Web.Api.Routing; using ASC.Web.CRM.Classes; using ASC.Web.Studio.Utility; using System; @@ -45,9 +50,7 @@ namespace ASC.Api.CRM { public partial class CRMController - { - #region Numbers - + { /// /// /// @@ -78,7 +81,7 @@ public IEnumerable GetUnlinkedPhoneNumbers() if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); var listPhones = VoipProvider.GetExistingPhoneNumbers(); - var buyedPhones = DaoFactory.VoipDao.GetNumbers(); + var buyedPhones = DaoFactory.GetVoipDao().GetNumbers(); return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList(); } @@ -95,7 +98,7 @@ public IEnumerable GetExistingPhoneNumbers() { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - return DaoFactory.VoipDao.GetNumbers(); + return DaoFactory.GetVoipDao().GetNumbers(); } /// /// @@ -115,7 +118,7 @@ public VoipPhone BuyNumber(string number) SetDefaultAudio(newPhone); VoipProvider.UpdateSettings(newPhone); - return DaoFactory.VoipDao.SaveOrUpdateNumber(newPhone); + return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); } /// @@ -137,7 +140,7 @@ public VoipPhone LinkNumber(string id) VoipProvider.UpdateSettings(newPhone); - return DaoFactory.VoipDao.SaveOrUpdateNumber(newPhone); + return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); } public void SetDefaultAudio(VoipPhone newPhone) @@ -176,12 +179,12 @@ public VoipPhone DeleteNumber(string numberId) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var phone = dao.GetNumber(numberId).NotFoundIfNull(); VoipProvider.DisablePhone(phone); dao.DeleteNumber(numberId); - new SignalRHelper(phone.Number).Reload(); + new SignalRHelper(phone.Number, SignalrServiceClient).Reload(); return phone; } @@ -196,7 +199,7 @@ public VoipPhone DeleteNumber(string numberId) [Read(@"voip/numbers/{numberId:\w+}")] public VoipPhone GetNumber(string numberId) { - return DaoFactory.VoipDao.GetNumber(numberId).NotFoundIfNull(); + return DaoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull(); } /// @@ -208,7 +211,7 @@ public VoipPhone GetNumber(string numberId) [Read(@"voip/numbers/current")] public VoipPhone GetCurrentNumber() { - return DaoFactory.VoipDao.GetCurrentNumber().NotFoundIfNull(); + return DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); } /// @@ -235,7 +238,7 @@ public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var number = dao.GetNumber(numberId).NotFoundIfNull(); number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias); @@ -284,7 +287,7 @@ public object UpdateSettings(Queue queue, bool pause) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var numbers = dao.GetNumbers(); if (queue != null) @@ -332,7 +335,7 @@ public object GetVoipSettings() { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null); if (number != null) { @@ -380,7 +383,7 @@ public IEnumerable GetUploadedFilesUri() return result; } - private static VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false) + private VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false) { return new VoipUpload { @@ -416,7 +419,7 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); store.Delete("voip", path); - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var numbers = dao.GetNumbers(); var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); @@ -458,11 +461,7 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) return result; } - - #endregion - - #region Operators - + /// /// /// @@ -473,7 +472,7 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) [Read(@"voip/numbers/{numberId:\w+}/oper")] public IEnumerable GetOperators(string numberId) { - return DaoFactory.VoipDao.GetNumber(numberId).Settings.Operators.Select(r => r.Id); + return DaoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id); } /// @@ -489,12 +488,12 @@ public IEnumerable AddOperators(string numberId, IEnumerable operat { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - if (DaoFactory.VoipDao.GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) + if (DaoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) { throw new ArgumentException("Duplicate", "operators"); } - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var phone = dao.GetNumber(numberId); var lastOper = phone.Settings.Operators.LastOrDefault(); var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100; @@ -518,7 +517,7 @@ public Guid DeleteOperator(string numberId, Guid oper) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var phone = dao.GetNumber(numberId); var startOperId = 100; @@ -547,7 +546,7 @@ public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOut { if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); var oper = phone.Settings.Operators.Find(r => r.Id == operatorId); @@ -581,16 +580,13 @@ public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOut if (allowOutgoingCalls.HasValue) { - new SignalRHelper(phone.Number).Reload(operatorId.ToString()); + new SignalRHelper(phone.Number, SignalrServiceClient).Reload(operatorId.ToString()); } return oper; } - #endregion - - #region Calls - + /// /// /// @@ -601,7 +597,7 @@ public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOut [Create(@"voip/call")] public VoipCallWrapper MakeCall(string to, string contactId) { - var number = DaoFactory.VoipDao.GetCurrentNumber().NotFoundIfNull(); + var number = DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); var contactPhone = to.TrimStart('+'); @@ -611,11 +607,11 @@ public VoipCallWrapper MakeCall(string to, string contactId) if (contact == null) { - contact = ToContactWrapper(new VoipEngine(DaoFactory).CreateContact(contactPhone)); + contact = ToContactWrapper(VoipEngine.CreateContact(contactPhone)); } contact = GetContactWithFotos(contact); - var call = number.Call(to, contact.ID.ToString(CultureInfo.InvariantCulture)); + var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); return new VoipCallWrapper(call, contact); } @@ -628,7 +624,7 @@ public VoipCallWrapper MakeCall(string to, string contactId) [Create(@"voip/call/{callId:\w+}/answer")] public VoipCallWrapper AnswerCall(string callId) { - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); number.AnswerQueueCall(call.Id); @@ -644,7 +640,7 @@ public VoipCallWrapper AnswerCall(string callId) [Create(@"voip/call/{callId:\w+}/reject")] public VoipCallWrapper RejectCall(string callId) { - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); number.RejectQueueCall(call.Id); @@ -660,13 +656,13 @@ public VoipCallWrapper RejectCall(string callId) [Create(@"voip/call/{callId:\w+}/redirect")] public VoipCallWrapper ReditectCall(string callId, string to) { - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); if (call.ContactId != 0) { - var contact = DaoFactory.ContactDao.GetByID(call.ContactId); + var contact = DaoFactory.GetContactDao().GetByID(call.ContactId); var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact); if (!managers.Contains(Guid.Parse(to))) @@ -689,7 +685,7 @@ public VoipCallWrapper ReditectCall(string callId, string to) [Create(@"voip/call/{callId:\w+}")] public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) { - var dao = DaoFactory.VoipDao; + var dao = DaoFactory.GetVoipDao(); var call = dao.GetCall(callId) ?? new VoipCall(); @@ -709,15 +705,18 @@ public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answ } else { - new VoipEngine(DaoFactory).GetContact(call); + VoipEngine.GetContact(call); } if (call.ContactId == 0) { contactPhone = contactPhone.TrimStart('+'); + var person = CreatePerson(contactPhone, TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), null, 0, null, ShareType.None, new List { SecurityContext.CurrentAccount.ID }, null, null); - DaoFactory.ContactInfoDao.Save(new ContactInfo { ContactID = person.ID, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); - call.ContactId = person.ID; + + DaoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); + + call.ContactId = person.Id; } } } @@ -762,7 +761,7 @@ public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answ [Create(@"voip/price/{callId:\w+}")] public void SavePrice(string callId) { - new VoipEngine(DaoFactory).SaveAdditionalInfo(callId); + VoipEngine.SaveAdditionalInfo(callId); } /// @@ -774,7 +773,7 @@ public void SavePrice(string callId) [Read(@"voip/call")] public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) { - var voipDao = DaoFactory.VoipDao; + var voipDao = DaoFactory.GetVoipDao(); var filter = new VoipCallFilter { @@ -784,17 +783,17 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, Agent = agent, Client = client, ContactID = contactID, - SortBy = _context.SortBy, - SortOrder = !_context.SortDescending, - SearchText = _context.FilterValue, - Offset = _context.StartIndex, - Max = _context.Count, + SortBy = ApiContext.SortBy, + SortOrder = !.ApiContext.SortDescending, + SearchText = ApiContext.FilterValue, + Offset = ApiContext.StartIndex, + Max = ApiContext.Count, }; - _context.SetDataPaginated(); - _context.SetDataFiltered(); - _context.SetDataSorted(); - _context.TotalCount = voipDao.GetCallsCount(filter); + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + ApiContext.TotalCount = voipDao.GetCallsCount(filter); var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); var calls = voipDao.GetCalls(filter).Select( @@ -826,7 +825,7 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, [Read(@"voip/call/missed")] public IEnumerable GetMissedCalls() { - var voipDao = DaoFactory.VoipDao; + var voipDao = DaoFactory.GetVoipDao(); var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( @@ -847,10 +846,10 @@ public IEnumerable GetMissedCalls() return new VoipCallWrapper(r, contact); }).ToList(); - _context.SetDataPaginated(); - _context.SetDataFiltered(); - _context.SetDataSorted(); - _context.TotalCount = calls.Count; + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + ApiContext.TotalCount = calls.Count; return calls; } @@ -864,9 +863,9 @@ public IEnumerable GetMissedCalls() [Read(@"voip/call/{callId:\w+}")] public VoipCallWrapper GetCall(string callId) { - var call = DaoFactory.VoipDao.GetCall(callId); + var call = DaoFactory.GetVoipDao().GetCall(callId); - new VoipEngine(DaoFactory).GetContact(call); + VoipEngine.GetContact(call); if (call.ContactId == 0) return new VoipCallWrapper(call); @@ -876,12 +875,10 @@ public VoipCallWrapper GetCall(string callId) return new VoipCallWrapper(call, contact); } - #endregion - - private static ContactWrapper GetContactWithFotos(ContactWrapper contact) + private ContactWrapper GetContactWithFotos(ContactWrapper contact) { - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany); - contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.ID, contact.IsCompany); + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); return contact; } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Controllers/CRMController.cs index 6311a2b37a0..c1c2e10d36d 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.cs @@ -1,17 +1,32 @@ using ASC.Api.Core; using ASC.Api.CRM.Wrappers; +using ASC.Api.Documents; using ASC.Common; using ASC.Common.Web; using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.Core.Notify.Signalr; +using ASC.Core.Tenants; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.Data.Storage; +using ASC.ElasticSearch; using ASC.MessagingSystem; +using ASC.VoipService; +using ASC.VoipService.Dao; +using ASC.Web.Api.Models; using ASC.Web.Api.Routing; +using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Services.DocumentService; using ASC.Web.Files.Services.WCFService; +using ASC.Web.Files.Utils; +using ASC.Web.Studio.Core; +using ASC.Web.Studio.Utility; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; @@ -30,8 +45,61 @@ public CRMController(CRMSecurity cRMSecurity, TaskWrapperHelper taskWrapperHelper, SecurityContext securityContext, UserManager userManager, - CurrencyProvider currencyProvider) + CurrencyProvider currencyProvider, + Global global, + SettingsManager settingsManager, + IServiceProvider serviceProvider, + PdfCreator pdfCreator, + TenantManager tenantManager, + SetupInfo setupInfo, + FileSizeComment fileSizeComment, + AuthManager authManager, + FileUploader fileUploader, + ReportHelper reportHelper, + IHttpContextAccessor httpContextAccessor, + InvoiceSetting invoiceSetting, + OrganisationLogoManager organisationLogoManager, + ContactBaseWrapperHelper contactBaseWrapperHelper, + ContactPhotoManager contactPhotoManager, + CommonLinkUtility commonLinkUtility, + StorageFactory storageFactory, + TenantUtil tenantUtil, + IVoipProvider voipProvider, + SignalrServiceClient signalrServiceClient, + VoipEngine voipEngine, + + Web.Files.Classes.FilesSettings filesSettings, + ASC.Files.Core.Data.DaoFactory filesDaoFactory, + + FileWrapperHelper fileWrapperHelper, + DisplayUserSettingsHelper displayUserSettingsHelper, + OpportunityWrapperHelper opportunityWrapperHelper, + EmployeeWraperHelper employeeWraperHelper, + ApiDateTimeHelper apiDateTimeHelper, + CurrencyInfoWrapperHelper currencyInfoWrapperHelper, + CurrencyRateInfoWrapperHelper currencyRateInfoWrapperHelper, + CurrencyRateWrapperHelper currencyRateWrapperHelper, + CasesWrapperHelper casesWrapperHelper, + InvoiceWrapperHelper invoiceWrapperHelper, + InvoiceItemWrapperHelper invoiceItemWrapperHelper, + InvoiceBaseWrapperHelper invoiceBaseWrapperHelper, + InvoiceLineWrapperHelper invoiceLineWrapperHelper, + InvoiceTaxWrapperHelper invoiceTaxWrapperHelper, + RelationshipEventWrapperHelper relationshipEventWrapperHelper, + DocbuilderReportsUtility docbuilderReportsUtility, + + FactoryIndexer factoryIndexerCasesWrapper, + FactoryIndexer factoryIndexerFieldsWrapper) { + + VoipEngine = voipEngine; + SignalrServiceClient = signalrServiceClient; + // voipProvider = VoipDao.GetProvider(); + + TenantUtil = tenantUtil; + StorageFactory = storageFactory; + CommonLinkUtility = commonLinkUtility; + ContactPhotoManager = contactPhotoManager; DaoFactory = daoFactory; ApiContext = apiContext; CRMSecurity = cRMSecurity; @@ -42,8 +110,86 @@ public CRMController(CRMSecurity cRMSecurity, SecurityContext = securityContext; UserManager = userManager; CurrencyProvider = currencyProvider; + OpportunityWrapperHelper = opportunityWrapperHelper; + EmployeeWraperHelper = employeeWraperHelper; + ApiDateTimeHelper = apiDateTimeHelper; + CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + CurrencyRateInfoWrapperHelper = currencyRateInfoWrapperHelper; + CurrencyRateWrapperHelper = currencyRateWrapperHelper; + CasesWrapperHelper = casesWrapperHelper; + ServiceProvider = serviceProvider; + FactoryIndexerCasesWrapper = factoryIndexerCasesWrapper; + FactoryIndexerFieldsWrapper = factoryIndexerFieldsWrapper; + InvoiceWrapperHelper = invoiceWrapperHelper; + InvoiceItemWrapperHelper = invoiceItemWrapperHelper; + InvoiceBaseWrapperHelper = invoiceBaseWrapperHelper; + InvoiceLineWrapperHelper = invoiceLineWrapperHelper; + InvoiceTaxWrapperHelper = invoiceTaxWrapperHelper; + RelationshipEventWrapperHelper = relationshipEventWrapperHelper; + FileWrapperHelper = fileWrapperHelper; + OrganisationLogoManager = organisationLogoManager; + + SetupInfo = setupInfo; + FileSizeComment = fileSizeComment; + TenantManager = tenantManager; + + AuthManager = authManager; + PdfCreator = pdfCreator; + FilesDaoFactory = filesDaoFactory; + + FilesSettings = filesSettings; + FileUploader = fileUploader; + Global = global; + ReportHelper = reportHelper; + HttpContextAccessor = httpContextAccessor; + DocbuilderReportsUtility = docbuilderReportsUtility; + InvoiceSetting = invoiceSetting; + + ContactBaseWrapperHelper = contactBaseWrapperHelper; } + + public VoipEngine VoipEngine { get; } + public SignalrServiceClient SignalrServiceClient { get; } + public IVoipProvider VoipProvider { get; } + public TenantUtil TenantUtil { get; } + public StorageFactory StorageFactory { get; } + public CommonLinkUtility CommonLinkUtility { get; } + public ContactPhotoManager ContactPhotoManager { get; } + public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public OrganisationLogoManager OrganisationLogoManager { get; } + public InvoiceSetting InvoiceSetting { get; } + public DocbuilderReportsUtility DocbuilderReportsUtility { get; } + public IHttpContextAccessor HttpContextAccessor { get; } + public ReportHelper ReportHelper { get; } + public FileUploader FileUploader { get; } + public Web.Files.Classes.FilesSettings FilesSettings { get; } + public ASC.Files.Core.Data.DaoFactory FilesDaoFactory { get; } + public FileWrapperHelper FileWrapperHelper { get; } + public RelationshipEventWrapperHelper RelationshipEventWrapperHelper { get; } + public AuthManager AuthManager { get; } + public FileSizeComment FileSizeComment { get; } + public SetupInfo SetupInfo { get; } + public TenantManager TenantManager { get; } + public PdfCreator PdfCreator { get; } + public InvoiceTaxWrapperHelper InvoiceTaxWrapperHelper { get; } + public InvoiceLineWrapperHelper InvoiceLineWrapperHelper { get; } + public InvoiceBaseWrapperHelper InvoiceBaseWrapperHelper { get; } + public InvoiceItemWrapperHelper InvoiceItemWrapperHelper { get; } + public InvoiceWrapperHelper InvoiceWrapperHelper { get; } + public FactoryIndexer FactoryIndexerFieldsWrapper { get; } + public FactoryIndexer FactoryIndexerCasesWrapper { get; } + public IServiceProvider ServiceProvider { get; } + public CasesWrapperHelper CasesWrapperHelper { get; } + public CurrencyRateWrapperHelper CurrencyRateWrapperHelper { get; } + public SettingsManager SettingsManager { get; } + public Global Global { get; } + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public CurrencyRateInfoWrapperHelper CurrencyRateInfoWrapperHelper { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public OpportunityWrapperHelper OpportunityWrapperHelper { get; } + public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public CurrencyProvider CurrencyProvider { get; } public UserManager UserManager { get; } public SecurityContext SecurityContext { get; } diff --git a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs index 20a51bba2f7..7a2715ba2b8 100644 --- a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs @@ -44,7 +44,7 @@ public sealed class CasesWrapper : Wrapper protected override string Table { get { return "crm_case"; } } - public static CasesWrapper GetTasksWrapper(IServiceProvider serviceProvider, Cases item) + public static CasesWrapper GetCasesWrapper(IServiceProvider serviceProvider, Cases item) { var tenantManager = serviceProvider.GetService(); diff --git a/products/ASC.CRM/Server/Model/CasesWrapper.cs b/products/ASC.CRM/Server/Model/CasesWrapper.cs index f493def6d5b..084a24942ca 100644 --- a/products/ASC.CRM/Server/Model/CasesWrapper.cs +++ b/products/ASC.CRM/Server/Model/CasesWrapper.cs @@ -30,6 +30,7 @@ using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.Web.Api.Models; using System; using System.Collections.Generic; @@ -94,13 +95,19 @@ public class CasesWrapperHelper { public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity) + CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ContactBaseWrapperHelper contactBaseWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; + DaoFactory = daoFactory; + ContactBaseWrapperHelper = contactBaseWrapperHelper; } + public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } @@ -124,8 +131,28 @@ public CasesWrapper Get(Cases cases) .Select(item => EmployeeWraperHelper.Get(item.Key)); } - return result; + result.CustomFields = DaoFactory + .GetCustomFieldDao() + .GetEnityFields(EntityType.Case, cases.ID, false) + .ConvertAll(item => new CustomFieldBaseWrapper(item)); + + result.Members = new List(); + + var memberIDs = DaoFactory.GetCasesDao().GetMembers(cases.ID); + var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); + var membersWrapperList = new List(); + + foreach (var member in membersList) + { + if (member == null) continue; + + membersWrapperList.Add(ContactBaseWrapperHelper.Get(member)); + } + + result.Members = membersWrapperList; + + return result; } } diff --git a/products/ASC.CRM/Server/Model/ContactWrapper.cs b/products/ASC.CRM/Server/Model/ContactWrapper.cs index 00a4738d3dd..dad31262425 100644 --- a/products/ASC.CRM/Server/Model/ContactWrapper.cs +++ b/products/ASC.CRM/Server/Model/ContactWrapper.cs @@ -25,6 +25,8 @@ using ASC.Api.Core; +using ASC.Common; +using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -45,17 +47,9 @@ namespace ASC.Api.CRM.Wrappers [DataContract(Name = "person", Namespace = "")] public class PersonWrapper : ContactWrapper { - public PersonWrapper(int id) : - base(id) + public PersonWrapper() { - } - public PersonWrapper(Person person) - : base(person) - { - FirstName = person.FirstName; - LastName = person.LastName; - Title = person.JobTitle; } public static PersonWrapper ToPersonWrapperQuick(Person person) @@ -111,22 +105,78 @@ public static PersonWrapper ToPersonWrapperQuick(Person person) public new static PersonWrapper GetSample() { return new PersonWrapper(0) - { - IsPrivate = true, - IsShared = false, - IsCompany = false, - FirstName = "Tadjeddine", - LastName = "Bachir", - Company = CompanyWrapper.GetSample(), - Title = "Programmer", - About = "", - Created = ApiDateTime.GetSample(), - CreateBy = EmployeeWraper.GetSample(), - ShareType = ShareType.None - }; + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + FirstName = "Tadjeddine", + LastName = "Bachir", + Company = CompanyWrapper.GetSample(), + Title = "Programmer", + About = "", + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + ShareType = ShareType.None + }; + } + } + + + public class PersonWrapperHelper + { + public PersonWrapperHelper() + { + } + + public PersonWrapper Get(Person person) + { + + FirstName = person.FirstName; + LastName = person.LastName; + Title = person.JobTitle; + + + return new PersonWrapper + { + FirstName = person.FirstName, + LastName = person.LastName, + Title = person.JobTitle + }; + } + } + + public static class PersonWrapperHelperHelperExtension + { + public static DIHelper AddPersonWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; } } + + + + + + + + + + + + + + + + + + + + + + /// /// Company /// @@ -194,14 +244,14 @@ public static CompanyWrapper ToCompanyWrapperQuick(Company company) public new static CompanyWrapper GetSample() { return new CompanyWrapper(0) - { - IsPrivate = true, - IsShared = false, - IsCompany = true, - About = "", - CompanyName = "Food and Culture Project", - PersonsCount = 0 - }; + { + IsPrivate = true, + IsShared = false, + IsCompany = true, + About = "", + CompanyName = "Food and Culture Project", + PersonsCount = 0 + }; } } @@ -210,8 +260,7 @@ public static CompanyWrapper ToCompanyWrapperQuick(Company company) [KnownType(typeof(CompanyWrapper))] public abstract class ContactWrapper : ContactBaseWrapper { - protected ContactWrapper(int id) - : base(id) + protected ContactWrapper() { } @@ -275,8 +324,8 @@ protected ContactWrapper(Contact contact) About = "", Created = ApiDateTime.GetSample(), CreateBy = EmployeeWraper.GetSample(), - CommonData = new List(){ContactInfoWrapper.GetSample()}, - CustomFields = new List(){CustomFieldBaseWrapper.GetSample()}, + CommonData = new List() { ContactInfoWrapper.GetSample() }, + CustomFields = new List() { CustomFieldBaseWrapper.GetSample() }, ShareType = ShareType.None, CanDelete = true, CanEdit = true, @@ -289,8 +338,7 @@ protected ContactWrapper(Contact contact) [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithEmailWrapper : ContactBaseWrapper { - protected ContactBaseWithEmailWrapper(int id) - : base(id) + protected ContactBaseWithEmailWrapper() { } @@ -299,7 +347,7 @@ public ContactBaseWithEmailWrapper(Contact contact) { } - public ContactBaseWithEmailWrapper(ContactWrapper contactWrapper) : base(contactWrapper.ID) + public ContactBaseWithEmailWrapper(ContactWrapper contactWrapper) { AccessList = contactWrapper.AccessList; CanEdit = contactWrapper.CanEdit; @@ -369,69 +417,44 @@ public ContactBaseWithPhoneWrapper(ContactWrapper contactWrapper) } - /// - /// Contact base information - /// - [DataContract(Name = "contactBase", Namespace = "")] - public class ContactBaseWrapper - { - public ContactBaseWrapper(Contact contact) - : base(contact.ID) - { - DisplayName = contact.GetTitle(); - IsPrivate = CRMSecurity.IsPrivate(contact); - IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read; - ShareType = contact.ShareType; - if (IsPrivate) - { - AccessList = CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeWraper.Get(item.Key)); - } - Currency = !String.IsNullOrEmpty(contact.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(contact.Currency)) : - null; - SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); - MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); - IsCompany = contact is Company; - CanEdit = CRMSecurity.CanEdit(contact); - CanDelete = CRMSecurity.CanDelete(contact); - } - public static ContactBaseWrapper ToContactBaseWrapperQuick(Contact contact) - { - var result = new ContactBaseWrapper(contact.ID); - result.DisplayName = contact.GetTitle(); - result.IsPrivate = CRMSecurity.IsPrivate(contact); - result.IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read; - result.ShareType = contact.ShareType; - if (result.IsPrivate) - { - result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeWraper.Get(item.Key)); - } - result.Currency = !String.IsNullOrEmpty(contact.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(contact.Currency)) : - null; - result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); - result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); - result.IsCompany = contact is Company; - result.CanEdit = CRMSecurity.CanEdit(contact); - //result.CanDelete = CRMSecurity.CanDelete(contact); - return result; - } - protected ContactBaseWrapper(int contactID) - : base(contactID) + + + + + + + + + + + + + + + /// + /// Contact base information + /// + [DataContract(Name = "contactBase", Namespace = "")] + public class ContactBaseWrapper + { + public ContactBaseWrapper() { + } + + [DataMember(Name = "id")] + public int Id { get; set; } + [DataMember(IsRequired = false, EmitDefaultValue = false)] public String SmallFotoUrl { get; set; } @@ -467,14 +490,14 @@ protected ContactBaseWrapper(int contactID) public static ContactBaseWrapper GetSample() { - return new ContactBaseWrapper(0) - { - IsPrivate = true, - IsShared = false, - IsCompany = false, - DisplayName = "Tadjeddine Bachir", - SmallFotoUrl = "url to foto" - }; + return new ContactBaseWrapper + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + DisplayName = "Tadjeddine Bachir", + SmallFotoUrl = "url to foto" + }; } } @@ -488,4 +511,110 @@ public class ContactWithTaskWrapper [DataMember(IsRequired = false, EmitDefaultValue = false)] public ContactWrapper Contact { get; set; } } + + + + + + + + + + + public class ContactBaseWrapperHelper + { + public ContactBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + CurrencyProvider currencyProvider, + PathProvider pathProvider, + CurrencyInfoWrapperHelper currencyInfoWrapperHelper) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + CurrencyProvider = currencyProvider; + PathProvider = pathProvider; + CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + } + + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public CRMSecurity CRMSecurity { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public CurrencyProvider CurrencyProvider { get; } + public PathProvider PathProvider { get; } + + public ContactBaseWrapper GetQuick(Contact contact) + { + var result = new ContactBaseWrapper + { + Id = contact.ID, + DisplayName = contact.GetTitle(), + IsPrivate = CRMSecurity.IsPrivate(contact), + IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read, + ShareType = contact.ShareType, + Currency = !String.IsNullOrEmpty(contact.Currency) ? + CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(contact.Currency)) : null, + SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), + MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), + IsCompany = contact is Company, + CanEdit = CRMSecurity.CanEdit(contact), + // CanDelete = CRMSecurity.CanDelete(contact), + }; + + if (result.IsPrivate) + { + result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) + .Select(item => EmployeeWraperHelper.Get(item.Key)); + } + + return result; + } + + + public ContactBaseWrapper Get(Contact contact) + { + var result = new ContactBaseWrapper + { + Id = contact.ID, + DisplayName = contact.GetTitle(), + IsPrivate = CRMSecurity.IsPrivate(contact), + IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read, + ShareType = contact.ShareType, + Currency = !String.IsNullOrEmpty(contact.Currency) ? + CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(contact.Currency)) : null, + SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), + MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), + IsCompany = contact is Company, + CanEdit = CRMSecurity.CanEdit(contact), + CanDelete = CRMSecurity.CanDelete(contact), + }; + + if (result.IsPrivate) + { + result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) + .Select(item => EmployeeWraperHelper.Get(item.Key)); + } + + return result; + } + } + + public static class ContactBaseWrapperHelperExtension + { + public static DIHelper AddContactBaseWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService() + .AddCurrencyProviderService() + .AddCRMPathProviderService(); + } + } + + + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs index 56fad5119ff..fe77216e1cd 100644 --- a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs +++ b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs @@ -26,6 +26,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common; using ASC.CRM.Core; namespace ASC.Api.CRM @@ -38,16 +39,8 @@ public class CurrencyInfoWrapper { public CurrencyInfoWrapper() { - } - public CurrencyInfoWrapper(CurrencyInfo currencyInfo) - { - Abbreviation = currencyInfo.Abbreviation; - CultureName = currencyInfo.CultureName; - Symbol = currencyInfo.Symbol; - Title = currencyInfo.Title; - IsConvertable = currencyInfo.IsConvertable; - IsBasic = currencyInfo.IsBasic; + } [DataMember] @@ -71,17 +64,52 @@ public CurrencyInfoWrapper(CurrencyInfo currencyInfo) public static CurrencyInfoWrapper GetSample() { return new CurrencyInfoWrapper - { - Title = "Chinese Yuan", - Abbreviation = "CNY", - Symbol = "¥", - CultureName = "CN", - IsConvertable = true, - IsBasic = false - }; + { + Title = "Chinese Yuan", + Abbreviation = "CNY", + Symbol = "¥", + CultureName = "CN", + IsConvertable = true, + IsBasic = false + }; + } + } + + public class CurrencyInfoWrapperHelper + { + public CurrencyInfoWrapperHelper() + { + } + + + + public CurrencyInfoWrapper Get(CurrencyInfo currencyInfo) + { + if (currencyInfo == null) return null; + + return new CurrencyInfoWrapper + { + Abbreviation = currencyInfo.Abbreviation, + CultureName = currencyInfo.CultureName, + Symbol = currencyInfo.Symbol, + Title = currencyInfo.Title, + IsConvertable = currencyInfo.IsConvertable, + IsBasic = currencyInfo.IsBasic + }; } } + public static class CurrencyInfoWrapperExtension + { + public static DIHelper AddCurrencyInfoWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } + } + + /// /// Currency rate information @@ -93,12 +121,50 @@ public CurrencyRateInfoWrapper() { } - public CurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate) : base(currencyInfo) + //public CurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate) + // : base(currencyInfo) + //{ + // Rate = rate; + //} + + [DataMember] + public decimal Rate { get; set; } + } + + + public class CurrencyRateInfoWrapperHelper + { + public CurrencyRateInfoWrapperHelper(CurrencyInfoWrapperHelper currencyInfoWrapperHelper) { - Rate = rate; + CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; } - [DataMember] - public Decimal Rate { get; set; } + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + + public CurrencyRateInfoWrapper Get(CurrencyInfo currencyInfo, decimal rate) + { + var currencyInfoWrapper = CurrencyInfoWrapperHelper.Get(currencyInfo); + + return new CurrencyRateInfoWrapper + { + Abbreviation = currencyInfoWrapper.Abbreviation, + CultureName = currencyInfoWrapper.CultureName, + Symbol = currencyInfoWrapper.Symbol, + Title = currencyInfoWrapper.Title, + IsConvertable = currencyInfoWrapper.IsConvertable, + IsBasic = currencyInfoWrapper.IsBasic, + Rate = rate + }; + } + } + + public static class CurrencyRateInfoWrapperExtension + { + public static DIHelper AddCurrencyRateInfoWrapperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs index 72b0d2b7864..841027f1c8f 100644 --- a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs +++ b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs @@ -26,8 +26,11 @@ using System; using System.Runtime.Serialization; +using ASC.Api.Core; using ASC.Api.CRM.Wrappers; +using ASC.Common; using ASC.CRM.Core; +using ASC.Web.Api.Models; namespace ASC.Api.CRM { @@ -35,18 +38,12 @@ namespace ASC.Api.CRM /// Currency rate /// [DataContract(Name = "currencyRate", Namespace = "")] - public class CurrencyRateWrapper + public class CurrencyRateWrapper { - public CurrencyRateWrapper(int id) + public CurrencyRateWrapper() { } - public CurrencyRateWrapper(CurrencyRate currencyRate) - { - FromCurrency = currencyRate.FromCurrency; - ToCurrency = currencyRate.ToCurrency; - Rate = currencyRate.Rate; - } [DataMember(Name = "id")] public int Id { get; set; } @@ -62,12 +59,43 @@ public CurrencyRateWrapper(CurrencyRate currencyRate) public static CurrencyRateWrapper GetSample() { - return new CurrencyRateWrapper(1) + return new CurrencyRateWrapper { + Id = 1, FromCurrency = "EUR", ToCurrency = "USD", Rate = (decimal)1.1 }; } } + + public class CurrencyRateWrapperHelper + { + public CurrencyRateWrapperHelper() + { + } + + public CurrencyRateWrapper Get(CurrencyRate currencyRate) + { + return new CurrencyRateWrapper + { + FromCurrency = currencyRate.FromCurrency, + ToCurrency = currencyRate.ToCurrency, + Rate = currencyRate.Rate + }; + } + } + + public static class CurrencyRateWrapperHelperExtension + { + public static DIHelper AddCurrencyRateWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } + } + + + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs index 648a7da85f9..cd2edff1f2d 100644 --- a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs +++ b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs @@ -24,14 +24,18 @@ */ using ASC.Api.Core; +using ASC.Common; +using ASC.Core.Common.Settings; using ASC.CRM.Classes; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.Api.Models; using ASC.Web.CRM.Classes; using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; namespace ASC.Api.CRM.Wrappers @@ -41,35 +45,13 @@ namespace ASC.Api.CRM.Wrappers /// Invoice /// [DataContract(Name = "invoiceBase", Namespace = "")] - public class InvoiceBaseWrapper + public class InvoiceBaseWrapper { - public InvoiceBaseWrapper(int id) + public InvoiceBaseWrapper() { - } - public InvoiceBaseWrapper(Invoice invoice) - { - Status = new InvoiceStatusWrapper(invoice.Status); - Number = invoice.Number; - IssueDate = (ApiDateTime) invoice.IssueDate; - TemplateType = invoice.TemplateType; - DueDate = (ApiDateTime) invoice.DueDate; - Currency = !String.IsNullOrEmpty(invoice.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) : - new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); - ExchangeRate = invoice.ExchangeRate; - Language = invoice.Language; - PurchaseOrderNumber = invoice.PurchaseOrderNumber; - Terms = invoice.Terms; - Description = invoice.Description; - FileID = invoice.FileID; - CreateOn = (ApiDateTime)invoice.CreateOn; - CreateBy = EmployeeWraper.Get(invoice.CreateBy); - CanEdit = CRMSecurity.CanEdit(invoice); - CanDelete = CRMSecurity.CanDelete(invoice); } - [DataMember(Name = "id")] public int Id { get; set; } @@ -134,48 +116,114 @@ public InvoiceBaseWrapper(Invoice invoice) public bool CanDelete { get; set; } } + public class InvoiceBaseWrapperHelper + { + public InvoiceBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + InvoiceStatusWrapperHelper invoiceStatusWrapperHelper, + DaoFactory daoFactory) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + SettingsManager = settingsManager; + CurrencyProvider = currencyProvider; + InvoiceStatusWrapperHelper = invoiceStatusWrapperHelper; + DaoFactory = daoFactory; + } + + public InvoiceStatusWrapperHelper InvoiceStatusWrapperHelper { get; } + public CurrencyProvider CurrencyProvider { get; } + public SettingsManager SettingsManager { get; } + public CRMSecurity CRMSecurity { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public DaoFactory DaoFactory { get; } + + public InvoiceBaseWrapper Get(Invoice invoice) + { + + var result = new InvoiceBaseWrapper + { + Id = invoice.ID, + Status = InvoiceStatusWrapperHelper.Get(invoice.Status), + Number = invoice.Number, + IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), + TemplateType = invoice.TemplateType, + DueDate = ApiDateTimeHelper.Get(invoice.DueDate), + Currency = !String.IsNullOrEmpty(invoice.Currency) ? + new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) : + new CurrencyInfoWrapper(SettingsManager.Load().DefaultCurrency), + ExchangeRate = invoice.ExchangeRate, + Language = invoice.Language, + PurchaseOrderNumber = invoice.PurchaseOrderNumber, + Terms = invoice.Terms, + Description = invoice.Description, + FileID = invoice.FileID, + CreateOn = ApiDateTimeHelper.Get(invoice.CreateOn), + CreateBy = EmployeeWraperHelper.Get(invoice.CreateBy), + CanEdit = CRMSecurity.CanEdit(invoice), + CanDelete = CRMSecurity.CanDelete(invoice) + }; + + if (invoice.ContactID > 0) + { + result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + } + + if (invoice.ConsigneeID > 0) + { + result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + } + + if (invoice.EntityID > 0) + { + result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); + } + + result.Cost = invoice.GetInvoiceCost(DaoFactory); + + return result; + + } + } + + public static class InvoiceBaseWrapperHelperExtension + { + public static DIHelper AddInvoiceBaseWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService() + .AddSettingsManagerService() + .AddCurrencyProviderService() + .AddInvoiceStatusWrapperHelperService(); + } + } + /// /// Invoice /// [DataContract(Name = "invoice", Namespace = "")] public class InvoiceWrapper : InvoiceBaseWrapper { - public InvoiceWrapper(int id) - : base(id) + public InvoiceWrapper() { } - public InvoiceWrapper(Invoice invoice) - : base(invoice.ID) - { - Status = new InvoiceStatusWrapper(invoice.Status); - Number = invoice.Number; - IssueDate = (ApiDateTime) invoice.IssueDate; - TemplateType = invoice.TemplateType; - DueDate = (ApiDateTime) invoice.DueDate; - Currency = !String.IsNullOrEmpty(invoice.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) : - new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); - ExchangeRate = invoice.ExchangeRate; - Language = invoice.Language; - PurchaseOrderNumber = invoice.PurchaseOrderNumber; - Terms = invoice.Terms; - Description = invoice.Description; - FileID = invoice.FileID; - CreateOn = (ApiDateTime)invoice.CreateOn; - CreateBy = EmployeeWraper.Get(invoice.CreateBy); - CanEdit = CRMSecurity.CanEdit(invoice); - CanDelete = CRMSecurity.CanDelete(invoice); - } - [DataMember] public List InvoiceLines { get; set; } public static InvoiceWrapper GetSample() { - return new InvoiceWrapper(0) + return new InvoiceWrapper { - Status = new InvoiceStatusWrapper(InvoiceStatus.Draft), + Status = InvoiceStatusWrapper.GetSample(), Number = string.Empty, IssueDate = ApiDateTime.GetSample(), TemplateType = InvoiceTemplateType.Eur, @@ -192,40 +240,120 @@ public static InvoiceWrapper GetSample() CanEdit = true, CanDelete = true, Cost = 0, - InvoiceLines = new List{ InvoiceLineWrapper.GetSample() } + InvoiceLines = new List { InvoiceLineWrapper.GetSample() } }; } } - /// - /// Invoice Item - /// - [DataContract(Name = "invoiceItem", Namespace = "")] - public class InvoiceItemWrapper + + public class InvoiceWrapperHelper { - public InvoiceItemWrapper(int id) + public InvoiceWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + InvoiceStatusWrapperHelper invoiceStatusWrapperHelper, + InvoiceLineWrapperHelper invoiceLineWrapperHelper, + DaoFactory daoFactory, + CurrencyInfoWrapperHelper currencyInfoWrapperHelper, + CurrencyRateInfoWrapperHelper currencyRateInfoWrapperHelper) { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + SettingsManager = settingsManager; + CurrencyProvider = currencyProvider; + InvoiceStatusWrapperHelper = invoiceStatusWrapperHelper; + DaoFactory = daoFactory; + InvoiceLineWrapperHelper = invoiceLineWrapperHelper; + CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + CurrencyRateInfoWrapperHelper = currencyRateInfoWrapperHelper; } - public InvoiceItemWrapper(InvoiceItem invoiceItem) + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public CurrencyRateInfoWrapperHelper CurrencyRateInfoWrapperHelper { get; } + public DaoFactory DaoFactory { get; } + public InvoiceLineWrapperHelper InvoiceLineWrapperHelper { get; } + public InvoiceStatusWrapperHelper InvoiceStatusWrapperHelper { get; } + public CurrencyProvider CurrencyProvider { get; } + public SettingsManager SettingsManager { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public CRMSecurity CRMSecurity { get; } + + public InvoiceWrapper Get(Invoice invoice) { - Title = invoiceItem.Title; - StockKeepingUnit = invoiceItem.StockKeepingUnit; - Description = invoiceItem.Description; - Price = invoiceItem.Price; - Quantity = invoiceItem.Quantity; - StockQuantity = invoiceItem.StockQuantity; - TrackInvenory = invoiceItem.TrackInventory; - - CreateOn = (ApiDateTime)invoiceItem.CreateOn; - CreateBy = EmployeeWraper.Get(invoiceItem.CreateBy); - Currency = !String.IsNullOrEmpty(invoiceItem.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(invoiceItem.Currency)) : - new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency); - CanEdit = CRMSecurity.CanEdit(invoiceItem); - CanDelete = CRMSecurity.CanDelete(invoiceItem); + var result = new InvoiceWrapper + { + Id = invoice.ID, + Status = InvoiceStatusWrapperHelper.Get(invoice.Status), + Number = invoice.Number, + IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), + TemplateType = invoice.TemplateType, + DueDate = ApiDateTimeHelper.Get(invoice.DueDate), + Currency = !String.IsNullOrEmpty(invoice.Currency) ? + CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(invoice.Currency)) : + CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency), + ExchangeRate = invoice.ExchangeRate, + Language = invoice.Language, + PurchaseOrderNumber = invoice.PurchaseOrderNumber, + Terms = invoice.Terms, + Description = invoice.Description, + FileID = invoice.FileID, + CreateOn = ApiDateTimeHelper.Get(invoice.CreateOn), + CreateBy = EmployeeWraperHelper.Get(invoice.CreateBy), + CanEdit = CRMSecurity.CanEdit(invoice), + CanDelete = CRMSecurity.CanDelete(invoice), + }; + + if (invoice.ContactID > 0) + { + result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + } + + if (invoice.ConsigneeID > 0) + { + result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + } + + if (invoice.EntityID > 0) + { + result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); + } + + result.Cost = invoice.GetInvoiceCost(DaoFactory); + + result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(x => InvoiceLineWrapperHelper.Get(x)).ToList(); + + return result; } + } + public static class InvoiceWrapperHelperExtension + { + public static DIHelper AddInvoiceWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddCurrencyProviderService() + .AddSettingsManagerService() + .AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService() + .AddInvoiceStatusWrapperHelperService(); + } + } + + /// + /// Invoice Item + /// + [DataContract(Name = "invoiceItem", Namespace = "")] + public class InvoiceItemWrapper + { + public InvoiceItemWrapper() + { + } [DataMember] public string Title { get; set; } @@ -243,10 +371,7 @@ public InvoiceItemWrapper(InvoiceItem invoiceItem) public CurrencyInfoWrapper Currency { get; set; } [DataMember] - public int Quantity { get; set; } - - [DataMember] - public int StockQuantity { get; set; } + public decimal StockQuantity { get; set; } [DataMember] public bool TrackInvenory { get; set; } @@ -269,6 +394,82 @@ public InvoiceItemWrapper(InvoiceItem invoiceItem) [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool CanDelete { get; set; } } + + public class InvoiceItemWrapperHelper + { + public InvoiceItemWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + DaoFactory daoFactory, + CurrencyInfoWrapperHelper currencyInfoWrapperHelper) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + SettingsManager = settingsManager; + CurrencyProvider = currencyProvider; + DaoFactory = daoFactory; + CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + } + + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public DaoFactory DaoFactory { get; } + public CurrencyProvider CurrencyProvider { get; } + public SettingsManager SettingsManager { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public CRMSecurity CRMSecurity { get; } + + public InvoiceItemWrapper Get(InvoiceItem invoiceItem) + { + var result = new InvoiceItemWrapper { + + Title = invoiceItem.Title, + StockKeepingUnit = invoiceItem.StockKeepingUnit, + Description = invoiceItem.Description, + Price = invoiceItem.Price, + StockQuantity = invoiceItem.StockQuantity, + TrackInvenory = invoiceItem.TrackInventory, + CreateOn = ApiDateTimeHelper.Get(invoiceItem.CreateOn), + CreateBy = EmployeeWraperHelper.Get(invoiceItem.CreateBy), + Currency = !String.IsNullOrEmpty(invoiceItem.Currency) ? + CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(invoiceItem.Currency)) : + CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency), + CanEdit = CRMSecurity.CanEdit(invoiceItem), + CanDelete = CRMSecurity.CanDelete(invoiceItem) + }; + + if (invoiceItem.InvoiceTax1ID > 0) + { + result.InvoiceTax1 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); + } + if (invoiceItem.InvoiceTax2ID > 0) + { + result.InvoiceTax2 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); + } + + + return result; + + } + + } + + public static class InvoiceItemWrapperHelperExtension + { + public static DIHelper AddInvoiceItemWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services.AddCurrencyProviderService() + .AddSettingsManagerService() + .AddApiDateTimeHelper() + .AddEmployeeWraper() + .AddCRMSecurityService(); + } + } /// /// Invoice Tax @@ -281,19 +482,6 @@ public InvoiceTaxWrapper() { } - public InvoiceTaxWrapper(InvoiceTax invoiceTax) - : base(invoiceTax.ID) - { - Name = invoiceTax.Name; - Description = invoiceTax.Description; - Rate = invoiceTax.Rate; - CreateOn = (ApiDateTime)invoiceTax.CreateOn; - CreateBy = EmployeeWraper.Get(invoiceTax.CreateBy); - CanEdit = CRMSecurity.CanEdit(invoiceTax); - CanDelete = CRMSecurity.CanDelete(invoiceTax); - } - - [DataMember(Name = "id")] public int Id { get; set; } @@ -319,30 +507,57 @@ public InvoiceTaxWrapper(InvoiceTax invoiceTax) public bool CanDelete { get; set; } } + public class InvoiceTaxWrapperHelper + { + public InvoiceTaxWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + } + + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public CRMSecurity CRMSecurity { get; } + + public InvoiceTaxWrapper Get(InvoiceTax invoiceTax) + { + return new InvoiceTaxWrapper + { + Id = invoiceTax.ID, + Name = invoiceTax.Name, + Description = invoiceTax.Description, + Rate = invoiceTax.Rate, + CreateOn = ApiDateTimeHelper.Get(invoiceTax.CreateOn), + CreateBy = EmployeeWraperHelper.Get(invoiceTax.CreateBy), + CanEdit = CRMSecurity.CanEdit(invoiceTax), + CanDelete = CRMSecurity.CanDelete(invoiceTax) + }; + } + } + + public static class InvoiceTaxWrapperHelperExtension + { + public static DIHelper AddInvoiceTaxWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } + } + /// /// Invoice Line /// [DataContract(Name = "invoiceLine", Namespace = "")] public class InvoiceLineWrapper { - public InvoiceLineWrapper(int id) - : base(id) + public InvoiceLineWrapper() { } - public InvoiceLineWrapper(InvoiceLine invoiceLine) - : base(invoiceLine.ID) - { - InvoiceID = invoiceLine.InvoiceID; - InvoiceItemID = invoiceLine.InvoiceItemID; - InvoiceTax1ID = invoiceLine.InvoiceTax1ID; - InvoiceTax2ID = invoiceLine.InvoiceTax2ID; - SortOrder = invoiceLine.SortOrder; - Description = invoiceLine.Description; - Quantity = invoiceLine.Quantity; - Price = invoiceLine.Price; - Discount = invoiceLine.Discount; - } [DataMember(Name = "id")] public int Id { get; set; } @@ -366,7 +581,7 @@ public InvoiceLineWrapper(InvoiceLine invoiceLine) public string Description { get; set; } [DataMember] - public int Quantity { get; set; } + public decimal Quantity { get; set; } [DataMember] public decimal Price { get; set; } @@ -376,17 +591,51 @@ public InvoiceLineWrapper(InvoiceLine invoiceLine) public static InvoiceLineWrapper GetSample() { - return new InvoiceLineWrapper(0) - { - Description = string.Empty, - Discount = (decimal)0.00, - InvoiceID = 0, - InvoiceItemID = 0, - InvoiceTax1ID = 0, - InvoiceTax2ID = 0, - Price = (decimal)0.00, - Quantity = 0 - }; + return new InvoiceLineWrapper + { + Description = string.Empty, + Discount = (decimal)0.00, + InvoiceID = 0, + InvoiceItemID = 0, + InvoiceTax1ID = 0, + InvoiceTax2ID = 0, + Price = (decimal)0.00, + Quantity = 0 + }; + } + } + + public class InvoiceLineWrapperHelper + { + public InvoiceLineWrapperHelper() + { + } + + public InvoiceLineWrapper Get(InvoiceLine invoiceLine) + { + return new InvoiceLineWrapper + { + Id = invoiceLine.ID, + InvoiceID = invoiceLine.InvoiceID, + InvoiceItemID = invoiceLine.InvoiceItemID, + InvoiceTax1ID = invoiceLine.InvoiceTax1ID, + InvoiceTax2ID = invoiceLine.InvoiceTax2ID, + SortOrder = invoiceLine.SortOrder, + Description = invoiceLine.Description, + Quantity = invoiceLine.Quantity, + Price = invoiceLine.Price, + Discount = invoiceLine.Discount + }; + } + } + + public static class InvoiceLineWrapperHelperExtension + { + public static DIHelper AddInvoiceLineWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; } } @@ -398,19 +647,7 @@ public class InvoiceStatusWrapper { public InvoiceStatusWrapper() { - - } - public InvoiceStatusWrapper(int id) - : base(id) - { - Title = ((InvoiceStatus)id).ToLocalizedString(); - } - - public InvoiceStatusWrapper(InvoiceStatus status) - : base((int)status) - { - Title = status.ToLocalizedString(); } [DataMember(Name = "id")] @@ -418,6 +655,41 @@ public InvoiceStatusWrapper(InvoiceStatus status) [DataMember] public string Title { get; set; } + + public static InvoiceStatusWrapper GetSample() + { + return new InvoiceStatusWrapper + { + Id = (int)InvoiceStatus.Draft, + Title = InvoiceStatus.Draft.ToLocalizedString() + }; + } + + } + + public class InvoiceStatusWrapperHelper + { + public InvoiceStatusWrapperHelper() + { + } + + public InvoiceStatusWrapper Get(InvoiceStatus status) + { + return new InvoiceStatusWrapper + { + Id = (int)status, + Title = status.ToLocalizedString() + }; + } } + public static class InvoiceStatusWrapperHelperExtension + { + public static DIHelper AddInvoiceStatusWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } + } } diff --git a/products/ASC.CRM/Server/Model/ListItemWrapper.cs b/products/ASC.CRM/Server/Model/ListItemWrapper.cs index bed1051a6bc..ddeee9f4e70 100644 --- a/products/ASC.CRM/Server/Model/ListItemWrapper.cs +++ b/products/ASC.CRM/Server/Model/ListItemWrapper.cs @@ -25,6 +25,7 @@ using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM.Configuration; using System; @@ -390,8 +391,9 @@ public static TagWrapper GetSample() [DataContract(Name = "listItem", Namespace = "")] public abstract class ListItemWrapper { - protected ListItemWrapper(int id) + protected ListItemWrapper() { + } protected ListItemWrapper(ListItem listItem) diff --git a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs index eacb2244dd2..0c5faf0f89a 100644 --- a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs +++ b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs @@ -26,12 +26,16 @@ using ASC.Api.Core; using ASC.Common; +using ASC.Common.Web; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; namespace ASC.Api.CRM.Wrappers @@ -131,20 +135,31 @@ public class OpportunityWrapperHelper { public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity) + CRMSecurity cRMSecurity, + DaoFactory daoFactory, + CurrencyProvider currencyProvider, + ContactBaseWrapperHelper contactBaseWrapperHelper + ) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; + DaoFactory = daoFactory; + ContactBaseWrapperHelper = contactBaseWrapperHelper; + CurrencyProvider = currencyProvider; } + public CurrencyProvider CurrencyProvider {get;} + public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public DaoFactory DaoFactory { get; } + public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } public OpportunityWrapper Get(Deal deal) { - return new OpportunityWrapper + var dealWrapper = new OpportunityWrapper { Id = deal.ID, CreateBy = EmployeeWraperHelper.Get(deal.CreateBy), @@ -160,6 +175,45 @@ public OpportunityWrapper Get(Deal deal) ExpectedCloseDate = ApiDateTimeHelper.Get(deal.ExpectedCloseDate), CanEdit = CRMSecurity.CanEdit(deal) }; + + if (deal.ContactID > 0) + dealWrapper.Contact = ContactBaseWrapperHelper.Get(DaoFactory.GetContactDao().GetByID(deal.ContactID)); + + if (deal.DealMilestoneID > 0) + { + var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); + + if (dealMilestone == null) + throw new ItemNotFoundException(); + + dealWrapper.Stage = new DealMilestoneBaseWrapper(dealMilestone); + } + + dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal) + .Select(item => EmployeeWraperHelper.Get(item.Key)).ToItemList(); + + dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); + + if (!string.IsNullOrEmpty(deal.BidCurrency)) + dealWrapper.BidCurrency = ToCurrencyInfoWrapper(CurrencyProvider.Get(deal.BidCurrency)); + + dealWrapper.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); + + dealWrapper.Members = new List(); + + var memberIDs = DaoFactory.GetDealDao().GetMembers(deal.ID); + var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); + var membersWrapperList = new List(); + + foreach (var member in membersList) + { + if (member == null) continue; + membersWrapperList.Add(ContactBaseWrapperHelper.Get(member)); + } + + dealWrapper.Members = membersWrapperList; + + return dealWrapper; } } @@ -171,8 +225,10 @@ public static DIHelper AddOpportunityWrapperHelperService(this DIHelper services return services.AddApiDateTimeHelper() .AddEmployeeWraper() - .AddCRMSecurityService(); + .AddCRMSecurityService() + .AddDaoFactoryService() + .AddContactBaseWrapperHelperService() + .AddCurrencyProviderService(); } } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs index 85bffeac0eb..3acd87c085a 100644 --- a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs +++ b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs @@ -28,6 +28,7 @@ using ASC.Api.Documents; using ASC.Common; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.Web.Api.Models; using System; @@ -59,7 +60,6 @@ public static EntityWrapper GetSample() } } - [DataContract(Name = "historyEvent", Namespace = "")] public class RelationshipEventWrapper { @@ -113,22 +113,32 @@ public static RelationshipEventWrapper GetSample() public class RelationshipEventWrapperHelper { - public RelationshipEventWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public RelationshipEventWrapperHelper( + ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity) + ContactBaseWrapperHelper contactBaseWrapperHelper, + FileWrapperHelper fileWrapperHelper, + CRMSecurity cRMSecurity, + DaoFactory daoFactory) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; + DaoFactory = daoFactory; + ContactBaseWrapperHelper = contactBaseWrapperHelper; + FileWrapperHelper = fileWrapperHelper; } + public FileWrapperHelper FileWrapperHelper { get; } + public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) { - return new RelationshipEventWrapper + var result = new RelationshipEventWrapper { Id = relationshipEvent.ID, CreateBy = EmployeeWraperHelper.Get(relationshipEvent.CreateBy), @@ -137,6 +147,35 @@ public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) Files = new List>(), CanEdit = CRMSecurity.CanEdit(relationshipEvent) }; + + + var historyCategory = DaoFactory.GetListItemDao().GetByID(relationshipEvent.CategoryID); + + if (historyCategory != null) + { + result.Category = new HistoryCategoryBaseWrapper(historyCategory); + } + + if (relationshipEvent.EntityID > 0) + { + result.Entity = ToEntityWrapper(relationshipEvent.EntityType, relationshipEvent.EntityID); + } + + result.Files = DaoFactory.GetRelationshipEventDao().GetFiles(relationshipEvent.ID).ConvertAll(file => FileWrapperHelper.Get(file)); + + if (relationshipEvent.ContactID > 0) + { + var relativeContact = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); + if (relativeContact != null) + { + result.Contact = ContactBaseWrapperHelper.Get(relativeContact); + } + } + + result.CanEdit = CRMSecurity.CanAccessTo(relationshipEvent); + + return result; + } } @@ -148,7 +187,9 @@ public static DIHelper AddRelationshipEventWrapperHelperService(this DIHelper se return services.AddApiDateTimeHelper() .AddEmployeeWraper() - .AddCRMSecurityService(); + .AddCRMSecurityService() + .AddContactBaseWrapperHelperService() + .AddFileWrapperHelperService(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/TaskWrapper.cs b/products/ASC.CRM/Server/Model/TaskWrapper.cs index 1386d2c6055..931844ed8f3 100644 --- a/products/ASC.CRM/Server/Model/TaskWrapper.cs +++ b/products/ASC.CRM/Server/Model/TaskWrapper.cs @@ -169,14 +169,17 @@ public class TaskWrapperHelper public TaskWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, - DaoFactory daoFactory) + DaoFactory daoFactory, + ContactBaseWrapperHelper contactBaseWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; DaoFactory = daoFactory; + ContactBaseWrapperHelper = contactBaseWrapperHelper; } + public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } @@ -201,7 +204,7 @@ public TaskWrapper Get(Task task) if (task.ContactID > 0) { - result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(task.ContactID)); + result.Contact = ContactBaseWrapperHelper.Get(DaoFactory.GetContactDao().GetByID(task.ContactID)); } if (task.EntityID > 0) From a6d618ce96dfd3c605077272cd8d4da41eb82538 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 22 Apr 2020 23:46:49 +0300 Subject: [PATCH 14/61] crm: migrate Api to EF Core --- products/ASC.CRM/Server/ASC.CRM.csproj | 15 - .../Server/Classes/ContactPhotoManager.cs | 11 + .../Server/Classes/TwilioController.cs | 10 +- .../Server/Controllers/CRMController.Cases.cs | 2 +- .../Controllers/CRMController.ContactInfo.cs | 22 +- .../Controllers/CRMController.Contacts.cs | 459 +++++++++--------- .../Controllers/CRMController.Invoices.cs | 2 +- .../CRMController.RelationshipEvent.cs | 121 ++--- .../Controllers/CRMController.TaskTemplate.cs | 10 +- .../Server/Controllers/CRMController.Tasks.cs | 31 +- .../Server/Controllers/CRMController.Voip.cs | 40 +- .../Server/Controllers/CRMController.cs | 29 +- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 8 +- .../Server/Core/Search/ContactsWrapper.cs | 4 +- .../ASC.CRM/Server/Core/Search/InfoWrapper.cs | 2 +- .../HttpHandlers/ContactPhotoHandler.cs | 18 +- .../Server/HttpHandlers/FileHandler.ashx.cs | 140 +++--- .../HttpHandlers/FileUploaderHandler.cs | 54 ++- .../HttpHandlers/OrganisationLogoHandler.cs | 71 ++- products/ASC.CRM/Server/Model/CasesWrapper.cs | 6 +- .../Server/Model/ContactInfoWrapper.cs | 1 + .../ASC.CRM/Server/Model/ContactWrapper.cs | 414 +++++++--------- .../ASC.CRM/Server/Model/InvoiceWrapper.cs | 48 +- .../ASC.CRM/Server/Model/ListItemWrapper.cs | 26 +- .../Server/Model/OpportunityWrapper.cs | 10 +- .../Server/Model/RelationshipEventWrapper.cs | 78 ++- products/ASC.CRM/Server/Model/TaskWrapper.cs | 64 +-- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 226 ++++----- products/ASC.CRM/Server/Utils/MailSender.cs | 311 ++++++------ .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 1 + 30 files changed, 1211 insertions(+), 1023 deletions(-) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index cc863371c15..78792265552 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -25,20 +25,6 @@ - - - - - - - - - - - - - - @@ -190,7 +176,6 @@ - diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs index 920a27c17d9..64bf0581b6f 100644 --- a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Threading.Workers; @@ -674,4 +675,14 @@ public class PhotoData #endregion } + + public static class ContactPhotoManagerExtension + { + public static DIHelper AddContactPhotoManagerService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/TwilioController.cs b/products/ASC.CRM/Server/Classes/TwilioController.cs index 6ecd3635bd3..e877c3a7ad2 100644 --- a/products/ASC.CRM/Server/Classes/TwilioController.cs +++ b/products/ASC.CRM/Server/Classes/TwilioController.cs @@ -55,7 +55,7 @@ namespace ASC.Web.CRM.Classes { - [ServiceFilter(typeof(ValidateRequestAttribute))] + [ServiceFilter(typeof(ValidateRequestFilter))] public class TwilioController : ApiController { public TwilioController(IOptionsMonitor logger, @@ -515,9 +515,9 @@ internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) internal VoiceResponse VoiceMail() { return GetTwilioResponseHelper().VoiceMail(); } } - public class ValidateRequestAttribute : ActionFilterAttribute + public class ValidateRequestFilter : ActionFilterAttribute { - public ValidateRequestAttribute(ConsumerFactory consumerFactory, IHttpContextAccessor httpContextAccessor) + public ValidateRequestFilter(ConsumerFactory consumerFactory, IHttpContextAccessor httpContextAccessor) { ConsumerFactory = consumerFactory; HttpContext = httpContextAccessor?.HttpContext; @@ -566,11 +566,11 @@ public static DIHelper AddTwilioVoiceRequestService(this DIHelper services) } - public static class ValidateRequestAttributeExtension + public static class ValidateRequestFilterExtension { public static DIHelper AddValidateRequestAttributeService(this DIHelper services) { - services.TryAddScoped(); + services.TryAddScoped(); return services.AddConsumerFactoryService(); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs index 4137a587bed..0799c4467bb 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs @@ -705,7 +705,7 @@ private IEnumerable ToListCasesWrappers(ICollection items) var contacts = DaoFactory .GetContactDao() .GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, ToContactBaseWrapper); + .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); foreach (var cases in items) { diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs index 622b4a8875b..5cd4105c7ef 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs @@ -93,7 +93,7 @@ public IEnumerable GetContactInfo(int contactid) return DaoFactory.GetContactInfoDao().GetList(contactid, null, null, null) .OrderByDescending(info => info.ID) .ToList() - .ConvertAll(ToContactInfoWrapper); + .ConvertAll(x => ContactInfoWrapperHelper.Get(x)); } /// @@ -117,7 +117,7 @@ public ContactInfoWrapper GetContactInfoByID(int contactid, int id) if (contactInfo == null || contactInfo.ContactID != contactid) throw new ArgumentException(); - return ToContactInfoWrapper(contactInfo); + return ContactInfoWrapperHelper.Get(contactInfo); } /// @@ -177,7 +177,9 @@ public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoT var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - var contactInfoWrapper = ToContactInfoWrapper(contactInfo); + + var contactInfoWrapper = ContactInfoWrapperHelper.Get(contactInfo); + contactInfoWrapper.Id = contactInfoID; return contactInfoWrapper; @@ -235,7 +237,7 @@ public ContactInfoWrapper CreateContactInfoAddress(int contactid, Address addres var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - return ToContactInfoWrapper(contactInfo); + return ContactInfoWrapperHelper.Get(contactInfo); } /// @@ -346,7 +348,8 @@ public ContactInfoWrapper UpdateContactInfo(int id, int contactid, ContactInfoTy var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - var contactInfoWrapper = ToContactInfoWrapper(contactInfo); + var contactInfoWrapper = ContactInfoWrapperHelper.Get(contactInfo); + return contactInfoWrapper; } @@ -402,7 +405,7 @@ public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Addres var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - return ToContactInfoWrapper(contactInfo); + return ContactInfoWrapperHelper.Get(contactInfo); } /// @@ -499,7 +502,7 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); if (contactInfo == null) throw new ItemNotFoundException(); - var wrapper = ToContactInfoWrapper(contactInfo); + var wrapper = ContactInfoWrapperHelper.Get(contactInfo); DaoFactory.GetContactInfoDao().Delete(id); @@ -508,15 +511,14 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) if (contactInfo.InfoType == ContactInfoType.Email) { - FactoryIndexer.DeleteAsync(EmailWrapper.ToEmailWrapper(contact, new List { contactInfo})); + FactoryIndexerEmailWrapper.DeleteAsync(EmailWrapper.GetEmailWrapper(TenantManager.CurrentTenant.TenantId, contact, new List { contactInfo})); } - FactoryIndexer.DeleteAsync(contactInfo); + FactoryIndexerInfoWrapper.DeleteAsync(InfoWrapper.Get(ServiceProvider, contactInfo)); return wrapper; } - private static ContactInfo FromContactInfoWrapper(ContactInfoWrapper contactInfoWrapper) { return new ContactInfo diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs index 751e1b552c0..aecd1157b1b 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs @@ -39,6 +39,7 @@ using ASC.Web.CRM.Classes; using ASC.Web.Studio.Core; using Autofac; +using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Linq; @@ -67,7 +68,7 @@ public ContactWrapper GetContactByID(int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return ToContactWrapper(contact); + return ContactWrapperHelper.GetContactWrapper(contact); } public IEnumerable GetContactsByID(IEnumerable contactid) @@ -533,7 +534,7 @@ public IEnumerable GetContactsForMail(IEnumerable ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); return result; } @@ -582,7 +583,7 @@ public IEnumerable DeleteBatchContacts( MessageService.Send( MessageAction.ContactsDeleted, MessageTarget.Create(contacts.Select(c => c.ID)), contacts.Select(c => c.GetTitle())); - return contacts.Select(ToContactBaseWrapper); + return contacts.Select(x => ContactWrapperHelper.GetContactBaseWrapper(x)); } @@ -633,7 +634,7 @@ public PersonWrapper AddPeopleToCompany(int companyid, int personid) MessageService.Send( MessageAction.CompanyLinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); - return (PersonWrapper)ToContactWrapper(person); + return (PersonWrapper)ContactWrapperHelper.GetContactWrapper(person); } /// @@ -661,7 +662,7 @@ public PersonWrapper DeletePeopleFromCompany(int companyid, int personid) MessageService.Send( MessageAction.CompanyUnlinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); - return (PersonWrapper)ToContactWrapper(person); + return (PersonWrapper)ContactWrapperHelper.GetContactWrapper(person); } /// @@ -690,7 +691,7 @@ public PersonWrapper CreatePerson( ShareType shareType, IEnumerable managerList, IEnumerable> customFieldList, - IEnumerable photo) + IEnumerable photo) { if (companyId > 0) { var company = DaoFactory.GetContactDao().GetByID(companyId); @@ -726,9 +727,10 @@ public PersonWrapper CreatePerson( } } - var wrapper = (PersonWrapper)ToContactWrapper(peopleInst); + var wrapper = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); + + var photoList = photo != null ? photo.ToList() : new List(); - var photoList = photo != null ? photo.ToList() : new List(); if (photoList.Any()) { wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); @@ -751,29 +753,33 @@ public PersonWrapper CreatePerson( /// Path to contact photo /// [Update(@"contact/{contactid:int}/changephoto")] - public string ChangeContactPhoto(int contactid, IEnumerable photo) + public string ChangeContactPhoto(int contactid, IEnumerable photo) { if (contactid <= 0) throw new ArgumentException(); var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); var firstPhoto = photo != null ? photo.FirstOrDefault() : null; + if (firstPhoto == null) throw new ArgumentException(); - if (firstPhoto.ContentLength == 0 || + var fileStream = firstPhoto.OpenReadStream(); + + if (firstPhoto.Length == 0 || !firstPhoto.ContentType.StartsWith("image/") || - !firstPhoto.InputStream.CanRead) + !fileStream.CanRead) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); if (SetupInfo.MaxImageUploadSize > 0 && - SetupInfo.MaxImageUploadSize < firstPhoto.ContentLength) + SetupInfo.MaxImageUploadSize < firstPhoto.Length) throw new Exception(FileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false)); - return ContactPhotoManager.UploadPhoto(firstPhoto.InputStream, contactid, false).Url; + return ContactPhotoManager.UploadPhoto(fileStream, contactid, false).Url; } /// @@ -829,7 +835,7 @@ public ContactWrapper MergeContacts(int fromcontactid, int tocontactid) var messageAction = resultContact is Person ? MessageAction.PersonsMerged : MessageAction.CompaniesMerged; MessageService.Send( messageAction, MessageTarget.Create(new[] { fromContact.ID, toContact.ID }), fromContact.GetTitle(), toContact.GetTitle()); - return ToContactWrapper(resultContact); + return ContactWrapperHelper.GetContactWrapper(resultContact); } /// @@ -861,7 +867,7 @@ public PersonWrapper UpdatePerson( ShareType shareType, IEnumerable managerList, IEnumerable> customFieldList, - IEnumerable photo) + IEnumerable photo) { if (personid <= 0 || string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) throw new ArgumentException(); @@ -896,9 +902,10 @@ public PersonWrapper UpdatePerson( } } - var wrapper = (PersonWrapper)ToContactWrapper(peopleInst); + var wrapper = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); + + var photoList = photo != null ? photo.ToList() : new List(); - var photoList = photo != null ? photo.ToList() : new List(); if (photoList.Any()) { wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); @@ -931,7 +938,7 @@ public CompanyWrapper CreateCompany( ShareType shareType, IEnumerable managerList, IEnumerable> customFieldList, - IEnumerable photo) + IEnumerable photo) { var companyInst = new Company { @@ -971,9 +978,9 @@ public CompanyWrapper CreateCompany( } } - var wrapper = (CompanyWrapper)ToContactWrapper(companyInst); + var wrapper = (CompanyWrapper)ContactWrapperHelper.GetContactWrapper(companyInst); - var photoList = photo != null ? photo.ToList() : new List(); + var photoList = photo != null ? photo.ToList() : new List(); if (photoList.Any()) { wrapper.SmallFotoUrl = ChangeContactPhoto(companyInst.ID, photoList); @@ -1025,7 +1032,7 @@ public IEnumerable CreateCompany(IEnumerable company CRMSecurity.SetAccessTo(ct, selectedManagers); } - return contacts.ConvertAll(ToContactBaseWrapper); + return contacts.ConvertAll(x => ContactWrapperHelper.GetContactBaseWrapper(x)); } /// @@ -1078,7 +1085,7 @@ public IEnumerable CreatePerson(IEnumerable x.ID)), contacts.Select(x => x.GetTitle())); - return contacts.ConvertAll(ToContactBaseWrapper); + return contacts.ConvertAll(x => ContactWrapperHelper.GetContactBaseWrapper(x)); } /// @@ -1135,7 +1142,7 @@ public CompanyWrapper UpdateCompany( MessageService.Send( MessageAction.CompanyUpdated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return (CompanyWrapper)ToContactWrapper(companyInst); + return (CompanyWrapper)ContactWrapperHelper.GetContactWrapper(companyInst); } /// @@ -1174,7 +1181,7 @@ public ContactWrapper UpdateContactStatus(int contactid, int contactStatusid) var messageAction = companyInst is Company ? MessageAction.CompanyUpdatedTemperatureLevel : MessageAction.PersonUpdatedTemperatureLevel; MessageService.Send( messageAction, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return ToContactWrapper(companyInst); + return ContactWrapperHelper.GetContactWrapper(companyInst); } /// @@ -1221,10 +1228,10 @@ public ContactWrapper UpdateCompanyAndParticipantsStatus(int companyid, int cont dao.UpdateContactStatus(forUpdateStatus, contactStatusid); - MessageService.Send( MessageAction.CompanyUpdatedTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - MessageService.Send( MessageAction.CompanyUpdatedPersonsTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + MessageService.Send(MessageAction.CompanyUpdatedTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + MessageService.Send(MessageAction.CompanyUpdatedPersonsTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return ToContactWrapper(companyInst); + return ContactWrapperHelper.GetContactWrapper(companyInst); } /// @@ -1295,7 +1302,7 @@ public ContactWrapper UpdatePersonAndItsCompanyStatus(int personid, int contactS MessageService.Send( MessageAction.PersonUpdatedCompanyTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); personInst = dao.GetByID(personInst.ID); - return ToContactWrapper(personInst); + return ContactWrapperHelper.GetContactWrapper(personInst); } /// @@ -1350,7 +1357,8 @@ public ContactWrapper SetAccessToContact(int contactid, bool isShared, IEnumerab SetAccessToContact(contact, isShared, managerList, false); - var wrapper = ToContactWrapper(contact); + var wrapper = ContactWrapperHelper.GetContactWrapper(contact); + return wrapper; } @@ -1492,7 +1500,7 @@ public ContactWrapper DeleteContact(int contactid) var messageAction = contact is Person ? MessageAction.PersonDeleted : MessageAction.CompanyDeleted; MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - return ToContactWrapper(contact); + return ContactWrapperHelper.GetContactWrapper(contact); } /// @@ -1514,7 +1522,7 @@ public IEnumerable DeleteBatchContacts(IEnumerable cont var contacts = DaoFactory.GetContactDao().DeleteBatchContact(contactids.ToArray()); MessageService.Send( MessageAction.ContactsDeleted, MessageTarget.Create(contactids), contacts.Select(c => c.GetTitle())); - return contacts.Select(ToContactBaseWrapper); + return contacts.Select(x => ContactWrapperHelper.GetContactBaseWrapper(x)); } /// @@ -1569,8 +1577,10 @@ public IEnumerable GetContactsByPrefix(string prefi } } } - result.AddRange(findedContacts.Select(ToContactBaseWithPhoneWrapper)); + result.AddRange(findedContacts.Select(x => ContactWrapperHelper.GetContactBaseWithPhoneWrapper(x))); + ApiContext.SetTotalCount(findedContacts.Count); + } else { @@ -1578,7 +1588,9 @@ public IEnumerable GetContactsByPrefix(string prefi if (searchType < -1 || searchType > 3) throw new ArgumentException(); allContacts = DaoFactory.GetContactDao().GetContactsByPrefix(prefix, searchType, 0, maxItemCount); - result.AddRange(allContacts.Select(ToContactBaseWithPhoneWrapper)); + + result.AddRange(allContacts.Select(x => ContactWrapperHelper.GetContactBaseWithPhoneWrapper(x))); + } return result; @@ -1603,102 +1615,102 @@ public IEnumerable GetContactsByContactInfo(ContactInfoType? inf var ids = DaoFactory.GetContactDao().GetContactIDsByContactInfo(infoType.Value, data, category, isPrimary); - var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(ToContactWrapper); + var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x=> ContactWrapperHelper.GetContactWrapper(x)); return result; } - /// - /// - /// - /// - /// - /// Contacts - /// - [Read(@"contact/{contactid:int}/tweets")] - public List GetUserTweets(int contactid, int count) - { - var MessageCount = 10; - var twitterAccounts = DaoFactory.GetContactInfoDao().GetList(contactid, ContactInfoType.Twitter, null, null); + ///// + ///// + ///// + ///// + ///// + ///// Contacts + ///// + //[Read(@"contact/{contactid:int}/tweets")] + //public List GetUserTweets(int contactid, int count) + //{ + // var MessageCount = 10; + // var twitterAccounts = DaoFactory.GetContactInfoDao().GetList(contactid, ContactInfoType.Twitter, null, null); - if (twitterAccounts.Count == 0) - throw new ResourceNotFoundException( - Newtonsoft.Json.JsonConvert.SerializeObject( - new - { - message = "", - description = CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter - } - )); + // if (twitterAccounts.Count == 0) + // throw new ResourceNotFoundException( + // Newtonsoft.Json.JsonConvert.SerializeObject( + // new + // { + // message = "", + // description = CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter + // } + // )); - var apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); - TwitterDataProvider twitterProvider = new TwitterDataProvider(apiInfo); + // var apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); + // TwitterDataProvider twitterProvider = new TwitterDataProvider(apiInfo); - List messages = new List(); + // List messages = new List(); - foreach (var twitterAccount in twitterAccounts) - { - try - { - messages.AddRange(twitterProvider.GetUserTweets(twitterAccount.ID, twitterAccount.Data, MessageCount)); - } - catch (ResourceNotFoundException ex) - { - throw new ResourceNotFoundException( - Newtonsoft.Json.JsonConvert.SerializeObject( - new - { - message = ex.Message, - description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) - } - )); - } - catch (Exception ex) - { - throw new Exception( - Newtonsoft.Json.JsonConvert.SerializeObject( - new - { - message = ex.Message, - description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) - } - )); - } - } + // foreach (var twitterAccount in twitterAccounts) + // { + // try + // { + // messages.AddRange(twitterProvider.GetUserTweets(twitterAccount.ID, twitterAccount.Data, MessageCount)); + // } + // catch (ResourceNotFoundException ex) + // { + // throw new ResourceNotFoundException( + // Newtonsoft.Json.JsonConvert.SerializeObject( + // new + // { + // message = ex.Message, + // description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) + // } + // )); + // } + // catch (Exception ex) + // { + // throw new Exception( + // Newtonsoft.Json.JsonConvert.SerializeObject( + // new + // { + // message = ex.Message, + // description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) + // } + // )); + // } + // } - return messages.OrderByDescending(m => m.PostedOn).Take(MessageCount).ToList(); + // return messages.OrderByDescending(m => m.PostedOn).Take(MessageCount).ToList(); - } + //} - /// - /// - /// - /// - /// Contacts - /// - [Read(@"contact/twitterprofile")] - public List FindTwitterProfiles(string searchText) - { - try - { - TwitterApiInfo apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); - if (apiInfo == null) - throw new SocialMediaAccountNotFound(CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter); - - TwitterDataProvider provider = new TwitterDataProvider(apiInfo); - List users = provider.FindUsers(searchText); - /*List users = new List(); - users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); - users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); - users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 });*/ - return users; - } - catch (Exception ex) { - throw new SocialMediaUI(DaoFactory).ProcessError(ex, "ASC.Api.CRM.CRMApi.FindTwitterProfiles"); - } - } + ///// + ///// + ///// + ///// + ///// Contacts + ///// + //[Read(@"contact/twitterprofile")] + //public List FindTwitterProfiles(string searchText) + //{ + // try + // { + // TwitterApiInfo apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); + // if (apiInfo == null) + // throw new SocialMediaAccountNotFound(CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter); + + // TwitterDataProvider provider = new TwitterDataProvider(apiInfo); + // List users = provider.FindUsers(searchText); + // /*List users = new List(); + // users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); + // users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); + // users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 });*/ + // return users; + // } + // catch (Exception ex) { + // throw new SocialMediaUI(DaoFactory).ProcessError(ex, "ASC.Api.CRM.CRMApi.FindTwitterProfiles"); + // } + //} /// /// @@ -1735,113 +1747,113 @@ public string DeleteContactAvatar(int contactId, string contactType, bool upload return ""; } - /// - /// - /// - /// - /// Contacts - /// - [Read(@"contact/{contactid:int}/socialmediaavatar")] - public List GetContactSMImages(int contactId) - { - return new SocialMediaUI(DaoFactory).GetContactSMImages(contactId); - } + ///// + ///// + ///// + ///// + ///// Contacts + ///// + //[Read(@"contact/{contactid:int}/socialmediaavatar")] + //public List GetContactSMImages(int contactId) + //{ + // return new SocialMediaUI(DaoFactory).GetContactSMImages(contactId); + //} - /// - /// - /// - /// - /// Contacts - /// - [Create(@"contact/socialmediaavatar")] - public List GetContactSMImagesByNetworks(List socialNetworks) - { - if (socialNetworks == null || socialNetworks.Count == 0) - { - return new List(); - } - var twitter = new List(); + ///// + ///// + ///// + ///// + ///// Contacts + ///// + //[Create(@"contact/socialmediaavatar")] + //public List GetContactSMImagesByNetworks(List socialNetworks) + //{ + // if (socialNetworks == null || socialNetworks.Count == 0) + // { + // return new List(); + // } + // var twitter = new List(); - foreach (var sn in socialNetworks) - { - if (sn.InfoType == ContactInfoType.Twitter) twitter.Add(sn.Data); - } + // foreach (var sn in socialNetworks) + // { + // if (sn.InfoType == ContactInfoType.Twitter) twitter.Add(sn.Data); + // } - return new SocialMediaUI(DaoFactory).GetContactSMImages(twitter); - } + // return new SocialMediaUI(DaoFactory).GetContactSMImages(twitter); + //} - /// - /// - /// - /// - /// - /// - /// - /// - /// Contacts - /// - [Update(@"contact/{contactid:int}/avatar")] - public ContactPhotoManager.PhotoData UploadUserAvatarFromSocialNetwork(int contactId, SocialNetworks socialNetwork, string userIdentity, bool uploadOnly, string tmpDirName) - { - if (socialNetwork != SocialNetworks.Twitter) - throw new ArgumentException(); + ///// + ///// + ///// + ///// + ///// + ///// + ///// + ///// + ///// Contacts + ///// + //[Update(@"contact/{contactid:int}/avatar")] + //public ContactPhotoManager.PhotoData UploadUserAvatarFromSocialNetwork(int contactId, SocialNetworks socialNetwork, string userIdentity, bool uploadOnly, string tmpDirName) + //{ + // if (socialNetwork != SocialNetworks.Twitter) + // throw new ArgumentException(); - if (contactId != 0) - { - var contact = DaoFactory.GetContactDao().GetByID(contactId); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + // if (contactId != 0) + // { + // var contact = DaoFactory.GetContactDao().GetByID(contactId); + // if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - if (!CRMSecurity.CanEdit(contact)) throw CRMSecurity.CreateSecurityException(); - } + // if (!CRMSecurity.CanEdit(contact)) throw CRMSecurity.CreateSecurityException(); + // } - if (socialNetwork == SocialNetworks.Twitter) - { - var provider = new TwitterDataProvider(TwitterApiHelper.GetTwitterApiInfoForCurrentUser()); - var imageUrl = provider.GetUrlOfUserImage(userIdentity, TwitterDataProvider.ImageSize.Original); - return UploadAvatar(contactId, imageUrl, uploadOnly, tmpDirName, false); - } + // if (socialNetwork == SocialNetworks.Twitter) + // { + // var provider = new TwitterDataProvider(TwitterApiHelper.GetTwitterApiInfoForCurrentUser()); + // var imageUrl = provider.GetUrlOfUserImage(userIdentity, TwitterDataProvider.ImageSize.Original); + // return UploadAvatar(contactId, imageUrl, uploadOnly, tmpDirName, false); + // } - return null; - } + // return null; + //} - /// false - [Create(@"contact/mailsmtp/send")] - public IProgressItem SendMailSMTPToContacts(List fileIDs, List contactIds, String subject, String body, bool storeInHistory) - { - if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); + ///// false + //[Create(@"contact/mailsmtp/send")] + //public IProgressItem SendMailSMTPToContacts(List fileIDs, List contactIds, String subject, String body, bool storeInHistory) + //{ + // if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()); - MessageService.Send(MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); + // var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()); + // MessageService.Send(MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); - return MailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); - } + // return MailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); + //} - /// false - [Create(@"contact/mailsmtp/preview")] - public string GetMailSMTPToContactsPreview(string template, int contactId) - { - if (contactId == 0 || String.IsNullOrEmpty(template)) throw new ArgumentException(); + ///// false + //[Create(@"contact/mailsmtp/preview")] + //public string GetMailSMTPToContactsPreview(string template, int contactId) + //{ + // if (contactId == 0 || String.IsNullOrEmpty(template)) throw new ArgumentException(); - var manager = new MailTemplateManager(DaoFactory); + // var manager = new MailTemplateManager(DaoFactory); - return manager.Apply(template, contactId); - } + // return manager.Apply(template, contactId); + //} - /// false - [Read(@"contact/mailsmtp/status")] - public IProgressItem GetMailSMTPToContactsStatus() - { - return MailSender.GetStatus(); - } + ///// false + //[Read(@"contact/mailsmtp/status")] + //public IProgressItem GetMailSMTPToContactsStatus() + //{ + // return MailSender.GetStatus(); + //} - /// false - [Update(@"contact/mailsmtp/cancel")] - public IProgressItem CancelMailSMTPToContacts() - { - var progressItem = MailSender.GetStatus(); - MailSender.Cancel(); - return progressItem; - } + ///// false + //[Update(@"contact/mailsmtp/cancel")] + //public IProgressItem CancelMailSMTPToContacts() + //{ + // var progressItem = MailSender.GetStatus(); + // MailSender.Cancel(); + // return progressItem; + //} /// false [Update(@"contact/{contactid:int}/creationdate")] @@ -1923,12 +1935,12 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly if (peopleCompanyIDs.Count > 0) { - var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ToContactBaseWrapperQuick(item)); + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactWrapperHelper.GetContactBaseWrapperQuick(item)); var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); foreach (var contactBaseWrapperQuick in tmpList) { - contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.ID]; + contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.Id]; peopleCompanyList.Add(contactBaseWrapperQuick.Id, contactBaseWrapperQuick); } } @@ -1958,11 +1970,11 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly { if (!contactInfos.ContainsKey(item.ContactID)) { - contactInfos.Add(item.ContactID, new List {new ContactInfoWrapper(item)}); + contactInfos.Add(item.ContactID, new List {ContactInfoWrapperHelper.Get(item)}); } else { - contactInfos[item.ContactID].Add(new ContactInfoWrapper(item)); + contactInfos[item.ContactID].Add(ContactInfoWrapperHelper.Get(item)); } } } @@ -1986,7 +1998,7 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly { var people = person; - var peopleWrapper = PersonWrapper.ToPersonWrapperQuick(people); + var peopleWrapper = ContactWrapperHelper.GetPersonWrapperQuick(people); if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) { @@ -2000,7 +2012,7 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly var company = contact as Company; if (company != null) { - contactWrapper = CompanyWrapper.ToCompanyWrapperQuick(company); + contactWrapper = ContactWrapperHelper.GetCompanyWrapperQuick(company); } else { @@ -2015,11 +2027,12 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly if (nearestTasks.ContainsKey(contactWrapper.Id)) { var task = nearestTasks[contactWrapper.Id]; - taskWrapper = new TaskBaseWrapper(task); + + taskWrapper = TaskWrapperHelper.GetTaskBaseWrapper(task); if (task.CategoryID > 0) { - taskWrapper.Category = taskCategories.First(x => x.ID == task.CategoryID); + taskWrapper.Category = taskCategories.First(x => x.Id == task.CategoryID); } } @@ -2038,7 +2051,7 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Contact.Id).ToArray()); foreach (var contactBaseWrapperQuick in result) { - contactBaseWrapperQuick.Contact.CanDelete = contactBaseWrapperQuick.Contact.CanEdit && resultListCanDelete[contactBaseWrapperQuick.Contact.ID]; + contactBaseWrapperQuick.Contact.CanDelete = contactBaseWrapperQuick.Contact.CanEdit && resultListCanDelete[contactBaseWrapperQuick.Contact.Id]; } } @@ -2091,11 +2104,11 @@ private IEnumerable ToListContactWrapper(IReadOnlyList if (peopleCompanyIDs.Count > 0) { - var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ToContactBaseWrapperQuick(item)); + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactWrapperHelper.GetContactBaseWrapperQuick(item)); var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); foreach (var contactBaseWrapperQuick in tmpList) { - contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.ID]; + contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.Id]; peopleCompanyList.Add(contactBaseWrapperQuick.Id, contactBaseWrapperQuick); } } @@ -2134,9 +2147,9 @@ private IEnumerable ToListContactWrapper(IReadOnlyList else { if (!contactInfos.ContainsKey(item.ContactID)) - contactInfos.Add(item.ContactID, new List {new ContactInfoWrapper(item)}); + contactInfos.Add(item.ContactID, new List { ContactInfoWrapperHelper.Get(item)}); else - contactInfos[item.ContactID].Add(new ContactInfoWrapper(item)); + contactInfos[item.ContactID].Add(ContactInfoWrapperHelper.Get(item)); } } ); @@ -2151,7 +2164,7 @@ private IEnumerable ToListContactWrapper(IReadOnlyList { var people = person; - var peopleWrapper = PersonWrapper.ToPersonWrapperQuick(people); + var peopleWrapper = ContactWrapperHelper.GetPersonWrapperQuick(people); if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) { @@ -2165,7 +2178,7 @@ private IEnumerable ToListContactWrapper(IReadOnlyList var company = contact as Company; if (company != null) { - contactWrapper = CompanyWrapper.ToCompanyWrapperQuick(company); + contactWrapper = ContactWrapperHelper.GetCompanyWrapperQuick(company); if (companiesMembersCount.ContainsKey(contactWrapper.Id)) { @@ -2211,7 +2224,7 @@ private IEnumerable ToListContactWrapper(IReadOnlyList var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Id).ToArray()); foreach (var contactBaseWrapperQuick in result) { - contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && resultListCanDelete[contactBaseWrapperQuick.ID]; + contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && resultListCanDelete[contactBaseWrapperQuick.Id]; } } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs index b9d65cd5535..981dad35dbe 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs @@ -1414,7 +1414,7 @@ private IEnumerable ToListInvoiceBaseWrappers(ICollection item.ConsigneeID)); var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper); + .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); foreach (var invoice in items) diff --git a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs index 6879fe1bef2..53ed913c388 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs @@ -36,6 +36,7 @@ using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Classes; using ASC.Web.Files.Utils; +using Microsoft.AspNetCore.Http; using System; using System.Collections; using System.Collections.Generic; @@ -229,64 +230,65 @@ public FileWrapper CreateTextFile(string entityType, int entityid, string t return result; } - ///// - ///// Upload file - ///// - ///// Upload file - ///// Files - ///// - ///// - /////
  • Single file upload. You should set Content-Type & Content-Disposition header to specify filename and content type, and send file in request body
  • - /////
  • Using standart multipart/form-data method
  • - ///// ]]> - /////
    - ///// Entity type - ///// Entity ID - ///// Request Input stream - ///// Content-Type Header - ///// Content-Disposition Header - ///// List of files when posted as multipart/form-data - ///// If True, upload documents in original formats as well - ///// - ///// File info - ///// - //[Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/upload")] - //public FileWrapper UploadFileInCRM( - // string entityType, - // int entityid, - // Stream file, - // ContentType contentType, - // ContentDisposition contentDisposition, - // IEnumerable files, - // bool storeOriginalFileFlag - // ) - //{ - // FilesSettings.StoreOriginalFilesSetting = storeOriginalFileFlag; - - // var folderid = GetRootFolderID(); - - // var fileNames = new List(); - - // FileWrapper uploadedFile = null; - // if (files != null && files.Any()) - // { - // //For case with multiple files - // foreach (var postedFile in files) - // { - // uploadedFile = SaveFile(folderid, postedFile.InputStream, postedFile.FileName); - // fileNames.Add(uploadedFile.Title); - // } - // } - // else if (file != null) - // { - // uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); - // fileNames.Add(uploadedFile.Title); - // } - - // return uploadedFile; - //} + /// + /// Upload file + /// + /// Upload file + /// Files + /// + /// + ///
  • Single file upload. You should set Content-Type & Content-Disposition header to specify filename and content type, and send file in request body
  • + ///
  • Using standart multipart/form-data method
  • + /// ]]> + ///
    + /// Entity type + /// Entity ID + /// Request Input stream + /// Content-Type Header + /// Content-Disposition Header + /// List of files when posted as multipart/form-data + /// If True, upload documents in original formats as well + /// + /// File info + /// + [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/upload")] + public FileWrapper UploadFileInCRM( + string entityType, + int entityid, + Stream file, + ContentType contentType, + ContentDisposition contentDisposition, + IEnumerable files, + bool storeOriginalFileFlag + ) + { + FilesSettings.StoreOriginalFilesSetting = storeOriginalFileFlag; + + var folderid = GetRootFolderID(); + + var fileNames = new List(); + + FileWrapper uploadedFile = null; + if (files != null && files.Any()) + { + //For case with multiple files + foreach (var postedFile in files) + { + using var fileStream = postedFile.OpenReadStream(); + uploadedFile = SaveFile(folderid, fileStream, postedFile.FileName); + fileNames.Add(uploadedFile.Title); + } + } + else if (file != null) + { + uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); + fileNames.Add(uploadedFile.Title); + } + + return uploadedFile; + } private FileWrapper SaveFile(int folderid, Stream file, string fileName) { @@ -655,7 +657,7 @@ private IEnumerable ToListRelationshipEventWrapper(Lis var files = DaoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray()); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWrapper); + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); foreach (var item in itemList) { @@ -712,6 +714,7 @@ private EntityWrapper ToEntityWrapper(EntityType entityType, int entityID) break; case EntityType.Opportunity: var dealObj = DaoFactory.GetDealDao().GetByID(entityID); + if (dealObj == null) return null; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs b/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs index 289c630a6a9..e4123110ed8 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs @@ -340,11 +340,11 @@ protected TaskTemplateWrapper ToTaskTemplateWrapper(TaskTemplate taskTemplate) ContainerID = taskTemplate.ContainerID, DeadLineIsFixed = taskTemplate.DeadLineIsFixed, Description = taskTemplate.Description, - ID = taskTemplate.ID, + Id = taskTemplate.ID, isNotify = taskTemplate.isNotify, Title = taskTemplate.Title, OffsetTicks = taskTemplate.Offset.Ticks, - Responsible = EmployeeWraper.Get(taskTemplate.ResponsibleID) + Responsible = EmployeeWraperHelper.Get(taskTemplate.ResponsibleID) }; } @@ -362,12 +362,12 @@ protected IEnumerable ToTaskListTemplateContainerW { Title = item.Title, EntityType = item.EntityType.ToString(), - ID = item.ID + Id = item.ID }; - if (taskTemplateDictionary.ContainsKey(taskTemplateContainer.ID)) + if (taskTemplateDictionary.ContainsKey(taskTemplateContainer.Id)) { - taskTemplateContainer.Items = taskTemplateDictionary[taskTemplateContainer.ID]; + taskTemplateContainer.Items = taskTemplateDictionary[taskTemplateContainer.Id]; } result.Add(taskTemplateContainer); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs index 995a356e56c..bab78430414 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs @@ -1,6 +1,5 @@ using ASC.Api.Core; using ASC.Api.CRM.Wrappers; -using ASC.Common; using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Dao; @@ -9,10 +8,7 @@ using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; -using ASC.Web.CRM.Classes; using ASC.Web.CRM.Services.NotifyService; -using ASC.Web.Files.Services.WCFService; -using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; @@ -44,7 +40,7 @@ public TaskWrapper GetTaskByID(int taskid) throw CRMSecurity.CreateSecurityException(); } - return TaskWrapperHelper.Get(task); + return TaskWrapperHelper.GetTaskWrapper(task); } /// @@ -89,7 +85,7 @@ public IEnumerable GetAllTasks( OrderBy taskOrderBy; - if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out taskSortedByType)) + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out taskSortedByType)) { taskOrderBy = new OrderBy(taskSortedByType, !ApiContext.SortDescending); } @@ -190,7 +186,7 @@ public TaskWrapper ReOpenTask(int taskid) MessageService.Send(MessageAction.CrmTaskOpened, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.Get(task); + return TaskWrapperHelper.GetTaskWrapper(task); } @@ -214,7 +210,7 @@ public TaskWrapper CloseTask(int taskid) var task = DaoFactory.GetTaskDao().GetByID(taskid); MessageService.Send(MessageAction.CrmTaskClosed, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.Get(task); + return TaskWrapperHelper.GetTaskWrapper(task); } @@ -240,7 +236,7 @@ public TaskWrapper DeleteTask(int taskid) DaoFactory.GetTaskDao().DeleteTask(taskid); MessageService.Send(MessageAction.CrmTaskDeleted, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.Get(task); + return TaskWrapperHelper.GetTaskWrapper(task); } @@ -331,7 +327,7 @@ int alertValue MessageService.Send(MessageAction.CrmTaskCreated, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.Get(task); + return TaskWrapperHelper.GetTaskWrapper(task); } /// @@ -531,7 +527,7 @@ public TaskWrapper UpdateTask( MessageService.Send(MessageAction.CrmTaskUpdated, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.Get(task); + return TaskWrapperHelper.GetTaskWrapper(task); } /// false @@ -643,8 +639,8 @@ private IEnumerable ToTaskListWrapper(IEnumerable itemList) } var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => new TaskCategoryBaseWrapper(x)); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper); - var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper); + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); + var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); foreach (var item in itemList) { @@ -687,13 +683,4 @@ private IEnumerable ToTaskListWrapper(IEnumerable itemList) } - - - //public CRMController(CRMSecurity cRMSecurity, - // DaoFactory daoFactory, - // ApiContext apiContext, - // MessageTarget messageTarget, - // NotifyClient notifyClient, - // TaskWrapperHelper taskWrapperHelper) - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs index 7de012935ca..560b9c6d467 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs @@ -607,12 +607,15 @@ public VoipCallWrapper MakeCall(string to, string contactId) if (contact == null) { - contact = ToContactWrapper(VoipEngine.CreateContact(contactPhone)); + contact = ContactWrapperHelper.GetContactWrapper(VoipEngine.CreateContact(contactPhone)); } contact = GetContactWithFotos(contact); + var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); + return new VoipCallWrapper(call, contact); + } /// @@ -627,8 +630,11 @@ public VoipCallWrapper AnswerCall(string callId) var dao = DaoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); + number.AnswerQueueCall(call.Id); + return new VoipCallWrapper(call); + } /// @@ -784,7 +790,7 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, Client = client, ContactID = contactID, SortBy = ApiContext.SortBy, - SortOrder = !.ApiContext.SortDescending, + SortOrder = !ApiContext.SortDescending, SearchText = ApiContext.FilterValue, Offset = ApiContext.StartIndex, Max = ApiContext.Count, @@ -800,19 +806,28 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, r => { ContactWrapper contact; + if (r.ContactId != 0) { contact = r.ContactIsCompany - ? (ContactWrapper)new CompanyWrapper(r.ContactId) {DisplayName = r.ContactTitle} - : new PersonWrapper(r.ContactId) {DisplayName = r.ContactTitle}; - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany); + ? (ContactWrapper)new CompanyWrapper() {DisplayName = r.ContactTitle, Id = r.ContactId } + : new PersonWrapper() { + DisplayName = r.ContactTitle, + Id = r.ContactId + }; + + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + } else { - contact = new PersonWrapper(-1) { SmallFotoUrl = defaultSmallPhoto }; + contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } + return new VoipCallWrapper(r, contact); + }).ToList(); + return calls; } @@ -832,18 +847,23 @@ public IEnumerable GetMissedCalls() r => { ContactWrapper contact; + if (r.ContactId != 0) { contact = r.ContactIsCompany - ? (ContactWrapper)new CompanyWrapper(r.ContactId) { DisplayName = r.ContactTitle } - : new PersonWrapper(r.ContactId) { DisplayName = r.ContactTitle }; - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany); + ? (ContactWrapper)new CompanyWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId } + : new PersonWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId }; + + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + } else { - contact = new PersonWrapper(-1) { SmallFotoUrl = defaultSmallPhoto }; + contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } + return new VoipCallWrapper(r, contact); + }).ToList(); ApiContext.SetDataPaginated(); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Controllers/CRMController.cs index c1c2e10d36d..5f20bdd77fe 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.cs @@ -59,12 +59,11 @@ public CRMController(CRMSecurity cRMSecurity, IHttpContextAccessor httpContextAccessor, InvoiceSetting invoiceSetting, OrganisationLogoManager organisationLogoManager, - ContactBaseWrapperHelper contactBaseWrapperHelper, + ContactWrapperHelper contactBaseWrapperHelper, ContactPhotoManager contactPhotoManager, CommonLinkUtility commonLinkUtility, StorageFactory storageFactory, TenantUtil tenantUtil, - IVoipProvider voipProvider, SignalrServiceClient signalrServiceClient, VoipEngine voipEngine, @@ -85,16 +84,20 @@ public CRMController(CRMSecurity cRMSecurity, InvoiceBaseWrapperHelper invoiceBaseWrapperHelper, InvoiceLineWrapperHelper invoiceLineWrapperHelper, InvoiceTaxWrapperHelper invoiceTaxWrapperHelper, + ContactInfoWrapperHelper contactInfoWrapperHelper, + RelationshipEventWrapperHelper relationshipEventWrapperHelper, DocbuilderReportsUtility docbuilderReportsUtility, + FactoryIndexer factoryIndexerInfoWrapper, + FactoryIndexer factoryIndexerEmailWrapper, FactoryIndexer factoryIndexerCasesWrapper, FactoryIndexer factoryIndexerFieldsWrapper) { VoipEngine = voipEngine; SignalrServiceClient = signalrServiceClient; - // voipProvider = VoipDao.GetProvider(); + TenantUtil = tenantUtil; StorageFactory = storageFactory; @@ -118,8 +121,12 @@ public CRMController(CRMSecurity cRMSecurity, CurrencyRateWrapperHelper = currencyRateWrapperHelper; CasesWrapperHelper = casesWrapperHelper; ServiceProvider = serviceProvider; + FactoryIndexerCasesWrapper = factoryIndexerCasesWrapper; FactoryIndexerFieldsWrapper = factoryIndexerFieldsWrapper; + FactoryIndexerInfoWrapper = factoryIndexerInfoWrapper; + FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; + InvoiceWrapperHelper = invoiceWrapperHelper; InvoiceItemWrapperHelper = invoiceItemWrapperHelper; InvoiceBaseWrapperHelper = invoiceBaseWrapperHelper; @@ -145,10 +152,12 @@ public CRMController(CRMSecurity cRMSecurity, DocbuilderReportsUtility = docbuilderReportsUtility; InvoiceSetting = invoiceSetting; - ContactBaseWrapperHelper = contactBaseWrapperHelper; + ContactWrapperHelper = contactBaseWrapperHelper; } + public ContactInfoWrapperHelper ContactInfoWrapperHelper { get; } + public VoipEngine VoipEngine { get; } public SignalrServiceClient SignalrServiceClient { get; } public IVoipProvider VoipProvider { get; } @@ -156,7 +165,7 @@ public CRMController(CRMSecurity cRMSecurity, public StorageFactory StorageFactory { get; } public CommonLinkUtility CommonLinkUtility { get; } public ContactPhotoManager ContactPhotoManager { get; } - public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public ContactWrapperHelper ContactWrapperHelper { get; } public OrganisationLogoManager OrganisationLogoManager { get; } public InvoiceSetting InvoiceSetting { get; } public DocbuilderReportsUtility DocbuilderReportsUtility { get; } @@ -177,6 +186,10 @@ public CRMController(CRMSecurity cRMSecurity, public InvoiceBaseWrapperHelper InvoiceBaseWrapperHelper { get; } public InvoiceItemWrapperHelper InvoiceItemWrapperHelper { get; } public InvoiceWrapperHelper InvoiceWrapperHelper { get; } + + + public FactoryIndexer FactoryIndexerInfoWrapper { get; } + public FactoryIndexer FactoryIndexerEmailWrapper { get; } public FactoryIndexer FactoryIndexerFieldsWrapper { get; } public FactoryIndexer FactoryIndexerCasesWrapper { get; } public IServiceProvider ServiceProvider { get; } @@ -203,7 +216,6 @@ public CRMController(CRMSecurity cRMSecurity, public CRMSecurity CRMSecurity { get; } public DaoFactory DaoFactory { get; } - private static EntityType ToEntityType(string entityTypeStr) { EntityType entityType; @@ -235,6 +247,9 @@ private static EntityType ToEntityType(string entityTypeStr) return entityType; } + + + private string GetEntityTitle(EntityType entityType, int entityId, bool checkAccess, out DomainObject entity) { switch (entityType) @@ -242,7 +257,7 @@ private string GetEntityTitle(EntityType entityType, int entityId, bool checkAcc case EntityType.Contact: case EntityType.Company: case EntityType.Person: - var conatct = (entity = DaoFactory.GetContactDao().GetByID(entityId)) as Contact; + var conatct = (entity = DaoFactory.GetContactDao().GetByID(entityId)) as ASC.CRM.Core.Entities.Contact; if (conatct == null || (checkAccess && !CRMSecurity.CanAccessTo(conatct))) throw new ItemNotFoundException(); return conatct.GetTitle(); diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index ec08d054d18..aff0d2112a0 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -187,7 +187,7 @@ public virtual int Update(ContactInfo contactInfo) FactoryIndexerEmailWrapper.Update(new EmailWrapper { Id = contactInfo.ContactID, EmailInfoWrapper = infos.Select(r => EmailInfoWrapper.FromContactInfo(TenantID, r)).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); } - FactoryIndexerInfoWrapper.UpdateAsync(InfoWrapper.FromCompany(ServiceProvider, contactInfo)); + FactoryIndexerInfoWrapper.UpdateAsync(InfoWrapper.Get(ServiceProvider, contactInfo)); return result; } @@ -224,7 +224,7 @@ public int Save(ContactInfo contactInfo) contactInfo.ID = id; - FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.FromCompany(ServiceProvider, contactInfo)); + FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.Get(ServiceProvider, contactInfo)); if (contactInfo.InfoType == ContactInfoType.Email) { @@ -326,7 +326,7 @@ public int[] UpdateList(List items, Contact contact = null) foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) { - FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.FromCompany(ServiceProvider, item)); + FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.Get(ServiceProvider, item)); } } @@ -356,7 +356,7 @@ public int[] SaveList(List items, Contact contact = null) foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) { - FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.FromCompany(ServiceProvider, item)); + FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.Get(ServiceProvider, item)); } } diff --git a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs index a798e16b2f7..1f80c226dce 100644 --- a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs @@ -106,7 +106,5 @@ public static DIHelper AddContactsWrapperService(this DIHelper services) return services .AddFactoryIndexerService(); } - } - - + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs index c4bc51a094c..98518708c31 100644 --- a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs +++ b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs @@ -98,7 +98,7 @@ public string Data private string data; - public static InfoWrapper FromCompany(IServiceProvider serviceProvider, ContactInfo cf) + public static InfoWrapper Get(IServiceProvider serviceProvider, ContactInfo cf) { var logger = serviceProvider.GetService>(); var tenantManager = serviceProvider.GetService(); diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs index 638f8f246d6..31c9591f12e 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs @@ -48,15 +48,19 @@ public ContactPhotoHandler(SetupInfo setupInfo, CRMSecurity cRMSecurity, FileSizeComment fileSizeComment, WebItemSecurity webItemSecurity, - MessageTarget messageTarget) + MessageTarget messageTarget, + MessageService messageService) { SetupInfo = setupInfo; FileSizeComment = fileSizeComment; CRMSecurity = cRMSecurity; WebItemSecurity = webItemSecurity; MessageTarget = messageTarget; + MessageService = messageService; } + public MessageService MessageService { get; } + public DaoFactory DaoFactory { get; } public MessageTarget MessageTarget { get; } public WebItemSecurity WebItemSecurity { get; } public FileSizeComment FileSizeComment { get; } @@ -72,12 +76,10 @@ public FileUploadResult ProcessUpload(HttpContext context) Contact contact = null; if (contactId != 0) { - using (var scope = DIHelper.Resolve()) - { - contact = scope.Resolve().ContactDao.GetByID(contactId); - if (!CRMSecurity.CanEdit(contact)) - throw CRMSecurity.CreateSecurityException(); - } + contact = DaoFactory.GetContactDao().GetByID(contactId); + + if (!CRMSecurity.CanEdit(contact)) + throw CRMSecurity.CreateSecurityException(); } var fileUploadResult = new FileUploadResult(); @@ -135,7 +137,7 @@ public FileUploadResult ProcessUpload(HttpContext context) if (contact != null) { var messageAction = contact is Company ? MessageAction.CompanyUpdatedPhoto : MessageAction.PersonUpdatedPhoto; - MessageService.Send(context.Request, messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); } return fileUploadResult; diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs index e4dc0fc76ea..fbb9505e681 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs @@ -24,112 +24,104 @@ */ +using ASC.Common; +using ASC.Common.Logging; using ASC.CRM.Resources; using ASC.Web.CRM.Classes; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using System; using System.IO; +using System.Threading.Tasks; namespace ASC.Web.CRM.HttpHandlers { - public class FileHandler + public class FileHandler { - public FileHandler(Global global) + public FileHandler(RequestDelegate next, + Global global, + ContactPhotoManager contactPhotoManager, + IOptionsMonitor logger) { + _next = next; Global = global; + ContactPhotoManager = contactPhotoManager; + Logger = logger.Get("ASC"); } + public ILog Logger { get; } + public ContactPhotoManager ContactPhotoManager { get; } public Global Global { get; } - public void ProcessRequest(HttpContext context) + private readonly RequestDelegate _next; + + public async Task InvokeAsync(HttpContext context) { var action = context.Request.Query["action"]; switch (action) { case "contactphotoulr": - ResponceContactPhotoUrl(context); + { + var contactId = Convert.ToInt32(context.Request.Query["cid"]); + var isCompany = Convert.ToBoolean(context.Request.Query["isc"]); + var photoSize = Convert.ToInt32(context.Request.Query["ps"]); + + string photoUrl = string.Empty; + + switch (photoSize) + { + case 1: + photoUrl = ContactPhotoManager.GetSmallSizePhoto(contactId, isCompany); + break; + case 2: + photoUrl = ContactPhotoManager.GetMediumSizePhoto(contactId, isCompany); + break; + case 3: + photoUrl = ContactPhotoManager.GetBigSizePhoto(contactId, isCompany); + break; + default: + throw new Exception(CRMErrorsResource.ContactPhotoSizeUnknown); + } + + context.Response.Clear(); + + await context.Response.WriteAsync(photoUrl); + } break; case "mailmessage": - ResponceMailMessageContent(context); - break; - default: - throw new ArgumentException(String.Format("action='{0}' is not defined", action)); - } - } + { + var messageId = Convert.ToInt32(context.Request.Query["message_id"]); - private void ResponceContactPhotoUrl(HttpContext context) - { - var contactId = Convert.ToInt32(context.Request.Query["cid"]); - var isCompany = Convert.ToBoolean(context.Request.Query["isc"]); - var photoSize = Convert.ToInt32(context.Request.Query["ps"]); + var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); - String photoUrl = String.Empty; + string messageContent = string.Empty; - switch (photoSize) - { - case 1: - photoUrl = ContactPhotoManager.GetSmallSizePhoto(contactId, isCompany); - break; - case 2: - photoUrl = ContactPhotoManager.GetMediumSizePhoto(contactId, isCompany); - break; - case 3: - photoUrl = ContactPhotoManager.GetBigSizePhoto(contactId, isCompany); - break; - default: - throw new Exception(CRMErrorsResource.ContactPhotoSizeUnknown); - } + using (var streamReader = new StreamReader(Global.GetStore().GetReadStream("mail_messages", filePath))) + { + messageContent = streamReader.ReadToEnd(); + } - context.Response.Clear(); - context.Response.Write(photoUrl); + context.Response.Clear(); - try - { - context.Response.Flush(); - context.Response.SuppressContent = true; - context.ApplicationInstance.CompleteRequest(); - } - catch (HttpException ex) - { - LogManager.GetLogger("ASC").Error("ResponceContactPhotoUrl", ex); + await context.Response.WriteAsync(messageContent); + } + break; + default: + throw new ArgumentException(String.Format("action='{0}' is not defined", action)); } } + } - private void ResponceMailMessageContent(HttpContext context) - { - var messageId = Convert.ToInt32(context.Request.Query["message_id"]); - - var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); - - String messageContent = String.Empty; - - using (var streamReader = new StreamReader(Global.GetStore().GetReadStream("mail_messages", filePath))) - { - messageContent = streamReader.ReadToEnd(); - } - - context.Response.Clear(); - context.Response.Write(messageContent); - - try - { - context.Response.Flush(); - context.Response.SuppressContent = true; - context.ApplicationInstance.CompleteRequest(); - } - catch (HttpException ex) - { - LogManager.GetLogger("ASC").Error("ResponceMailMessageContent", ex); - } - } - public bool IsReusable + public static class FileHandlerExtension + { + public static DIHelper AddFileHandlerService(this DIHelper services) { - get - { - return false; - } + services.TryAddTransient(); + + return services.AddGlobalService() + .AddContactPhotoManagerService(); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs index 033861fb82a..dd2e14e85e5 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs @@ -26,21 +26,39 @@ using ASC.CRM.Core.Dao; using ASC.CRM.Resources; -using ASC.Web.CRM.Core; +using ASC.Files.Core; using ASC.Web.Studio.Core; -using Autofac; +using ASC.Web.Studio.UserControls.Statistics; +using ASC.Web.Studio.Utility; using Microsoft.AspNetCore.Http; using System; +using Microsoft.Extensions.DependencyInjection; namespace ASC.Web.CRM.Classes { public class FileUploaderHandler : FileUploadHandler { - public FileUploaderHandler(SetupInfo setupInfo) + public FileUploaderHandler(SetupInfo setupInfo, + DaoFactory daoFactory, + FileSizeComment fileSizeComment, + IServiceProvider serviceProvider, + TenantExtra tenantExtra, + TenantStatisticsProvider tenantStatisticsProvider) { SetupInfo = setupInfo; + DaoFactory = daoFactory; + FileSizeComment = fileSizeComment; + ServiceProvider = serviceProvider; + TenantExtra = tenantExtra; + TenantStatisticsProvider = tenantStatisticsProvider; + } + public TenantExtra TenantExtra { get; } + public TenantStatisticsProvider TenantStatisticsProvider { get; } + public IServiceProvider ServiceProvider { get; } + public FileSizeComment FileSizeComment { get; } + public DaoFactory DaoFactory { get; } public SetupInfo SetupInfo { get; } public override FileUploadResult ProcessUpload(HttpContext context) @@ -54,33 +72,29 @@ public override FileUploadResult ProcessUpload(HttpContext context) if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); - if (0 < SetupInfo.MaxUploadSize && SetupInfo.MaxUploadSize < file.ContentLength) + if (0 < SetupInfo.MaxUploadSize(TenantExtra, TenantStatisticsProvider) && SetupInfo.MaxUploadSize(TenantExtra, TenantStatisticsProvider) < file.ContentLength) throw FileSizeComment.FileSizeException; var fileName = file.FileName.LastIndexOf('\\') != -1 ? file.FileName.Substring(file.FileName.LastIndexOf('\\') + 1) : file.FileName; - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var document = new File - { - Title = fileName, - FolderID = daoFactory.FileDao.GetRoot(), - ContentLength = file.ContentLength - }; + var document = ServiceProvider.GetService>(); - document = daoFactory.FileDao.SaveFile(document, file.InputStream); + document.Title = fileName; + document.FolderID = DaoFactory.GetFileDao().GetRoot(); + document.ContentLength = file.ContentLength; - fileUploadResult.Data = document.ID; - fileUploadResult.FileName = document.Title; - fileUploadResult.FileURL = document.DownloadUrl; - fileUploadResult.Success = true; + document = DaoFactory.GetFileDao().SaveFile(document, file.InputStream); + fileUploadResult.Data = document.ID; + fileUploadResult.FileName = document.Title; + fileUploadResult.FileURL = document.DownloadUrl; + fileUploadResult.Success = true; + + + return fileUploadResult; - return fileUploadResult; - } } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs index 12899880736..e71d0bd0fe5 100644 --- a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs @@ -24,6 +24,7 @@ */ +using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Resources; using ASC.Web.Core.Files; @@ -31,7 +32,7 @@ using ASC.Web.Studio.Core; using Microsoft.AspNetCore.Http; using System; - +using System.IO; namespace ASC.Web.CRM.Classes { @@ -46,6 +47,8 @@ public OrganisationLogoHandler(CRMSecurity cRMSecurity, FileSizeComment = fileSizeComment; } + public OrganisationLogoManager OrganisationLogoManager { get; } + public ContactPhotoManager ContactPhotoManager { get; } public FileSizeComment FileSizeComment { get; } public SetupInfo SetupInfo { get; } public CRMSecurity CRMSecurity { get; } @@ -96,4 +99,70 @@ public FileUploadResult ProcessUpload(HttpContext context) } } } +} + + + +namespace ASC.Web.Studio.Controls.FileUploader +{ + public class FileToUpload + { + public string FileName { get; private set; } + public Stream InputStream { get; private set; } + public string FileContentType { get; private set; } + public long ContentLength { get; private set; } + public bool NeedSaveToTemp { get; private set; } + + public FileToUpload(HttpContext context) + { + if (IsHtml5Upload(context)) + { + FileName = GetFileName(context); + InputStream = context.Request.InputStream; + FileContentType = GetFileContentType(context); + ContentLength = (int)context.Request.InputStream.Length; + } + else + { + var file = context.Request.Files[0]; + FileName = file.FileName; + InputStream = file.InputStream; + FileContentType = file.ContentType; + ContentLength = file.ContentLength; + } + + NeedSaveToTemp = Convert.ToBoolean(GetNeedSaveToTemp(context)); + + if (string.IsNullOrEmpty(FileContentType)) + { + FileContentType = MimeMapping.GetMimeMapping(FileName) ?? string.Empty; + } + FileName = FileName.Replace("'", "_").Replace("\"", "_"); + } + + public static bool HasFilesToUpload(HttpContext context) + { + return 0 < context.Request.Form.Files.Count || (IsHtml5Upload(context) && context.Request.Form..InputStream != null); + } + + private static string GetFileName(HttpContext context) + { + return context.Request["fileName"]; + } + + private static string GetNeedSaveToTemp(HttpContext context) + { + return context.Request["needSaveToTemp"]; + } + + private static string GetFileContentType(HttpContext context) + { + return context.Request["fileContentType"]; + } + + private static bool IsHtml5Upload(HttpContext context) + { + return "html5".Equals(context.Request["type"]); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CasesWrapper.cs b/products/ASC.CRM/Server/Model/CasesWrapper.cs index 084a24942ca..10e6659cf98 100644 --- a/products/ASC.CRM/Server/Model/CasesWrapper.cs +++ b/products/ASC.CRM/Server/Model/CasesWrapper.cs @@ -97,7 +97,7 @@ public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, - ContactBaseWrapperHelper contactBaseWrapperHelper) + ContactWrapperHelper contactBaseWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -106,7 +106,7 @@ public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, ContactBaseWrapperHelper = contactBaseWrapperHelper; } - public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public ContactWrapperHelper ContactBaseWrapperHelper { get; } public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } @@ -147,7 +147,7 @@ public CasesWrapper Get(Cases cases) { if (member == null) continue; - membersWrapperList.Add(ContactBaseWrapperHelper.Get(member)); + membersWrapperList.Add(ContactBaseWrapperHelper.GetContactBaseWrapper(member)); } result.Members = membersWrapperList; diff --git a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs index fd0ed85e4a3..cd592c7e10e 100644 --- a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs +++ b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs @@ -174,6 +174,7 @@ public ContactInfoWrapperHelper() public ContactInfoWrapper Get(ContactInfo contactInfo) { + if (contactInfo == null) return null; return new ContactInfoWrapper { diff --git a/products/ASC.CRM/Server/Model/ContactWrapper.cs b/products/ASC.CRM/Server/Model/ContactWrapper.cs index dad31262425..6fe7a088a47 100644 --- a/products/ASC.CRM/Server/Model/ContactWrapper.cs +++ b/products/ASC.CRM/Server/Model/ContactWrapper.cs @@ -26,8 +26,10 @@ using ASC.Api.Core; using ASC.Common; +using ASC.Common.Web; using ASC.CRM.Classes; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.Api.Models; @@ -52,44 +54,6 @@ public PersonWrapper() } - public static PersonWrapper ToPersonWrapperQuick(Person person) - { - var result = new PersonWrapper(person.ID); - - result.DisplayName = person.GetTitle(); - result.IsPrivate = CRMSecurity.IsPrivate(person); - result.IsShared = person.ShareType == ShareType.ReadWrite || person.ShareType == ShareType.Read; - result.ShareType = person.ShareType; - - if (result.IsPrivate) - { - result.AccessList = CRMSecurity.GetAccessSubjectTo(person) - .Select(item => EmployeeWraper.Get(item.Key)); - } - result.Currency = !String.IsNullOrEmpty(person.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(person.Currency)) : - null; - - result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, person.ID, false).ToLower(); - result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, person.ID, false).ToLower(); - result.IsCompany = false; - result.CanEdit = CRMSecurity.CanEdit(person); - //result.CanDelete = CRMSecurity.CanDelete(contact); - - result.CreateBy = EmployeeWraper.Get(person.CreateBy); - result.Created = (ApiDateTime)person.CreateOn; - result.About = person.About; - result.Industry = person.Industry; - - - result.FirstName = person.FirstName; - result.LastName = person.LastName; - result.Title = person.JobTitle; - - return result; - } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public String FirstName { get; set; } @@ -104,7 +68,7 @@ public static PersonWrapper ToPersonWrapperQuick(Person person) public new static PersonWrapper GetSample() { - return new PersonWrapper(0) + return new PersonWrapper { IsPrivate = true, IsShared = false, @@ -121,7 +85,6 @@ public static PersonWrapper ToPersonWrapperQuick(Person person) } } - public class PersonWrapperHelper { public PersonWrapperHelper() @@ -130,19 +93,25 @@ public PersonWrapperHelper() public PersonWrapper Get(Person person) { + return new PersonWrapper + { + FirstName = person.FirstName, + LastName = person.LastName, + Title = person.JobTitle + }; + } - FirstName = person.FirstName; - LastName = person.LastName; - Title = person.JobTitle; - - + public PersonWrapper GetQuick(Person person) + { return new PersonWrapper { FirstName = person.FirstName, LastName = person.LastName, Title = person.JobTitle - }; + }; } + + } public static class PersonWrapperHelperHelperExtension @@ -155,81 +124,24 @@ public static DIHelper AddPersonWrapperHelperService(this DIHelper services) } } - - - - - - - - - - - - - - - - - - - - - - /// /// Company /// [DataContract(Name = "company", Namespace = "")] public class CompanyWrapper : ContactWrapper { - public CompanyWrapper(int id) : - base(id) + public CompanyWrapper() { } - public CompanyWrapper(Company company) - : base(company) - { - CompanyName = company.CompanyName; - // PersonsCount = Global.DaoFactory.ContactDao.GetMembersCount(company.ID); - } - - - public static CompanyWrapper ToCompanyWrapperQuick(Company company) - { - var result = new CompanyWrapper(company.ID); - - result.DisplayName = company.GetTitle(); - result.IsPrivate = CRMSecurity.IsPrivate(company); - result.IsShared = company.ShareType == ShareType.ReadWrite || company.ShareType == ShareType.Read; - result.ShareType = company.ShareType; - - if (result.IsPrivate) - { - result.AccessList = CRMSecurity.GetAccessSubjectTo(company) - .Select(item => EmployeeWraper.Get(item.Key)); - } - result.Currency = !String.IsNullOrEmpty(company.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(company.Currency)) : - null; - - result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, company.ID, true).ToLower(); - result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, company.ID, true).ToLower(); - result.IsCompany = true; - result.CanEdit = CRMSecurity.CanEdit(company); - //result.CanDelete = CRMSecurity.CanDelete(contact); + //public CompanyWrapper(Company company) + // : base(company) + //{ + // CompanyName = company.CompanyName; + // // PersonsCount = Global.DaoFactory.ContactDao.GetMembersCount(company.ID); + //} - result.CompanyName = company.CompanyName; - - result.CreateBy = EmployeeWraper.Get(company.CreateBy); - result.Created = (ApiDateTime)company.CreateOn; - result.About = company.About; - result.Industry = company.Industry; - - return result; - } [DataMember(IsRequired = true, EmitDefaultValue = false)] @@ -243,7 +155,7 @@ public static CompanyWrapper ToCompanyWrapperQuick(Company company) public new static CompanyWrapper GetSample() { - return new CompanyWrapper(0) + return new CompanyWrapper { IsPrivate = true, IsShared = false, @@ -260,19 +172,20 @@ public static CompanyWrapper ToCompanyWrapperQuick(Company company) [KnownType(typeof(CompanyWrapper))] public abstract class ContactWrapper : ContactBaseWrapper { - protected ContactWrapper() + public ContactWrapper() { - } - protected ContactWrapper(Contact contact) - : base(contact) - { - CreateBy = EmployeeWraper.Get(contact.CreateBy); - Created = (ApiDateTime)contact.CreateOn; - About = contact.About; - Industry = contact.Industry; } + //protected ContactWrapper(Contact contact) + // : base(contact) + //{ + // CreateBy = EmployeeWraper.Get(contact.CreateBy); + // Created = (ApiDateTime)contact.CreateOn; + // About = contact.About; + // Industry = contact.Industry; + //} + [DataMember(IsRequired = false, EmitDefaultValue = false)] public IEnumerable
    Addresses { get; set; } @@ -312,7 +225,7 @@ protected ContactWrapper(Contact contact) public new static ContactWrapper GetSample() { - return new PersonWrapper(0) + return new PersonWrapper { IsPrivate = true, IsShared = false, @@ -338,38 +251,6 @@ protected ContactWrapper(Contact contact) [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithEmailWrapper : ContactBaseWrapper { - protected ContactBaseWithEmailWrapper() - { - } - - public ContactBaseWithEmailWrapper(Contact contact) - : base(contact) - { - } - - public ContactBaseWithEmailWrapper(ContactWrapper contactWrapper) - { - AccessList = contactWrapper.AccessList; - CanEdit = contactWrapper.CanEdit; - DisplayName = contactWrapper.DisplayName; - IsCompany = contactWrapper.IsCompany; - IsPrivate = contactWrapper.IsPrivate; - IsShared = contactWrapper.IsShared; - ShareType = contactWrapper.ShareType; - MediumFotoUrl = contactWrapper.MediumFotoUrl; - SmallFotoUrl = contactWrapper.SmallFotoUrl; - - if (contactWrapper.CommonData != null && contactWrapper.CommonData.Count() != 0) - { - Email = contactWrapper.CommonData.FirstOrDefault(item => item.InfoType == ContactInfoType.Email && item.IsPrimary); - } - else - { - Email = null; - } - } - - [DataMember(IsRequired = false, EmitDefaultValue = false)] public ContactInfoWrapper Email { get; set; } } @@ -378,43 +259,23 @@ public ContactBaseWithEmailWrapper(ContactWrapper contactWrapper) [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithPhoneWrapper : ContactBaseWrapper { - protected ContactBaseWithPhoneWrapper(int id) - : base(id) - { - } + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ContactInfoWrapper Phone { get; set; } + } + + + + + + + + + + - public ContactBaseWithPhoneWrapper(Contact contact) - : base(contact) - { - } - public ContactBaseWithPhoneWrapper(ContactWrapper contactWrapper) - : base(contactWrapper.ID) - { - AccessList = contactWrapper.AccessList; - CanEdit = contactWrapper.CanEdit; - DisplayName = contactWrapper.DisplayName; - IsCompany = contactWrapper.IsCompany; - IsPrivate = contactWrapper.IsPrivate; - IsShared = contactWrapper.IsShared; - ShareType = contactWrapper.ShareType; - MediumFotoUrl = contactWrapper.MediumFotoUrl; - SmallFotoUrl = contactWrapper.SmallFotoUrl; - - if (contactWrapper.CommonData != null && contactWrapper.CommonData.Count() != 0) - { - Phone = contactWrapper.CommonData.FirstOrDefault(item => item.InfoType == ContactInfoType.Phone && item.IsPrimary); - } - else - { - Phone = null; - } - } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactInfoWrapper Phone { get; set; } - } @@ -501,7 +362,6 @@ public static ContactBaseWrapper GetSample() } } - [DataContract(Name = "contact_task", Namespace = "")] public class ContactWithTaskWrapper { @@ -512,40 +372,37 @@ public class ContactWithTaskWrapper public ContactWrapper Contact { get; set; } } - - - - - - - - - - public class ContactBaseWrapperHelper + public class ContactWrapperHelper { - public ContactBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public ContactWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, CurrencyProvider currencyProvider, PathProvider pathProvider, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper) + CurrencyInfoWrapperHelper currencyInfoWrapperHelper, + DaoFactory daoFactory, + ContactInfoWrapperHelper contactInfoWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; + EmployeeWrapperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; CurrencyProvider = currencyProvider; PathProvider = pathProvider; CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + DaoFactory = daoFactory; + ContactInfoWrapperHelper = contactInfoWrapperHelper; } + public ContactInfoWrapperHelper ContactInfoWrapperHelper { get; } + public DaoFactory DaoFactory { get; } public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } + public EmployeeWraperHelper EmployeeWrapperHelper { get; } public CurrencyProvider CurrencyProvider { get; } public PathProvider PathProvider { get; } - public ContactBaseWrapper GetQuick(Contact contact) + public ContactBaseWrapper GetContactBaseWrapperQuick(Contact contact) { var result = new ContactBaseWrapper { @@ -560,52 +417,157 @@ public ContactBaseWrapper GetQuick(Contact contact) MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), IsCompany = contact is Company, CanEdit = CRMSecurity.CanEdit(contact), - // CanDelete = CRMSecurity.CanDelete(contact), + // CanDelete = CRMSecurity.CanDelete(contact), }; if (result.IsPrivate) { result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeWraperHelper.Get(item.Key)); + .Select(item => EmployeeWrapperHelper.Get(item.Key)); } return result; } - public ContactBaseWrapper Get(Contact contact) + public ContactBaseWrapper GetContactBaseWrapper(Contact contact) { - var result = new ContactBaseWrapper + var result = GetContactBaseWrapperQuick(contact); + + result.CanDelete = CRMSecurity.CanDelete(contact); + + return result; + } + + public ContactBaseWithPhoneWrapper GetContactBaseWithPhoneWrapper(Contact contact) + { + if (contact == null) return null; + + var result = (ContactBaseWithPhoneWrapper)GetContactBaseWrapper(contact); + + result.Phone = ContactInfoWrapperHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Phone, null, true).FirstOrDefault()); + + return result; + } + + public ContactBaseWithEmailWrapper GetContactBaseWithEmailWrapper(Contact contact) + { + if (contact == null) return null; + + var result = (ContactBaseWithEmailWrapper)GetContactBaseWrapper(contact); + + result.Email = ContactInfoWrapperHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Email, null, true).FirstOrDefault()); + + return result; + } + + public ContactWrapper GetContactWrapper(Contact contact) + { + ContactWrapper result; + + var person = contact as Person; + if (person != null) { - Id = contact.ID, - DisplayName = contact.GetTitle(), - IsPrivate = CRMSecurity.IsPrivate(contact), - IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read, - ShareType = contact.ShareType, - Currency = !String.IsNullOrEmpty(contact.Currency) ? - CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(contact.Currency)) : null, - SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), - MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), - IsCompany = contact is Company, - CanEdit = CRMSecurity.CanEdit(contact), - CanDelete = CRMSecurity.CanDelete(contact), - }; + var peopleWrapper = (PersonWrapper)GetContactBaseWrapper(contact); - if (result.IsPrivate) + peopleWrapper.FirstName = person.FirstName; + peopleWrapper.LastName = person.LastName; + peopleWrapper.Title = person.JobTitle; + + if (person.CompanyID > 0) + { + peopleWrapper.Company = GetContactBaseWrapper(DaoFactory.GetContactDao().GetByID(person.CompanyID)); + } + + result = peopleWrapper; + } + else { - result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeWraperHelper.Get(item.Key)); + var company = contact as Company; + + if (company != null) + { + result = (CompanyWrapper)GetContactBaseWrapper(company); + ((CompanyWrapper)result).CompanyName = company.CompanyName; + ((CompanyWrapper)result).PersonsCount = DaoFactory.GetContactDao().GetMembersCount(result.Id); + } + else throw new ArgumentException(); } + if (contact.StatusID > 0) + { + var listItem = DaoFactory.GetListItemDao().GetByID(contact.StatusID); + if (listItem == null) throw new ItemNotFoundException(); + + result.ContactStatus = new ContactStatusBaseWrapper(listItem); + } + + result.TaskCount = DaoFactory.GetTaskDao().GetTasksCount(contact.ID); + result.HaveLateTasks = DaoFactory.GetTaskDao().HaveLateTask(contact.ID); + + var contactInfos = new List(); + var addresses = new List
    (); + + var data = DaoFactory.GetContactInfoDao().GetList(contact.ID, null, null, null); + + foreach (var contactInfo in data) + { + if (contactInfo.InfoType == ContactInfoType.Address) + { + addresses.Add(new Address(contactInfo)); + } + else + { + contactInfos.Add(ContactInfoWrapperHelper.Get(contactInfo)); + } + } + + result.Addresses = addresses; + result.CommonData = contactInfos; + + result.CustomFields = DaoFactory.GetCustomFieldDao() + .GetEnityFields(contact is Person ? EntityType.Person : EntityType.Company, contact.ID, false) + .ConvertAll(item => new CustomFieldBaseWrapper(item)); + return result; + } + + + public CompanyWrapper GetCompanyWrapperQuick(Company company) + { + var result = (CompanyWrapper)GetContactBaseWrapperQuick(company); + + result.CompanyName = company.CompanyName; + + result.CreateBy = EmployeeWrapperHelper.Get(company.CreateBy); + result.Created = ApiDateTimeHelper.Get(company.CreateOn); + result.About = company.About; + result.Industry = company.Industry; + + return result; + } + + public PersonWrapper GetPersonWrapperQuick(Person person) + { + var result = (PersonWrapper)GetContactBaseWrapperQuick(person); + + result.CreateBy = EmployeeWrapperHelper.Get(person.CreateBy); + result.Created = ApiDateTimeHelper.Get(person.CreateOn); + result.About = person.About; + result.Industry = person.Industry; + + result.FirstName = person.FirstName; + result.LastName = person.LastName; + result.Title = person.JobTitle; + return result; } } - public static class ContactBaseWrapperHelperExtension + public static class ContactWrapperHelperExtension { - public static DIHelper AddContactBaseWrapperHelperService(this DIHelper services) + public static DIHelper AddContactWrapperHelperService(this DIHelper services) { - services.TryAddTransient(); + services.TryAddTransient(); return services.AddApiDateTimeHelper() .AddEmployeeWraper() @@ -615,6 +577,4 @@ public static DIHelper AddContactBaseWrapperHelperService(this DIHelper services } } - - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs index cd2edff1f2d..6d3faa4fe87 100644 --- a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs +++ b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs @@ -124,7 +124,10 @@ public InvoiceBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, SettingsManager settingsManager, CurrencyProvider currencyProvider, InvoiceStatusWrapperHelper invoiceStatusWrapperHelper, - DaoFactory daoFactory) + CurrencyInfoWrapperHelper currencyInfoWrapperHelper, + DaoFactory daoFactory, + ContactWrapperHelper contactWrapperHelper, + EntityWrapperHelper entityWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -133,8 +136,14 @@ public InvoiceBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, CurrencyProvider = currencyProvider; InvoiceStatusWrapperHelper = invoiceStatusWrapperHelper; DaoFactory = daoFactory; + CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + ContactWrapperHelper = contactWrapperHelper; + EntityWrapperHelper = entityWrapperHelper; } + public EntityWrapperHelper EntityWrapperHelper { get; } + public ContactWrapperHelper ContactWrapperHelper { get; } + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } public InvoiceStatusWrapperHelper InvoiceStatusWrapperHelper { get; } public CurrencyProvider CurrencyProvider { get; } public SettingsManager SettingsManager { get; } @@ -155,8 +164,8 @@ public InvoiceBaseWrapper Get(Invoice invoice) TemplateType = invoice.TemplateType, DueDate = ApiDateTimeHelper.Get(invoice.DueDate), Currency = !String.IsNullOrEmpty(invoice.Currency) ? - new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) : - new CurrencyInfoWrapper(SettingsManager.Load().DefaultCurrency), + CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(invoice.Currency)) : + CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency), ExchangeRate = invoice.ExchangeRate, Language = invoice.Language, PurchaseOrderNumber = invoice.PurchaseOrderNumber, @@ -171,17 +180,17 @@ public InvoiceBaseWrapper Get(Invoice invoice) if (invoice.ContactID > 0) { - result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + result.Contact = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); } if (invoice.ConsigneeID > 0) { - result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + result.Consignee = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); } if (invoice.EntityID > 0) { - result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); + result.Entity = EntityWrapperHelper.Get(invoice.EntityType, invoice.EntityID); } result.Cost = invoice.GetInvoiceCost(DaoFactory); @@ -257,7 +266,9 @@ public InvoiceWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, InvoiceLineWrapperHelper invoiceLineWrapperHelper, DaoFactory daoFactory, CurrencyInfoWrapperHelper currencyInfoWrapperHelper, - CurrencyRateInfoWrapperHelper currencyRateInfoWrapperHelper) + CurrencyRateInfoWrapperHelper currencyRateInfoWrapperHelper, + ContactWrapperHelper contactWrapperHelper, + EntityWrapperHelper entityWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -269,8 +280,11 @@ public InvoiceWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, InvoiceLineWrapperHelper = invoiceLineWrapperHelper; CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; CurrencyRateInfoWrapperHelper = currencyRateInfoWrapperHelper; + ContactWrapperHelper = contactWrapperHelper; + EntityWrapperHelper = entityWrapperHelper; } + public ContactWrapperHelper ContactWrapperHelper { get; } public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } public CurrencyRateInfoWrapperHelper CurrencyRateInfoWrapperHelper { get; } public DaoFactory DaoFactory { get; } @@ -281,7 +295,7 @@ public InvoiceWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } public CRMSecurity CRMSecurity { get; } - + public EntityWrapperHelper EntityWrapperHelper { get; } public InvoiceWrapper Get(Invoice invoice) { var result = new InvoiceWrapper @@ -309,17 +323,17 @@ public InvoiceWrapper Get(Invoice invoice) if (invoice.ContactID > 0) { - result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + result.Contact = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); } if (invoice.ConsigneeID > 0) { - result.Consignee = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + result.Consignee = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); } if (invoice.EntityID > 0) { - result.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); + result.Entity = EntityWrapperHelper.Get(invoice.EntityType, invoice.EntityID); } result.Cost = invoice.GetInvoiceCost(DaoFactory); @@ -327,6 +341,7 @@ public InvoiceWrapper Get(Invoice invoice) result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(x => InvoiceLineWrapperHelper.Get(x)).ToList(); return result; + } } @@ -403,7 +418,8 @@ public InvoiceItemWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, SettingsManager settingsManager, CurrencyProvider currencyProvider, DaoFactory daoFactory, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper) + CurrencyInfoWrapperHelper currencyInfoWrapperHelper, + InvoiceTaxWrapperHelper invoiceTaxWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -412,8 +428,11 @@ public InvoiceItemWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, CurrencyProvider = currencyProvider; DaoFactory = daoFactory; CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + InvoiceTaxWrapperHelper = invoiceTaxWrapperHelper; } + public InvoiceTaxWrapperHelper InvoiceTaxWrapperHelper { get; } + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } public DaoFactory DaoFactory { get; } public CurrencyProvider CurrencyProvider { get; } @@ -443,14 +462,13 @@ public InvoiceItemWrapper Get(InvoiceItem invoiceItem) if (invoiceItem.InvoiceTax1ID > 0) { - result.InvoiceTax1 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); + result.InvoiceTax1 = InvoiceTaxWrapperHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); } if (invoiceItem.InvoiceTax2ID > 0) { - result.InvoiceTax2 = ToInvoiceTaxWrapper(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); + result.InvoiceTax2 = InvoiceTaxWrapperHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); } - return result; } diff --git a/products/ASC.CRM/Server/Model/ListItemWrapper.cs b/products/ASC.CRM/Server/Model/ListItemWrapper.cs index ddeee9f4e70..4f4d0ec13d4 100644 --- a/products/ASC.CRM/Server/Model/ListItemWrapper.cs +++ b/products/ASC.CRM/Server/Model/ListItemWrapper.cs @@ -39,8 +39,9 @@ namespace ASC.Api.CRM.Wrappers [DataContract(Name = "historyCategoryBase", Namespace = "")] public class HistoryCategoryBaseWrapper : ListItemWrapper { - public HistoryCategoryBaseWrapper() : base(0) + public HistoryCategoryBaseWrapper() { + } public HistoryCategoryBaseWrapper(ListItem listItem) @@ -60,7 +61,6 @@ public static HistoryCategoryBaseWrapper GetSample() { return new HistoryCategoryBaseWrapper { - ID = 30, Title = "Lunch", SortOrder = 10, Color = String.Empty, @@ -89,7 +89,6 @@ public HistoryCategoryWrapper(ListItem listItem) { return new HistoryCategoryWrapper { - ID = 30, Title = "Lunch", SortOrder = 10, Color = String.Empty, @@ -108,12 +107,10 @@ public HistoryCategoryWrapper(ListItem listItem) public class DealMilestoneBaseWrapper : ListItemWrapper { public DealMilestoneBaseWrapper() - : base(0) { } public DealMilestoneBaseWrapper(DealMilestone dealMilestone) - : base(dealMilestone.ID) { SuccessProbability = dealMilestone.Probability; StageType = dealMilestone.Status; @@ -132,7 +129,6 @@ public static DealMilestoneBaseWrapper GetSample() { return new DealMilestoneBaseWrapper { - ID = 30, Title = "Discussion", SortOrder = 2, Color = "#B9AFD3", @@ -162,7 +158,6 @@ public DealMilestoneWrapper(DealMilestone dealMilestone) { return new DealMilestoneWrapper { - ID = 30, Title = "Discussion", SortOrder = 2, Color = "#B9AFD3", @@ -182,7 +177,6 @@ public DealMilestoneWrapper(DealMilestone dealMilestone) public class TaskCategoryBaseWrapper : ListItemWrapper { public TaskCategoryBaseWrapper() - : base(0) { } @@ -199,7 +193,6 @@ public static TaskCategoryBaseWrapper GetSample() { return new TaskCategoryBaseWrapper { - ID = 30, Title = "Appointment", SortOrder = 2, Description = "", @@ -227,7 +220,7 @@ public TaskCategoryWrapper(ListItem listItem) { return new TaskCategoryWrapper { - ID = 30, + Id = 30, Title = "Appointment", SortOrder = 2, Description = "", @@ -244,8 +237,7 @@ public TaskCategoryWrapper(ListItem listItem) [DataContract(Name = "contactStatusBase", Namespace = "")] public class ContactStatusBaseWrapper : ListItemWrapper { - public ContactStatusBaseWrapper() : - base(0) + public ContactStatusBaseWrapper() { } @@ -258,7 +250,6 @@ public static ContactStatusBaseWrapper GetSample() { return new ContactStatusBaseWrapper { - ID = 30, Title = "Cold", SortOrder = 2, Description = "" @@ -285,7 +276,6 @@ public ContactStatusWrapper(ListItem listItem) { return new ContactStatusWrapper { - ID = 30, Title = "Cold", SortOrder = 2, Description = "", @@ -301,9 +291,9 @@ public ContactStatusWrapper(ListItem listItem) [DataContract(Name = "contactTypeBase", Namespace = "")] public class ContactTypeBaseWrapper : ListItemWrapper { - public ContactTypeBaseWrapper() : - base(0) + public ContactTypeBaseWrapper() { + } public ContactTypeBaseWrapper(ListItem listItem) @@ -315,7 +305,7 @@ public static ContactTypeBaseWrapper GetSample() { return new ContactTypeBaseWrapper { - ID = 30, + Id = 30, Title = "Client", SortOrder = 2, Description = "" @@ -342,7 +332,7 @@ public ContactTypeWrapper(ListItem listItem) { return new ContactTypeWrapper { - ID = 30, + Id= 30, Title = "Client", SortOrder = 2, Description = "", diff --git a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs index 0c5faf0f89a..3f74fa5ce71 100644 --- a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs +++ b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs @@ -138,7 +138,7 @@ public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, CurrencyProvider currencyProvider, - ContactBaseWrapperHelper contactBaseWrapperHelper + ContactWrapperHelper contactBaseWrapperHelper ) { ApiDateTimeHelper = apiDateTimeHelper; @@ -150,7 +150,7 @@ ContactBaseWrapperHelper contactBaseWrapperHelper } public CurrencyProvider CurrencyProvider {get;} - public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public ContactWrapperHelper ContactBaseWrapperHelper { get; } public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } @@ -177,7 +177,7 @@ public OpportunityWrapper Get(Deal deal) }; if (deal.ContactID > 0) - dealWrapper.Contact = ContactBaseWrapperHelper.Get(DaoFactory.GetContactDao().GetByID(deal.ContactID)); + dealWrapper.Contact = ContactBaseWrapperHelper.GetContactBaseWrapper(DaoFactory.GetContactDao().GetByID(deal.ContactID)); if (deal.DealMilestoneID > 0) { @@ -208,7 +208,7 @@ public OpportunityWrapper Get(Deal deal) foreach (var member in membersList) { if (member == null) continue; - membersWrapperList.Add(ContactBaseWrapperHelper.Get(member)); + membersWrapperList.Add(ContactBaseWrapperHelper.GetContactBaseWrapper(member)); } dealWrapper.Members = membersWrapperList; @@ -227,7 +227,7 @@ public static DIHelper AddOpportunityWrapperHelperService(this DIHelper services .AddEmployeeWraper() .AddCRMSecurityService() .AddDaoFactoryService() - .AddContactBaseWrapperHelperService() + .AddContactWrapperHelperService() .AddCurrencyProviderService(); } } diff --git a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs index 3acd87c085a..4bf781f40c0 100644 --- a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs +++ b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs @@ -30,6 +30,7 @@ using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.Web.Api.Models; using System; using System.Collections.Generic; @@ -60,6 +61,67 @@ public static EntityWrapper GetSample() } } + + public class EntityWrapperHelper + { + public EntityWrapperHelper(DaoFactory daoFactory) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public EntityWrapper Get(EntityType entityType, int entityID) + { + if (entityID == 0) return null; + + var result = new EntityWrapper + { + EntityId = entityID + }; + + switch (entityType) + { + case EntityType.Case: + var caseObj = DaoFactory.GetCasesDao().GetByID(entityID); + if (caseObj == null) + return null; + + result.EntityType = "case"; + result.EntityTitle = caseObj.Title; + + break; + case EntityType.Opportunity: + var dealObj = DaoFactory.GetDealDao().GetByID(entityID); + if (dealObj == null) + return null; + + result.EntityType = "opportunity"; + result.EntityTitle = dealObj.Title; + + break; + default: + return null; + } + + return result; + } + } + + + public static class EntityWrapperHelperExtension + { + public static DIHelper AddEntityWrapperHelperService(this DIHelper services) + { + services.TryAddTransient(); + + return services; + } + } + + + + [DataContract(Name = "historyEvent", Namespace = "")] public class RelationshipEventWrapper { @@ -116,10 +178,11 @@ public class RelationshipEventWrapperHelper public RelationshipEventWrapperHelper( ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - ContactBaseWrapperHelper contactBaseWrapperHelper, + ContactWrapperHelper contactBaseWrapperHelper, FileWrapperHelper fileWrapperHelper, CRMSecurity cRMSecurity, - DaoFactory daoFactory) + DaoFactory daoFactory, + EntityWrapperHelper entityWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -127,15 +190,16 @@ public RelationshipEventWrapperHelper( DaoFactory = daoFactory; ContactBaseWrapperHelper = contactBaseWrapperHelper; FileWrapperHelper = fileWrapperHelper; + EntityWrapperHelper = entityWrapperHelper; } public FileWrapperHelper FileWrapperHelper { get; } - public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public ContactWrapperHelper ContactBaseWrapperHelper { get; } public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - + public EntityWrapperHelper EntityWrapperHelper { get; } public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) { var result = new RelationshipEventWrapper @@ -158,7 +222,7 @@ public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) if (relationshipEvent.EntityID > 0) { - result.Entity = ToEntityWrapper(relationshipEvent.EntityType, relationshipEvent.EntityID); + result.Entity = EntityWrapperHelper.Get(relationshipEvent.EntityType, relationshipEvent.EntityID); } result.Files = DaoFactory.GetRelationshipEventDao().GetFiles(relationshipEvent.ID).ConvertAll(file => FileWrapperHelper.Get(file)); @@ -168,7 +232,7 @@ public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) var relativeContact = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); if (relativeContact != null) { - result.Contact = ContactBaseWrapperHelper.Get(relativeContact); + result.Contact = ContactBaseWrapperHelper.GetContactBaseWrapper(relativeContact); } } @@ -188,7 +252,7 @@ public static DIHelper AddRelationshipEventWrapperHelperService(this DIHelper se return services.AddApiDateTimeHelper() .AddEmployeeWraper() .AddCRMSecurityService() - .AddContactBaseWrapperHelperService() + .AddContactWrapperHelperService() .AddFileWrapperHelperService(); } } diff --git a/products/ASC.CRM/Server/Model/TaskWrapper.cs b/products/ASC.CRM/Server/Model/TaskWrapper.cs index 931844ed8f3..7986867f458 100644 --- a/products/ASC.CRM/Server/Model/TaskWrapper.cs +++ b/products/ASC.CRM/Server/Model/TaskWrapper.cs @@ -29,6 +29,7 @@ using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.Web.Api.Models; using System; using System.Runtime.Serialization; @@ -41,18 +42,6 @@ namespace ASC.Api.CRM.Wrappers [DataContract(Name = "task", Namespace = "")] public class TaskWrapper { - //public TaskWrapper(Task task) - //{ - // CreateBy = EmployeeWraper.Get(task.CreateBy); - // Created = (ApiDateTime)task.CreateOn; - // Title = task.Title; - // Description = task.Description; - // DeadLine = (ApiDateTime)task.DeadLine; - // Responsible = EmployeeWraper.Get(task.ResponsibleID); - // IsClosed = task.IsClosed; - // AlertValue = task.AlertValue; - //} - [DataMember(Name = "id")] public int Id { get; set; } @@ -120,7 +109,7 @@ public TaskBaseWrapper() } - + [DataMember(IsRequired = false, EmitDefaultValue = false)] public String Title { get; set; } @@ -165,28 +154,43 @@ public static TaskBaseWrapper GetSample() public class TaskWrapperHelper { - - public TaskWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + + public TaskWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, - ContactBaseWrapperHelper contactBaseWrapperHelper) + ContactWrapperHelper contactBaseWrapperHelper, + EntityWrapperHelper entityWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; DaoFactory = daoFactory; ContactBaseWrapperHelper = contactBaseWrapperHelper; + EntityWrapperHelper = entityWrapperHelper; } - public ContactBaseWrapperHelper ContactBaseWrapperHelper { get; } + public ContactWrapperHelper ContactBaseWrapperHelper { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } public DaoFactory DaoFactory { get; } + public EntityWrapperHelper EntityWrapperHelper { get; } - public TaskWrapper Get(Task task) - { + public TaskBaseWrapper GetTaskBaseWrapper(Task task) + { + return new TaskBaseWrapper { + Title = task.Title, + Description = task.Description, + DeadLine = ApiDateTimeHelper.Get(task.DeadLine), + Responsible = EmployeeWraperHelper.Get(task.ResponsibleID), + IsClosed = task.IsClosed, + AlertValue = task.AlertValue + }; + } + + public TaskWrapper GetTaskWrapper(Task task) + { var result = new TaskWrapper { Title = task.Title, @@ -199,17 +203,24 @@ public TaskWrapper Get(Task task) if (task.CategoryID > 0) { - result.Category = GetTaskCategoryByID(task.CategoryID); + var categoryItem = DaoFactory.GetListItemDao().GetByID(task.CategoryID); + + result.Category = new TaskCategoryWrapper(categoryItem) + { + RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, categoryItem.ID) + }; + } if (task.ContactID > 0) { - result.Contact = ContactBaseWrapperHelper.Get(DaoFactory.GetContactDao().GetByID(task.ContactID)); + result.Contact = ContactBaseWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(task.ContactID)); } if (task.EntityID > 0) { - result.Entity = ToEntityWrapper(task.EntityType, task.EntityID); + + result.Entity = EntityWrapperHelper.Get(task.EntityType, task.EntityID); } result.CanEdit = CRMSecurity.CanEdit(task); @@ -229,11 +240,4 @@ public static DIHelper AddTaskWrapperHelperService(this DIHelper services) .AddCRMSecurityService(); } } -} - -//private TaskWrapper ToTaskWrapper(Task task) -//{ -// var result = new TaskWrapper(task); - -// return result; -//} \ No newline at end of file +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index b49ae9d900c..74ca4766ce1 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -38,11 +38,10 @@ using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.Web.Core.Files; -using ASC.Web.CRM.Core; +using ASC.Web.Core.Users; using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Utils; using ASC.Web.Studio.Utility; -using Autofac; using Ionic.Zip; using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; @@ -108,8 +107,13 @@ public ExportDataOperation(UserManager userManager, IOptionsMonitor logger, TenantManager tenantManager, Global global, - ExportDataCache exportDataCache) + ExportDataCache exportDataCache, + CommonLinkUtility commonLinkUtility, + DisplayUserSettings displayUserSettings, + NotifyClient notifyClient, + DaoFactory daoFactory) { + DaoFactory = daoFactory; UserManager = userManager; FileUtility = fileUtility; @@ -117,9 +121,9 @@ public ExportDataOperation(UserManager userManager, _author = securityContext.CurrentAccount; _dataStore = global.GetStore(); - _notifyClient = NotifyClient.Instance; + _notifyClient = notifyClient; _filterObject = filterObject; - + _log = logger.Get("ASC.CRM"); Id = ExportToCsv.GetKey(filterObject != null); @@ -132,10 +136,15 @@ public ExportDataOperation(UserManager userManager, ExportDataCache = exportDataCache; SecurityContext = securityContext; + + CommonLinkUtility = commonLinkUtility; } - - public SecurityContext SecurityContext { get; } + + public TenantManager TenantManager { get; } + public CommonLinkUtility CommonLinkUtility { get; } + public SecurityContext SecurityContext { get; } + public DaoFactory DaoFactory { get; } public ExportDataCache ExportDataCache { get; } public UserManager UserManager { get; } @@ -155,7 +164,7 @@ public ExportDataOperation(UserManager userManager, private readonly ILog _log; private int _totalCount; - + public override bool Equals(object obj) { if (obj == null) return false; @@ -163,7 +172,7 @@ public override bool Equals(object obj) var exportDataOperation = obj as ExportDataOperation; if (exportDataOperation == null) return false; - + return Id == exportDataOperation.Id; } @@ -175,19 +184,19 @@ public override int GetHashCode() public object Clone() { var cloneObj = new ExportDataOperation - { - Id = Id, - Status = Status, - Error = Error, - Percentage = Percentage, - IsCompleted = IsCompleted, - FileName = FileName, - FileUrl = FileUrl - }; + { + Id = Id, + Status = Status, + Error = Error, + Percentage = Percentage, + IsCompleted = IsCompleted, + FileName = FileName, + FileUrl = FileUrl + }; return cloneObj; } - + public object Id { get; set; } public object Status { get; set; } @@ -201,7 +210,7 @@ public object Clone() public string FileName { get; set; } public string FileUrl { get; set; } - + private String WrapDoubleQuote(String value) { return "\"" + value.Trim().Replace("\"", "\"\"") + "\""; @@ -246,27 +255,23 @@ public void RunJob() try { Status = ProgressStatus.Started; - - CoreContext.TenantManager.SetCurrentTenant(_tenantId); + + TenantManager.SetCurrentTenant(_tenantId); SecurityContext.AuthenticateMe(_author); - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - var userCulture = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); - System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; - System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; + System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; + System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; - _log.Debug("Start Export Data"); + _log.Debug("Start Export Data"); - ExportDataCache.Insert((string) Id, (ExportDataOperation) Clone()); + ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); - if (_filterObject == null) - ExportAllData(daoFactory); - else - ExportPartData(daoFactory); - } + if (_filterObject == null) + ExportAllData(daoFactory); + else + ExportPartData(daoFactory); Complete(100, ProgressStatus.Done, null); @@ -275,7 +280,7 @@ public void RunJob() catch (OperationCanceledException) { Complete(0, ProgressStatus.Done, null); - + _log.Debug("Export is cancel"); } catch (Exception ex) @@ -286,7 +291,7 @@ public void RunJob() } finally { - ExportDataCache.ResetAll((string) Id); + ExportDataCache.ResetAll((string)Id); } } @@ -297,20 +302,20 @@ private void Complete(double percentage, ProgressStatus status, object error) Status = status; Error = error; - ExportDataCache.Insert((string) Id, (ExportDataOperation)Clone()); + ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); } private void ExportAllData(DaoFactory daoFactory) { using (var stream = TempStream.Create()) { - var contactDao = daoFactory.ContactDao; - var contactInfoDao = daoFactory.ContactInfoDao; - var dealDao = daoFactory.DealDao; - var casesDao = daoFactory.CasesDao; - var taskDao = daoFactory.TaskDao; - var historyDao = daoFactory.RelationshipEventDao; - var invoiceItemDao = daoFactory.InvoiceItemDao; + var contactDao = daoFactory.GetContactDao(); + var contactInfoDao = daoFactory.GetContactInfoDao(); + var dealDao = daoFactory.GetDealDao(); + var casesDao = daoFactory.GetCasesDao(); + var taskDao = daoFactory.GetTaskDao(); + var historyDao = daoFactory.GetRelationshipEventDao(); + var invoiceItemDao = daoFactory.GetInvoiceItemDao(); _totalCount += contactDao.GetAllContactsCount(); _totalCount += dealDao.GetDealsCount(); @@ -406,9 +411,9 @@ private void ExportPartData(DaoFactory daoFactory) if (items is List) { - var contactInfoDao = daoFactory.ContactInfoDao; + var contactInfoDao = daoFactory.GetContactInfoDao(); - var contacts = (List) items; + var contacts = (List)items; var contactInfos = new StringDictionary(); @@ -416,7 +421,7 @@ private void ExportPartData(DaoFactory daoFactory) .ForEach(item => { var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, - (int) item.InfoType, + (int)item.InfoType, item.Category); if (contactInfos.ContainsKey(contactInfoKey)) @@ -429,23 +434,23 @@ private void ExportPartData(DaoFactory daoFactory) } else if (items is List) { - fileContent = ExportDealsToCsv((List) items, daoFactory); + fileContent = ExportDealsToCsv((List)items, daoFactory); } else if (items is List) { - fileContent = ExportCasesToCsv((List) items, daoFactory); + fileContent = ExportCasesToCsv((List)items, daoFactory); } else if (items is List) { - fileContent = ExportHistoryToCsv((List) items, daoFactory); + fileContent = ExportHistoryToCsv((List)items, daoFactory); } else if (items is List) { - fileContent = ExportTasksToCsv((List) items, daoFactory); + fileContent = ExportTasksToCsv((List)items, daoFactory); } else if (items is List) { - fileContent = ExportInvoiceItemsToCsv((List) items, daoFactory); + fileContent = ExportInvoiceItemsToCsv((List)items, daoFactory); } else throw new ArgumentException(); @@ -455,11 +460,11 @@ private void ExportPartData(DaoFactory daoFactory) private String ExportContactsToCsv(IReadOnlyCollection contacts, StringDictionary contactInfos, DaoFactory daoFactory) { - var key = (string) Id; - var listItemDao = daoFactory.ListItemDao; - var tagDao = daoFactory.TagDao; - var customFieldDao = daoFactory.CustomFieldDao; - var contactDao = daoFactory.ContactDao; + var key = (string)Id; + var listItemDao = daoFactory.GetListItemDao(); + var tagDao = daoFactory.GetTagDao(); + var customFieldDao = daoFactory.GetCustomFieldDao(); + var contactDao = daoFactory.GetContactDao(); var dataTable = new DataTable(); @@ -520,17 +525,17 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String if (infoTypeEnum == ContactInfoType.Address) dataTable.Columns.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) select new DataColumn - { - Caption = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString().ToLower()), - ColumnName = String.Format("contactInfo_{0}_{1}_{2}", (int)infoTypeEnum, categoryEnum, (int)addressPartEnum) - }).ToArray()); + { + Caption = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString().ToLower()), + ColumnName = String.Format("contactInfo_{0}_{1}_{2}", (int)infoTypeEnum, categoryEnum, (int)addressPartEnum) + }).ToArray()); else dataTable.Columns.Add(new DataColumn - { - Caption = localTitle, - ColumnName = String.Format("contactInfo_{0}_{1}", (int)infoTypeEnum, categoryEnum) - }); + { + Caption = localTitle, + ColumnName = String.Format("contactInfo_{0}_{1}", (int)infoTypeEnum, categoryEnum) + }); } var fieldsDescription = customFieldDao.GetFieldsDescription(EntityType.Company); @@ -550,10 +555,10 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String dataTable.Columns.Add( new DataColumn - { - Caption = item.Label, - ColumnName = "customField_" + item.ID - } + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + } ); }); @@ -586,13 +591,13 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String { ExportDataCache.ResetAll(key); - throw new OperationCanceledException(); + throw new OperationCanceledException(); } - ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); Percentage += 1.0 * 100 / _totalCount; - + var isCompany = contact is Company; var compPersType = (isCompany) ? CRMContactResource.Company : CRMContactResource.Person; @@ -713,11 +718,11 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) { - var key = (string) Id; - var tagDao = daoFactory.TagDao; - var customFieldDao = daoFactory.CustomFieldDao; - var dealMilestoneDao = daoFactory.DealMilestoneDao; - var contactDao = daoFactory.ContactDao; + var key = (string)Id; + var tagDao = daoFactory.GetTagDao(); + var customFieldDao = daoFactory.GetCustomFieldDao(); + var dealMilestoneDao = daoFactory.GetDealMilestoneDao(); + var contactDao = daoFactory.GetContactDao(); var dataTable = new DataTable(); @@ -801,10 +806,10 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) if (item.FieldType == CustomFieldType.Heading) return; dataTable.Columns.Add(new DataColumn - { - Caption = item.Label, - ColumnName = "customField_" + item.ID - }); + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + }); }); var customFieldEntity = new Dictionary>(); @@ -829,7 +834,7 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) throw new OperationCanceledException(); } - ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); Percentage += 1.0 * 100 / _totalCount; @@ -898,9 +903,9 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) private String ExportCasesToCsv(IEnumerable cases, DaoFactory daoFactory) { - var key = (string) Id; - var tagDao = daoFactory.TagDao; - var customFieldDao = daoFactory.CustomFieldDao; + var key = (string)Id; + var tagDao = daoFactory.GetTagDao(); + var customFieldDao = daoFactory.GetCustomFieldDao(); var dataTable = new DataTable(); @@ -924,10 +929,10 @@ private String ExportCasesToCsv(IEnumerable cases, if (item.FieldType == CustomFieldType.Heading) return; dataTable.Columns.Add(new DataColumn - { - Caption = item.Label, - ColumnName = "customField_" + item.ID - }); + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + }); }); var customFieldEntity = new Dictionary>(); @@ -952,7 +957,7 @@ private String ExportCasesToCsv(IEnumerable cases, throw new OperationCanceledException(); } - ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); Percentage += 1.0 * 100 / _totalCount; @@ -976,11 +981,11 @@ private String ExportCasesToCsv(IEnumerable cases, private String ExportHistoryToCsv(IEnumerable events, DaoFactory daoFactory) { - var key = (string) Id; - var listItemDao = daoFactory.ListItemDao; - var dealDao = daoFactory.DealDao; - var casesDao = daoFactory.CasesDao; - var contactDao = daoFactory.ContactDao; + var key = (string)Id; + var listItemDao = daoFactory.GetListItemDao(); + var dealDao = daoFactory.GetDealDao(); + var casesDao = daoFactory.GetCasesDao(); + var contactDao = daoFactory.GetContactDao(); var dataTable = new DataTable(); @@ -1027,7 +1032,7 @@ private String ExportHistoryToCsv(IEnumerable events, DaoFact throw new OperationCanceledException(); } - ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); Percentage += 1.0 * 100 / _totalCount; @@ -1095,11 +1100,11 @@ private String ExportHistoryToCsv(IEnumerable events, DaoFact private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) { - var key = (string) Id; - var listItemDao = daoFactory.ListItemDao; - var dealDao = daoFactory.DealDao; - var casesDao = daoFactory.CasesDao; - var contactDao = daoFactory.ContactDao; + var key = (string)Id; + var listItemDao = daoFactory.GetListItemDao(); + var dealDao = daoFactory.GetDealDao(); + var casesDao = daoFactory.GetCasesDao(); + var contactDao = daoFactory.GetContactDao(); var dataTable = new DataTable(); @@ -1161,7 +1166,7 @@ private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) throw new OperationCanceledException(); } - ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); Percentage += 1.0 * 100 / _totalCount; @@ -1201,7 +1206,7 @@ private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) item.DeadLine == DateTime.MinValue ? "" : item.DeadLine.ToShortString(), - CoreContext.UserManager.GetUsers(item.ResponsibleID).DisplayUserName(false), + UserManager.GetUsers(item.ResponsibleID).DisplayUserName(false,), contactTitle, item.IsClosed ? CRMTaskResource.TaskStatus_Closed @@ -1217,8 +1222,8 @@ private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, DaoFactory daoFactory) { - var key = (string) Id; - var taxes = daoFactory.InvoiceTaxDao.GetAll(); + var key = (string)Id; + var taxes = daoFactory.GetInvoiceTaxDao().GetAll(); var dataTable = new DataTable(); dataTable.Columns.AddRange(new[] @@ -1292,7 +1297,7 @@ private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, Da throw new OperationCanceledException(); } - ExportDataCache.Insert(key, (ExportDataOperation) Clone()); + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); Percentage += 1.0 * 100 / _totalCount; @@ -1348,12 +1353,12 @@ public class ExportToCsv private readonly object Locker = new object(); private readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromSeconds(60), true); - + public ExportToCsv(SecurityContext securityContext, ExportDataCache exportDataCache, TenantManager tenantManager) { - SecurityContext = securityContext; + SecurityContext = securityContext; ExportDataCache = exportDataCache; TenantID = tenantManager.GetCurrentTenant().TenantId; } @@ -1364,7 +1369,6 @@ public ExportToCsv(SecurityContext securityContext, public SecurityContext SecurityContext { get; } - public IProgressItem GetStatus(bool partialDataExport) { var key = GetKey(partialDataExport); @@ -1380,7 +1384,7 @@ public IProgressItem Start(FilterObject filterObject, string fileName) var operation = Queue.GetStatus(key); - if (operation == null ) + if (operation == null) { var fromCache = ExportDataCache.Get(key); diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index a27ccf9ea67..e579e14df88 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -160,7 +160,7 @@ private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) }; if (historyCategory == 0) { - var listItemDao = _daoFactory.ListItemDao; + var listItemDao = _daoFactory.GetListItemDao(); // HACK var listItem = listItemDao.GetItems(ListType.HistoryCategory).Find(item => item.AdditionalParams == "event_category_email.png"); @@ -174,7 +174,9 @@ private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) } historyEvent.CategoryID = historyCategory; - var relationshipEventDao = _daoFactory.RelationshipEventDao; + + var relationshipEventDao = _daoFactory.GetRelationshipEventDao(); + historyEvent = relationshipEventDao.CreateItem(historyEvent); if (historyEvent.ID > 0 && _fileID != null && _fileID.Count > 0) @@ -193,148 +195,159 @@ public void RunJob() smtpClient = GetSmtpClient(); - using (var scope = DIHelper.Resolve()) - { - var _daoFactory = scope.Resolve(); - var userCulture = UserManager.GetUsers(_currUser).GetCulture(); + var userCulture = UserManager.GetUsers(_currUser).GetCulture(); - Thread.CurrentThread.CurrentCulture = userCulture; - Thread.CurrentThread.CurrentUICulture = userCulture; + Thread.CurrentThread.CurrentCulture = userCulture; + Thread.CurrentThread.CurrentUICulture = userCulture; - var contactCount = _contactID.Count; + var contactCount = _contactID.Count; - if (contactCount == 0) - { - Complete(); - return; - } + if (contactCount == 0) + { + Complete(); + return; + } - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); - var filePaths = new List(); - var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); + var filePaths = new List(); + var fileDao = FilesIntegration.DaoFactory.GetFileDao(); - foreach (var fileID in _fileID) + foreach (var fileID in _fileID) + { + var fileObj = fileDao.GetFile(fileID); + if (fileObj == null) continue; + using (var fileStream = fileDao.GetFileStream(fileObj)) { - var fileObj = fileDao.GetFile(fileID); - if (fileObj == null) continue; - using (var fileStream = fileDao.GetFileStream(fileObj)) - { - var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), - "crm/files/mailsender/"); + var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), + "crm/files/mailsender/"); - if (!Directory.Exists(directoryPath)) - { - Directory.CreateDirectory(directoryPath); - } + if (!Directory.Exists(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } - var filePath = Path.Combine(directoryPath, fileObj.Title); + var filePath = Path.Combine(directoryPath, fileObj.Title); - using (var newFileStream = File.Create(filePath)) - { - fileStream.StreamCopyTo(newFileStream); - } + using (var newFileStream = File.Create(filePath)) + { + fileStream.StreamCopyTo(newFileStream); + } - filePaths.Add(filePath); + filePaths.Add(filePath); - } } + } - var templateManager = new MailTemplateManager(_daoFactory); - var deliveryCount = 0; + var templateManager = new MailTemplateManager(DaoFactory); + var deliveryCount = 0; - try + try + { + Error = string.Empty; + foreach (var contactID in _contactID) { - Error = string.Empty; - foreach (var contactID in _contactID) + _exactPercentageValue += 100.0 / contactCount; + Percentage = Math.Round(_exactPercentageValue); + + if (IsCompleted) break; // User selected cancel + + var contactInfoDao = DaoFactory.GetContactInfoDao(); + + var startDate = DateTime.Now; + + var contactEmails = contactInfoDao.GetList(contactID, ContactInfoType.Email, null, true); + if (contactEmails.Count == 0) { - _exactPercentageValue += 100.0 / contactCount; - Percentage = Math.Round(_exactPercentageValue); + continue; + } - if (IsCompleted) break; // User selected cancel + var recipientEmail = contactEmails[0].Data; - var contactInfoDao = _daoFactory.ContactInfoDao; - var startDate = DateTime.Now; + if (!recipientEmail.TestEmailRegex()) + { + Error += string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail) + + "
    "; + continue; + } - var contactEmails = contactInfoDao.GetList(contactID, ContactInfoType.Email, null, true); - if (contactEmails.Count == 0) - { - continue; - } + var to = new MailboxAddress(recipientEmail); - var recipientEmail = contactEmails[0].Data; + var mimeMessage = new MimeMessage + { + Subject = _subject + }; - if (!recipientEmail.TestEmailRegex()) - { - Error += string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail) + - "
    "; - continue; - } + mimeMessage.From.Add(from); + mimeMessage.To.Add(to); - var to = new MailboxAddress(recipientEmail); + var bodyBuilder = new BodyBuilder + { + HtmlBody = templateManager.Apply(_bodyTempate, contactID) + }; - var mimeMessage = new MimeMessage - { - Subject = _subject - }; + foreach (var filePath in filePaths) + { + bodyBuilder.Attachments.Add(filePath); + } - mimeMessage.From.Add(from); - mimeMessage.To.Add(to); + mimeMessage.Body = bodyBuilder.ToMessageBody(); - var bodyBuilder = new BodyBuilder - { - HtmlBody = templateManager.Apply(_bodyTempate, contactID) - }; + mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); - foreach (var filePath in filePaths) - { - bodyBuilder.Attachments.Add(filePath); - } + _log.Debug(GetLoggerRow(mimeMessage)); - mimeMessage.Body = bodyBuilder.ToMessageBody(); + var success = false; - mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); + try + { + smtpClient.Send(mimeMessage); - _log.Debug(GetLoggerRow(mimeMessage)); + success = true; + } + catch (SmtpCommandException ex) + { + _log.Error(Error, ex); - var success = false; + Error += string.Format(CRMCommonResource.MailSender_FailedDeliverException, recipientEmail) + "
    "; + } - try + if (success) + { + if (_storeInHistory) { - smtpClient.Send(mimeMessage); - - success = true; + AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), DaoFactory); } - catch (SmtpCommandException ex) - { - _log.Error(Error, ex); - Error += string.Format(CRMCommonResource.MailSender_FailedDeliverException, recipientEmail) + "
    "; - } + var endDate = DateTime.Now; + var waitInterval = endDate.Subtract(startDate); - if (success) + deliveryCount++; + + var estimatedTime = + TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); + + Status = new { - if (_storeInHistory) - { - AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), _daoFactory); - } + RecipientCount = _contactID.Count, + EstimatedTime = estimatedTime.ToString(), + DeliveryCount = deliveryCount + }; + } - var endDate = DateTime.Now; - var waitInterval = endDate.Subtract(startDate); + if (MailSenderDataCache.CheckCancelFlag()) + { + MailSenderDataCache.ResetAll(); - deliveryCount++; + throw new OperationCanceledException(); + } - var estimatedTime = - TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = estimatedTime.ToString(), - DeliveryCount = deliveryCount - }; - } + if (Percentage > 100) + { + Percentage = 100; if (MailSenderDataCache.CheckCancelFlag()) { @@ -345,44 +358,66 @@ public void RunJob() MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - if (Percentage > 100) - { - Percentage = 100; - - if (MailSenderDataCache.CheckCancelFlag()) - { - MailSenderDataCache.ResetAll(); - - throw new OperationCanceledException(); - } - - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - - } } } - catch (OperationCanceledException) - { - _log.Debug("cancel mail sender"); - } - finally + } + catch (OperationCanceledException) + { + _log.Debug("cancel mail sender"); + } + finally + { + foreach (var filePath in filePaths) { - foreach (var filePath in filePaths) + if (File.Exists(filePath)) { - if (File.Exists(filePath)) - { - File.Delete(filePath); - } + File.Delete(filePath); } } - - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = TimeSpan.Zero.ToString(), - DeliveryCount = deliveryCount - }; } + + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = TimeSpan.Zero.ToString(), + DeliveryCount = deliveryCount + }; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } catch (SocketException e) { @@ -802,9 +837,9 @@ private String Apply(String template, IEnumerable templateTags, var result = template; - var contactDao = _daoFactory.ContactDao; - var contactInfoDao = _daoFactory.ContactInfoDao; - var customFieldDao = _daoFactory.CustomFieldDao; + var contactDao = _daoFactory.GetContactDao(); + var contactInfoDao = _daoFactory.GetContactInfoDao(); + var customFieldDao = _daoFactory.GetCustomFieldDao(); var contact = contactDao.GetByID(contactID); @@ -1014,7 +1049,7 @@ public List GetTags(bool isCompany) var entityType = isCompany ? EntityType.Company : EntityType.Person; - var customFieldsDao = _daoFactory.CustomFieldDao; + var customFieldsDao = _daoFactory.GetCustomFieldDao(); var customFields = customFieldsDao.GetFieldsDescription(entityType); diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index 3166b7a4b47..df38220752a 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -32,6 +32,7 @@ using ASC.Common.Web; using ASC.Core; using Microsoft.AspNetCore.Http; +using ASC.CRM.Core.Enums; namespace ASC.Web.CRM.Classes { From 083d25bcd672e38c70ed6f21b3b13fdc4a2e1955 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 24 Feb 2021 19:50:07 +0300 Subject: [PATCH 15/61] =?UTF-8?q?CRM:=20=D0=BF=D1=80=D0=BE=D0=B4=D0=BE?= =?UTF-8?q?=D0=BB=D0=B6=D0=B0=D1=8E=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D0=B8=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ASC.Web.sln | 8 +- config/nlog.config | 2 +- products/ASC.CRM/Server/ASC.CRM.csproj | 7 +- products/ASC.CRM/Server/Classes/Global.cs | 79 +------ .../Server/Configuration/VoipModule.cs | 44 ++-- .../ASC.CRM/Server/Controllers/CRMCalendar.cs | 17 +- .../Server/Controllers/CRMController.Cases.cs | 4 - .../Controllers/CRMController.Contacts.cs | 179 ++++++++------- .../Server/Controllers/CRMController.cs | 22 -- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 5 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 25 +- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 80 +++---- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 103 +++------ .../Server/Core/Dao/CurrencyInfoDao.cs | 26 +-- .../Server/Core/Dao/CurrencyRateDao.cs | 20 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 33 +-- .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 33 --- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 48 ++-- .../Server/Core/Dao/DealMilestoneDao.cs | 33 ++- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 20 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 37 ++- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 28 +-- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 26 +-- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 25 +- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 26 +-- .../Server/Core/Dao/RelationshipEventDao.cs | 48 ++-- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 23 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 56 ++--- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 25 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 39 +--- .../Core/Dao/TaskTemplateContainerDao.cs | 29 +-- .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 215 +----------------- products/ASC.CRM/Server/Core/EF/DbCase.cs | 72 +++++- products/ASC.CRM/Server/Core/EF/DbContact.cs | 113 ++++++++- .../ASC.CRM/Server/Core/EF/DbContactInfo.cs | 30 ++- .../ASC.CRM/Server/Core/EF/DbCurrencyRate.cs | 3 + products/ASC.CRM/Server/Core/EF/DbDeal.cs | 164 +++++++++---- .../ASC.CRM/Server/Core/EF/DbFieldValue.cs | 80 ++++++- products/ASC.CRM/Server/Core/EF/DbInvoice.cs | 26 ++- .../Server/Core/EF/DbRelationshipEvent.cs | 86 ++++++- products/ASC.CRM/Server/Core/EF/DbTask.cs | 96 +++++++- .../Server/Core/Search/BundleSearch.cs | 179 ++++----------- .../Server/Core/Search/CasesWrapper.cs | 70 ------ .../Server/Core/Search/ContactsWrapper.cs | 110 --------- .../Server/Core/Search/DealsWrapper.cs | 73 ------ .../Server/Core/Search/EmailWrapper.cs | 142 ------------ .../Server/Core/Search/EventsWrapper.cs | 81 ------- .../Server/Core/Search/FactoryIndexerCase.cs | 102 +++++++++ .../Core/Search/FactoryIndexerContact.cs | 102 +++++++++ .../Core/Search/FactoryIndexerContactInfo.cs | 104 +++++++++ .../Server/Core/Search/FactoryIndexerDeal.cs | 74 ++++++ .../Core/Search/FactoryIndexerEvents.cs | 99 ++++++++ .../Core/Search/FactoryIndexerFieldValue.cs | 103 +++++++++ .../Core/Search/FactoryIndexerInvoice.cs | 102 +++++++++ .../Server/Core/Search/FactoryIndexerTask.cs | 100 ++++++++ .../Server/Core/Search/FieldsWrapper.cs | 81 ------- .../ASC.CRM/Server/Core/Search/InfoWrapper.cs | 127 ----------- .../Server/Core/Search/InvoicesWrapper.cs | 81 ------- .../Server/Core/Search/TasksWrapper.cs | 74 ------ .../Server/Core/Security/CRMSecutiry.cs | 20 +- .../Server/HttpHandlers/FileHandler.ashx.cs | 13 +- products/ASC.CRM/Server/Model/CasesWrapper.cs | 13 +- .../Server/Model/ContactInfoWrapper.cs | 12 +- .../ASC.CRM/Server/Model/ContactWrapper.cs | 26 +-- .../Server/Model/CurrencyInfoWrapper.cs | 27 +-- .../Server/Model/CurrencyRateWrapper.cs | 18 +- .../ASC.CRM/Server/Model/InvoiceWrapper.cs | 90 ++------ .../Server/Model/OpportunityWrapper.cs | 16 +- .../Server/Model/RelationshipEventWrapper.cs | 30 +-- products/ASC.CRM/Server/Model/TaskWrapper.cs | 13 +- products/ASC.CRM/Server/Startup.cs | 105 +-------- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 15 +- .../ASC.Files/Core/Core/FilesIntegration.cs | 2 +- 73 files changed, 1880 insertions(+), 2359 deletions(-) delete mode 100644 products/ASC.CRM/Server/Core/Search/CasesWrapper.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/DealsWrapper.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/EmailWrapper.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/EventsWrapper.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs create mode 100644 products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/InfoWrapper.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs delete mode 100644 products/ASC.CRM/Server/Core/Search/TasksWrapper.cs diff --git a/ASC.Web.sln b/ASC.Web.sln index f6670794de8..e00cdd70adf 100644 --- a/ASC.Web.sln +++ b/ASC.Web.sln @@ -75,7 +75,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .editorconfig = .editorconfig EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.Data.Encryption", "common\ASC.Data.Encryption\ASC.Data.Encryption.csproj", "{C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Encryption", "common\ASC.Data.Encryption\ASC.Data.Encryption.csproj", "{C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.CRM", "products\ASC.CRM\Server\ASC.CRM.csproj", "{C8982CA1-AE34-4837-AFDB-2CB0CB838A76}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -215,6 +217,10 @@ Global {C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}.Debug|Any CPU.Build.0 = Debug|Any CPU {C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}.Release|Any CPU.ActiveCfg = Release|Any CPU {C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}.Release|Any CPU.Build.0 = Release|Any CPU + {C8982CA1-AE34-4837-AFDB-2CB0CB838A76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8982CA1-AE34-4837-AFDB-2CB0CB838A76}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8982CA1-AE34-4837-AFDB-2CB0CB838A76}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8982CA1-AE34-4837-AFDB-2CB0CB838A76}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/config/nlog.config b/config/nlog.config index 28fd9b092e1..d208716642a 100644 --- a/config/nlog.config +++ b/config/nlog.config @@ -20,6 +20,6 @@ - + \ No newline at end of file diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 78792265552..68e870f818f 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -1,4 +1,4 @@ - + netcoreapp3.1 @@ -28,9 +28,8 @@ - - - + + diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 8cfa564e1eb..f8fd05aa44b 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -48,6 +48,7 @@ namespace ASC.Web.CRM.Classes { + [Transient] public class Global { public Global(StorageFactory storageFactory, @@ -201,67 +202,6 @@ public void SaveDefaultCurrencySettings(CurrencyInfo currency) // } //} - //Code snippet - - public static String GetUpButtonHTML(Uri requestUrlReferrer) - { - return String.Format(@"", - CRMCommonResource.Up, - requestUrlReferrer != null ? "href='" + requestUrlReferrer.OriginalString + "'" : "", - requestUrlReferrer != null ? "" : " disable"); - } - - public static String RenderItemHeaderWithMenu(String title, EntityType entityType, Boolean isPrivate, Boolean canEdit) - { - var sbIcon = new StringBuilder(); - var sbPrivateMark = new StringBuilder(); - - string titleIconClass; - switch (entityType) - { - case EntityType.Contact: - titleIconClass = "group"; - break; - case EntityType.Person: - titleIconClass = "people"; - break; - case EntityType.Company: - titleIconClass = "company"; - break; - case EntityType.Case: - titleIconClass = "cases"; - break; - case EntityType.Opportunity: - titleIconClass = "opportunities"; - break; - case EntityType.Invoice: - titleIconClass = "documents"; - break; - default: - titleIconClass = string.Empty; - break; - } - if (!String.IsNullOrEmpty(titleIconClass)) - { - if (isPrivate) - { - sbPrivateMark.AppendFormat("
    ", CRMCommonResource.Private); - } - sbIcon.AppendFormat("{1}", titleIconClass, sbPrivateMark); - } - - return String.Format(@"
    - {0}{1} - {2} -
    - ", - sbIcon, - title, - canEdit ? "" : "" - ); - } - - /// /// The method to Decode your Base64 strings. /// @@ -351,21 +291,4 @@ public static JObject JObjectParseWithDateAsString(string data) return JObject.Load(reader); } } - - public static class GlobalExtention - { - public static DIHelper AddGlobalService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddStorageFactoryService() - .AddSecurityContextService() - .AddSetupInfo() - .AddFilesLinkUtilityService() - .AddCRMSecurityService() - .AddTenantManagerService() - .AddSettingsManagerService() - .AddPdfCreatorService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Configuration/VoipModule.cs b/products/ASC.CRM/Server/Configuration/VoipModule.cs index 69c84f8b614..f8388010e6a 100644 --- a/products/ASC.CRM/Server/Configuration/VoipModule.cs +++ b/products/ASC.CRM/Server/Configuration/VoipModule.cs @@ -24,6 +24,7 @@ */ +using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.Web.Core; using ASC.Web.Core.WebZones; @@ -33,8 +34,18 @@ namespace ASC.Web.CRM.Configuration { [WebZone(WebZoneType.CustomProductList)] - public class VoipModule : IAddon, IRenderCustomNavigation + public class VoipModule : IAddon { + public VoipModule(PathProvider pathProvider, + SetupInfo setupInfo) + { + PathProvider = pathProvider; + SetupInfo = setupInfo; + } + + public PathProvider PathProvider { get; } + public SetupInfo SetupInfo { get; } + public Guid ID { get { return WebItemManager.VoipModuleID; } @@ -62,7 +73,7 @@ public string HelpURL public string ProductClassName { get { return "voip"; } } - public bool Visible { get { return SetupInfo.VoipEnabled == "true"; } } + public bool Visible { get { return SetupInfo.VoipEnabled; } } public AddonContext Context { get; private set; } @@ -86,33 +97,6 @@ WebItemContext IWebItem.Context get { return Context; } } - public Control LoadCustomNavigationControl(Page page) - { - return null; - } - - public string RenderCustomNavigation(Page page) - { - try - { - if (!VoipNumberData.CanMakeOrReceiveCall) return string.Empty; - } - catch (Exception) - { - return string.Empty; - } - page.RegisterBodyScripts("~/js/asc/core/voip.navigationitem.js"); - - return - string.Format(@"
  • - - - {2} - -
  • ", - "VoIP", - WebPath.GetPath("/"), - 0); - } + public string ApiURL => throw new NotImplementedException(); } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs index e22e7c38446..29a89f55e37 100644 --- a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs +++ b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs @@ -39,6 +39,7 @@ namespace ASC.Api.CRM { + [Scope] public sealed class CRMCalendar : BaseCalendar { [AllDayLongUTCAttribute] @@ -129,20 +130,4 @@ private bool IsVisibleEvent(DateTime startDate, DateTime endDate, DateTime event (eventStartDate < startDate && eventEndDate > endDate); } } - - - public static class CRMCalendarDaoExtention - { - public static DIHelper AddCRMCalendarService(this DIHelper services) - { - services.TryAddScoped(); - services.TryAddScoped(); - - return services.AddWebItemManagerSecurity() - .AddDaoFactoryService() - .AddAuthContextService() - .AddTenantManagerService() - .AddTenantUtilService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs index 0799c4467bb..071f9366fd6 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs @@ -139,8 +139,6 @@ public CasesWrapper CreateCases( CreateOn = DateTime.UtcNow }; - FactoryIndexerCasesWrapper.IndexAsync(Web.CRM.Core.Search.CasesWrapper.GetCasesWrapper(ServiceProvider, cases)); - SetAccessToCases(cases, isPrivate, accessList, isNotify, false); var membersList = members != null ? members.ToList() : new List(); @@ -498,8 +496,6 @@ public CasesWrapper DeleteCase(int caseid) if (cases == null) throw new ItemNotFoundException(); - FactoryIndexerCasesWrapper.DeleteAsync(Web.CRM.Core.Search.CasesWrapper.GetCasesWrapper(ServiceProvider, cases)); - MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); return CasesWrapperHelper.Get(cases); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs index aecd1157b1b..ed4dac1f613 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs @@ -38,13 +38,17 @@ using ASC.Web.Api.Routing; using ASC.Web.CRM.Classes; using ASC.Web.Studio.Core; + using Autofac; + using Microsoft.AspNetCore.Http; + using System; using System.Collections.Generic; using System.Linq; using System.Security; using System.Web; + using Contact = ASC.CRM.Core.Entities.Contact; namespace ASC.Api.CRM @@ -74,9 +78,9 @@ public ContactWrapper GetContactByID(int contactid) public IEnumerable GetContactsByID(IEnumerable contactid) { var contacts = DaoFactory.GetContactDao().GetContacts(contactid.ToArray()).Where(r => r != null && CRMSecurity.CanAccessTo(r)); - + return ToListContactWrapper(contacts.ToList()); - + } /// @@ -150,7 +154,7 @@ public IEnumerable GetContactsByProjectID(int projectid) //public IEnumerable SetRelativeContactListToProject(IEnumerable contactid, int projectid) //{ // if (contactid == null) throw new ArgumentException(); - + // var contactIds = contactid.ToList(); // if (!contactIds.Any() || projectid <= 0) throw new ArgumentException(); @@ -233,7 +237,7 @@ public OpportunityWrapper AddDealToContact(int contactid, int opportunityid) DaoFactory.GetDealDao().AddMember(opportunityid, contactid); var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), opportunity.Title, contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), opportunity.Title, contact.GetTitle()); return OpportunityWrapperHelper.Get(opportunity); } @@ -581,7 +585,7 @@ public IEnumerable DeleteBatchContacts( contacts = DaoFactory.GetContactDao().DeleteBatchContact(contacts); - MessageService.Send( MessageAction.ContactsDeleted, MessageTarget.Create(contacts.Select(c => c.ID)), contacts.Select(c => c.GetTitle())); + MessageService.Send(MessageAction.ContactsDeleted, MessageTarget.Create(contacts.Select(c => c.ID)), contacts.Select(c => c.GetTitle())); return contacts.Select(x => ContactWrapperHelper.GetContactBaseWrapper(x)); } @@ -631,8 +635,8 @@ public PersonWrapper AddPeopleToCompany(int companyid, int personid) if (person == null || company == null || !CRMSecurity.CanAccessTo(person) || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); DaoFactory.GetContactDao().AddMember(personid, companyid); - - MessageService.Send( MessageAction.CompanyLinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); + + MessageService.Send(MessageAction.CompanyLinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); return (PersonWrapper)ContactWrapperHelper.GetContactWrapper(person); } @@ -660,7 +664,7 @@ public PersonWrapper DeletePeopleFromCompany(int companyid, int personid) DaoFactory.GetContactDao().RemoveMember(personid); - MessageService.Send( MessageAction.CompanyUnlinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); + MessageService.Send(MessageAction.CompanyUnlinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); return (PersonWrapper)ContactWrapperHelper.GetContactWrapper(person); } @@ -693,20 +697,21 @@ public PersonWrapper CreatePerson( IEnumerable> customFieldList, IEnumerable photo) { - if (companyId > 0) { + if (companyId > 0) + { var company = DaoFactory.GetContactDao().GetByID(companyId); if (company == null || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); } var peopleInst = new Person - { - FirstName = firstName, - LastName = lastName, - JobTitle = jobTitle, - CompanyID = companyId, - About = about, - ShareType = shareType - }; + { + FirstName = firstName, + LastName = lastName, + JobTitle = jobTitle, + CompanyID = companyId, + About = about, + ShareType = shareType + }; peopleInst.ID = DaoFactory.GetContactDao().SaveContact(peopleInst); peopleInst.CreateBy = SecurityContext.CurrentAccount.ID; @@ -736,7 +741,7 @@ public PersonWrapper CreatePerson( wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); } - MessageService.Send( MessageAction.PersonCreated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); + MessageService.Send(MessageAction.PersonCreated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); return wrapper; } @@ -759,7 +764,7 @@ public string ChangeContactPhoto(int contactid, IEnumerable photo) throw new ArgumentException(); var contact = DaoFactory.GetContactDao().GetByID(contactid); - + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); @@ -769,9 +774,9 @@ public string ChangeContactPhoto(int contactid, IEnumerable photo) throw new ArgumentException(); var fileStream = firstPhoto.OpenReadStream(); - + if (firstPhoto.Length == 0 || - !firstPhoto.ContentType.StartsWith("image/") || + !firstPhoto.ContentType.StartsWith("image/") || !fileStream.CanRead) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); @@ -833,7 +838,7 @@ public ContactWrapper MergeContacts(int fromcontactid, int tocontactid) var resultContact = DaoFactory.GetContactDao().GetByID(tocontactid); var messageAction = resultContact is Person ? MessageAction.PersonsMerged : MessageAction.CompaniesMerged; - MessageService.Send( messageAction, MessageTarget.Create(new[] { fromContact.ID, toContact.ID }), fromContact.GetTitle(), toContact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(new[] { fromContact.ID, toContact.ID }), fromContact.GetTitle(), toContact.GetTitle()); return ContactWrapperHelper.GetContactWrapper(resultContact); } @@ -872,15 +877,15 @@ public PersonWrapper UpdatePerson( if (personid <= 0 || string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) throw new ArgumentException(); var peopleInst = new Person - { - ID = personid, - FirstName = firstName, - LastName = lastName, - JobTitle = jobTitle, - CompanyID = companyId, - About = about, - ShareType = shareType - }; + { + ID = personid, + FirstName = firstName, + LastName = lastName, + JobTitle = jobTitle, + CompanyID = companyId, + About = about, + ShareType = shareType + }; DaoFactory.GetContactDao().UpdateContact(peopleInst); @@ -911,7 +916,7 @@ public PersonWrapper UpdatePerson( wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); } - MessageService.Send( MessageAction.PersonUpdated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); + MessageService.Send(MessageAction.PersonUpdated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); return wrapper; } @@ -941,11 +946,11 @@ public CompanyWrapper CreateCompany( IEnumerable photo) { var companyInst = new Company - { - CompanyName = companyName, - About = about, - ShareType = shareType - }; + { + CompanyName = companyName, + About = about, + ShareType = shareType + }; companyInst.ID = DaoFactory.GetContactDao().SaveContact(companyInst); companyInst.CreateBy = SecurityContext.CurrentAccount.ID; @@ -986,7 +991,7 @@ public CompanyWrapper CreateCompany( wrapper.SmallFotoUrl = ChangeContactPhoto(companyInst.ID, photoList); } - MessageService.Send( MessageAction.CompanyCreated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + MessageService.Send(MessageAction.CompanyCreated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); return wrapper; } @@ -1014,18 +1019,18 @@ public IEnumerable CreateCompany(IEnumerable company if (string.IsNullOrEmpty(item)) continue; contacts.Add(new Company - { - ID = recordIndex++, - CompanyName = item, - ShareType = ShareType.None - }); + { + ID = recordIndex++, + CompanyName = item, + ShareType = ShareType.None + }); } if (contacts.Count == 0) return null; DaoFactory.GetContactDao().SaveContactList(contacts); - var selectedManagers = new List {SecurityContext.CurrentAccount.ID}; + var selectedManagers = new List { SecurityContext.CurrentAccount.ID }; foreach (var ct in contacts) { @@ -1064,26 +1069,26 @@ public IEnumerable CreatePerson(IEnumerable {SecurityContext.CurrentAccount.ID}; + var selectedManagers = new List { SecurityContext.CurrentAccount.ID }; foreach (var ct in contacts) { CRMSecurity.SetAccessTo(ct, selectedManagers); } - MessageService.Send( MessageAction.PersonsCreated, MessageTarget.Create(contacts.Select(x => x.ID)), contacts.Select(x => x.GetTitle())); + MessageService.Send(MessageAction.PersonsCreated, MessageTarget.Create(contacts.Select(x => x.ID)), contacts.Select(x => x.GetTitle())); return contacts.ConvertAll(x => ContactWrapperHelper.GetContactBaseWrapper(x)); } @@ -1113,18 +1118,18 @@ public CompanyWrapper UpdateCompany( IEnumerable> customFieldList) { var companyInst = new Company - { - ID = companyid, - CompanyName = companyName, - About = about, - ShareType = shareType - }; + { + ID = companyid, + CompanyName = companyName, + About = about, + ShareType = shareType + }; DaoFactory.GetContactDao().UpdateContact(companyInst); companyInst = (Company)DaoFactory.GetContactDao().GetByID(companyInst.ID); - var managerListLocal = managerList != null ? managerList.ToList(): new List(); + var managerListLocal = managerList != null ? managerList.ToList() : new List(); if (managerListLocal.Any()) { CRMSecurity.SetAccessTo(companyInst, managerListLocal); @@ -1140,7 +1145,7 @@ public CompanyWrapper UpdateCompany( } } - MessageService.Send( MessageAction.CompanyUpdated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + MessageService.Send(MessageAction.CompanyUpdated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); return (CompanyWrapper)ContactWrapperHelper.GetContactWrapper(companyInst); } @@ -1175,11 +1180,11 @@ public ContactWrapper UpdateContactStatus(int contactid, int contactStatusid) if (!CRMSecurity.CanEdit(companyInst)) throw CRMSecurity.CreateSecurityException(); - dao.UpdateContactStatus(new List{companyInst.ID}, contactStatusid); + dao.UpdateContactStatus(new List { companyInst.ID }, contactStatusid); companyInst.StatusID = contactStatusid; var messageAction = companyInst is Company ? MessageAction.CompanyUpdatedTemperatureLevel : MessageAction.PersonUpdatedTemperatureLevel; - MessageService.Send( messageAction, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); return ContactWrapperHelper.GetContactWrapper(companyInst); } @@ -1298,8 +1303,8 @@ public ContactWrapper UpdatePersonAndItsCompanyStatus(int personid, int contactS dao.UpdateContactStatus(forUpdateStatus, contactStatusid); } - MessageService.Send( MessageAction.PersonUpdatedTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); - MessageService.Send( MessageAction.PersonUpdatedCompanyTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); + MessageService.Send(MessageAction.PersonUpdatedTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); + MessageService.Send(MessageAction.PersonUpdatedCompanyTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); personInst = dao.GetByID(personInst.ID); return ContactWrapperHelper.GetContactWrapper(personInst); @@ -1370,11 +1375,11 @@ private void SetAccessToContact(Contact contact, bool isShared, IEnumerable n != SecurityContext.CurrentAccount.ID).ToArray(); - + if (contact is Person) - NotifyClient.SendAboutSetAccess(EntityType.Person, contact.ID, DaoFactory, notifyUsers); + NotifyClient.SendAboutSetAccess(EntityType.Person, contact.ID, DaoFactory, notifyUsers); else - NotifyClient.SendAboutSetAccess(EntityType.Company, contact.ID, DaoFactory, notifyUsers); + NotifyClient.SendAboutSetAccess(EntityType.Company, contact.ID, DaoFactory, notifyUsers); } @@ -1405,7 +1410,7 @@ private void SetAccessToContact(Contact contact, bool isShared, IEnumerable SetAccessToBatchContact(IEnumerable contactid, bool isShared, IEnumerable managerList) { if (contactid == null) throw new ArgumentException(); - + var result = new List(); foreach (var id in contactid) @@ -1498,7 +1503,7 @@ public ContactWrapper DeleteContact(int contactid) if (contact == null) throw new ItemNotFoundException(); var messageAction = contact is Person ? MessageAction.PersonDeleted : MessageAction.CompanyDeleted; - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); return ContactWrapperHelper.GetContactWrapper(contact); } @@ -1520,7 +1525,7 @@ public IEnumerable DeleteBatchContacts(IEnumerable cont if (contactids == null) throw new ArgumentException(); var contacts = DaoFactory.GetContactDao().DeleteBatchContact(contactids.ToArray()); - MessageService.Send( MessageAction.ContactsDeleted, MessageTarget.Create(contactids), contacts.Select(c => c.GetTitle())); + MessageService.Send(MessageAction.ContactsDeleted, MessageTarget.Create(contactids), contacts.Select(c => c.GetTitle())); return contacts.Select(x => ContactWrapperHelper.GetContactBaseWrapper(x)); } @@ -1580,7 +1585,7 @@ public IEnumerable GetContactsByPrefix(string prefi result.AddRange(findedContacts.Select(x => ContactWrapperHelper.GetContactBaseWithPhoneWrapper(x))); ApiContext.SetTotalCount(findedContacts.Count); - + } else { @@ -1588,9 +1593,9 @@ public IEnumerable GetContactsByPrefix(string prefi if (searchType < -1 || searchType > 3) throw new ArgumentException(); allContacts = DaoFactory.GetContactDao().GetContactsByPrefix(prefix, searchType, 0, maxItemCount); - + result.AddRange(allContacts.Select(x => ContactWrapperHelper.GetContactBaseWithPhoneWrapper(x))); - + } return result; @@ -1615,7 +1620,7 @@ public IEnumerable GetContactsByContactInfo(ContactInfoType? inf var ids = DaoFactory.GetContactDao().GetContactIDsByContactInfo(infoType.Value, data, category, isPrimary); - var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x=> ContactWrapperHelper.GetContactWrapper(x)); + var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => ContactWrapperHelper.GetContactWrapper(x)); return result; } @@ -1880,7 +1885,7 @@ public void SetContactLastModifedDate(int contactId, ApiDateTime lastModifedDate dao.SetContactLastModifedDate(contactId, lastModifedDate); } - + private ContactPhotoManager.PhotoData UploadAvatar(int contactID, string imageUrl, bool uploadOnly, string tmpDirName, bool checkFormat = true) { @@ -1970,7 +1975,7 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly { if (!contactInfos.ContainsKey(item.ContactID)) { - contactInfos.Add(item.ContactID, new List {ContactInfoWrapperHelper.Get(item)}); + contactInfos.Add(item.ContactID, new List { ContactInfoWrapperHelper.Get(item) }); } else { @@ -2037,10 +2042,10 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly } result.Add(new ContactWithTaskWrapper - { - Contact = contactWrapper, - Task = taskWrapper - }); + { + Contact = contactWrapper, + Task = taskWrapper + }); } @@ -2060,6 +2065,15 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly return result; } + private ContactWrapper ToContactWrapper(Contact contact) + { + return ToListContactWrapper(new List + { + contact + }).Single(); + } + + private IEnumerable ToListContactWrapper(IReadOnlyList itemList) { if (itemList.Count == 0) return new List(); @@ -2107,7 +2121,8 @@ private IEnumerable ToListContactWrapper(IReadOnlyList var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactWrapperHelper.GetContactBaseWrapperQuick(item)); var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); - foreach (var contactBaseWrapperQuick in tmpList) { + foreach (var contactBaseWrapperQuick in tmpList) + { contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.Id]; peopleCompanyList.Add(contactBaseWrapperQuick.Id, contactBaseWrapperQuick); } @@ -2147,7 +2162,7 @@ private IEnumerable ToListContactWrapper(IReadOnlyList else { if (!contactInfos.ContainsKey(item.ContactID)) - contactInfos.Add(item.ContactID, new List { ContactInfoWrapperHelper.Get(item)}); + contactInfos.Add(item.ContactID, new List { ContactInfoWrapperHelper.Get(item) }); else contactInfos[item.ContactID].Add(ContactInfoWrapperHelper.Get(item)); } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Controllers/CRMController.cs index 5f20bdd77fe..e41543fa28b 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.cs @@ -186,8 +186,6 @@ public CRMController(CRMSecurity cRMSecurity, public InvoiceBaseWrapperHelper InvoiceBaseWrapperHelper { get; } public InvoiceItemWrapperHelper InvoiceItemWrapperHelper { get; } public InvoiceWrapperHelper InvoiceWrapperHelper { get; } - - public FactoryIndexer FactoryIndexerInfoWrapper { get; } public FactoryIndexer FactoryIndexerEmailWrapper { get; } public FactoryIndexer FactoryIndexerFieldsWrapper { get; } @@ -276,24 +274,4 @@ private string GetEntityTitle(EntityType entityType, int entityId, bool checkAcc } } } - - public static class CRMControllerExtention - { - public static DIHelper AddCRMControllerService(this DIHelper services) - { - return services.AddCRMSecurityService() - .AddDaoFactoryService() - .AddApiContextService() - .AddGlobalService() - .AddMessageTargetService() - .AddTaskWrapperHelperService() - .AddFileStorageService() - .AddNotifyClientService() - .AddSecurityContextService() - .AddUserManagerService() - .AddCurrencyProviderService(); - - } - } - } diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index a7b94050044..7b9b138276a 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -53,13 +53,14 @@ public AbstractDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger + IOptionsMonitor logger, + AscCache ascCache ) { Logger = logger.Get("ASC.CRM"); - _cache = AscCache.Memory; + _cache = ascCache; CRMDbContext = dbContextManager.Get(CRMConstants.DatabaseId); TenantID = tenantManager.GetCurrentTenant().TenantId; SecurityContext = securityContext; diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 18e76eb98bd..61fec2034a5 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -46,6 +46,7 @@ using Microsoft.Extensions.Options; using ASC.Common.Logging; using ASC.Common; +using ASC.Common.Caching; namespace ASC.CRM.Core.Dao { @@ -61,6 +62,7 @@ public CachedCasesDao(DbContextManager dbContextManager, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, IOptionsMonitor logger, + AscCache ascCache, IHttpContextAccessor httpContextAccessor, BundleSearch bundleSearch) : @@ -72,6 +74,7 @@ public CachedCasesDao(DbContextManager dbContextManager, filesIntegration, authorizationManager, logger, + ascCache, bundleSearch) { @@ -109,6 +112,7 @@ private void ResetCache(int taskID) } } + [Scope] public class CasesDao : AbstractDao { public CasesDao( @@ -120,12 +124,14 @@ public CasesDao( FilesIntegration filesIntegration, AuthorizationManager authorizationManager, IOptionsMonitor logger, + AscCache ascCache, BundleSearch bundleSearch ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; @@ -684,21 +690,4 @@ public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) } } } - - public static class CasesDaoExtention - { - public static DIHelper AddCasesDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddCRMSecurityService() - .AddTenantUtilService() - .AddFilesIntegrationService() - .AddAuthorizationManagerService() - .AddBundleSearchService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index bd808cdbde7..dc556a41a97 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -62,9 +63,10 @@ public CachedContactDao( TenantUtil tenantUtil, AuthorizationManager authorizationManager, FilesIntegration filesIntegration, - FactoryIndexer factoryIndexerContactsWrapper, - FactoryIndexer factoryIndexerEmailWrapper, + FactoryIndexerContact factoryIndexerContact, + FactoryIndexerContactInfo factoryIndexerContactInfo, IOptionsMonitor logger, + AscCache ascCache, DbContextManager coreDbContext, BundleSearch bundleSearch) : base(dbContextManager, @@ -74,9 +76,10 @@ public CachedContactDao( tenantUtil, authorizationManager, filesIntegration, - factoryIndexerContactsWrapper, - factoryIndexerEmailWrapper, + factoryIndexerContact, + factoryIndexerContactInfo, logger, + ascCache, coreDbContext, bundleSearch) { @@ -126,6 +129,7 @@ private void ResetCache(int contactID) } } + [Scope] public class ContactDao : AbstractDao { public ContactDao( @@ -136,31 +140,35 @@ public ContactDao( TenantUtil tenantUtil, AuthorizationManager authorizationManager, FilesIntegration filesIntegration, - FactoryIndexer factoryIndexerContactsWrapper, - FactoryIndexer factoryIndexerEmailWrapper, + FactoryIndexerContact factoryIndexerContact, + FactoryIndexerContactInfo factoryIndexerContactInfo, IOptionsMonitor logger, + AscCache ascCache, DbContextManager coreDbContext, BundleSearch bundleSearch ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; AuthorizationManager = authorizationManager; FilesIntegration = filesIntegration; - FactoryIndexerContactsWrapper = factoryIndexerContactsWrapper; - FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; + FactoryIndexerContact = factoryIndexerContact; + FactoryIndexerContactInfo = factoryIndexerContactInfo; CoreDbContext = coreDbContext.Value; BundleSearch = bundleSearch; + } public BundleSearch BundleSearch { get; } public CoreDbContext CoreDbContext { get; } - public FactoryIndexer FactoryIndexerEmailWrapper { get; } - public FactoryIndexer FactoryIndexerContactsWrapper { get; } + public FactoryIndexerContact FactoryIndexerContact { get; } + public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } + public FilesIntegration FilesIntegration { get; } public AuthorizationManager AuthorizationManager { get; } public TenantUtil TenantUtil { get; } @@ -411,12 +419,14 @@ public List SearchContactsByEmail(string searchText, int maxCount) List contactsIds; - if (FactoryIndexerEmailWrapper.TrySelectIds(s => s.MatchAll(searchText), out contactsIds)) + IReadOnlyCollection dbContactInfos; + + if (FactoryIndexerContactInfo.TrySelect(s => s.MatchAll(searchText), out dbContactInfos)) { - if (!contactsIds.Any()) + if (!dbContactInfos.Any()) return contacts; - ids = contactsIds.Select(r => Convert.ToInt32(r)).ToList(); + ids = dbContactInfos.Select(r => r.Id).ToList(); } var isAdmin = CRMSecurity.IsAdmin; @@ -1271,12 +1281,10 @@ private void UpdateContactFromDb(Contact contact) CRMDbContext.Update(itemToUpdate); CRMDbContext.SaveChanges(); - // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); - FactoryIndexerContactsWrapper.UpdateAsync(contact); - + FactoryIndexerContact.Update(itemToUpdate); } public void UpdateContactStatus(IEnumerable contactid, int statusid) @@ -1394,7 +1402,9 @@ public void MakePublic(int contactId, bool isShared) public virtual int SaveContact(Contact contact) { var result = SaveContactToDb(contact); - FactoryIndexerContactsWrapper.IndexAsync(contact); + + FactoryIndexerContact.Index(Query(CRMDbContext.Contacts) + .Where(x => x.Id == contact.ID).Single()); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); @@ -1606,21 +1616,14 @@ public virtual Contact DeleteContact(int contactID) CRMSecurity.DemandDelete(contact); + FactoryIndexerContact.Delete(Query(CRMDbContext.Contacts) + .Where(x => x.Id == contactID).Single()); + DeleteBatchContactsExecute(new List() { contact }); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); - var person = contact as Person; - if (person != null) - { - FactoryIndexerContactsWrapper.DeleteAsync(person); - } - else - { - FactoryIndexerContactsWrapper.DeleteAsync(contact as Company); - } - return contact; } @@ -2082,24 +2085,5 @@ public void SetContactLastModifedDate(int contactId, DateTime lastModifedDate) // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } - } - - public static class ContactDaoExtention - { - public static DIHelper AddContactDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddCRMSecurityService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddTenantUtilService() - .AddAuthorizationManagerService() - .AddFilesIntegrationService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddBundleSearchService(); - } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index aff0d2112a0..c559cbe8ccd 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -53,8 +54,8 @@ public CachedContactInfo( SecurityContext securityContext, TenantUtil tenantUtil, IOptionsMonitor logger, - FactoryIndexer factoryIndexerEmailWrapper, - FactoryIndexer factoryIndexerInfoWrapper, + AscCache ascCache, + FactoryIndexerContactInfo factoryIndexerContactInfo, IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider ) @@ -64,8 +65,8 @@ IServiceProvider serviceProvider securityContext, tenantUtil, logger, - factoryIndexerEmailWrapper, - factoryIndexerInfoWrapper, + ascCache, + factoryIndexerContactInfo, serviceProvider) { _contactInfoCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact_info"); @@ -110,6 +111,7 @@ public override int Update(ContactInfo contactInfo) } + [Scope] public class ContactInfoDao : AbstractDao { public ContactInfoDao( @@ -118,25 +120,24 @@ public ContactInfoDao( SecurityContext securityContext, TenantUtil tenantUtil, IOptionsMonitor logger, - FactoryIndexer factoryIndexerEmailWrapper, - FactoryIndexer factoryIndexerInfoWrapper, + AscCache ascCache, + FactoryIndexerContactInfo factoryIndexerContactInfo, IServiceProvider serviceProvider) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { TenantUtil = tenantUtil; ServiceProvider = serviceProvider; - FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; - FactoryIndexerInfoWrapper = factoryIndexerInfoWrapper; + FactoryIndexerContactInfo = factoryIndexerContactInfo; } public IServiceProvider ServiceProvider { get; } public TenantUtil TenantUtil { get; } - public FactoryIndexer FactoryIndexerEmailWrapper { get; } - public FactoryIndexer FactoryIndexerInfoWrapper { get; } + public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } public virtual ContactInfo GetByID(int id) { @@ -153,8 +154,7 @@ public virtual void Delete(int id) CRMDbContext.ContactsInfo.Remove(itemToDelete); CRMDbContext.SaveChanges(); - FactoryIndexerEmailWrapper.DeleteAsync(r => r.Where(a => a.Id, id)); - + FactoryIndexerContactInfo.Delete(r => r.Where(a => a.Id, id)); } public virtual void DeleteByContact(int contactID) @@ -166,28 +166,15 @@ public virtual void DeleteByContact(int contactID) CRMDbContext.SaveChanges(); - FactoryIndexerInfoWrapper.DeleteAsync(r => r.Where(a => a.ContactId, contactID)); - - var infos = GetList(contactID, ContactInfoType.Email, null, null); - - FactoryIndexerEmailWrapper.Update(new EmailWrapper { Id = contactID, - EmailInfoWrapper = infos.Select(r => EmailInfoWrapper.FromContactInfo(TenantID, r)).ToList() }, - UpdateAction.Replace, r => r.EmailInfoWrapper); - + FactoryIndexerContactInfo.Delete(r => r.Where(a => a.ContactId, contactID)); } public virtual int Update(ContactInfo contactInfo) { var result = UpdateInDb(contactInfo); - - if (contactInfo.InfoType == ContactInfoType.Email) - { - var infos = GetList(contactInfo.ContactID, ContactInfoType.Email, null, null); - FactoryIndexerEmailWrapper.Update(new EmailWrapper { Id = contactInfo.ContactID, EmailInfoWrapper = infos.Select(r => EmailInfoWrapper.FromContactInfo(TenantID, r)).ToList() }, UpdateAction.Replace, r => r.EmailInfoWrapper); - } - - FactoryIndexerInfoWrapper.UpdateAsync(InfoWrapper.Get(ServiceProvider, contactInfo)); + FactoryIndexerContactInfo.Update(Query(CRMDbContext.ContactsInfo) + .Where(x => x.ContactId == contactInfo.ID).Single()); return result; } @@ -223,21 +210,12 @@ public int Save(ContactInfo contactInfo) var id = SaveInDb(contactInfo); contactInfo.ID = id; - - FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.Get(ServiceProvider, contactInfo)); - if (contactInfo.InfoType == ContactInfoType.Email) - { - FactoryIndexerEmailWrapper.Index(new EmailWrapper - { - Id = contactInfo.ContactID, - TenantId = TenantID, - EmailInfoWrapper = new List - { - EmailInfoWrapper.FromContactInfo(TenantID, contactInfo) - } - }); - } + var dbContactInfo = Query(CRMDbContext.ContactsInfo) + .Where(x => x.ContactId == contactInfo.ID) + .Single(); + + FactoryIndexerContactInfo.Index(dbContactInfo); return id; } @@ -321,12 +299,14 @@ public int[] UpdateList(List items, Contact contact = null) if (contact != null) { - - FactoryIndexerEmailWrapper.IndexAsync(EmailWrapper.GetEmailWrapper(TenantID, contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); + var itemIDs = items.Select(y => y.ID); - foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) + var dbContactInfos = Query(CRMDbContext.ContactsInfo) + .Where(x => itemIDs.Contains(x.Id)); + + foreach (var dbContactInfo in dbContactInfos) { - FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.Get(ServiceProvider, item)); + FactoryIndexerContactInfo.Index(dbContactInfo); } } @@ -352,13 +332,15 @@ public int[] SaveList(List items, Contact contact = null) if (contact != null) { - FactoryIndexerEmailWrapper.IndexAsync(EmailWrapper.GetEmailWrapper(TenantID, contact, items.Where(r => r.InfoType == ContactInfoType.Email).ToList())); - - foreach (var item in items.Where(r => r.InfoType != ContactInfoType.Email)) + var itemIDs = items.Select(y => y.ID); + + var dbContactInfos = Query(CRMDbContext.ContactsInfo) + .Where(x => itemIDs.Contains(x.Id)); + + foreach (var dbContactInfo in dbContactInfos) { - FactoryIndexerInfoWrapper.IndexAsync(InfoWrapper.Get(ServiceProvider, item)); + FactoryIndexerContactInfo.Index(dbContactInfo); } - } return result.ToArray(); @@ -379,21 +361,4 @@ protected static ContactInfo ToContactInfo(DbContactInfo dbContactInfo) }; } } - - - - public static class ContactInfoDaoExtention - { - public static DIHelper AddContactInfoDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddTenantUtilService() - .AddFactoryIndexerService() - .AddFactoryIndexerService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 706c41e33bc..2f9b904f1d6 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Linq; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -36,16 +37,19 @@ namespace ASC.CRM.Core.Dao { + [Scope] public class CurrencyInfoDao : AbstractDao { public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) : - base(dbContextManager, - tenantManager, - securityContext, - logger) + IOptionsMonitor logger, + AscCache ascCache) : + base(dbContextManager, + tenantManager, + securityContext, + logger, + ascCache) { @@ -90,16 +94,4 @@ private static CurrencyInfo ToCurrencyInfo(DbCurrencyInfo dbCurrencyInfo) ); } } - - public static class CurrencyInfoDaoExtention - { - public static DIHelper AddCurrencyInfoDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } } diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index 1e8ec09c627..249dda12c25 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -27,6 +27,7 @@ using System.Collections.Generic; using System.Linq; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -35,17 +36,20 @@ namespace ASC.CRM.Core.Dao { + [Scope] public class CurrencyRateDao : AbstractDao { public CurrencyRateDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) : + IOptionsMonitor logger, + AscCache ascCache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { } @@ -174,16 +178,4 @@ private static CurrencyRate ToCurrencyRate(DbCurrencyRate dbCurrencyRate) }; } } - - public static class CurrencyRateDaoExtention - { - public static DIHelper AddCurrencyRateDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index f8bc2b96864..b47c875f86d 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -24,6 +24,7 @@ */ using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -44,6 +45,7 @@ namespace ASC.CRM.Core.Dao { + [Scope] public class CustomFieldDao : AbstractDao { public CustomFieldDao( @@ -51,19 +53,21 @@ public CustomFieldDao( TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - IOptionsMonitor logger + IOptionsMonitor logger, + AscCache ascCache ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { TenantUtil = tenantUtil; } public TenantUtil TenantUtil { get; } - public FactoryIndexer FactoryIndexer { get; } + public FactoryIndexerFieldValue FactoryIndexer { get; } public void SaveList(List items) { @@ -122,16 +126,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, var id = dbFieldValue.Id; - FactoryIndexer.IndexAsync(new FieldsWrapper - { - Id = id, - EntityId = entityID, - EntityType = (int)entityType, - Value = fieldValue, - FieldId = fieldID, - LastModifiedOn = lastModifiedOn, - TenantId = TenantID - }); + FactoryIndexer.Index(dbFieldValue); } } @@ -582,16 +577,4 @@ public CustomField ToCustomField(DbFieldDescription dbFieldDescription, } } - public static class CustomFieldDaoExtention - { - public static DIHelper AddCustomFieldDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddTenantUtilService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 78652faaa53..d9fdc76ab4f 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -26,8 +26,6 @@ using Microsoft.Extensions.DependencyInjection; using ASC.VoipService.Dao; using System; -using ASC.Common; -using ASC.Core.Common.Settings; namespace ASC.CRM.Core.Dao { @@ -157,37 +155,6 @@ public VoipDao GetVoipDao() return ServiceProvider.GetService(); } } - - public static class DaoFactoryExtention - { - public static DIHelper AddDaoFactoryService(this DIHelper services) - { - services.TryAddScoped(); - - // return services; - return services.AddTaskDaoService() - .AddListItemDaoService() - .AddContactDaoService() - .AddCustomFieldDaoService() - .AddDealDaoService() - .AddDealMilestoneDaoService() - .AddTagDaoService() - .AddSearchDaoService() - .AddRelationshipEventDaoService() - .AddFileDaoService() - .AddCasesDaoService() - .AddTaskTemplateDaoService() - .AddTaskTemplateContainerDaoService() - // .AddReportDaoService() - .AddCurrencyRateDaoService() - .AddCurrencyInfoDaoService() - .AddContactInfoDaoService() - .AddInvoiceDaoService() - .AddInvoiceLineDaoService() - .AddInvoiceTaxDaoService() - .AddInvoiceLineDaoService(); - } - } } //TaskDao diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index a84fcac4f27..d44359a3fe2 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -57,10 +58,11 @@ public CachedDealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, CRMSecurity cRMSecurity, - FactoryIndexer factoryIndexer, + FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, + AscCache ascCache, BundleSearch bundleSearch) : base(dbContextManager, tenantManager, @@ -109,20 +111,23 @@ private void ResetCache(int dealID) } } + [Scope] public class DealDao : AbstractDao { public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, CRMSecurity cRMSecurity, - FactoryIndexer factoryIndexer, + FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, IOptionsMonitor logger, + AscCache ascCache, BundleSearch bundleSearch) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { CRMSecurity = cRMSecurity; FactoryIndexer = factoryIndexer; @@ -134,7 +139,7 @@ public DealDao(DbContextManager dbContextManager, public FilesIntegration FilesIntegration { get; } - public FactoryIndexer FactoryIndexer { get; } + public FactoryIndexerDeal FactoryIndexer { get; } public TenantUtil TenantUtil { get; } public CRMSecurity CRMSecurity { get; } @@ -190,8 +195,8 @@ public virtual int CreateNewDeal(Deal deal) var result = CreateNewDealInDb(deal); deal.ID = result; - - FactoryIndexer.IndexAsync(DealsWrapper.FromDeal(TenantID, deal)); + + FactoryIndexer.Index(Query(CRMDbContext.Deals).Where(x => x.Id == deal.ID).FirstOrDefault()); return result; } @@ -243,14 +248,13 @@ public virtual int[] SaveDealList(List items) var result = items.Select(item => CreateNewDealInDb(item)).ToArray(); tx.Commit(); - - foreach (var deal in items) + + foreach (var deal in Query(CRMDbContext.Deals).Where(x => result.Contains(x.Id))) { - FactoryIndexer.IndexAsync(DealsWrapper.FromDeal(TenantID, deal)); + FactoryIndexer.Index(deal); } return result; - } public virtual void EditDeal(Deal deal) @@ -285,7 +289,7 @@ public virtual void EditDeal(Deal deal) CRMDbContext.Update(itemToUpdate); CRMDbContext.SaveChanges(); - FactoryIndexer.IndexAsync(DealsWrapper.FromDeal(TenantID, deal)); + FactoryIndexer.Index(itemToUpdate); } @@ -793,13 +797,13 @@ public virtual Deal DeleteDeal(int dealID) CRMSecurity.DemandDelete(deal); + FactoryIndexer.Delete(Query(CRMDbContext.Deals).Where(x => x.Id == dealID).Single()); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); DeleteBatchDealsExecute(new List() { deal }); - FactoryIndexer.DeleteAsync(DealsWrapper.FromDeal(TenantID, deal)); - return deal; } @@ -973,21 +977,5 @@ public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); } - } - - public static class DealDaoExtention - { - public static DIHelper AddDealDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddCRMSecurityService() - .AddFactoryIndexerService() - .AddFilesIntegrationService() - .AddBundleSearchService(); - } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index f4da5b060ec..a200b42a154 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -28,6 +28,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -53,11 +54,14 @@ public CachedDealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger) + IOptionsMonitor logger, + AscCache ascCache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache + ) { _dealMilestoneCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal_milestone"); @@ -110,17 +114,20 @@ public override void Reorder(int[] ids) } } + [Scope] public class DealMilestoneDao : AbstractDao { public DealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) : - base(dbContextManager, - tenantManager, - securityContext, - logger) + IOptionsMonitor logger, + AscCache ascCache) : + base(dbContextManager, + tenantManager, + securityContext, + logger, + ascCache) { @@ -297,16 +304,4 @@ private static DealMilestone ToDealMilestone(DbDealMilestone dbDealMilestone) }; } } - - public static class DealMilestoneDaoExtention - { - public static DIHelper AddDealMilestoneDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 94c233527fa..2029462a9ac 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Linq; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -38,17 +39,20 @@ namespace ASC.CRM.Core.Dao { + [Scope] public class FileDao : AbstractDao { public FileDao(FilesIntegration filesIntegration, DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) : + IOptionsMonitor logger, + AscCache ascCache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { FilesIntegration = filesIntegration; } @@ -99,16 +103,4 @@ public List GetEventsByFile(int id) } - public static class FileDaoExtention - { - public static DIHelper AddFileDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddFilesIntegrationService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 16270ef7ab5..48ad8226096 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -58,9 +59,10 @@ public class CachedInvoiceDao : InvoiceDao public CachedInvoiceDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - FactoryIndexer factoryIndexer, + FactoryIndexerInvoice factoryIndexer, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, + AscCache ascCache, SettingsManager settingsManager, InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData) @@ -69,6 +71,7 @@ public CachedInvoiceDao(DbContextManager dbContextManager, securityContext, factoryIndexer, logger, + ascCache, settingsManager, invoiceSetting, invoiceFormattedData @@ -108,6 +111,7 @@ private void ResetCache(int invoiceID) } } + [Scope] public class InvoiceDao : AbstractDao { public List> invoiceStatusMap = new List>() @@ -123,15 +127,17 @@ public InvoiceDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - FactoryIndexer factoryIndexer, + FactoryIndexerInvoice factoryIndexer, IOptionsMonitor logger, + AscCache ascCache, SettingsManager settingsManager, InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { FactoryIndexer = factoryIndexer; SettingsManager = settingsManager; @@ -144,7 +150,7 @@ public InvoiceDao( public InvoiceFormattedData InvoiceFormattedData { get; } public SettingsManager SettingsManager { get; } - public FactoryIndexer FactoryIndexer { get; } + public FactoryIndexerInvoice FactoryIndexer { get; } public TenantUtil TenantUtil { get; } public CRMSecurity CRMSecurity { get; } @@ -526,7 +532,7 @@ public virtual int SaveOrUpdateInvoice(Invoice invoice) var result = SaveOrUpdateInvoiceInDb(invoice); - FactoryIndexer.IndexAsync(InvoicesWrapper.FromInvoice(TenantID, invoice)); + FactoryIndexer.Index(Query(CRMDbContext.Invoices).Where(x => x.Id == invoice.ID).Single()); return result; } @@ -781,14 +787,16 @@ private void DeleteBatchInvoicesExecute(List invoices) using var tx = CRMDbContext.Database.BeginTransaction(); + var dbInvoicesQuery = Query(CRMDbContext.Invoices).Where(x => invoiceID.Contains(x.Id)); + CRMDbContext.InvoiceLine.RemoveRange(Query(CRMDbContext.InvoiceLine).Where(x => invoiceID.Contains(x.InvoiceId))); - CRMDbContext.Invoices.RemoveRange(Query(CRMDbContext.Invoices).Where(x => invoiceID.Contains(x.Id))); + CRMDbContext.Invoices.RemoveRange(dbInvoicesQuery); CRMDbContext.SaveChanges(); tx.Commit(); - invoices.ForEach(invoice => FactoryIndexer.DeleteAsync(InvoicesWrapper.FromInvoice(TenantID, invoice))); + dbInvoicesQuery.ToList().ForEach(invoice => FactoryIndexer.Delete(invoice)); } @@ -985,19 +993,4 @@ public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) } } - public static class InvoiceDaoExtention - { - public static DIHelper AddInvoiceDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddFactoryIndexerService() - .AddSettingsManagerService() - .AddInvoiceFormattedDataService() - .AddInvoiceSettingService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 9680a69fd30..7a29190bb1f 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -54,13 +55,15 @@ public CachedInvoiceItemDao(DbContextManager dbContextManager, TenantUtil tenantUtil, CRMSecurity cRMSecurity, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger + IOptionsMonitor logger, + AscCache ascCache ) : base(dbContextManager, tenantManager, securityContext, tenantUtil, cRMSecurity, - logger) + logger, + ascCache) { _invoiceItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_item"); @@ -97,6 +100,7 @@ private void ResetCache(int invoiceItemID) } } + [Scope] public class InvoiceItemDao : AbstractDao { public InvoiceItemDao( @@ -105,11 +109,13 @@ public InvoiceItemDao( SecurityContext securityContext, TenantUtil tenantUtil, CRMSecurity cRMSecurity, - IOptionsMonitor logger + IOptionsMonitor logger, + AscCache ascCache ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { TenantUtil = tenantUtil; CRMSecurity = cRMSecurity; @@ -486,18 +492,4 @@ private IQueryable GetDbInvoiceItemByFilters( return sqlQuery; } } - - public static class InvoiceItemDaoExtention - { - public static DIHelper AddInvoiceItemDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddTenantUtilService() - .AddCRMSecurityService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 8dc383ef46a..ebb31e35074 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -50,11 +51,13 @@ public CachedInvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger) + IOptionsMonitor logger, + AscCache ascCache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { _invoiceLineCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_line"); } @@ -90,16 +93,19 @@ private void ResetCache(int invoiceLineID) } } + [Scope] public class InvoiceLineDao : AbstractDao { public InvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) + IOptionsMonitor logger, + AscCache ascCache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { } @@ -284,16 +290,4 @@ private InvoiceLine ToInvoiceLine(DbInvoiceLine dbInvoiceLine) }; } } - - public static class InvoiceLineDaoExtention - { - public static DIHelper AddInvoiceLineDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 43a7b9e87ae..fc74f2a05ff 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -49,12 +50,14 @@ public CachedInvoiceTaxDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger + IOptionsMonitor logger, + AscCache ascCache ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { _invoiceTaxCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_tax"); @@ -91,18 +94,21 @@ private void ResetCache(int invoiceTaxID) } } + [Scope] public class InvoiceTaxDao : AbstractDao { public InvoiceTaxDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger + IOptionsMonitor logger, + AscCache ascCache ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { } @@ -265,15 +271,4 @@ private InvoiceTax ToInvoiceTax(DbInvoiceTax dbInvoiceTax) } } - public static class InvoiceTaxDaoExtention - { - public static DIHelper AddInvoiceTaxDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 5977a8dabde..5697eeb8f83 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -25,6 +25,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -53,11 +54,13 @@ public CachedListItem( TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger) + IOptionsMonitor logger, + AscCache ascCache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { _listItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_list_item"); } @@ -113,17 +116,20 @@ private void ResetCache(int id) } } + [Scope] public class ListItemDao : AbstractDao { public ListItemDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) + IOptionsMonitor logger, + AscCache ascCache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { @@ -599,16 +605,4 @@ public static ListItem ToListItem(DbListItem dbListItem) } } - - public static class ListItemDaoExtention - { - public static DIHelper AddListItemDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index f738a73fc1e..dae0203f7c6 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -54,7 +55,6 @@ namespace ASC.CRM.Core.Dao { - public class CachedRelationshipEventDao : RelationshipEventDao { private readonly HttpRequestDictionary _relationshipEventCache; @@ -68,8 +68,8 @@ public CachedRelationshipEventDao(DbContextManager dbContextManage SetupInfo setupInfo, PathProvider pathProvider, IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger - + IOptionsMonitor logger, + AscCache ascCache ) : base(dbContextManager, tenantManager, @@ -79,7 +79,8 @@ IOptionsMonitor logger tenantUtil, setupInfo, pathProvider, - logger) + logger, + ascCache) { _relationshipEventCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_relationshipEvent"); } @@ -100,6 +101,7 @@ private void ResetCache(int dealID) } } + [Scope] public class RelationshipEventDao : AbstractDao { @@ -111,12 +113,14 @@ public RelationshipEventDao(DbContextManager dbContextManager, TenantUtil tenantUtil, SetupInfo setupInfo, PathProvider pathProvider, - IOptionsMonitor logger + IOptionsMonitor logger, + AscCache ascCache ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { FilesIntegration = filesIntegration; TenantUtil = tenantUtil; @@ -136,7 +140,7 @@ IOptionsMonitor logger public FilesIntegration FilesIntegration { get; } - public FactoryIndexer FactoryIndexer { get; } + public FactoryIndexerEvents FactoryIndexer { get; } public RelationshipEvent AttachFiles(int contactID, EntityType entityType, int entityID, int[] fileIDs) { @@ -441,7 +445,7 @@ public RelationshipEvent CreateItem(RelationshipEvent item) if (item.CreateOn.Kind == DateTimeKind.Utc) item.CreateOn = TenantUtil.DateTimeFromUtc(item.CreateOn); - FactoryIndexer.IndexAsync(EventsWrapper.FromEvent(TenantID, item)); + FactoryIndexer.Index(itemToInsert); return item; } @@ -640,16 +644,14 @@ public void DeleteItem(RelationshipEvent item) relativeFiles.ForEach(f => RemoveFile(f)); - var itemToDelete = new DbRelationshipEvent - { - Id = item.ID, - TenantId = TenantID - }; + var itemToDelete = Query(CRMDbContext.RelationshipEvent).Where(x => x.Id == item.ID).Single(); + + FactoryIndexer.DeleteAsync(itemToDelete); CRMDbContext.RelationshipEvent.Remove(itemToDelete); + CRMDbContext.SaveChanges(); - FactoryIndexer.DeleteAsync(EventsWrapper.FromEvent(TenantID, item)); } [DataContract] @@ -716,22 +718,4 @@ private static string GetHistoryContentJson(JObject apiResponse) } } } - - public static class RelationshipEventDaoExtention - { - public static DIHelper AddRelationshipEventDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddFilesIntegrationService() - .AddCRMSecurityService() - .AddTenantUtilService() - .AddSetupInfo() - .AddCRMPathProviderService(); - } - } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 1bd621e62f0..aa076a220e3 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -48,12 +48,14 @@ using System.Linq; using Microsoft.Extensions.DependencyInjection; using ASC.Common; +using ASC.Common.Caching; #endregion namespace ASC.CRM.Core.Dao { + [Scope] public class ReportDao : AbstractDao { const string TimeFormat = "[h]:mm:ss;@"; @@ -68,6 +70,7 @@ public ReportDao(DbContextManager dbContextManager, SecurityContext securityContext, FilesIntegration filesIntegration, IOptionsMonitor logger, + AscCache ascCache, TenantUtil tenantUtil, SettingsManager settingsManager, Global global, @@ -76,7 +79,8 @@ public ReportDao(DbContextManager dbContextManager, base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { TenantUtil = tenantUtil; @@ -2221,21 +2225,4 @@ public void SaveFile(int fileId, int reportType) //#endregion } - - public static class ReportDaoExtention - { - public static DIHelper AddReportDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddFilesIntegrationService() - .AddTenantUtilService() - .AddSettingsManagerService() - // .AddGlobalService() - .AddUserManagerService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index 47f850a13d6..a315162c801 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -25,6 +25,7 @@ using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Utils; using ASC.Core; @@ -48,32 +49,38 @@ namespace ASC.CRM.Core.Dao { + [Scope] public class SearchDao : AbstractDao { private Dictionary> _findedIDs; + + //TODO: setting _fullTextSearchEnable field private bool _fullTextSearchEnable; - private DaoFactory DaoFactory { get; set; } + private DaoFactory DaoFactory { get; set; } + public SearchDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, CRMSecurity cRMSecurity, TenantUtil tenantUtil, PathProvider pathProvider, - FactoryIndexer tasksWrapperIndexer, - FactoryIndexer invoicesWrapperIndexer, + FactoryIndexerTask tasksWrapperIndexer, + FactoryIndexerInvoice invoicesWrapperIndexer, IOptionsMonitor logger, + AscCache ascCache, WebImageSupplier webImageSupplier, BundleSearch bundleSearch ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { - TasksWrapperIndexer = tasksWrapperIndexer; - InvoicesWrapperIndexer = invoicesWrapperIndexer; + FactoryIndexerTask = tasksWrapperIndexer; + FactoryIndexerInvoice = invoicesWrapperIndexer; CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; PathProvider = pathProvider; @@ -81,14 +88,15 @@ BundleSearch bundleSearch BundleSearch = bundleSearch; } + public BundleSearch BundleSearch { get; } public WebImageSupplier WebImageSupplier { get; } public TenantUtil TenantUtil { get; } public PathProvider PathProvider { get; } - public FactoryIndexer TasksWrapperIndexer { get; } - public FactoryIndexer InvoicesWrapperIndexer { get; } + public FactoryIndexerTask FactoryIndexerTask { get; } + public FactoryIndexerInvoice FactoryIndexerInvoice { get; } public CRMSecurity CRMSecurity { get; } public SearchResultItem[] Search(String searchText) @@ -97,13 +105,7 @@ public SearchResultItem[] Search(String searchText) .ToArray(); if (keywords.Length == 0) return new List().ToArray(); - - _fullTextSearchEnable = BundleSearch.Support(EntityType.Case) - && BundleSearch.Support(EntityType.Contact) - && BundleSearch.Support(EntityType.Opportunity) - && BundleSearch.Support(EntityType.Task) - && BundleSearch.Support(EntityType.Invoice); - + if (_fullTextSearchEnable) { _findedIDs = new Dictionary>(); @@ -128,14 +130,14 @@ public SearchResultItem[] Search(String searchText) List tasksId; - if (TasksWrapperIndexer.TrySelectIds(r => r.MatchAll(searchText), out tasksId)) + if (FactoryIndexerTask.TrySelectIds(r => r.MatchAll(searchText), out tasksId)) { _findedIDs.Add(EntityType.Task, tasksId); } List invoicesId; - if (InvoicesWrapperIndexer.TrySelectIds(r => r.MatchAll(searchText), out invoicesId)) + if (FactoryIndexerInvoice.TrySelectIds(r => r.MatchAll(searchText), out invoicesId)) { _findedIDs.Add(EntityType.Invoice, invoicesId); } @@ -201,7 +203,7 @@ private Dictionary> SearchByContactInfos(String[] k private bool IncludeToSearch(EntityType entityType) { - return !BundleSearch.Support(entityType) || _findedIDs.ContainsKey(entityType); + return _findedIDs.ContainsKey(entityType); } private SearchResultItem[] GetSearchResultItems(String[] keywords) @@ -465,22 +467,4 @@ private String GetPath(int contactID, int entityID, EntityType entityType) } } - public static class SearchDaoExtention - { - public static DIHelper AddSearchDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddCRMSecurityService() - .AddTenantUtilService() - .AddCRMPathProviderService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddWebImageSupplierService() - .AddBundleSearchService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index a0e63340895..d6052b2d68f 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -25,6 +25,7 @@ using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -40,16 +41,19 @@ namespace ASC.CRM.Core.Dao { + [Scope] public class TagDao : AbstractDao { public TagDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) : - base(dbContextManager, - tenantManager, - securityContext, - logger) + IOptionsMonitor logger, + AscCache ascCache) : + base(dbContextManager, + tenantManager, + securityContext, + logger, + ascCache) { } @@ -418,15 +422,4 @@ private static string CorrectTag(string tag) } - public static class TagDaoExtention - { - public static DIHelper AddTagDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 00ff73498d4..450be306faa 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -56,7 +56,7 @@ public CachedTaskDao(DbContextManager dbContextManager, SecurityContext securityContext, CRMSecurity cRMSecurity, TenantUtil tenantUtil, - FactoryIndexer factoryIndexer, + FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, IHttpContextAccessor httpContextAccessor, DbContextManager userDbContext, @@ -113,6 +113,7 @@ private void ResetCache(int taskID) } + [Scope] public class TaskDao : AbstractDao { public TaskDao(DbContextManager dbContextManager, @@ -120,7 +121,7 @@ public TaskDao(DbContextManager dbContextManager, SecurityContext securityContext, CRMSecurity cRMSecurity, TenantUtil tenantUtil, - FactoryIndexer factoryIndexer, + FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, DbContextManager userDbContext, DbContextManager coreDbContext @@ -141,7 +142,7 @@ DbContextManager coreDbContext public UserDbContext UserDbContext { get; } - public FactoryIndexer FactoryIndexer { get; } + public FactoryIndexerTask FactoryIndexer { get; } public TenantUtil TenantUtil { get; } @@ -853,7 +854,6 @@ private Task SaveOrUpdateTaskInDb(Task newTask) CRMDbContext.SaveChanges(); newTask.ID = itemToInsert.Id; - } else { @@ -889,12 +889,9 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.LastModifedBy = SecurityContext.CurrentAccount.ID; newTask.IsClosed = oldTask.IsClosed; - } - - - - FactoryIndexer.IndexAsync(TasksWrapper.FromTask(TenantID, newTask)); + + FactoryIndexer.Index(Query(CRMDbContext.Tasks).Where(x => x.Id == newTask.ID).Single()); return newTask; } @@ -936,7 +933,7 @@ private int SaveTaskInDb(Task newTask) newTask.ID = dbTask.Id; - FactoryIndexer.IndexAsync(TasksWrapper.FromTask(TenantID, newTask)); + FactoryIndexer.Index(dbTask); return newTask.ID; } @@ -969,11 +966,14 @@ public virtual void DeleteTask(int taskID) CRMSecurity.DemandEdit(task); + var dbTask = Query(CRMDbContext.Tasks).Where(x => x.Id == taskID).Single(); + + FactoryIndexer.Delete(dbTask); + CRMDbContext.Tasks.Remove(new DbTask { Id = taskID }); _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); - FactoryIndexer.DeleteAsync(TasksWrapper.FromTask(TenantID, task)); } public List CreateByTemplate(List templateItems, EntityType entityType, int entityID) @@ -1177,21 +1177,4 @@ public Task ToTask(DbTask dbTask) } } - - public static class TaskDaoExtention - { - public static DIHelper AddTaskDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService() - .AddCRMSecurityService() - .AddTenantUtilService() - .AddFactoryIndexerService() - .AddUserDbContextService() - .AddCoreDbContextService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 37ac5371460..c6cf5a10ac2 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -38,6 +38,7 @@ namespace ASC.CRM.Core.Dao { + [Scope] public class TaskTemplateContainerDao : AbstractDao { public TaskTemplateContainerDao( @@ -133,6 +134,7 @@ protected TaskTemplateContainer ToObject(DbTaskTemplateContainer dbTaskTemplateC } } + [Scope] public class TaskTemplateDao : AbstractDao { public TaskTemplateDao(DbContextManager dbContextManager, @@ -280,30 +282,5 @@ protected TaskTemplate ToObject(DbTaskTemplate dbTaskTemplate) }; } } - - - public static class TaskTemplateDaoExtention - { - public static DIHelper AddTaskTemplateDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } - - public static class TaskTemplateContainerDaoExtention - { - public static DIHelper AddTaskTemplateContainerDaoService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCRMDbContextService() - .AddTenantManagerService() - .AddSecurityContextService(); - } - } - + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index 989362d32ce..3b7e09d0d80 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -1,6 +1,8 @@ using System; using ASC.Common; using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; + using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; @@ -38,84 +40,16 @@ public partial class CRMDbContext : BaseDbContext protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); - - entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); - - entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); - - entity.Property(e => e.CreateBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.LastModifedBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Title) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - }); - - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); - - entity.HasIndex(e => new { e.LastModifedOn, e.TenantId }) - .HasName("last_modifed_on"); - - entity.HasIndex(e => new { e.TenantId, e.CompanyId }) - .HasName("company_id"); - - entity.HasIndex(e => new { e.TenantId, e.DisplayName }) - .HasName("display_name"); - - entity.Property(e => e.CompanyName) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.CreateBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Currency) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.DisplayName) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.FirstName) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Industry) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.LastModifedBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + ModelBuilderWrapper.From(modelBuilder, Provider) + .AddDbFieldValue() + .AddDbContact() + .AddDbCase() + .AddDbRelationshipEvent() + .AddDbDeal() + .AddDbTask(); - entity.Property(e => e.LastName) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - entity.Property(e => e.Notes) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Title) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - }); + modelBuilder.Entity(entity => { @@ -181,44 +115,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); - - entity.HasIndex(e => e.DealMilestoneId) - .HasName("deal_milestone_id"); - - entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); - - entity.HasIndex(e => new { e.TenantId, e.ContactId }) - .HasName("contact_id"); - - entity.Property(e => e.BidCurrency) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.CreateBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Description) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.LastModifedBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.ResponsibleId) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Title) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - }); +; modelBuilder.Entity(entity => { @@ -271,26 +168,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.FieldId) - .HasName("field_id"); - - entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); - - entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType, e.FieldId }) - .HasName("tenant_id"); - - entity.Property(e => e.LastModifedBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Value) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - }); - + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) @@ -453,32 +331,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("project_id"); }); - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.ContactId) - .HasName("IX_Contact"); - - entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); - - entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); - - entity.HasIndex(e => new { e.EntityId, e.EntityType }) - .HasName("IX_Entity"); - - entity.Property(e => e.Content) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.CreateBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.LastModifedBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - }); modelBuilder.Entity(entity => { @@ -509,49 +361,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_bin"); }); - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); - - entity.HasIndex(e => e.Deadline) - .HasName("deadline"); - - entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); - - entity.HasIndex(e => new { e.TenantId, e.ContactId }) - .HasName("IX_Contact"); - - entity.HasIndex(e => new { e.TenantId, e.ResponsibleId }) - .HasName("responsible_id"); - - entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType }) - .HasName("IX_Entity"); - - entity.Property(e => e.ContactId).HasDefaultValueSql("'-1'"); - - entity.Property(e => e.CreateBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Description) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.LastModifedBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.ResponsibleId) - .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.Title) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - }); modelBuilder.Entity(entity => { diff --git a/products/ASC.CRM/Server/Core/EF/DbCase.cs b/products/ASC.CRM/Server/Core/EF/DbCase.cs index 82f98621900..6febbab39be 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCase.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCase.cs @@ -1,18 +1,25 @@ using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; + +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; +using ASC.ElasticSearch; + +using Microsoft.EntityFrameworkCore; + +using Nest; namespace ASC.CRM.Core.EF { [Table("crm_case")] - public partial class DbCase : IDbCrm + public class DbCase : IDbCrm, ISearchItem { - [Key] - [Column("id", TypeName = "int(11)")] public int Id { get; set; } [Required] - [Column("title", TypeName = "varchar(255)")] + [Text(Analyzer = "whitespacecustom")] public string Title { get; set; } [Column("is_closed")] @@ -33,5 +40,62 @@ public partial class DbCase : IDbCrm [Column("last_modifed_by", TypeName = "char(38)")] public Guid? LastModifedBy { get; set; } + + [NotMapped] + [Ignore] + public string IndexName + { + get + { + return "crm_case"; + } + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Title }; + } + } } + + public static class DbCaseExtension + { + public static ModelBuilderWrapper AddDbCase(this ModelBuilderWrapper modelBuilder) + { + modelBuilder + .Add(MySqlAddDbCase, Provider.MySql); + + return modelBuilder; + } + private static void MySqlAddDbCase(this ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + } + } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbContact.cs b/products/ASC.CRM/Server/Core/EF/DbContact.cs index 67ae56c536d..bbf72fb78db 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContact.cs @@ -1,24 +1,31 @@ -using ASC.CRM.Core.Enums; +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Microsoft.EntityFrameworkCore; + +using Nest; + using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; namespace ASC.CRM.Core.EF { + [ElasticsearchType(RelationName = "crm_contact")] [Table("crm_contact")] - public partial class DbContact : IDbCrm + public partial class DbContact : IDbCrm, ISearchItem { - [Key] - [Column("id", TypeName = "int(11)")] public int Id { get; set; } [Column("is_company")] public bool IsCompany { get; set; } - [Column("notes", TypeName = "text")] public string Notes { get; set; } - [Column("title", TypeName = "varchar(255)")] + [Text(Analyzer = "whitespacecustom")] public string Title { get; set; } [Column("first_name", TypeName = "varchar(255)")] @@ -67,5 +74,99 @@ public partial class DbContact : IDbCrm [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + [NotMapped] + [Ignore] + public string IndexName + { + get + { + return "crm_contact"; + } + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Title }; + } + } + } + + public static class DbContactExtension + { + public static ModelBuilderWrapper AddDbContact(this ModelBuilderWrapper modelBuilder) + { + modelBuilder + .Add(MySqlAddDbContact, Provider.MySql) + .Add(PgSqlAddDbContact, Provider.Postgre); + + return modelBuilder; + } + + private static void MySqlAddDbContact(this ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => new { e.LastModifedOn, e.TenantId }) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.CompanyId }) + .HasName("company_id"); + + entity.HasIndex(e => new { e.TenantId, e.DisplayName }) + .HasName("display_name"); + + entity.Property(e => e.CompanyName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Currency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.DisplayName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.FirstName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Industry) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastName) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Notes) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + } + + private static void PgSqlAddDbContact(this ModelBuilder modelBuilder) + { + throw new NotImplementedException(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs index efc67f0e207..1e9450d54e4 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs @@ -1,19 +1,23 @@ using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Nest; + using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; namespace ASC.CRM.Core.EF { [Table("crm_contact_info")] - public partial class DbContactInfo : IDbCrm + public partial class DbContactInfo : IDbCrm, ISearchItem { - [Key] - [Column("id", TypeName = "int(10)")] public int Id { get; set; } [Required] [Column("data", TypeName = "text")] + [Text(Analyzer = "whitespacecustom")] public string Data { get; set; } [Column("category", TypeName = "int(255)")] @@ -37,5 +41,25 @@ public partial class DbContactInfo : IDbCrm [Column("last_modifed_by", TypeName = "char(38)")] public Guid LastModifedBy { get; set; } + [NotMapped] + [Ignore] + public string IndexName + { + get + { + return "crm_field_value"; + } + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Value }; + } + } + + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs index 9bea9922d9b..6502389b0e9 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs @@ -10,12 +10,15 @@ public partial class DbCurrencyRate [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } + [Required] [Column("from_currency", TypeName = "varchar(255)")] public string FromCurrency { get; set; } + [Required] [Column("to_currency", TypeName = "varchar(255)")] public string ToCurrency { get; set; } + [Column("rate", TypeName = "decimal(10,2)")] public decimal Rate { get; set; } [Required] diff --git a/products/ASC.CRM/Server/Core/EF/DbDeal.cs b/products/ASC.CRM/Server/Core/EF/DbDeal.cs index 01475a4dbec..266a130e550 100644 --- a/products/ASC.CRM/Server/Core/EF/DbDeal.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDeal.cs @@ -23,72 +23,158 @@ * */ +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +using Nest; + using System; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; namespace ASC.CRM.Core.EF { + [ElasticsearchType(RelationName = "crm_deal")] [Table("crm_deal")] - public partial class DbDeal : IDbCrm + public class DbDeal : IDbCrm, ISearchItem { - [Key] - [Column("id", TypeName = "int(11)")] public int Id { get; set; } - - [Required] - [Column("title", TypeName = "varchar(255)")] + + [Text(Analyzer = "whitespacecustom")] public string Title { get; set; } - - [Column("description", TypeName = "text")] + + [Text(Analyzer = "whitespacecustom")] public string Description { get; set; } - - [Required] - [Column("responsible_id", TypeName = "char(38)")] + + [Column("responsible_id")] public Guid ResponsibleId { get; set; } - - [Column("contact_id", TypeName = "int(11)")] + + [Column("contact_id")] public int ContactId { get; set; } - - [Column("create_on", TypeName = "datetime")] + + [Column("create_on")] public DateTime CreateOn { get; set; } - - [Required] - [Column("create_by", TypeName = "char(38)")] + + [Column("create_by")] public Guid CreateBy { get; set; } - - [Column("bid_currency", TypeName = "varchar(255)")] + + [Column("bid_currency")] public string BidCurrency { get; set; } - - [Column("bid_value", TypeName = "decimal(50,9)")] + + [Column("bid_value")] public decimal BidValue { get; set; } - - [Column("bid_type", TypeName = "int(11)")] + + [Column("bid_type")] public BidType BidType { get; set; } - - [Column("deal_milestone_id", TypeName = "int(11)")] + + [Column("deal_milestone_id")] public int DealMilestoneId { get; set; } - - [Column("tenant_id", TypeName = "int(11)")] + + [Column("tenant_id")] public int TenantId { get; set; } - - [Column("expected_close_date", TypeName = "datetime")] + + [Column("expected_close_date")] public DateTime ExpectedCloseDate { get; set; } - - [Column("per_period_value", TypeName = "int(11)")] + + [Column("per_period_value")] public int PerPeriodValue { get; set; } - - [Column("deal_milestone_probability", TypeName = "int(11)")] + + [Column("deal_milestone_probability")] public int DealMilestoneProbability { get; set; } - - [Column("last_modifed_on", TypeName = "datetime")] + + [Column("last_modifed_on")] public DateTime? LastModifedOn { get; set; } - [Column("last_modifed_by", TypeName = "char(38)")] + [Column("last_modifed_by")] public Guid LastModifedBy { get; set; } - [Column("actual_close_date", TypeName = "datetime")] + [Column("actual_close_date")] public DateTime? ActualCloseDate { get; set; } + + [NotMapped] + [Ignore] + public string IndexName + { + get + { + return "crm_deal"; + } + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Title, Description }; + } + } + } + + public static class DbDealExtension + { + public static ModelBuilderWrapper AddDbDeal(this ModelBuilderWrapper modelBuilder) + { + modelBuilder + .Add(MySqlAddDbDeal, Provider.MySql) + .Add(PgSqlAddDbDeal, Provider.Postgre); + + return modelBuilder; + } + private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.Property(x => x.Id) + .ValueGeneratedOnAdd(); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ResponsibleId) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.HasIndex(e => new { e.TenantId, e.ContactId }) + .HasName("contact_id"); + + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.BidCurrency) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => e.DealMilestoneId) + .HasName("deal_milestone_id"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + } + + private static void PgSqlAddDbDeal(this ModelBuilder modelBuilder) + { + throw new NotImplementedException(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs index 4d5f0a9f588..53612816467 100644 --- a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs @@ -1,18 +1,26 @@ -using ASC.CRM.Core.Enums; +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Microsoft.EntityFrameworkCore; + +using Nest; + using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; namespace ASC.CRM.Core.EF { + [ElasticsearchType(RelationName = "crm_field_value")] [Table("crm_field_value")] - public partial class DbFieldValue : IDbCrm + public partial class DbFieldValue : IDbCrm, ISearchItem { - [Key] - [Column("id", TypeName = "int(11)")] public int Id { get; set; } - - [Column("value", TypeName = "text")] + + [Text(Analyzer = "whitespacecustom")] public string Value { get; set; } [Column("entity_id", TypeName = "int(11)")] @@ -32,5 +40,65 @@ public partial class DbFieldValue : IDbCrm [Column("last_modifed_by", TypeName = "char(38)")] public Guid LastModifedBy { get; set; } + + [NotMapped] + [Ignore] + public string IndexName + { + get + { + return "crm_field_value"; + } + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Value }; + } + } + } + + public static class DbFieldValueExtension + { + public static ModelBuilderWrapper AddDbFieldValue(this ModelBuilderWrapper modelBuilder) + { + modelBuilder + .Add(MySqlAddDbDeal, Provider.MySql) + .Add(PgSqlAddDbDeal, Provider.Postgre); + + return modelBuilder; + } + + private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.FieldId) + .HasName("field_id"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType, e.FieldId }) + .HasName("tenant_id"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Value) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + } + + private static void PgSqlAddDbDeal(this ModelBuilder modelBuilder) + { + throw new NotImplementedException(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs index 0469625f735..cf9abc0174b 100644 --- a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs @@ -1,12 +1,17 @@ using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Nest; + using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; namespace ASC.CRM.Core.EF { [Table("crm_invoice")] - public partial class DbInvoice : IDbCrm + public class DbInvoice : IDbCrm, ISearchItem { [Key] [Column("id", TypeName = "int(11)")] @@ -82,5 +87,24 @@ public partial class DbInvoice : IDbCrm [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } + + [NotMapped] + [Ignore] + public string IndexName + { + get + { + return "crm_deal"; + } + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Description }; + } + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index a8d7f221725..3c45a80f15a 100644 --- a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -1,21 +1,32 @@ -using ASC.CRM.Core.Enums; +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Microsoft.EntityFrameworkCore; + +using Nest; + using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; namespace ASC.CRM.Core.EF { + [ElasticsearchType(RelationName = "crm_relationship_event")] [Table("crm_relationship_event")] - public partial class DbRelationshipEvent : IDbCrm + public class DbRelationshipEvent : IDbCrm, ISearchItem { [Key] - [Column("id", TypeName = "int(11)")] + [Column("id")] public int Id { get; set; } - [Column("contact_id", TypeName = "int(11)")] + [Column("contact_id")] public int ContactId { get; set; } - [Column("content", TypeName = "text")] + [Column("content")] + [Text(Analyzer = "whitespacecustom")] public string Content { get; set; } [Required] @@ -45,5 +56,70 @@ public partial class DbRelationshipEvent : IDbCrm [Column("have_files", TypeName = "int(11)")] public bool HaveFiles { get; set; } + + [NotMapped] + [Ignore] + public string IndexName + { + get + { + return "crm_relationship_event"; + } + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Content }; + } + } + } + + public static class DbRelationshipEventExtension + { + public static ModelBuilderWrapper AddDbRelationshipEvent(this ModelBuilderWrapper modelBuilder) + { + modelBuilder + .Add(MySqlAddDbRelationshipEvent, Provider.MySql) + .Add(PgSqlAddDbRelationshipEvent, Provider.Postgre); + + return modelBuilder; + } + private static void MySqlAddDbRelationshipEvent(this ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.ContactId) + .HasName("IX_Contact"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => e.TenantId) + .HasName("tenant_id"); + + entity.HasIndex(e => new { e.EntityId, e.EntityType }) + .HasName("IX_Entity"); + + entity.Property(e => e.Content) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + } + + private static void PgSqlAddDbRelationshipEvent(this ModelBuilder modelBuilder) + { + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs index f6f77bb27c2..a6f536feeb2 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -1,22 +1,30 @@ -using ASC.CRM.Core.Enums; +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Microsoft.EntityFrameworkCore; + +using Nest; + using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; namespace ASC.CRM.Core.EF { + [ElasticsearchType(RelationName = "crm_task")] [Table("crm_task")] - public partial class DbTask: IDbCrm + public partial class DbTask: IDbCrm, ISearchItem { - [Key] - [Column("id", TypeName = "int(11)")] public int Id { get; set; } [Required] - [Column("title", TypeName = "varchar(255)")] + [Text(Analyzer = "whitespacecustom")] public string Title { get; set; } - [Column("description", TypeName = "text")] + [Text(Analyzer = "whitespacecustom")] public string Description { get; set; } [Column("deadline", TypeName = "datetime")] @@ -62,5 +70,81 @@ public partial class DbTask: IDbCrm [Column("exec_alert", TypeName = "int(10)")] public int ExecAlert { get; set; } + + [NotMapped] + [Ignore] + public string IndexName + { + get => "crm_task"; + } + + [Ignore] + public Expression> SearchContentFields + { + get + { + return (a) => new[] { Title, Description }; + } + } + } + + public static class DbTaskExtension + { + public static ModelBuilderWrapper AddDbTask(this ModelBuilderWrapper modelBuilder) + { + modelBuilder + .Add(MySqlAddDbTask, Provider.MySql); + + return modelBuilder; + } + + public static void MySqlAddDbTask(this ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.ToTable("crm_task"); + + entity.HasIndex(e => e.CreateOn) + .HasName("create_on"); + + entity.HasIndex(e => e.Deadline) + .HasName("deadline"); + + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + + entity.HasIndex(e => new { e.TenantId, e.ContactId }) + .HasName("IX_Contact"); + + entity.HasIndex(e => new { e.TenantId, e.ResponsibleId }) + .HasName("responsible_id"); + + entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType }) + .HasName("IX_Entity"); + + entity.Property(e => e.ContactId).HasDefaultValueSql("'-1'"); + + entity.Property(e => e.CreateBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Description) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.ResponsibleId) + .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.Title) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index 9ffff1cd6ca..2fef47837ab 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -26,102 +26,39 @@ using System.Collections.Generic; using System.Linq; -using ASC.Common; -using ASC.CRM.Core; -using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; +using ASC.CRM.Core.EF; namespace ASC.Web.CRM.Core.Search { public class BundleSearch { - public BundleSearch(FactoryIndexer contactsWrapperFactoryIndexer, - FactoryIndexer infoWrapperFactoryIndexer, - FactoryIndexer fieldsWrapperFactoryIndexer, - FactoryIndexer eventsWrapperFactoryIndexer, - FactoryIndexer dealsWrapperFactoryIndexer, - FactoryIndexer tasksWrapperFactoryIndexer, - FactoryIndexer casesWrapperFactoryIndexer, - FactoryIndexer invoicesWrapperFactoryIndexer, - FactoryIndexerHelper factoryIndexerHelper, - ContactsWrapper contactsWrapper, - InfoWrapper infoWrapper, - FieldsWrapper fieldsWrapper, - EventsWrapper eventsWrapper, - DealsWrapper dealsWrapper, - TasksWrapper tasksWrapper, - CasesWrapper casesWrapper, - InvoicesWrapper invoicesWrapper) + public BundleSearch(FactoryIndexerContact factoryIndexerContact, + FactoryIndexerContactInfo factoryIndexerContactInfo, + FactoryIndexerFieldValue fieldsWrapperFactoryIndexer, + FactoryIndexerEvents factoryIndexerEvents, + FactoryIndexerDeal factoryIndexerDeal, + FactoryIndexerTask factoryIndexerTask, + FactoryIndexerCase factoryIndexerCase, + FactoryIndexerInvoice factoryIndexerInvoice) { - ContactsWrapperFactoryIndexer = contactsWrapperFactoryIndexer; - InfoWrapperFactoryIndexer = infoWrapperFactoryIndexer; - FieldsWrapperFactoryIndexer = fieldsWrapperFactoryIndexer; - EventsWrapperFactoryIndexer = eventsWrapperFactoryIndexer; - DealsWrapperFactoryIndexer = dealsWrapperFactoryIndexer; - TasksWrapperFactoryIndexer = tasksWrapperFactoryIndexer; - CasesWrapperFactoryIndexer = casesWrapperFactoryIndexer; - InvoicesWrapperFactoryIndexer = invoicesWrapperFactoryIndexer; - FactoryIndexerHelper = factoryIndexerHelper; - - ContactsWrapper = contactsWrapper; - InfoWrapper = infoWrapper; - FieldsWrapper = fieldsWrapper; - EventsWrapper = eventsWrapper; - DealsWrapper = dealsWrapper; - TasksWrapper = tasksWrapper; - CasesWrapper = casesWrapper; - InvoicesWrapper = invoicesWrapper; - + FactoryIndexerContact = factoryIndexerContact; + FactoryIndexerContactInfo = factoryIndexerContactInfo; + FactoryIndexerFieldValue = fieldsWrapperFactoryIndexer; + FactoryIndexerEvents = factoryIndexerEvents; + FactoryIndexerDeal = factoryIndexerDeal; + FactoryIndexerTask = factoryIndexerTask; + FactoryIndexerCase = factoryIndexerCase; + FactoryIndexerInvoice = factoryIndexerInvoice; } - public ContactsWrapper ContactsWrapper { get; } - public InfoWrapper InfoWrapper { get; } - public FieldsWrapper FieldsWrapper { get; } - public EventsWrapper EventsWrapper { get; } - public DealsWrapper DealsWrapper { get; } - public TasksWrapper TasksWrapper { get; } - public CasesWrapper CasesWrapper { get; } - public InvoicesWrapper InvoicesWrapper { get; } - - public FactoryIndexerHelper FactoryIndexerHelper { get; } - public FactoryIndexer ContactsWrapperFactoryIndexer { get; } - public FactoryIndexer InfoWrapperFactoryIndexer { get; } - public FactoryIndexer FieldsWrapperFactoryIndexer { get; } - public FactoryIndexer EventsWrapperFactoryIndexer { get; } - public FactoryIndexer DealsWrapperFactoryIndexer { get; } - public FactoryIndexer TasksWrapperFactoryIndexer { get; } - public FactoryIndexer CasesWrapperFactoryIndexer { get; } - public FactoryIndexer InvoicesWrapperFactoryIndexer { get; } - - public bool Support(EntityType entityType) - { - switch (entityType) - { - case EntityType.Person: - case EntityType.Contact: - case EntityType.Company: - return FactoryIndexerHelper.Support(ContactsWrapper) && - FactoryIndexerHelper.Support(InfoWrapper) && - FactoryIndexerHelper.Support(FieldsWrapper) && - FactoryIndexerHelper.Support(EventsWrapper); - case EntityType.Opportunity: - return FactoryIndexerHelper.Support(DealsWrapper) && - FactoryIndexerHelper.Support(FieldsWrapper) && - FactoryIndexerHelper.Support(EventsWrapper); - case EntityType.RelationshipEvent: - return FactoryIndexerHelper.Support(EventsWrapper); - case EntityType.Task: - return FactoryIndexerHelper.Support(TasksWrapper); - case EntityType.Case: - return FactoryIndexerHelper.Support(CasesWrapper) && - FactoryIndexerHelper.Support(FieldsWrapper) && - FactoryIndexerHelper.Support(EventsWrapper); - case EntityType.Invoice: - return FactoryIndexerHelper.Support(InvoicesWrapper); - } - - return false; - } + public FactoryIndexerContact FactoryIndexerContact { get; } + public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } + public FactoryIndexerFieldValue FactoryIndexerFieldValue { get; } + public FactoryIndexerEvents FactoryIndexerEvents { get; } + public FactoryIndexerDeal FactoryIndexerDeal { get; } + public FactoryIndexerTask FactoryIndexerTask { get; } + public FactoryIndexerCase FactoryIndexerCase { get; } + public FactoryIndexerInvoice FactoryIndexerInvoice { get; } public bool TrySelectCase(string text, out List result) { @@ -129,21 +66,23 @@ public bool TrySelectCase(string text, out List result) result = new List(); List casesId; - if (CasesWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out casesId)) + + if (FactoryIndexerCase.TrySelectIds(s => s.MatchAll(text), out casesId)) { result.AddRange(casesId); success = true; } - IReadOnlyCollection casesCustom; - if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7), out casesCustom)) + IReadOnlyCollection casesCustom; + if (FactoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 7), out casesCustom)) { result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); success = true; } - IReadOnlyCollection events; - if (!EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) + IReadOnlyCollection events; + + if (!FactoryIndexerEvents.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) { result.AddRange(events.Select(r => r.EntityId).ToList()); success = true; @@ -159,31 +98,31 @@ public bool TrySelectContact(string text, out List result) List contactsId; - if (ContactsWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out contactsId)) + if (FactoryIndexerContact.TrySelectIds(s => s.MatchAll(text), out contactsId)) { result.AddRange(contactsId); success = true; } - IReadOnlyCollection infos; + IReadOnlyCollection infos; - if (InfoWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text), out infos)) + if (FactoryIndexerContactInfo.TrySelect(s => s.MatchAll(text), out infos)) { result.AddRange(infos.Select(r => r.ContactId).ToList()); success = true; } - IReadOnlyCollection personCustom; + IReadOnlyCollection personCustom; - if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] { 0, 4, 5 }), out personCustom)) + if (FactoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] { 0, 4, 5 }), out personCustom)) { result.AddRange(personCustom.Select(r => r.EntityId).ToList()); success = true; } - IReadOnlyCollection events; + IReadOnlyCollection events; - if (EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events)) + if (FactoryIndexerEvents.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events)) { result.AddRange(events.Select(r => r.ContactId).ToList()); success = true; @@ -198,21 +137,24 @@ public bool TrySelectOpportunity(string text, out List result) result = new List(); List dealsId; - if (DealsWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out dealsId)) + + if (FactoryIndexerDeal.TrySelectIds(s => s.MatchAll(text), out dealsId)) { result.AddRange(dealsId); success = true; } - IReadOnlyCollection casesCustom; - if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1), out casesCustom)) + IReadOnlyCollection casesCustom; + + if (FactoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 1), out casesCustom)) { result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); success = true; } - IReadOnlyCollection events; - if (!EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1).Gt(r => r.EntityId, 0), out events)) + IReadOnlyCollection events; + + if (!FactoryIndexerEvents.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 1).Gt(r => r.EntityId, 0), out events)) { result.AddRange(events.Select(r => r.EntityId).ToList()); success = true; @@ -221,31 +163,4 @@ public bool TrySelectOpportunity(string text, out List result) return success; } } - - public static class BundleSearchExtention - { - public static DIHelper AddBundleSearchService(this DIHelper services) - { - services.TryAddScoped(); - - - return services.AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddFactoryIndexerService() - .AddFactoryIndexerHelperService() - .AddContactsWrapperService() - .AddInfoWrapperService() - .AddFieldsWrapperService() - .AddEventsWrapperService() - .AddDealsWrapperService() - .AddTasksWrapperService() - .AddCasesWrapperService() - .AddInvoicesWrapperService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs b/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs deleted file mode 100644 index 7a2715ba2b8..00000000000 --- a/products/ASC.CRM/Server/Core/Search/CasesWrapper.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common; -using ASC.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; - -using Microsoft.Extensions.DependencyInjection; - -namespace ASC.Web.CRM.Core.Search -{ - public sealed class CasesWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [Column("title", 1)] - public string Title { get; set; } - - protected override string Table { get { return "crm_case"; } } - - public static CasesWrapper GetCasesWrapper(IServiceProvider serviceProvider, Cases item) - { - var tenantManager = serviceProvider.GetService(); - - return new CasesWrapper - { - Id = item.ID, - Title = item.Title, - TenantId = tenantManager.CurrentTenant.TenantId - }; - } - } - - public static class CasesWrapperExtention - { - public static DIHelper AddCasesWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs b/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs deleted file mode 100644 index 1f80c226dce..00000000000 --- a/products/ASC.CRM/Server/Core/Search/ContactsWrapper.cs +++ /dev/null @@ -1,110 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common; -using ASC.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; - -using Microsoft.Extensions.DependencyInjection; - - -namespace ASC.Web.CRM.Core.Search -{ - public class ContactsWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [Column("title", 1)] - public string Title { get; set; } - - [Column("first_name", 2)] - public string FirstName { get; set; } - - [Column("last_name", 3)] - public string LastName { get; set; } - - [Column("company_name", 4)] - public string CompanyName { get; set; } - - [Column("notes", 5)] - public string Notes { get; set; } - - [Column("industry", 6)] - public string Industry { get; set; } - - protected override string Table { get { return "crm_contact"; } } - - public static implicit operator ContactsWrapper(Contact d) - { - var person = d as Person; - if (person != null) - { - return person; - } - return d as Company; - } - - public static ContactsWrapper FromCompany(int tenantId, Company d) - { - return new ContactsWrapper - { - Id = d.ID, - CompanyName = d.CompanyName, - Industry = d.Industry, - Notes = d.About, - TenantId = tenantId - }; - } - - public static ContactsWrapper FromPerson(int tenantId, Person d) - { - return new ContactsWrapper - { - Id = d.ID, - Title = d.JobTitle, - FirstName = d.FirstName, - LastName = d.LastName, - Industry = d.Industry, - Notes = d.About, - TenantId = tenantId - }; - } - } - - public static class ContactsWrapperExtention - { - public static DIHelper AddContactsWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs b/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs deleted file mode 100644 index d1d26c2486f..00000000000 --- a/products/ASC.CRM/Server/Core/Search/DealsWrapper.cs +++ /dev/null @@ -1,73 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common; -using ASC.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; - -using Microsoft.Extensions.DependencyInjection; - - -namespace ASC.Web.CRM.Core.Search -{ - public sealed class DealsWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [Column("title", 1)] - public string Title { get; set; } - - [Column("description", 2)] - public string Description { get; set; } - - protected override string Table { get { return "crm_deal"; } } - - public static DealsWrapper FromDeal(int tenantId, Deal deal) - { - return new DealsWrapper - { - Id = deal.ID, - Title = deal.Title, - Description = deal.Description, - TenantId = tenantId - }; - } - } - - public static class DealsWrapperExtention - { - public static DIHelper AddDealsWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs b/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs deleted file mode 100644 index 27635a0388b..00000000000 --- a/products/ASC.CRM/Server/Core/Search/EmailWrapper.cs +++ /dev/null @@ -1,142 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common; -using ASC.CRM.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; -using System; -using System.Collections.Generic; -using System.Linq; - - -namespace ASC.Web.CRM.Core.Search -{ - public class EmailWrapper : ContactsWrapper - { - [Join(JoinTypeEnum.Sub, "id:contact_id", "tenant_id:tenant_id")] - public List EmailInfoWrapper { get; set; } - - protected override string IndexName - { - get - { - return "crm_contact_email"; - } - } - - public static EmailWrapper GetEmailWrapper(int tenantId, - Contact contact, - List contactInfo) - { - var result = new EmailWrapper(); - - var person = contact as Person; - if (person != null) - { - result = new EmailWrapper - { - Id = person.ID, - Title = person.JobTitle, - FirstName = person.FirstName, - LastName = person.LastName, - Industry = person.Industry, - Notes = person.About, - TenantId = tenantId - }; - } - - var company = contact as Company; - - if (company != null) - { - result = new EmailWrapper - { - Id = company.ID, - CompanyName = company.CompanyName, - Industry = company.Industry, - Notes = company.About, - TenantId = tenantId - }; - } - - result.EmailInfoWrapper = contactInfo.Select(r => ASC.Web.CRM.Core.Search.EmailInfoWrapper.FromContactInfo(tenantId, r)).ToList(); - - return result; - } - } - - public class EmailInfoWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [ColumnCondition("contact_id", 1)] - public int ContactId { get; set; } - - [Column("data", 2, Analyzer = Analyzer.uax_url_email)] - public string Data { get; set; } - - [ColumnCondition("type", 3, 1)] - public int Type { get; set; } - - protected override string Table { get { return "crm_contact_info"; } } - - public static EmailInfoWrapper FromContactInfo(int tenantId, ContactInfo cf) - { - return new EmailInfoWrapper - { - Id = cf.ID, - ContactId = cf.ContactID, - Data = cf.Data, - Type = (int)cf.InfoType, - TenantId = tenantId - }; - } - } - - public static class EmailWrapperExtention - { - public static DIHelper AddEmailWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } - - public static class EmailInfoWrapperExtention - { - public static DIHelper AddEmailInfoWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs b/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs deleted file mode 100644 index f0efab17f7d..00000000000 --- a/products/ASC.CRM/Server/Core/Search/EventsWrapper.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common; -using ASC.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; - -using Microsoft.Extensions.DependencyInjection; - - -namespace ASC.Web.CRM.Core.Search -{ - public sealed class EventsWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [ColumnCondition("contact_id", 1)] - public int ContactId { get; set; } - - [ColumnCondition("entity_id", 2)] - public int EntityId { get; set; } - - [ColumnCondition("entity_type", 2)] - public int EntityType { get; set; } - - [Column("content", 3, charFilter: CharFilter.html)] - public string Content { get; set; } - - protected override string Table { get { return "crm_relationship_event"; } } - - public static EventsWrapper FromEvent(int tenantId, RelationshipEvent relationshipEvent) - { - return new EventsWrapper - { - Id = relationshipEvent.ID, - ContactId = relationshipEvent.ContactID, - EntityId = relationshipEvent.EntityID, - EntityType = (int)relationshipEvent.EntityType, - Content = relationshipEvent.Content, - TenantId = tenantId - }; - } - } - - public static class EventsWrapperExtention - { - public static DIHelper AddEventsWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs new file mode 100644 index 00000000000..418eade63ce --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs @@ -0,0 +1,102 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerCase : FactoryIndexer + { + public FactoryIndexerCase ( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var casesDao = DaoFactory.GetCasesDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = casesDao.CRMDbContext.Cases + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + casesDao.CRMDbContext.Cases + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs new file mode 100644 index 00000000000..2ba40eac7f4 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs @@ -0,0 +1,102 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerContact : FactoryIndexer + { + public FactoryIndexerContact( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var contactDao = DaoFactory.GetContactDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = contactDao.CRMDbContext.Contacts + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + contactDao.CRMDbContext.Contacts + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs new file mode 100644 index 00000000000..b1337001d1e --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs @@ -0,0 +1,104 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Text; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; +using Microsoft.Extensions.Options; +using Newtonsoft.Json.Linq; + +using Microsoft.Extensions.DependencyInjection; +using ASC.Common; +using ASC.CRM.Core.EF; +using ASC.ElasticSearch.Core; +using ASC.Common.Caching; +using ASC.CRM.Core.Dao; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerContactInfo : FactoryIndexer + { + public FactoryIndexerContactInfo( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var contactInfoDao = DaoFactory.GetContactInfoDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = contactInfoDao.CRMDbContext.ContactsInfo + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + contactInfoDao.CRMDbContext.ContactsInfo + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs new file mode 100644 index 00000000000..93fe4867691 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.Options; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerDeal : FactoryIndexer + { + public FactoryIndexerDeal( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var dealDao = DaoFactory.GetDealDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = dealDao.CRMDbContext.ContactsInfo + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + dealDao.CRMDbContext.Deals + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs new file mode 100644 index 00000000000..7597932b76b --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs @@ -0,0 +1,99 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.Options; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerEvents : FactoryIndexer + { + public FactoryIndexerEvents( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var eventsDao = DaoFactory.GetRelationshipEventDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = eventsDao.CRMDbContext.RelationshipEvent + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + eventsDao.CRMDbContext.RelationshipEvent + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs new file mode 100644 index 00000000000..5ce3f5e32fb --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs @@ -0,0 +1,103 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerFieldValue : FactoryIndexer + { + public FactoryIndexerFieldValue ( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var fieldValueDao = DaoFactory.GetCustomFieldDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = fieldValueDao.CRMDbContext.FieldValue + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + fieldValueDao.CRMDbContext.FieldValue + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs new file mode 100644 index 00000000000..37b9091bb76 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs @@ -0,0 +1,102 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerInvoice : FactoryIndexer + { + public FactoryIndexerInvoice( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var invoiceDao = DaoFactory.GetInvoiceDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = invoiceDao.CRMDbContext.Invoices + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + invoiceDao.CRMDbContext.Invoices + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs new file mode 100644 index 00000000000..2ca345c8158 --- /dev/null +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs @@ -0,0 +1,100 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.Options; + +namespace ASC.Web.CRM.Core.Search +{ + [Scope] + public sealed class FactoryIndexerTask : FactoryIndexer + { + public FactoryIndexerTask( + IOptionsMonitor options, + TenantManager tenantManager, + SearchSettingsHelper searchSettingsHelper, + FactoryIndexer factoryIndexer, + BaseIndexer baseIndexer, + IServiceProvider serviceProvider, + DaoFactory daoFactory, + ICache cache) + : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) + { + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + + public override void IndexAll() + { + var taskDao = DaoFactory.GetTaskDao(); + + (int, int, int) getCount(DateTime lastIndexed) + { + var q = taskDao.CRMDbContext.Tasks + .Where(r => r.LastModifedOn >= lastIndexed); + + var count = q.GroupBy(a => a.Id).Count(); + var min = count > 0 ? q.Min(r => r.Id) : 0; + var max = count > 0 ? q.Max(r => r.Id) : 0; + + return (count, max, min); + } + + List getData(long i, long step, DateTime lastIndexed) => + taskDao.CRMDbContext.Tasks + .Where(r => r.LastModifedOn >= lastIndexed) + .Where(r => r.Id >= i && r.Id <= i + step) + .Select(r => r) + .ToList(); + + try + { + foreach (var data in Indexer.IndexAll(getCount, getData)) + { + Index(data); + } + } + catch (Exception e) + { + Logger.Error(e); + throw; + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs b/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs deleted file mode 100644 index 6ded7ae62cb..00000000000 --- a/products/ASC.CRM/Server/Core/Search/FieldsWrapper.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common; -using ASC.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; - -using Microsoft.Extensions.DependencyInjection; - -namespace ASC.Web.CRM.Core.Search -{ - public sealed class FieldsWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [ColumnCondition("field_id", 1)] - public int FieldId { get; set; } - - [ColumnCondition("entity_id", 2)] - public int EntityId { get; set; } - - [ColumnCondition("entity_type", 3)] - public int EntityType { get; set; } - - [Column("value", 4)] - public string Value { get; set; } - - protected override string Table { get { return "crm_field_value"; } } - - public static FieldsWrapper GetEventsWrapper(IServiceProvider serviceProvider, CustomField cf) - { - var tenantManager = serviceProvider.GetService(); - - return new FieldsWrapper - { - Id = cf.ID, - EntityId = cf.EntityID, - EntityType = (int)cf.EntityType, - Value = cf.Value, - TenantId = tenantManager.GetCurrentTenant().TenantId - }; - } - } - - public static class FieldsWrapperExtention - { - public static DIHelper AddFieldsWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs b/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs deleted file mode 100644 index 98518708c31..00000000000 --- a/products/ASC.CRM/Server/Core/Search/InfoWrapper.cs +++ /dev/null @@ -1,127 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using System.Text; -using ASC.Common.Logging; -using ASC.Core; -using ASC.CRM.Core; -using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; -using Microsoft.Extensions.Options; -using Newtonsoft.Json.Linq; - -using Microsoft.Extensions.DependencyInjection; -using ASC.Common; - -namespace ASC.Web.CRM.Core.Search -{ - public class InfoWrapper : Wrapper - { - public InfoWrapper(IOptionsMonitor logger) - { - Logger = logger.Get("ASC"); - } - - public ILog Logger { get; } - - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [ColumnCondition("contact_id", 1)] - public int ContactId { get; set; } - - [ColumnMeta("type", 2)] - public int Type { get; set; } - - [Column("data", 3)] - public string Data - { - get - { - if (Type == (int)ContactInfoType.Address && !string.IsNullOrEmpty(data)) - { - try - { - var result = new StringBuilder(); - var obj = JObject.Parse(data); - foreach (var o in obj.Values()) - { - var val = o.ToString(); - if (!string.IsNullOrEmpty(val)) - { - result.AppendFormat("{0} ", val); - } - } - return result.ToString().TrimEnd(); - } - catch (Exception e) - { - Logger.Error("Index Contact Adrress Parse", e); - } - - return ""; - } - - return data; - } - set - { - data = value; - } - } - - protected override string Table { get { return "crm_contact_info"; } } - - private string data; - - public static InfoWrapper Get(IServiceProvider serviceProvider, ContactInfo cf) - { - var logger = serviceProvider.GetService>(); - var tenantManager = serviceProvider.GetService(); - - return new InfoWrapper(logger) - { - Id = cf.ID, - ContactId = cf.ContactID, - Data = cf.Data, - Type = (int)cf.InfoType, - TenantId = tenantManager.GetCurrentTenant().TenantId - }; - } - } - - public static class InfoWrapperExtention - { - public static DIHelper AddInfoWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs b/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs deleted file mode 100644 index 321d32a8497..00000000000 --- a/products/ASC.CRM/Server/Core/Search/InvoicesWrapper.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common; -using ASC.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; - -using Microsoft.Extensions.DependencyInjection; - - -namespace ASC.Web.CRM.Core.Search -{ - public sealed class InvoicesWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [Column("number", 1)] - public string Number { get; set; } - - [Column("terms", 2)] - public string Terms { get; set; } - - [Column("description", 3)] - public string Description { get; set; } - - [Column("purchase_order_number", 4)] - public string PurchaseOrderNumber { get; set; } - - protected override string Table { get { return "crm_invoice"; } } - - public static InvoicesWrapper FromInvoice(int tenantId, Invoice invoice) - { - return new InvoicesWrapper - { - Id = invoice.ID, - Number = invoice.Number, - Terms = invoice.Terms, - Description = invoice.Description, - PurchaseOrderNumber = invoice.PurchaseOrderNumber, - TenantId = tenantId - }; - } - } - - public static class InvoicesWrapperExtention - { - public static DIHelper AddInvoicesWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs b/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs deleted file mode 100644 index 127815aab62..00000000000 --- a/products/ASC.CRM/Server/Core/Search/TasksWrapper.cs +++ /dev/null @@ -1,74 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System; -using ASC.Common; -using ASC.Core; -using ASC.CRM.Core.Entities; -using ASC.ElasticSearch; - -using Microsoft.Extensions.DependencyInjection; - - -namespace ASC.Web.CRM.Core.Search -{ - public sealed class TasksWrapper : Wrapper - { - [ColumnLastModified("last_modifed_on")] - public override DateTime LastModifiedOn { get; set; } - - [Column("title", 1)] - public string Title { get; set; } - - [Column("description", 2)] - public string Description { get; set; } - - protected override string Table { get { return "crm_task"; } } - - public static TasksWrapper FromTask(int tenantId, Task task) - { - return new TasksWrapper - { - Id = task.ID, - Title = task.Description, - Description = task.Description, - TenantId = tenantId - }; - } - } - - public static class TasksWrapperExtention - { - public static DIHelper AddTasksWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services - .AddFactoryIndexerService(); - } - } - -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 8d5511c8562..3d2bb49f606 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -858,23 +858,5 @@ public bool CanGoToFeed(Task task) { return IsAdmin || task.ResponsibleID == SecurityContext.CurrentAccount.ID || task.CreateBy == SecurityContext.CurrentAccount.ID; } - } - - public static class CRMSecurityExtention - { - public static DIHelper AddCRMSecurityService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddSecurityContextService() - .AddAuthorizationManagerService() - .AddUserManagerService() - .AddDisplayUserSettingsService() - // .AddDaoFactoryService() - .AddWebItemSecurity() - .AddPermissionContextService() - .AddCurrencyProviderService() - ; - } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs index fbb9505e681..0bd1b39ed91 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs @@ -36,6 +36,7 @@ namespace ASC.Web.CRM.HttpHandlers { + [Transient] public class FileHandler { public FileHandler(RequestDelegate next, @@ -112,16 +113,4 @@ public async Task InvokeAsync(HttpContext context) } } } - - - public static class FileHandlerExtension - { - public static DIHelper AddFileHandlerService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddGlobalService() - .AddContactPhotoManagerService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CasesWrapper.cs b/products/ASC.CRM/Server/Model/CasesWrapper.cs index 10e6659cf98..608cb3d28f6 100644 --- a/products/ASC.CRM/Server/Model/CasesWrapper.cs +++ b/products/ASC.CRM/Server/Model/CasesWrapper.cs @@ -91,6 +91,7 @@ public static CasesWrapper GetSample() } } + [Transient] public class CasesWrapperHelper { public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -155,18 +156,6 @@ public CasesWrapper Get(Cases cases) return result; } } - - public static class CasesWrapperHelperExtension - { - public static DIHelper AddCasesWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService(); - } - } } diff --git a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs index cd592c7e10e..ed6f3824d5a 100644 --- a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs +++ b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs @@ -108,7 +108,6 @@ public static bool TryParse(ContactInfo contactInfo, out Address res) [DataMember(Order = 8, IsRequired = false, EmitDefaultValue = false)] public Boolean IsPrimary { get; set; } - public static Address GetSample() { return new Address @@ -166,6 +165,7 @@ public static ContactInfoWrapper GetSample() } } + [Transient] public class ContactInfoWrapperHelper { public ContactInfoWrapperHelper() @@ -188,14 +188,4 @@ public ContactInfoWrapper Get(ContactInfo contactInfo) } } - - public static class ContactInfoWrapperHelperExtension - { - public static DIHelper AddContactInfoWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/ContactWrapper.cs b/products/ASC.CRM/Server/Model/ContactWrapper.cs index 6fe7a088a47..45f670f07c8 100644 --- a/products/ASC.CRM/Server/Model/ContactWrapper.cs +++ b/products/ASC.CRM/Server/Model/ContactWrapper.cs @@ -85,6 +85,7 @@ public PersonWrapper() } } + [Transient] public class PersonWrapperHelper { public PersonWrapperHelper() @@ -114,16 +115,6 @@ public PersonWrapper GetQuick(Person person) } - public static class PersonWrapperHelperHelperExtension - { - public static DIHelper AddPersonWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } - /// /// Company /// @@ -372,6 +363,7 @@ public class ContactWithTaskWrapper public ContactWrapper Contact { get; set; } } + [Transient] public class ContactWrapperHelper { public ContactWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -563,18 +555,4 @@ public PersonWrapper GetPersonWrapperQuick(Person person) } } - public static class ContactWrapperHelperExtension - { - public static DIHelper AddContactWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService() - .AddCurrencyProviderService() - .AddCRMPathProviderService(); - } - } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs index fe77216e1cd..dffed5a5998 100644 --- a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs +++ b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs @@ -75,6 +75,7 @@ public static CurrencyInfoWrapper GetSample() } } + [Transient] public class CurrencyInfoWrapperHelper { public CurrencyInfoWrapperHelper() @@ -98,19 +99,7 @@ public CurrencyInfoWrapper Get(CurrencyInfo currencyInfo) }; } } - - public static class CurrencyInfoWrapperExtension - { - public static DIHelper AddCurrencyInfoWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } - - - + /// /// Currency rate information /// @@ -131,7 +120,7 @@ public CurrencyRateInfoWrapper() public decimal Rate { get; set; } } - + [Transient] public class CurrencyRateInfoWrapperHelper { public CurrencyRateInfoWrapperHelper(CurrencyInfoWrapperHelper currencyInfoWrapperHelper) @@ -157,14 +146,4 @@ public CurrencyRateInfoWrapper Get(CurrencyInfo currencyInfo, decimal rate) }; } } - - public static class CurrencyRateInfoWrapperExtension - { - public static DIHelper AddCurrencyRateInfoWrapperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs index 841027f1c8f..5e4d8ab614d 100644 --- a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs +++ b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs @@ -26,11 +26,9 @@ using System; using System.Runtime.Serialization; -using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; + using ASC.Common; using ASC.CRM.Core; -using ASC.Web.Api.Models; namespace ASC.Api.CRM { @@ -69,6 +67,7 @@ public static CurrencyRateWrapper GetSample() } } + [Transient] public class CurrencyRateWrapperHelper { public CurrencyRateWrapperHelper() @@ -85,17 +84,4 @@ public CurrencyRateWrapper Get(CurrencyRate currencyRate) }; } } - - public static class CurrencyRateWrapperHelperExtension - { - public static DIHelper AddCurrencyRateWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } - - - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs index 6d3faa4fe87..a87e7fb0695 100644 --- a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs +++ b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs @@ -116,6 +116,7 @@ public InvoiceBaseWrapper() public bool CanDelete { get; set; } } + [Transient] public class InvoiceBaseWrapperHelper { public InvoiceBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -200,21 +201,6 @@ public InvoiceBaseWrapper Get(Invoice invoice) } } - public static class InvoiceBaseWrapperHelperExtension - { - public static DIHelper AddInvoiceBaseWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService() - .AddSettingsManagerService() - .AddCurrencyProviderService() - .AddInvoiceStatusWrapperHelperService(); - } - } - /// /// Invoice /// @@ -254,7 +240,7 @@ public static InvoiceWrapper GetSample() } } - + [Transient] public class InvoiceWrapperHelper { public InvoiceWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -345,21 +331,6 @@ public InvoiceWrapper Get(Invoice invoice) } } - public static class InvoiceWrapperHelperExtension - { - public static DIHelper AddInvoiceWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddCurrencyProviderService() - .AddSettingsManagerService() - .AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService() - .AddInvoiceStatusWrapperHelperService(); - } - } - /// /// Invoice Item /// @@ -475,19 +446,18 @@ public InvoiceItemWrapper Get(InvoiceItem invoiceItem) } - public static class InvoiceItemWrapperHelperExtension - { - public static DIHelper AddInvoiceItemWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddCurrencyProviderService() - .AddSettingsManagerService() - .AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService(); - } - } + //public static class InvoiceItemWrapperHelperExtension + //{ + // public static DIHelper AddInvoiceItemWrapperHelperService(this DIHelper services) + // { + // services.TryAddTransient(); + // return services.AddCurrencyProviderService() + // .AddSettingsManagerService() + // .AddApiDateTimeHelper() + // .AddEmployeeWraper() + // .AddCRMSecurityService(); + // } + //} /// /// Invoice Tax @@ -525,6 +495,7 @@ public InvoiceTaxWrapper() public bool CanDelete { get; set; } } + [Transient] public class InvoiceTaxWrapperHelper { public InvoiceTaxWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -556,16 +527,6 @@ public InvoiceTaxWrapper Get(InvoiceTax invoiceTax) } } - public static class InvoiceTaxWrapperHelperExtension - { - public static DIHelper AddInvoiceTaxWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } - /// /// Invoice Line /// @@ -623,6 +584,7 @@ public static InvoiceLineWrapper GetSample() } } + [Transient] public class InvoiceLineWrapperHelper { public InvoiceLineWrapperHelper() @@ -647,16 +609,6 @@ public InvoiceLineWrapper Get(InvoiceLine invoiceLine) } } - public static class InvoiceLineWrapperHelperExtension - { - public static DIHelper AddInvoiceLineWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } - /// /// Invoice Status /// @@ -685,6 +637,7 @@ public static InvoiceStatusWrapper GetSample() } + [Transient] public class InvoiceStatusWrapperHelper { public InvoiceStatusWrapperHelper() @@ -701,13 +654,4 @@ public InvoiceStatusWrapper Get(InvoiceStatus status) } } - public static class InvoiceStatusWrapperHelperExtension - { - public static DIHelper AddInvoiceStatusWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } } diff --git a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs index 3f74fa5ce71..9634ab27fe6 100644 --- a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs +++ b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs @@ -131,6 +131,7 @@ public static OpportunityWrapper GetSample() } + [Transient] public class OpportunityWrapperHelper { public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -216,19 +217,4 @@ public OpportunityWrapper Get(Deal deal) return dealWrapper; } } - - public static class OpportunityWrapperHelperExtension - { - public static DIHelper AddOpportunityWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService() - .AddDaoFactoryService() - .AddContactWrapperHelperService() - .AddCurrencyProviderService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs index 4bf781f40c0..684fde57372 100644 --- a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs +++ b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs @@ -61,7 +61,7 @@ public static EntityWrapper GetSample() } } - + [Transient] public class EntityWrapperHelper { public EntityWrapperHelper(DaoFactory daoFactory) @@ -108,20 +108,6 @@ public EntityWrapper Get(EntityType entityType, int entityID) } } - - public static class EntityWrapperHelperExtension - { - public static DIHelper AddEntityWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } - - - - [DataContract(Name = "historyEvent", Namespace = "")] public class RelationshipEventWrapper { @@ -173,6 +159,7 @@ public static RelationshipEventWrapper GetSample() } } + [Transient] public class RelationshipEventWrapperHelper { public RelationshipEventWrapperHelper( @@ -243,17 +230,4 @@ public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) } } - public static class RelationshipEventWrapperHelperExtension - { - public static DIHelper AddRelationshipEventWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService() - .AddContactWrapperHelperService() - .AddFileWrapperHelperService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/TaskWrapper.cs b/products/ASC.CRM/Server/Model/TaskWrapper.cs index 7986867f458..4cd900857c1 100644 --- a/products/ASC.CRM/Server/Model/TaskWrapper.cs +++ b/products/ASC.CRM/Server/Model/TaskWrapper.cs @@ -152,6 +152,7 @@ public static TaskBaseWrapper GetSample() } } + [Transient] public class TaskWrapperHelper { @@ -228,16 +229,4 @@ public TaskWrapper GetTaskWrapper(Task task) return result; } } - - public static class TaskWrapperHelperExtension - { - public static DIHelper AddTaskWrapperHelperService(this DIHelper services) - { - services.TryAddTransient(); - - return services.AddApiDateTimeHelper() - .AddEmployeeWraper() - .AddCRMSecurityService(); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 91e8f3c453f..83769599723 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,111 +1,30 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using ASC.Api.Core.Auth; -using ASC.Api.Core.Core; -using ASC.Api.Core.Middleware; +using System.Text; + +using ASC.Api.Core; +using ASC.Api.CRM; using ASC.Common; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Mvc; + using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using ASC.Common.Logging; -using Autofac.Extensions.DependencyInjection; -using ASC.Common.DependencyInjection; -using ASC.Api.CRM; -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc.Authorization; -using Microsoft.AspNetCore.Mvc.Formatters; -using System.Text; namespace ASC.CRM { - public class Startup + public class Startup : BaseStartup { public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) + : base(configuration, hostEnvironment) { - Configuration = configuration; - HostEnvironment = hostEnvironment; } - public IHostEnvironment HostEnvironment { get; } - - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) + public override void ConfigureServices(IServiceCollection services) { - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - - services.AddHttpContextAccessor(); - - services.AddControllers() - .AddNewtonsoftJson() - .AddXmlSerializerFormatters(); - - services.AddTransient, CustomJsonOptionsWrapper>(); - - services.AddMemoryCache(); - - services.AddAuthentication("cookie") - .AddScheme("cookie", a => { }); + base.ConfigureServices(services); - var builder = services.AddMvcCore(config => - { - //var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); - //config.Filters.Add(new AuthorizeFilter(policy)); - //config.Filters.Add(new TypeFilterAttribute(typeof(TenantStatusFilter))); - //config.Filters.Add(new TypeFilterAttribute(typeof(PaymentFilter))); - //config.Filters.Add(new TypeFilterAttribute(typeof(IpSecurityFilter))); - //config.Filters.Add(new TypeFilterAttribute(typeof(ProductSecurityFilter))); - //config.Filters.Add(new CustomResponseFilterAttribute()); - //config.Filters.Add(new CustomExceptionFilterAttribute()); - //config.Filters.Add(new TypeFilterAttribute(typeof(FormatFilter))); - - config.OutputFormatters.RemoveType(); - config.OutputFormatters.Add(new XmlOutputFormatter()); - }); - - var diHelper = new DIHelper(services); - diHelper - .AddCookieAuthHandler() - .AddCultureMiddleware() - .AddIpSecurityFilter() - .AddPaymentFilter() - .AddProductSecurityFilter() - .AddTenantStatusFilter(); - - - diHelper.AddNLogManager("ASC.CRM"); - - diHelper.AddCRMControllerService(); - - services.AddAutofac(Configuration, HostEnvironment.ContentRootPath); - - } - - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - - app.UseRouting(); + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - app.UseAuthorization(); + DIHelper.TryAdd(); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); - } + } } } diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 74ca4766ce1..f3eb683e9b8 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -42,7 +42,9 @@ using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Utils; using ASC.Web.Studio.Utility; -using Ionic.Zip; + +using ICSharpCode.SharpZipLib.Zip; + using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; using System; @@ -58,7 +60,12 @@ namespace ASC.Web.CRM.Classes { public class ExportDataCache { - public readonly ICache Cache = AscCache.Memory; + public ExportDataCache(AscCache ascCache) + { + Cache = ascCache; + } + + public readonly ICache Cache; public String GetStateCacheKey(string key) { @@ -146,9 +153,7 @@ public ExportDataOperation(UserManager userManager, public SecurityContext SecurityContext { get; } public DaoFactory DaoFactory { get; } public ExportDataCache ExportDataCache { get; } - public UserManager UserManager { get; } - public FileUtility FileUtility { get; } private readonly int _tenantId; @@ -324,7 +329,7 @@ private void ExportAllData(DaoFactory daoFactory) _totalCount += historyDao.GetAllItemsCount(); _totalCount += invoiceItemDao.GetInvoiceItemsCount(); - using (var zipStream = new ZipOutputStream(stream, true)) + using (var zipStream = new ZipOutputStream(stream)) { zipStream.AlternateEncoding = Encoding.UTF8; zipStream.AlternateEncodingUsage = ZipOption.Always; diff --git a/products/ASC.Files/Core/Core/FilesIntegration.cs b/products/ASC.Files/Core/Core/FilesIntegration.cs index c73dbb2aa23..63c88b4de43 100644 --- a/products/ASC.Files/Core/Core/FilesIntegration.cs +++ b/products/ASC.Files/Core/Core/FilesIntegration.cs @@ -39,7 +39,7 @@ public class FilesIntegration { private static readonly IDictionary providers = new Dictionary(); - private IDaoFactory DaoFactory { get; } + public IDaoFactory DaoFactory { get; } public FilesIntegration(IDaoFactory daoFactory) { From 8afbae082e767e8f9a7f5a3dd4b692e93d6c7c01 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 1 Mar 2021 20:36:18 +0300 Subject: [PATCH 16/61] crm: migrate from old project --- products/ASC.CRM/Server/ASC.CRM.csproj | 22 + .../Server/Classes/ContactPhotoManager.cs | 154 +- products/ASC.CRM/Server/Classes/Global.cs | 50 +- .../Server/Classes/InvoiceFormattedData.cs | 15 +- .../ASC.CRM/Server/Classes/PathProvider.cs | 13 +- .../Server/Classes/TwilioController.cs | 1118 +++---- products/ASC.CRM/Server/Classes/VoipEngine.cs | 41 +- .../Controllers/CRMController.ContactInfo.cs | 8 +- .../Controllers/CRMController.Contacts.cs | 4 +- .../Controllers/CRMController.CustomFields.cs | 2 +- .../Server/Controllers/CRMController.Deals.cs | 4 +- .../Controllers/CRMController.Invoices.cs | 2 +- .../Controllers/CRMController.ListItem.cs | 18 +- .../CRMController.RelationshipEvent.cs | 2 +- .../Server/Controllers/CRMController.Tasks.cs | 10 +- .../Server/Controllers/CRMController.Utils.cs | 184 +- .../Server/Controllers/CRMController.Voip.cs | 22 +- .../Server/Controllers/CRMController.cs | 51 +- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 4 +- .../Server/Core/Dao/CurrencyInfoDao.cs | 2 +- .../Server/Core/Dao/CurrencyRateDao.cs | 2 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 2 +- .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 2 + products/ASC.CRM/Server/Core/Dao/DealDao.cs | 5 +- .../Server/Core/Dao/DealMilestoneDao.cs | 4 +- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 2 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 4 +- .../Server/Core/Dao/RelationshipEventDao.cs | 4 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 7 +- .../Core/Dao/TaskTemplateContainerDao.cs | 13 +- .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 17 +- .../ASC.CRM/Server/Core/EF/DbContactInfo.cs | 45 +- .../ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs | 9 +- .../Server/Core/Entities/CurrencyInfo.cs | 2 - .../Core/Security/FileSecurityProvider.cs | 9 +- .../HttpHandlers/ContactPhotoHandler.cs | 65 +- .../{FileHandler.ashx.cs => FileHandler.cs} | 0 .../HttpHandlers/FileUploaderHandler.cs | 6 +- .../Server/HttpHandlers/ImportFileHandler.cs | 5 +- .../HttpHandlers/OrganisationLogoHandler.cs | 70 +- .../HttpHandlers/WebToLeadFromHandler.ashx.cs | 391 --- .../Server/HttpHandlers/filehandler.ashx | 4 - .../HttpHandlers/webtoleadfromhandler.ashx | 4 - products/ASC.CRM/Server/Model/CasesWrapper.cs | 2 +- .../Server/Model/ContactInfoWrapper.cs | 2 +- .../ASC.CRM/Server/Model/ContactWrapper.cs | 6 +- .../Server/Model/CurrencyInfoWrapper.cs | 5 +- .../Server/Model/CurrencyRateWrapper.cs | 2 +- .../ASC.CRM/Server/Model/InvoiceWrapper.cs | 11 +- .../ASC.CRM/Server/Model/ListItemWrapper.cs | 57 +- .../Server/Model/OpportunityWrapper.cs | 13 +- .../Server/Model/RelationshipEventWrapper.cs | 11 +- products/ASC.CRM/Server/Model/TaskWrapper.cs | 3 +- .../ASC.CRM/Server/Model/VoipCallWrapper.cs | 47 +- .../Services/NotifyService/NotifyClient.cs | 13 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 11 - products/ASC.CRM/Server/Utils/ExportToCSV.cs | 2905 +++++++++-------- .../Utils/Import/CSV/ImportDataOperation.cs | 10 +- .../Server/Utils/Import/CSV/ImportFromCSV.cs | 2 +- products/ASC.CRM/Server/Utils/MailSender.cs | 1874 +++++------ products/ASC.CRM/Server/Utils/PdfCreator.cs | 200 +- .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 8 +- .../proto/ContactPhotoManagerCacheItem.proto | 8 + 73 files changed, 3606 insertions(+), 4014 deletions(-) rename products/ASC.CRM/Server/HttpHandlers/{FileHandler.ashx.cs => FileHandler.cs} (100%) delete mode 100644 products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs delete mode 100644 products/ASC.CRM/Server/HttpHandlers/filehandler.ashx delete mode 100644 products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx create mode 100644 products/ASC.CRM/Server/proto/ContactPhotoManagerCacheItem.proto diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 68e870f818f..133676bccff 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -4,6 +4,18 @@ netcoreapp3.1 + + + + + + + + + + + + @@ -28,6 +40,11 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + @@ -173,6 +190,11 @@ + + + + + diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs index 64bf0581b6f..3c23480471d 100644 --- a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -33,7 +33,9 @@ using ASC.Web.Core; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM.Configuration; + using Microsoft.Extensions.Options; + using System; using System.Collections.Generic; using System.Drawing; @@ -73,22 +75,33 @@ public override int GetHashCode() } } + [Scope] public class ContactPhotoManager { public ContactPhotoManager(Global global, WebImageSupplier webImageSupplier, - IOptionsMonitor logger) + IOptionsMonitor logger, + ICache cache, + ICacheNotify cacheNotify) { Global = global; WebImageSupplier = webImageSupplier; + CacheNotify = cacheNotify; + Cache = cache; Logger = logger.Get("ASC.CRM"); + + CacheNotify.Subscribe((x) => + { + Cache.Remove($"contact_photo_cache_key_id_{x.Id}"); + + }, CacheNotifyAction.Remove); } public ILog Logger { get; } public Global Global { get; } - + public WebImageSupplier WebImageSupplier { get; } #region Members @@ -96,12 +109,11 @@ public ContactPhotoManager(Global global, private const string PhotosBaseDirName = "photos"; private const string PhotosDefaultTmpDirName = "temp"; - private readonly Dictionary> _photoCache = new Dictionary>(); - - private readonly WorkerQueue ResizeQueue = new WorkerQueue(2, TimeSpan.FromSeconds(30), 1, true); - private readonly ICacheNotify cachyNotify; + private readonly WorkerQueue ResizeQueue = new WorkerQueue(); + private readonly ICacheNotify CacheNotify; + private readonly ICache Cache; - private readonly Size _oldBigSize = new Size(145, 145); + private static readonly Size _oldBigSize = new Size(145, 145); private readonly Size _bigSize = new Size(200, 200); private readonly Size _mediumSize = new Size(82, 82); @@ -113,82 +125,27 @@ public ContactPhotoManager(Global global, #region Cache and DataStore Methods - ContactPhotoManager() - { - cachyNotify = AscCache.Memory; - cachyNotify.Subscribe>>( - (item, action) => - { - var contactID = item.Key; - var sizeUriPair = item.Value; - - switch (action) - { - case CacheNotifyAction.InsertOrUpdate: - ToPrivateCache(contactID, sizeUriPair.Value, sizeUriPair.Key); - break; - case CacheNotifyAction.Remove: - RemoveFromPrivateCache(contactID); - break; - } - }); - } - private String FromCache(int contactID, Size photoSize) { - lock (locker) - { - if (_photoCache.ContainsKey(contactID)) - { - if (_photoCache[contactID].ContainsKey(photoSize)) - { - return _photoCache[contactID][photoSize]; - } - if (photoSize == _bigSize && _photoCache[contactID].ContainsKey(_oldBigSize)) - { - return _photoCache[contactID][_oldBigSize]; - } - } - } - return String.Empty; - } + var cacheItem = Cache.Get>($"contact_photo_cache_key_id_{contactID}"); - private void RemoveFromCache(int contactID) - { - cachyNotify.Publish(CreateCacheItem(contactID, "", Size.Empty), CacheNotifyAction.Remove); - } + if (cacheItem is null) return String.Empty; - private void RemoveFromPrivateCache(int contactID) - { - lock (locker) - { - _photoCache.Remove(contactID); - } + if (cacheItem.ContainsKey(photoSize)) return cacheItem[photoSize]; + + return String.Empty; } private void ToCache(int contactID, String photoUri, Size photoSize) { - cachyNotify.Publish(CreateCacheItem(contactID, photoUri, photoSize), CacheNotifyAction.InsertOrUpdate); - } + var photoUriBySize = Cache.Get>($"contact_photo_cache_key_id_{contactID}"); - private void ToPrivateCache(int contactID, String photoUri, Size photoSize) - { - lock (locker) - { - if (_photoCache.ContainsKey(contactID)) - if (_photoCache[contactID].ContainsKey(photoSize)) - _photoCache[contactID][photoSize] = photoUri; - else - _photoCache[contactID].Add(photoSize, photoUri); - else - _photoCache.Add(contactID, new Dictionary {{photoSize, photoUri}}); - } - } + if (photoUriBySize.ContainsKey(photoSize)) + photoUriBySize[photoSize] = photoUri; + else + photoUriBySize.Add(photoSize, photoUri); - private KeyValuePair> CreateCacheItem(int contactID, String photoUri, Size photoSize) - { - var sizeUriPair = new KeyValuePair(photoSize, photoUri); - return new KeyValuePair>(contactID, sizeUriPair); + Cache.Insert($"contact_photo_cache_key_id_{contactID}", photoUriBySize, TimeSpan.FromMinutes(15)); } private String FromDataStore(int contactID, Size photoSize) @@ -419,7 +376,8 @@ public void DeletePhoto(int contactID, bool isTmpDir, string tmpDirName, bool re if (!isTmpDir) { - RemoveFromCache(contactID); + Cache.Remove($"contact_photo_cache_key_id_{contactID}"); + CacheNotify.Publish(new ContactPhotoManagerCacheItem { Id = contactID }, CacheNotifyAction.Remove); } } } @@ -452,7 +410,7 @@ public void TryUploadPhotoFromTmp(int contactID, bool isNewContact, string tmpDi { DeletePhoto(contactID, false, null, false); } - foreach (var photoSize in new[] {_bigSize, _mediumSize, _smallSize}) + foreach (var photoSize in new[] { _bigSize, _mediumSize, _smallSize }) { var photoTmpPath = FromDataStoreRelative(isNewContact ? 0 : contactID, photoSize, true, tmpDirName); if (string.IsNullOrEmpty(photoTmpPath)) throw new Exception("Temp phono not found"); @@ -475,10 +433,10 @@ public void TryUploadPhotoFromTmp(int contactID, bool isNewContact, string tmpDi } DeletePhoto(contactID, true, tmpDirName, true); } - catch(Exception ex) + catch (Exception ex) { Logger.ErrorFormat("TryUploadPhotoFromTmp for contactID={0} failed witth error: {1}", contactID, ex); - + return; } } @@ -519,14 +477,14 @@ private PhotoData ResizeToBigSize(byte[] imageData, string tmpDirName) private PhotoData ResizeToBigSize(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) { var resizeWorkerItem = new ResizeWorkerItem - { - ContactID = contactID, - UploadOnly = uploadOnly, - RequireFotoSize = new[] {_bigSize}, - ImageData = imageData, - DataStore = Global.GetStore(), - TmpDirName = tmpDirName - }; + { + ContactID = contactID, + UploadOnly = uploadOnly, + RequireFotoSize = new[] { _bigSize }, + ImageData = imageData, + DataStore = Global.GetStore(), + TmpDirName = tmpDirName + }; ExecResizeImage(resizeWorkerItem); @@ -558,14 +516,14 @@ private void ExecGenerateThumbnail(byte[] imageData, string tmpDirName) private void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadOnly, string tmpDirName) { var resizeWorkerItem = new ResizeWorkerItem - { - ContactID = contactID, - UploadOnly = uploadOnly, - RequireFotoSize = new[] {_mediumSize, _smallSize}, - ImageData = imageData, - DataStore = Global.GetStore(), - TmpDirName = tmpDirName - }; + { + ContactID = contactID, + UploadOnly = uploadOnly, + RequireFotoSize = new[] { _mediumSize, _smallSize }, + ImageData = imageData, + DataStore = Global.GetStore(), + TmpDirName = tmpDirName + }; if (!ResizeQueue.GetItems().Contains(resizeWorkerItem)) ResizeQueue.Add(resizeWorkerItem); @@ -675,14 +633,4 @@ public class PhotoData #endregion } - - public static class ContactPhotoManagerExtension - { - public static DIHelper AddContactPhotoManagerService(this DIHelper services) - { - services.TryAddTransient(); - - return services; - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index f8fd05aa44b..868a7a14c85 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -58,8 +58,8 @@ public Global(StorageFactory storageFactory, CRMSecurity cRMSecurity, TenantManager tenantManager, SettingsManager settingsManager, - IConfiguration configuration - // PdfCreator pdfCreator + IConfiguration configuration, + PdfCreator pdfCreator ) { StorageFactory = storageFactory; @@ -70,10 +70,10 @@ IConfiguration configuration TenantID = tenantManager.GetCurrentTenant().TenantId; SettingsManager = settingsManager; Configuration = configuration; - // PdfCreator = pdfCreator; + PdfCreator = pdfCreator; } -// public PdfCreator PdfCreator { get; } + public PdfCreator PdfCreator { get; } public IConfiguration Configuration { get; } public SettingsManager SettingsManager { get; } @@ -102,9 +102,7 @@ IConfiguration configuration public StorageFactory StorageFactory { get; } public CRMSecurity CRMSecurity { get; } - - - + public IDataStore GetStore() { return StorageFactory.GetStorage(TenantID.ToString(), "crm"); @@ -184,23 +182,27 @@ public void SaveDefaultCurrencySettings(CurrencyInfo currency) tenantSettings.DefaultCurrency = currency; SettingsManager.Save(tenantSettings); } - - //public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) - //{ - // var existingFile = invoice.GetInvoiceFile(factory); - // if (existingFile != null) - // { - // return existingFile; - // } - // else - // { - // var newFile = PdfCreator.CreateFile(invoice, factory); - // invoice.FileID = Int32.Parse(newFile.ID.ToString()); - // factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - // factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); - // return newFile; - // } - //} + + public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) + { + var existingFile = invoice.GetInvoiceFile(factory); + if (existingFile != null) + { + return existingFile; + } + else + { + var newFile = PdfCreator.CreateFile(invoice, factory); + + invoice.FileID = Int32.Parse(newFile.ID.ToString()); + + factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + + factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + + return newFile; + } + } /// /// The method to Decode your Base64 strings. diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 91d4b5962a7..e846bd64f37 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -37,6 +37,7 @@ namespace ASC.Web.CRM.Classes { + [Scope] public class InvoiceFormattedData { public InvoiceFormattedData(DaoFactory daoFactory, @@ -680,17 +681,5 @@ private InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, return data; } - } - - - public static class InvoiceFormattedDataExtention - { - public static DIHelper AddInvoiceFormattedDataService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddOrganisationLogoManagerService(); - // .AddDaoFactoryService(); - } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/PathProvider.cs b/products/ASC.CRM/Server/Classes/PathProvider.cs index 773eceb3d5b..9a4dc49290c 100644 --- a/products/ASC.CRM/Server/Classes/PathProvider.cs +++ b/products/ASC.CRM/Server/Classes/PathProvider.cs @@ -38,6 +38,7 @@ namespace ASC.Web.CRM { + [Scope] public class PathProvider { public PathProvider(IHttpContextAccessor httpContextAccessor, @@ -105,16 +106,6 @@ public String StartURL() // return fileName; //} - } - - public static class PathProviderExtention - { - public static DIHelper AddCRMPathProviderService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCommonLinkUtilityService(); - } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/TwilioController.cs b/products/ASC.CRM/Server/Classes/TwilioController.cs index e877c3a7ad2..b3fe4aea856 100644 --- a/products/ASC.CRM/Server/Classes/TwilioController.cs +++ b/products/ASC.CRM/Server/Classes/TwilioController.cs @@ -1,580 +1,538 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common; -using ASC.Common.Logging; -using ASC.Core; -using ASC.Core.Common.Configuration; -using ASC.Core.Notify.Signalr; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.VoipService; -using ASC.VoipService.Twilio; -using ASC.Web.Studio.Utility; -using Autofac; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.Filters; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Web; -using System.Web.Http; -using Twilio.AspNet.Common; -using Twilio.AspNet.Core; -using Twilio.TwiML; - -namespace ASC.Web.CRM.Classes -{ - - [ServiceFilter(typeof(ValidateRequestFilter))] - public class TwilioController : ApiController - { - public TwilioController(IOptionsMonitor logger, - DaoFactory daoFactory, - VoipEngine voipEngine, - TenantManager tenantManager, - SecurityContext securityContext) - { - TenantManager = tenantManager; - Log = logger.Get("ASC"); - DaoFactory = daoFactory; - VoipEngine = voipEngine; - SecurityContext = securityContext; - } - - public SecurityContext SecurityContext { get; } - public TenantManager TenantManager { get; } - public VoipEngine VoipEngine { get; } - public DaoFactory DaoFactory { get; } - - private readonly ILog Log; - private static readonly object LockObj = new object(); - - [System.Web.Http.HttpPost] - public HttpResponseMessage Index(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) - { - try - { - lock (LockObj) - { - request.AddAdditionalFields(callerId, contactId); - - var response = request.IsInbound ? Inbound(request, DaoFactory) : Outbound(request, DaoFactory); - - return GetHttpResponse(response); - - } - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage Client(TwilioVoiceRequest request, [FromUri]Guid callerId) - { - try - { - request.AddAdditionalFields(callerId); - - VoipEngine.SaveOrUpdateCall(CallFromTwilioRequest(request)); - - return GetHttpResponse(new VoiceResponse()); - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage Dial(TwilioVoiceRequest request, [FromUri]Guid callerId, [FromUri]int contactId = 0, [FromUri]string reject = null) - { - try - { - request.AddAdditionalFields(callerId, contactId, reject); - - var call = CallFromTwilioRequest(request); - call = VoipEngine.SaveOrUpdateCall(call); - - var parentCall = DaoFactory.GetVoipDao().GetCall(call.ParentID); - - if (!string.IsNullOrEmpty(request.RecordingSid)) - { - if (parentCall.VoipRecord == null || string.IsNullOrEmpty(parentCall.VoipRecord.Id)) - { - parentCall.VoipRecord = new VoipRecord { Id = request.RecordingSid }; - } - - DaoFactory.GetVoipDao().SaveOrUpdateCall(parentCall); - } - - VoipEngine.SaveAdditionalInfo(parentCall.Id); - - return GetHttpResponse(request.Dial()); - - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage Enqueue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) - { - try - { - request.AddAdditionalFields(callerId, contactId); - - if (request.QueueResult != "bridged" && request.QueueResult != "redirected") - { - MissCall(request, VoipEngine); - } - - return GetHttpResponse(request.Enqueue(request.QueueResult)); - - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage Queue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) - { - try - { - request.AddAdditionalFields(callerId, contactId); - return GetHttpResponse(request.Queue()); - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage Dequeue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0, [FromUri]string reject = "") - { - try - { - request.AddAdditionalFields(callerId, contactId, reject); - - if (Convert.ToBoolean(request.Reject)) - { - MissCall(request, VoipEngine); - return GetHttpResponse(request.Leave()); - } - - VoipEngine.AnswerCall(CallFromTwilioRequest(request)); - - return GetHttpResponse(request.Dequeue()); - - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage Wait(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0, [FromUri]string redirectTo = null) - { - try - { - - request.AddAdditionalFields(callerId, contactId, redirectTo: redirectTo); - if (Convert.ToInt32(request.QueueTime) == 0) - { - var history = CallFromTwilioRequest(request); - - history.ParentID = history.Id; - - VoipEngine.SaveOrUpdateCall(history); - - var to = request.RedirectTo; - if (string.IsNullOrEmpty(to)) - { - request.GetSignalRHelper() - .Enqueue(request.CallSid, callerId.HasValue ? callerId.Value.ToString() : ""); - } - else - { - request.GetSignalRHelper().Incoming(request.CallSid, to); - } - } - - return GetHttpResponse(request.Wait()); - - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage GatherQueue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) - { - try - { - request.AddAdditionalFields(callerId, contactId); - return GetHttpResponse(request.GatherQueue()); - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage Redirect(TwilioVoiceRequest request, [FromUri]string redirectTo, [FromUri]Guid? callerId = null) - { - try - { - request.AddAdditionalFields(callerId, redirectTo: redirectTo); - return GetHttpResponse(request.Redirect()); - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - [System.Web.Http.HttpPost] - public HttpResponseMessage VoiceMail(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) - { - try - { - request.AddAdditionalFields(callerId, contactId); - - MissCall(request, VoipEngine); - - return GetHttpResponse(request.VoiceMail()); - - } - catch (Exception e) - { - Log.Error(e); - throw; - } - } - - private VoiceResponse Inbound(TwilioVoiceRequest request, DaoFactory daoFactory) - { - SecurityContext.AuthenticateMe(TenantManager.GetCurrentTenant().OwnerId); - var call = SaveCall(request, VoipCallStatus.Incoming, daoFactory); - - return request.Inbound(call, daoFactory); - } - - private VoiceResponse Outbound(TwilioVoiceRequest request, DaoFactory daoFactory) - { - SaveCall(request, VoipCallStatus.Outcoming, daoFactory); - - var history = CallFromTwilioRequest(request); - history.ParentID = history.Id; - - VoipEngine.SaveOrUpdateCall(history); - - return request.Outbound(); - } - - private VoipCall SaveCall(TwilioVoiceRequest request, VoipCallStatus status, DaoFactory daoFactory) - { - var call = CallFromTwilioRequest(request); - call.Status = status; - - return DaoFactory.GetVoipDao().SaveOrUpdateCall(call); - } - - private void MissCall(TwilioVoiceRequest request, VoipEngine voipEngine) - { - var voipCall = CallFromTwilioRequest(request); - voipCall.Status = VoipCallStatus.Missed; - - if (!string.IsNullOrEmpty(request.RecordingSid)) - { - if (voipCall.VoipRecord == null || string.IsNullOrEmpty(voipCall.VoipRecord.Id)) - { - voipCall.VoipRecord = new VoipRecord { Id = request.RecordingSid }; - } - } - - voipCall = voipEngine.SaveOrUpdateCall(voipCall); - request.GetSignalRHelper().MissCall(request.CallSid, voipCall.AnsweredBy.ToString()); - voipEngine.SaveAdditionalInfo(voipCall.Id); - } - - private VoipCall CallFromTwilioRequest(TwilioVoiceRequest request) - { - if (!string.IsNullOrEmpty(request.DialCallSid)) - { - return new VoipCall - { - Id = request.DialCallSid, - ParentID = request.CallSid, - From = request.From, - To = request.To, - AnsweredBy = request.CallerId, - EndDialDate = DateTime.UtcNow - }; - } - - return new VoipCall - { - Id = request.CallSid, - ParentID = request.ParentCallSid, - From = request.From, - To = request.To, - AnsweredBy = request.CallerId, - Date = DateTime.UtcNow, - ContactId = request.ContactId - }; - } - - - private HttpResponseMessage GetHttpResponse(VoiceResponse response) - { - Log.Info(response); - return new HttpResponseMessage { Content = new StringContent(response.ToString(), Encoding.UTF8, "application/xml") }; - } - } - - public class TwilioVoiceRequest : VoiceRequest - { - public TwilioVoiceRequest(TwilioResponseHelper twilioResponseHelper, - CommonLinkUtility commonLinkUtility, - DaoFactory daoFactory, - SecurityContext securityContext, - CRMSecurity cRMSecurity, - VoipEngine voipEngine, - SignalrServiceClient signalrServiceClient) - { - - DaoFactory = daoFactory; - CommonLinkUtility = commonLinkUtility; - TwilioResponseHelper = twilioResponseHelper; - SecurityContext = securityContext; - CRMSecurity = cRMSecurity; - VoipEngine = voipEngine; - SignalrServiceClient = signalrServiceClient; - - } - - public SignalrServiceClient SignalrServiceClient { get; } - - public VoipEngine VoipEngine { get; } - public CRMSecurity CRMSecurity { get; } - public TwilioResponseHelper TwilioResponseHelper { get; } - public CommonLinkUtility CommonLinkUtility { get; } - public DaoFactory DaoFactory { get; } - public SecurityContext SecurityContext { get; } - public Guid CallerId { get; set; } - public int ContactId { get; set; } - public string ParentCallSid { get; set; } - public string QueueResult { get; set; } - public string QueueTime { get; set; } - public string QueueSid { get; set; } - public bool Reject { get; set; } - public string RedirectTo { get; set; } - public string CurrentQueueSize { get; set; } - - public bool Pause { get { return GetSettings().Pause; } } - - private TwilioResponseHelper GetTwilioResponseHelper() - { - return TwilioResponseHelper; - } - - private VoipSettings settings; - private VoipSettings GetSettings() - { - return settings ?? (settings = DaoFactory.GetVoipDao().GetNumber(IsInbound ? To : From).Settings); - } - - private SignalRHelper signalRHelper; - public SignalRHelper GetSignalRHelper() - { - return signalRHelper ?? (signalRHelper = new SignalRHelper(IsInbound ? To : From, SignalrServiceClient)); - } - - public bool IsInbound - { - get { return Direction == "inbound"; } - } - - public void AddAdditionalFields(Guid? callerId, int contactId = 0, string reject = null, string redirectTo = null) - { - if (callerId.HasValue && !callerId.Value.Equals(ASC.Core.Configuration.Constants.Guest.ID)) - { - CallerId = callerId.Value; - SecurityContext.AuthenticateMe(CallerId); - } - if (contactId != 0) - { - ContactId = contactId; - } - - if (!string.IsNullOrEmpty(reject)) - { - Reject = Convert.ToBoolean(reject); - } - - if (!string.IsNullOrEmpty(redirectTo)) - { - RedirectTo = redirectTo; - } - } - - internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) - { - var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered - ? call.From - : call.To; - - Contact contact; - var contacts = VoipEngine.GetContacts(contactPhone, daoFactory); - var managers = contacts.SelectMany(CRMSecurity.GetAccessSubjectGuidsTo).ToList(); - var agent = GetSignalRHelper().GetAgent(managers); - - if (agent != null && agent.Item1 != null) - { - var agentId = agent.Item1.Id; - SecurityContext.AuthenticateMe(agentId); - call.AnsweredBy = agentId; - - contact = contacts.FirstOrDefault(CRMSecurity.CanAccessTo); - - DaoFactory.GetVoipDao().SaveOrUpdateCall(call); - } - else - { - contact = contacts.FirstOrDefault(); - } - - if (contact == null) - { - contact = VoipEngine.CreateContact(call.From.TrimStart('+')); - call.ContactId = contact.ID; - DaoFactory.GetVoipDao().SaveOrUpdateCall(call); - } - - return GetTwilioResponseHelper().Inbound(agent); - } - internal VoiceResponse Outbound() { return GetTwilioResponseHelper().Outbound(); } - internal VoiceResponse Dial() { return GetTwilioResponseHelper().Dial(); } - internal VoiceResponse Enqueue(string queueResult) { return GetTwilioResponseHelper().Enqueue(queueResult); } - internal VoiceResponse Queue() { return GetTwilioResponseHelper().Queue(); } - internal VoiceResponse Leave() { return GetTwilioResponseHelper().Leave(); } - internal VoiceResponse Dequeue() { return GetTwilioResponseHelper().Dequeue(); } - internal VoiceResponse Wait() { return GetTwilioResponseHelper().Wait(QueueSid, QueueTime, QueueTime); } - internal VoiceResponse GatherQueue() { return GetTwilioResponseHelper().GatherQueue(Digits, To.Substring(1), new List()); } - internal VoiceResponse Redirect() { return GetTwilioResponseHelper().Redirect(RedirectTo); } - internal VoiceResponse VoiceMail() { return GetTwilioResponseHelper().VoiceMail(); } - } - - public class ValidateRequestFilter : ActionFilterAttribute - { - public ValidateRequestFilter(ConsumerFactory consumerFactory, IHttpContextAccessor httpContextAccessor) - { - ConsumerFactory = consumerFactory; - HttpContext = httpContextAccessor?.HttpContext; - } - - public HttpContext HttpContext { get; } - public ConsumerFactory ConsumerFactory { get; } - - public override void OnActionExecuting(ActionExecutingContext filterContext) - { - if (!new RequestValidationHelper().IsValidRequest(filterContext.HttpContext, ConsumerFactory.Get()["twilioAuthToken"], HttpContext.Request.GetUrlRewriter().AbsoluteUri)) - filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden); - - base.OnActionExecuting(filterContext); - - } - } - - public static class TwilioControllerExtension - { - public static DIHelper AddTwilioControllerService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddDaoFactoryService() - .AddVoipEngineService() - .AddTenantManagerService() - .AddSecurityContextService(); - - } - } - - public static class TwilioVoiceRequestExtension - { - public static DIHelper AddTwilioVoiceRequestService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddCommonLinkUtilityService() - .AddDaoFactoryService() - .AddSecurityContextService() - .AddCRMSecurityService() - .AddSignalrServiceClient(); - - } - } - - - public static class ValidateRequestFilterExtension - { - public static DIHelper AddValidateRequestAttributeService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddConsumerFactoryService(); - - } - } - -} \ No newline at end of file +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//using ASC.Common; +//using ASC.Common.Logging; +//using ASC.Core; +//using ASC.Core.Common.Configuration; +//using ASC.Core.Notify.Signalr; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Dao; +//using ASC.CRM.Core.Entities; +//using ASC.VoipService; +//using ASC.VoipService.Twilio; +//using ASC.Web.Studio.Utility; +//using Autofac; +//using Microsoft.AspNetCore.Http; +//using Microsoft.AspNetCore.Mvc; +//using Microsoft.AspNetCore.Mvc.Filters; +//using Microsoft.Extensions.Options; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Net; +//using System.Net.Http; +//using System.Text; +//using System.Web; +//using Twilio.AspNet.Common; +//using Twilio.AspNet.Core; +//using Twilio.TwiML; + +//namespace ASC.Web.CRM.Classes +//{ +// [ServiceFilter(typeof(ValidateRequestFilter))] +// public class TwilioController : ApiController +// { +// public TwilioController(IOptionsMonitor logger, +// DaoFactory daoFactory, +// VoipEngine voipEngine, +// TenantManager tenantManager, +// SecurityContext securityContext) +// { +// TenantManager = tenantManager; +// Log = logger.Get("ASC"); +// DaoFactory = daoFactory; +// VoipEngine = voipEngine; +// SecurityContext = securityContext; +// } + +// public SecurityContext SecurityContext { get; } +// public TenantManager TenantManager { get; } +// public VoipEngine VoipEngine { get; } +// public DaoFactory DaoFactory { get; } + +// private readonly ILog Log; +// private static readonly object LockObj = new object(); + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Index(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) +// { +// try +// { +// lock (LockObj) +// { +// request.AddAdditionalFields(callerId, contactId); + +// var response = request.IsInbound ? Inbound(request, DaoFactory) : Outbound(request, DaoFactory); + +// return GetHttpResponse(response); + +// } +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Client(TwilioVoiceRequest request, [FromUri]Guid callerId) +// { +// try +// { +// request.AddAdditionalFields(callerId); + +// VoipEngine.SaveOrUpdateCall(CallFromTwilioRequest(request)); + +// return GetHttpResponse(new VoiceResponse()); +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Dial(TwilioVoiceRequest request, [FromUri]Guid callerId, [FromUri]int contactId = 0, [FromUri]string reject = null) +// { +// try +// { +// request.AddAdditionalFields(callerId, contactId, reject); + +// var call = CallFromTwilioRequest(request); +// call = VoipEngine.SaveOrUpdateCall(call); + +// var parentCall = DaoFactory.GetVoipDao().GetCall(call.ParentID); + +// if (!string.IsNullOrEmpty(request.RecordingSid)) +// { +// if (parentCall.VoipRecord == null || string.IsNullOrEmpty(parentCall.VoipRecord.Id)) +// { +// parentCall.VoipRecord = new VoipRecord { Id = request.RecordingSid }; +// } + +// DaoFactory.GetVoipDao().SaveOrUpdateCall(parentCall); +// } + +// VoipEngine.SaveAdditionalInfo(parentCall.Id); + +// return GetHttpResponse(request.Dial()); + +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Enqueue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) +// { +// try +// { +// request.AddAdditionalFields(callerId, contactId); + +// if (request.QueueResult != "bridged" && request.QueueResult != "redirected") +// { +// MissCall(request, VoipEngine); +// } + +// return GetHttpResponse(request.Enqueue(request.QueueResult)); + +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Queue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) +// { +// try +// { +// request.AddAdditionalFields(callerId, contactId); +// return GetHttpResponse(request.Queue()); +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Dequeue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0, [FromUri]string reject = "") +// { +// try +// { +// request.AddAdditionalFields(callerId, contactId, reject); + +// if (Convert.ToBoolean(request.Reject)) +// { +// MissCall(request, VoipEngine); +// return GetHttpResponse(request.Leave()); +// } + +// VoipEngine.AnswerCall(CallFromTwilioRequest(request)); + +// return GetHttpResponse(request.Dequeue()); + +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Wait(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0, [FromUri]string redirectTo = null) +// { +// try +// { + +// request.AddAdditionalFields(callerId, contactId, redirectTo: redirectTo); +// if (Convert.ToInt32(request.QueueTime) == 0) +// { +// var history = CallFromTwilioRequest(request); + +// history.ParentID = history.Id; + +// VoipEngine.SaveOrUpdateCall(history); + +// var to = request.RedirectTo; +// if (string.IsNullOrEmpty(to)) +// { +// request.GetSignalRHelper() +// .Enqueue(request.CallSid, callerId.HasValue ? callerId.Value.ToString() : ""); +// } +// else +// { +// request.GetSignalRHelper().Incoming(request.CallSid, to); +// } +// } + +// return GetHttpResponse(request.Wait()); + +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage GatherQueue(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) +// { +// try +// { +// request.AddAdditionalFields(callerId, contactId); +// return GetHttpResponse(request.GatherQueue()); +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage Redirect(TwilioVoiceRequest request, [FromUri]string redirectTo, [FromUri]Guid? callerId = null) +// { +// try +// { +// request.AddAdditionalFields(callerId, redirectTo: redirectTo); +// return GetHttpResponse(request.Redirect()); +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// [System.Web.Http.HttpPost] +// public HttpResponseMessage VoiceMail(TwilioVoiceRequest request, [FromUri]Guid? callerId = null, [FromUri]int contactId = 0) +// { +// try +// { +// request.AddAdditionalFields(callerId, contactId); + +// MissCall(request, VoipEngine); + +// return GetHttpResponse(request.VoiceMail()); + +// } +// catch (Exception e) +// { +// Log.Error(e); +// throw; +// } +// } + +// private VoiceResponse Inbound(TwilioVoiceRequest request, DaoFactory daoFactory) +// { +// SecurityContext.AuthenticateMe(TenantManager.GetCurrentTenant().OwnerId); +// var call = SaveCall(request, VoipCallStatus.Incoming, daoFactory); + +// return request.Inbound(call, daoFactory); +// } + +// private VoiceResponse Outbound(TwilioVoiceRequest request, DaoFactory daoFactory) +// { +// SaveCall(request, VoipCallStatus.Outcoming, daoFactory); + +// var history = CallFromTwilioRequest(request); +// history.ParentID = history.Id; + +// VoipEngine.SaveOrUpdateCall(history); + +// return request.Outbound(); +// } + +// private VoipCall SaveCall(TwilioVoiceRequest request, VoipCallStatus status, DaoFactory daoFactory) +// { +// var call = CallFromTwilioRequest(request); +// call.Status = status; + +// return DaoFactory.GetVoipDao().SaveOrUpdateCall(call); +// } + +// private void MissCall(TwilioVoiceRequest request, VoipEngine voipEngine) +// { +// var voipCall = CallFromTwilioRequest(request); +// voipCall.Status = VoipCallStatus.Missed; + +// if (!string.IsNullOrEmpty(request.RecordingSid)) +// { +// if (voipCall.VoipRecord == null || string.IsNullOrEmpty(voipCall.VoipRecord.Id)) +// { +// voipCall.VoipRecord = new VoipRecord { Id = request.RecordingSid }; +// } +// } + +// voipCall = voipEngine.SaveOrUpdateCall(voipCall); +// request.GetSignalRHelper().MissCall(request.CallSid, voipCall.AnsweredBy.ToString()); +// voipEngine.SaveAdditionalInfo(voipCall.Id); +// } + +// private VoipCall CallFromTwilioRequest(TwilioVoiceRequest request) +// { +// if (!string.IsNullOrEmpty(request.DialCallSid)) +// { +// return new VoipCall +// { +// Id = request.DialCallSid, +// ParentID = request.CallSid, +// From = request.From, +// To = request.To, +// AnsweredBy = request.CallerId, +// EndDialDate = DateTime.UtcNow +// }; +// } + +// return new VoipCall +// { +// Id = request.CallSid, +// ParentID = request.ParentCallSid, +// From = request.From, +// To = request.To, +// AnsweredBy = request.CallerId, +// Date = DateTime.UtcNow, +// ContactId = request.ContactId +// }; +// } + + +// private HttpResponseMessage GetHttpResponse(VoiceResponse response) +// { +// Log.Info(response); +// return new HttpResponseMessage { Content = new StringContent(response.ToString(), Encoding.UTF8, "application/xml") }; +// } +// } + +// [Scope] +// public class TwilioVoiceRequest : VoiceRequest +// { +// public TwilioVoiceRequest(TwilioResponseHelper twilioResponseHelper, +// CommonLinkUtility commonLinkUtility, +// DaoFactory daoFactory, +// SecurityContext securityContext, +// CRMSecurity cRMSecurity, +// VoipEngine voipEngine, +// SignalrServiceClient signalrServiceClient) +// { + +// DaoFactory = daoFactory; +// CommonLinkUtility = commonLinkUtility; +// TwilioResponseHelper = twilioResponseHelper; +// SecurityContext = securityContext; +// CRMSecurity = cRMSecurity; +// VoipEngine = voipEngine; +// SignalrServiceClient = signalrServiceClient; + +// } + +// public SignalrServiceClient SignalrServiceClient { get; } + +// public VoipEngine VoipEngine { get; } +// public CRMSecurity CRMSecurity { get; } +// public TwilioResponseHelper TwilioResponseHelper { get; } +// public CommonLinkUtility CommonLinkUtility { get; } +// public DaoFactory DaoFactory { get; } +// public SecurityContext SecurityContext { get; } +// public Guid CallerId { get; set; } +// public int ContactId { get; set; } +// public string ParentCallSid { get; set; } +// public string QueueResult { get; set; } +// public string QueueTime { get; set; } +// public string QueueSid { get; set; } +// public bool Reject { get; set; } +// public string RedirectTo { get; set; } +// public string CurrentQueueSize { get; set; } + +// public bool Pause { get { return GetSettings().Pause; } } + +// private TwilioResponseHelper GetTwilioResponseHelper() +// { +// return TwilioResponseHelper; +// } + +// private VoipSettings settings; +// private VoipSettings GetSettings() +// { +// return settings ?? (settings = DaoFactory.GetVoipDao().GetNumber(IsInbound ? To : From).Settings); +// } + +// private SignalRHelper signalRHelper; +// public SignalRHelper GetSignalRHelper() +// { +// return signalRHelper ?? (signalRHelper = new SignalRHelper(IsInbound ? To : From, SignalrServiceClient)); +// } + +// public bool IsInbound +// { +// get { return Direction == "inbound"; } +// } + +// public void AddAdditionalFields(Guid? callerId, int contactId = 0, string reject = null, string redirectTo = null) +// { +// if (callerId.HasValue && !callerId.Value.Equals(ASC.Core.Configuration.Constants.Guest.ID)) +// { +// CallerId = callerId.Value; +// SecurityContext.AuthenticateMe(CallerId); +// } +// if (contactId != 0) +// { +// ContactId = contactId; +// } + +// if (!string.IsNullOrEmpty(reject)) +// { +// Reject = Convert.ToBoolean(reject); +// } + +// if (!string.IsNullOrEmpty(redirectTo)) +// { +// RedirectTo = redirectTo; +// } +// } + +// internal VoiceResponse Inbound(VoipCall call, DaoFactory daoFactory) +// { +// var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered +// ? call.From +// : call.To; + +// Contact contact; +// var contacts = VoipEngine.GetContacts(contactPhone, daoFactory); +// var managers = contacts.SelectMany(CRMSecurity.GetAccessSubjectGuidsTo).ToList(); +// var agent = GetSignalRHelper().GetAgent(managers); + +// if (agent != null && agent.Item1 != null) +// { +// var agentId = agent.Item1.Id; +// SecurityContext.AuthenticateMe(agentId); +// call.AnsweredBy = agentId; + +// contact = contacts.FirstOrDefault(CRMSecurity.CanAccessTo); + +// DaoFactory.GetVoipDao().SaveOrUpdateCall(call); +// } +// else +// { +// contact = contacts.FirstOrDefault(); +// } + +// if (contact == null) +// { +// contact = VoipEngine.CreateContact(call.From.TrimStart('+')); +// call.ContactId = contact.ID; +// DaoFactory.GetVoipDao().SaveOrUpdateCall(call); +// } + +// return GetTwilioResponseHelper().Inbound(agent); +// } +// internal VoiceResponse Outbound() { return GetTwilioResponseHelper().Outbound(); } +// internal VoiceResponse Dial() { return GetTwilioResponseHelper().Dial(); } +// internal VoiceResponse Enqueue(string queueResult) { return GetTwilioResponseHelper().Enqueue(queueResult); } +// internal VoiceResponse Queue() { return GetTwilioResponseHelper().Queue(); } +// internal VoiceResponse Leave() { return GetTwilioResponseHelper().Leave(); } +// internal VoiceResponse Dequeue() { return GetTwilioResponseHelper().Dequeue(); } +// internal VoiceResponse Wait() { return GetTwilioResponseHelper().Wait(QueueSid, QueueTime, QueueTime); } +// internal VoiceResponse GatherQueue() { return GetTwilioResponseHelper().GatherQueue(Digits, To.Substring(1), new List()); } +// internal VoiceResponse Redirect() { return GetTwilioResponseHelper().Redirect(RedirectTo); } +// internal VoiceResponse VoiceMail() { return GetTwilioResponseHelper().VoiceMail(); } +// } + +// [Scope] +// public class ValidateRequestFilter : ActionFilterAttribute +// { +// public ValidateRequestFilter(ConsumerFactory consumerFactory, IHttpContextAccessor httpContextAccessor) +// { +// ConsumerFactory = consumerFactory; +// HttpContext = httpContextAccessor?.HttpContext; +// } + +// public HttpContext HttpContext { get; } +// public ConsumerFactory ConsumerFactory { get; } + +// public override void OnActionExecuting(ActionExecutingContext filterContext) +// { +// if (!new RequestValidationHelper().IsValidRequest(filterContext.HttpContext, ConsumerFactory.Get()["twilioAuthToken"], HttpContext.Request.GetUrlRewriter().AbsoluteUri)) +// filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden); + +// base.OnActionExecuting(filterContext); + +// } +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index fab91061302..f490a0cec1c 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -24,7 +24,10 @@ */ -using ASC.Common; +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Common.Logging; using ASC.Common.Threading.Workers; using ASC.Core; @@ -36,18 +39,15 @@ using ASC.CRM.Resources; using ASC.VoipService; using ASC.VoipService.Dao; -using ASC.Web.CRM.Core; -using Autofac; + using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; namespace ASC.Web.CRM.Classes { public class VoipEngine { private readonly WorkerQueue Queue = new WorkerQueue(); + private readonly object Locker = new object(); public VoipEngine(DaoFactory daoFactory, @@ -328,33 +328,4 @@ private class QueueItem public string CallID { get; set; } } } - - - - public static class VoipEngineExtension - { - public static DIHelper AddVoipEngineService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddDaoFactoryService() - .AddCRMSecurityService() - .AddTenantUtilService() - .AddSecurityContextService() - .AddTenantManagerService(); - } - } - - //public VoipEngine(DaoFactory daoFactory, - // CRMSecurity cRMSecurity, - // TenantUtil tenantUtil, - // SecurityContext securityContext, - // IOptionsMonitor logger, - // TenantManager tenantManager, - // VoipDao voipDao) - - - - - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs index 5cd4105c7ef..ef7fc81aadd 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs @@ -507,15 +507,9 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) DaoFactory.GetContactInfoDao().Delete(id); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; + MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - if (contactInfo.InfoType == ContactInfoType.Email) - { - FactoryIndexerEmailWrapper.DeleteAsync(EmailWrapper.GetEmailWrapper(TenantManager.CurrentTenant.TenantId, contact, new List { contactInfo})); - } - - FactoryIndexerInfoWrapper.DeleteAsync(InfoWrapper.Get(ServiceProvider, contactInfo)); - return wrapper; } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs index ed4dac1f613..05f28252743 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs @@ -1568,7 +1568,7 @@ public IEnumerable GetContactsByPrefix(string prefi { var people = person; - if (AuthManager.UserFormatter.GetUserName(people.FirstName, people.LastName).IndexOf(prefix, StringComparison.Ordinal) != -1) + if (UserFormatter.GetUserName(people.FirstName, people.LastName).IndexOf(prefix, StringComparison.Ordinal) != -1) { findedContacts.Add(person); } @@ -1991,7 +1991,7 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly if (nearestTasks.Any()) { - taskCategories = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => new TaskCategoryBaseWrapper(item)); + taskCategories = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => TaskCategoryWrapperHelper.Get(item)); } foreach (var contact in itemList) diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs index 2519846f5b3..1c1e6e78f7d 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs @@ -281,7 +281,7 @@ public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) var result = ToCustomFieldWrapper(customField); DaoFactory.GetCustomFieldDao().DeleteField(fieldid); - FactoryIndexerFieldsWrapper.DeleteAsync(Web.CRM.Core.Search.FieldsWrapper.GetEventsWrapper(ServiceProvider, customField)); + FactoryIndexerFieldValue.DeleteAsync(Web.CRM.Core.Search.FieldsWrapper.GetEventsWrapper(ServiceProvider, customField)); var messageAction = GetCustomFieldDeletedAction(ToEntityType(entityType)); MessageService.Send( messageAction, MessageTarget.Create(customField.ID), result.Label); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs index 83ff577ea4d..df90e5e346b 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs @@ -879,7 +879,7 @@ private IEnumerable ToListOpportunityWrapper(ICollection { if (item == null) return; - contacts.Add(item.ID, ToContactBaseWrapper(item)); + contacts.Add(item.ID, ContactWrapperHelper.GetContactBaseWrapper(item)); }); } @@ -914,7 +914,7 @@ private IEnumerable ToListOpportunityWrapper(ICollection GetInvoicePdfExistOrCreate(int invoiceid) throw CRMSecurity.CreateSecurityException(); } - return new FileWrapper(Global.GetInvoicePdfExistingOrCreate(invoice, DaoFactory)); + return FileWrapperHelper.Get(Global.GetInvoicePdfExistingOrCreate(invoice, DaoFactory)); } /// diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs b/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs index a402294a927..1da7db9f7bf 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs @@ -965,7 +965,7 @@ public IEnumerable GetHistoryCategoryWrapper() [Read(@"task/category")] public IEnumerable GetTaskCategories() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => new TaskCategoryWrapper(item)); + var result = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => (TaskCategoryWrapper)TaskCategoryWrapperHelper.Get(item)); var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory); @@ -1070,19 +1070,19 @@ public ContactTypeWrapper ToContactTypeWrapper(ListItem listItem) public HistoryCategoryWrapper ToHistoryCategoryWrapper(ListItem listItem) { - var result = new HistoryCategoryWrapper(listItem) - { - RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID) - }; + var result = (HistoryCategoryWrapper)HistoryCategoryWrapperHelper.Get(listItem); + + result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID); + return result; } public TaskCategoryWrapper ToTaskCategoryWrapper(ListItem listItem) { - var result = new TaskCategoryWrapper(listItem) - { - RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID) - }; + var result = (TaskCategoryWrapper)TaskCategoryWrapperHelper.Get(listItem); + + result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID); + return result; } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs index 53ed913c388..4e7e6e64d46 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs @@ -653,7 +653,7 @@ private IEnumerable ToListRelationshipEventWrapper(Lis } } - var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => new HistoryCategoryBaseWrapper(x)); + var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => HistoryCategoryWrapperHelper.Get(x)); var files = DaoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray()); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs index bab78430414..74ee25264bc 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs @@ -638,18 +638,20 @@ private IEnumerable ToTaskListWrapper(IEnumerable itemList) } } - var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => new TaskCategoryBaseWrapper(x)); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); - var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); + var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => TaskCategoryWrapperHelper.Get(x)); + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); + var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); foreach (var item in itemList) { - var taskWrapper = new TaskWrapper(item) { CanEdit = CRMSecurity.CanEdit(item) }; + var taskWrapper = TaskWrapperHelper.GetTaskWrapper(item); + taskWrapper.CanEdit = CRMSecurity.CanEdit(item); if (contacts.ContainsKey(item.ContactID)) { taskWrapper.Contact = contacts[item.ContactID]; } + if (restrictedContacts.ContainsKey(item.ContactID)) { taskWrapper.Contact = restrictedContacts[item.ContactID]; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs index 76b1955bfc1..c8fe0d18613 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs @@ -414,7 +414,7 @@ public string StartImportFromCSV(string entityType, string csvFileURI, string js throw new ArgumentException(); } - new ImportFromCSVManager().StartImport(entityTypeObj, csvFileURI, jsonSettings); + ImportFromCSVManager.StartImport(entityTypeObj, csvFileURI, jsonSettings); return ""; @@ -448,117 +448,117 @@ public IProgressItem GetImportFromCSVStatus(string entityType) return ImportFromCSV.GetStatus(entityTypeObj); } - /// false - [Read(@"import/samplerow")] - public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string jsonSettings) - { - if (String.IsNullOrEmpty(csvFileURI) || indexRow < 0) throw new ArgumentException(); + ///// false + //[Read(@"import/samplerow")] + //public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string jsonSettings) + //{ + // if (String.IsNullOrEmpty(csvFileURI) || indexRow < 0) throw new ArgumentException(); - if (!Global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException(); + // if (!Global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException(); - var CSVFileStream = Global.GetStore().GetReadStream("temp", csvFileURI); + // var CSVFileStream = Global.GetStore().GetReadStream("temp", csvFileURI); - return ImportFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings); - } + // return ImportFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings); + //} - /// false - [Create(@"import/uploadfake")] - public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings) - { - return new ImportFromCSVManager().ProcessUploadFake(csvFileURI, jsonSettings); - } + ///// false + //[Create(@"import/uploadfake")] + //public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings) + //{ + // return ImportFromCSVManager.ProcessUploadFake(csvFileURI, jsonSettings); + //} - /// false - [Read(@"export/status")] - public IProgressItem GetExportStatus() - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + ///// false + //[Read(@"export/status")] + //public IProgressItem GetExportStatus() + //{ + // if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - return ExportToCsv.GetStatus(false); + // return ExportToCsv.GetStatus(false); - } + //} - /// false - [Update(@"export/cancel")] - public IProgressItem CancelExport() - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + ///// false + //[Update(@"export/cancel")] + //public IProgressItem CancelExport() + //{ + // if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - ExportToCsv.Cancel(false); + // ExportToCsv.Cancel(false); - return ExportToCsv.GetStatus(false); + // return ExportToCsv.GetStatus(false); - } + //} - /// false - [Create(@"export/start")] - public IProgressItem StartExport() - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + ///// false + //[Create(@"export/start")] + //public IProgressItem StartExport() + //{ + // if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - MessageService.Send( MessageAction.CrmAllDataExported); + // MessageService.Send( MessageAction.CrmAllDataExported); - return ExportToCsv.Start(null, CRMSettingResource.Export + ".zip"); - } + // return ExportToCsv.Start(null, CRMSettingResource.Export + ".zip"); + //} - /// false - [Read(@"export/partial/status")] - public IProgressItem GetPartialExportStatus() - { - return ExportToCsv.GetStatus(true); - } + ///// false + //[Read(@"export/partial/status")] + //public IProgressItem GetPartialExportStatus() + //{ + // return ExportToCsv.GetStatus(true); + //} - /// false - [Update(@"export/partial/cancel")] - public IProgressItem CancelPartialExport() - { + ///// false + //[Update(@"export/partial/cancel")] + //public IProgressItem CancelPartialExport() + //{ - ExportToCsv.Cancel(true); + // ExportToCsv.Cancel(true); - return ExportToCsv.GetStatus(true); + // return ExportToCsv.GetStatus(true); - } + //} - /// false - [Create(@"export/partial/{entityType:(contact|opportunity|case|task|invoiceitem)}/start")] - public IProgressItem StartPartialExport(string entityType, string base64FilterString) - { - if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException(); + ///// false + //[Create(@"export/partial/{entityType:(contact|opportunity|case|task|invoiceitem)}/start")] + //public IProgressItem StartPartialExport(string entityType, string base64FilterString) + //{ + // if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException(); - FilterObject filterObject; - String fileName; - - switch (entityType.ToLower()) - { - case "contact": - filterObject = new ContactFilterObject(base64FilterString); - fileName = CRMContactResource.Contacts + ".csv"; - MessageService.Send( MessageAction.ContactsExportedToCsv); - break; - case "opportunity": - filterObject = new DealFilterObject(base64FilterString); - fileName = CRMCommonResource.DealModuleName + ".csv"; - MessageService.Send( MessageAction.OpportunitiesExportedToCsv); - break; - case "case": - filterObject = new CasesFilterObject(base64FilterString); - fileName = CRMCommonResource.CasesModuleName + ".csv"; - MessageService.Send( MessageAction.CasesExportedToCsv); - break; - case "task": - filterObject = new TaskFilterObject(base64FilterString); - fileName = CRMCommonResource.TaskModuleName + ".csv"; - MessageService.Send( MessageAction.CrmTasksExportedToCsv); - break; - case "invoiceitem": - fileName = CRMCommonResource.ProductsAndServices + ".csv"; - filterObject = new InvoiceItemFilterObject(base64FilterString); - break; - default: - throw new ArgumentException(); - } - - return ExportToCsv.Start(filterObject, fileName); - } + // FilterObject filterObject; + // String fileName; + + // switch (entityType.ToLower()) + // { + // case "contact": + // filterObject = new ContactFilterObject(base64FilterString); + // fileName = CRMContactResource.Contacts + ".csv"; + // MessageService.Send( MessageAction.ContactsExportedToCsv); + // break; + // case "opportunity": + // filterObject = new DealFilterObject(base64FilterString); + // fileName = CRMCommonResource.DealModuleName + ".csv"; + // MessageService.Send( MessageAction.OpportunitiesExportedToCsv); + // break; + // case "case": + // filterObject = new CasesFilterObject(base64FilterString); + // fileName = CRMCommonResource.CasesModuleName + ".csv"; + // MessageService.Send( MessageAction.CasesExportedToCsv); + // break; + // case "task": + // filterObject = new TaskFilterObject(base64FilterString); + // fileName = CRMCommonResource.TaskModuleName + ".csv"; + // MessageService.Send( MessageAction.CrmTasksExportedToCsv); + // break; + // case "invoiceitem": + // fileName = CRMCommonResource.ProductsAndServices + ".csv"; + // filterObject = new InvoiceItemFilterObject(base64FilterString); + // break; + // default: + // throw new ArgumentException(); + // } + + // return ExportToCsv.Start(filterObject, fileName); + //} } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs index 560b9c6d467..c34ae3233ed 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs @@ -614,7 +614,7 @@ public VoipCallWrapper MakeCall(string to, string contactId) var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); - return new VoipCallWrapper(call, contact); + return VoipCallWrapperHelper.Get(call, contact); } @@ -633,7 +633,7 @@ public VoipCallWrapper AnswerCall(string callId) number.AnswerQueueCall(call.Id); - return new VoipCallWrapper(call); + return VoipCallWrapperHelper.Get(call); } @@ -650,7 +650,7 @@ public VoipCallWrapper RejectCall(string callId) var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); number.RejectQueueCall(call.Id); - return new VoipCallWrapper(call); + return VoipCallWrapperHelper.Get(call); } /// @@ -679,7 +679,7 @@ public VoipCallWrapper ReditectCall(string callId, string to) } number.RedirectCall(call.Id, to); - return new VoipCallWrapper(call); + return VoipCallWrapperHelper.Get(call); } /// @@ -743,17 +743,17 @@ public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answ call = dao.SaveOrUpdateCall(call); - if (call.ContactId == 0) return new VoipCallWrapper(call); + if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); try { var contact = GetContactByID(call.ContactId); contact = GetContactWithFotos(contact); - return new VoipCallWrapper(call, contact); + return VoipCallWrapperHelper.Get(call, contact); } catch (Exception) { - return new VoipCallWrapper(call); + return VoipCallWrapperHelper.Get(call); } } @@ -824,7 +824,7 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } - return new VoipCallWrapper(r, contact); + return VoipCallWrapperHelper.Get(r, contact); }).ToList(); @@ -862,7 +862,7 @@ public IEnumerable GetMissedCalls() contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } - return new VoipCallWrapper(r, contact); + return VoipCallWrapperHelper.Get(r, contact); }).ToList(); @@ -887,12 +887,12 @@ public VoipCallWrapper GetCall(string callId) VoipEngine.GetContact(call); - if (call.ContactId == 0) return new VoipCallWrapper(call); + if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); var contact = GetContactByID(call.ContactId); contact = GetContactWithFotos(contact); - return new VoipCallWrapper(call, contact); + return VoipCallWrapperHelper.Get(call, contact); } private ContactWrapper GetContactWithFotos(ContactWrapper contact) diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Controllers/CRMController.cs index e41543fa28b..fb3e8522ffa 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.cs @@ -7,6 +7,7 @@ using ASC.Core.Common.Settings; using ASC.Core.Notify.Signalr; using ASC.Core.Tenants; +using ASC.Core.Users; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -20,6 +21,7 @@ using ASC.Web.Api.Routing; using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Core.Search; using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Services.DocumentService; using ASC.Web.Files.Services.WCFService; @@ -45,6 +47,7 @@ public CRMController(CRMSecurity cRMSecurity, TaskWrapperHelper taskWrapperHelper, SecurityContext securityContext, UserManager userManager, + UserFormatter userFormatter, CurrencyProvider currencyProvider, Global global, SettingsManager settingsManager, @@ -85,14 +88,20 @@ public CRMController(CRMSecurity cRMSecurity, InvoiceLineWrapperHelper invoiceLineWrapperHelper, InvoiceTaxWrapperHelper invoiceTaxWrapperHelper, ContactInfoWrapperHelper contactInfoWrapperHelper, + HistoryCategoryWrapperHelper historyCategoryBaseWrapperHelper, + TaskCategoryWrapperHelper taskCategoryWrapperHelper, + VoipCallWrapperHelper voipCallWrapperHelper, RelationshipEventWrapperHelper relationshipEventWrapperHelper, DocbuilderReportsUtility docbuilderReportsUtility, - FactoryIndexer factoryIndexerInfoWrapper, - FactoryIndexer factoryIndexerEmailWrapper, - FactoryIndexer factoryIndexerCasesWrapper, - FactoryIndexer factoryIndexerFieldsWrapper) + FactoryIndexerContactInfo factoryIndexerContactInfo, + FactoryIndexerCase factoryIndexerCase, + FactoryIndexerFieldValue factoryIndexerFieldValue, + + // ExportToCsv exportToCsv, + ImportFromCSV importFromCSV, + ImportFromCSVManager importFromCSVManager) { VoipEngine = voipEngine; @@ -112,6 +121,7 @@ public CRMController(CRMSecurity cRMSecurity, TaskWrapperHelper = taskWrapperHelper; SecurityContext = securityContext; UserManager = userManager; + UserFormatter = userFormatter; CurrencyProvider = currencyProvider; OpportunityWrapperHelper = opportunityWrapperHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -122,10 +132,9 @@ public CRMController(CRMSecurity cRMSecurity, CasesWrapperHelper = casesWrapperHelper; ServiceProvider = serviceProvider; - FactoryIndexerCasesWrapper = factoryIndexerCasesWrapper; - FactoryIndexerFieldsWrapper = factoryIndexerFieldsWrapper; - FactoryIndexerInfoWrapper = factoryIndexerInfoWrapper; - FactoryIndexerEmailWrapper = factoryIndexerEmailWrapper; + FactoryIndexerCase = factoryIndexerCase; + FactoryIndexerFieldValue = factoryIndexerFieldValue; + FactoryIndexerContactInfo = factoryIndexerContactInfo; InvoiceWrapperHelper = invoiceWrapperHelper; InvoiceItemWrapperHelper = invoiceItemWrapperHelper; @@ -152,12 +161,20 @@ public CRMController(CRMSecurity cRMSecurity, DocbuilderReportsUtility = docbuilderReportsUtility; InvoiceSetting = invoiceSetting; + ContactInfoWrapperHelper = contactInfoWrapperHelper; + HistoryCategoryWrapperHelper = historyCategoryBaseWrapperHelper; ContactWrapperHelper = contactBaseWrapperHelper; - } + VoipCallWrapperHelper = voipCallWrapperHelper; + //ExportToCsv = exportToCsv; + ImportFromCSV = importFromCSV; + ImportFromCSVManager = importFromCSVManager; + } + public ImportFromCSVManager ImportFromCSVManager { get; } + public TaskCategoryWrapperHelper TaskCategoryWrapperHelper { get; } + public HistoryCategoryWrapperHelper HistoryCategoryWrapperHelper { get; } public ContactInfoWrapperHelper ContactInfoWrapperHelper { get; } - public VoipEngine VoipEngine { get; } public SignalrServiceClient SignalrServiceClient { get; } public IVoipProvider VoipProvider { get; } @@ -166,6 +183,7 @@ public CRMController(CRMSecurity cRMSecurity, public CommonLinkUtility CommonLinkUtility { get; } public ContactPhotoManager ContactPhotoManager { get; } public ContactWrapperHelper ContactWrapperHelper { get; } + public VoipCallWrapperHelper VoipCallWrapperHelper { get; } public OrganisationLogoManager OrganisationLogoManager { get; } public InvoiceSetting InvoiceSetting { get; } public DocbuilderReportsUtility DocbuilderReportsUtility { get; } @@ -186,10 +204,9 @@ public CRMController(CRMSecurity cRMSecurity, public InvoiceBaseWrapperHelper InvoiceBaseWrapperHelper { get; } public InvoiceItemWrapperHelper InvoiceItemWrapperHelper { get; } public InvoiceWrapperHelper InvoiceWrapperHelper { get; } - public FactoryIndexer FactoryIndexerInfoWrapper { get; } - public FactoryIndexer FactoryIndexerEmailWrapper { get; } - public FactoryIndexer FactoryIndexerFieldsWrapper { get; } - public FactoryIndexer FactoryIndexerCasesWrapper { get; } + public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } + public FactoryIndexerFieldValue FactoryIndexerFieldValue { get; } + public FactoryIndexerCase FactoryIndexerCase { get; } public IServiceProvider ServiceProvider { get; } public CasesWrapperHelper CasesWrapperHelper { get; } public CurrencyRateWrapperHelper CurrencyRateWrapperHelper { get; } @@ -202,17 +219,19 @@ public CRMController(CRMSecurity cRMSecurity, public OpportunityWrapperHelper OpportunityWrapperHelper { get; } public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public CurrencyProvider CurrencyProvider { get; } + public UserFormatter UserFormatter { get; } public UserManager UserManager { get; } public SecurityContext SecurityContext { get; } public TaskWrapperHelper TaskWrapperHelper { get; } public NotifyClient NotifyClient { get; } - private readonly ApiContext ApiContext; - + private readonly ApiContext ApiContext; public MessageService MessageService { get; } public MessageTarget MessageTarget { get; } public CRMSecurity CRMSecurity { get; } public DaoFactory DaoFactory { get; } + // public ExportToCsv ExportToCsv { get; } + public ImportFromCSV ImportFromCSV { get; } private static EntityType ToEntityType(string entityTypeStr) { diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index 7b9b138276a..c167f4e0684 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -54,7 +54,7 @@ public AbstractDao( TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) { diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 61fec2034a5..cde80ce9a29 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -62,7 +62,7 @@ public CachedCasesDao(DbContextManager dbContextManager, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, IHttpContextAccessor httpContextAccessor, BundleSearch bundleSearch) : @@ -124,7 +124,7 @@ public CasesDao( FilesIntegration filesIntegration, AuthorizationManager authorizationManager, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, BundleSearch bundleSearch ) : base(dbContextManager, diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index dc556a41a97..d675afedf1e 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -66,7 +66,7 @@ public CachedContactDao( FactoryIndexerContact factoryIndexerContact, FactoryIndexerContactInfo factoryIndexerContactInfo, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, DbContextManager coreDbContext, BundleSearch bundleSearch) : base(dbContextManager, @@ -143,7 +143,7 @@ public ContactDao( FactoryIndexerContact factoryIndexerContact, FactoryIndexerContactInfo factoryIndexerContactInfo, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, DbContextManager coreDbContext, BundleSearch bundleSearch ) : diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index c559cbe8ccd..d1aad3ad4f4 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -54,7 +54,7 @@ public CachedContactInfo( SecurityContext securityContext, TenantUtil tenantUtil, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, FactoryIndexerContactInfo factoryIndexerContactInfo, IHttpContextAccessor httpContextAccessor, IServiceProvider serviceProvider @@ -120,7 +120,7 @@ public ContactInfoDao( SecurityContext securityContext, TenantUtil tenantUtil, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, FactoryIndexerContactInfo factoryIndexerContactInfo, IServiceProvider serviceProvider) : base(dbContextManager, diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 2f9b904f1d6..77ea1222794 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -44,7 +44,7 @@ public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache) : + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index 249dda12c25..ee89cae7742 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -44,7 +44,7 @@ public CurrencyRateDao( TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache) : + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index b47c875f86d..8ec5cf39277 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -54,7 +54,7 @@ public CustomFieldDao( SecurityContext securityContext, TenantUtil tenantUtil, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) : base(dbContextManager, tenantManager, diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index d9fdc76ab4f..e9d7d48b413 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -26,9 +26,11 @@ using Microsoft.Extensions.DependencyInjection; using ASC.VoipService.Dao; using System; +using ASC.Common; namespace ASC.CRM.Core.Dao { + [Scope] public class DaoFactory { public DaoFactory(IServiceProvider serviceProvider) diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index d44359a3fe2..5ce580f8018 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -62,7 +62,7 @@ public CachedDealDao(DbContextManager dbContextManager, FilesIntegration filesIntegration, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, BundleSearch bundleSearch) : base(dbContextManager, tenantManager, @@ -71,6 +71,7 @@ public CachedDealDao(DbContextManager dbContextManager, factoryIndexer, filesIntegration, logger, + ascCache, bundleSearch) { _dealCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal"); @@ -121,7 +122,7 @@ public DealDao(DbContextManager dbContextManager, FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, BundleSearch bundleSearch) : base(dbContextManager, tenantManager, diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index a200b42a154..b77e83e12ce 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -55,7 +55,7 @@ public CachedDealMilestoneDao(DbContextManager dbContextManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache) + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, @@ -122,7 +122,7 @@ public DealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache) : + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 2029462a9ac..c31883c9623 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -47,7 +47,7 @@ public FileDao(FilesIntegration filesIntegration, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache) : + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 48ad8226096..c7249f40b9d 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -62,7 +62,7 @@ public CachedInvoiceDao(DbContextManager dbContextManager, FactoryIndexerInvoice factoryIndexer, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, SettingsManager settingsManager, InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData) @@ -129,7 +129,7 @@ public InvoiceDao( SecurityContext securityContext, FactoryIndexerInvoice factoryIndexer, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, SettingsManager settingsManager, InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData) diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 7a29190bb1f..10a30ef0cbc 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -56,7 +56,7 @@ public CachedInvoiceItemDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) : base(dbContextManager, tenantManager, securityContext, @@ -110,7 +110,7 @@ public InvoiceItemDao( TenantUtil tenantUtil, CRMSecurity cRMSecurity, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index ebb31e35074..8b4c5b04557 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -52,7 +52,7 @@ public CachedInvoiceLineDao(DbContextManager dbContextManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache) + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, @@ -100,7 +100,7 @@ public InvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache) + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index fc74f2a05ff..dfdca57bd60 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -51,7 +51,7 @@ public CachedInvoiceTaxDao(DbContextManager dbContextManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) : base(dbContextManager, tenantManager, @@ -102,7 +102,7 @@ public InvoiceTaxDao( TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) : base(dbContextManager, tenantManager, diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 5697eeb8f83..ad68e724481 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -55,7 +55,7 @@ public CachedListItem( SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache) + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, @@ -124,7 +124,7 @@ public ListItemDao( TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache) + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index dae0203f7c6..f7d8e0c6468 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -69,7 +69,7 @@ public CachedRelationshipEventDao(DbContextManager dbContextManage PathProvider pathProvider, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) : base(dbContextManager, tenantManager, @@ -114,7 +114,7 @@ public RelationshipEventDao(DbContextManager dbContextManager, SetupInfo setupInfo, PathProvider pathProvider, IOptionsMonitor logger, - AscCache ascCache + ICache ascCache ) : base(dbContextManager, tenantManager, diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index aa076a220e3..a145f4cc986 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -70,7 +70,7 @@ public ReportDao(DbContextManager dbContextManager, SecurityContext securityContext, FilesIntegration filesIntegration, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, TenantUtil tenantUtil, SettingsManager settingsManager, Global global, diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index a315162c801..fd50fa720b2 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -69,7 +69,7 @@ public SearchDao(DbContextManager dbContextManager, FactoryIndexerTask tasksWrapperIndexer, FactoryIndexerInvoice invoicesWrapperIndexer, IOptionsMonitor logger, - AscCache ascCache, + ICache ascCache, WebImageSupplier webImageSupplier, BundleSearch bundleSearch ) : diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index d6052b2d68f..a1932d6e065 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -48,7 +48,7 @@ public TagDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - AscCache ascCache) : + ICache ascCache) : base(dbContextManager, tenantManager, securityContext, diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 450be306faa..bb7192fcc4e 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -26,6 +26,7 @@ using ASC.Collections; using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -58,6 +59,7 @@ public CachedTaskDao(DbContextManager dbContextManager, TenantUtil tenantUtil, FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, + ICache ascCache, IHttpContextAccessor httpContextAccessor, DbContextManager userDbContext, DbContextManager coreDbContext @@ -69,6 +71,7 @@ DbContextManager coreDbContext tenantUtil, factoryIndexer, logger, + ascCache, userDbContext, coreDbContext ) @@ -123,13 +126,15 @@ public TaskDao(DbContextManager dbContextManager, TenantUtil tenantUtil, FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, + ICache ascCache, DbContextManager userDbContext, DbContextManager coreDbContext ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + ascCache) { CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index c6cf5a10ac2..c67e9f9e410 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -24,6 +24,7 @@ */ using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; @@ -45,12 +46,14 @@ public TaskTemplateContainerDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger + IOptionsMonitor logger, + ICache cache ) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + cache) { } @@ -140,11 +143,13 @@ public class TaskTemplateDao : AbstractDao public TaskTemplateDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - IOptionsMonitor logger) + IOptionsMonitor logger, + ICache cache) : base(dbContextManager, tenantManager, securityContext, - logger) + logger, + cache) { } diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index 3b7e09d0d80..21ac37570a6 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -43,6 +43,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) ModelBuilderWrapper.From(modelBuilder, Provider) .AddDbFieldValue() .AddDbContact() + .AddDbContactInfo() .AddDbCase() .AddDbRelationshipEvent() .AddDbDeal() @@ -51,22 +52,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) - modelBuilder.Entity(entity => - { - entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); - - entity.HasIndex(e => new { e.TenantId, e.ContactId }) - .HasName("IX_Contact"); - - entity.Property(e => e.Data) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - - entity.Property(e => e.LastModifedBy) - .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); - }); modelBuilder.Entity(entity => { diff --git a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs index 1e9450d54e4..b66e90b3ce3 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs @@ -1,6 +1,10 @@ -using ASC.CRM.Core.Enums; +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; +using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using Microsoft.EntityFrameworkCore; + using Nest; using System; @@ -10,13 +14,13 @@ namespace ASC.CRM.Core.EF { + [ElasticsearchType(RelationName = "crm_contact_info")] [Table("crm_contact_info")] - public partial class DbContactInfo : IDbCrm, ISearchItem + public sealed class DbContactInfo : IDbCrm, ISearchItem { public int Id { get; set; } [Required] - [Column("data", TypeName = "text")] [Text(Analyzer = "whitespacecustom")] public string Data { get; set; } @@ -56,10 +60,43 @@ public Expression> SearchContentFields { get { - return (a) => new[] { Value }; + return (a) => new[] { Data }; } } + } + + public static class DbContactInfoExtension + { + public static ModelBuilderWrapper AddDbContactInfo(this ModelBuilderWrapper modelBuilder) + { + modelBuilder + .Add(MySqlAddDbContactInfo, Provider.MySql); + + return modelBuilder; + } + + private static void MySqlAddDbContactInfo(this ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.LastModifedOn) + .HasName("last_modifed_on"); + entity.HasIndex(e => new { e.TenantId, e.ContactId }) + .HasName("IX_Contact"); + entity.Property(e => e.Data) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + + entity.Property(e => e.LastModifedBy) + .HasCharSet("utf8") + .HasCollation("utf8_general_ci"); + }); + } } + + + + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs b/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs index 6c5eadc9bcb..3df94f761ca 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCurrencyInfo.cs @@ -4,10 +4,17 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using ASC.Core.Common.EF; +using ASC.Core.Common.EF.Model; + +using Microsoft.EntityFrameworkCore; + +using Nest; + namespace ASC.CRM.Core.EF { [Table("crm_currency_info")] - public partial class DbCurrencyInfo + public sealed class DbCurrencyInfo { [Required] [Column("resource_key", TypeName = "varchar(255)")] diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index f9b9afc4873..505569f9842 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -64,7 +64,6 @@ public String Title [DataMember(Name = "isBasic")] public bool IsBasic { get; set; } - public CurrencyInfo(string resourceKey, string abbreviation, string symbol, string cultureName, bool isConvertable, bool isBasic) { _resourceKey = resourceKey; @@ -90,6 +89,5 @@ public override string ToString() { return string.Concat(Abbreviation, "-", Title); } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index a4021f196de..d3216be0f52 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -76,8 +76,8 @@ public bool CanReview(FileEntry entry, Guid userId) public bool CanDelete(FileEntry entry, Guid userId) { return CanEdit(entry, userId); - } - + } + public bool CanEdit(FileEntry entry, Guid userId) { return @@ -117,6 +117,11 @@ public IEnumerable WhoCanRead(FileEntry entry) { throw new NotImplementedException(); } + + public bool CanCustomFilterEdit(FileEntry entry, Guid userId) + { + return CanEdit(entry, userId); + } } public class FileSecurityProvider : IFileSecurityProvider diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs index 31c9591f12e..78a06dd5b79 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs @@ -31,55 +31,52 @@ using ASC.MessagingSystem; using ASC.Web.Core; using ASC.Web.Core.Files; -using ASC.Web.Core.Utility; using ASC.Web.CRM.Configuration; -using ASC.Web.CRM.Core; using ASC.Web.Studio.Core; -using Autofac; + +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using System; +using System; +using System.Threading.Tasks; namespace ASC.Web.CRM.Classes { - public class ContactPhotoHandler : IFileUploadHandler + public class ContactPhotoHandlerMiddleware { - public ContactPhotoHandler(SetupInfo setupInfo, - CRMSecurity cRMSecurity, - FileSizeComment fileSizeComment, - WebItemSecurity webItemSecurity, - MessageTarget messageTarget, - MessageService messageService) + public ContactPhotoHandlerMiddleware(RequestDelegate next) { - SetupInfo = setupInfo; - FileSizeComment = fileSizeComment; - CRMSecurity = cRMSecurity; - WebItemSecurity = webItemSecurity; - MessageTarget = messageTarget; - MessageService = messageService; + _next = next; } - public MessageService MessageService { get; } - public DaoFactory DaoFactory { get; } - public MessageTarget MessageTarget { get; } - public WebItemSecurity WebItemSecurity { get; } - public FileSizeComment FileSizeComment { get; } - public CRMSecurity CRMSecurity { get; } - public SetupInfo SetupInfo { get; } + private readonly RequestDelegate _next; - public FileUploadResult ProcessUpload(HttpContext context) + public async Task Invoke(HttpContext context, + SetupInfo setupInfo, + CRMSecurity cRMSecurity, + FileSizeComment fileSizeComment, + WebItemSecurity webItemSecurity, + MessageTarget messageTarget, + MessageService messageService, + DaoFactory daoFactory) { - if (!WebItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) - throw CRMSecurity.CreateSecurityException(); + + if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) + throw cRMSecurity.CreateSecurityException(); + + context.Request.EnableBuffering(); + var contactId = Convert.ToInt32(context.Request["contactID"]); + Contact contact = null; + if (contactId != 0) { - contact = DaoFactory.GetContactDao().GetByID(contactId); + contact = daoFactory.GetContactDao().GetByID(contactId); - if (!CRMSecurity.CanEdit(contact)) - throw CRMSecurity.CreateSecurityException(); + if (!cRMSecurity.CanEdit(contact)) + throw cRMSecurity.CreateSecurityException(); } var fileUploadResult = new FileUploadResult(); @@ -91,10 +88,10 @@ public FileUploadResult ProcessUpload(HttpContext context) if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); - if (0 < SetupInfo.MaxImageUploadSize && SetupInfo.MaxImageUploadSize < file.ContentLength) + if (0 < setupInfo.MaxImageUploadSize && setupInfo.MaxImageUploadSize < file.ContentLength) { fileUploadResult.Success = false; - fileUploadResult.Message = FileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false).HtmlEncode(); + fileUploadResult.Message = fileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false).HtmlEncode(); return fileUploadResult; } @@ -137,7 +134,9 @@ public FileUploadResult ProcessUpload(HttpContext context) if (contact != null) { var messageAction = contact is Company ? MessageAction.CompanyUpdatedPhoto : MessageAction.PersonUpdatedPhoto; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + messageService.Send(messageAction, messageTarget.Create(contact.ID), contact.GetTitle()); + } return fileUploadResult; diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs similarity index 100% rename from products/ASC.CRM/Server/HttpHandlers/FileHandler.ashx.cs rename to products/ASC.CRM/Server/HttpHandlers/FileHandler.cs diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs index dd2e14e85e5..390f2f34858 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs @@ -33,10 +33,11 @@ using Microsoft.AspNetCore.Http; using System; using Microsoft.Extensions.DependencyInjection; +using ASC.Web.Core.Utility; namespace ASC.Web.CRM.Classes { - public class FileUploaderHandler : FileUploadHandler + public class FileUploaderHandler { public FileUploaderHandler(SetupInfo setupInfo, DaoFactory daoFactory, @@ -51,7 +52,6 @@ public FileUploaderHandler(SetupInfo setupInfo, ServiceProvider = serviceProvider; TenantExtra = tenantExtra; TenantStatisticsProvider = tenantStatisticsProvider; - } public TenantExtra TenantExtra { get; } @@ -61,7 +61,7 @@ public FileUploaderHandler(SetupInfo setupInfo, public DaoFactory DaoFactory { get; } public SetupInfo SetupInfo { get; } - public override FileUploadResult ProcessUpload(HttpContext context) + public FileUploadResult ProcessUpload(HttpContext context) { var fileUploadResult = new FileUploadResult(); diff --git a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs index 92dff9eac51..805ea7a5bd6 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs @@ -28,13 +28,15 @@ using ASC.Web.Core; using ASC.Web.Core.Utility; using ASC.Web.CRM.Configuration; + using Microsoft.AspNetCore.Http; + using System; namespace ASC.Web.CRM.Classes { - public class ImportFileHandler : IFileUploadHandler + public class ImportFileHandler { public ImportFileHandler(WebItemSecurity webItemSecurity, CRMSecurity cRMSecurity, @@ -43,7 +45,6 @@ public ImportFileHandler(WebItemSecurity webItemSecurity, CRMSecurity = cRMSecurity; WebItemSecurity = webItemSecurity; Global = global; - } public Global Global { get; } diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs index e71d0bd0fe5..c5aca4eed98 100644 --- a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs @@ -30,13 +30,15 @@ using ASC.Web.Core.Files; using ASC.Web.Core.Utility; using ASC.Web.Studio.Core; + using Microsoft.AspNetCore.Http; + using System; using System.IO; namespace ASC.Web.CRM.Classes { - public class OrganisationLogoHandler : IFileUploadHandler + public class OrganisationLogoHandler { public OrganisationLogoHandler(CRMSecurity cRMSecurity, SetupInfo setupInfo, @@ -99,70 +101,4 @@ public FileUploadResult ProcessUpload(HttpContext context) } } } -} - - - -namespace ASC.Web.Studio.Controls.FileUploader -{ - public class FileToUpload - { - public string FileName { get; private set; } - public Stream InputStream { get; private set; } - public string FileContentType { get; private set; } - public long ContentLength { get; private set; } - public bool NeedSaveToTemp { get; private set; } - - public FileToUpload(HttpContext context) - { - if (IsHtml5Upload(context)) - { - FileName = GetFileName(context); - InputStream = context.Request.InputStream; - FileContentType = GetFileContentType(context); - ContentLength = (int)context.Request.InputStream.Length; - } - else - { - var file = context.Request.Files[0]; - FileName = file.FileName; - InputStream = file.InputStream; - FileContentType = file.ContentType; - ContentLength = file.ContentLength; - } - - NeedSaveToTemp = Convert.ToBoolean(GetNeedSaveToTemp(context)); - - if (string.IsNullOrEmpty(FileContentType)) - { - FileContentType = MimeMapping.GetMimeMapping(FileName) ?? string.Empty; - } - FileName = FileName.Replace("'", "_").Replace("\"", "_"); - } - - public static bool HasFilesToUpload(HttpContext context) - { - return 0 < context.Request.Form.Files.Count || (IsHtml5Upload(context) && context.Request.Form..InputStream != null); - } - - private static string GetFileName(HttpContext context) - { - return context.Request["fileName"]; - } - - private static string GetNeedSaveToTemp(HttpContext context) - { - return context.Request["needSaveToTemp"]; - } - - private static string GetFileContentType(HttpContext context) - { - return context.Request["fileContentType"]; - } - - private static bool IsHtml5Upload(HttpContext context) - { - return "html5".Equals(context.Request["type"]); - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs deleted file mode 100644 index 3fd29cbc99c..00000000000 --- a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.ashx.cs +++ /dev/null @@ -1,391 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Core; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.CRM.Resources; -using ASC.MessagingSystem; -using ASC.Web.Core; -using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Configuration; -using ASC.Web.CRM.Core; -using ASC.Web.CRM.Services.NotifyService; -using Autofac; -using Microsoft.AspNetCore.Http; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using System.Text; -using System.Web; - -namespace ASC.Web.CRM.HttpHandlers -{ - public class WebToLeadFromHandler // : IHttpHandler - { - private HttpContext _context; - - private String GetValue(String propertyName) - { - return _context.Request.Form[propertyName]; - } - - private bool CheckPermission() - { - try - { - var webFromKey = GetValue("web_form_key"); - - if (String.IsNullOrEmpty(webFromKey)) - return false; - - var webFromKeyAsGuid = new Guid(webFromKey); - - return Global.TenantSettings.WebFormKey == webFromKeyAsGuid; - } - catch(Exception) - { - return false; - } - } - - public void ProcessRequest(HttpContext context) - { - try - { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - _context = context; - - SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); - - if (!CheckPermission()) - { - throw new Exception(CRMSettingResource.WebToLeadsForm_InvalidKeyException); - } - - var productInfo = WebItemSecurity.GetSecurityInfo(ProductEntryPoint.ID.ToString()); - if (!productInfo.Enabled) - { - throw new Exception(CRMCommonResource.CRMProductIsDisabled); - } - - Contact contact; - - var fieldCollector = new NameValueCollection(); - - var addressTemplate = new JObject(); - foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) - addressTemplate.Add(addressPartName.ToLower(), ""); - var addressTemplateStr = addressTemplate.ToString(); - - var isCompany = false; - - var isCompanyString = GetValue("is_company"); - var firstName = GetValue("firstName"); - var lastName = GetValue("lastName"); - var companyName = GetValue("companyName"); - - if (!String.IsNullOrEmpty(isCompanyString)) - { - if (!Boolean.TryParse(isCompanyString, out isCompany)) - { - throw new ArgumentException(); - } - } - else //old scheme - { - if (!String.IsNullOrEmpty(firstName)) - { - isCompany = false; - } - else if (!String.IsNullOrEmpty(companyName)) - { - isCompany = true; - } - else - { - throw new ArgumentException(); - } - } - - - if (isCompany) - { - contact = new Company(); - - ((Company) contact).CompanyName = companyName; - - fieldCollector.Add(CRMContactResource.CompanyName, companyName); - } - else - { - contact = new Person(); - - ((Person) contact).FirstName = firstName; - ((Person) contact).LastName = lastName; - ((Person) contact).JobTitle = GetValue("jobTitle"); - - fieldCollector.Add(CRMContactResource.FirstName, firstName); - fieldCollector.Add(CRMContactResource.LastName, lastName); - - if (!String.IsNullOrEmpty(GetValue("jobTitle"))) - fieldCollector.Add(CRMContactResource.JobTitle, ((Person) contact).JobTitle); - } - - contact.About = GetValue("about"); - - if (!String.IsNullOrEmpty(contact.About)) - fieldCollector.Add(CRMContactResource.About, contact.About); - - if (!String.IsNullOrEmpty(GetValue("is_shared"))) - { - contact.ShareType = Convert.ToBoolean(GetValue("is_shared")) - ? ShareType.ReadWrite - : ShareType.None; - } - else - { - contact.ShareType = (ShareType) (Convert.ToInt32(GetValue("share_type"))); - } - - contact.ID = daoFactory.ContactDao.SaveContact(contact); - - var messageAction = contact is Company - ? MessageAction.CompanyCreatedWithWebForm - : MessageAction.PersonCreatedWithWebForm; - MessageService.Send(HttpContext.Current.Request, MessageInitiator.System, messageAction, - MessageTarget.Create(contact.ID), contact.GetTitle()); - - var contactInfos = new List(); - - foreach (var key in _context.Request.Form.AllKeys) - { - if (key.StartsWith("customField_")) - { - var fieldID = Convert.ToInt32(key.Split(new[] {'_'})[1]); - String fieldValue = GetValue(key); - - if (String.IsNullOrEmpty(fieldValue)) continue; - - var customField = daoFactory.CustomFieldDao.GetFieldDescription(fieldID); - - if (customField == null || - !(customField.EntityType == EntityType.Contact || - customField.EntityType == EntityType.Company && isCompany || - customField.EntityType == EntityType.Person && !isCompany)) continue; - - if (customField.FieldType == CustomFieldType.CheckBox) - { - fieldValue = fieldValue == "on" || fieldValue == "true" ? "true" : "false"; - } - fieldCollector.Add(customField.Label, fieldValue); - - daoFactory.CustomFieldDao.SetFieldValue(isCompany ? EntityType.Company : EntityType.Person, contact.ID, fieldID, fieldValue); - } - else if (key.StartsWith("contactInfo_")) - { - var nameParts = key.Split(new[] {'_'}).Skip(1).ToList(); - var contactInfoType = (ContactInfoType) Enum.Parse(typeof(ContactInfoType), nameParts[0]); - var category = Convert.ToInt32(nameParts[1]); - - bool categoryIsExists = Enum.GetValues(ContactInfo.GetCategory(contactInfoType)) - .Cast() - .Any(categoryEnum => (int) categoryEnum == category); - if (!categoryIsExists) - throw new ArgumentException(String.Format("Category for {0} not found", nameParts[0])); - - if (contactInfoType == ContactInfoType.Address) - { - var addressPart = (AddressPart) Enum.Parse(typeof(AddressPart), nameParts[2]); - - var findedAddress = - contactInfos.Find( - item => - (category == item.Category) && (item.InfoType == ContactInfoType.Address)); - - if (findedAddress == null) - { - findedAddress = new ContactInfo - { - Category = category, - InfoType = contactInfoType, - Data = addressTemplateStr, - ContactID = contact.ID - }; - - contactInfos.Add(findedAddress); - } - - var addressParts = JObject.Parse(findedAddress.Data); - - addressParts[addressPart.ToString().ToLower()] = GetValue(key); - - findedAddress.Data = addressParts.ToString(); - - continue; - } - - var fieldValue = GetValue(key); - - if (String.IsNullOrEmpty(fieldValue)) continue; - - contactInfos.Add(new ContactInfo - { - Category = category, - InfoType = contactInfoType, - Data = fieldValue, - ContactID = contact.ID, - IsPrimary = true - }); - } - else if (String.Compare(key, "tag", true) == 0) - { - var tags = _context.Request.Form.GetValues("tag"); - - daoFactory.TagDao.SetTagToEntity(EntityType.Contact, contact.ID, tags); - } - } - - contactInfos.ForEach( - item => - fieldCollector[item.InfoType.ToLocalizedString()] = - PrepareteDataToView(item.InfoType, item.Data)); - - daoFactory.ContactInfoDao.SaveList(contactInfos, contact); - - var notifyList = GetValue("notify_list"); - - if (!String.IsNullOrEmpty(notifyList)) - NotifyClient.Instance.SendAboutCreateNewContact( - notifyList - .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) - .Select(item => new Guid(item)).ToList(), contact.ID, contact.GetTitle(), fieldCollector); - - var managersList = GetValue("managers_list"); - SetPermission(contact, managersList); - - if (contact is Person && !String.IsNullOrEmpty(companyName)) - AssignPersonToCompany((Person)contact, companyName, managersList, daoFactory); - - if (contact is Company && !String.IsNullOrEmpty(firstName) && !String.IsNullOrEmpty(lastName)) - AssignCompanyToPerson((Company)contact, firstName, lastName, managersList, daoFactory); - - SecurityContext.Logout(); - - var newURL = new UriBuilder(GetValue("return_url")).Uri.AbsoluteUri; - context.Response.Buffer = true; - context.Response.Status = "302 Object moved"; - context.Response.AddHeader("Location", newURL); - context.Response.Write(""); - context.Response.Write(String.Format("", newURL)); - context.Response.Write(String.Format("", newURL)); - context.Response.Write(""); - context.Response.Write(""); - } - } - catch(Exception error) - { - LogManager.GetLogger("ASC.CRM").Error(error); - context.Response.StatusCode = 400; - context.Response.Write(HttpUtility.HtmlEncode(error.Message)); - } - } - - private String PrepareteDataToView(ContactInfoType contactInfoType, String data) - { - if (contactInfoType != ContactInfoType.Address) return data; - - var addressParts = JObject.Parse(data); - - var address = new StringBuilder(); - - foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) - address.Append(addressParts[addressPartEnum.ToString().ToLower()] + " "); - - return address.ToString(); - } - - public bool IsReusable - { - get { return false; } - } - - protected void SetPermission(Contact contact, String privateList) - { - if (String.IsNullOrEmpty(privateList)) return; - - var selectedUsers = privateList - .Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries) - .Select(item => new Guid(item)).ToList(); - - CRMSecurity.SetAccessTo(contact, selectedUsers); - } - - protected void AssignCompanyToPerson(Company company, String firstName, String lastName, String privateList, DaoFactory daoFactory) - { - var person = new Person - { - FirstName = firstName, - LastName = lastName, - CompanyID = company.ID - }; - person.ID = daoFactory.ContactDao.SaveContact(person); - SetPermission(person, privateList); - } - - - protected void AssignPersonToCompany(Person person, String companyName, String privateList, DaoFactory daoFactory) - { - Company company; - - var findedCompanies = daoFactory.ContactDao.GetContactsByName(companyName, true).ToList(); - - if (findedCompanies.Count == 0) - { - company = new Company - { - CompanyName = companyName - }; - - company.ID = daoFactory.ContactDao.SaveContact(company); - - SetPermission(company, privateList); - } - else - { - company = (Company)findedCompanies[0]; - } - - daoFactory.ContactDao.AddMember(person.ID, company.ID); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/filehandler.ashx b/products/ASC.CRM/Server/HttpHandlers/filehandler.ashx deleted file mode 100644 index a98987a3f2a..00000000000 --- a/products/ASC.CRM/Server/HttpHandlers/filehandler.ashx +++ /dev/null @@ -1,4 +0,0 @@ -<%@ Assembly Name="ASC.Web.CRM" %> -<%@ Assembly Name="ASC.Web.Studio" %> -<%@ Assembly Name="ASC.Web.Core" %> -<%@ WebHandler Language="C#" CodeBehind="FileHandler.ashx.cs" Class="ASC.Web.CRM.HttpHandlers.FileHandler, ASC.Web.CRM" %> diff --git a/products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx b/products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx deleted file mode 100644 index bbfb15ae1c9..00000000000 --- a/products/ASC.CRM/Server/HttpHandlers/webtoleadfromhandler.ashx +++ /dev/null @@ -1,4 +0,0 @@ -<%@ Assembly Name="ASC.Web.CRM" %> -<%@ Assembly Name="ASC.Web.Studio" %> -<%@ Assembly Name="ASC.Web.Core" %> -<%@ WebHandler Language="C#" CodeBehind="WebToLeadFromHandler.ashx.cs" Class="ASC.Web.CRM.HttpHandlers.WebToLeadFromHandler, ASC.Web.CRM" %> diff --git a/products/ASC.CRM/Server/Model/CasesWrapper.cs b/products/ASC.CRM/Server/Model/CasesWrapper.cs index 608cb3d28f6..30c7091e329 100644 --- a/products/ASC.CRM/Server/Model/CasesWrapper.cs +++ b/products/ASC.CRM/Server/Model/CasesWrapper.cs @@ -91,7 +91,7 @@ public static CasesWrapper GetSample() } } - [Transient] + [Scope] public class CasesWrapperHelper { public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, diff --git a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs index ed6f3824d5a..5914e8cf456 100644 --- a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs +++ b/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs @@ -165,7 +165,7 @@ public static ContactInfoWrapper GetSample() } } - [Transient] + [Scope] public class ContactInfoWrapperHelper { public ContactInfoWrapperHelper() diff --git a/products/ASC.CRM/Server/Model/ContactWrapper.cs b/products/ASC.CRM/Server/Model/ContactWrapper.cs index 45f670f07c8..70effeb4bca 100644 --- a/products/ASC.CRM/Server/Model/ContactWrapper.cs +++ b/products/ASC.CRM/Server/Model/ContactWrapper.cs @@ -85,7 +85,7 @@ public PersonWrapper() } } - [Transient] + [Scope] public class PersonWrapperHelper { public PersonWrapperHelper() @@ -111,8 +111,6 @@ public PersonWrapper GetQuick(Person person) Title = person.JobTitle }; } - - } /// @@ -363,7 +361,7 @@ public class ContactWithTaskWrapper public ContactWrapper Contact { get; set; } } - [Transient] + [Scope] public class ContactWrapperHelper { public ContactWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, diff --git a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs index dffed5a5998..a5fe23ffe3d 100644 --- a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs +++ b/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs @@ -75,7 +75,7 @@ public static CurrencyInfoWrapper GetSample() } } - [Transient] + [Singletone] public class CurrencyInfoWrapperHelper { public CurrencyInfoWrapperHelper() @@ -83,7 +83,6 @@ public CurrencyInfoWrapperHelper() } - public CurrencyInfoWrapper Get(CurrencyInfo currencyInfo) { if (currencyInfo == null) return null; @@ -120,7 +119,7 @@ public CurrencyRateInfoWrapper() public decimal Rate { get; set; } } - [Transient] + [Scope] public class CurrencyRateInfoWrapperHelper { public CurrencyRateInfoWrapperHelper(CurrencyInfoWrapperHelper currencyInfoWrapperHelper) diff --git a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs index 5e4d8ab614d..60a8d0b1e60 100644 --- a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs +++ b/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs @@ -67,7 +67,7 @@ public static CurrencyRateWrapper GetSample() } } - [Transient] + [Scope] public class CurrencyRateWrapperHelper { public CurrencyRateWrapperHelper() diff --git a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs index a87e7fb0695..bbc09c26b2e 100644 --- a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs +++ b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs @@ -116,7 +116,7 @@ public InvoiceBaseWrapper() public bool CanDelete { get; set; } } - [Transient] + [Scope] public class InvoiceBaseWrapperHelper { public InvoiceBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -240,7 +240,7 @@ public static InvoiceWrapper GetSample() } } - [Transient] + [Scope] public class InvoiceWrapperHelper { public InvoiceWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -495,7 +495,7 @@ public InvoiceTaxWrapper() public bool CanDelete { get; set; } } - [Transient] + [Scope] public class InvoiceTaxWrapperHelper { public InvoiceTaxWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -584,7 +584,7 @@ public static InvoiceLineWrapper GetSample() } } - [Transient] + [Singletone] public class InvoiceLineWrapperHelper { public InvoiceLineWrapperHelper() @@ -637,7 +637,7 @@ public static InvoiceStatusWrapper GetSample() } - [Transient] + [Singletone] public class InvoiceStatusWrapperHelper { public InvoiceStatusWrapperHelper() @@ -653,5 +653,4 @@ public InvoiceStatusWrapper Get(InvoiceStatus status) }; } } - } diff --git a/products/ASC.CRM/Server/Model/ListItemWrapper.cs b/products/ASC.CRM/Server/Model/ListItemWrapper.cs index 4f4d0ec13d4..bedd93300be 100644 --- a/products/ASC.CRM/Server/Model/ListItemWrapper.cs +++ b/products/ASC.CRM/Server/Model/ListItemWrapper.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.Core.Utility.Skins; @@ -47,8 +48,6 @@ public HistoryCategoryBaseWrapper() public HistoryCategoryBaseWrapper(ListItem listItem) : base(listItem) { - if (!String.IsNullOrEmpty(listItem.AdditionalParams)) - ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID); } [DataMember(Name = "id")] @@ -99,6 +98,25 @@ public HistoryCategoryWrapper(ListItem listItem) } } + [Scope] + public sealed class HistoryCategoryWrapperHelper + { + public HistoryCategoryWrapperHelper(WebImageSupplier webImageSupplier) + { + WebImageSupplier = webImageSupplier; + } + + public WebImageSupplier WebImageSupplier { get; } + + public HistoryCategoryBaseWrapper Get(ListItem listItem) + { + return new HistoryCategoryBaseWrapper(listItem) + { + ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) + }; + } + } + #endregion #region Deal Milestone @@ -180,10 +198,9 @@ public TaskCategoryBaseWrapper() { } - public TaskCategoryBaseWrapper(ListItem listItem) - : base(listItem) + public TaskCategoryBaseWrapper(ListItem listItem) : base(listItem) { - ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID); + } [DataMember(IsRequired = false, EmitDefaultValue = false)] @@ -208,11 +225,11 @@ public TaskCategoryWrapper() { } - public TaskCategoryWrapper(ListItem listItem) - : base(listItem) + public TaskCategoryWrapper(ListItem listItem): base(listItem) { } + [DataMember(IsRequired = false, EmitDefaultValue = false)] public int RelativeItemsCount { get; set; } @@ -230,6 +247,32 @@ public TaskCategoryWrapper(ListItem listItem) } } + + [Scope] + public sealed class TaskCategoryWrapperHelper + { + public TaskCategoryWrapperHelper(WebImageSupplier webImageSupplier) + { + WebImageSupplier = webImageSupplier; + } + + public WebImageSupplier WebImageSupplier { get; } + + public TaskCategoryBaseWrapper Get(ListItem listItem) + { + return new TaskCategoryBaseWrapper(listItem) + { + ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) + }; + } + } + + + + + + + #endregion #region Contact Status diff --git a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs index 9634ab27fe6..702fbbd9529 100644 --- a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs +++ b/products/ASC.CRM/Server/Model/OpportunityWrapper.cs @@ -131,7 +131,7 @@ public static OpportunityWrapper GetSample() } - [Transient] + [Scope] public class OpportunityWrapperHelper { public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, @@ -139,7 +139,8 @@ public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, CurrencyProvider currencyProvider, - ContactWrapperHelper contactBaseWrapperHelper + ContactWrapperHelper contactBaseWrapperHelper, + CurrencyInfoWrapperHelper currencyInfoWrapperHelper ) { ApiDateTimeHelper = apiDateTimeHelper; @@ -148,8 +149,10 @@ ContactWrapperHelper contactBaseWrapperHelper DaoFactory = daoFactory; ContactBaseWrapperHelper = contactBaseWrapperHelper; CurrencyProvider = currencyProvider; + CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; } + public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } public CurrencyProvider CurrencyProvider {get;} public ContactWrapperHelper ContactBaseWrapperHelper { get; } public DaoFactory DaoFactory { get; } @@ -191,14 +194,14 @@ public OpportunityWrapper Get(Deal deal) } dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal) - .Select(item => EmployeeWraperHelper.Get(item.Key)).ToItemList(); + .Select(item => EmployeeWraperHelper.Get(item.Key)); dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); if (!string.IsNullOrEmpty(deal.BidCurrency)) - dealWrapper.BidCurrency = ToCurrencyInfoWrapper(CurrencyProvider.Get(deal.BidCurrency)); + dealWrapper.BidCurrency = CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); - dealWrapper.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList(); + dealWrapper.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseWrapper(item)); dealWrapper.Members = new List(); diff --git a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs index 684fde57372..a07f3243041 100644 --- a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs +++ b/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs @@ -61,7 +61,7 @@ public static EntityWrapper GetSample() } } - [Transient] + [Scope] public class EntityWrapperHelper { public EntityWrapperHelper(DaoFactory daoFactory) @@ -159,7 +159,7 @@ public static RelationshipEventWrapper GetSample() } } - [Transient] + [Scope] public class RelationshipEventWrapperHelper { public RelationshipEventWrapperHelper( @@ -169,7 +169,8 @@ public RelationshipEventWrapperHelper( FileWrapperHelper fileWrapperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, - EntityWrapperHelper entityWrapperHelper) + EntityWrapperHelper entityWrapperHelper, + HistoryCategoryWrapperHelper historyCategoryWrapperHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -178,8 +179,10 @@ public RelationshipEventWrapperHelper( ContactBaseWrapperHelper = contactBaseWrapperHelper; FileWrapperHelper = fileWrapperHelper; EntityWrapperHelper = entityWrapperHelper; + HistoryCategoryWrapperHelper = historyCategoryWrapperHelper; } + public HistoryCategoryWrapperHelper HistoryCategoryWrapperHelper { get; } public FileWrapperHelper FileWrapperHelper { get; } public ContactWrapperHelper ContactBaseWrapperHelper { get; } public DaoFactory DaoFactory { get; } @@ -204,7 +207,7 @@ public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) if (historyCategory != null) { - result.Category = new HistoryCategoryBaseWrapper(historyCategory); + result.Category = HistoryCategoryWrapperHelper.Get(historyCategory); } if (relationshipEvent.EntityID > 0) diff --git a/products/ASC.CRM/Server/Model/TaskWrapper.cs b/products/ASC.CRM/Server/Model/TaskWrapper.cs index 4cd900857c1..4100c1a0540 100644 --- a/products/ASC.CRM/Server/Model/TaskWrapper.cs +++ b/products/ASC.CRM/Server/Model/TaskWrapper.cs @@ -152,10 +152,9 @@ public static TaskBaseWrapper GetSample() } } - [Transient] + [Scope] public class TaskWrapperHelper { - public TaskWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, diff --git a/products/ASC.CRM/Server/Model/VoipCallWrapper.cs b/products/ASC.CRM/Server/Model/VoipCallWrapper.cs index e260ef9cfe8..b3828cd4bf0 100644 --- a/products/ASC.CRM/Server/Model/VoipCallWrapper.cs +++ b/products/ASC.CRM/Server/Model/VoipCallWrapper.cs @@ -25,6 +25,7 @@ using ASC.Api.Core; +using ASC.Common; using ASC.VoipService; using ASC.Web.Api.Models; using System.Collections.Generic; @@ -72,24 +73,44 @@ public class VoipCallWrapper [DataMember(Order = 14)] public int RecordDuration { get; set; } - public VoipCallWrapper(VoipCall call, ContactWrapper contact = null) + } + + [Scope] + public class VoipCallWrapperHelper + { + public VoipCallWrapperHelper(EmployeeWraperHelper employeeWraper, + ApiDateTimeHelper apiDateTimeHelper) { - Id = call.Id; - From = call.From; - To = call.To; - Status = call.Status; - AnsweredBy = EmployeeWraper.Get(call.AnsweredBy); - DialDate = new ApiDateTime(call.DialDate); - DialDuration = call.DialDuration; - Cost = call.Price + call.ChildCalls.Sum(r=> r.Price) + call.VoipRecord.Price; - Contact = contact; - RecordUrl = call.VoipRecord.Uri; - RecordDuration = call.VoipRecord.Duration; + EmployeeWraperHelper = employeeWraper; + ApiDateTimeHelper = apiDateTimeHelper; + } + + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + + public VoipCallWrapper Get(VoipCall call, ContactWrapper contact = null) + { + var result = new VoipCallWrapper + { + Id = call.Id, + From = call.From, + To = call.To, + Status = call.Status, + AnsweredBy = EmployeeWraperHelper.Get(call.AnsweredBy), + DialDate = ApiDateTimeHelper.Get(call.DialDate), + DialDuration = call.DialDuration, + Cost = call.Price + call.ChildCalls.Sum(r => r.Price) + call.VoipRecord.Price, + Contact = contact, + RecordUrl = call.VoipRecord.Uri, + RecordDuration = call.VoipRecord.Duration + }; if (call.ChildCalls.Any()) { - Calls = call.ChildCalls.Select(childCall => new VoipCallWrapper(childCall)); + result.Calls = call.ChildCalls.Select(childCall => Get(childCall)); } + + return result; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index d997536425e..ba846ec0548 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -49,6 +49,7 @@ namespace ASC.Web.CRM.Services.NotifyService { + [Scope] public class NotifyClient { public NotifyClient(IServiceProvider serviceProvider) @@ -535,16 +536,4 @@ public void SendAboutResponsibleForOpportunity(Deal deal) ); } } - - - public static class NotifyClientExtention - { - public static DIHelper AddNotifyClientService(this DIHelper services) - { - services.TryAddScoped(); - - return services; - - } - } } diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index a9d10a93de0..b02077b40d0 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -347,15 +347,4 @@ private void DownloadCurrencyPage(string currency, string filepath) } } - - public static class CurrencyProviderExtention - { - public static DIHelper AddCurrencyProviderService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddSettingsManagerService(); - // .AddDaoFactoryService(); - } - } } diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index f3eb683e9b8..2caf3c8cbbe 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -1,1446 +1,1477 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common.Caching; -using ASC.Common.Logging; -using ASC.Common.Security.Authentication; -using ASC.Common.Threading.Progress; -using ASC.Core; -using ASC.Core.Users; -using ASC.CRM.Classes; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.CRM.Resources; -using ASC.Data.Storage; -using ASC.Web.Core.Files; -using ASC.Web.Core.Users; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Web.Files.Utils; -using ASC.Web.Studio.Utility; - -using ICSharpCode.SharpZipLib.Zip; - -using Microsoft.Extensions.Options; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Data; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; - -namespace ASC.Web.CRM.Classes -{ - public class ExportDataCache - { - public ExportDataCache(AscCache ascCache) - { - Cache = ascCache; - } - - public readonly ICache Cache; - - public String GetStateCacheKey(string key) - { - return String.Format("{0}:crm:queue:exporttocsv", key); - } - - public String GetCancelCacheKey(string key) - { - return String.Format("{0}:crm:queue:exporttocsv:cancel", key); - } - - public ExportDataOperation Get(string key) - { - return Cache.Get(GetStateCacheKey(key)); - } - - public void Insert(string key, ExportDataOperation data) - { - Cache.Insert(GetStateCacheKey(key), data, TimeSpan.FromMinutes(1)); - } - - public bool CheckCancelFlag(string key) - { - var fromCache = Cache.Get(GetCancelCacheKey(key)); - - return !String.IsNullOrEmpty(fromCache); - } - - public void SetCancelFlag(string key) - { - Cache.Insert(GetCancelCacheKey(key), "true", TimeSpan.FromMinutes(1)); - } - - public void ResetAll(string key) - { - Cache.Remove(GetStateCacheKey(key)); - Cache.Remove(GetCancelCacheKey(key)); - } - } - - public class ExportDataOperation : IProgressItem - { - public ExportDataOperation(UserManager userManager, - FileUtility fileUtility, - SecurityContext securityContext, - IOptionsMonitor logger, - TenantManager tenantManager, - Global global, - ExportDataCache exportDataCache, - CommonLinkUtility commonLinkUtility, - DisplayUserSettings displayUserSettings, - NotifyClient notifyClient, - DaoFactory daoFactory) - { - DaoFactory = daoFactory; - UserManager = userManager; - FileUtility = fileUtility; - - _tenantId = tenantManager.GetCurrentTenant().TenantId; - - _author = securityContext.CurrentAccount; - _dataStore = global.GetStore(); - _notifyClient = notifyClient; - _filterObject = filterObject; - - _log = logger.Get("ASC.CRM"); - - Id = ExportToCsv.GetKey(filterObject != null); - Status = ProgressStatus.Queued; - Error = null; - Percentage = 0; - IsCompleted = false; - FileName = fileName ?? CRMSettingResource.Export + (filterObject == null ? ".zip" : ".csv"); - FileUrl = null; - - ExportDataCache = exportDataCache; - SecurityContext = securityContext; - - CommonLinkUtility = commonLinkUtility; - } - - - public TenantManager TenantManager { get; } - public CommonLinkUtility CommonLinkUtility { get; } - public SecurityContext SecurityContext { get; } - public DaoFactory DaoFactory { get; } - public ExportDataCache ExportDataCache { get; } - public UserManager UserManager { get; } - public FileUtility FileUtility { get; } - - private readonly int _tenantId; - - private readonly IAccount _author; - - private readonly IDataStore _dataStore; - - private readonly NotifyClient _notifyClient; - - private readonly FilterObject _filterObject; - - private readonly ILog _log; - - private int _totalCount; - - public override bool Equals(object obj) - { - if (obj == null) return false; - - var exportDataOperation = obj as ExportDataOperation; - - if (exportDataOperation == null) return false; +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//using ASC.Common; +//using ASC.Common.Caching; +//using ASC.Common.Logging; +//using ASC.Common.Security.Authentication; +//using ASC.Common.Threading.Progress; +//using ASC.Core; +//using ASC.Core.Users; +//using ASC.CRM.Classes; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Dao; +//using ASC.CRM.Core.Entities; +//using ASC.CRM.Core.Enums; +//using ASC.CRM.Resources; +//using ASC.Data.Storage; +//using ASC.Files.Core; +//using ASC.Web.Core.Files; +//using ASC.Web.Core.Users; +//using ASC.Web.CRM.Services.NotifyService; +//using ASC.Web.Files.Classes; +//using ASC.Web.Files.Utils; +//using ASC.Web.Studio.Utility; + +//using ICSharpCode.SharpZipLib.Zip; + +//using Microsoft.Extensions.Options; +//using Newtonsoft.Json.Linq; +//using System; +//using System.Collections.Generic; +//using System.Collections.Specialized; +//using System.Data; +//using System.Globalization; +//using System.IO; +//using System.Linq; +//using System.Text; + +//namespace ASC.Web.CRM.Classes +//{ +// [Singletone] +// public class ExportDataCache +// { +// public ExportDataCache(ICache ascCache) +// { +// Cache = ascCache; +// } + +// public readonly ICache Cache; + +// public String GetStateCacheKey(string key) +// { +// return String.Format("{0}:crm:queue:exporttocsv", key); +// } + +// public String GetCancelCacheKey(string key) +// { +// return String.Format("{0}:crm:queue:exporttocsv:cancel", key); +// } + +// public ExportDataOperation Get(string key) +// { +// return Cache.Get(GetStateCacheKey(key)); +// } + +// public void Insert(string key, ExportDataOperation data) +// { +// Cache.Insert(GetStateCacheKey(key), data, TimeSpan.FromMinutes(1)); +// } + +// public bool CheckCancelFlag(string key) +// { +// var fromCache = Cache.Get(GetCancelCacheKey(key)); + +// return !String.IsNullOrEmpty(fromCache); +// } + +// public void SetCancelFlag(string key) +// { +// Cache.Insert(GetCancelCacheKey(key), "true", TimeSpan.FromMinutes(1)); +// } + +// public void ResetAll(string key) +// { +// Cache.Remove(GetStateCacheKey(key)); +// Cache.Remove(GetCancelCacheKey(key)); +// } +// } + +// public class ExportDataOperation : IProgressItem +// { +// public ExportDataOperation(UserManager userManager, +// FileUtility fileUtility, +// SecurityContext securityContext, +// IOptionsMonitor logger, +// TenantManager tenantManager, +// Global global, +// ExportDataCache exportDataCache, +// CommonLinkUtility commonLinkUtility, +// DisplayUserSettings displayUserSettings, +// NotifyClient notifyClient, +// DaoFactory daoFactory, +// FileUploader fileUploader, +// GlobalFolder globalFolder, +// FileMarker fileMarker, +// IDaoFactory fileDaoFactory, +// FilesLinkUtility filesLinkUtility, +// DisplayUserSettingsHelper displayUserSettingsHelper) +// { +// DaoFactory = daoFactory; +// UserManager = userManager; +// FileUtility = fileUtility; +// FileUploader = fileUploader; + +// _tenantId = tenantManager.GetCurrentTenant().TenantId; + +// _author = securityContext.CurrentAccount; +// _dataStore = global.GetStore(); +// _notifyClient = notifyClient; +// _filterObject = filterObject; + +// _log = logger.Get("ASC.CRM"); + +// Id = ExportToCsv.GetKey(filterObject != null); +// Status = ProgressStatus.Queued; +// Error = null; +// Percentage = 0; +// IsCompleted = false; +// FileName = fileName ?? CRMSettingResource.Export + (filterObject == null ? ".zip" : ".csv"); +// FileUrl = null; + +// ExportDataCache = exportDataCache; +// SecurityContext = securityContext; + +// CommonLinkUtility = commonLinkUtility; +// GlobalFolder = globalFolder; +// FileMarker = fileMarker; +// FileDaoFactory = fileDaoFactory; +// FilesLinkUtility = filesLinkUtility; +// DisplayUserSettingsHelper = displayUserSettingsHelper; +// } + +// public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } +// public FilesLinkUtility FilesLinkUtility { get; } +// public FileMarker FileMarker { get; } +// public IDaoFactory FileDaoFactory { get; } +// public GlobalFolder GlobalFolder { get; } +// public FileUploader FileUploader { get; } +// public TenantManager TenantManager { get; } +// public CommonLinkUtility CommonLinkUtility { get; } +// public SecurityContext SecurityContext { get; } +// public DaoFactory DaoFactory { get; } +// public ExportDataCache ExportDataCache { get; } +// public UserManager UserManager { get; } +// public FileUtility FileUtility { get; } + +// private readonly int _tenantId; + +// private readonly IAccount _author; + +// private readonly IDataStore _dataStore; + +// private readonly NotifyClient _notifyClient; + +// private readonly FilterObject _filterObject; + +// private readonly ILog _log; + +// private int _totalCount; + +// public override bool Equals(object obj) +// { +// if (obj == null) return false; + +// var exportDataOperation = obj as ExportDataOperation; + +// if (exportDataOperation == null) return false; - return Id == exportDataOperation.Id; - } +// return Id == exportDataOperation.Id; +// } - public override int GetHashCode() - { - return Id.GetHashCode(); - } +// public override int GetHashCode() +// { +// return Id.GetHashCode(); +// } - public object Clone() - { - var cloneObj = new ExportDataOperation - { - Id = Id, - Status = Status, - Error = Error, - Percentage = Percentage, - IsCompleted = IsCompleted, - FileName = FileName, - FileUrl = FileUrl - }; +// public object Clone() +// { +// var cloneObj = new ExportDataOperation +// { +// Id = Id, +// Status = Status, +// Error = Error, +// Percentage = Percentage, +// IsCompleted = IsCompleted, +// FileName = FileName, +// FileUrl = FileUrl +// }; - return cloneObj; - } +// return cloneObj; +// } - public object Id { get; set; } +// public object Id { get; set; } - public object Status { get; set; } - - public object Error { get; set; } +// public object Status { get; set; } + +// public object Error { get; set; } - public double Percentage { get; set; } +// public double Percentage { get; set; } - public bool IsCompleted { get; set; } +// public bool IsCompleted { get; set; } - public string FileName { get; set; } - - public string FileUrl { get; set; } - - private String WrapDoubleQuote(String value) - { - return "\"" + value.Trim().Replace("\"", "\"\"") + "\""; - } - - private String DataTableToCsv(DataTable dataTable) - { - var result = new StringBuilder(); - - var columnsCount = dataTable.Columns.Count; - - for (var index = 0; index < columnsCount; index++) - { - if (index != columnsCount - 1) - result.Append(dataTable.Columns[index].Caption + ","); - else - result.Append(dataTable.Columns[index].Caption); - } - - result.Append(Environment.NewLine); - - foreach (DataRow row in dataTable.Rows) - { - for (var i = 0; i < columnsCount; i++) - { - var itemValue = WrapDoubleQuote(row[i].ToString()); - - if (i != columnsCount - 1) - result.Append(itemValue + ","); - else - result.Append(itemValue); - } - - result.Append(Environment.NewLine); - } - - return result.ToString(); - } - - public void RunJob() - { - try - { - Status = ProgressStatus.Started; - - TenantManager.SetCurrentTenant(_tenantId); - SecurityContext.AuthenticateMe(_author); - - var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); - - System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; - System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; - - _log.Debug("Start Export Data"); - - ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); - - if (_filterObject == null) - ExportAllData(daoFactory); - else - ExportPartData(daoFactory); - - Complete(100, ProgressStatus.Done, null); - - _log.Debug("Export is completed"); - } - catch (OperationCanceledException) - { - Complete(0, ProgressStatus.Done, null); - - _log.Debug("Export is cancel"); - } - catch (Exception ex) - { - Complete(0, ProgressStatus.Failed, ex.Message); - - _log.Error(ex); - } - finally - { - ExportDataCache.ResetAll((string)Id); - } - } - - private void Complete(double percentage, ProgressStatus status, object error) - { - IsCompleted = true; - Percentage = percentage; - Status = status; - Error = error; - - ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); - } - - private void ExportAllData(DaoFactory daoFactory) - { - using (var stream = TempStream.Create()) - { - var contactDao = daoFactory.GetContactDao(); - var contactInfoDao = daoFactory.GetContactInfoDao(); - var dealDao = daoFactory.GetDealDao(); - var casesDao = daoFactory.GetCasesDao(); - var taskDao = daoFactory.GetTaskDao(); - var historyDao = daoFactory.GetRelationshipEventDao(); - var invoiceItemDao = daoFactory.GetInvoiceItemDao(); - - _totalCount += contactDao.GetAllContactsCount(); - _totalCount += dealDao.GetDealsCount(); - _totalCount += casesDao.GetCasesCount(); - _totalCount += taskDao.GetAllTasksCount(); - _totalCount += historyDao.GetAllItemsCount(); - _totalCount += invoiceItemDao.GetInvoiceItemsCount(); - - using (var zipStream = new ZipOutputStream(stream)) - { - zipStream.AlternateEncoding = Encoding.UTF8; - zipStream.AlternateEncodingUsage = ZipOption.Always; - - zipStream.PutNextEntry(CRMContactResource.Contacts + ".csv"); - var contactData = contactDao.GetAllContacts(); - var contactInfos = new StringDictionary(); - contactInfoDao.GetAll() - .ForEach(item => - { - var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, (int)item.InfoType, item.Category); - if (contactInfos.ContainsKey(contactInfoKey)) - { - contactInfos[contactInfoKey] += "," + item.Data; - } - else - { - contactInfos.Add(contactInfoKey, item.Data); - } - }); - - using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportContactsToCsv(contactData, contactInfos, daoFactory)))) - { - zipEntryData.StreamCopyTo(zipStream); - } - - zipStream.PutNextEntry(CRMCommonResource.DealModuleName + ".csv"); - var dealData = dealDao.GetAllDeals(); - using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportDealsToCsv(dealData, daoFactory)))) - { - zipEntryData.StreamCopyTo(zipStream); - } - - zipStream.PutNextEntry(CRMCommonResource.CasesModuleName + ".csv"); - var casesData = casesDao.GetAllCases(); - using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportCasesToCsv(casesData, daoFactory)))) - { - zipEntryData.StreamCopyTo(zipStream); - } - - zipStream.PutNextEntry(CRMCommonResource.TaskModuleName + ".csv"); - var taskData = taskDao.GetAllTasks(); - using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportTasksToCsv(taskData, daoFactory)))) - { - zipEntryData.StreamCopyTo(zipStream); - } - - zipStream.PutNextEntry(CRMCommonResource.History + ".csv"); - var historyData = historyDao.GetAllItems(); - using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportHistoryToCsv(historyData, daoFactory)))) - { - zipEntryData.StreamCopyTo(zipStream); - } - - zipStream.PutNextEntry(CRMCommonResource.ProductsAndServices + ".csv"); - var invoiceItemData = invoiceItemDao.GetAll(); - using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportInvoiceItemsToCsv(invoiceItemData, daoFactory)))) - { - zipEntryData.StreamCopyTo(zipStream); - } - - zipStream.Flush(); - zipStream.Close(); - - stream.Position = 0; - } - - FileUrl = CommonLinkUtility.GetFullAbsolutePath(_dataStore.SavePrivate(String.Empty, FileName, stream, DateTime.Now.AddDays(1))); - - _notifyClient.SendAboutExportCompleted(_author.ID, FileName, FileUrl); - } - } - - private void ExportPartData(DaoFactory daoFactory) - { - var items = _filterObject.GetItemsByFilter(daoFactory); - - string fileContent; - - _totalCount = items.Count; - - if (_totalCount == 0) - throw new ArgumentException(CRMErrorsResource.ExportToCSVDataEmpty); - - if (items is List) - { - var contactInfoDao = daoFactory.GetContactInfoDao(); - - var contacts = (List)items; - - var contactInfos = new StringDictionary(); - - contactInfoDao.GetAll(contacts.Select(item => item.ID).ToArray()) - .ForEach(item => - { - var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, - (int)item.InfoType, - item.Category); - - if (contactInfos.ContainsKey(contactInfoKey)) - contactInfos[contactInfoKey] += "," + item.Data; - else - contactInfos.Add(contactInfoKey, item.Data); - }); - - fileContent = ExportContactsToCsv(contacts, contactInfos, daoFactory); - } - else if (items is List) - { - fileContent = ExportDealsToCsv((List)items, daoFactory); - } - else if (items is List) - { - fileContent = ExportCasesToCsv((List)items, daoFactory); - } - else if (items is List) - { - fileContent = ExportHistoryToCsv((List)items, daoFactory); - } - else if (items is List) - { - fileContent = ExportTasksToCsv((List)items, daoFactory); - } - else if (items is List) - { - fileContent = ExportInvoiceItemsToCsv((List)items, daoFactory); - } - else - throw new ArgumentException(); - - FileUrl = SaveCsvFileInMyDocument(FileName, fileContent); - } - - private String ExportContactsToCsv(IReadOnlyCollection contacts, StringDictionary contactInfos, DaoFactory daoFactory) - { - var key = (string)Id; - var listItemDao = daoFactory.GetListItemDao(); - var tagDao = daoFactory.GetTagDao(); - var customFieldDao = daoFactory.GetCustomFieldDao(); - var contactDao = daoFactory.GetContactDao(); - - var dataTable = new DataTable(); - - dataTable.Columns.AddRange(new[] - { - new DataColumn - { - Caption = CRMCommonResource.TypeCompanyOrPerson, - ColumnName = "company/person" - }, - new DataColumn - { - Caption = CRMContactResource.FirstName, - ColumnName = "firstname" - }, - new DataColumn - { - Caption = CRMContactResource.LastName, - ColumnName = "lastname" - }, - new DataColumn - { - Caption = CRMContactResource.CompanyName, - ColumnName = "companyname" - }, - new DataColumn - { - Caption = CRMContactResource.JobTitle, - ColumnName = "jobtitle" - }, - new DataColumn - { - Caption = CRMContactResource.About, - ColumnName = "about" - }, - new DataColumn - { - Caption = CRMContactResource.ContactStage, - ColumnName = "contact_stage" - }, - new DataColumn - { - Caption = CRMContactResource.ContactType, - ColumnName = "contact_type" - }, - new DataColumn - { - Caption = CRMContactResource.ContactTagList, - ColumnName = "contact_tag_list" - } - }); - - foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) - foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) - { - var localTitle = String.Format("{1} ({0})", categoryEnum.ToLocalizedString().ToLower(), infoTypeEnum.ToLocalizedString()); - - if (infoTypeEnum == ContactInfoType.Address) - dataTable.Columns.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) - select new DataColumn - { - Caption = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString().ToLower()), - ColumnName = String.Format("contactInfo_{0}_{1}_{2}", (int)infoTypeEnum, categoryEnum, (int)addressPartEnum) - }).ToArray()); - - else - dataTable.Columns.Add(new DataColumn - { - Caption = localTitle, - ColumnName = String.Format("contactInfo_{0}_{1}", (int)infoTypeEnum, categoryEnum) - }); - } - - var fieldsDescription = customFieldDao.GetFieldsDescription(EntityType.Company); - - customFieldDao.GetFieldsDescription(EntityType.Person).ForEach(item => - { - var alreadyContains = fieldsDescription.Any(field => field.ID == item.ID); - - if (!alreadyContains) - fieldsDescription.Add(item); - }); - - fieldsDescription.ForEach( - item => - { - if (item.FieldType == CustomFieldType.Heading) return; - - dataTable.Columns.Add( - new DataColumn - { - Caption = item.Label, - ColumnName = "customField_" + item.ID - } - ); - }); - - var customFieldEntity = new Dictionary>(); - - var entityFields = customFieldDao.GetEnityFields(EntityType.Company, 0, false); - - customFieldDao.GetEnityFields(EntityType.Person, 0, false).ForEach(item => - { - var alreadyContains = entityFields.Any(field => field.ID == item.ID && field.EntityID == item.EntityID); - - if (!alreadyContains) - entityFields.Add(item); - }); - - entityFields.ForEach( - item => - { - if (!customFieldEntity.ContainsKey(item.EntityID)) - customFieldEntity.Add(item.EntityID, new List { item }); - else - customFieldEntity[item.EntityID].Add(item); - }); - - var tags = tagDao.GetEntitiesTags(EntityType.Contact); - - foreach (var contact in contacts) - { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - - Percentage += 1.0 * 100 / _totalCount; - - var isCompany = contact is Company; - - var compPersType = (isCompany) ? CRMContactResource.Company : CRMContactResource.Person; - - var contactTags = String.Empty; - - if (tags.ContainsKey(contact.ID)) - contactTags = String.Join(",", tags[contact.ID].OrderBy(x => x)); - - String firstName; - String lastName; - - String companyName; - String title; - - if (contact is Company) - { - firstName = String.Empty; - lastName = String.Empty; - title = String.Empty; - companyName = ((Company)contact).CompanyName; - } - else - { - var people = (Person)contact; - - firstName = people.FirstName; - lastName = people.LastName; - title = people.JobTitle; - - companyName = String.Empty; - - if (people.CompanyID > 0) - { - var personCompany = contacts.SingleOrDefault(item => item.ID == people.CompanyID) ?? - contactDao.GetByID(people.CompanyID); - - if (personCompany != null) - companyName = personCompany.GetTitle(); - } - } - - var contactStatus = String.Empty; - - if (contact.StatusID > 0) - { - - var listItem = listItemDao.GetByID(contact.StatusID); - - if (listItem != null) - contactStatus = listItem.Title; - } - - var contactType = String.Empty; - - if (contact.ContactTypeID > 0) - { - - var listItem = listItemDao.GetByID(contact.ContactTypeID); - - if (listItem != null) - contactType = listItem.Title; - } - - var dataRowItems = new List - { - compPersType, - firstName, - lastName, - companyName, - title, - contact.About, - contactStatus, - contactType, - contactTags - }; - - foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) - foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) - { - var contactInfoKey = String.Format("{0}_{1}_{2}", contact.ID, - (int)infoTypeEnum, - Convert.ToInt32(categoryEnum)); - - var columnValue = ""; - - if (contactInfos.ContainsKey(contactInfoKey)) - columnValue = contactInfos[contactInfoKey]; - - if (infoTypeEnum == ContactInfoType.Address) - { - if (!String.IsNullOrEmpty(columnValue)) - { - var addresses = JArray.Parse(String.Concat("[", columnValue, "]")); - - dataRowItems.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) - select String.Join(",", addresses.Select(item => (String)item.SelectToken(addressPartEnum.ToString().ToLower())).ToArray())).ToArray()); - } - else - { - dataRowItems.AddRange(new[] { "", "", "", "", "" }); - } - } - else - { - dataRowItems.Add(columnValue); - } - } - - var dataRow = dataTable.Rows.Add(dataRowItems.ToArray()); - - if (customFieldEntity.ContainsKey(contact.ID)) - customFieldEntity[contact.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); - } - - return DataTableToCsv(dataTable); - } - - private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) - { - var key = (string)Id; - var tagDao = daoFactory.GetTagDao(); - var customFieldDao = daoFactory.GetCustomFieldDao(); - var dealMilestoneDao = daoFactory.GetDealMilestoneDao(); - var contactDao = daoFactory.GetContactDao(); - - var dataTable = new DataTable(); - - dataTable.Columns.AddRange(new[] - { - new DataColumn - { - Caption = CRMDealResource.NameDeal, - ColumnName = "title" - }, - new DataColumn - { - Caption = CRMDealResource.ClientDeal, - ColumnName = "client_deal" - }, - new DataColumn - { - Caption = CRMDealResource.DescriptionDeal, - ColumnName = "description" - }, - new DataColumn - { - Caption = CRMCommonResource.Currency, - ColumnName = "currency" - }, - new DataColumn - { - Caption = CRMDealResource.DealAmount, - ColumnName = "amount" - }, - new DataColumn - { - Caption = CRMDealResource.BidType, - ColumnName = "bid_type" - }, - new DataColumn - { - Caption = CRMDealResource.BidTypePeriod, - ColumnName = "bid_type_period" - }, - new DataColumn - { - Caption = CRMJSResource.ExpectedCloseDate, - ColumnName = "expected_close_date" - }, - new DataColumn - { - Caption = CRMJSResource.ActualCloseDate, - ColumnName = "actual_close_date" - }, - new DataColumn - { - Caption = CRMDealResource.ResponsibleDeal, - ColumnName = "responsible_deal" - }, - new DataColumn - { - Caption = CRMDealResource.CurrentDealMilestone, - ColumnName = "current_deal_milestone" - }, - new DataColumn - { - Caption = CRMDealResource.DealMilestoneType, - ColumnName = "deal_milestone_type" - }, - new DataColumn - { - Caption = (CRMDealResource.ProbabilityOfWinning + " %"), - ColumnName = "probability_of_winning" - }, - new DataColumn - { - Caption = (CRMDealResource.DealTagList), - ColumnName = "tag_list" - } - }); - - customFieldDao.GetFieldsDescription(EntityType.Opportunity).ForEach( - item => - { - if (item.FieldType == CustomFieldType.Heading) return; - - dataTable.Columns.Add(new DataColumn - { - Caption = item.Label, - ColumnName = "customField_" + item.ID - }); - }); - - var customFieldEntity = new Dictionary>(); - - customFieldDao.GetEnityFields(EntityType.Opportunity, 0, false).ForEach( - item => - { - if (!customFieldEntity.ContainsKey(item.EntityID)) - customFieldEntity.Add(item.EntityID, new List { item }); - else - customFieldEntity[item.EntityID].Add(item); - }); - - var tags = tagDao.GetEntitiesTags(EntityType.Opportunity); - - foreach (var deal in deals) - { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - - Percentage += 1.0 * 100 / _totalCount; - - var contactTags = String.Empty; - - if (tags.ContainsKey(deal.ID)) - contactTags = String.Join(",", tags[deal.ID].OrderBy(x => x)); - - String bidType; - - switch (deal.BidType) - { - case BidType.FixedBid: - bidType = CRMDealResource.BidType_FixedBid; - break; - case BidType.PerDay: - bidType = CRMDealResource.BidType_PerDay; - break; - case BidType.PerHour: - bidType = CRMDealResource.BidType_PerHour; - break; - case BidType.PerMonth: - bidType = CRMDealResource.BidType_PerMonth; - break; - case BidType.PerWeek: - bidType = CRMDealResource.BidType_PerWeek; - break; - case BidType.PerYear: - bidType = CRMDealResource.BidType_PerYear; - break; - default: - throw new ArgumentException(); - } - - var currentDealMilestone = dealMilestoneDao.GetByID(deal.DealMilestoneID); - var currentDealMilestoneStatus = currentDealMilestone.Status.ToLocalizedString(); - var contactTitle = String.Empty; - - if (deal.ContactID != 0) - contactTitle = contactDao.GetByID(deal.ContactID).GetTitle(); - - var dataRow = dataTable.Rows.Add(new object[] - { - deal.Title, - contactTitle, - deal.Description, - deal.BidCurrency, - deal.BidValue.ToString(CultureInfo.InvariantCulture), - bidType, - deal.PerPeriodValue == 0 ? "" : deal.PerPeriodValue.ToString(CultureInfo.InvariantCulture), - deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern), - deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern), - UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(false), - currentDealMilestone.Title, - currentDealMilestoneStatus, - deal.DealMilestoneProbability.ToString(CultureInfo.InvariantCulture), - contactTags - }); - - if (customFieldEntity.ContainsKey(deal.ID)) - customFieldEntity[deal.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); - } - - return DataTableToCsv(dataTable); - } - - private String ExportCasesToCsv(IEnumerable cases, DaoFactory daoFactory) - { - var key = (string)Id; - var tagDao = daoFactory.GetTagDao(); - var customFieldDao = daoFactory.GetCustomFieldDao(); - - var dataTable = new DataTable(); - - dataTable.Columns.AddRange(new[] - { - new DataColumn - { - Caption = CRMCasesResource.CaseTitle, - ColumnName = "title" - }, - new DataColumn(CRMCasesResource.CasesTagList) - { - Caption = CRMCasesResource.CasesTagList, - ColumnName = "tag_list" - } - }); - - customFieldDao.GetFieldsDescription(EntityType.Case).ForEach( - item => - { - if (item.FieldType == CustomFieldType.Heading) return; - - dataTable.Columns.Add(new DataColumn - { - Caption = item.Label, - ColumnName = "customField_" + item.ID - }); - }); - - var customFieldEntity = new Dictionary>(); - - customFieldDao.GetEnityFields(EntityType.Case, 0, false).ForEach( - item => - { - if (!customFieldEntity.ContainsKey(item.EntityID)) - customFieldEntity.Add(item.EntityID, new List { item }); - else - customFieldEntity[item.EntityID].Add(item); - }); - - var tags = tagDao.GetEntitiesTags(EntityType.Case); - - foreach (var item in cases) - { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - - Percentage += 1.0 * 100 / _totalCount; - - var contactTags = String.Empty; - - if (tags.ContainsKey(item.ID)) - contactTags = String.Join(",", tags[item.ID].OrderBy(x => x)); - - var dataRow = dataTable.Rows.Add(new object[] - { - item.Title, - contactTags - }); - - if (customFieldEntity.ContainsKey(item.ID)) - customFieldEntity[item.ID].ForEach(row => dataRow["customField_" + row.ID] = row.Value); - } - - return DataTableToCsv(dataTable); - } - - private String ExportHistoryToCsv(IEnumerable events, DaoFactory daoFactory) - { - var key = (string)Id; - var listItemDao = daoFactory.GetListItemDao(); - var dealDao = daoFactory.GetDealDao(); - var casesDao = daoFactory.GetCasesDao(); - var contactDao = daoFactory.GetContactDao(); - - var dataTable = new DataTable(); - - dataTable.Columns.AddRange(new[] - { - new DataColumn - { - Caption = (CRMContactResource.Content), - ColumnName = "content" - }, - new DataColumn - { - Caption = (CRMCommonResource.Category), - ColumnName = "category" - }, - new DataColumn - { - Caption = (CRMContactResource.ContactTitle), - ColumnName = "contact_title" - }, - new DataColumn - { - Caption = (CRMContactResource.RelativeEntity), - ColumnName = "relative_entity" - }, - new DataColumn - { - Caption = (CRMCommonResource.Author), - ColumnName = "author" - }, - new DataColumn - { - Caption = (CRMCommonResource.CreateDate), - ColumnName = "create_date" - } - }); - - foreach (var item in events) - { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - - Percentage += 1.0 * 100 / _totalCount; - - var entityTitle = String.Empty; - - if (item.EntityID > 0) - switch (item.EntityType) - { - case EntityType.Case: - var casesObj = casesDao.GetByID(item.EntityID); - - if (casesObj != null) - entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, - casesObj.Title); - break; - case EntityType.Opportunity: - var dealObj = dealDao.GetByID(item.EntityID); - - if (dealObj != null) - entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, - dealObj.Title); - break; - } - - var contactTitle = String.Empty; - - if (item.ContactID > 0) - { - var contactObj = contactDao.GetByID(item.ContactID); - - if (contactObj != null) - contactTitle = contactObj.GetTitle(); - } - - var categoryTitle = String.Empty; - - if (item.CategoryID > 0) - { - var categoryObj = listItemDao.GetByID(item.CategoryID); - - if (categoryObj != null) - categoryTitle = categoryObj.Title; - - } - else if (item.CategoryID == (int)HistoryCategorySystem.TaskClosed) - categoryTitle = HistoryCategorySystem.TaskClosed.ToLocalizedString(); - else if (item.CategoryID == (int)HistoryCategorySystem.FilesUpload) - categoryTitle = HistoryCategorySystem.FilesUpload.ToLocalizedString(); - else if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) - categoryTitle = HistoryCategorySystem.MailMessage.ToLocalizedString(); - - dataTable.Rows.Add(new object[] - { - item.Content, - categoryTitle, - contactTitle, - entityTitle, - UserManager.GetUsers(item.CreateBy).DisplayUserName(false), - item.CreateOn.ToShortString() - }); - } - - return DataTableToCsv(dataTable); - } - - private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) - { - var key = (string)Id; - var listItemDao = daoFactory.GetListItemDao(); - var dealDao = daoFactory.GetDealDao(); - var casesDao = daoFactory.GetCasesDao(); - var contactDao = daoFactory.GetContactDao(); - - var dataTable = new DataTable(); - - dataTable.Columns.AddRange(new[] - { - new DataColumn - { - Caption = (CRMTaskResource.TaskTitle), - ColumnName = "title" - }, - new DataColumn - { - Caption = (CRMTaskResource.Description), - ColumnName = "description" - }, - new DataColumn - { - Caption = (CRMTaskResource.DueDate), - ColumnName = "due_date" - }, - new DataColumn - { - Caption = (CRMTaskResource.Responsible), - ColumnName = "responsible" - }, - new DataColumn - { - Caption = (CRMContactResource.ContactTitle), - ColumnName = "contact_title" - }, - new DataColumn - { - Caption = (CRMTaskResource.TaskStatus), - ColumnName = "task_status" - }, - new DataColumn - { - Caption = (CRMTaskResource.TaskCategory), - ColumnName = "task_category" - }, - new DataColumn - { - Caption = (CRMContactResource.RelativeEntity), - ColumnName = "relative_entity" - }, - new DataColumn - { - Caption = (CRMCommonResource.Alert), - ColumnName = "alert_value" - } - }); - - foreach (var item in tasks) - { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - - Percentage += 1.0 * 100 / _totalCount; - - var entityTitle = String.Empty; - - if (item.EntityID > 0) - switch (item.EntityType) - { - case EntityType.Case: - var caseObj = casesDao.GetByID(item.EntityID); - - if (caseObj != null) - entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, caseObj.Title); - break; - case EntityType.Opportunity: - var dealObj = dealDao.GetByID(item.EntityID); - - if (dealObj != null) - entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, dealObj.Title); - break; - } - - var contactTitle = String.Empty; - - if (item.ContactID > 0) - { - var contact = contactDao.GetByID(item.ContactID); - - if (contact != null) - contactTitle = contact.GetTitle(); - } - - dataTable.Rows.Add(new object[] - { - item.Title, - item.Description, - item.DeadLine == DateTime.MinValue - ? "" - : item.DeadLine.ToShortString(), - UserManager.GetUsers(item.ResponsibleID).DisplayUserName(false,), - contactTitle, - item.IsClosed - ? CRMTaskResource.TaskStatus_Closed - : CRMTaskResource.TaskStatus_Open, - listItemDao.GetByID(item.CategoryID).Title, - entityTitle, - item.AlertValue.ToString(CultureInfo.InvariantCulture) - }); - } - - return DataTableToCsv(dataTable); - } - - private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, DaoFactory daoFactory) - { - var key = (string)Id; - var taxes = daoFactory.GetInvoiceTaxDao().GetAll(); - var dataTable = new DataTable(); - - dataTable.Columns.AddRange(new[] - { - new DataColumn - { - Caption = (CRMInvoiceResource.InvoiceItemName), - ColumnName = "title" - }, - new DataColumn - { - Caption = (CRMSettingResource.Description), - ColumnName = "description" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.StockKeepingUnit), - ColumnName = "sku" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.InvoiceItemPrice), - ColumnName = "price" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.FormInvoiceItemStockQuantity), - ColumnName = "stock_quantity" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.TrackInventory), - ColumnName = "track_inventory" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.Currency), - ColumnName = "currency" - }, - - new DataColumn - { - Caption = (CRMInvoiceResource.InvoiceTax1Name), - ColumnName = "tax1_name" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.InvoiceTax1Rate), - ColumnName = "tax1_rate" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.InvoiceTax2Name), - ColumnName = "tax2_name" - }, - new DataColumn - { - Caption = (CRMInvoiceResource.InvoiceTax2Rate), - ColumnName = "tax2_rate" - } - - }); - - - foreach (var item in invoiceItems) - { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - - Percentage += 1.0 * 100 / _totalCount; - - var tax1 = item.InvoiceTax1ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax1ID) : null; - var tax2 = item.InvoiceTax2ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax2ID) : null; - - dataTable.Rows.Add(new object[] - { - item.Title, - item.Description, - item.StockKeepingUnit, - item.Price.ToString(CultureInfo.InvariantCulture), - item.StockQuantity.ToString(CultureInfo.InvariantCulture), - item.TrackInventory.ToString(), - item.Currency, - tax1 != null ? tax1.Name : "", - tax1 != null ? tax1.Rate.ToString(CultureInfo.InvariantCulture) : "", - tax2 != null ? tax2.Name : "", - tax2 != null ? tax2.Rate.ToString(CultureInfo.InvariantCulture) : "" - }); - } - - return DataTableToCsv(dataTable); - } - - private String SaveCsvFileInMyDocument(String title, String data) - { - string fileUrl; - - using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(data))) - { - var file = FileUploader.Exec(Files.Classes.Global.FolderMy.ToString(), title, memStream.Length, memStream, true); - - if (FileUtility.CanWebView(title) || FileUtility.CanWebEdit(title)) - { - fileUrl = FilesLinkUtility.GetFileWebEditorUrl((int)file.ID); - fileUrl += string.Format("&options={{\"delimiter\":{0},\"codePage\":{1}}}", - (int)FileUtility.CsvDelimiter.Comma, - Encoding.UTF8.CodePage); - } - else - { - fileUrl = FilesLinkUtility.GetFileDownloadUrl((int)file.ID); - } - } - - return fileUrl; - } - } - - public class ExportToCsv - { - private readonly object Locker = new object(); - - private readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromSeconds(60), true); - - public ExportToCsv(SecurityContext securityContext, - ExportDataCache exportDataCache, - TenantManager tenantManager) - { - SecurityContext = securityContext; - ExportDataCache = exportDataCache; - TenantID = tenantManager.GetCurrentTenant().TenantId; - } - - protected int TenantID { get; private set; } - - public ExportDataCache ExportDataCache { get; } - - public SecurityContext SecurityContext { get; } - - public IProgressItem GetStatus(bool partialDataExport) - { - var key = GetKey(partialDataExport); - - return Queue.GetStatus(key) ?? ExportDataCache.Get(key); - } - - public IProgressItem Start(FilterObject filterObject, string fileName) - { - lock (Locker) - { - var key = GetKey(filterObject != null); - - var operation = Queue.GetStatus(key); - - if (operation == null) - { - var fromCache = ExportDataCache.Get(key); - - if (fromCache != null) - return fromCache; - } - - if (operation == null) - { - operation = new ExportDataOperation(filterObject, fileName); - - Queue.Add(operation); - } - - if (!Queue.IsStarted) - Queue.Start(x => x.RunJob()); - - return operation; - } - } - - public void Cancel(bool partialDataExport) - { - lock (Locker) - { - var key = GetKey(partialDataExport); - - var findedItem = Queue.GetItems().FirstOrDefault(elem => (string)elem.Id == key); - - if (findedItem != null) - { - Queue.Remove(findedItem); - } - - ExportDataCache.SetCancelFlag(key); - } - } - - public string GetKey(bool partialDataExport) - { - return string.Format("{0}_{1}", TenantID, - partialDataExport ? SecurityContext.CurrentAccount.ID : Guid.Empty); - } - - public String ExportItems(FilterObject filterObject, string fileName) - { - var operation = new ExportDataOperation(filterObject, fileName); - - operation.RunJob(); - - return operation.FileUrl; - } - } -} \ No newline at end of file +// public string FileName { get; set; } + +// public string FileUrl { get; set; } + +// private String WrapDoubleQuote(String value) +// { +// return "\"" + value.Trim().Replace("\"", "\"\"") + "\""; +// } + +// private String DataTableToCsv(DataTable dataTable) +// { +// var result = new StringBuilder(); + +// var columnsCount = dataTable.Columns.Count; + +// for (var index = 0; index < columnsCount; index++) +// { +// if (index != columnsCount - 1) +// result.Append(dataTable.Columns[index].Caption + ","); +// else +// result.Append(dataTable.Columns[index].Caption); +// } + +// result.Append(Environment.NewLine); + +// foreach (DataRow row in dataTable.Rows) +// { +// for (var i = 0; i < columnsCount; i++) +// { +// var itemValue = WrapDoubleQuote(row[i].ToString()); + +// if (i != columnsCount - 1) +// result.Append(itemValue + ","); +// else +// result.Append(itemValue); +// } + +// result.Append(Environment.NewLine); +// } + +// return result.ToString(); +// } + +// public void RunJob() +// { +// try +// { +// Status = ProgressStatus.Started; + +// TenantManager.SetCurrentTenant(_tenantId); +// SecurityContext.AuthenticateMe(_author); + +// var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + +// System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; +// System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; + +// _log.Debug("Start Export Data"); + +// ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); + +// if (_filterObject == null) +// ExportAllData(daoFactory); +// else +// ExportPartData(daoFactory); + +// Complete(100, ProgressStatus.Done, null); + +// _log.Debug("Export is completed"); +// } +// catch (OperationCanceledException) +// { +// Complete(0, ProgressStatus.Done, null); + +// _log.Debug("Export is cancel"); +// } +// catch (Exception ex) +// { +// Complete(0, ProgressStatus.Failed, ex.Message); + +// _log.Error(ex); +// } +// finally +// { +// ExportDataCache.ResetAll((string)Id); +// } +// } + +// private void Complete(double percentage, ProgressStatus status, object error) +// { +// IsCompleted = true; +// Percentage = percentage; +// Status = status; +// Error = error; + +// ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); +// } + +// private void ExportAllData(DaoFactory daoFactory) +// { +// using (var stream = TempStream.Create()) +// { +// var contactDao = daoFactory.GetContactDao(); +// var contactInfoDao = daoFactory.GetContactInfoDao(); +// var dealDao = daoFactory.GetDealDao(); +// var casesDao = daoFactory.GetCasesDao(); +// var taskDao = daoFactory.GetTaskDao(); +// var historyDao = daoFactory.GetRelationshipEventDao(); +// var invoiceItemDao = daoFactory.GetInvoiceItemDao(); + +// _totalCount += contactDao.GetAllContactsCount(); +// _totalCount += dealDao.GetDealsCount(); +// _totalCount += casesDao.GetCasesCount(); +// _totalCount += taskDao.GetAllTasksCount(); +// _totalCount += historyDao.GetAllItemsCount(); +// _totalCount += invoiceItemDao.GetInvoiceItemsCount(); + +// using (var zipStream = new ZipOutputStream(stream)) +// { +// zipStream.PutNextEntry(new ZipEntry(CRMContactResource.Contacts + ".csv")); + +// var contactData = contactDao.GetAllContacts(); +// var contactInfos = new StringDictionary(); + +// contactInfoDao.GetAll() +// .ForEach(item => +// { +// var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, (int)item.InfoType, item.Category); +// if (contactInfos.ContainsKey(contactInfoKey)) +// { +// contactInfos[contactInfoKey] += "," + item.Data; +// } +// else +// { +// contactInfos.Add(contactInfoKey, item.Data); +// } +// }); + +// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportContactsToCsv(contactData, contactInfos, daoFactory)))) +// { +// zipEntryData.CopyTo(zipStream); +// } + +// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.DealModuleName + ".csv")); + +// var dealData = dealDao.GetAllDeals(); + +// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportDealsToCsv(dealData, daoFactory)))) +// { +// zipEntryData.CopyTo(zipStream); +// } + +// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.CasesModuleName + ".csv")); + +// var casesData = casesDao.GetAllCases(); + +// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportCasesToCsv(casesData, daoFactory)))) +// { +// zipEntryData.CopyTo(zipStream); +// } + + +// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.TaskModuleName + ".csv")); + +// var taskData = taskDao.GetAllTasks(); + +// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportTasksToCsv(taskData, daoFactory)))) +// { +// zipEntryData.CopyTo(zipStream); +// } + +// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.History + ".csv")); + +// var historyData = historyDao.GetAllItems(); + +// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportHistoryToCsv(historyData, daoFactory)))) +// { +// zipEntryData.CopyTo(zipStream); +// } + +// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.ProductsAndServices + ".csv")); + +// var invoiceItemData = invoiceItemDao.GetAll(); + +// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportInvoiceItemsToCsv(invoiceItemData, daoFactory)))) +// { +// zipEntryData.CopyTo(zipStream); +// } + +// zipStream.Flush(); +// zipStream.Close(); + +// stream.Position = 0; +// } + +// FileUrl = CommonLinkUtility.GetFullAbsolutePath(_dataStore.SavePrivate(String.Empty, FileName, stream, DateTime.Now.AddDays(1))); + +// _notifyClient.SendAboutExportCompleted(_author.ID, FileName, FileUrl); +// } +// } + +// private void ExportPartData(DaoFactory daoFactory) +// { +// var items = _filterObject.GetItemsByFilter(daoFactory); + +// string fileContent; + +// _totalCount = items.Count; + +// if (_totalCount == 0) +// throw new ArgumentException(CRMErrorsResource.ExportToCSVDataEmpty); + +// if (items is List) +// { +// var contactInfoDao = daoFactory.GetContactInfoDao(); + +// var contacts = (List)items; + +// var contactInfos = new StringDictionary(); + +// contactInfoDao.GetAll(contacts.Select(item => item.ID).ToArray()) +// .ForEach(item => +// { +// var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, +// (int)item.InfoType, +// item.Category); + +// if (contactInfos.ContainsKey(contactInfoKey)) +// contactInfos[contactInfoKey] += "," + item.Data; +// else +// contactInfos.Add(contactInfoKey, item.Data); +// }); + +// fileContent = ExportContactsToCsv(contacts, contactInfos, daoFactory); +// } +// else if (items is List) +// { +// fileContent = ExportDealsToCsv((List)items, daoFactory); +// } +// else if (items is List) +// { +// fileContent = ExportCasesToCsv((List)items, daoFactory); +// } +// else if (items is List) +// { +// fileContent = ExportHistoryToCsv((List)items, daoFactory); +// } +// else if (items is List) +// { +// fileContent = ExportTasksToCsv((List)items, daoFactory); +// } +// else if (items is List) +// { +// fileContent = ExportInvoiceItemsToCsv((List)items, daoFactory); +// } +// else +// throw new ArgumentException(); + +// FileUrl = SaveCsvFileInMyDocument(FileName, fileContent); +// } + +// private String ExportContactsToCsv(IReadOnlyCollection contacts, StringDictionary contactInfos, DaoFactory daoFactory) +// { +// var key = (string)Id; +// var listItemDao = daoFactory.GetListItemDao(); +// var tagDao = daoFactory.GetTagDao(); +// var customFieldDao = daoFactory.GetCustomFieldDao(); +// var contactDao = daoFactory.GetContactDao(); + +// var dataTable = new DataTable(); + +// dataTable.Columns.AddRange(new[] +// { +// new DataColumn +// { +// Caption = CRMCommonResource.TypeCompanyOrPerson, +// ColumnName = "company/person" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.FirstName, +// ColumnName = "firstname" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.LastName, +// ColumnName = "lastname" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.CompanyName, +// ColumnName = "companyname" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.JobTitle, +// ColumnName = "jobtitle" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.About, +// ColumnName = "about" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.ContactStage, +// ColumnName = "contact_stage" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.ContactType, +// ColumnName = "contact_type" +// }, +// new DataColumn +// { +// Caption = CRMContactResource.ContactTagList, +// ColumnName = "contact_tag_list" +// } +// }); + +// foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) +// foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) +// { +// var localTitle = String.Format("{1} ({0})", categoryEnum.ToLocalizedString().ToLower(), infoTypeEnum.ToLocalizedString()); + +// if (infoTypeEnum == ContactInfoType.Address) +// dataTable.Columns.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) +// select new DataColumn +// { +// Caption = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString().ToLower()), +// ColumnName = String.Format("contactInfo_{0}_{1}_{2}", (int)infoTypeEnum, categoryEnum, (int)addressPartEnum) +// }).ToArray()); + +// else +// dataTable.Columns.Add(new DataColumn +// { +// Caption = localTitle, +// ColumnName = String.Format("contactInfo_{0}_{1}", (int)infoTypeEnum, categoryEnum) +// }); +// } + +// var fieldsDescription = customFieldDao.GetFieldsDescription(EntityType.Company); + +// customFieldDao.GetFieldsDescription(EntityType.Person).ForEach(item => +// { +// var alreadyContains = fieldsDescription.Any(field => field.ID == item.ID); + +// if (!alreadyContains) +// fieldsDescription.Add(item); +// }); + +// fieldsDescription.ForEach( +// item => +// { +// if (item.FieldType == CustomFieldType.Heading) return; + +// dataTable.Columns.Add( +// new DataColumn +// { +// Caption = item.Label, +// ColumnName = "customField_" + item.ID +// } +// ); +// }); + +// var customFieldEntity = new Dictionary>(); + +// var entityFields = customFieldDao.GetEnityFields(EntityType.Company, 0, false); + +// customFieldDao.GetEnityFields(EntityType.Person, 0, false).ForEach(item => +// { +// var alreadyContains = entityFields.Any(field => field.ID == item.ID && field.EntityID == item.EntityID); + +// if (!alreadyContains) +// entityFields.Add(item); +// }); + +// entityFields.ForEach( +// item => +// { +// if (!customFieldEntity.ContainsKey(item.EntityID)) +// customFieldEntity.Add(item.EntityID, new List { item }); +// else +// customFieldEntity[item.EntityID].Add(item); +// }); + +// var tags = tagDao.GetEntitiesTags(EntityType.Contact); + +// foreach (var contact in contacts) +// { +// if (ExportDataCache.CheckCancelFlag(key)) +// { +// ExportDataCache.ResetAll(key); + +// throw new OperationCanceledException(); +// } + +// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + +// Percentage += 1.0 * 100 / _totalCount; + +// var isCompany = contact is Company; + +// var compPersType = (isCompany) ? CRMContactResource.Company : CRMContactResource.Person; + +// var contactTags = String.Empty; + +// if (tags.ContainsKey(contact.ID)) +// contactTags = String.Join(",", tags[contact.ID].OrderBy(x => x)); + +// String firstName; +// String lastName; + +// String companyName; +// String title; + +// if (contact is Company) +// { +// firstName = String.Empty; +// lastName = String.Empty; +// title = String.Empty; +// companyName = ((Company)contact).CompanyName; +// } +// else +// { +// var people = (Person)contact; + +// firstName = people.FirstName; +// lastName = people.LastName; +// title = people.JobTitle; + +// companyName = String.Empty; + +// if (people.CompanyID > 0) +// { +// var personCompany = contacts.SingleOrDefault(item => item.ID == people.CompanyID) ?? +// contactDao.GetByID(people.CompanyID); + +// if (personCompany != null) +// companyName = personCompany.GetTitle(); +// } +// } + +// var contactStatus = String.Empty; + +// if (contact.StatusID > 0) +// { + +// var listItem = listItemDao.GetByID(contact.StatusID); + +// if (listItem != null) +// contactStatus = listItem.Title; +// } + +// var contactType = String.Empty; + +// if (contact.ContactTypeID > 0) +// { + +// var listItem = listItemDao.GetByID(contact.ContactTypeID); + +// if (listItem != null) +// contactType = listItem.Title; +// } + +// var dataRowItems = new List +// { +// compPersType, +// firstName, +// lastName, +// companyName, +// title, +// contact.About, +// contactStatus, +// contactType, +// contactTags +// }; + +// foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) +// foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) +// { +// var contactInfoKey = String.Format("{0}_{1}_{2}", contact.ID, +// (int)infoTypeEnum, +// Convert.ToInt32(categoryEnum)); + +// var columnValue = ""; + +// if (contactInfos.ContainsKey(contactInfoKey)) +// columnValue = contactInfos[contactInfoKey]; + +// if (infoTypeEnum == ContactInfoType.Address) +// { +// if (!String.IsNullOrEmpty(columnValue)) +// { +// var addresses = JArray.Parse(String.Concat("[", columnValue, "]")); + +// dataRowItems.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) +// select String.Join(",", addresses.Select(item => (String)item.SelectToken(addressPartEnum.ToString().ToLower())).ToArray())).ToArray()); +// } +// else +// { +// dataRowItems.AddRange(new[] { "", "", "", "", "" }); +// } +// } +// else +// { +// dataRowItems.Add(columnValue); +// } +// } + +// var dataRow = dataTable.Rows.Add(dataRowItems.ToArray()); + +// if (customFieldEntity.ContainsKey(contact.ID)) +// customFieldEntity[contact.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); +// } + +// return DataTableToCsv(dataTable); +// } + +// private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) +// { +// var key = (string)Id; +// var tagDao = daoFactory.GetTagDao(); +// var customFieldDao = daoFactory.GetCustomFieldDao(); +// var dealMilestoneDao = daoFactory.GetDealMilestoneDao(); +// var contactDao = daoFactory.GetContactDao(); + +// var dataTable = new DataTable(); + +// dataTable.Columns.AddRange(new[] +// { +// new DataColumn +// { +// Caption = CRMDealResource.NameDeal, +// ColumnName = "title" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.ClientDeal, +// ColumnName = "client_deal" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.DescriptionDeal, +// ColumnName = "description" +// }, +// new DataColumn +// { +// Caption = CRMCommonResource.Currency, +// ColumnName = "currency" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.DealAmount, +// ColumnName = "amount" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.BidType, +// ColumnName = "bid_type" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.BidTypePeriod, +// ColumnName = "bid_type_period" +// }, +// new DataColumn +// { +// Caption = CRMJSResource.ExpectedCloseDate, +// ColumnName = "expected_close_date" +// }, +// new DataColumn +// { +// Caption = CRMJSResource.ActualCloseDate, +// ColumnName = "actual_close_date" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.ResponsibleDeal, +// ColumnName = "responsible_deal" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.CurrentDealMilestone, +// ColumnName = "current_deal_milestone" +// }, +// new DataColumn +// { +// Caption = CRMDealResource.DealMilestoneType, +// ColumnName = "deal_milestone_type" +// }, +// new DataColumn +// { +// Caption = (CRMDealResource.ProbabilityOfWinning + " %"), +// ColumnName = "probability_of_winning" +// }, +// new DataColumn +// { +// Caption = (CRMDealResource.DealTagList), +// ColumnName = "tag_list" +// } +// }); + +// customFieldDao.GetFieldsDescription(EntityType.Opportunity).ForEach( +// item => +// { +// if (item.FieldType == CustomFieldType.Heading) return; + +// dataTable.Columns.Add(new DataColumn +// { +// Caption = item.Label, +// ColumnName = "customField_" + item.ID +// }); +// }); + +// var customFieldEntity = new Dictionary>(); + +// customFieldDao.GetEnityFields(EntityType.Opportunity, 0, false).ForEach( +// item => +// { +// if (!customFieldEntity.ContainsKey(item.EntityID)) +// customFieldEntity.Add(item.EntityID, new List { item }); +// else +// customFieldEntity[item.EntityID].Add(item); +// }); + +// var tags = tagDao.GetEntitiesTags(EntityType.Opportunity); + +// foreach (var deal in deals) +// { +// if (ExportDataCache.CheckCancelFlag(key)) +// { +// ExportDataCache.ResetAll(key); + +// throw new OperationCanceledException(); +// } + +// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + +// Percentage += 1.0 * 100 / _totalCount; + +// var contactTags = String.Empty; + +// if (tags.ContainsKey(deal.ID)) +// contactTags = String.Join(",", tags[deal.ID].OrderBy(x => x)); + +// String bidType; + +// switch (deal.BidType) +// { +// case BidType.FixedBid: +// bidType = CRMDealResource.BidType_FixedBid; +// break; +// case BidType.PerDay: +// bidType = CRMDealResource.BidType_PerDay; +// break; +// case BidType.PerHour: +// bidType = CRMDealResource.BidType_PerHour; +// break; +// case BidType.PerMonth: +// bidType = CRMDealResource.BidType_PerMonth; +// break; +// case BidType.PerWeek: +// bidType = CRMDealResource.BidType_PerWeek; +// break; +// case BidType.PerYear: +// bidType = CRMDealResource.BidType_PerYear; +// break; +// default: +// throw new ArgumentException(); +// } + +// var currentDealMilestone = dealMilestoneDao.GetByID(deal.DealMilestoneID); +// var currentDealMilestoneStatus = currentDealMilestone.Status.ToLocalizedString(); +// var contactTitle = String.Empty; + +// if (deal.ContactID != 0) +// contactTitle = contactDao.GetByID(deal.ContactID).GetTitle(); + +// var dataRow = dataTable.Rows.Add(new object[] +// { +// deal.Title, +// contactTitle, +// deal.Description, +// deal.BidCurrency, +// deal.BidValue.ToString(CultureInfo.InvariantCulture), +// bidType, +// deal.PerPeriodValue == 0 ? "" : deal.PerPeriodValue.ToString(CultureInfo.InvariantCulture), +// deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern), +// deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern), +// UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(DisplayUserSettingsHelper), +// currentDealMilestone.Title, +// currentDealMilestoneStatus, +// deal.DealMilestoneProbability.ToString(CultureInfo.InvariantCulture), +// contactTags +// }); + +// if (customFieldEntity.ContainsKey(deal.ID)) +// customFieldEntity[deal.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); +// } + +// return DataTableToCsv(dataTable); +// } + +// private String ExportCasesToCsv(IEnumerable cases, DaoFactory daoFactory) +// { +// var key = (string)Id; +// var tagDao = daoFactory.GetTagDao(); +// var customFieldDao = daoFactory.GetCustomFieldDao(); + +// var dataTable = new DataTable(); + +// dataTable.Columns.AddRange(new[] +// { +// new DataColumn +// { +// Caption = CRMCasesResource.CaseTitle, +// ColumnName = "title" +// }, +// new DataColumn(CRMCasesResource.CasesTagList) +// { +// Caption = CRMCasesResource.CasesTagList, +// ColumnName = "tag_list" +// } +// }); + +// customFieldDao.GetFieldsDescription(EntityType.Case).ForEach( +// item => +// { +// if (item.FieldType == CustomFieldType.Heading) return; + +// dataTable.Columns.Add(new DataColumn +// { +// Caption = item.Label, +// ColumnName = "customField_" + item.ID +// }); +// }); + +// var customFieldEntity = new Dictionary>(); + +// customFieldDao.GetEnityFields(EntityType.Case, 0, false).ForEach( +// item => +// { +// if (!customFieldEntity.ContainsKey(item.EntityID)) +// customFieldEntity.Add(item.EntityID, new List { item }); +// else +// customFieldEntity[item.EntityID].Add(item); +// }); + +// var tags = tagDao.GetEntitiesTags(EntityType.Case); + +// foreach (var item in cases) +// { +// if (ExportDataCache.CheckCancelFlag(key)) +// { +// ExportDataCache.ResetAll(key); + +// throw new OperationCanceledException(); +// } + +// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + +// Percentage += 1.0 * 100 / _totalCount; + +// var contactTags = String.Empty; + +// if (tags.ContainsKey(item.ID)) +// contactTags = String.Join(",", tags[item.ID].OrderBy(x => x)); + +// var dataRow = dataTable.Rows.Add(new object[] +// { +// item.Title, +// contactTags +// }); + +// if (customFieldEntity.ContainsKey(item.ID)) +// customFieldEntity[item.ID].ForEach(row => dataRow["customField_" + row.ID] = row.Value); +// } + +// return DataTableToCsv(dataTable); +// } + +// private String ExportHistoryToCsv(IEnumerable events, DaoFactory daoFactory) +// { +// var key = (string)Id; +// var listItemDao = daoFactory.GetListItemDao(); +// var dealDao = daoFactory.GetDealDao(); +// var casesDao = daoFactory.GetCasesDao(); +// var contactDao = daoFactory.GetContactDao(); + +// var dataTable = new DataTable(); + +// dataTable.Columns.AddRange(new[] +// { +// new DataColumn +// { +// Caption = (CRMContactResource.Content), +// ColumnName = "content" +// }, +// new DataColumn +// { +// Caption = (CRMCommonResource.Category), +// ColumnName = "category" +// }, +// new DataColumn +// { +// Caption = (CRMContactResource.ContactTitle), +// ColumnName = "contact_title" +// }, +// new DataColumn +// { +// Caption = (CRMContactResource.RelativeEntity), +// ColumnName = "relative_entity" +// }, +// new DataColumn +// { +// Caption = (CRMCommonResource.Author), +// ColumnName = "author" +// }, +// new DataColumn +// { +// Caption = (CRMCommonResource.CreateDate), +// ColumnName = "create_date" +// } +// }); + +// foreach (var item in events) +// { +// if (ExportDataCache.CheckCancelFlag(key)) +// { +// ExportDataCache.ResetAll(key); + +// throw new OperationCanceledException(); +// } + +// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + +// Percentage += 1.0 * 100 / _totalCount; + +// var entityTitle = String.Empty; + +// if (item.EntityID > 0) +// switch (item.EntityType) +// { +// case EntityType.Case: +// var casesObj = casesDao.GetByID(item.EntityID); + +// if (casesObj != null) +// entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, +// casesObj.Title); +// break; +// case EntityType.Opportunity: +// var dealObj = dealDao.GetByID(item.EntityID); + +// if (dealObj != null) +// entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, +// dealObj.Title); +// break; +// } + +// var contactTitle = String.Empty; + +// if (item.ContactID > 0) +// { +// var contactObj = contactDao.GetByID(item.ContactID); + +// if (contactObj != null) +// contactTitle = contactObj.GetTitle(); +// } + +// var categoryTitle = String.Empty; + +// if (item.CategoryID > 0) +// { +// var categoryObj = listItemDao.GetByID(item.CategoryID); + +// if (categoryObj != null) +// categoryTitle = categoryObj.Title; + +// } +// else if (item.CategoryID == (int)HistoryCategorySystem.TaskClosed) +// categoryTitle = HistoryCategorySystem.TaskClosed.ToLocalizedString(); +// else if (item.CategoryID == (int)HistoryCategorySystem.FilesUpload) +// categoryTitle = HistoryCategorySystem.FilesUpload.ToLocalizedString(); +// else if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) +// categoryTitle = HistoryCategorySystem.MailMessage.ToLocalizedString(); + +// dataTable.Rows.Add(new object[] +// { +// item.Content, +// categoryTitle, +// contactTitle, +// entityTitle, +// UserManager.GetUsers(item.CreateBy).DisplayUserName(DisplayUserSettingsHelper), +// item.CreateOn.ToShortString() +// }); +// } + +// return DataTableToCsv(dataTable); +// } + +// private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) +// { +// var key = (string)Id; +// var listItemDao = daoFactory.GetListItemDao(); +// var dealDao = daoFactory.GetDealDao(); +// var casesDao = daoFactory.GetCasesDao(); +// var contactDao = daoFactory.GetContactDao(); + +// var dataTable = new DataTable(); + +// dataTable.Columns.AddRange(new[] +// { +// new DataColumn +// { +// Caption = (CRMTaskResource.TaskTitle), +// ColumnName = "title" +// }, +// new DataColumn +// { +// Caption = (CRMTaskResource.Description), +// ColumnName = "description" +// }, +// new DataColumn +// { +// Caption = (CRMTaskResource.DueDate), +// ColumnName = "due_date" +// }, +// new DataColumn +// { +// Caption = (CRMTaskResource.Responsible), +// ColumnName = "responsible" +// }, +// new DataColumn +// { +// Caption = (CRMContactResource.ContactTitle), +// ColumnName = "contact_title" +// }, +// new DataColumn +// { +// Caption = (CRMTaskResource.TaskStatus), +// ColumnName = "task_status" +// }, +// new DataColumn +// { +// Caption = (CRMTaskResource.TaskCategory), +// ColumnName = "task_category" +// }, +// new DataColumn +// { +// Caption = (CRMContactResource.RelativeEntity), +// ColumnName = "relative_entity" +// }, +// new DataColumn +// { +// Caption = (CRMCommonResource.Alert), +// ColumnName = "alert_value" +// } +// }); + +// foreach (var item in tasks) +// { +// if (ExportDataCache.CheckCancelFlag(key)) +// { +// ExportDataCache.ResetAll(key); + +// throw new OperationCanceledException(); +// } + +// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + +// Percentage += 1.0 * 100 / _totalCount; + +// var entityTitle = String.Empty; + +// if (item.EntityID > 0) +// switch (item.EntityType) +// { +// case EntityType.Case: +// var caseObj = casesDao.GetByID(item.EntityID); + +// if (caseObj != null) +// entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, caseObj.Title); +// break; +// case EntityType.Opportunity: +// var dealObj = dealDao.GetByID(item.EntityID); + +// if (dealObj != null) +// entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, dealObj.Title); +// break; +// } + +// var contactTitle = String.Empty; + +// if (item.ContactID > 0) +// { +// var contact = contactDao.GetByID(item.ContactID); + +// if (contact != null) +// contactTitle = contact.GetTitle(); +// } + +// dataTable.Rows.Add(new object[] +// { +// item.Title, +// item.Description, +// item.DeadLine == DateTime.MinValue +// ? "" +// : item.DeadLine.ToShortString(), +// UserManager.GetUsers(item.ResponsibleID).DisplayUserName(false,), +// contactTitle, +// item.IsClosed +// ? CRMTaskResource.TaskStatus_Closed +// : CRMTaskResource.TaskStatus_Open, +// listItemDao.GetByID(item.CategoryID).Title, +// entityTitle, +// item.AlertValue.ToString(CultureInfo.InvariantCulture) +// }); +// } + +// return DataTableToCsv(dataTable); +// } + +// private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, DaoFactory daoFactory) +// { +// var key = (string)Id; +// var taxes = daoFactory.GetInvoiceTaxDao().GetAll(); +// var dataTable = new DataTable(); + +// dataTable.Columns.AddRange(new[] +// { +// new DataColumn +// { +// Caption = (CRMInvoiceResource.InvoiceItemName), +// ColumnName = "title" +// }, +// new DataColumn +// { +// Caption = (CRMSettingResource.Description), +// ColumnName = "description" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.StockKeepingUnit), +// ColumnName = "sku" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.InvoiceItemPrice), +// ColumnName = "price" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.FormInvoiceItemStockQuantity), +// ColumnName = "stock_quantity" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.TrackInventory), +// ColumnName = "track_inventory" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.Currency), +// ColumnName = "currency" +// }, + +// new DataColumn +// { +// Caption = (CRMInvoiceResource.InvoiceTax1Name), +// ColumnName = "tax1_name" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.InvoiceTax1Rate), +// ColumnName = "tax1_rate" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.InvoiceTax2Name), +// ColumnName = "tax2_name" +// }, +// new DataColumn +// { +// Caption = (CRMInvoiceResource.InvoiceTax2Rate), +// ColumnName = "tax2_rate" +// } + +// }); + + +// foreach (var item in invoiceItems) +// { +// if (ExportDataCache.CheckCancelFlag(key)) +// { +// ExportDataCache.ResetAll(key); + +// throw new OperationCanceledException(); +// } + +// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + +// Percentage += 1.0 * 100 / _totalCount; + +// var tax1 = item.InvoiceTax1ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax1ID) : null; +// var tax2 = item.InvoiceTax2ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax2ID) : null; + +// dataTable.Rows.Add(new object[] +// { +// item.Title, +// item.Description, +// item.StockKeepingUnit, +// item.Price.ToString(CultureInfo.InvariantCulture), +// item.StockQuantity.ToString(CultureInfo.InvariantCulture), +// item.TrackInventory.ToString(), +// item.Currency, +// tax1 != null ? tax1.Name : "", +// tax1 != null ? tax1.Rate.ToString(CultureInfo.InvariantCulture) : "", +// tax2 != null ? tax2.Name : "", +// tax2 != null ? tax2.Rate.ToString(CultureInfo.InvariantCulture) : "" +// }); +// } + +// return DataTableToCsv(dataTable); +// } + +// private String SaveCsvFileInMyDocument(String title, String data) +// { +// string fileUrl; + +// using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(data))) +// { +// var file = FileUploader.Exec(GlobalFolder.GetFolderMy(FileMarker, FileDaoFactory).ToString(), title, memStream.Length, memStream, true); + +// if (FileUtility.CanWebView(title) || FileUtility.CanWebEdit(title)) +// { +// fileUrl = FilesLinkUtility.GetFileWebEditorUrl(file.ID); +// fileUrl += string.Format("&options={{\"delimiter\":{0},\"codePage\":{1}}}", +// (int)FileUtility.CsvDelimiter.Comma, +// Encoding.UTF8.CodePage); +// } +// else +// { +// fileUrl = FilesLinkUtility.GetFileDownloadUrl(file.ID); +// } +// } + +// return fileUrl; +// } +// } + +// public class ExportToCsv +// { +// private readonly object Locker = new object(); + +// private readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromSeconds(60), true); + +// public ExportToCsv(SecurityContext securityContext, +// ExportDataCache exportDataCache, +// TenantManager tenantManager) +// { +// SecurityContext = securityContext; +// ExportDataCache = exportDataCache; +// TenantID = tenantManager.GetCurrentTenant().TenantId; +// } + +// protected int TenantID { get; private set; } + +// public ExportDataCache ExportDataCache { get; } + +// public SecurityContext SecurityContext { get; } + +// public IProgressItem GetStatus(bool partialDataExport) +// { +// var key = GetKey(partialDataExport); + +// return Queue.GetStatus(key) ?? ExportDataCache.Get(key); +// } + +// public IProgressItem Start(FilterObject filterObject, string fileName) +// { +// lock (Locker) +// { +// var key = GetKey(filterObject != null); + +// var operation = Queue.GetStatus(key); + +// if (operation == null) +// { +// var fromCache = ExportDataCache.Get(key); + +// if (fromCache != null) +// return fromCache; +// } + +// if (operation == null) +// { +// operation = new ExportDataOperation(filterObject, fileName); + +// Queue.Add(operation); +// } + +// if (!Queue.IsStarted) +// Queue.Start(x => x.RunJob()); + +// return operation; +// } +// } + +// public void Cancel(bool partialDataExport) +// { +// lock (Locker) +// { +// var key = GetKey(partialDataExport); + +// var findedItem = Queue.GetItems().FirstOrDefault(elem => (string)elem.Id == key); + +// if (findedItem != null) +// { +// Queue.Remove(findedItem); +// } + +// ExportDataCache.SetCancelFlag(key); +// } +// } + +// public string GetKey(bool partialDataExport) +// { +// return string.Format("{0}_{1}", TenantID, +// partialDataExport ? SecurityContext.CurrentAccount.ID : Guid.Empty); +// } + +// public String ExportItems(FilterObject filterObject, string fileName) +// { +// var operation = new ExportDataOperation(filterObject, fileName); + +// operation.RunJob(); + +// return operation.FileUrl; +// } +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index b56503d49e7..6627c2af8cb 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -47,14 +47,16 @@ namespace ASC.Web.CRM.Classes { public class ImportDataCache { - public ImportDataCache(TenantManager tenantManager) + public ImportDataCache(TenantManager tenantManager, + ICache cache) { - TenantID = tenantManager.CurrentTenant.TenantId; + TenantID = tenantManager.GetCurrentTenant().TenantId; + Cache = cache; } public int TenantID { get; } - public readonly ICache Cache = AscCache.Memory; + public readonly ICache Cache; public String GetStateCacheKey(EntityType entityType, int tenantId = -1) { @@ -139,7 +141,7 @@ DaoFactory daoFactory SecurityContext = securityContext; _dataStore = global.GetStore(); - _tenantID = tenantManager.CurrentTenant.TenantId; + _tenantID = tenantManager.GetCurrentTenant().TenantId; _author = SecurityContext.CurrentAccount; NotifyClient = notifyClient; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index 768d998fca7..9a56a99d8d0 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -41,7 +41,7 @@ public class ImportFromCSV public ImportFromCSV(TenantManager tenantProvider, ImportDataCache importDataCache) { - TenantId = tenantProvider.CurrentTenant.TenantId; + TenantId = tenantProvider.GetCurrentTenant().TenantId; ImportDataCache = importDataCache; } diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index e579e14df88..0709c8f7f96 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -1,387 +1,387 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -#region Import - -using ASC.Common.Caching; -using ASC.Common.Logging; -using ASC.Common.Threading.Progress; -using ASC.Core; -using ASC.Core.Common.Settings; -using ASC.Core.Tenants; -using ASC.CRM.Classes; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.CRM.Resources; -using ASC.Web.CRM.Core; -using ASC.Web.Files.Api; -using Autofac; -using MailKit; -using MailKit.Net.Smtp; -using MailKit.Security; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Options; -using MimeKit; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.Sockets; -using System.Runtime.Serialization; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading; -using File = System.IO.File; -using SmtpClient = MailKit.Net.Smtp.SmtpClient; - -#endregion - -namespace ASC.Web.CRM.Classes -{ - public class SendBatchEmailsOperation : IProgressItem, IDisposable - { - private readonly bool _storeInHistory; - private readonly ILog _log; - private readonly SMTPServerSetting _smtpSetting; - private readonly Guid _currUser; - private readonly int _tenantID; - private readonly List _contactID; - private readonly String _subject; - private readonly String _bodyTempate; - private readonly List _fileID; - private int historyCategory; - private double _exactPercentageValue = 0; - - public object Id { get; set; } - public object Status { get; set; } - public object Error { get; set; } - public double Percentage { get; set; } - public bool IsCompleted { get; set; } - - private SendBatchEmailsOperation() - { - } - - public SendBatchEmailsOperation( - List fileID, - List contactID, - String subject, - String bodyTempate, - bool storeInHistory, - TenantUtil tenantUtil, - IOptionsMonitor logger, - Global global, - SecurityContext securityContext, - TenantManager tenantManager, - UserManager userManager, - AuthManager authManager, - SettingsManager settingsManager, - MailSenderDataCache mailSenderDataCache - ) - { - TenantUtil = tenantUtil; - SecurityContext = securityContext; - - Percentage = 0; - - _fileID = fileID; - _contactID = contactID; - _subject = subject; - _bodyTempate = bodyTempate; - - _log = logger.Get("ASC.CRM.MailSender"); - - _tenantID = tenantManager.GetCurrentTenant().TenantId; - _smtpSetting = settingsManager.Load().SMTPServerSetting; - _currUser = SecurityContext.CurrentAccount.ID; - _storeInHistory = storeInHistory; - - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = 0, - DeliveryCount = 0 - }; - - AuthManager = authManager; - UserManager = userManager; - MailSenderDataCache = mailSenderDataCache; - } - - public FilesIntegration FilesIntegration { get; } - - public MailSenderDataCache MailSenderDataCache { get; } - public AuthManager AuthManager { get; } - - public UserManager UserManager { get; } - - public TenantManager TenantManager { get; } - - public SecurityContext SecurityContext { get; } - - public TenantUtil TenantUtil { get; } - - private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) - { - if (contactID == 0 || String.IsNullOrEmpty(content)) return; - - var historyEvent = new RelationshipEvent() - { - ContactID = contactID, - Content = content, - CreateBy = _currUser, - CreateOn = TenantUtil.DateTimeNow(), - }; - if (historyCategory == 0) - { - var listItemDao = _daoFactory.GetListItemDao(); - - // HACK - var listItem = listItemDao.GetItems(ListType.HistoryCategory).Find(item => item.AdditionalParams == "event_category_email.png"); - if (listItem == null) - { - listItemDao.CreateItem( - ListType.HistoryCategory, - new ListItem { AdditionalParams = "event_category_email.png", Title = CRMCommonResource.HistoryCategory_Note }); - } - historyCategory = listItem.ID; - } - - historyEvent.CategoryID = historyCategory; - - var relationshipEventDao = _daoFactory.GetRelationshipEventDao(); - - historyEvent = relationshipEventDao.CreateItem(historyEvent); - - if (historyEvent.ID > 0 && _fileID != null && _fileID.Count > 0) - { - relationshipEventDao.AttachFiles(historyEvent.ID, _fileID.ToArray()); - } - } - - public void RunJob() - { - SmtpClient smtpClient = null; - try - { - TenantManager.SetCurrentTenant(_tenantID); - SecurityContext.AuthenticateMe(AuthManager.GetAccountByID(_tenantID, _currUser)); - - smtpClient = GetSmtpClient(); - - var userCulture = UserManager.GetUsers(_currUser).GetCulture(); - - Thread.CurrentThread.CurrentCulture = userCulture; - Thread.CurrentThread.CurrentUICulture = userCulture; +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//#region Import + +//using ASC.Common.Caching; +//using ASC.Common.Logging; +//using ASC.Common.Threading.Progress; +//using ASC.Core; +//using ASC.Core.Common.Settings; +//using ASC.Core.Tenants; +//using ASC.CRM.Classes; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Dao; +//using ASC.CRM.Core.Entities; +//using ASC.CRM.Core.Enums; +//using ASC.CRM.Resources; +//using ASC.Web.CRM.Core; +//using ASC.Web.Files.Api; +//using Autofac; +//using MailKit; +//using MailKit.Net.Smtp; +//using MailKit.Security; +//using Microsoft.Extensions.Configuration; +//using Microsoft.Extensions.Options; +//using MimeKit; +//using Newtonsoft.Json.Linq; +//using System; +//using System.Collections.Generic; +//using System.IO; +//using System.Linq; +//using System.Net.Sockets; +//using System.Runtime.Serialization; +//using System.Text; +//using System.Text.RegularExpressions; +//using System.Threading; +//using File = System.IO.File; +//using SmtpClient = MailKit.Net.Smtp.SmtpClient; + +//#endregion + +//namespace ASC.Web.CRM.Classes +//{ +// public class SendBatchEmailsOperation : IProgressItem, IDisposable +// { +// private readonly bool _storeInHistory; +// private readonly ILog _log; +// private readonly SMTPServerSetting _smtpSetting; +// private readonly Guid _currUser; +// private readonly int _tenantID; +// private readonly List _contactID; +// private readonly String _subject; +// private readonly String _bodyTempate; +// private readonly List _fileID; +// private int historyCategory; +// private double _exactPercentageValue = 0; + +// public object Id { get; set; } +// public object Status { get; set; } +// public object Error { get; set; } +// public double Percentage { get; set; } +// public bool IsCompleted { get; set; } + +// private SendBatchEmailsOperation() +// { +// } + +// public SendBatchEmailsOperation( +// List fileID, +// List contactID, +// String subject, +// String bodyTempate, +// bool storeInHistory, +// TenantUtil tenantUtil, +// IOptionsMonitor logger, +// Global global, +// SecurityContext securityContext, +// TenantManager tenantManager, +// UserManager userManager, +// AuthManager authManager, +// SettingsManager settingsManager, +// MailSenderDataCache mailSenderDataCache +// ) +// { +// TenantUtil = tenantUtil; +// SecurityContext = securityContext; + +// Percentage = 0; + +// _fileID = fileID; +// _contactID = contactID; +// _subject = subject; +// _bodyTempate = bodyTempate; + +// _log = logger.Get("ASC.CRM.MailSender"); + +// _tenantID = tenantManager.GetCurrentTenant().TenantId; +// _smtpSetting = settingsManager.Load().SMTPServerSetting; +// _currUser = SecurityContext.CurrentAccount.ID; +// _storeInHistory = storeInHistory; + +// Status = new +// { +// RecipientCount = _contactID.Count, +// EstimatedTime = 0, +// DeliveryCount = 0 +// }; + +// AuthManager = authManager; +// UserManager = userManager; +// MailSenderDataCache = mailSenderDataCache; +// } + +// public FilesIntegration FilesIntegration { get; } + +// public MailSenderDataCache MailSenderDataCache { get; } +// public AuthManager AuthManager { get; } + +// public UserManager UserManager { get; } + +// public TenantManager TenantManager { get; } + +// public SecurityContext SecurityContext { get; } + +// public TenantUtil TenantUtil { get; } + +// private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) +// { +// if (contactID == 0 || String.IsNullOrEmpty(content)) return; + +// var historyEvent = new RelationshipEvent() +// { +// ContactID = contactID, +// Content = content, +// CreateBy = _currUser, +// CreateOn = TenantUtil.DateTimeNow(), +// }; +// if (historyCategory == 0) +// { +// var listItemDao = _daoFactory.GetListItemDao(); + +// // HACK +// var listItem = listItemDao.GetItems(ListType.HistoryCategory).Find(item => item.AdditionalParams == "event_category_email.png"); +// if (listItem == null) +// { +// listItemDao.CreateItem( +// ListType.HistoryCategory, +// new ListItem { AdditionalParams = "event_category_email.png", Title = CRMCommonResource.HistoryCategory_Note }); +// } +// historyCategory = listItem.ID; +// } + +// historyEvent.CategoryID = historyCategory; + +// var relationshipEventDao = _daoFactory.GetRelationshipEventDao(); + +// historyEvent = relationshipEventDao.CreateItem(historyEvent); + +// if (historyEvent.ID > 0 && _fileID != null && _fileID.Count > 0) +// { +// relationshipEventDao.AttachFiles(historyEvent.ID, _fileID.ToArray()); +// } +// } + +// public void RunJob() +// { +// SmtpClient smtpClient = null; +// try +// { +// TenantManager.SetCurrentTenant(_tenantID); +// SecurityContext.AuthenticateMe(AuthManager.GetAccountByID(_tenantID, _currUser)); + +// smtpClient = GetSmtpClient(); + +// var userCulture = UserManager.GetUsers(_currUser).GetCulture(); + +// Thread.CurrentThread.CurrentCulture = userCulture; +// Thread.CurrentThread.CurrentUICulture = userCulture; - var contactCount = _contactID.Count; +// var contactCount = _contactID.Count; - if (contactCount == 0) - { - Complete(); - return; - } +// if (contactCount == 0) +// { +// Complete(); +// return; +// } - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); +// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); - var filePaths = new List(); - var fileDao = FilesIntegration.DaoFactory.GetFileDao(); +// var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); +// var filePaths = new List(); +// var fileDao = FilesIntegration.DaoFactory.GetFileDao(); - foreach (var fileID in _fileID) - { - var fileObj = fileDao.GetFile(fileID); - if (fileObj == null) continue; - using (var fileStream = fileDao.GetFileStream(fileObj)) - { - var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), - "crm/files/mailsender/"); +// foreach (var fileID in _fileID) +// { +// var fileObj = fileDao.GetFile(fileID); +// if (fileObj == null) continue; +// using (var fileStream = fileDao.GetFileStream(fileObj)) +// { +// var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), +// "crm/files/mailsender/"); - if (!Directory.Exists(directoryPath)) - { - Directory.CreateDirectory(directoryPath); - } +// if (!Directory.Exists(directoryPath)) +// { +// Directory.CreateDirectory(directoryPath); +// } - var filePath = Path.Combine(directoryPath, fileObj.Title); +// var filePath = Path.Combine(directoryPath, fileObj.Title); - using (var newFileStream = File.Create(filePath)) - { - fileStream.StreamCopyTo(newFileStream); - } +// using (var newFileStream = File.Create(filePath)) +// { +// fileStream.StreamCopyTo(newFileStream); +// } - filePaths.Add(filePath); +// filePaths.Add(filePath); - } - } +// } +// } - var templateManager = new MailTemplateManager(DaoFactory); - var deliveryCount = 0; +// var templateManager = new MailTemplateManager(DaoFactory); +// var deliveryCount = 0; - try - { - Error = string.Empty; - foreach (var contactID in _contactID) - { - _exactPercentageValue += 100.0 / contactCount; - Percentage = Math.Round(_exactPercentageValue); +// try +// { +// Error = string.Empty; +// foreach (var contactID in _contactID) +// { +// _exactPercentageValue += 100.0 / contactCount; +// Percentage = Math.Round(_exactPercentageValue); - if (IsCompleted) break; // User selected cancel +// if (IsCompleted) break; // User selected cancel - var contactInfoDao = DaoFactory.GetContactInfoDao(); +// var contactInfoDao = DaoFactory.GetContactInfoDao(); - var startDate = DateTime.Now; +// var startDate = DateTime.Now; - var contactEmails = contactInfoDao.GetList(contactID, ContactInfoType.Email, null, true); - if (contactEmails.Count == 0) - { - continue; - } +// var contactEmails = contactInfoDao.GetList(contactID, ContactInfoType.Email, null, true); +// if (contactEmails.Count == 0) +// { +// continue; +// } - var recipientEmail = contactEmails[0].Data; +// var recipientEmail = contactEmails[0].Data; - if (!recipientEmail.TestEmailRegex()) - { - Error += string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail) + - "
    "; - continue; - } +// if (!recipientEmail.TestEmailRegex()) +// { +// Error += string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail) + +// "
    "; +// continue; +// } - var to = new MailboxAddress(recipientEmail); +// var to = new MailboxAddress(recipientEmail); - var mimeMessage = new MimeMessage - { - Subject = _subject - }; - - mimeMessage.From.Add(from); - mimeMessage.To.Add(to); - - var bodyBuilder = new BodyBuilder - { - HtmlBody = templateManager.Apply(_bodyTempate, contactID) - }; +// var mimeMessage = new MimeMessage +// { +// Subject = _subject +// }; + +// mimeMessage.From.Add(from); +// mimeMessage.To.Add(to); + +// var bodyBuilder = new BodyBuilder +// { +// HtmlBody = templateManager.Apply(_bodyTempate, contactID) +// }; - foreach (var filePath in filePaths) - { - bodyBuilder.Attachments.Add(filePath); - } +// foreach (var filePath in filePaths) +// { +// bodyBuilder.Attachments.Add(filePath); +// } - mimeMessage.Body = bodyBuilder.ToMessageBody(); +// mimeMessage.Body = bodyBuilder.ToMessageBody(); - mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); +// mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); - _log.Debug(GetLoggerRow(mimeMessage)); +// _log.Debug(GetLoggerRow(mimeMessage)); - var success = false; +// var success = false; - try - { - smtpClient.Send(mimeMessage); +// try +// { +// smtpClient.Send(mimeMessage); - success = true; - } - catch (SmtpCommandException ex) - { - _log.Error(Error, ex); +// success = true; +// } +// catch (SmtpCommandException ex) +// { +// _log.Error(Error, ex); - Error += string.Format(CRMCommonResource.MailSender_FailedDeliverException, recipientEmail) + "
    "; - } +// Error += string.Format(CRMCommonResource.MailSender_FailedDeliverException, recipientEmail) + "
    "; +// } - if (success) - { - if (_storeInHistory) - { - AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), DaoFactory); - } +// if (success) +// { +// if (_storeInHistory) +// { +// AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), DaoFactory); +// } - var endDate = DateTime.Now; - var waitInterval = endDate.Subtract(startDate); +// var endDate = DateTime.Now; +// var waitInterval = endDate.Subtract(startDate); - deliveryCount++; +// deliveryCount++; - var estimatedTime = - TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); +// var estimatedTime = +// TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = estimatedTime.ToString(), - DeliveryCount = deliveryCount - }; - } +// Status = new +// { +// RecipientCount = _contactID.Count, +// EstimatedTime = estimatedTime.ToString(), +// DeliveryCount = deliveryCount +// }; +// } - if (MailSenderDataCache.CheckCancelFlag()) - { - MailSenderDataCache.ResetAll(); +// if (MailSenderDataCache.CheckCancelFlag()) +// { +// MailSenderDataCache.ResetAll(); - throw new OperationCanceledException(); - } +// throw new OperationCanceledException(); +// } - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); +// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - if (Percentage > 100) - { - Percentage = 100; +// if (Percentage > 100) +// { +// Percentage = 100; - if (MailSenderDataCache.CheckCancelFlag()) - { - MailSenderDataCache.ResetAll(); +// if (MailSenderDataCache.CheckCancelFlag()) +// { +// MailSenderDataCache.ResetAll(); - throw new OperationCanceledException(); - } +// throw new OperationCanceledException(); +// } - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); +// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - } - } - } - catch (OperationCanceledException) - { - _log.Debug("cancel mail sender"); - } - finally - { - foreach (var filePath in filePaths) - { - if (File.Exists(filePath)) - { - File.Delete(filePath); - } - } - } +// } +// } +// } +// catch (OperationCanceledException) +// { +// _log.Debug("cancel mail sender"); +// } +// finally +// { +// foreach (var filePath in filePaths) +// { +// if (File.Exists(filePath)) +// { +// File.Delete(filePath); +// } +// } +// } - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = TimeSpan.Zero.ToString(), - DeliveryCount = deliveryCount - }; +// Status = new +// { +// RecipientCount = _contactID.Count, +// EstimatedTime = TimeSpan.Zero.ToString(), +// DeliveryCount = deliveryCount +// }; @@ -418,668 +418,668 @@ public void RunJob() - } - catch (SocketException e) - { - Error = e.Message; - _log.Error(Error); - } - finally - { - if (smtpClient != null) - { - smtpClient.Dispose(); - } - Complete(); - } - } +// } +// catch (SocketException e) +// { +// Error = e.Message; +// _log.Error(Error); +// } +// finally +// { +// if (smtpClient != null) +// { +// smtpClient.Dispose(); +// } +// Complete(); +// } +// } - public string GetLoggerRow(MimeMessage mailMessage) - { - if (mailMessage == null) - return String.Empty; +// public string GetLoggerRow(MimeMessage mailMessage) +// { +// if (mailMessage == null) +// return String.Empty; - var result = new StringBuilder(); +// var result = new StringBuilder(); - result.AppendLine("From:" + mailMessage.From); - result.AppendLine("To:" + mailMessage.To[0]); - result.AppendLine("Subject:" + mailMessage.Subject); - result.AppendLine("Body:" + mailMessage.Body); - result.AppendLine("TenantID:" + _tenantID); +// result.AppendLine("From:" + mailMessage.From); +// result.AppendLine("To:" + mailMessage.To[0]); +// result.AppendLine("Subject:" + mailMessage.Subject); +// result.AppendLine("Body:" + mailMessage.Body); +// result.AppendLine("TenantID:" + _tenantID); - foreach (var attachment in mailMessage.Attachments) - { - result.AppendLine("Attachment: " + attachment.ContentDisposition.FileName); - } +// foreach (var attachment in mailMessage.Attachments) +// { +// result.AppendLine("Attachment: " + attachment.ContentDisposition.FileName); +// } - return result.ToString(); - } +// return result.ToString(); +// } - public object Clone() - { - var cloneObj = new SendBatchEmailsOperation(); +// public object Clone() +// { +// var cloneObj = new SendBatchEmailsOperation(); - cloneObj.Error = Error; - cloneObj.Id = Id; - cloneObj.IsCompleted = IsCompleted; - cloneObj.Percentage = Percentage; - cloneObj.Status = Status; +// cloneObj.Error = Error; +// cloneObj.Id = Id; +// cloneObj.IsCompleted = IsCompleted; +// cloneObj.Percentage = Percentage; +// cloneObj.Status = Status; - return cloneObj; - } +// return cloneObj; +// } - private void DeleteFiles() - { - if (_fileID == null || _fileID.Count == 0) return; +// private void DeleteFiles() +// { +// if (_fileID == null || _fileID.Count == 0) return; - var fileDao = FilesIntegration.DaoFactory.GetFileDao(); +// var fileDao = FilesIntegration.DaoFactory.GetFileDao(); - foreach (var fileID in _fileID) - { - var fileObj = fileDao.GetFile(fileID); - if (fileObj == null) continue; +// foreach (var fileID in _fileID) +// { +// var fileObj = fileDao.GetFile(fileID); +// if (fileObj == null) continue; - fileDao.DeleteFile(fileObj.ID); - } +// fileDao.DeleteFile(fileObj.ID); +// } - } +// } - private SmtpClient GetSmtpClient() - { - var client = new SmtpClient - { - ServerCertificateValidationCallback = (sender, certificate, chain, errors) => - WorkContext.IsMono || MailKit.MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), - Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds - }; +// private SmtpClient GetSmtpClient() +// { +// var client = new SmtpClient +// { +// ServerCertificateValidationCallback = (sender, certificate, chain, errors) => +// WorkContext.IsMono || MailKit.MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), +// Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds +// }; - client.Connect(_smtpSetting.Host, _smtpSetting.Port, - _smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); +// client.Connect(_smtpSetting.Host, _smtpSetting.Port, +// _smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); - if (_smtpSetting.RequiredHostAuthentication) - { - client.Authenticate(_smtpSetting.HostLogin, _smtpSetting.HostPassword); - } +// if (_smtpSetting.RequiredHostAuthentication) +// { +// client.Authenticate(_smtpSetting.HostLogin, _smtpSetting.HostPassword); +// } - return client; - } +// return client; +// } - private void Complete() - { - IsCompleted = true; - Percentage = 100; - _log.Debug("Completed"); +// private void Complete() +// { +// IsCompleted = true; +// Percentage = 100; +// _log.Debug("Completed"); - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - - Thread.Sleep(10000); - MailSenderDataCache.ResetAll(); - } - - public override bool Equals(object obj) - { - if (obj == null || !(obj is SendBatchEmailsOperation)) return false; - - var curOperation = (SendBatchEmailsOperation)obj; - return (curOperation.Id == Id) && (curOperation._tenantID == _tenantID); - } - - public override int GetHashCode() - { - return Id.GetHashCode() ^ _tenantID.GetHashCode(); - } - - public void Dispose() - { - DeleteFiles(); - } - } - - public class MailSenderDataCache - { - public MailSenderDataCache(TenantManager tenantManager) - { - TenantID = tenantManager.GetCurrentTenant().TenantId; - } - - public int TenantID { get; } - - public readonly ICache Cache = AscCache.Memory; - - public string GetStateCacheKey() - { - return string.Format("{0}:crm:queue:sendbatchemails", TenantID); - } - - public string GetCancelCacheKey() - { - return string.Format("{0}:crm:queue:sendbatchemails:cancel", TenantID); - } - - public SendBatchEmailsOperation Get() - { - return Cache.Get(GetStateCacheKey()); - } - - public void Insert(SendBatchEmailsOperation data) - { - Cache.Insert(GetStateCacheKey(), data, TimeSpan.FromMinutes(1)); - } - - public bool CheckCancelFlag() - { - var fromCache = Cache.Get(GetCancelCacheKey()); - - if (!String.IsNullOrEmpty(fromCache)) - return true; - - return false; - - } - - public void SetCancelFlag() - { - Cache.Insert(GetCancelCacheKey(), "true", TimeSpan.FromMinutes(1)); - } - - public void ResetAll() - { - Cache.Remove(GetStateCacheKey()); - Cache.Remove(GetCancelCacheKey()); - } - } - - public class MailSender - { - private readonly Object _syncObj = new Object(); - private readonly ProgressQueue _mailQueue = new ProgressQueue(2, TimeSpan.FromSeconds(60), true); - private readonly int quotas = 50; - - public MailSender( - IConfiguration configuration, - TenantManager tenantManager, - SettingsManager settingsManager, - MailSenderDataCache mailSenderDataCache - ) - { - TenantID = tenantManager.GetCurrentTenant().TenantId; - MailSenderDataCache = mailSenderDataCache; - - int parsed; - - if (int.TryParse(configuration["crm:mailsender:quotas"], out parsed)) - { - quotas = parsed; - } - - TenantManager = tenantManager; - SettingsManager = settingsManager; - - // LogManager = logger.Get(); - } - - public TenantManager TenantManager { get; } - public SettingsManager SettingsManager { get; } - - public MailSenderDataCache MailSenderDataCache { get; } - public int TenantID { get; } - - public IOptionsMonitor LogManager { get; } - - public int GetQuotas() - { - return quotas; - } - - public IProgressItem Start(List fileID, List contactID, String subject, String bodyTemplate, bool storeInHistory) - { - lock (_syncObj) - { - var operation = _mailQueue.GetStatus(TenantID); - - if (operation == null) - { - var mailSender = MailSenderDataCache.Get(); - - if (mailSender != null) - return mailSender; - } - - if (operation == null) - { - if (fileID == null) - { - fileID = new List(); - } - if (contactID == null || contactID.Count == 0 || - String.IsNullOrEmpty(subject) || String.IsNullOrEmpty(bodyTemplate)) - { - return null; - } - - if (contactID.Count > GetQuotas()) - { - contactID = contactID.Take(GetQuotas()).ToList(); - } - - operation = new SendBatchEmailsOperation(fileID, contactID, subject, bodyTemplate, storeInHistory); - _mailQueue.Add(operation); - } - - if (!_mailQueue.IsStarted) - { - _mailQueue.Start(x => x.RunJob()); - } - return operation; - } - } - - private SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) - { - var client = new SmtpClient - { - ServerCertificateValidationCallback = (sender, certificate, chain, errors) => MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), - Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds - }; - - client.Connect(smtpSetting.Host, smtpSetting.Port, - smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); - - if (smtpSetting.RequiredHostAuthentication) - { - client.Authenticate(smtpSetting.HostLogin, smtpSetting.HostPassword); - } - - return client; - } - - public void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) - { - var log = LogManager.Get("ASC.CRM.MailSender"); - - if (!recipientEmail.TestEmailRegex()) - { - throw new Exception(string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail)); - } - - TenantManager.SetCurrentTenant(TenantID); - var smtpSetting = SettingsManager.Load().SMTPServerSetting; - - ThreadPool.QueueUserWorkItem(_ => - { - try - { - var toAddress = new MailboxAddress(recipientEmail); - var fromAddress = new MailboxAddress(smtpSetting.SenderDisplayName, smtpSetting.SenderEmailAddress); - - var mimeMessage = new MimeMessage - { - Subject = mailSubj - }; - - mimeMessage.From.Add(fromAddress); - - mimeMessage.To.Add(toAddress); - - var bodyBuilder = new BodyBuilder - { - TextBody = mailBody - }; - - mimeMessage.Body = bodyBuilder.ToMessageBody(); - - mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); - - using (var smtpClient = GetSmtpClient(smtpSetting)) - { - smtpClient.Send(FormatOptions.Default, mimeMessage, CancellationToken.None); - } - } - catch (Exception ex) - { - log.Error(ex); - } - }); - } - - public IProgressItem GetStatus() - { - var result = _mailQueue.GetStatus(TenantID); - - if (result == null) - return MailSenderDataCache.Get(); - - return result; - } +// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); + +// Thread.Sleep(10000); +// MailSenderDataCache.ResetAll(); +// } + +// public override bool Equals(object obj) +// { +// if (obj == null || !(obj is SendBatchEmailsOperation)) return false; + +// var curOperation = (SendBatchEmailsOperation)obj; +// return (curOperation.Id == Id) && (curOperation._tenantID == _tenantID); +// } + +// public override int GetHashCode() +// { +// return Id.GetHashCode() ^ _tenantID.GetHashCode(); +// } + +// public void Dispose() +// { +// DeleteFiles(); +// } +// } + +// public class MailSenderDataCache +// { +// public MailSenderDataCache(TenantManager tenantManager) +// { +// TenantID = tenantManager.GetCurrentTenant().TenantId; +// } + +// public int TenantID { get; } + +// public readonly ICache Cache = ICache.Memory; + +// public string GetStateCacheKey() +// { +// return string.Format("{0}:crm:queue:sendbatchemails", TenantID); +// } + +// public string GetCancelCacheKey() +// { +// return string.Format("{0}:crm:queue:sendbatchemails:cancel", TenantID); +// } + +// public SendBatchEmailsOperation Get() +// { +// return Cache.Get(GetStateCacheKey()); +// } + +// public void Insert(SendBatchEmailsOperation data) +// { +// Cache.Insert(GetStateCacheKey(), data, TimeSpan.FromMinutes(1)); +// } + +// public bool CheckCancelFlag() +// { +// var fromCache = Cache.Get(GetCancelCacheKey()); + +// if (!String.IsNullOrEmpty(fromCache)) +// return true; + +// return false; + +// } + +// public void SetCancelFlag() +// { +// Cache.Insert(GetCancelCacheKey(), "true", TimeSpan.FromMinutes(1)); +// } + +// public void ResetAll() +// { +// Cache.Remove(GetStateCacheKey()); +// Cache.Remove(GetCancelCacheKey()); +// } +// } + +// public class MailSender +// { +// private readonly Object _syncObj = new Object(); +// private readonly ProgressQueue _mailQueue = new ProgressQueue(2, TimeSpan.FromSeconds(60), true); +// private readonly int quotas = 50; + +// public MailSender( +// IConfiguration configuration, +// TenantManager tenantManager, +// SettingsManager settingsManager, +// MailSenderDataCache mailSenderDataCache +// ) +// { +// TenantID = tenantManager.GetCurrentTenant().TenantId; +// MailSenderDataCache = mailSenderDataCache; + +// int parsed; + +// if (int.TryParse(configuration["crm:mailsender:quotas"], out parsed)) +// { +// quotas = parsed; +// } + +// TenantManager = tenantManager; +// SettingsManager = settingsManager; + +// // LogManager = logger.Get(); +// } + +// public TenantManager TenantManager { get; } +// public SettingsManager SettingsManager { get; } + +// public MailSenderDataCache MailSenderDataCache { get; } +// public int TenantID { get; } + +// public IOptionsMonitor LogManager { get; } + +// public int GetQuotas() +// { +// return quotas; +// } + +// public IProgressItem Start(List fileID, List contactID, String subject, String bodyTemplate, bool storeInHistory) +// { +// lock (_syncObj) +// { +// var operation = _mailQueue.GetStatus(TenantID); + +// if (operation == null) +// { +// var mailSender = MailSenderDataCache.Get(); + +// if (mailSender != null) +// return mailSender; +// } + +// if (operation == null) +// { +// if (fileID == null) +// { +// fileID = new List(); +// } +// if (contactID == null || contactID.Count == 0 || +// String.IsNullOrEmpty(subject) || String.IsNullOrEmpty(bodyTemplate)) +// { +// return null; +// } + +// if (contactID.Count > GetQuotas()) +// { +// contactID = contactID.Take(GetQuotas()).ToList(); +// } + +// operation = new SendBatchEmailsOperation(fileID, contactID, subject, bodyTemplate, storeInHistory); +// _mailQueue.Add(operation); +// } + +// if (!_mailQueue.IsStarted) +// { +// _mailQueue.Start(x => x.RunJob()); +// } +// return operation; +// } +// } + +// private SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) +// { +// var client = new SmtpClient +// { +// ServerCertificateValidationCallback = (sender, certificate, chain, errors) => MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), +// Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds +// }; + +// client.Connect(smtpSetting.Host, smtpSetting.Port, +// smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); + +// if (smtpSetting.RequiredHostAuthentication) +// { +// client.Authenticate(smtpSetting.HostLogin, smtpSetting.HostPassword); +// } + +// return client; +// } + +// public void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) +// { +// var log = LogManager.Get("ASC.CRM.MailSender"); + +// if (!recipientEmail.TestEmailRegex()) +// { +// throw new Exception(string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail)); +// } + +// TenantManager.SetCurrentTenant(TenantID); +// var smtpSetting = SettingsManager.Load().SMTPServerSetting; + +// ThreadPool.QueueUserWorkItem(_ => +// { +// try +// { +// var toAddress = new MailboxAddress(recipientEmail); +// var fromAddress = new MailboxAddress(smtpSetting.SenderDisplayName, smtpSetting.SenderEmailAddress); + +// var mimeMessage = new MimeMessage +// { +// Subject = mailSubj +// }; + +// mimeMessage.From.Add(fromAddress); + +// mimeMessage.To.Add(toAddress); + +// var bodyBuilder = new BodyBuilder +// { +// TextBody = mailBody +// }; + +// mimeMessage.Body = bodyBuilder.ToMessageBody(); + +// mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); + +// using (var smtpClient = GetSmtpClient(smtpSetting)) +// { +// smtpClient.Send(FormatOptions.Default, mimeMessage, CancellationToken.None); +// } +// } +// catch (Exception ex) +// { +// log.Error(ex); +// } +// }); +// } + +// public IProgressItem GetStatus() +// { +// var result = _mailQueue.GetStatus(TenantID); + +// if (result == null) +// return MailSenderDataCache.Get(); + +// return result; +// } - public void Cancel() - { - lock (_syncObj) - { - var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantID); +// public void Cancel() +// { +// lock (_syncObj) +// { +// var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantID); - if (findedItem.Any()) - { - _mailQueue.Remove(findedItem.ElementAt(0)); +// if (findedItem.Any()) +// { +// _mailQueue.Remove(findedItem.ElementAt(0)); - MailSenderDataCache.ResetAll(); - } - else - { - MailSenderDataCache.SetCancelFlag(); - } - } - } - } +// MailSenderDataCache.ResetAll(); +// } +// else +// { +// MailSenderDataCache.SetCancelFlag(); +// } +// } +// } +// } - [Serializable] - [DataContract] - public class MailTemplateTag - { - [DataMember(Name = "sysname")] - public String SysName { get; set; } +// [Serializable] +// [DataContract] +// public class MailTemplateTag +// { +// [DataMember(Name = "sysname")] +// public String SysName { get; set; } - [DataMember(Name = "display_name")] - public String DisplayName { get; set; } +// [DataMember(Name = "display_name")] +// public String DisplayName { get; set; } - [DataMember(Name = "category")] - public String Category { get; set; } +// [DataMember(Name = "category")] +// public String Category { get; set; } - [DataMember(Name = "is_company")] - public bool isCompany { get; set; } +// [DataMember(Name = "is_company")] +// public bool isCompany { get; set; } - [DataMember(Name = "name")] - public String Name { get; set; } - } +// [DataMember(Name = "name")] +// public String Name { get; set; } +// } - public class MailTemplateManager - { - private readonly Dictionary> _templateTagsCache = new Dictionary>(); +// public class MailTemplateManager +// { +// private readonly Dictionary> _templateTagsCache = new Dictionary>(); - private readonly DaoFactory _daoFactory; +// private readonly DaoFactory _daoFactory; - public MailTemplateManager(DaoFactory daoFactory) - { - _daoFactory = daoFactory; - } +// public MailTemplateManager(DaoFactory daoFactory) +// { +// _daoFactory = daoFactory; +// } - private IEnumerable GetTagsFrom(String template) - { - if (_templateTagsCache.ContainsKey(template)) return _templateTagsCache[template]; +// private IEnumerable GetTagsFrom(String template) +// { +// if (_templateTagsCache.ContainsKey(template)) return _templateTagsCache[template]; - var tags = GetAllTags(); +// var tags = GetAllTags(); - var result = new List(); +// var result = new List(); - var _regex = new Regex("\\$\\((Person|Company)\\.[^<>\\)]*\\)"); +// var _regex = new Regex("\\$\\((Person|Company)\\.[^<>\\)]*\\)"); - if (!_regex.IsMatch(template)) - return new List(); +// if (!_regex.IsMatch(template)) +// return new List(); - foreach (Match match in _regex.Matches(template)) - { - var findedTag = tags.Find(item => String.Compare(item.Name, match.Value) == 0); +// foreach (Match match in _regex.Matches(template)) +// { +// var findedTag = tags.Find(item => String.Compare(item.Name, match.Value) == 0); - if (findedTag == null) continue; +// if (findedTag == null) continue; - if (!result.Contains(findedTag)) - result.Add(findedTag); - } +// if (!result.Contains(findedTag)) +// result.Add(findedTag); +// } - _templateTagsCache.Add(template, result); +// _templateTagsCache.Add(template, result); - return result; - } +// return result; +// } - private String Apply(String template, IEnumerable templateTags, int contactID) - { - var result = template; +// private String Apply(String template, IEnumerable templateTags, int contactID) +// { +// var result = template; - var contactDao = _daoFactory.GetContactDao(); - var contactInfoDao = _daoFactory.GetContactInfoDao(); - var customFieldDao = _daoFactory.GetCustomFieldDao(); +// var contactDao = _daoFactory.GetContactDao(); +// var contactInfoDao = _daoFactory.GetContactInfoDao(); +// var customFieldDao = _daoFactory.GetCustomFieldDao(); - var contact = contactDao.GetByID(contactID); +// var contact = contactDao.GetByID(contactID); - if (contact == null) - throw new ArgumentException(CRMErrorsResource.ContactNotFound); +// if (contact == null) +// throw new ArgumentException(CRMErrorsResource.ContactNotFound); - foreach (var tag in templateTags) - { - var tagParts = tag.SysName.Split(new[] { '_' }); +// foreach (var tag in templateTags) +// { +// var tagParts = tag.SysName.Split(new[] { '_' }); - var source = tagParts[0]; +// var source = tagParts[0]; - var tagValue = String.Empty; +// var tagValue = String.Empty; - switch (source) - { - case "common": +// switch (source) +// { +// case "common": - if (contact is Person) - { +// if (contact is Person) +// { - var person = (Person)contact; +// var person = (Person)contact; - switch (tagParts[1]) - { +// switch (tagParts[1]) +// { - case "firstName": - tagValue = person.FirstName; +// case "firstName": +// tagValue = person.FirstName; - break; - case "lastName": - tagValue = person.LastName; +// break; +// case "lastName": +// tagValue = person.LastName; - break; - case "jobTitle": - tagValue = person.JobTitle; - break; - case "companyName": - var relativeCompany = contactDao.GetByID(((Person)contact).CompanyID); +// break; +// case "jobTitle": +// tagValue = person.JobTitle; +// break; +// case "companyName": +// var relativeCompany = contactDao.GetByID(((Person)contact).CompanyID); - if (relativeCompany != null) - tagValue = relativeCompany.GetTitle(); +// if (relativeCompany != null) +// tagValue = relativeCompany.GetTitle(); - break; - default: - tagValue = String.Empty; - break; +// break; +// default: +// tagValue = String.Empty; +// break; - } +// } - } - else - { +// } +// else +// { - var company = (Company)contact; +// var company = (Company)contact; - switch (tagParts[1]) - { - case "companyName": - tagValue = company.CompanyName; - break; - default: - tagValue = String.Empty; - break; - } - } +// switch (tagParts[1]) +// { +// case "companyName": +// tagValue = company.CompanyName; +// break; +// default: +// tagValue = String.Empty; +// break; +// } +// } - break; - case "customField": - var tagID = Convert.ToInt32(tagParts[tagParts.Length - 1]); +// break; +// case "customField": +// var tagID = Convert.ToInt32(tagParts[tagParts.Length - 1]); - var entityType = contact is Company ? EntityType.Company : EntityType.Person; +// var entityType = contact is Company ? EntityType.Company : EntityType.Person; - tagValue = customFieldDao.GetValue(entityType, contactID, tagID); +// tagValue = customFieldDao.GetValue(entityType, contactID, tagID); - break; - case "contactInfo": - var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), tagParts[1]); - var category = Convert.ToInt32(tagParts[2]); - var contactInfos = contactInfoDao.GetList(contactID, contactInfoType, category, true); +// break; +// case "contactInfo": +// var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), tagParts[1]); +// var category = Convert.ToInt32(tagParts[2]); +// var contactInfos = contactInfoDao.GetList(contactID, contactInfoType, category, true); - if (contactInfos == null || contactInfos.Count == 0) break; +// if (contactInfos == null || contactInfos.Count == 0) break; - var contactInfo = contactInfos[0]; +// var contactInfo = contactInfos[0]; - if (contactInfoType == ContactInfoType.Address) - { - var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), tagParts[3]); - - tagValue = JObject.Parse(contactInfo.Data)[addressPart.ToString().ToLower()].Value(); - - } - else - tagValue = contactInfo.Data; - - break; - default: - throw new ArgumentException(tag.SysName); - } - - result = result.Replace(tag.Name, tagValue); - } - - return result; - } - - public String Apply(String template, int contactID) - { - return Apply(template, GetTagsFrom(template), contactID); - } - - private String ToTagName(String value, bool isCompany) - { - return String.Format("$({0}.{1})", isCompany ? "Company" : "Person", value); - } - - private List GetAllTags() - { - return GetTags(true).Union(GetTags(false)).ToList(); - } - - public List GetTags(bool isCompany) - { - var result = new List(); - - if (isCompany) - { - - result.Add(new MailTemplateTag - { - DisplayName = CRMContactResource.CompanyName, - SysName = "common_companyName", - Category = CRMContactResource.GeneralInformation, - isCompany = isCompany, - Name = ToTagName("Company Name", isCompany) - }); - - } - else - { - result.Add(new MailTemplateTag - { - DisplayName = CRMContactResource.FirstName, - SysName = "common_firstName", - Category = CRMContactResource.GeneralInformation, - isCompany = false, - Name = ToTagName("First Name", isCompany) - }); - - result.Add(new MailTemplateTag - { - DisplayName = CRMContactResource.LastName, - SysName = "common_lastName", - Category = CRMContactResource.GeneralInformation, - isCompany = false, - Name = ToTagName("Last Name", isCompany) - }); - - result.Add(new MailTemplateTag - { - DisplayName = CRMContactResource.JobTitle, - SysName = "common_jobTitle", - Category = CRMContactResource.GeneralInformation, - isCompany = false, - Name = ToTagName("Job Title", isCompany) - }); - - - result.Add(new MailTemplateTag - { - DisplayName = CRMContactResource.CompanyName, - SysName = "common_companyName", - Category = CRMContactResource.GeneralInformation, - isCompany = false, - Name = ToTagName("Company Name", isCompany) - }); - - } - - foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) - { - - var localName = String.Format("contactInfo_{0}_{1}", infoTypeEnum, ContactInfo.GetDefaultCategory(infoTypeEnum)); - var localTitle = infoTypeEnum.ToLocalizedString(); - - if (infoTypeEnum == ContactInfoType.Address) - foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) - result.Add(new MailTemplateTag - { - SysName = String.Format(localName + "_{0}_{1}", addressPartEnum, (int)AddressCategory.Work), - DisplayName = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString()), - Category = CRMContactResource.GeneralInformation, - isCompany = isCompany, - Name = ToTagName(String.Format("{0} {1}", infoTypeEnum.ToString(), addressPartEnum.ToString()), isCompany) - }); - else - result.Add(new MailTemplateTag - { - SysName = localName, - DisplayName = localTitle, - Category = CRMContactResource.GeneralInformation, - isCompany = isCompany, - Name = ToTagName(infoTypeEnum.ToString(), isCompany) - }); - } - - var entityType = isCompany ? EntityType.Company : EntityType.Person; - - var customFieldsDao = _daoFactory.GetCustomFieldDao(); - - var customFields = customFieldsDao.GetFieldsDescription(entityType); - - var category = CRMContactResource.GeneralInformation; - - foreach (var customField in customFields) - { - if (customField.FieldType == CustomFieldType.SelectBox) continue; - if (customField.FieldType == CustomFieldType.CheckBox) continue; - - if (customField.FieldType == CustomFieldType.Heading) - { - if (!String.IsNullOrEmpty(customField.Label)) - category = customField.Label; - - continue; - } - - result.Add(new MailTemplateTag - { - SysName = "customField_" + customField.ID, - DisplayName = customField.Label.HtmlEncode(), - Category = category, - isCompany = isCompany, - Name = ToTagName(customField.Label, isCompany) - }); - } - - return result; - } - - } -} \ No newline at end of file +// if (contactInfoType == ContactInfoType.Address) +// { +// var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), tagParts[3]); + +// tagValue = JObject.Parse(contactInfo.Data)[addressPart.ToString().ToLower()].Value(); + +// } +// else +// tagValue = contactInfo.Data; + +// break; +// default: +// throw new ArgumentException(tag.SysName); +// } + +// result = result.Replace(tag.Name, tagValue); +// } + +// return result; +// } + +// public String Apply(String template, int contactID) +// { +// return Apply(template, GetTagsFrom(template), contactID); +// } + +// private String ToTagName(String value, bool isCompany) +// { +// return String.Format("$({0}.{1})", isCompany ? "Company" : "Person", value); +// } + +// private List GetAllTags() +// { +// return GetTags(true).Union(GetTags(false)).ToList(); +// } + +// public List GetTags(bool isCompany) +// { +// var result = new List(); + +// if (isCompany) +// { + +// result.Add(new MailTemplateTag +// { +// DisplayName = CRMContactResource.CompanyName, +// SysName = "common_companyName", +// Category = CRMContactResource.GeneralInformation, +// isCompany = isCompany, +// Name = ToTagName("Company Name", isCompany) +// }); + +// } +// else +// { +// result.Add(new MailTemplateTag +// { +// DisplayName = CRMContactResource.FirstName, +// SysName = "common_firstName", +// Category = CRMContactResource.GeneralInformation, +// isCompany = false, +// Name = ToTagName("First Name", isCompany) +// }); + +// result.Add(new MailTemplateTag +// { +// DisplayName = CRMContactResource.LastName, +// SysName = "common_lastName", +// Category = CRMContactResource.GeneralInformation, +// isCompany = false, +// Name = ToTagName("Last Name", isCompany) +// }); + +// result.Add(new MailTemplateTag +// { +// DisplayName = CRMContactResource.JobTitle, +// SysName = "common_jobTitle", +// Category = CRMContactResource.GeneralInformation, +// isCompany = false, +// Name = ToTagName("Job Title", isCompany) +// }); + + +// result.Add(new MailTemplateTag +// { +// DisplayName = CRMContactResource.CompanyName, +// SysName = "common_companyName", +// Category = CRMContactResource.GeneralInformation, +// isCompany = false, +// Name = ToTagName("Company Name", isCompany) +// }); + +// } + +// foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) +// { + +// var localName = String.Format("contactInfo_{0}_{1}", infoTypeEnum, ContactInfo.GetDefaultCategory(infoTypeEnum)); +// var localTitle = infoTypeEnum.ToLocalizedString(); + +// if (infoTypeEnum == ContactInfoType.Address) +// foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) +// result.Add(new MailTemplateTag +// { +// SysName = String.Format(localName + "_{0}_{1}", addressPartEnum, (int)AddressCategory.Work), +// DisplayName = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString()), +// Category = CRMContactResource.GeneralInformation, +// isCompany = isCompany, +// Name = ToTagName(String.Format("{0} {1}", infoTypeEnum.ToString(), addressPartEnum.ToString()), isCompany) +// }); +// else +// result.Add(new MailTemplateTag +// { +// SysName = localName, +// DisplayName = localTitle, +// Category = CRMContactResource.GeneralInformation, +// isCompany = isCompany, +// Name = ToTagName(infoTypeEnum.ToString(), isCompany) +// }); +// } + +// var entityType = isCompany ? EntityType.Company : EntityType.Person; + +// var customFieldsDao = _daoFactory.GetCustomFieldDao(); + +// var customFields = customFieldsDao.GetFieldsDescription(entityType); + +// var category = CRMContactResource.GeneralInformation; + +// foreach (var customField in customFields) +// { +// if (customField.FieldType == CustomFieldType.SelectBox) continue; +// if (customField.FieldType == CustomFieldType.CheckBox) continue; + +// if (customField.FieldType == CustomFieldType.Heading) +// { +// if (!String.IsNullOrEmpty(customField.Label)) +// category = customField.Label; + +// continue; +// } + +// result.Add(new MailTemplateTag +// { +// SysName = "customField_" + customField.ID, +// DisplayName = customField.Label.HtmlEncode(), +// Category = category, +// isCompany = isCompany, +// Name = ToTagName(customField.Label, isCompany) +// }); +// } + +// return result; +// } + +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index 3aec6ba17f5..1485ea353a3 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -34,7 +34,6 @@ using ASC.Web.Files.Services.DocumentService; using ASC.Web.Files.Utils; using Autofac; -using Ionic.Zip; using Microsoft.Extensions.Options; using System; using System.Globalization; @@ -47,9 +46,11 @@ using Microsoft.Extensions.DependencyInjection; using ASC.Common; using ASC.Web.Files.Classes; +using ICSharpCode.SharpZipLib.Zip; namespace ASC.Web.CRM.Classes { + [Scope] public class PdfCreator { public PdfCreator(IOptionsMonitor logger, @@ -61,7 +62,7 @@ public PdfCreator(IOptionsMonitor logger, InvoiceFormattedData invoiceFormattedData) { FilesPathProvider = filesPathProvider; - + Logger = logger.Get("ASC.CRM"); DocumentServiceConnector = documentServiceConnector; @@ -72,7 +73,7 @@ public PdfCreator(IOptionsMonitor logger, } public InvoiceFormattedData InvoiceFormattedData { get; } - + public DaoFactory DaoFactory { get; } private Stream Template @@ -97,62 +98,62 @@ private Stream Template private const string DocumentLogoImage = "word/media/logo.jpeg"; public void CreateAndSaveFile(int invoiceId) - { + { Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}", invoiceId); - + try { - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); - if (invoice == null) - { - Logger.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); - - return; - } + if (invoice == null) + { + Logger.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. Convertation", invoiceId); + return; + } - string urlToFile; - - using (var docxStream = GetStreamDocx(invoice)) - { - urlToFile = GetUrlToFile(docxStream); - } + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. Convertation", invoiceId); - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, - urlToFile); + string urlToFile; - var file = ServiceProvider.GetService>(); + using (var docxStream = GetStreamDocx(invoice)) + { + urlToFile = GetUrlToFile(docxStream); + } - file.Title = string.Format("{0}{1}", invoice.Number, FormatPdf); - file.FolderID = DaoFactory.GetFileDao().GetRoot(); + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, + urlToFile); - var request = WebRequest.Create(urlToFile); + var file = ServiceProvider.GetService>(); - using (var response = request.GetResponse()) - using (var stream = response.GetResponseStream()) - { - file.ContentLength = response.ContentLength; + file.Title = string.Format("{0}{1}", invoice.Number, FormatPdf); + file.FolderID = DaoFactory.GetFileDao().GetRoot(); - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); - file = DaoFactory.GetFileDao().SaveFile(file, stream); - } + var request = WebRequest.Create(urlToFile); - if (file == null) - { - throw new Exception(CRMErrorsResource.FileCreateError); - } + using (var response = request.GetResponse()) + using (var stream = response.GetResponseStream()) + { + file.ContentLength = response.ContentLength; + + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); + file = DaoFactory.GetFileDao().SaveFile(file, stream); + } + + if (file == null) + { + throw new Exception(CRMErrorsResource.FileCreateError); + } - invoice.FileID = Int32.Parse(file.ID.ToString()); + invoice.FileID = Int32.Parse(file.ID.ToString()); - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); - DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); - - DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] {invoice.FileID}); + Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); + + DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); } catch (Exception e) { @@ -188,13 +189,13 @@ private string GetUrlToFile(Stream docxStream) Logger.DebugFormat("PdfCreator. GetUrlToFile. externalUri = {0}", externalUri); var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); - + string urlToFile; - + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, false, out urlToFile); Logger.DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); - + return urlToFile; } @@ -208,17 +209,17 @@ public ConverterData StartCreationFileAsync(Invoice data) externalUri = DocumentServiceConnector.ReplaceCommunityAdress(externalUri); var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); - + string urlToFile; - + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, true, out urlToFile); return new ConverterData - { - StorageUrl = externalUri, - RevisionId = revisionId, - InvoiceId = data.ID, - }; + { + StorageUrl = externalUri, + RevisionId = revisionId, + InvoiceId = data.ID, + }; } } @@ -228,7 +229,7 @@ public File GetConvertedFile(ConverterData data, DaoFactory daoFactory) { return null; } - + string urlToFile; DocumentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, true, out urlToFile); @@ -277,7 +278,7 @@ private File SaveFile(Invoice data, string url, DaoFactory daoFactory) private Stream GetStreamDocx(Invoice data) { var invoiceData = InvoiceFormattedData.GetData(data, 0, 0); - var logo = new byte[] {}; + var logo = new byte[] { }; if (!string.IsNullOrEmpty(invoiceData.LogoBase64)) { @@ -288,32 +289,57 @@ private Stream GetStreamDocx(Invoice data) logo = Convert.FromBase64String(OrganisationLogoManager.GetOrganisationLogoBase64(invoiceData.LogoBase64Id)); } - using (var zip = ZipFile.Read(Template)) + var result = new MemoryStream(); + + using (var zipOutputStream = new ZipOutputStream(Template)) + using (var zipInputStream = new ZipInputStream(Template)) { - var documentXmlStream = new MemoryStream(); - foreach (var entry in zip.Entries.Where(entry => entry.FileName == DocumentXml)) - { - entry.Extract(documentXmlStream); - } - documentXmlStream.Position = 0; - zip.RemoveEntry(DocumentXml); - var document = new XmlDocument(); - document.Load(documentXmlStream); - var documentStr = GenerateDocumentXml(document, invoiceData, logo); - zip.AddEntry(DocumentXml, documentStr, Encoding.UTF8); - - if (logo.Length > 0) + ZipEntry zipEntry; + + while((zipEntry = zipInputStream.GetNextEntry()) != null) { - zip.UpdateEntry(DocumentLogoImage, logo); + zipOutputStream.PutNextEntry(new ZipEntry(zipEntry.Name)); + + if (zipEntry.Name == DocumentXml) + { + var documentXmlStream = new MemoryStream(); + + zipInputStream.CopyTo(documentXmlStream); + + documentXmlStream.Position = 0; + + var document = new XmlDocument(); + + document.Load(documentXmlStream); + + var documentStr = GenerateDocumentXml(document, invoiceData, logo); + + var documentStrAsStream = new MemoryStream(Encoding.UTF8.GetBytes(documentStr)); + + documentStrAsStream.CopyTo(zipOutputStream); + + continue; + + } + + if (zipEntry.Name == DocumentLogoImage && logo.Length > 0) + { + var logoAsStream = new MemoryStream(logo); + + logoAsStream.CopyTo(zipOutputStream); + + continue; + } + + zipInputStream.CopyTo(zipOutputStream); } - var streamZip = new MemoryStream(); - zip.Save(streamZip); - streamZip.Seek(0, SeekOrigin.Begin); - streamZip.Flush(); - return streamZip; + zipOutputStream.Position = 0; + + zipOutputStream.CopyTo(result); } + return result; } private string GenerateDocumentXml(XmlDocument xDocument, InvoiceFormattedData data, byte[] logo) @@ -370,8 +396,8 @@ private string GenerateDocumentXml(XmlDocument xDocument, InvoiceFormattedData d using (var stream = new MemoryStream(logo)) using (var img = System.Drawing.Image.FromStream(stream)) { - var cx = img.Width*9525; //1px = 9525emu - var cy = img.Height*9525; //1px = 9525emu + var cx = img.Width * 9525; //1px = 9525emu + var cy = img.Height * 9525; //1px = 9525emu var newText = parent.CloneNode(true).OuterXml; newText = newText @@ -763,18 +789,20 @@ public class ConverterData public int FileId { get; set; } } - - public static class PdfCreatorExtention + class CustomStaticDataSource: IStaticDataSource { - public static DIHelper AddPdfCreatorService(this DIHelper services) + private Stream _stream; + // Implement method from IStaticDataSource + public Stream GetSource() { - services.TryAddScoped(); + return _stream; + } - return services.AddPathProviderService() - .AddDocumentServiceConnectorService() - .AddOrganisationLogoManagerService() - // .AddDaoFactoryService() - .AddInvoiceFormattedDataService(); + // Call this to provide the memorystream + public void SetStream(Stream inputStream) + { + _stream = inputStream; + _stream.Position = 0; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index df38220752a..06324e52cea 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -98,9 +98,11 @@ public class PdfProgressItem : IProgressItem public double Percentage { get; set; } public bool IsCompleted { get; set; } - public PdfProgressItem(IHttpContextAccessor httpContextAccessor, - int tenantId, - Guid userId, + + + public PdfProgressItem(IHttpContextAccessor httpContextAccessor, + int tenantId, + Guid userId, int invoiceId) { _contextUrl = context != null ? context.Request.GetUrlRewriter().ToString() : null; diff --git a/products/ASC.CRM/Server/proto/ContactPhotoManagerCacheItem.proto b/products/ASC.CRM/Server/proto/ContactPhotoManagerCacheItem.proto new file mode 100644 index 00000000000..44218c86354 --- /dev/null +++ b/products/ASC.CRM/Server/proto/ContactPhotoManagerCacheItem.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package ASC.Web.CRM.Classes; + +message ContactPhotoManagerCacheItem { + int32 id = 1; +} + \ No newline at end of file From e061a6db9e3fe0a5ae9358c8e1520c551a528473 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 2 Mar 2021 19:29:07 +0300 Subject: [PATCH 17/61] crm: migrate from old project --- .../ASC.CRM/Server/Classes/CRMSettings.cs | 15 +- products/ASC.CRM/Server/Classes/Global.cs | 27 +- .../Server/Classes/ImportFromCSVManager.cs | 2 + .../Server/Classes/OrganisationLogoManager.cs | 17 +- products/ASC.CRM/Server/Classes/VoipEngine.cs | 2 + .../CRMsSpaceUsageStatManager.cs | 5 +- .../ASC.CRM/Server/Controllers/CRMCalendar.cs | 5 +- .../Server/Controllers/CRMController.Cases.cs | 1458 ++++----- .../Controllers/CRMController.ContactInfo.cs | 72 +- .../Controllers/CRMController.Contacts.cs | 10 +- .../CRMController.CurrencyRates.cs | 39 +- .../Controllers/CRMController.CustomFields.cs | 48 +- .../Server/Controllers/CRMController.Deals.cs | 1838 +++++------ .../Controllers/CRMController.Invoices.cs | 2908 +++++++++-------- .../Controllers/CRMController.ListItem.cs | 217 +- .../CRMController.RelationshipEvent.cs | 358 +- .../Controllers/CRMController.Reports.cs | 326 +- .../Server/Controllers/CRMController.Tag.cs | 41 +- .../Controllers/CRMController.TaskTemplate.cs | 87 +- .../Server/Controllers/CRMController.Tasks.cs | 5 +- .../Server/Controllers/CRMController.Utils.cs | 49 +- .../Server/Controllers/CRMController.Voip.cs | 1756 +++++----- .../Server/Controllers/CRMController.cs | 13 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 2 + .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 27 +- .../Server/Core/Security/CRMSecutiry.cs | 1 + .../HttpHandlers/WebToLeadFromHandler.cs | 408 +++ .../ASC.CRM/Server/Model/InvoiceWrapper.cs | 1 + products/ASC.CRM/Server/Program.cs | 41 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 1 + .../Utils/Import/CSV/ImportDataOperation.cs | 2 + .../Server/Utils/Import/CSV/ImportFromCSV.cs | 3 +- .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 80 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 7 +- 34 files changed, 5163 insertions(+), 4708 deletions(-) create mode 100644 products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index 5bed2ce6af8..19f0480ebdf 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -92,6 +92,7 @@ public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) [Serializable] [DataContract] + [Scope] public class InvoiceSetting { public InvoiceSetting(IConfiguration configuration) @@ -258,18 +259,6 @@ public ISettings GetDefault(IServiceProvider serviceProvider) return new CRMReportSampleSettings { NeedToGenerate = true }; } } - - public static class InvoiceSettingExtention - { - public static DIHelper AddInvoiceSettingService(this DIHelper services) - { - services.TryAddScoped(); - - return services; - - } - } - - + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 868a7a14c85..98559cb2be7 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -58,8 +58,7 @@ public Global(StorageFactory storageFactory, CRMSecurity cRMSecurity, TenantManager tenantManager, SettingsManager settingsManager, - IConfiguration configuration, - PdfCreator pdfCreator + IConfiguration configuration ) { StorageFactory = storageFactory; @@ -70,10 +69,8 @@ PdfCreator pdfCreator TenantID = tenantManager.GetCurrentTenant().TenantId; SettingsManager = settingsManager; Configuration = configuration; - PdfCreator = pdfCreator; } - public PdfCreator PdfCreator { get; } public IConfiguration Configuration { get; } public SettingsManager SettingsManager { get; } @@ -183,27 +180,7 @@ public void SaveDefaultCurrencySettings(CurrencyInfo currency) SettingsManager.Save(tenantSettings); } - public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) - { - var existingFile = invoice.GetInvoiceFile(factory); - if (existingFile != null) - { - return existingFile; - } - else - { - var newFile = PdfCreator.CreateFile(invoice, factory); - - invoice.FileID = Int32.Parse(newFile.ID.ToString()); - - factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - - factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); - - return newFile; - } - } - + /// /// The method to Decode your Base64 strings. /// diff --git a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs index 697930ae702..5e27aeaba0d 100644 --- a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs +++ b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs @@ -36,11 +36,13 @@ using System.IO; using Newtonsoft.Json.Linq; using ASC.CRM.Core.Enums; +using ASC.Common; #endregion namespace ASC.Web.CRM.Classes { + [Scope] public class ImportFromCSVManager { public ImportFromCSVManager(Global global, diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs index 4d51ed47965..f058600a8f5 100644 --- a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -41,6 +41,7 @@ namespace ASC.Web.CRM.Classes { + [Scope] public class OrganisationLogoManager { public OrganisationLogoManager(WebImageSupplier webImageSupplier, @@ -130,7 +131,7 @@ public String GetOrganisationLogoBase64(int logoID) } - + public String GetOrganisationLogoSrc(int logoID) { var bytestring = GetOrganisationLogoBase64(logoID); @@ -194,17 +195,5 @@ public String UploadLogo(byte[] imageData, ImageFormat imageFormat) return ExecResizeImage(imageData, OrganisationLogoSize, Global.GetStore(), photoPath); } - } - - public static class OrganisationLogoManagerExtention - { - public static DIHelper AddOrganisationLogoManagerService(this DIHelper services) - { - services.TryAddScoped(); - - return services.AddWebImageSupplierService(); - - - } - } + } } diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index f490a0cec1c..8cafa9e5f7e 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Linq; +using ASC.Common; using ASC.Common.Logging; using ASC.Common.Threading.Workers; using ASC.Core; @@ -44,6 +45,7 @@ namespace ASC.Web.CRM.Classes { + [Scope] public class VoipEngine { private readonly WorkerQueue Queue = new WorkerQueue(); diff --git a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs index 2cba3ff71b3..11cd58ddf1e 100644 --- a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs +++ b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Web; using ASC.Core; using ASC.Core.Common.EF; @@ -38,6 +39,8 @@ namespace ASC.Web.CRM.Configuration { + + [Scope] public class CRMSpaceUsageStatManager : SpaceUsageStatManager { public CRMSpaceUsageStatManager(DbContextManager filesDbContext, @@ -46,7 +49,7 @@ public CRMSpaceUsageStatManager(DbContextManager filesDbContext, { PathProvider = pathProvider; FilesDbContext = filesDbContext.Value; - TenantId = tenantManager.CurrentTenant.TenantId; + TenantId = tenantManager.GetCurrentTenant().TenantId; } public int TenantId { get; } diff --git a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs index 29a89f55e37..2e60e10580c 100644 --- a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs +++ b/products/ASC.CRM/Server/Controllers/CRMCalendar.cs @@ -33,6 +33,7 @@ using ASC.CRM.Resources; using ASC.Web.Core; using ASC.Web.Core.Calendars; + using System; using System.Collections.Generic; using System.Globalization; @@ -42,7 +43,7 @@ namespace ASC.Api.CRM [Scope] public sealed class CRMCalendar : BaseCalendar { - [AllDayLongUTCAttribute] + [AllDayLongUTC] private class Event : BaseEvent { } @@ -75,7 +76,7 @@ TenantUtil tenantUtil Name = CRMCommonResource.ProductName; Description = ""; SharingOptions = new SharingOptions(); -// SharingOptions.PublicItems.Add(new SharingOptions.PublicItem { Id = userId, IsGroup = false }); + // SharingOptions.PublicItems.Add(new SharingOptions.PublicItem { Id = userId, IsGroup = false }); } public override List LoadEvents(Guid userId, DateTime startDate, DateTime endDate) diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs index 071f9366fd6..7ca28329d67 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs @@ -1,729 +1,729 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Api.Collections; -using ASC.Api.CRM.Wrappers; -using ASC.Common.Web; -using ASC.Core; -using ASC.Core.Users; -using ASC.CRM.Core; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; -using ASC.MessagingSystem; -using ASC.Web.Api.Routing; -using ASC.Web.Files.Services.WCFService; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace ASC.Api.CRM -{ - public partial class CRMController - { - /// - /// Close the case with the ID specified in the request - /// - /// Close case - /// Cases - /// Case ID - /// - /// - /// - /// Case - /// - [Update(@"case/{caseid:int}/close")] - public CasesWrapper CloseCases(int caseid) - { - if (caseid <= 0) throw new ArgumentException(); - - var cases = DaoFactory.GetCasesDao().CloseCases(caseid); - if (cases == null) throw new ItemNotFoundException(); - - MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); - - return CasesWrapperHelper.Get(cases); - } - - /// - /// Resume the case with the ID specified in the request - /// - /// Resume case - /// Cases - /// Case ID - /// - /// - /// - /// Case - /// - [Update(@"case/{caseid:int}/reopen")] - public CasesWrapper ReOpenCases(int caseid) - { - if (caseid <= 0) throw new ArgumentException(); - - var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid); - if (cases == null) throw new ItemNotFoundException(); - - MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); - - return CasesWrapperHelper.Get(cases); - } - - /// - /// Creates the case with the parameters specified in the request - /// - /// Create case - /// Case title - /// Participants - /// User field list - /// Case privacy: private or not - /// List of users with access to the case - /// Notify users in accessList about the case - /// Case - /// Cases - /// - /// - /// - /// - [Create(@"case")] - public CasesWrapper CreateCases( - string title, - IEnumerable members, - IEnumerable> customFieldList, - bool isPrivate, - IEnumerable accessList, - bool isNotify) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentException(); - - var casesID = DaoFactory.GetCasesDao().CreateCases(title); - - var cases = new Cases - { - ID = casesID, - Title = title, - CreateBy = SecurityContext.CurrentAccount.ID, - CreateOn = DateTime.UtcNow - }; - - SetAccessToCases(cases, isPrivate, accessList, isNotify, false); - - var membersList = members != null ? members.ToList() : new List(); - if (membersList.Any()) - { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); - membersList = contacts.Select(m => m.ID).ToList(); - DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); - } - - if (customFieldList != null) - { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); - foreach (var field in customFieldList) - { - if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); - } - } - - return CasesWrapperHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); - } - - /// - /// Updates the selected case with the parameters specified in the request - /// - /// Update case - /// Case ID - /// Case title - /// Participants - /// User field list - /// Case privacy: private or not - /// List of users with access to the case - /// Notify users in accessList about the case - /// Cases - /// Case - /// - /// - /// - /// - /// - [Update(@"case/{caseid:int}")] - public CasesWrapper UpdateCases( - int caseid, - string title, - IEnumerable members, - IEnumerable> customFieldList, - bool isPrivate, - IEnumerable accessList, - bool isNotify) - { - if ((caseid <= 0) || (string.IsNullOrEmpty(title))) throw new ArgumentException(); - - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null) throw new ItemNotFoundException(); - - cases.Title = title; - - DaoFactory.GetCasesDao().UpdateCases(cases); - - if (CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) - { - SetAccessToCases(cases, isPrivate, accessList, isNotify, false); - } - - var membersList = members != null ? members.ToList() : new List(); - if (membersList.Any()) - { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); - membersList = contacts.Select(m => m.ID).ToList(); - DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); - } - - if (customFieldList != null) - { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); - foreach (var field in customFieldList) - { - if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); - } - } - - return CasesWrapperHelper.Get(cases); - } - - /// - /// Sets access rights for the selected case with the parameters specified in the request - /// - /// Case ID - /// Case privacy: private or not - /// List of users with access to the case - /// Set rights to case - /// Cases - /// - /// - /// - /// Case - /// - [Update(@"case/{caseid:int}/access")] - public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) - { - if (caseid <= 0) throw new ArgumentException(); - - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null) throw new ItemNotFoundException(); - - if (!(CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); - - return SetAccessToCases(cases, isPrivate, accessList, false, true); - } - - private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) - { - var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); - if (isPrivate && accessListLocal.Any()) - { - if (isNotify) - { - accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); - NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, DaoFactory, accessListLocal.ToArray()); - } - - if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) - { - accessListLocal.Add(SecurityContext.CurrentAccount.ID); - } - - CRMSecurity.SetAccessTo(cases, accessListLocal); - if (isMessageServicSende) - { - var users = GetUsersByIdList(accessListLocal); - MessageService.Send(MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); - } - } - else - { - CRMSecurity.MakePublic(cases); - if (isMessageServicSende) - { - MessageService.Send(MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title); - } - } - - return CasesWrapperHelper.Get(cases); - } - - /// - /// Sets access rights for other users to the list of cases with the IDs specified in the request - /// - /// Case ID list - /// Case privacy: private or not - /// List of users with access - /// Set case access rights - /// Cases - /// - /// - /// - /// Case list - /// - [Update(@"case/access")] - public IEnumerable SetAccessToBatchCases(IEnumerable casesid, bool isPrivate, IEnumerable accessList) - { - var result = new List(); - - var cases = DaoFactory.GetCasesDao().GetCases(casesid); - - if (!cases.Any()) return new List(); - - foreach (var c in cases) - { - if (c == null) throw new ItemNotFoundException(); - - if (!(CRMSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - - SetAccessToCases(c, isPrivate, accessList, false, true); - result.Add(c); - } - - return ToListCasesWrappers(result); - } - - /// - /// Sets access rights for other users to the list of all cases matching the parameters specified in the request - /// - /// Contact ID - /// Case status - /// Tags - /// Case privacy: private or not - /// List of users with access - /// Set case access rights - /// Cases - /// - /// - /// - /// Case list - /// - [Update(@"case/filter/access")] - public IEnumerable SetAccessToBatchCases( - int contactid, - bool? isClosed, - IEnumerable tags, - bool isPrivate, - IEnumerable accessList - ) - { - var result = new List(); - - var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); - - if (!caseses.Any()) return new List(); - - foreach (var casese in caseses) - { - if (casese == null) throw new ItemNotFoundException(); - - if (!(CRMSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - - SetAccessToCases(casese, isPrivate, accessList, false, true); - result.Add(casese); - } - - return ToListCasesWrappers(result); - } - - /// - /// Returns the detailed information about the case with the ID specified in the request - /// - /// Get case by ID - /// Cases - /// Case ID - /// - /// - [Read(@"case/{caseid:int}")] - public CasesWrapper GetCaseByID(int caseid) - { - if (caseid <= 0) throw new ItemNotFoundException(); - - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - - return CasesWrapperHelper.Get(cases); - } - - /// - /// Returns the list of all cases matching the parameters specified in the request - /// - /// Get case list - /// Contact ID - /// Case status - /// Tags - /// Cases - /// - /// Case list - /// - [Read(@"case/filter")] - public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable tags) - { - IEnumerable result; - SortedByType sortBy; - OrderBy casesOrderBy; - - var searchString = ApiContext.FilterValue; - - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) - { - casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); - } - else if (string.IsNullOrEmpty(ApiContext.SortBy)) - { - casesOrderBy = new OrderBy(SortedByType.Title, true); - } - else - { - casesOrderBy = null; - } - - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; - - if (casesOrderBy != null) - { - result = ToListCasesWrappers( - DaoFactory - .GetCasesDao() - .GetCases( - searchString, - contactid, - isClosed, - tags, - fromIndex, - count, - casesOrderBy)).ToList(); - - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - } - else - { - result = ToListCasesWrappers( - DaoFactory - .GetCasesDao() - .GetCases( - searchString, contactid, isClosed, - tags, - 0, - 0, - null)).ToList(); - } - - int totalCount; - - if (result.Count() < count) - { - totalCount = fromIndex + result.Count(); - } - else - { - totalCount = DaoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); - } - - ApiContext.SetTotalCount(totalCount); - return result; - } - - /// - /// Deletes the case with the ID specified in the request - /// - /// Delete case - /// Case ID - /// Cases - /// - /// - /// - /// Case - /// - [Delete(@"case/{caseid:int}")] - public CasesWrapper DeleteCase(int caseid) - { - if (caseid <= 0) throw new ArgumentException(); - - var cases = DaoFactory.GetCasesDao().DeleteCases(caseid); - - if (cases == null) throw new ItemNotFoundException(); - - MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); - - return CasesWrapperHelper.Get(cases); - } - - /// - /// Deletes the group of cases with the IDs specified in the request - /// - /// Case ID list - /// - /// - /// Delete case group - /// Cases - /// - /// Case list - /// - [Update(@"case")] - public IEnumerable DeleteBatchCases(IEnumerable casesids) - { - if (casesids == null) throw new ArgumentException(); - - casesids = casesids.Distinct(); - var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); - - if (caseses == null || !caseses.Any()) return new List(); - - MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); - - return ToListCasesWrappers(caseses); - } - - /// - /// Deletes the list of all cases matching the parameters specified in the request - /// - /// Contact ID - /// Case status - /// Tags - /// - /// - /// Delete case group - /// Cases - /// - /// Case list - /// - [Delete(@"case/filter")] - public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) - { - var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); - if (!caseses.Any()) return new List(); - - caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); - - MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); - - return ToListCasesWrappers(caseses); - } - - /// - /// Returns the list of all contacts associated with the case with the ID specified in the request - /// - /// Get all case contacts - /// Case ID - /// Cases - /// Contact list - /// - [Read(@"case/{caseid:int}/contact")] - public IEnumerable GetCasesMembers(int caseid) - { - var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); - return contactIDs == null - ? new ItemList() - : ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)); - } - - /// - /// Adds the selected contact to the case with the ID specified in the request - /// - /// Add case contact - /// Cases - /// Case ID - /// Contact ID - /// - /// - /// - /// Participant - /// - [Create(@"case/{caseid:int}/contact")] - public ContactWrapper AddMemberToCases(int caseid, int contactid) - { - if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); - - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - - DaoFactory.GetCasesDao().AddMember(caseid, contactid); - - var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; - MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); - - return ToContactWrapper(contact); - } - - /// - /// Delete the selected contact from the case with the ID specified in the request - /// - /// Delete case contact - /// Cases - /// Case ID - /// Contact ID - /// - /// - /// - /// Participant - /// - [Delete(@"case/{caseid:int}/contact/{contactid:int}")] - public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) - { - if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); - - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - - var result = ToContactWrapper(contact); - - DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); - - var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; - MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); - - return result; - } - - /// - /// Returns the list of 30 cases in the CRM module with prefix - /// - /// - /// - /// Cases - /// - /// Cases list - /// - /// false - [Read(@"case/byprefix")] - public IEnumerable GetCasesByPrefix(string prefix, int contactID) - { - var result = new List(); - - if (contactID > 0) - { - var findedCases = DaoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null); - - foreach (var item in findedCases) - { - if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) - { - result.Add(CasesWrapperHelper.Get(item)); - } - } - - ApiContext.SetTotalCount(findedCases.Count); - } - else - { - const int maxItemCount = 30; - var findedCases = DaoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount); - - foreach (var item in findedCases) - { - result.Add(CasesWrapperHelper.Get(item)); - } - } - - return result; - } - - private IEnumerable ToListCasesWrappers(ICollection items) - { - if (items == null || items.Count == 0) return new List(); - - var result = new List(); - - var contactIDs = new List(); - var casesIDs = items.Select(item => item.ID).ToArray(); - - var customFields = DaoFactory.GetCustomFieldDao() - .GetEnityFields(EntityType.Case, casesIDs) - .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); - - var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); - - foreach (var value in casesMembers.Values) - { - contactIDs.AddRange(value); - } - - var contacts = DaoFactory - .GetContactDao() - .GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); - - foreach (var cases in items) - { - var casesWrapper = CasesWrapperHelper.Get(cases); - - casesWrapper.CustomFields = customFields.ContainsKey(cases.ID) - ? customFields[cases.ID] - : new List(); - - casesWrapper.Members = casesMembers.ContainsKey(cases.ID) - ? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) - : new List(); - - result.Add(casesWrapper); - } - - return result; - } - - private IEnumerable GetUsersByIdList(IEnumerable ids) - { - return UserManager.GetUsers().Where(x => ids.Contains(x.ID)); - } - } -} \ No newline at end of file +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//using ASC.Api.Collections; +//using ASC.Api.CRM.Wrappers; +//using ASC.Common.Web; +//using ASC.Core; +//using ASC.Core.Users; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Entities; +//using ASC.CRM.Core.Enums; +//using ASC.ElasticSearch; +//using ASC.MessagingSystem; +//using ASC.Web.Api.Routing; +//using ASC.Web.Files.Services.WCFService; +//using System; +//using System.Collections.Generic; +//using System.Linq; + +//namespace ASC.Api.CRM +//{ +// public partial class CRMController +// { +// /// +// /// Close the case with the ID specified in the request +// /// +// /// Close case +// /// Cases +// /// Case ID +// /// +// /// +// /// +// /// Case +// /// +// [Update(@"case/{caseid:int}/close")] +// public CasesWrapper CloseCases(int caseid) +// { +// if (caseid <= 0) throw new ArgumentException(); + +// var cases = DaoFactory.GetCasesDao().CloseCases(caseid); +// if (cases == null) throw new ItemNotFoundException(); + +// MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); + +// return CasesWrapperHelper.Get(cases); +// } + +// /// +// /// Resume the case with the ID specified in the request +// /// +// /// Resume case +// /// Cases +// /// Case ID +// /// +// /// +// /// +// /// Case +// /// +// [Update(@"case/{caseid:int}/reopen")] +// public CasesWrapper ReOpenCases(int caseid) +// { +// if (caseid <= 0) throw new ArgumentException(); + +// var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid); +// if (cases == null) throw new ItemNotFoundException(); + +// MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); + +// return CasesWrapperHelper.Get(cases); +// } + +// /// +// /// Creates the case with the parameters specified in the request +// /// +// /// Create case +// /// Case title +// /// Participants +// /// User field list +// /// Case privacy: private or not +// /// List of users with access to the case +// /// Notify users in accessList about the case +// /// Case +// /// Cases +// /// +// /// +// /// +// /// +// [Create(@"case")] +// public CasesWrapper CreateCases( +// string title, +// IEnumerable members, +// IEnumerable> customFieldList, +// bool isPrivate, +// IEnumerable accessList, +// bool isNotify) +// { +// if (string.IsNullOrEmpty(title)) throw new ArgumentException(); + +// var casesID = DaoFactory.GetCasesDao().CreateCases(title); + +// var cases = new Cases +// { +// ID = casesID, +// Title = title, +// CreateBy = SecurityContext.CurrentAccount.ID, +// CreateOn = DateTime.UtcNow +// }; + +// SetAccessToCases(cases, isPrivate, accessList, isNotify, false); + +// var membersList = members != null ? members.ToList() : new List(); +// if (membersList.Any()) +// { +// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); +// membersList = contacts.Select(m => m.ID).ToList(); +// DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); +// } + +// if (customFieldList != null) +// { +// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); +// foreach (var field in customFieldList) +// { +// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; +// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); +// } +// } + +// return CasesWrapperHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); +// } + +// /// +// /// Updates the selected case with the parameters specified in the request +// /// +// /// Update case +// /// Case ID +// /// Case title +// /// Participants +// /// User field list +// /// Case privacy: private or not +// /// List of users with access to the case +// /// Notify users in accessList about the case +// /// Cases +// /// Case +// /// +// /// +// /// +// /// +// /// +// [Update(@"case/{caseid:int}")] +// public CasesWrapper UpdateCases( +// int caseid, +// string title, +// IEnumerable members, +// IEnumerable> customFieldList, +// bool isPrivate, +// IEnumerable accessList, +// bool isNotify) +// { +// if ((caseid <= 0) || (string.IsNullOrEmpty(title))) throw new ArgumentException(); + +// var cases = DaoFactory.GetCasesDao().GetByID(caseid); +// if (cases == null) throw new ItemNotFoundException(); + +// cases.Title = title; + +// DaoFactory.GetCasesDao().UpdateCases(cases); + +// if (CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) +// { +// SetAccessToCases(cases, isPrivate, accessList, isNotify, false); +// } + +// var membersList = members != null ? members.ToList() : new List(); +// if (membersList.Any()) +// { +// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); +// membersList = contacts.Select(m => m.ID).ToList(); +// DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); +// } + +// if (customFieldList != null) +// { +// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); +// foreach (var field in customFieldList) +// { +// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; +// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); +// } +// } + +// return CasesWrapperHelper.Get(cases); +// } + +// /// +// /// Sets access rights for the selected case with the parameters specified in the request +// /// +// /// Case ID +// /// Case privacy: private or not +// /// List of users with access to the case +// /// Set rights to case +// /// Cases +// /// +// /// +// /// +// /// Case +// /// +// [Update(@"case/{caseid:int}/access")] +// public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) +// { +// if (caseid <= 0) throw new ArgumentException(); + +// var cases = DaoFactory.GetCasesDao().GetByID(caseid); +// if (cases == null) throw new ItemNotFoundException(); + +// if (!(CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + +// return SetAccessToCases(cases, isPrivate, accessList, false, true); +// } + +// private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) +// { +// var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); +// if (isPrivate && accessListLocal.Any()) +// { +// if (isNotify) +// { +// accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); +// NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, DaoFactory, accessListLocal.ToArray()); +// } + +// if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) +// { +// accessListLocal.Add(SecurityContext.CurrentAccount.ID); +// } + +// CRMSecurity.SetAccessTo(cases, accessListLocal); +// if (isMessageServicSende) +// { +// var users = GetUsersByIdList(accessListLocal); +// MessageService.Send(MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); +// } +// } +// else +// { +// CRMSecurity.MakePublic(cases); +// if (isMessageServicSende) +// { +// MessageService.Send(MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title); +// } +// } + +// return CasesWrapperHelper.Get(cases); +// } + +// /// +// /// Sets access rights for other users to the list of cases with the IDs specified in the request +// /// +// /// Case ID list +// /// Case privacy: private or not +// /// List of users with access +// /// Set case access rights +// /// Cases +// /// +// /// +// /// +// /// Case list +// /// +// [Update(@"case/access")] +// public IEnumerable SetAccessToBatchCases(IEnumerable casesid, bool isPrivate, IEnumerable accessList) +// { +// var result = new List(); + +// var cases = DaoFactory.GetCasesDao().GetCases(casesid); + +// if (!cases.Any()) return new List(); + +// foreach (var c in cases) +// { +// if (c == null) throw new ItemNotFoundException(); + +// if (!(CRMSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + +// SetAccessToCases(c, isPrivate, accessList, false, true); +// result.Add(c); +// } + +// return ToListCasesWrappers(result); +// } + +// /// +// /// Sets access rights for other users to the list of all cases matching the parameters specified in the request +// /// +// /// Contact ID +// /// Case status +// /// Tags +// /// Case privacy: private or not +// /// List of users with access +// /// Set case access rights +// /// Cases +// /// +// /// +// /// +// /// Case list +// /// +// [Update(@"case/filter/access")] +// public IEnumerable SetAccessToBatchCases( +// int contactid, +// bool? isClosed, +// IEnumerable tags, +// bool isPrivate, +// IEnumerable accessList +// ) +// { +// var result = new List(); + +// var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + +// if (!caseses.Any()) return new List(); + +// foreach (var casese in caseses) +// { +// if (casese == null) throw new ItemNotFoundException(); + +// if (!(CRMSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + +// SetAccessToCases(casese, isPrivate, accessList, false, true); +// result.Add(casese); +// } + +// return ToListCasesWrappers(result); +// } + +// /// +// /// Returns the detailed information about the case with the ID specified in the request +// /// +// /// Get case by ID +// /// Cases +// /// Case ID +// /// +// /// +// [Read(@"case/{caseid:int}")] +// public CasesWrapper GetCaseByID(int caseid) +// { +// if (caseid <= 0) throw new ItemNotFoundException(); + +// var cases = DaoFactory.GetCasesDao().GetByID(caseid); +// if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + +// return CasesWrapperHelper.Get(cases); +// } + +// /// +// /// Returns the list of all cases matching the parameters specified in the request +// /// +// /// Get case list +// /// Contact ID +// /// Case status +// /// Tags +// /// Cases +// /// +// /// Case list +// /// +// [Read(@"case/filter")] +// public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable tags) +// { +// IEnumerable result; +// SortedByType sortBy; +// OrderBy casesOrderBy; + +// var searchString = ApiContext.FilterValue; + +// if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) +// { +// casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); +// } +// else if (string.IsNullOrEmpty(ApiContext.SortBy)) +// { +// casesOrderBy = new OrderBy(SortedByType.Title, true); +// } +// else +// { +// casesOrderBy = null; +// } + +// var fromIndex = (int)ApiContext.StartIndex; +// var count = (int)ApiContext.Count; + +// if (casesOrderBy != null) +// { +// result = ToListCasesWrappers( +// DaoFactory +// .GetCasesDao() +// .GetCases( +// searchString, +// contactid, +// isClosed, +// tags, +// fromIndex, +// count, +// casesOrderBy)).ToList(); + +// ApiContext.SetDataPaginated(); +// ApiContext.SetDataFiltered(); +// ApiContext.SetDataSorted(); +// } +// else +// { +// result = ToListCasesWrappers( +// DaoFactory +// .GetCasesDao() +// .GetCases( +// searchString, contactid, isClosed, +// tags, +// 0, +// 0, +// null)).ToList(); +// } + +// int totalCount; + +// if (result.Count() < count) +// { +// totalCount = fromIndex + result.Count(); +// } +// else +// { +// totalCount = DaoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); +// } + +// ApiContext.SetTotalCount(totalCount); +// return result; +// } + +// /// +// /// Deletes the case with the ID specified in the request +// /// +// /// Delete case +// /// Case ID +// /// Cases +// /// +// /// +// /// +// /// Case +// /// +// [Delete(@"case/{caseid:int}")] +// public CasesWrapper DeleteCase(int caseid) +// { +// if (caseid <= 0) throw new ArgumentException(); + +// var cases = DaoFactory.GetCasesDao().DeleteCases(caseid); + +// if (cases == null) throw new ItemNotFoundException(); + +// MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); + +// return CasesWrapperHelper.Get(cases); +// } + +// /// +// /// Deletes the group of cases with the IDs specified in the request +// /// +// /// Case ID list +// /// +// /// +// /// Delete case group +// /// Cases +// /// +// /// Case list +// /// +// [Update(@"case")] +// public IEnumerable DeleteBatchCases(IEnumerable casesids) +// { +// if (casesids == null) throw new ArgumentException(); + +// casesids = casesids.Distinct(); +// var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); + +// if (caseses == null || !caseses.Any()) return new List(); + +// MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); + +// return ToListCasesWrappers(caseses); +// } + +// /// +// /// Deletes the list of all cases matching the parameters specified in the request +// /// +// /// Contact ID +// /// Case status +// /// Tags +// /// +// /// +// /// Delete case group +// /// Cases +// /// +// /// Case list +// /// +// [Delete(@"case/filter")] +// public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) +// { +// var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); +// if (!caseses.Any()) return new List(); + +// caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); + +// MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); + +// return ToListCasesWrappers(caseses); +// } + +// /// +// /// Returns the list of all contacts associated with the case with the ID specified in the request +// /// +// /// Get all case contacts +// /// Case ID +// /// Cases +// /// Contact list +// /// +// [Read(@"case/{caseid:int}/contact")] +// public IEnumerable GetCasesMembers(int caseid) +// { +// var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); +// return contactIDs == null +// ? new ItemList() +// : ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)); +// } + +// /// +// /// Adds the selected contact to the case with the ID specified in the request +// /// +// /// Add case contact +// /// Cases +// /// Case ID +// /// Contact ID +// /// +// /// +// /// +// /// Participant +// /// +// [Create(@"case/{caseid:int}/contact")] +// public ContactWrapper AddMemberToCases(int caseid, int contactid) +// { +// if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); + +// var cases = DaoFactory.GetCasesDao().GetByID(caseid); +// if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + +// var contact = DaoFactory.GetContactDao().GetByID(contactid); +// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + +// DaoFactory.GetCasesDao().AddMember(caseid, contactid); + +// var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; +// MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + +// return ToContactWrapper(contact); +// } + +// /// +// /// Delete the selected contact from the case with the ID specified in the request +// /// +// /// Delete case contact +// /// Cases +// /// Case ID +// /// Contact ID +// /// +// /// +// /// +// /// Participant +// /// +// [Delete(@"case/{caseid:int}/contact/{contactid:int}")] +// public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) +// { +// if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); + +// var cases = DaoFactory.GetCasesDao().GetByID(caseid); +// if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + +// var contact = DaoFactory.GetContactDao().GetByID(contactid); +// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + +// var result = ToContactWrapper(contact); + +// DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); + +// var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; +// MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + +// return result; +// } + +// /// +// /// Returns the list of 30 cases in the CRM module with prefix +// /// +// /// +// /// +// /// Cases +// /// +// /// Cases list +// /// +// /// false +// [Read(@"case/byprefix")] +// public IEnumerable GetCasesByPrefix(string prefix, int contactID) +// { +// var result = new List(); + +// if (contactID > 0) +// { +// var findedCases = DaoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null); + +// foreach (var item in findedCases) +// { +// if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) +// { +// result.Add(CasesWrapperHelper.Get(item)); +// } +// } + +// ApiContext.SetTotalCount(findedCases.Count); +// } +// else +// { +// const int maxItemCount = 30; +// var findedCases = DaoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount); + +// foreach (var item in findedCases) +// { +// result.Add(CasesWrapperHelper.Get(item)); +// } +// } + +// return result; +// } + +// private IEnumerable ToListCasesWrappers(ICollection items) +// { +// if (items == null || items.Count == 0) return new List(); + +// var result = new List(); + +// var contactIDs = new List(); +// var casesIDs = items.Select(item => item.ID).ToArray(); + +// var customFields = DaoFactory.GetCustomFieldDao() +// .GetEnityFields(EntityType.Case, casesIDs) +// .GroupBy(item => item.EntityID) +// .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + +// var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); + +// foreach (var value in casesMembers.Values) +// { +// contactIDs.AddRange(value); +// } + +// var contacts = DaoFactory +// .GetContactDao() +// .GetContacts(contactIDs.Distinct().ToArray()) +// .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); + +// foreach (var cases in items) +// { +// var casesWrapper = CasesWrapperHelper.Get(cases); + +// casesWrapper.CustomFields = customFields.ContainsKey(cases.ID) +// ? customFields[cases.ID] +// : new List(); + +// casesWrapper.Members = casesMembers.ContainsKey(cases.ID) +// ? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) +// : new List(); + +// result.Add(casesWrapper); +// } + +// return result; +// } + +// private IEnumerable GetUsersByIdList(IEnumerable ids) +// { +// return UserManager.GetUsers().Where(x => ids.Contains(x.ID)); +// } +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs index ef7fc81aadd..a867cd16b39 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs @@ -34,8 +34,10 @@ using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.CRM.Core.Search; + using Newtonsoft.Json; using Newtonsoft.Json.Serialization; + using System; using System.Collections.Generic; using System.Linq; @@ -157,13 +159,13 @@ public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoT var contactInfo = new ContactInfo - { - Data = data, - InfoType = infoType, - ContactID = contactid, - IsPrimary = isPrimary, - Category = (int)Enum.Parse(categoryType, category) - }; + { + Data = data, + InfoType = infoType, + ContactID = contactid, + IsPrimary = isPrimary, + Category = (int)Enum.Parse(categoryType, category) + }; if (contactInfo.InfoType == ContactInfoType.Address) { @@ -175,7 +177,7 @@ public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoT var contactInfoID = DaoFactory.GetContactInfoDao().Save(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); var contactInfoWrapper = ContactInfoWrapperHelper.Get(contactInfo); @@ -215,27 +217,27 @@ public ContactInfoWrapper CreateContactInfoAddress(int contactid, Address addres address.CategoryName = ((AddressCategory)address.Category).ToLocalizedString(); var settings = new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver { - ContractResolver = new DefaultContractResolver - { - NamingStrategy = new CamelCaseNamingStrategy() - }, - Formatting = Formatting.Indented - }; + NamingStrategy = new CamelCaseNamingStrategy() + }, + Formatting = Formatting.Indented + }; var contactInfo = new ContactInfo - { - InfoType = ContactInfoType.Address, - ContactID = contactid, - IsPrimary = address.IsPrimary, - Category = address.Category, - Data = JsonConvert.SerializeObject(address, settings) - }; + { + InfoType = ContactInfoType.Address, + ContactID = contactid, + IsPrimary = address.IsPrimary, + Category = address.Category, + Data = JsonConvert.SerializeObject(address, settings) + }; contactInfo.ID = DaoFactory.GetContactInfoDao().Save(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); return ContactInfoWrapperHelper.Get(contactInfo); } @@ -274,7 +276,7 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEn if (contactInfo.InfoType == ContactInfoType.Address) { Address res; - if(!Address.TryParse(contactInfo, out res)) + if (!Address.TryParse(contactInfo, out res)) throw new ArgumentException(); } contactInfo.ContactID = contactid; @@ -346,7 +348,7 @@ public ContactInfoWrapper UpdateContactInfo(int id, int contactid, ContactInfoTy DaoFactory.GetContactInfoDao().Update(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); var contactInfoWrapper = ContactInfoWrapperHelper.Get(contactInfo); @@ -385,7 +387,7 @@ public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Addres if (!Enum.IsDefined(typeof(AddressCategory), address.Category)) throw new ArgumentException("Value does not fall within the expected range.", "address.Category"); - address.CategoryName = ((AddressCategory) address.Category).ToLocalizedString(); + address.CategoryName = ((AddressCategory)address.Category).ToLocalizedString(); var settings = new JsonSerializerSettings { @@ -403,7 +405,7 @@ public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Addres DaoFactory.GetContactInfoDao().Update(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); return ContactInfoWrapperHelper.Get(contactInfo); } @@ -507,8 +509,8 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) DaoFactory.GetContactInfoDao().Delete(id); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - - MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + + MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); return wrapper; } @@ -516,13 +518,13 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) private static ContactInfo FromContactInfoWrapper(ContactInfoWrapper contactInfoWrapper) { return new ContactInfo - { - ID = contactInfoWrapper.Id, - Category = contactInfoWrapper.Category, - Data = contactInfoWrapper.Data, - InfoType = contactInfoWrapper.InfoType, - IsPrimary = contactInfoWrapper.IsPrimary - }; + { + ID = contactInfoWrapper.Id, + Category = contactInfoWrapper.Category, + Data = contactInfoWrapper.Data, + InfoType = contactInfoWrapper.InfoType, + IsPrimary = contactInfoWrapper.IsPrimary + }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs index 05f28252743..801aa9d89cf 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs @@ -64,7 +64,7 @@ public partial class CRMController /// Contacts /// /// - [Read(@"contact/{contactid:int")] + [Read(@"contact/{contactid:int}")] public ContactWrapper GetContactByID(int contactid) { if (contactid <= 0) throw new ArgumentException(); @@ -130,10 +130,10 @@ public IEnumerable GetContactsByProjectID(int projectid) // if (!scope.Resolve().CanLinkContact(project)) throw CRMSecurity.CreateSecurityException(); // } - // DaoFactory.GetContactDao().SetRelativeContactProject(new List {contactid}, projectid); + // DaoFactory.GetContactDao().SetRelativeContactProject(new List { contactid }, projectid); // var messageAction = contact is Company ? MessageAction.ProjectLinkedCompany : MessageAction.ProjectLinkedPerson; - // MessageService.Send( messageAction, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); + // MessageService.Send(messageAction, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); // return ToContactWrapper(contact); //} @@ -174,7 +174,7 @@ public IEnumerable GetContactsByProjectID(int projectid) // DaoFactory.GetContactDao().SetRelativeContactProject(contactIds, projectid); - // MessageService.Send( MessageAction.ProjectLinkedContacts, MessageTarget.Create(contactIds), project.Title, contacts.Select(x => x.GetTitle())); + // MessageService.Send(MessageAction.ProjectLinkedContacts, MessageTarget.Create(contactIds), project.Title, contacts.Select(x => x.GetTitle())); // return contacts.ConvertAll(ToContactWrapper); //} @@ -207,7 +207,7 @@ public IEnumerable GetContactsByProjectID(int projectid) // DaoFactory.GetContactDao().RemoveRelativeContactProject(contactid, projectid); // var action = contact is Company ? MessageAction.ProjectUnlinkedCompany : MessageAction.ProjectUnlinkedPerson; - // MessageService.Send( action, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); + // MessageService.Send(action, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); // return ToContactBaseWrapper(contact); //} diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs b/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs index b714b38c53b..0d651ac1798 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs @@ -30,6 +30,7 @@ using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.CRM.Classes; + using System; using System.Collections.Generic; using System.Linq; @@ -39,7 +40,7 @@ namespace ASC.Api.CRM public partial class CRMController { //TABLE `crm_currency_rate` column `rate` DECIMAL(10,2) NOT NULL - public const decimal MaxRateValue = (decimal) 99999999.99; + public const decimal MaxRateValue = (decimal)99999999.99; /// /// Get the list of currency rates @@ -105,17 +106,17 @@ public CurrencyRateWrapper CreateCurrencyRate(string fromCurrency, string toCurr { ValidateRate(rate); - ValidateCurrencies(new[] {fromCurrency, toCurrency}); + ValidateCurrencies(new[] { fromCurrency, toCurrency }); var currencyRate = new CurrencyRate - { - FromCurrency = fromCurrency, - ToCurrency = toCurrency, - Rate = rate - }; + { + FromCurrency = fromCurrency, + ToCurrency = toCurrency, + Rate = rate + }; currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); - MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); + MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); return CurrencyRateWrapperHelper.Get(currencyRate); } @@ -134,7 +135,7 @@ public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, strin ValidateRate(rate); - ValidateCurrencies(new[] {fromCurrency, toCurrency}); + ValidateCurrencies(new[] { fromCurrency, toCurrency }); var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); @@ -146,7 +147,7 @@ public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, strin currencyRate.Rate = rate; currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); - MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); + MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); return CurrencyRateWrapperHelper.Get(currencyRate); } @@ -169,7 +170,7 @@ public List SetCurrencyRates(String currency, List().DefaultCurrency.Abbreviation != currency) { var cur = CurrencyProvider.Get(currency); @@ -179,14 +180,14 @@ public List SetCurrencyRates(String currency, List CurrencyRateWrapperHelper.Get(x)).ToList(); @@ -211,7 +212,7 @@ public List AddCurrencyRates(List rates) foreach (var rate in rates) { var exist = false; - + foreach (var existingRate in existingRates) { if (rate.FromCurrency != existingRate.FromCurrency || rate.ToCurrency != existingRate.ToCurrency) @@ -219,7 +220,7 @@ public List AddCurrencyRates(List rates) existingRate.Rate = rate.Rate; DaoFactory.GetCurrencyRateDao().SaveOrUpdate(existingRate); - MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + MessageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); exist = true; break; } @@ -227,7 +228,7 @@ public List AddCurrencyRates(List rates) if (exist) continue; rate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(rate); - MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + MessageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); existingRates.Add(rate); } @@ -247,7 +248,7 @@ public CurrencyRateWrapper DeleteCurrencyRate(int id) throw new ArgumentException(); var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); - + if (currencyRate == null) throw new ArgumentException(); @@ -269,7 +270,7 @@ private void ValidateCurrencyRates(IEnumerable rates) ValidateCurrencies(currencies.ToArray()); } - + private void ValidateCurrencies(string[] currencies) { if (currencies.Any(string.IsNullOrEmpty)) @@ -289,6 +290,6 @@ private static void ValidateRate(decimal rate) if (rate < 0 || rate > MaxRateValue) throw new ArgumentException(string.Format(CRMErrorsResource.InvalidCurrencyRate, rate)); } - + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs index 1c1e6e78f7d..64c46ae111a 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs @@ -33,6 +33,7 @@ using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.CRM.Core.Search; + using System; using System.Collections.Generic; using System.Linq; @@ -52,7 +53,7 @@ public partial class CRMController /// User field list /// /// - [Read(@"{entityType:(contact|person|company|opportunity|case)}/customfield/definitions")] + [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/definitions")] public IEnumerable GetCustomFieldDefinitions(string entityType) { return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldWrapper); @@ -66,7 +67,7 @@ public IEnumerable GetCustomFieldDefinitions(string entityTy /// Get user field values /// User fields /// - [Read(@"{entityType:(contact|person|company|opportunity|case)}/{entityid:int}/customfield")] + [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield")] public IEnumerable GetCustomFieldForSubject(string entityType, int entityid) { return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseWrapper); @@ -84,7 +85,7 @@ public IEnumerable GetCustomFieldForSubject(string entit /// /// User field /// - [Create(@"{entityType:(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")] + [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")] public CustomFieldBaseWrapper SetEntityCustomFieldValue(string entityType, int entityid, int fieldid, string fieldValue) { var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); @@ -191,7 +192,7 @@ public CustomFieldBaseWrapper SetEntityCustomFieldValue(string entityType, int e /// /// ]]> /// - [Create(@"{entityType:(contact|person|company|opportunity|case)}/customfield")] + [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield")] public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label, int fieldType, int position, string mask) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -200,7 +201,7 @@ public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label var wrapper = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID); var messageAction = GetCustomFieldCreatedAction(entityTypeObj); - MessageService.Send( messageAction, MessageTarget.Create(wrapper.ID), wrapper.Label); + MessageService.Send(messageAction, MessageTarget.Create(wrapper.ID), wrapper.Label); return ToCustomFieldWrapper(DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); } @@ -229,7 +230,7 @@ public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label /// /// /// - [Update(@"{entityType:(contact|person|company|opportunity|case)}/customfield/{id:int}")] + [Update(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/{id:int}")] public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, string label, int fieldType, int position, string mask) { if (id <= 0) throw new ArgumentException(); @@ -238,21 +239,21 @@ public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, stri var entityTypeObj = ToEntityType(entityType); var customField = new CustomField - { - EntityType = entityTypeObj, - FieldType = (CustomFieldType)fieldType, - ID = id, - Mask = mask, - Label = label, - Position = position - }; + { + EntityType = entityTypeObj, + FieldType = (CustomFieldType)fieldType, + ID = id, + Mask = mask, + Label = label, + Position = position + }; DaoFactory.GetCustomFieldDao().EditItem(customField); customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(id); var messageAction = GetCustomFieldUpdatedAction(entityTypeObj); - MessageService.Send( messageAction, MessageTarget.Create(customField.ID), customField.Label); + MessageService.Send(messageAction, MessageTarget.Create(customField.ID), customField.Label); return ToCustomFieldWrapper(customField); } @@ -269,7 +270,7 @@ public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, stri /// /// User field /// - [Delete(@"{entityType:(contact|person|company|opportunity|case)}/customfield/{fieldid:int}")] + [Delete(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/{fieldid:int}")] public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -279,12 +280,11 @@ public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) if (customField == null) throw new ItemNotFoundException(); var result = ToCustomFieldWrapper(customField); - DaoFactory.GetCustomFieldDao().DeleteField(fieldid); - FactoryIndexerFieldValue.DeleteAsync(Web.CRM.Core.Search.FieldsWrapper.GetEventsWrapper(ServiceProvider, customField)); + DaoFactory.GetCustomFieldDao().DeleteField(fieldid); var messageAction = GetCustomFieldDeletedAction(ToEntityType(entityType)); - MessageService.Send( messageAction, MessageTarget.Create(customField.ID), result.Label); + MessageService.Send(messageAction, MessageTarget.Create(customField.ID), result.Label); return result; } @@ -301,7 +301,7 @@ public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) /// /// /// - [Update(@"{entityType:(contact|person|company|opportunity|case)}/customfield/reorder")] + [Update(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/reorder")] public IEnumerable UpdateCustomFieldsOrder(IEnumerable fieldids, string entityType) { if (fieldids == null) throw new ArgumentException(); @@ -317,7 +317,7 @@ public IEnumerable UpdateCustomFieldsOrder(IEnumerable x.Label)); + MessageService.Send(messageAction, MessageTarget.Create(fieldids), customFields.Select(x => x.Label)); return customFields.Select(ToCustomFieldBaseWrapper); } @@ -330,9 +330,9 @@ private static CustomFieldBaseWrapper ToCustomFieldBaseWrapper(CustomField custo private CustomFieldWrapper ToCustomFieldWrapper(CustomField customField) { var result = new CustomFieldWrapper(customField) - { - RelativeItemsCount = DaoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID) - }; + { + RelativeItemsCount = DaoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID) + }; return result; } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs index df90e5e346b..1adc1fe401b 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs @@ -1,926 +1,926 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Api.Collections; -using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; -using ASC.Common.Web; -using ASC.Core; -using ASC.Core.Users; -using ASC.CRM.Core; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.MessagingSystem; -using ASC.Web.Api.Models; -using ASC.Web.Api.Routing; -using ASC.Web.CRM.Classes; -using ASC.Web.Files.Services.WCFService; -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.CRM.Classes; - -namespace ASC.Api.CRM -{ - public partial class CRMController - { - /// - /// Returns the detailed information about the opportunity with the ID specified in the request - /// - /// Opportunity ID - /// - /// Opportunity - /// - /// Get opportunity by ID - /// Opportunities - /// - /// - [Read(@"opportunity/{opportunityid:int}")] - public OpportunityWrapper GetDealByID(int opportunityid) - { - if (opportunityid <= 0) throw new ArgumentException(); - - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); - if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); - - return OpportunityWrapperHelper.Get(deal); - } - - /// - /// Updates the selected opportunity to the stage with the ID specified in the request - /// - /// Opportunity ID - /// Opportunity stage ID - /// - /// Opportunity - /// - /// Update opportunity stage - /// Opportunities - /// - /// - [Update(@"opportunity/{opportunityid:int}/stage/{id:int}")] - public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) - { - if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException(); - - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); - if (deal == null || !CRMSecurity.CanEdit(deal)) throw new ItemNotFoundException(); - - var stage = DaoFactory.GetDealMilestoneDao().GetByID(stageid); - if (stage == null) throw new ItemNotFoundException(); - - deal.DealMilestoneID = stageid; - deal.DealMilestoneProbability = stage.Probability; - - deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue; - DaoFactory.GetDealDao().EditDeal(deal); - MessageService.Send( MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); - - return OpportunityWrapperHelper.Get(deal); - } - - /// - /// Sets access rights for the selected opportunity with the parameters specified in the request - /// - /// Opportunity ID - /// Opportunity privacy: private or not - /// List of users with access - /// Set rights to opportunity - /// Opportunities - /// - /// - /// - /// Opportunity - /// - [Update(@"opportunity/{opportunityid:int}/access")] - public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) - { - if (opportunityid <= 0) throw new ArgumentException(); +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//using ASC.Api.Collections; +//using ASC.Api.Core; +//using ASC.Api.CRM.Wrappers; +//using ASC.Common.Web; +//using ASC.Core; +//using ASC.Core.Users; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Entities; +//using ASC.CRM.Core.Enums; +//using ASC.MessagingSystem; +//using ASC.Web.Api.Models; +//using ASC.Web.Api.Routing; +//using ASC.Web.CRM.Classes; +//using ASC.Web.Files.Services.WCFService; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using ASC.CRM.Classes; + +//namespace ASC.Api.CRM +//{ +// public partial class CRMController +// { +// /// +// /// Returns the detailed information about the opportunity with the ID specified in the request +// /// +// /// Opportunity ID +// /// +// /// Opportunity +// /// +// /// Get opportunity by ID +// /// Opportunities +// /// +// /// +// [Read(@"opportunity/{opportunityid:int}")] +// public OpportunityWrapper GetDealByID(int opportunityid) +// { +// if (opportunityid <= 0) throw new ArgumentException(); + +// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); +// if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); + +// return OpportunityWrapperHelper.Get(deal); +// } + +// /// +// /// Updates the selected opportunity to the stage with the ID specified in the request +// /// +// /// Opportunity ID +// /// Opportunity stage ID +// /// +// /// Opportunity +// /// +// /// Update opportunity stage +// /// Opportunities +// /// +// /// +// [Update(@"opportunity/{opportunityid:int}/stage/{id:int}")] +// public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) +// { +// if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException(); + +// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); +// if (deal == null || !CRMSecurity.CanEdit(deal)) throw new ItemNotFoundException(); + +// var stage = DaoFactory.GetDealMilestoneDao().GetByID(stageid); +// if (stage == null) throw new ItemNotFoundException(); + +// deal.DealMilestoneID = stageid; +// deal.DealMilestoneProbability = stage.Probability; + +// deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue; +// DaoFactory.GetDealDao().EditDeal(deal); +// MessageService.Send( MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); + +// return OpportunityWrapperHelper.Get(deal); +// } + +// /// +// /// Sets access rights for the selected opportunity with the parameters specified in the request +// /// +// /// Opportunity ID +// /// Opportunity privacy: private or not +// /// List of users with access +// /// Set rights to opportunity +// /// Opportunities +// /// +// /// +// /// +// /// Opportunity +// /// +// [Update(@"opportunity/{opportunityid:int}/access")] +// public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) +// { +// if (opportunityid <= 0) throw new ArgumentException(); - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); - if (deal == null) throw new ItemNotFoundException(); - - if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); - return SetAccessToDeal(deal, isPrivate, accessList, false, true); - } - - private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) - { - var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); - if (isPrivate && accessListLocal.Count > 0) - { - - if (isNotify) - { - accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); - NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, DaoFactory, accessListLocal.ToArray()); - } - - if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) - { - accessListLocal.Add(SecurityContext.CurrentAccount.ID); - } - - CRMSecurity.SetAccessTo(deal, accessListLocal); - - if (isMessageServicSende) - { - var users = GetUsersByIdList(accessListLocal); - MessageService.Send( MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); - } - } - else - { - CRMSecurity.MakePublic(deal); - if (isMessageServicSende) - { - MessageService.Send( MessageAction.OpportunityOpenedAccess, MessageTarget.Create(deal.ID), deal.Title); - } - } - - return OpportunityWrapperHelper.Get(deal); - } - - /// - /// Sets access rights for other users to the list of all opportunities matching the parameters specified in the request - /// - /// Opportunity responsible - /// Opportunity stage ID - /// Tags - /// Contact ID - /// Participation status: take into account opportunities where the contact is a participant or not - /// Start date - /// End date - /// Opportunity stage type - /// Opportunity privacy: private or not - /// List of users with access - /// Set opportunity access rights - /// Opportunities - /// - /// - /// - /// Opportunity list - /// - [Update(@"opportunity/filter/access")] - public IEnumerable SetAccessToBatchDeal( - Guid responsibleid, - int opportunityStagesid, - IEnumerable tags, - int contactid, - DealMilestoneStatus? stageType, - bool? contactAlsoIsParticipant, - ApiDateTime fromDate, - ApiDateTime toDate, - bool isPrivate, - IEnumerable accessList - ) - { - var result = new List(); - var deals = DaoFactory.GetDealDao() - .GetDeals(ApiContext.FilterValue, - responsibleid, - opportunityStagesid, - tags, - contactid, - stageType, - contactAlsoIsParticipant, - fromDate, toDate, 0, 0, null); - if (!deals.Any()) return Enumerable.Empty(); - - foreach (var deal in deals) - { - if (deal == null) throw new ItemNotFoundException(); - - if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - - SetAccessToDeal(deal.ID, isPrivate, accessList); - result.Add(deal); - } - - return ToListOpportunityWrapper(result); - } - - /// - /// Sets access rights for other users to the list of opportunities with the IDs specified in the request - /// - /// Opportunity ID list - /// Opportunity privacy: private or not - /// List of users with access - /// Set opportunity access rights - /// Opportunities - /// - /// - /// - /// Opportunity list - /// - [Update(@"opportunity/access")] - public IEnumerable SetAccessToBatchDeal(IEnumerable opportunityid, bool isPrivate, IEnumerable accessList) - { - if(opportunityid == null) throw new ArgumentException(); +// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); +// if (deal == null) throw new ItemNotFoundException(); + +// if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); +// return SetAccessToDeal(deal, isPrivate, accessList, false, true); +// } + +// private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) +// { +// var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); +// if (isPrivate && accessListLocal.Count > 0) +// { + +// if (isNotify) +// { +// accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); +// NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, DaoFactory, accessListLocal.ToArray()); +// } + +// if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) +// { +// accessListLocal.Add(SecurityContext.CurrentAccount.ID); +// } + +// CRMSecurity.SetAccessTo(deal, accessListLocal); + +// if (isMessageServicSende) +// { +// var users = GetUsersByIdList(accessListLocal); +// MessageService.Send( MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); +// } +// } +// else +// { +// CRMSecurity.MakePublic(deal); +// if (isMessageServicSende) +// { +// MessageService.Send( MessageAction.OpportunityOpenedAccess, MessageTarget.Create(deal.ID), deal.Title); +// } +// } + +// return OpportunityWrapperHelper.Get(deal); +// } + +// /// +// /// Sets access rights for other users to the list of all opportunities matching the parameters specified in the request +// /// +// /// Opportunity responsible +// /// Opportunity stage ID +// /// Tags +// /// Contact ID +// /// Participation status: take into account opportunities where the contact is a participant or not +// /// Start date +// /// End date +// /// Opportunity stage type +// /// Opportunity privacy: private or not +// /// List of users with access +// /// Set opportunity access rights +// /// Opportunities +// /// +// /// +// /// +// /// Opportunity list +// /// +// [Update(@"opportunity/filter/access")] +// public IEnumerable SetAccessToBatchDeal( +// Guid responsibleid, +// int opportunityStagesid, +// IEnumerable tags, +// int contactid, +// DealMilestoneStatus? stageType, +// bool? contactAlsoIsParticipant, +// ApiDateTime fromDate, +// ApiDateTime toDate, +// bool isPrivate, +// IEnumerable accessList +// ) +// { +// var result = new List(); +// var deals = DaoFactory.GetDealDao() +// .GetDeals(ApiContext.FilterValue, +// responsibleid, +// opportunityStagesid, +// tags, +// contactid, +// stageType, +// contactAlsoIsParticipant, +// fromDate, toDate, 0, 0, null); +// if (!deals.Any()) return Enumerable.Empty(); + +// foreach (var deal in deals) +// { +// if (deal == null) throw new ItemNotFoundException(); + +// if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + +// SetAccessToDeal(deal.ID, isPrivate, accessList); +// result.Add(deal); +// } + +// return ToListOpportunityWrapper(result); +// } + +// /// +// /// Sets access rights for other users to the list of opportunities with the IDs specified in the request +// /// +// /// Opportunity ID list +// /// Opportunity privacy: private or not +// /// List of users with access +// /// Set opportunity access rights +// /// Opportunities +// /// +// /// +// /// +// /// Opportunity list +// /// +// [Update(@"opportunity/access")] +// public IEnumerable SetAccessToBatchDeal(IEnumerable opportunityid, bool isPrivate, IEnumerable accessList) +// { +// if(opportunityid == null) throw new ArgumentException(); - var result = new List(); - - var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); - - if (!deals.Any()) return new List(); - - foreach (var d in deals) - { - if (d == null) throw new ItemNotFoundException(); - - if (!(CRMSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - - SetAccessToDeal(d, isPrivate, accessList, false, true); - result.Add(d); - } - - return ToListOpportunityWrapper(result); - } - - - /// - /// Deletes the group of opportunities with the IDs specified in the request - /// - /// Opportunity ID list - /// - /// - /// Delete opportunity group - /// Opportunities - /// - /// Opportunity list - /// - [Update(@"opportunity")] - public IEnumerable DeleteBatchDeals(IEnumerable opportunityids) - { - if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); - - var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); - MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); - - return ToListOpportunityWrapper(opportunities); - } - - /// - /// Deletes the list of all opportunities matching the parameters specified in the request - /// - /// Opportunity responsible - /// Opportunity stage ID - /// Tags - /// Contact ID - /// Participation status: take into account opportunities where the contact is a participant or not - /// Start date - /// End date - /// Opportunity stage type - /// - /// - /// Delete opportunity group - /// Opportunities - /// - /// Opportunity list - /// - [Delete(@"opportunity/filter")] - public IEnumerable DeleteBatchDeals( - Guid responsibleid, - int opportunityStagesid, - IEnumerable tags, - int contactid, - DealMilestoneStatus? stageType, - bool? contactAlsoIsParticipant, - ApiDateTime fromDate, - ApiDateTime toDate) - { - var deals = DaoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, - responsibleid, - opportunityStagesid, - tags, - contactid, - stageType, - contactAlsoIsParticipant, - fromDate, toDate, 0, 0, null); - - if (!deals.Any()) return Enumerable.Empty(); - - deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals); - MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); - - return ToListOpportunityWrapper(deals); - } - - /// - /// Returns the list of all opportunities matching the parameters specified in the request - /// - /// Opportunity responsible - /// Opportunity stage ID - /// Tags - /// Contact ID - /// Participation status: take into account opportunities where the contact is a participant or not - /// Start date - /// End date - /// Opportunity stage type - /// Get opportunity list - /// Opportunities - /// - /// Opportunity list - /// - [Read(@"opportunity/filter")] - public IEnumerable GetDeals( - Guid responsibleid, - int opportunityStagesid, - IEnumerable tags, - int contactid, - DealMilestoneStatus? stageType, - bool? contactAlsoIsParticipant, - ApiDateTime fromDate, - ApiDateTime toDate) - { - DealSortedByType dealSortedByType; - - IEnumerable result; - - var searchString = ApiContext.FilterValue; - - OrderBy dealsOrderBy; - - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) - { - dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending); - } - else if (string.IsNullOrEmpty(ApiContext.SortBy)) - { - dealsOrderBy = new OrderBy(DealSortedByType.Stage, true); - } - else - { - dealsOrderBy = null; - } - - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; - - if (dealsOrderBy != null) - { - result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( - searchString, - responsibleid, - opportunityStagesid, - tags, - contactid, - stageType, - contactAlsoIsParticipant, - fromDate, - toDate, - fromIndex, - count, - dealsOrderBy)).ToList(); - - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - } - else - { - result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( - searchString, - responsibleid, - opportunityStagesid, - tags, - contactid, - stageType, - contactAlsoIsParticipant, - fromDate, - toDate, - 0, 0, null)).ToList(); - } - - - int totalCount; - - if (result.Count() < count) - { - totalCount = fromIndex + result.Count(); - } - else - { - totalCount = DaoFactory - .GetDealDao() - .GetDealsCount(searchString, - responsibleid, - opportunityStagesid, - tags, - contactid, - stageType, - contactAlsoIsParticipant, - fromDate, - toDate); - } - - ApiContext.SetTotalCount(totalCount); - - return result; - } - - /// - /// Deletes the opportunity with the ID specified in the request - /// - /// Opportunity ID - /// Delete opportunity - /// Opportunities - /// - /// - /// - /// Opportunity - /// - [Delete(@"opportunity/{opportunityid:int}")] - public OpportunityWrapper DeleteDeal(int opportunityid) - { - if (opportunityid <= 0) throw new ArgumentException(); - - var deal = DaoFactory.GetDealDao().DeleteDeal(opportunityid); - if (deal == null) throw new ItemNotFoundException(); - - MessageService.Send( MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); - - return OpportunityWrapperHelper.Get(deal); - } - - /// - /// Creates the opportunity with the parameters specified in the request - /// - /// Create opportunity - /// Opportunity primary contact - /// Participants - /// Opportunity title - /// Opportunity description - /// Opportunity responsible - /// Bid - /// Amount of transaction - /// Currency (Abbreviation) - /// Period - /// Stage ID - /// Opportunity success probability - /// Actual opportunity closure date - /// Expected opportunity closure date - /// User field list - /// Opportunity privacy: private or not - /// List of users with access to the opportunity - /// Notify users in accessList about the opportunity - /// Opportunities - /// - /// Opportunity - /// - /// - [Create(@"opportunity")] - public OpportunityWrapper CreateDeal( - int contactid, - IEnumerable members, - string title, - string description, - Guid responsibleid, - BidType bidType, - decimal bidValue, - string bidCurrencyAbbr, - int perPeriodValue, - int stageid, - int successProbability, - ApiDateTime actualCloseDate, - ApiDateTime expectedCloseDate, - IEnumerable> customFieldList, - bool isPrivate, - IEnumerable accessList, - bool isNotify) - { - var deal = new Deal - { - Title = title, - Description = description, - ResponsibleID = responsibleid, - BidType = bidType, - BidValue = bidValue, - PerPeriodValue = perPeriodValue, - DealMilestoneID = stageid, - DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability), - ContactID = contactid, - ActualCloseDate = actualCloseDate, - ExpectedCloseDate = expectedCloseDate, - BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null, - }; - - CRMSecurity.DemandCreateOrUpdate(deal); - - deal.ID = DaoFactory.GetDealDao().CreateNewDeal(deal); - - deal.CreateBy = SecurityContext.CurrentAccount.ID; - deal.CreateOn = DateTime.UtcNow; - - SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); - - var membersList = members != null ? members.ToList() : new List(); - - if (deal.ContactID > 0) - membersList.Add(deal.ContactID); - - if (membersList.Any()) - { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); - membersList = contacts.Select(m => m.ID).ToList(); - DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); - } - - if (customFieldList != null) - { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); - foreach (var field in customFieldList) - { - if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); - } - } - - return OpportunityWrapperHelper.Get(deal); - } - - /// - /// Updates the selected opportunity with the parameters specified in the request - /// - /// Update opportunity - ///Opportunity ID - ///Opportunity primary contact - /// Participants - /// Opportunity title - /// Opportunity description - /// Opportunity responsible - /// Bid - /// Amount of transaction - /// Currency (Abbreviation) - /// Period - /// Stage ID - /// Opportunity success probability - /// Actual opportunity closure date - /// Expected opportunity closure date - /// User field list - /// Opportunity privacy: private or not - /// List of users with access to the opportunity - /// Notify users in accessList about the opportunity - /// Opportunities - /// - /// Opportunity - /// - /// - [Update(@"opportunity/{opportunityid:int}")] - public OpportunityWrapper UpdateDeal( - int opportunityid, - int contactid, - IEnumerable members, - string title, - string description, - Guid responsibleid, - BidType bidType, - decimal bidValue, - string bidCurrencyAbbr, - int perPeriodValue, - int stageid, - int successProbability, - ApiDateTime actualCloseDate, - ApiDateTime expectedCloseDate, - IEnumerable> customFieldList, - bool isPrivate, - IEnumerable accessList, - bool isNotify) - { - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); - if (deal == null) throw new ItemNotFoundException(); - - deal.Title = title; - deal.Description = description; - deal.ResponsibleID = responsibleid; - deal.BidType = bidType; - deal.BidValue = bidValue; - deal.PerPeriodValue = perPeriodValue; - deal.DealMilestoneID = stageid; - deal.DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability); - deal.ContactID = contactid; - deal.ActualCloseDate = actualCloseDate; - deal.ExpectedCloseDate = expectedCloseDate; - deal.BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null; - - CRMSecurity.DemandCreateOrUpdate(deal); - - DaoFactory.GetDealDao().EditDeal(deal); - - deal = DaoFactory.GetDealDao().GetByID(opportunityid); - - var membersList = members != null ? members.ToList() : new List(); - if (membersList.Any()) - { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); - membersList = contacts.Select(m => m.ID).ToList(); - - DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); - } - - - if (CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) - { - SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); - } - - if (customFieldList != null) - { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); - foreach (var field in customFieldList) - { - if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); - } - } - - return OpportunityWrapperHelper.Get(deal); - } - - /// - /// Returns the list of all contacts associated with the opportunity with the ID specified in the request - /// - /// Opportunity ID - /// Get all opportunity contacts - /// Opportunities - /// Contact list - /// - /// - [Read(@"opportunity/{opportunityid:int}/contact")] - public IEnumerable GetDealMembers(int opportunityid) - { - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - - var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); - if (contactIDs == null) return new ItemList(); - - var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); - - result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); - - return result; - } - - /// - /// Adds the selected contact to the opportunity with the ID specified in the request - /// - /// Opportunity ID - /// Contact ID - /// Add opportunity contact - /// Opportunities - /// - /// - /// Participant - /// - [Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] - public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) - { - if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); - - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - - var result = ToContactWrapper(contact); - - DaoFactory.GetDealDao().AddMember(opportunityid, contactid); - - var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; - MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); - - return result; - } - - /// - /// Deletes the selected contact from the opportunity with the ID specified in the request - /// - /// Opportunity ID - /// Contact ID - /// Delete opportunity contact - /// Opportunities - /// - /// - /// - /// Participant - /// - [Delete(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] - public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) - { - if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); - - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - - var result = ToContactWrapper(contact); - - DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); - - var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson; - MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); - - return result; - } - - /// - /// Returns the list of 30 opportunities in the CRM module with prefix - /// - /// - /// - /// - /// Opportunities - /// - /// Opportunities list - /// - /// false - [Read(@"opportunity/byprefix")] - public IEnumerable GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true) - { - var result = new List(); - - if (contactID > 0 && internalSearch) - { - var findedDeals = DaoFactory.GetDealDao().GetDealsByContactID(contactID); - foreach (var item in findedDeals) - { - if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) - { - result.Add(OpportunityWrapperHelper.Get(item)); - } - } - - ApiContext.SetTotalCount(result.Count); - } - else - { - const int maxItemCount = 30; - var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); - foreach (var item in findedDeals) - { - result.Add(OpportunityWrapperHelper.Get(item)); - } - } - - return result; - } - - /// - /// Returns the list of all contact opportunities - /// - /// Contact ID - /// Get opportunity list - /// Opportunities - /// - /// Opportunity list - /// - [Read(@"opportunity/bycontact/{contactid:int}")] - public IEnumerable GetDeals(int contactid) - { - var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid); - return ToListOpportunityWrapper(deals); - } - - /// false - [Update(@"opportunity/{opportunityid:int}/creationdate")] - public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate) - { - var dao = DaoFactory.GetDealDao(); - var opportunity = dao.GetByID(opportunityid); - - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) - throw new ItemNotFoundException(); - - dao.SetDealCreationDate(opportunityid, creationDate); - } - - /// false - [Update(@"opportunity/{opportunityid:int}/lastmodifeddate")] - public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDate) - { - var dao = DaoFactory.GetDealDao(); - var opportunity = dao.GetByID(opportunityid); - - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) - throw new ItemNotFoundException(); - - dao.SetDealLastModifedDate(opportunityid, lastModifedDate); - } - - - private IEnumerable ToListOpportunityWrapper(ICollection deals) - { - if (deals == null || deals.Count == 0) return new List(); - - var result = new List(); - - var contactIDs = new List(); - var dealIDs = new List(); - var dealMilestoneIDs = new List(); - - foreach (var deal in deals) - { - contactIDs.Add(deal.ContactID); - dealIDs.Add(deal.ID); - dealMilestoneIDs.Add(deal.DealMilestoneID); - } - - dealMilestoneIDs = dealMilestoneIDs.Distinct().ToList(); - - var contacts = new Dictionary(); - - var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) - .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); - - var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) - .ToDictionary(item => item.ID, item => new DealMilestoneBaseWrapper(item)); - - - var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); - - foreach (var value in dealMembers.Values) - { - contactIDs.AddRange(value); - } - - contactIDs = contactIDs.Distinct().ToList(); - - if (contactIDs.Count > 0) - { - DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item => - { - if (item == null) return; - contacts.Add(item.ID, ContactWrapperHelper.GetContactBaseWrapper(item)); - }); - } - - foreach (var deal in deals) - { - var dealWrapper = OpportunityWrapperHelper.Get(deal); - - if (contacts.ContainsKey(deal.ContactID)) - { - dealWrapper.Contact = contacts[deal.ContactID]; - } - - dealWrapper.CustomFields = customFields.ContainsKey(deal.ID) - ? customFields[deal.ID] - : new List(); - - dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.Id) - ? dealMembers[dealWrapper.Id].Where(contacts.ContainsKey).Select(item => contacts[item]) - : new List(); - - if (dealMilestones.ContainsKey(deal.DealMilestoneID)) - { - dealWrapper.Stage = dealMilestones[deal.DealMilestoneID]; - } +// var result = new List(); + +// var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); + +// if (!deals.Any()) return new List(); + +// foreach (var d in deals) +// { +// if (d == null) throw new ItemNotFoundException(); + +// if (!(CRMSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + +// SetAccessToDeal(d, isPrivate, accessList, false, true); +// result.Add(d); +// } + +// return ToListOpportunityWrapper(result); +// } + + +// /// +// /// Deletes the group of opportunities with the IDs specified in the request +// /// +// /// Opportunity ID list +// /// +// /// +// /// Delete opportunity group +// /// Opportunities +// /// +// /// Opportunity list +// /// +// [Update(@"opportunity")] +// public IEnumerable DeleteBatchDeals(IEnumerable opportunityids) +// { +// if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); + +// var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); +// MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); + +// return ToListOpportunityWrapper(opportunities); +// } + +// /// +// /// Deletes the list of all opportunities matching the parameters specified in the request +// /// +// /// Opportunity responsible +// /// Opportunity stage ID +// /// Tags +// /// Contact ID +// /// Participation status: take into account opportunities where the contact is a participant or not +// /// Start date +// /// End date +// /// Opportunity stage type +// /// +// /// +// /// Delete opportunity group +// /// Opportunities +// /// +// /// Opportunity list +// /// +// [Delete(@"opportunity/filter")] +// public IEnumerable DeleteBatchDeals( +// Guid responsibleid, +// int opportunityStagesid, +// IEnumerable tags, +// int contactid, +// DealMilestoneStatus? stageType, +// bool? contactAlsoIsParticipant, +// ApiDateTime fromDate, +// ApiDateTime toDate) +// { +// var deals = DaoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, +// responsibleid, +// opportunityStagesid, +// tags, +// contactid, +// stageType, +// contactAlsoIsParticipant, +// fromDate, toDate, 0, 0, null); + +// if (!deals.Any()) return Enumerable.Empty(); + +// deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals); +// MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); + +// return ToListOpportunityWrapper(deals); +// } + +// /// +// /// Returns the list of all opportunities matching the parameters specified in the request +// /// +// /// Opportunity responsible +// /// Opportunity stage ID +// /// Tags +// /// Contact ID +// /// Participation status: take into account opportunities where the contact is a participant or not +// /// Start date +// /// End date +// /// Opportunity stage type +// /// Get opportunity list +// /// Opportunities +// /// +// /// Opportunity list +// /// +// [Read(@"opportunity/filter")] +// public IEnumerable GetDeals( +// Guid responsibleid, +// int opportunityStagesid, +// IEnumerable tags, +// int contactid, +// DealMilestoneStatus? stageType, +// bool? contactAlsoIsParticipant, +// ApiDateTime fromDate, +// ApiDateTime toDate) +// { +// DealSortedByType dealSortedByType; + +// IEnumerable result; + +// var searchString = ApiContext.FilterValue; + +// OrderBy dealsOrderBy; + +// if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) +// { +// dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending); +// } +// else if (string.IsNullOrEmpty(ApiContext.SortBy)) +// { +// dealsOrderBy = new OrderBy(DealSortedByType.Stage, true); +// } +// else +// { +// dealsOrderBy = null; +// } + +// var fromIndex = (int)ApiContext.StartIndex; +// var count = (int)ApiContext.Count; + +// if (dealsOrderBy != null) +// { +// result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( +// searchString, +// responsibleid, +// opportunityStagesid, +// tags, +// contactid, +// stageType, +// contactAlsoIsParticipant, +// fromDate, +// toDate, +// fromIndex, +// count, +// dealsOrderBy)).ToList(); + +// ApiContext.SetDataPaginated(); +// ApiContext.SetDataFiltered(); +// ApiContext.SetDataSorted(); +// } +// else +// { +// result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( +// searchString, +// responsibleid, +// opportunityStagesid, +// tags, +// contactid, +// stageType, +// contactAlsoIsParticipant, +// fromDate, +// toDate, +// 0, 0, null)).ToList(); +// } + + +// int totalCount; + +// if (result.Count() < count) +// { +// totalCount = fromIndex + result.Count(); +// } +// else +// { +// totalCount = DaoFactory +// .GetDealDao() +// .GetDealsCount(searchString, +// responsibleid, +// opportunityStagesid, +// tags, +// contactid, +// stageType, +// contactAlsoIsParticipant, +// fromDate, +// toDate); +// } + +// ApiContext.SetTotalCount(totalCount); + +// return result; +// } + +// /// +// /// Deletes the opportunity with the ID specified in the request +// /// +// /// Opportunity ID +// /// Delete opportunity +// /// Opportunities +// /// +// /// +// /// +// /// Opportunity +// /// +// [Delete(@"opportunity/{opportunityid:int}")] +// public OpportunityWrapper DeleteDeal(int opportunityid) +// { +// if (opportunityid <= 0) throw new ArgumentException(); + +// var deal = DaoFactory.GetDealDao().DeleteDeal(opportunityid); +// if (deal == null) throw new ItemNotFoundException(); + +// MessageService.Send( MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); + +// return OpportunityWrapperHelper.Get(deal); +// } + +// /// +// /// Creates the opportunity with the parameters specified in the request +// /// +// /// Create opportunity +// /// Opportunity primary contact +// /// Participants +// /// Opportunity title +// /// Opportunity description +// /// Opportunity responsible +// /// Bid +// /// Amount of transaction +// /// Currency (Abbreviation) +// /// Period +// /// Stage ID +// /// Opportunity success probability +// /// Actual opportunity closure date +// /// Expected opportunity closure date +// /// User field list +// /// Opportunity privacy: private or not +// /// List of users with access to the opportunity +// /// Notify users in accessList about the opportunity +// /// Opportunities +// /// +// /// Opportunity +// /// +// /// +// [Create(@"opportunity")] +// public OpportunityWrapper CreateDeal( +// int contactid, +// IEnumerable members, +// string title, +// string description, +// Guid responsibleid, +// BidType bidType, +// decimal bidValue, +// string bidCurrencyAbbr, +// int perPeriodValue, +// int stageid, +// int successProbability, +// ApiDateTime actualCloseDate, +// ApiDateTime expectedCloseDate, +// IEnumerable> customFieldList, +// bool isPrivate, +// IEnumerable accessList, +// bool isNotify) +// { +// var deal = new Deal +// { +// Title = title, +// Description = description, +// ResponsibleID = responsibleid, +// BidType = bidType, +// BidValue = bidValue, +// PerPeriodValue = perPeriodValue, +// DealMilestoneID = stageid, +// DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability), +// ContactID = contactid, +// ActualCloseDate = actualCloseDate, +// ExpectedCloseDate = expectedCloseDate, +// BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null, +// }; + +// CRMSecurity.DemandCreateOrUpdate(deal); + +// deal.ID = DaoFactory.GetDealDao().CreateNewDeal(deal); + +// deal.CreateBy = SecurityContext.CurrentAccount.ID; +// deal.CreateOn = DateTime.UtcNow; + +// SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); + +// var membersList = members != null ? members.ToList() : new List(); + +// if (deal.ContactID > 0) +// membersList.Add(deal.ContactID); + +// if (membersList.Any()) +// { +// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); +// membersList = contacts.Select(m => m.ID).ToList(); +// DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); +// } + +// if (customFieldList != null) +// { +// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); +// foreach (var field in customFieldList) +// { +// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; +// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); +// } +// } + +// return OpportunityWrapperHelper.Get(deal); +// } + +// /// +// /// Updates the selected opportunity with the parameters specified in the request +// /// +// /// Update opportunity +// ///Opportunity ID +// ///Opportunity primary contact +// /// Participants +// /// Opportunity title +// /// Opportunity description +// /// Opportunity responsible +// /// Bid +// /// Amount of transaction +// /// Currency (Abbreviation) +// /// Period +// /// Stage ID +// /// Opportunity success probability +// /// Actual opportunity closure date +// /// Expected opportunity closure date +// /// User field list +// /// Opportunity privacy: private or not +// /// List of users with access to the opportunity +// /// Notify users in accessList about the opportunity +// /// Opportunities +// /// +// /// Opportunity +// /// +// /// +// [Update(@"opportunity/{opportunityid:int}")] +// public OpportunityWrapper UpdateDeal( +// int opportunityid, +// int contactid, +// IEnumerable members, +// string title, +// string description, +// Guid responsibleid, +// BidType bidType, +// decimal bidValue, +// string bidCurrencyAbbr, +// int perPeriodValue, +// int stageid, +// int successProbability, +// ApiDateTime actualCloseDate, +// ApiDateTime expectedCloseDate, +// IEnumerable> customFieldList, +// bool isPrivate, +// IEnumerable accessList, +// bool isNotify) +// { +// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); +// if (deal == null) throw new ItemNotFoundException(); + +// deal.Title = title; +// deal.Description = description; +// deal.ResponsibleID = responsibleid; +// deal.BidType = bidType; +// deal.BidValue = bidValue; +// deal.PerPeriodValue = perPeriodValue; +// deal.DealMilestoneID = stageid; +// deal.DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability); +// deal.ContactID = contactid; +// deal.ActualCloseDate = actualCloseDate; +// deal.ExpectedCloseDate = expectedCloseDate; +// deal.BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null; + +// CRMSecurity.DemandCreateOrUpdate(deal); + +// DaoFactory.GetDealDao().EditDeal(deal); + +// deal = DaoFactory.GetDealDao().GetByID(opportunityid); + +// var membersList = members != null ? members.ToList() : new List(); +// if (membersList.Any()) +// { +// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); +// membersList = contacts.Select(m => m.ID).ToList(); + +// DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); +// } + + +// if (CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) +// { +// SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); +// } + +// if (customFieldList != null) +// { +// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); +// foreach (var field in customFieldList) +// { +// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; +// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); +// } +// } + +// return OpportunityWrapperHelper.Get(deal); +// } + +// /// +// /// Returns the list of all contacts associated with the opportunity with the ID specified in the request +// /// +// /// Opportunity ID +// /// Get all opportunity contacts +// /// Opportunities +// /// Contact list +// /// +// /// +// [Read(@"opportunity/{opportunityid:int}/contact")] +// public IEnumerable GetDealMembers(int opportunityid) +// { +// var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + +// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + +// var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); +// if (contactIDs == null) return new ItemList(); + +// var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); + +// result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); + +// return result; +// } + +// /// +// /// Adds the selected contact to the opportunity with the ID specified in the request +// /// +// /// Opportunity ID +// /// Contact ID +// /// Add opportunity contact +// /// Opportunities +// /// +// /// +// /// Participant +// /// +// [Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] +// public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) +// { +// if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); + +// var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); +// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + +// var contact = DaoFactory.GetContactDao().GetByID(contactid); +// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + +// var result = ToContactWrapper(contact); + +// DaoFactory.GetDealDao().AddMember(opportunityid, contactid); + +// var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; +// MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + +// return result; +// } + +// /// +// /// Deletes the selected contact from the opportunity with the ID specified in the request +// /// +// /// Opportunity ID +// /// Contact ID +// /// Delete opportunity contact +// /// Opportunities +// /// +// /// +// /// +// /// Participant +// /// +// [Delete(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] +// public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) +// { +// if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); + +// var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); +// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + +// var contact = DaoFactory.GetContactDao().GetByID(contactid); +// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + +// var result = ToContactWrapper(contact); + +// DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); + +// var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson; +// MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + +// return result; +// } + +// /// +// /// Returns the list of 30 opportunities in the CRM module with prefix +// /// +// /// +// /// +// /// +// /// Opportunities +// /// +// /// Opportunities list +// /// +// /// false +// [Read(@"opportunity/byprefix")] +// public IEnumerable GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true) +// { +// var result = new List(); + +// if (contactID > 0 && internalSearch) +// { +// var findedDeals = DaoFactory.GetDealDao().GetDealsByContactID(contactID); +// foreach (var item in findedDeals) +// { +// if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) +// { +// result.Add(OpportunityWrapperHelper.Get(item)); +// } +// } + +// ApiContext.SetTotalCount(result.Count); +// } +// else +// { +// const int maxItemCount = 30; +// var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); +// foreach (var item in findedDeals) +// { +// result.Add(OpportunityWrapperHelper.Get(item)); +// } +// } + +// return result; +// } + +// /// +// /// Returns the list of all contact opportunities +// /// +// /// Contact ID +// /// Get opportunity list +// /// Opportunities +// /// +// /// Opportunity list +// /// +// [Read(@"opportunity/bycontact/{contactid:int}")] +// public IEnumerable GetDeals(int contactid) +// { +// var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid); +// return ToListOpportunityWrapper(deals); +// } + +// /// false +// [Update(@"opportunity/{opportunityid:int}/creationdate")] +// public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate) +// { +// var dao = DaoFactory.GetDealDao(); +// var opportunity = dao.GetByID(opportunityid); + +// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) +// throw new ItemNotFoundException(); + +// dao.SetDealCreationDate(opportunityid, creationDate); +// } + +// /// false +// [Update(@"opportunity/{opportunityid:int}/lastmodifeddate")] +// public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDate) +// { +// var dao = DaoFactory.GetDealDao(); +// var opportunity = dao.GetByID(opportunityid); + +// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) +// throw new ItemNotFoundException(); + +// dao.SetDealLastModifedDate(opportunityid, lastModifedDate); +// } + + +// private IEnumerable ToListOpportunityWrapper(ICollection deals) +// { +// if (deals == null || deals.Count == 0) return new List(); + +// var result = new List(); + +// var contactIDs = new List(); +// var dealIDs = new List(); +// var dealMilestoneIDs = new List(); + +// foreach (var deal in deals) +// { +// contactIDs.Add(deal.ContactID); +// dealIDs.Add(deal.ID); +// dealMilestoneIDs.Add(deal.DealMilestoneID); +// } + +// dealMilestoneIDs = dealMilestoneIDs.Distinct().ToList(); + +// var contacts = new Dictionary(); + +// var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) +// .GroupBy(item => item.EntityID) +// .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + +// var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) +// .ToDictionary(item => item.ID, item => new DealMilestoneBaseWrapper(item)); + + +// var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); + +// foreach (var value in dealMembers.Values) +// { +// contactIDs.AddRange(value); +// } + +// contactIDs = contactIDs.Distinct().ToList(); + +// if (contactIDs.Count > 0) +// { +// DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item => +// { +// if (item == null) return; +// contacts.Add(item.ID, ContactWrapperHelper.GetContactBaseWrapper(item)); +// }); +// } + +// foreach (var deal in deals) +// { +// var dealWrapper = OpportunityWrapperHelper.Get(deal); + +// if (contacts.ContainsKey(deal.ContactID)) +// { +// dealWrapper.Contact = contacts[deal.ContactID]; +// } + +// dealWrapper.CustomFields = customFields.ContainsKey(deal.ID) +// ? customFields[deal.ID] +// : new List(); + +// dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.Id) +// ? dealMembers[dealWrapper.Id].Where(contacts.ContainsKey).Select(item => contacts[item]) +// : new List(); + +// if (dealMilestones.ContainsKey(deal.DealMilestoneID)) +// { +// dealWrapper.Stage = dealMilestones[deal.DealMilestoneID]; +// } - dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); +// dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); - if (dealWrapper.IsPrivate) - { - dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); - } +// if (dealWrapper.IsPrivate) +// { +// dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); +// } - if (!string.IsNullOrEmpty(deal.BidCurrency)) - { - dealWrapper.BidCurrency = CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); - } +// if (!string.IsNullOrEmpty(deal.BidCurrency)) +// { +// dealWrapper.BidCurrency = CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); +// } - result.Add(dealWrapper); - } +// result.Add(dealWrapper); +// } - return result; - } - } -} \ No newline at end of file +// return result; +// } +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs index 0b539f743d2..4e3d1f22775 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs @@ -1,1447 +1,1469 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; -using ASC.Api.Documents; -using ASC.Common.Web; -using ASC.Core; -using ASC.CRM.Classes; -using ASC.CRM.Core; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.CRM.Resources; -using ASC.MessagingSystem; -using ASC.Web.Api.Routing; -using ASC.Web.CRM.Classes; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace ASC.Api.CRM -{ - public partial class CRMController - { - /// - /// Returns the detailed information about the invoice with the ID specified in the request - /// - /// Invoice ID - /// Get invoice by ID - /// Invoices - /// Invoice - [Read(@"invoice/{invoiceid:int}")] - public InvoiceWrapper GetInvoiceByID(int invoiceid) - { - if (invoiceid <= 0) throw new ArgumentException(); - - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); - if (invoice == null) throw new ItemNotFoundException(); - - if (!CRMSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); - } - - return InvoiceWrapperHelper.Get(invoice); - } - - /// - /// Returns the detailed information about the invoice sample - /// - /// Get invoice sample - /// Invoices - /// Invoice - [Read(@"invoice/sample")] - public InvoiceWrapper GetInvoiceSample() - { - var sample = InvoiceWrapper.GetSample(); - sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); - sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; - - sample.IssueDate = ApiDateTimeHelper.Get(DateTime.UtcNow); - sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); - sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow); - - sample.Currency = CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency); - - sample.InvoiceLines.First().Quantity = 1; - - return sample; - } - - /// - /// Returns the json data of the invoice with the ID specified in the request - /// - /// Invoice ID - /// Get invoice json data - /// Invoices - /// Json Data - [Read(@"invoice/jsondata/{invoiceid:int}")] - public string GetInvoiceJsonData(int invoiceid) - { - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); - if (invoice == null) throw new ItemNotFoundException(); - - if (!CRMSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); - } - - return invoice.JsonData; - } - - /// - /// Returns the list of invoices matching the creteria specified in the request - /// - /// Invoice status - /// Invoice issue date from - /// Invoice issue date to - /// Invoice due date from - /// Invoice due date to - /// Invoice entity type - /// Invoice entity ID - /// Invoice currency - /// Get invoice list - /// Invoices - /// Invoice list - [Read(@"invoice/filter")] - public IEnumerable GetInvoices( - InvoiceStatus? status, - ApiDateTime issueDateFrom, - ApiDateTime issueDateTo, - ApiDateTime dueDateFrom, - ApiDateTime dueDateTo, - String entityType, - int entityid, - String currency - ) - { - if (!String.IsNullOrEmpty(entityType) && !( - String.Compare(entityType, "contact", true) == 0 || - String.Compare(entityType, "opportunity", true) == 0 || - String.Compare(entityType, "case", true) == 0)) - throw new ArgumentException(); - - IEnumerable result; - - InvoiceSortedByType sortBy; - - OrderBy invoiceOrderBy; - - var searchString = ApiContext.FilterValue; - - if (InvoiceSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) - { - invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); - } - else if (String.IsNullOrEmpty(ApiContext.SortBy)) - { - invoiceOrderBy = new OrderBy(InvoiceSortedByType.Number, true); - } - else - { - invoiceOrderBy = null; - } - - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; - - if (invoiceOrderBy != null) - { - result = ToListInvoiceBaseWrappers( - DaoFactory.GetInvoiceDao().GetInvoices( - searchString, - status, - issueDateFrom, issueDateTo, - dueDateFrom, dueDateTo, - ToEntityType(entityType), entityid, - currency, - fromIndex, count, - invoiceOrderBy)); - - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - } - else - { - result = ToListInvoiceBaseWrappers( - DaoFactory.GetInvoiceDao().GetInvoices( - searchString, - status, - issueDateFrom, issueDateTo, - dueDateFrom, dueDateTo, - ToEntityType(entityType), entityid, - currency, - 0, - 0, - null)); - } - - int totalCount; - - if (result.Count() < count) - { - totalCount = fromIndex + result.Count(); - } - else - { - totalCount = DaoFactory.GetInvoiceDao().GetInvoicesCount( - searchString, - status, - issueDateFrom, issueDateTo, - dueDateFrom, dueDateTo, - ToEntityType(entityType), entityid, - currency); - } - - ApiContext.SetTotalCount(totalCount); - - return result; - } - - /// - /// Returns the list of all invoices associated with the entity with the ID and type specified in the request - /// - /// Invoice entity type - /// Invoice entity ID - /// Get entity invoices - /// Invoices - /// Invoice list - [Read(@"{entityType:(contact|person|company|opportunity)}/invoicelist/{entityid:int}")] - public IEnumerable GetEntityInvoices(String entityType, int entityid) - { - if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); - - return ToListInvoiceBaseWrappers(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); - } - - /// - /// Updates the status of invoices with the IDs specified in the request - /// - /// Invoice ID list - /// Status - /// Update invoice group status - /// Invoices - /// KeyValuePair of Invoices and InvoiceItems - [Update(@"invoice/status/{status:[\w\d-]+}")] - public KeyValuePair,IEnumerable> UpdateInvoiceBatchStatus( - int[] invoiceids, - InvoiceStatus status - ) - { - if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); - - var oldInvoices = DaoFactory.GetInvoiceDao().GetByID(invoiceids).Where(CRMSecurity.CanAccessTo).ToList(); - - var updatedInvoices = DaoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status); - - // detect what really changed - var realUpdatedInvoices = updatedInvoices - .Select(t => oldInvoices.FirstOrDefault(x => x.ID == t.ID && x.Status != t.Status)) - .Where(inv => inv != null) - .ToList(); - - if (realUpdatedInvoices.Any()) - { - MessageService.Send( MessageAction.InvoicesUpdatedStatus, MessageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString()); - } - - var invoiceItemsUpdated = new List(); - - if (status == InvoiceStatus.Sent || status == InvoiceStatus.Rejected) - { - var invoiceItemsAll = DaoFactory.GetInvoiceItemDao().GetAll(); - var invoiceItemsWithTrackInventory = invoiceItemsAll.Where(item => item.TrackInventory).ToList(); - - if (status == InvoiceStatus.Sent && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) - { - foreach (var inv in updatedInvoices) - { - if (inv.Status == InvoiceStatus.Sent) - { - //could be changed - var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); - if (oldInv != null && oldInv.Status == InvoiceStatus.Draft) - { - //was changed to Sent - var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); - - foreach (var line in invoiceLines) - { - var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); - if (item != null) - { - item.StockQuantity -= line.Quantity; - DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); - var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); - if (oldItem != null) - { - invoiceItemsUpdated.Remove(oldItem); - } - invoiceItemsUpdated.Add(item); - } - } - } - } - } - } - - if (status == InvoiceStatus.Rejected && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) - { - foreach (var inv in updatedInvoices) - { - if (inv.Status == InvoiceStatus.Rejected) - { - //could be changed - var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); - if (oldInv != null && oldInv.Status == InvoiceStatus.Sent) - { - //was changed from Sent to Rejectes - var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); - - foreach (var line in invoiceLines) - { - var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); - if (item != null) - { - item.StockQuantity += line.Quantity; - DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); - var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); - if (oldItem != null) - { - invoiceItemsUpdated.Remove(oldItem); - } - invoiceItemsUpdated.Add(item); - } - } - } - } - } - } - } - - var listInvoiceBaseWrappers = ToListInvoiceBaseWrappers(updatedInvoices); - - return new KeyValuePair,IEnumerable>(listInvoiceBaseWrappers,invoiceItemsUpdated.ConvertAll(i => InvoiceItemWrapperHelper.Get(i))); - } - - /// - /// Delete the invoice with the ID specified in the request - /// - /// Invoice ID - /// Delete invoice - /// Invoices - /// Invoice - [Delete(@"invoice/{invoiceid:int}")] - public InvoiceBaseWrapper DeleteInvoice(int invoiceid) - { - if (invoiceid <= 0) throw new ArgumentException(); - - var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); - if (invoice == null) throw new ItemNotFoundException(); - - MessageService.Send( MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); - - return InvoiceBaseWrapperHelper.Get(invoice); - - } - - /// - /// Deletes the group of invoices with the IDs specified in the request - /// - /// Invoice ID list - /// Delete invoice group - /// Invoices - /// Invoice list - [Delete(@"invoice")] - public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids) - { - if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); - - var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); - MessageService.Send( MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); - - return ToListInvoiceBaseWrappers(invoices); - } - - /// - /// Creates the invoice with the parameters (contactId, consigneeId, etc.) specified in the request - /// - /// Invoice number - /// Invoice issue date - /// Invoice template type - /// Invoice contact ID - /// Invoice consignee ID - /// Invoice entity ID - /// Invoice billing address ID - /// Invoice delivery address ID - /// Invoice due date - /// Invoice language - /// Invoice currency - /// Invoice exchange rate - /// Invoice purchase order number - /// Invoice terms - /// Invoice description - /// Invoice lines list - /// Create invoice - /// Invoices - /// Invoice - /// - /// - /// - [Create(@"invoice")] - public InvoiceWrapper CreateInvoice( - string number, - ApiDateTime issueDate, - int templateType, - int contactId, - int consigneeId, - int entityId, - int billingAddressID, - int deliveryAddressID, - ApiDateTime dueDate, - string language, - string currency, - decimal exchangeRate, - string purchaseOrderNumber, - string terms, - string description, - IEnumerable invoiceLines - ) - { - var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); - if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); - - var invoice = new Invoice - { - Status = InvoiceStatus.Draft, - Number = number, - IssueDate = issueDate, - TemplateType = (InvoiceTemplateType)templateType, - ContactID = contactId, - ConsigneeID = consigneeId, - EntityType = EntityType.Opportunity, - EntityID = entityId, - DueDate = dueDate, - Language = language, - Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null, - ExchangeRate = exchangeRate, - PurchaseOrderNumber = purchaseOrderNumber, - Terms = terms, - Description = description - }; - - CRMSecurity.DemandCreateOrUpdate(invoice); - - if (billingAddressID > 0) - { - var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); - if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) - throw new ArgumentException(); - } - - if (deliveryAddressID > 0) - { - var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); - if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) - throw new ArgumentException(); - } - - - invoice.ID = DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); - - CreateInvoiceLines(invoiceLinesList, invoice); - - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - - return InvoiceWrapperHelper.Get(invoice); - } - - - private bool IsLinesForInvoiceCorrect(List invoiceLines) - { - foreach (var line in invoiceLines) - { - if (line.InvoiceItemID <= 0 || - line.Quantity < 0 || line.Price < 0 || - line.Discount < 0 || line.Discount > 100 || - line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0) - return false; - if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) - return false; - - if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) - return false; - - if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) - return false; - } - return true; - } - - private List CreateInvoiceLines(List invoiceLines, Invoice invoice) - { - var result = new List(); - for (var i = 0; i < invoiceLines.Count; i++) - { - var line = new InvoiceLine - { - ID = 0, - InvoiceID = invoice.ID, - InvoiceItemID = invoiceLines[i].InvoiceItemID, - InvoiceTax1ID = invoiceLines[i].InvoiceTax1ID, - InvoiceTax2ID = invoiceLines[i].InvoiceTax2ID, - SortOrder = i, - Description = invoiceLines[i].Description, - Quantity = invoiceLines[i].Quantity, - Price = invoiceLines[i].Price, - Discount = Convert.ToInt32(invoiceLines[i].Discount) - }; - - line.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line); - result.Add(line); - } - return result; - } - - /// - /// Updates the selected invoice with the parameters (contactId, consigneeId, etc.) specified in the request - /// - /// Invoice ID - /// Invoice issue date - /// Invoice template type - /// Invoice contact ID - /// Invoice consignee ID - /// Invoice entity ID - /// Invoice billing address ID - /// Invoice delivery address ID - /// Invoice due date - /// Invoice language - /// Invoice currency - /// Invoice exchange rate - /// Invoice purchase order number - /// Invoice terms - /// Invoice description - /// Invoice lines list - /// Update invoice - /// Invoices - /// Invoice - /// - /// - /// - [Update(@"invoice/{id:int}")] - public InvoiceWrapper UpdateInvoice( - int id, - ApiDateTime issueDate, - int templateType, - int contactId, - int consigneeId, - int entityId, - int billingAddressID, - int deliveryAddressID, - ApiDateTime dueDate, - string language, - string currency, - decimal exchangeRate, - string purchaseOrderNumber, - string terms, - string description, - IEnumerable invoiceLines) - { - - var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); - if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); - - var invoice = DaoFactory.GetInvoiceDao().GetByID(id); - if (invoice == null || !CRMSecurity.CanEdit(invoice)) throw new ItemNotFoundException(); - - invoice.IssueDate = issueDate; - invoice.TemplateType = (InvoiceTemplateType)templateType; - invoice.ContactID = contactId; - invoice.ConsigneeID = consigneeId; - invoice.EntityType = EntityType.Opportunity; - invoice.EntityID = entityId; - invoice.DueDate = dueDate; - invoice.Language = language; - invoice.Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null;; - invoice.ExchangeRate = exchangeRate; - invoice.PurchaseOrderNumber = purchaseOrderNumber; - invoice.Terms = terms; - invoice.Description = description; - invoice.JsonData = null; - - CRMSecurity.DemandCreateOrUpdate(invoice); - - if (billingAddressID > 0) - { - var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); - if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) - throw new ArgumentException(); - } - - if (deliveryAddressID > 0) - { - var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); - if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) - throw new ArgumentException(); - } - - DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); - - - DaoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID); - CreateInvoiceLines(invoiceLinesList, invoice); - - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - - if (Global.CanDownloadInvoices) - { - PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); - } - - return InvoiceWrapperHelper.Get(invoice); - } - - /// - /// Returns the pdf file associated with the invoice with the ID specified in the request - /// - /// Invoice ID - /// Get invoice pdf file - /// Invoices - /// File - [Read(@"invoice/{invoiceid:int}/pdf")] - public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) - { - if (invoiceid <= 0) throw new ArgumentException(); - - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); - if (invoice == null) throw new ItemNotFoundException(); - - if (!CRMSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); - } - - return FileWrapperHelper.Get(Global.GetInvoicePdfExistingOrCreate(invoice, DaoFactory)); - } - - /// - /// Returns information about the generation of the pdf file of the invoice - /// - /// Invoice ID - /// Storage Url - /// Revision ID - /// Check invoice pdf file - /// Invoices - /// ConverterData - [Create(@"invoice/converter/data")] - public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, string revisionId) - { - if (invoiceId <= 0) throw new ArgumentException(); - - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); - if (invoice == null) throw new ItemNotFoundException(); - - if (!CRMSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); - } - - var converterData = new ConverterData - { - StorageUrl = storageUrl, - RevisionId = revisionId, - InvoiceId = invoiceId - }; - - var existingFile = invoice.GetInvoiceFile(DaoFactory); - if (existingFile != null) - { - converterData.FileId = invoice.FileID; - return converterData; - } - - if (string.IsNullOrEmpty(storageUrl) || string.IsNullOrEmpty(revisionId)) - { - return PdfCreator.StartCreationFileAsync(invoice); - } - else - { - var convertedFile = PdfCreator.GetConvertedFile(converterData, DaoFactory); - if (convertedFile != null) - { - invoice.FileID = Int32.Parse(convertedFile.ID.ToString()); - DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); - - converterData.FileId = invoice.FileID; - return converterData; - } - else - { - return converterData; - } - } - } - - /// - /// Returns the existence of the invoice with the Number specified in the request - /// - /// Invoice number - /// Check invoice existence by number - /// Invoices - /// IsExist - [Read(@"invoice/bynumber/exist")] - public Boolean GetInvoiceByNumberExistence(string number) - { - if (String.IsNullOrEmpty(number)) throw new ArgumentException(); - - return DaoFactory.GetInvoiceDao().IsExist(number); - - } - - /// - /// Returns the detailed information about the invoice with the Number specified in the request - /// - /// Invoice number - /// Get invoice by number - /// Invoices - /// Invoice - [Read(@"invoice/bynumber")] - public InvoiceWrapper GetInvoiceByNumber(string number) - { - if (String.IsNullOrEmpty(number)) throw new ArgumentException(); - - var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number); - if (invoice == null) throw new ItemNotFoundException(); - - if (!CRMSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); - } - - return InvoiceWrapperHelper.Get(invoice); - } - - /// - /// Returns the list of invoice items matching the creteria specified in the request - /// - /// Status - /// InventoryStock - /// Get invoice item list - /// Invoices - /// InvoiceItem list - [Read(@"invoiceitem/filter")] - public IEnumerable GetInvoiceItems(int status, bool? inventoryStock) - { - IEnumerable result; - - InvoiceItemSortedByType sortBy; - - OrderBy invoiceOrderBy; - - var searchString = ApiContext.FilterValue; - - if (InvoiceItemSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) - { - invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); - } - else if (String.IsNullOrEmpty(ApiContext.SortBy)) - { - invoiceOrderBy = new OrderBy(InvoiceItemSortedByType.Name, true); - } - else - { - invoiceOrderBy = null; - } - - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; - - if (invoiceOrderBy != null) - { - result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( - searchString, - status, - inventoryStock, - fromIndex, count, - invoiceOrderBy) - .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); - - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - } - else - { - result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( - searchString, - status, - inventoryStock, - 0, 0, - null) - .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); - } - - int totalCount; - - if (result.Count() < count) - { - totalCount = fromIndex + result.Count(); - } - else - { - totalCount = DaoFactory.GetInvoiceItemDao().GetInvoiceItemsCount( - searchString, - status, - inventoryStock); - } - - ApiContext.SetTotalCount(totalCount); - - return result; - } - - /// - /// Returns the detailed information about the invoice item with the ID specified in the request - /// - /// Invoice Item ID - /// Get invoice item by ID - /// Invoices - /// Invoice Item - [Read(@"invoiceitem/{invoiceitemid:int}")] - public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) - { - if (invoiceitemid <= 0) throw new ArgumentException(); - - var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); - if (invoiceItem == null) throw new ItemNotFoundException(); - - return InvoiceItemWrapperHelper.Get(invoiceItem); - } - - /// - /// Creates the invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request - /// - /// Invoice ID - /// Invoice item ID - /// First invoice tax ID - /// Second invoice tax ID - /// Sort Order - /// Description - /// Quantity - /// Price - /// Discount - /// Create invoice line - /// Invoices - /// InvoiceLine - [Create(@"invoiceline")] - public InvoiceLineWrapper CreateInvoiceLine( - int invoiceId, - int invoiceItemId, - int invoiceTax1Id, - int invoiceTax2Id, - int sortOrder, - string description, - int quantity, - decimal price, - int discount - ) - { - var invoiceLine = new InvoiceLine - { - InvoiceID = invoiceId, - InvoiceItemID = invoiceItemId, - InvoiceTax1ID = invoiceTax1Id, - InvoiceTax2ID = invoiceTax2Id, - SortOrder = sortOrder, - Description = description, - Quantity = quantity, - Price = price, - Discount = discount - }; - - if (invoiceId <= 0) - throw new ArgumentException(); - - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); - - CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); - - invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); - - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - if (Global.CanDownloadInvoices) - { - PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); - } - - return InvoiceLineWrapperHelper.Get(invoiceLine); - } - - /// - /// Updates the selected invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request - /// - /// Line ID - /// Invoice ID - /// Invoice item ID - /// First invoice tax ID - /// Second invoice tax ID - /// Sort Order - /// Description - /// Quantity - /// Price - /// Discount - /// Update invoice line - /// Invoices - /// InvoiceLine - [Update(@"invoiceline/{id:int}")] - public InvoiceLineWrapper UpdateInvoiceLine( - int id, - int invoiceId, - int invoiceItemId, - int invoiceTax1Id, - int invoiceTax2Id, - int sortOrder, - string description, - int quantity, - decimal price, - int discount - ) - { - if (invoiceId <= 0) - throw new ArgumentException(); - - var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); - if (invoiceLine == null || invoiceLine.InvoiceID != invoiceId) throw new ItemNotFoundException(); - - - invoiceLine.InvoiceID = invoiceId; - invoiceLine.InvoiceItemID = invoiceItemId; - invoiceLine.InvoiceTax1ID = invoiceTax1Id; - invoiceLine.InvoiceTax2ID = invoiceTax2Id; - invoiceLine.SortOrder = sortOrder; - invoiceLine.Description = description; - invoiceLine.Quantity = quantity; - invoiceLine.Price = price; - invoiceLine.Discount = discount; - - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); - CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); - - DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); - - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - - if (Global.CanDownloadInvoices) - { - PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); - } - - return InvoiceLineWrapperHelper.Get(invoiceLine); - } - - /// - /// Deletes the invoice line with the ID specified in the request - /// - /// Line ID - /// Delete invoice line - /// Invoices - /// Line ID - [Delete(@"invoiceline/{id:int}")] - public int DeleteInvoiceLine(int id) - { - var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); - if (invoiceLine == null) throw new ItemNotFoundException(); - if (!DaoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line"); - - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID); - if (invoice == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanEdit(invoice)) throw CRMSecurity.CreateSecurityException(); - - DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); - - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - - if (Global.CanDownloadInvoices) - { - PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); - } - - return id; - } - - /// - /// Creates the invoice item with the parameters (title, description, price, etc.) specified in the request - /// - /// Item title - /// Item description - /// Item price - /// Item stock keeping unit - /// Item quantity - /// Item stock quantity - /// Track inventory - /// Item first invoice tax ID - /// Item second invoice tax ID - /// Create invoice item - /// Invoices - /// InvoiceItem - [Create(@"invoiceitem")] - public InvoiceItemWrapper CreateInvoiceItem( - string title, - string description, - decimal price, - string sku, - int quantity, - int stockQuantity, - bool trackInventory, - int invoiceTax1id, - int invoiceTax2id) - { - if (!CRMSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); - } - - if (String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); - - var invoiceItem = new InvoiceItem - { - Title = title, - Description = description, - Price = price, - StockKeepingUnit = sku, - StockQuantity = stockQuantity, - TrackInventory = trackInventory, - InvoiceTax1ID = invoiceTax1id, - InvoiceTax2ID = invoiceTax2id - }; - - invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); - - MessageService.Send( MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - - return InvoiceItemWrapperHelper.Get(invoiceItem); - } - - /// - /// Updates the selected invoice item with the parameters (title, description, price, etc.) specified in the request - /// - /// Item ID - /// Item title - /// Item description - /// Item price - /// Item stock keeping unit - /// Item quantity - /// Item stock quantity - /// Track inventory - /// Item first invoice tax ID - /// Item second invoice tax ID - /// Update invoice item - /// Invoices - /// InvoiceItem - [Update(@"invoiceitem/{id:int}")] - public InvoiceItemWrapper UpdateInvoiceItem(int id, - string title, - string description, - decimal price, - string sku, - int quantity, - int stockQuantity, - bool trackInventory, - int invoiceTax1id, - int invoiceTax2id) - { - if (!CRMSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); - } - - if (id <= 0 || String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); - - if (!DaoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException(); - - var invoiceItem = new InvoiceItem - { - ID = id, - Title = title, - Description = description, - Price = price, - StockKeepingUnit = sku, - StockQuantity = stockQuantity, - TrackInventory = trackInventory, - InvoiceTax1ID = invoiceTax1id, - InvoiceTax2ID = invoiceTax2id - }; - - invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); - MessageService.Send( MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - - return InvoiceItemWrapperHelper.Get(invoiceItem); - } - - /// - /// Deletes the invoice item with the ID specified in the request - /// - /// Item ID - /// Delete invoice item - /// Invoices - /// InvoiceItem - [Delete(@"invoiceitem/{id:int}")] - public InvoiceItemWrapper DeleteInvoiceItem(int id) - { - if (!CRMSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); - } - - if (id <= 0) throw new ArgumentException(); - - var invoiceItem = DaoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id); - if (invoiceItem == null) throw new ItemNotFoundException(); - - MessageService.Send( MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - - return InvoiceItemWrapperHelper.Get(invoiceItem); - - } - - /// - /// Deletes the group of invoice items with the IDs specified in the request - /// - /// Item ID list - /// Delete Invoice item group - /// Invoices - /// InvoiceItem list - [Delete(@"invoiceitem")] - public IEnumerable DeleteBatchItems(IEnumerable ids) - { - if (!CRMSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); - } - - if (ids == null) throw new ArgumentException(); - ids = ids.Distinct(); - - var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); - MessageService.Send( MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); - - return items.ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); - } - - /// - /// Returns the list of invoice taxes - /// - /// Get invoice taxes list - /// Invoices - /// InvoiceTax list - [Read(@"invoice/tax")] - public IEnumerable GetInvoiceTaxes() - { - return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxWrapperHelper.Get(x)); - } - - /// - /// Creates the invoice tax with the parameters (name, description, rate) specified in the request - /// - /// Tax name - /// Tax description - /// Tax rate - /// Create invoice tax - /// Invoices - /// InvoiceTax - [Create(@"invoice/tax")] - public InvoiceTaxWrapper CreateInvoiceTax( - string name, - string description, - decimal rate) - { - if (!CRMSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); - } - - if (String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); - if (DaoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError); - - var invoiceTax = new InvoiceTax - { - Name = name, - Description = description, - Rate = rate - }; - - invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); - MessageService.Send( MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - - return InvoiceTaxWrapperHelper.Get(invoiceTax); - } - - /// - /// Updates the selected invoice tax with the parameters (name, description, rate) specified in the request - /// - /// Tax ID - /// Tax name - /// Tax description - /// Tax rate - /// Update invoice tax - /// Invoices - /// InvoiceTax - [Update(@"invoice/tax/{id:int}")] - public InvoiceTaxWrapper UpdateInvoiceTax( - int id, - string name, - string description, - decimal rate) - { - if (!CRMSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); - } - - if (id <= 0 || String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); - - if (!DaoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException(); - - var invoiceTax = new InvoiceTax - { - ID = id, - Name = name, - Description = description, - Rate = rate - }; - - invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); - MessageService.Send( MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - - return InvoiceTaxWrapperHelper.Get(invoiceTax); - } - - /// - /// Delete the invoice tax with the ID specified in the request - /// - /// Tax ID - /// Delete invoice tax - /// Invoices - /// InvoiceTax - [Delete(@"invoice/tax/{id:int}")] - public InvoiceTaxWrapper DeleteInvoiceTax(int id) - { - if (!CRMSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); - } - - if (id <= 0) throw new ArgumentException(); - - var invoiceTax = DaoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id); - if (invoiceTax == null) throw new ItemNotFoundException(); - - MessageService.Send( MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - - return InvoiceTaxWrapperHelper.Get(invoiceTax); - } - - /// - /// Get default invoice settings - /// - /// Get default invoice settings - /// Invoices - /// InvoiceSetting - [Read(@"invoice/settings")] - public InvoiceSetting GetSettings() - { - return DaoFactory.GetInvoiceDao().GetSettings(); - } - - /// - /// Save default invoice number - /// - /// Is autogenerated - /// Prefix - /// Number - /// Save default invoice number - /// Invoices - /// InvoiceSetting - [Update(@"invoice/settings/name")] - public InvoiceSetting SaveNumberSettings(bool autogenerated, string prefix, string number) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - if (autogenerated && string.IsNullOrEmpty(number)) - throw new ArgumentException(); - - if (autogenerated && DaoFactory.GetInvoiceDao().IsExist(prefix + number)) - throw new ArgumentException(); - - var invoiceSetting = GetSettings(); - - invoiceSetting.Autogenerated = autogenerated; - invoiceSetting.Prefix = prefix; - invoiceSetting.Number = number; - - var settings = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); - MessageService.Send( MessageAction.InvoiceNumberFormatUpdated); - - return settings; - } - - /// - /// Save default invoice terms - /// - /// Terms - /// Save default invoice terms - /// Invoices - /// InvoiceSetting - [Update(@"invoice/settings/terms")] - public InvoiceSetting SaveTermsSettings(string terms) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var invoiceSetting = GetSettings(); - - invoiceSetting.Terms = terms; - - var result = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); - MessageService.Send( MessageAction.InvoiceDefaultTermsUpdated); - - return result; - } - - /// false - [Update(@"invoice/{invoiceid:int}/creationdate")] - public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate) - { - var dao = DaoFactory.GetInvoiceDao(); - var invoice = dao.GetByID(invoiceid); - - if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) - throw new ItemNotFoundException(); - - dao.SetInvoiceCreationDate(invoiceid, creationDate); - } - - /// false - [Update(@"invoice/{invoiceid:int}/lastmodifeddate")] - public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate) - { - var dao = DaoFactory.GetInvoiceDao(); - var invoice = dao.GetByID(invoiceid); - - if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) - throw new ItemNotFoundException(); - - dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); - } - - private IEnumerable ToListInvoiceBaseWrappers(ICollection items) - { - if (items == null || items.Count == 0) return new List(); - - var result = new List(); - - - var contactIDs = items.Select(item => item.ContactID); - contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID)); - - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); - - - foreach (var invoice in items) - { - var invoiceWrapper = InvoiceBaseWrapperHelper.Get(invoice); - - if (contacts.ContainsKey(invoice.ContactID)) - { - invoiceWrapper.Contact = contacts[invoice.ContactID]; - } - - if (contacts.ContainsKey(invoice.ConsigneeID)) - { - invoiceWrapper.Consignee = contacts[invoice.ContactID]; - } +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//using ASC.Api.Core; +//using ASC.Api.CRM.Wrappers; +//using ASC.Api.Documents; +//using ASC.Common.Web; +//using ASC.Core; +//using ASC.CRM.Classes; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Entities; +//using ASC.CRM.Core.Enums; +//using ASC.CRM.Resources; +//using ASC.MessagingSystem; +//using ASC.Web.Api.Routing; +//using ASC.Web.CRM.Classes; +//using System; +//using System.Collections.Generic; +//using System.Linq; + +//namespace ASC.Api.CRM +//{ +// public partial class CRMController +// { +// /// +// /// Returns the detailed information about the invoice with the ID specified in the request +// /// +// /// Invoice ID +// /// Get invoice by ID +// /// Invoices +// /// Invoice +// [Read(@"invoice/{invoiceid:int}")] +// public InvoiceWrapper GetInvoiceByID(int invoiceid) +// { +// if (invoiceid <= 0) throw new ArgumentException(); + +// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); +// if (invoice == null) throw new ItemNotFoundException(); + +// if (!CRMSecurity.CanAccessTo(invoice)) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// return InvoiceWrapperHelper.Get(invoice); +// } + +// /// +// /// Returns the detailed information about the invoice sample +// /// +// /// Get invoice sample +// /// Invoices +// /// Invoice +// [Read(@"invoice/sample")] +// public InvoiceWrapper GetInvoiceSample() +// { +// var sample = InvoiceWrapper.GetSample(); +// sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); +// sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; + +// sample.IssueDate = ApiDateTimeHelper.Get(DateTime.UtcNow); +// sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); +// sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow); + +// sample.Currency = CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency); + +// sample.InvoiceLines.First().Quantity = 1; + +// return sample; +// } + +// /// +// /// Returns the json data of the invoice with the ID specified in the request +// /// +// /// Invoice ID +// /// Get invoice json data +// /// Invoices +// /// Json Data +// [Read(@"invoice/jsondata/{invoiceid:int}")] +// public string GetInvoiceJsonData(int invoiceid) +// { +// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); +// if (invoice == null) throw new ItemNotFoundException(); + +// if (!CRMSecurity.CanAccessTo(invoice)) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// return invoice.JsonData; +// } + +// /// +// /// Returns the list of invoices matching the creteria specified in the request +// /// +// /// Invoice status +// /// Invoice issue date from +// /// Invoice issue date to +// /// Invoice due date from +// /// Invoice due date to +// /// Invoice entity type +// /// Invoice entity ID +// /// Invoice currency +// /// Get invoice list +// /// Invoices +// /// Invoice list +// [Read(@"invoice/filter")] +// public IEnumerable GetInvoices( +// InvoiceStatus? status, +// ApiDateTime issueDateFrom, +// ApiDateTime issueDateTo, +// ApiDateTime dueDateFrom, +// ApiDateTime dueDateTo, +// String entityType, +// int entityid, +// String currency +// ) +// { +// if (!String.IsNullOrEmpty(entityType) && !( +// String.Compare(entityType, "contact", true) == 0 || +// String.Compare(entityType, "opportunity", true) == 0 || +// String.Compare(entityType, "case", true) == 0)) +// throw new ArgumentException(); + +// IEnumerable result; + +// InvoiceSortedByType sortBy; + +// OrderBy invoiceOrderBy; + +// var searchString = ApiContext.FilterValue; + +// if (InvoiceSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) +// { +// invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); +// } +// else if (String.IsNullOrEmpty(ApiContext.SortBy)) +// { +// invoiceOrderBy = new OrderBy(InvoiceSortedByType.Number, true); +// } +// else +// { +// invoiceOrderBy = null; +// } + +// var fromIndex = (int)ApiContext.StartIndex; +// var count = (int)ApiContext.Count; + +// if (invoiceOrderBy != null) +// { +// result = ToListInvoiceBaseWrappers( +// DaoFactory.GetInvoiceDao().GetInvoices( +// searchString, +// status, +// issueDateFrom, issueDateTo, +// dueDateFrom, dueDateTo, +// ToEntityType(entityType), entityid, +// currency, +// fromIndex, count, +// invoiceOrderBy)); + +// ApiContext.SetDataPaginated(); +// ApiContext.SetDataFiltered(); +// ApiContext.SetDataSorted(); +// } +// else +// { +// result = ToListInvoiceBaseWrappers( +// DaoFactory.GetInvoiceDao().GetInvoices( +// searchString, +// status, +// issueDateFrom, issueDateTo, +// dueDateFrom, dueDateTo, +// ToEntityType(entityType), entityid, +// currency, +// 0, +// 0, +// null)); +// } + +// int totalCount; + +// if (result.Count() < count) +// { +// totalCount = fromIndex + result.Count(); +// } +// else +// { +// totalCount = DaoFactory.GetInvoiceDao().GetInvoicesCount( +// searchString, +// status, +// issueDateFrom, issueDateTo, +// dueDateFrom, dueDateTo, +// ToEntityType(entityType), entityid, +// currency); +// } + +// ApiContext.SetTotalCount(totalCount); + +// return result; +// } + +// /// +// /// Returns the list of all invoices associated with the entity with the ID and type specified in the request +// /// +// /// Invoice entity type +// /// Invoice entity ID +// /// Get entity invoices +// /// Invoices +// /// Invoice list +// [Read(@"{entityType:(contact|person|company|opportunity)}/invoicelist/{entityid:int}")] +// public IEnumerable GetEntityInvoices(String entityType, int entityid) +// { +// if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); + +// return ToListInvoiceBaseWrappers(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); +// } + +// /// +// /// Updates the status of invoices with the IDs specified in the request +// /// +// /// Invoice ID list +// /// Status +// /// Update invoice group status +// /// Invoices +// /// KeyValuePair of Invoices and InvoiceItems +// [Update(@"invoice/status/{status:[\w\d-]+}")] +// public KeyValuePair,IEnumerable> UpdateInvoiceBatchStatus( +// int[] invoiceids, +// InvoiceStatus status +// ) +// { +// if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); + +// var oldInvoices = DaoFactory.GetInvoiceDao().GetByID(invoiceids).Where(CRMSecurity.CanAccessTo).ToList(); + +// var updatedInvoices = DaoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status); + +// // detect what really changed +// var realUpdatedInvoices = updatedInvoices +// .Select(t => oldInvoices.FirstOrDefault(x => x.ID == t.ID && x.Status != t.Status)) +// .Where(inv => inv != null) +// .ToList(); + +// if (realUpdatedInvoices.Any()) +// { +// MessageService.Send( MessageAction.InvoicesUpdatedStatus, MessageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString()); +// } + +// var invoiceItemsUpdated = new List(); + +// if (status == InvoiceStatus.Sent || status == InvoiceStatus.Rejected) +// { +// var invoiceItemsAll = DaoFactory.GetInvoiceItemDao().GetAll(); +// var invoiceItemsWithTrackInventory = invoiceItemsAll.Where(item => item.TrackInventory).ToList(); + +// if (status == InvoiceStatus.Sent && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) +// { +// foreach (var inv in updatedInvoices) +// { +// if (inv.Status == InvoiceStatus.Sent) +// { +// //could be changed +// var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); +// if (oldInv != null && oldInv.Status == InvoiceStatus.Draft) +// { +// //was changed to Sent +// var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + +// foreach (var line in invoiceLines) +// { +// var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); +// if (item != null) +// { +// item.StockQuantity -= line.Quantity; +// DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); +// var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); +// if (oldItem != null) +// { +// invoiceItemsUpdated.Remove(oldItem); +// } +// invoiceItemsUpdated.Add(item); +// } +// } +// } +// } +// } +// } + +// if (status == InvoiceStatus.Rejected && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) +// { +// foreach (var inv in updatedInvoices) +// { +// if (inv.Status == InvoiceStatus.Rejected) +// { +// //could be changed +// var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); +// if (oldInv != null && oldInv.Status == InvoiceStatus.Sent) +// { +// //was changed from Sent to Rejectes +// var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + +// foreach (var line in invoiceLines) +// { +// var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); +// if (item != null) +// { +// item.StockQuantity += line.Quantity; +// DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); +// var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); +// if (oldItem != null) +// { +// invoiceItemsUpdated.Remove(oldItem); +// } +// invoiceItemsUpdated.Add(item); +// } +// } +// } +// } +// } +// } +// } + +// var listInvoiceBaseWrappers = ToListInvoiceBaseWrappers(updatedInvoices); + +// return new KeyValuePair,IEnumerable>(listInvoiceBaseWrappers,invoiceItemsUpdated.ConvertAll(i => InvoiceItemWrapperHelper.Get(i))); +// } + +// /// +// /// Delete the invoice with the ID specified in the request +// /// +// /// Invoice ID +// /// Delete invoice +// /// Invoices +// /// Invoice +// [Delete(@"invoice/{invoiceid:int}")] +// public InvoiceBaseWrapper DeleteInvoice(int invoiceid) +// { +// if (invoiceid <= 0) throw new ArgumentException(); + +// var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); +// if (invoice == null) throw new ItemNotFoundException(); + +// MessageService.Send( MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); + +// return InvoiceBaseWrapperHelper.Get(invoice); + +// } + +// /// +// /// Deletes the group of invoices with the IDs specified in the request +// /// +// /// Invoice ID list +// /// Delete invoice group +// /// Invoices +// /// Invoice list +// [Delete(@"invoice")] +// public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids) +// { +// if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); + +// var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); +// MessageService.Send( MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); + +// return ToListInvoiceBaseWrappers(invoices); +// } + +// /// +// /// Creates the invoice with the parameters (contactId, consigneeId, etc.) specified in the request +// /// +// /// Invoice number +// /// Invoice issue date +// /// Invoice template type +// /// Invoice contact ID +// /// Invoice consignee ID +// /// Invoice entity ID +// /// Invoice billing address ID +// /// Invoice delivery address ID +// /// Invoice due date +// /// Invoice language +// /// Invoice currency +// /// Invoice exchange rate +// /// Invoice purchase order number +// /// Invoice terms +// /// Invoice description +// /// Invoice lines list +// /// Create invoice +// /// Invoices +// /// Invoice +// /// +// /// +// /// +// [Create(@"invoice")] +// public InvoiceWrapper CreateInvoice( +// string number, +// ApiDateTime issueDate, +// int templateType, +// int contactId, +// int consigneeId, +// int entityId, +// int billingAddressID, +// int deliveryAddressID, +// ApiDateTime dueDate, +// string language, +// string currency, +// decimal exchangeRate, +// string purchaseOrderNumber, +// string terms, +// string description, +// IEnumerable invoiceLines +// ) +// { +// var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); +// if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); + +// var invoice = new Invoice +// { +// Status = InvoiceStatus.Draft, +// Number = number, +// IssueDate = issueDate, +// TemplateType = (InvoiceTemplateType)templateType, +// ContactID = contactId, +// ConsigneeID = consigneeId, +// EntityType = EntityType.Opportunity, +// EntityID = entityId, +// DueDate = dueDate, +// Language = language, +// Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null, +// ExchangeRate = exchangeRate, +// PurchaseOrderNumber = purchaseOrderNumber, +// Terms = terms, +// Description = description +// }; + +// CRMSecurity.DemandCreateOrUpdate(invoice); + +// if (billingAddressID > 0) +// { +// var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); +// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) +// throw new ArgumentException(); +// } + +// if (deliveryAddressID > 0) +// { +// var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); +// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) +// throw new ArgumentException(); +// } + + +// invoice.ID = DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + +// CreateInvoiceLines(invoiceLinesList, invoice); + +// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + +// return InvoiceWrapperHelper.Get(invoice); +// } + + +// private bool IsLinesForInvoiceCorrect(List invoiceLines) +// { +// foreach (var line in invoiceLines) +// { +// if (line.InvoiceItemID <= 0 || +// line.Quantity < 0 || line.Price < 0 || +// line.Discount < 0 || line.Discount > 100 || +// line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0) +// return false; +// if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) +// return false; + +// if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) +// return false; + +// if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) +// return false; +// } +// return true; +// } + +// private List CreateInvoiceLines(List invoiceLines, Invoice invoice) +// { +// var result = new List(); +// for (var i = 0; i < invoiceLines.Count; i++) +// { +// var line = new InvoiceLine +// { +// ID = 0, +// InvoiceID = invoice.ID, +// InvoiceItemID = invoiceLines[i].InvoiceItemID, +// InvoiceTax1ID = invoiceLines[i].InvoiceTax1ID, +// InvoiceTax2ID = invoiceLines[i].InvoiceTax2ID, +// SortOrder = i, +// Description = invoiceLines[i].Description, +// Quantity = invoiceLines[i].Quantity, +// Price = invoiceLines[i].Price, +// Discount = Convert.ToInt32(invoiceLines[i].Discount) +// }; + +// line.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line); +// result.Add(line); +// } +// return result; +// } + +// /// +// /// Updates the selected invoice with the parameters (contactId, consigneeId, etc.) specified in the request +// /// +// /// Invoice ID +// /// Invoice issue date +// /// Invoice template type +// /// Invoice contact ID +// /// Invoice consignee ID +// /// Invoice entity ID +// /// Invoice billing address ID +// /// Invoice delivery address ID +// /// Invoice due date +// /// Invoice language +// /// Invoice currency +// /// Invoice exchange rate +// /// Invoice purchase order number +// /// Invoice terms +// /// Invoice description +// /// Invoice lines list +// /// Update invoice +// /// Invoices +// /// Invoice +// /// +// /// +// /// +// [Update(@"invoice/{id:int}")] +// public InvoiceWrapper UpdateInvoice( +// int id, +// ApiDateTime issueDate, +// int templateType, +// int contactId, +// int consigneeId, +// int entityId, +// int billingAddressID, +// int deliveryAddressID, +// ApiDateTime dueDate, +// string language, +// string currency, +// decimal exchangeRate, +// string purchaseOrderNumber, +// string terms, +// string description, +// IEnumerable invoiceLines) +// { + +// var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); +// if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); + +// var invoice = DaoFactory.GetInvoiceDao().GetByID(id); +// if (invoice == null || !CRMSecurity.CanEdit(invoice)) throw new ItemNotFoundException(); + +// invoice.IssueDate = issueDate; +// invoice.TemplateType = (InvoiceTemplateType)templateType; +// invoice.ContactID = contactId; +// invoice.ConsigneeID = consigneeId; +// invoice.EntityType = EntityType.Opportunity; +// invoice.EntityID = entityId; +// invoice.DueDate = dueDate; +// invoice.Language = language; +// invoice.Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null;; +// invoice.ExchangeRate = exchangeRate; +// invoice.PurchaseOrderNumber = purchaseOrderNumber; +// invoice.Terms = terms; +// invoice.Description = description; +// invoice.JsonData = null; + +// CRMSecurity.DemandCreateOrUpdate(invoice); + +// if (billingAddressID > 0) +// { +// var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); +// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) +// throw new ArgumentException(); +// } + +// if (deliveryAddressID > 0) +// { +// var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); +// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) +// throw new ArgumentException(); +// } + +// DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + + +// DaoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID); +// CreateInvoiceLines(invoiceLinesList, invoice); + +// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + +// if (Global.CanDownloadInvoices) +// { +// // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); +// } + +// return InvoiceWrapperHelper.Get(invoice); +// } + +// /// +// /// Returns the pdf file associated with the invoice with the ID specified in the request +// /// +// /// Invoice ID +// /// Get invoice pdf file +// /// Invoices +// /// File +// [Read(@"invoice/{invoiceid:int}/pdf")] +// public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) +// { +// if (invoiceid <= 0) throw new ArgumentException(); + +// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); +// if (invoice == null) throw new ItemNotFoundException(); + +// if (!CRMSecurity.CanAccessTo(invoice)) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// return FileWrapperHelper.Get(Global.GetInvoicePdfExistingOrCreate(invoice, DaoFactory)); +// } + +//public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) +//{ +// var existingFile = invoice.GetInvoiceFile(factory); +// if (existingFile != null) +// { +// return existingFile; +// } +// else +// { +// var newFile = PdfCreator.CreateFile(invoice, factory); + +// invoice.FileID = Int32.Parse(newFile.ID.ToString()); + +// factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + +// factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + +// return newFile; +// } +//} + + +// /// +// /// Returns information about the generation of the pdf file of the invoice +// /// +// /// Invoice ID +// /// Storage Url +// /// Revision ID +// /// Check invoice pdf file +// /// Invoices +// /// ConverterData +// [Create(@"invoice/converter/data")] +// public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, string revisionId) +// { +// if (invoiceId <= 0) throw new ArgumentException(); + +// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); +// if (invoice == null) throw new ItemNotFoundException(); + +// if (!CRMSecurity.CanAccessTo(invoice)) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// var converterData = new ConverterData +// { +// StorageUrl = storageUrl, +// RevisionId = revisionId, +// InvoiceId = invoiceId +// }; + +// var existingFile = invoice.GetInvoiceFile(DaoFactory); +// if (existingFile != null) +// { +// converterData.FileId = invoice.FileID; +// return converterData; +// } + +// if (string.IsNullOrEmpty(storageUrl) || string.IsNullOrEmpty(revisionId)) +// { +// return PdfCreator.StartCreationFileAsync(invoice); +// } +// else +// { +// var convertedFile = PdfCreator.GetConvertedFile(converterData, DaoFactory); +// if (convertedFile != null) +// { +// invoice.FileID = Int32.Parse(convertedFile.ID.ToString()); +// DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); +// DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + +// converterData.FileId = invoice.FileID; +// return converterData; +// } +// else +// { +// return converterData; +// } +// } +// } + +// /// +// /// Returns the existence of the invoice with the Number specified in the request +// /// +// /// Invoice number +// /// Check invoice existence by number +// /// Invoices +// /// IsExist +// [Read(@"invoice/bynumber/exist")] +// public Boolean GetInvoiceByNumberExistence(string number) +// { +// if (String.IsNullOrEmpty(number)) throw new ArgumentException(); + +// return DaoFactory.GetInvoiceDao().IsExist(number); + +// } + +// /// +// /// Returns the detailed information about the invoice with the Number specified in the request +// /// +// /// Invoice number +// /// Get invoice by number +// /// Invoices +// /// Invoice +// [Read(@"invoice/bynumber")] +// public InvoiceWrapper GetInvoiceByNumber(string number) +// { +// if (String.IsNullOrEmpty(number)) throw new ArgumentException(); + +// var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number); +// if (invoice == null) throw new ItemNotFoundException(); + +// if (!CRMSecurity.CanAccessTo(invoice)) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// return InvoiceWrapperHelper.Get(invoice); +// } + +// /// +// /// Returns the list of invoice items matching the creteria specified in the request +// /// +// /// Status +// /// InventoryStock +// /// Get invoice item list +// /// Invoices +// /// InvoiceItem list +// [Read(@"invoiceitem/filter")] +// public IEnumerable GetInvoiceItems(int status, bool? inventoryStock) +// { +// IEnumerable result; + +// InvoiceItemSortedByType sortBy; + +// OrderBy invoiceOrderBy; + +// var searchString = ApiContext.FilterValue; + +// if (InvoiceItemSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) +// { +// invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); +// } +// else if (String.IsNullOrEmpty(ApiContext.SortBy)) +// { +// invoiceOrderBy = new OrderBy(InvoiceItemSortedByType.Name, true); +// } +// else +// { +// invoiceOrderBy = null; +// } + +// var fromIndex = (int)ApiContext.StartIndex; +// var count = (int)ApiContext.Count; + +// if (invoiceOrderBy != null) +// { +// result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( +// searchString, +// status, +// inventoryStock, +// fromIndex, count, +// invoiceOrderBy) +// .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); + +// ApiContext.SetDataPaginated(); +// ApiContext.SetDataFiltered(); +// ApiContext.SetDataSorted(); +// } +// else +// { +// result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( +// searchString, +// status, +// inventoryStock, +// 0, 0, +// null) +// .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); +// } + +// int totalCount; + +// if (result.Count() < count) +// { +// totalCount = fromIndex + result.Count(); +// } +// else +// { +// totalCount = DaoFactory.GetInvoiceItemDao().GetInvoiceItemsCount( +// searchString, +// status, +// inventoryStock); +// } + +// ApiContext.SetTotalCount(totalCount); + +// return result; +// } + +// /// +// /// Returns the detailed information about the invoice item with the ID specified in the request +// /// +// /// Invoice Item ID +// /// Get invoice item by ID +// /// Invoices +// /// Invoice Item +// [Read(@"invoiceitem/{invoiceitemid:int}")] +// public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) +// { +// if (invoiceitemid <= 0) throw new ArgumentException(); + +// var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); +// if (invoiceItem == null) throw new ItemNotFoundException(); + +// return InvoiceItemWrapperHelper.Get(invoiceItem); +// } + +// /// +// /// Creates the invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request +// /// +// /// Invoice ID +// /// Invoice item ID +// /// First invoice tax ID +// /// Second invoice tax ID +// /// Sort Order +// /// Description +// /// Quantity +// /// Price +// /// Discount +// /// Create invoice line +// /// Invoices +// /// InvoiceLine +// [Create(@"invoiceline")] +// public InvoiceLineWrapper CreateInvoiceLine( +// int invoiceId, +// int invoiceItemId, +// int invoiceTax1Id, +// int invoiceTax2Id, +// int sortOrder, +// string description, +// int quantity, +// decimal price, +// int discount +// ) +// { +// var invoiceLine = new InvoiceLine +// { +// InvoiceID = invoiceId, +// InvoiceItemID = invoiceItemId, +// InvoiceTax1ID = invoiceTax1Id, +// InvoiceTax2ID = invoiceTax2Id, +// SortOrder = sortOrder, +// Description = description, +// Quantity = quantity, +// Price = price, +// Discount = discount +// }; + +// if (invoiceId <= 0) +// throw new ArgumentException(); + +// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + +// CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + +// invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + +// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); +// if (Global.CanDownloadInvoices) +// { +// // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); +// } + +// return InvoiceLineWrapperHelper.Get(invoiceLine); +// } + +// /// +// /// Updates the selected invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request +// /// +// /// Line ID +// /// Invoice ID +// /// Invoice item ID +// /// First invoice tax ID +// /// Second invoice tax ID +// /// Sort Order +// /// Description +// /// Quantity +// /// Price +// /// Discount +// /// Update invoice line +// /// Invoices +// /// InvoiceLine +// [Update(@"invoiceline/{id:int}")] +// public InvoiceLineWrapper UpdateInvoiceLine( +// int id, +// int invoiceId, +// int invoiceItemId, +// int invoiceTax1Id, +// int invoiceTax2Id, +// int sortOrder, +// string description, +// int quantity, +// decimal price, +// int discount +// ) +// { +// if (invoiceId <= 0) +// throw new ArgumentException(); + +// var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); +// if (invoiceLine == null || invoiceLine.InvoiceID != invoiceId) throw new ItemNotFoundException(); + + +// invoiceLine.InvoiceID = invoiceId; +// invoiceLine.InvoiceItemID = invoiceItemId; +// invoiceLine.InvoiceTax1ID = invoiceTax1Id; +// invoiceLine.InvoiceTax2ID = invoiceTax2Id; +// invoiceLine.SortOrder = sortOrder; +// invoiceLine.Description = description; +// invoiceLine.Quantity = quantity; +// invoiceLine.Price = price; +// invoiceLine.Discount = discount; + +// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); +// CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + +// DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + +// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + +// if (Global.CanDownloadInvoices) +// { +//// PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); +// } + +// return InvoiceLineWrapperHelper.Get(invoiceLine); +// } + +// /// +// /// Deletes the invoice line with the ID specified in the request +// /// +// /// Line ID +// /// Delete invoice line +// /// Invoices +// /// Line ID +// [Delete(@"invoiceline/{id:int}")] +// public int DeleteInvoiceLine(int id) +// { +// var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); +// if (invoiceLine == null) throw new ItemNotFoundException(); +// if (!DaoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line"); + +// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID); +// if (invoice == null) throw new ItemNotFoundException(); +// if (!CRMSecurity.CanEdit(invoice)) throw CRMSecurity.CreateSecurityException(); + +// DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); + +// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + +// if (Global.CanDownloadInvoices) +// { +// // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); +// } + +// return id; +// } + +// /// +// /// Creates the invoice item with the parameters (title, description, price, etc.) specified in the request +// /// +// /// Item title +// /// Item description +// /// Item price +// /// Item stock keeping unit +// /// Item quantity +// /// Item stock quantity +// /// Track inventory +// /// Item first invoice tax ID +// /// Item second invoice tax ID +// /// Create invoice item +// /// Invoices +// /// InvoiceItem +// [Create(@"invoiceitem")] +// public InvoiceItemWrapper CreateInvoiceItem( +// string title, +// string description, +// decimal price, +// string sku, +// int quantity, +// int stockQuantity, +// bool trackInventory, +// int invoiceTax1id, +// int invoiceTax2id) +// { +// if (!CRMSecurity.IsAdmin) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// if (String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); + +// var invoiceItem = new InvoiceItem +// { +// Title = title, +// Description = description, +// Price = price, +// StockKeepingUnit = sku, +// StockQuantity = stockQuantity, +// TrackInventory = trackInventory, +// InvoiceTax1ID = invoiceTax1id, +// InvoiceTax2ID = invoiceTax2id +// }; + +// invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + +// MessageService.Send( MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + +// return InvoiceItemWrapperHelper.Get(invoiceItem); +// } + +// /// +// /// Updates the selected invoice item with the parameters (title, description, price, etc.) specified in the request +// /// +// /// Item ID +// /// Item title +// /// Item description +// /// Item price +// /// Item stock keeping unit +// /// Item quantity +// /// Item stock quantity +// /// Track inventory +// /// Item first invoice tax ID +// /// Item second invoice tax ID +// /// Update invoice item +// /// Invoices +// /// InvoiceItem +// [Update(@"invoiceitem/{id:int}")] +// public InvoiceItemWrapper UpdateInvoiceItem(int id, +// string title, +// string description, +// decimal price, +// string sku, +// int quantity, +// int stockQuantity, +// bool trackInventory, +// int invoiceTax1id, +// int invoiceTax2id) +// { +// if (!CRMSecurity.IsAdmin) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// if (id <= 0 || String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); + +// if (!DaoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException(); + +// var invoiceItem = new InvoiceItem +// { +// ID = id, +// Title = title, +// Description = description, +// Price = price, +// StockKeepingUnit = sku, +// StockQuantity = stockQuantity, +// TrackInventory = trackInventory, +// InvoiceTax1ID = invoiceTax1id, +// InvoiceTax2ID = invoiceTax2id +// }; + +// invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); +// MessageService.Send( MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + +// return InvoiceItemWrapperHelper.Get(invoiceItem); +// } + +// /// +// /// Deletes the invoice item with the ID specified in the request +// /// +// /// Item ID +// /// Delete invoice item +// /// Invoices +// /// InvoiceItem +// [Delete(@"invoiceitem/{id:int}")] +// public InvoiceItemWrapper DeleteInvoiceItem(int id) +// { +// if (!CRMSecurity.IsAdmin) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// if (id <= 0) throw new ArgumentException(); + +// var invoiceItem = DaoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id); +// if (invoiceItem == null) throw new ItemNotFoundException(); + +// MessageService.Send( MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + +// return InvoiceItemWrapperHelper.Get(invoiceItem); + +// } + +// /// +// /// Deletes the group of invoice items with the IDs specified in the request +// /// +// /// Item ID list +// /// Delete Invoice item group +// /// Invoices +// /// InvoiceItem list +// [Delete(@"invoiceitem")] +// public IEnumerable DeleteBatchItems(IEnumerable ids) +// { +// if (!CRMSecurity.IsAdmin) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// if (ids == null) throw new ArgumentException(); +// ids = ids.Distinct(); + +// var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); +// MessageService.Send( MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); + +// return items.ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); +// } + +// /// +// /// Returns the list of invoice taxes +// /// +// /// Get invoice taxes list +// /// Invoices +// /// InvoiceTax list +// [Read(@"invoice/tax")] +// public IEnumerable GetInvoiceTaxes() +// { +// return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxWrapperHelper.Get(x)); +// } + +// /// +// /// Creates the invoice tax with the parameters (name, description, rate) specified in the request +// /// +// /// Tax name +// /// Tax description +// /// Tax rate +// /// Create invoice tax +// /// Invoices +// /// InvoiceTax +// [Create(@"invoice/tax")] +// public InvoiceTaxWrapper CreateInvoiceTax( +// string name, +// string description, +// decimal rate) +// { +// if (!CRMSecurity.IsAdmin) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// if (String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); +// if (DaoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError); + +// var invoiceTax = new InvoiceTax +// { +// Name = name, +// Description = description, +// Rate = rate +// }; + +// invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); +// MessageService.Send( MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + +// return InvoiceTaxWrapperHelper.Get(invoiceTax); +// } + +// /// +// /// Updates the selected invoice tax with the parameters (name, description, rate) specified in the request +// /// +// /// Tax ID +// /// Tax name +// /// Tax description +// /// Tax rate +// /// Update invoice tax +// /// Invoices +// /// InvoiceTax +// [Update(@"invoice/tax/{id:int}")] +// public InvoiceTaxWrapper UpdateInvoiceTax( +// int id, +// string name, +// string description, +// decimal rate) +// { +// if (!CRMSecurity.IsAdmin) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// if (id <= 0 || String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); + +// if (!DaoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException(); + +// var invoiceTax = new InvoiceTax +// { +// ID = id, +// Name = name, +// Description = description, +// Rate = rate +// }; + +// invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); +// MessageService.Send( MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + +// return InvoiceTaxWrapperHelper.Get(invoiceTax); +// } + +// /// +// /// Delete the invoice tax with the ID specified in the request +// /// +// /// Tax ID +// /// Delete invoice tax +// /// Invoices +// /// InvoiceTax +// [Delete(@"invoice/tax/{id:int}")] +// public InvoiceTaxWrapper DeleteInvoiceTax(int id) +// { +// if (!CRMSecurity.IsAdmin) { +// throw CRMSecurity.CreateSecurityException(); +// } + +// if (id <= 0) throw new ArgumentException(); + +// var invoiceTax = DaoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id); +// if (invoiceTax == null) throw new ItemNotFoundException(); + +// MessageService.Send( MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + +// return InvoiceTaxWrapperHelper.Get(invoiceTax); +// } + +// /// +// /// Get default invoice settings +// /// +// /// Get default invoice settings +// /// Invoices +// /// InvoiceSetting +// [Read(@"invoice/settings")] +// public InvoiceSetting GetSettings() +// { +// return DaoFactory.GetInvoiceDao().GetSettings(); +// } + +// /// +// /// Save default invoice number +// /// +// /// Is autogenerated +// /// Prefix +// /// Number +// /// Save default invoice number +// /// Invoices +// /// InvoiceSetting +// [Update(@"invoice/settings/name")] +// public InvoiceSetting SaveNumberSettings(bool autogenerated, string prefix, string number) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// if (autogenerated && string.IsNullOrEmpty(number)) +// throw new ArgumentException(); + +// if (autogenerated && DaoFactory.GetInvoiceDao().IsExist(prefix + number)) +// throw new ArgumentException(); + +// var invoiceSetting = GetSettings(); + +// invoiceSetting.Autogenerated = autogenerated; +// invoiceSetting.Prefix = prefix; +// invoiceSetting.Number = number; + +// var settings = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); +// MessageService.Send( MessageAction.InvoiceNumberFormatUpdated); + +// return settings; +// } + +// /// +// /// Save default invoice terms +// /// +// /// Terms +// /// Save default invoice terms +// /// Invoices +// /// InvoiceSetting +// [Update(@"invoice/settings/terms")] +// public InvoiceSetting SaveTermsSettings(string terms) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var invoiceSetting = GetSettings(); + +// invoiceSetting.Terms = terms; + +// var result = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); +// MessageService.Send( MessageAction.InvoiceDefaultTermsUpdated); + +// return result; +// } + +// /// false +// [Update(@"invoice/{invoiceid:int}/creationdate")] +// public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate) +// { +// var dao = DaoFactory.GetInvoiceDao(); +// var invoice = dao.GetByID(invoiceid); + +// if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) +// throw new ItemNotFoundException(); + +// dao.SetInvoiceCreationDate(invoiceid, creationDate); +// } + +// /// false +// [Update(@"invoice/{invoiceid:int}/lastmodifeddate")] +// public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate) +// { +// var dao = DaoFactory.GetInvoiceDao(); +// var invoice = dao.GetByID(invoiceid); + +// if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) +// throw new ItemNotFoundException(); - if (invoice.EntityID > 0) - { - invoiceWrapper.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); //Need to optimize - } +// dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); +// } - invoiceWrapper.Cost = invoice.GetInvoiceCost(DaoFactory); +// private IEnumerable ToListInvoiceBaseWrappers(ICollection items) +// { +// if (items == null || items.Count == 0) return new List(); + +// var result = new List(); + + +// var contactIDs = items.Select(item => item.ContactID); +// contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID)); + +// var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) +// .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); + + +// foreach (var invoice in items) +// { +// var invoiceWrapper = InvoiceBaseWrapperHelper.Get(invoice); - result.Add(invoiceWrapper); - } +// if (contacts.ContainsKey(invoice.ContactID)) +// { +// invoiceWrapper.Contact = contacts[invoice.ContactID]; +// } - return result; - } - } -} \ No newline at end of file +// if (contacts.ContainsKey(invoice.ConsigneeID)) +// { +// invoiceWrapper.Consignee = contacts[invoice.ContactID]; +// } + +// if (invoice.EntityID > 0) +// { +// invoiceWrapper.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); //Need to optimize +// } + +// invoiceWrapper.Cost = invoice.GetInvoiceCost(DaoFactory); + +// result.Add(invoiceWrapper); +// } + +// return result; +// } +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs b/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs index 1da7db9f7bf..9a6c5e6fd41 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs @@ -31,6 +31,7 @@ using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Api.Routing; + using System; using System.Collections.Generic; using System.Linq; @@ -69,16 +70,16 @@ public DealMilestoneWrapper CreateDealMilestone( if (successProbability < 0) successProbability = 0; var dealMilestone = new DealMilestone - { - Title = title, - Color = color, - Description = description, - Probability = successProbability, - Status = stageType - }; + { + Title = title, + Color = color, + Description = description, + Probability = successProbability, + Status = stageType + }; dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone); - MessageService.Send( MessageAction.OpportunityStageCreated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + MessageService.Send(MessageAction.OpportunityStageCreated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneWrapper(dealMilestone); } @@ -118,17 +119,17 @@ public DealMilestoneWrapper UpdateDealMilestone( if (!curDealMilestoneExist) throw new ItemNotFoundException(); var dealMilestone = new DealMilestone - { - Title = title, - Color = color, - Description = description, - Probability = successProbability, - Status = stageType, - ID = id - }; + { + Title = title, + Color = color, + Description = description, + Probability = successProbability, + Status = stageType, + ID = id + }; DaoFactory.GetDealMilestoneDao().Edit(dealMilestone); - MessageService.Send( MessageAction.OpportunityStageUpdated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + MessageService.Send(MessageAction.OpportunityStageUpdated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneWrapper(dealMilestone); } @@ -158,7 +159,7 @@ public DealMilestoneWrapper UpdateDealMilestoneColor(int id, string color) dealMilestone.Color = color; DaoFactory.GetDealMilestoneDao().ChangeColor(id, color); - MessageService.Send( MessageAction.OpportunityStageUpdatedColor, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + MessageService.Send(MessageAction.OpportunityStageUpdatedColor, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneWrapper(dealMilestone); } @@ -189,7 +190,7 @@ public IEnumerable UpdateDealMilestonesOrder(IEnumerable DaoFactory.GetDealMilestoneDao().GetByID(id)).ToList(); DaoFactory.GetDealMilestoneDao().Reorder(idsList.ToArray()); - MessageService.Send( MessageAction.OpportunityStagesUpdatedOrder, MessageTarget.Create(idsList), result.Select(x => x.Title)); + MessageService.Send(MessageAction.OpportunityStagesUpdatedOrder, MessageTarget.Create(idsList), result.Select(x => x.Title)); return result.Select(ToDealMilestoneWrapper); } @@ -218,7 +219,7 @@ public DealMilestoneWrapper DeleteDealMilestone(int id) var result = ToDealMilestoneWrapper(dealMilestone); DaoFactory.GetDealMilestoneDao().Delete(id); - MessageService.Send( MessageAction.OpportunityStageDeleted, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + MessageService.Send(MessageAction.OpportunityStageDeleted, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return result; } @@ -242,15 +243,15 @@ public HistoryCategoryWrapper CreateHistoryCategory(string title, string descrip if (string.IsNullOrEmpty(title)) throw new ArgumentException(); var listItem = new ListItem - { - Title = title, - Description = description, - SortOrder = sortOrder, - AdditionalParams = imageName - }; + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName + }; listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.HistoryCategory, listItem); - MessageService.Send( MessageAction.HistoryEventCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.HistoryEventCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); return ToHistoryCategoryWrapper(listItem); } @@ -279,16 +280,16 @@ public HistoryCategoryWrapper UpdateHistoryCategory(int id, string title, string if (!curHistoryCategoryExist) throw new ItemNotFoundException(); var listItem = new ListItem - { - Title = title, - Description = description, - SortOrder = sortOrder, - AdditionalParams = imageName, - ID = id - }; + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName, + ID = id + }; DaoFactory.GetListItemDao().EditItem(ListType.HistoryCategory, listItem); - MessageService.Send( MessageAction.HistoryEventCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.HistoryEventCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); return ToHistoryCategoryWrapper(listItem); } @@ -318,7 +319,7 @@ public HistoryCategoryWrapper UpdateHistoryCategoryIcon(int id, string imageName historyCategory.AdditionalParams = imageName; DaoFactory.GetListItemDao().ChangePicture(id, imageName); - MessageService.Send( MessageAction.HistoryEventCategoryUpdatedIcon, MessageTarget.Create(historyCategory.ID), historyCategory.Title); + MessageService.Send(MessageAction.HistoryEventCategoryUpdatedIcon, MessageTarget.Create(historyCategory.ID), historyCategory.Title); return ToHistoryCategoryWrapper(historyCategory); } @@ -347,7 +348,7 @@ public IEnumerable UpdateHistoryCategoriesOrder(IEnumera var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.HistoryCategory, title)).ToList(); DaoFactory.GetListItemDao().ReorderItems(ListType.HistoryCategory, titles.ToArray()); - MessageService.Send( MessageAction.HistoryEventCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + MessageService.Send(MessageAction.HistoryEventCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToHistoryCategoryWrapper); } @@ -373,14 +374,15 @@ public HistoryCategoryWrapper DeleteHistoryCategory(int id) var listItem = dao.GetByID(id); if (listItem == null) throw new ItemNotFoundException(); - if (dao.GetItemsCount(ListType.HistoryCategory) < 2) { + if (dao.GetItemsCount(ListType.HistoryCategory) < 2) + { throw new ArgumentException("The last history category cannot be deleted"); } var result = ToHistoryCategoryWrapper(listItem); dao.DeleteItem(ListType.HistoryCategory, id, 0); - MessageService.Send( MessageAction.HistoryEventCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.HistoryEventCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); return result; } @@ -405,15 +407,15 @@ public TaskCategoryWrapper CreateTaskCategory(string title, string description, if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); var listItem = new ListItem - { - Title = title, - Description = description, - SortOrder = sortOrder, - AdditionalParams = imageName - }; + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName + }; listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.TaskCategory, listItem); - MessageService.Send( MessageAction.CrmTaskCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.CrmTaskCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryWrapper(listItem); } @@ -446,16 +448,16 @@ public TaskCategoryWrapper UpdateTaskCategory(int id, string title, string descr if (!curTaskCategoryExist) throw new ItemNotFoundException(); var listItem = new ListItem - { - Title = title, - Description = description, - SortOrder = sortOrder, - AdditionalParams = imageName, - ID = id - }; + { + Title = title, + Description = description, + SortOrder = sortOrder, + AdditionalParams = imageName, + ID = id + }; DaoFactory.GetListItemDao().EditItem(ListType.TaskCategory, listItem); - MessageService.Send( MessageAction.CrmTaskCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.CrmTaskCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryWrapper(listItem); } @@ -485,7 +487,7 @@ public TaskCategoryWrapper UpdateTaskCategoryIcon(int id, string imageName) taskCategory.AdditionalParams = imageName; DaoFactory.GetListItemDao().ChangePicture(id, imageName); - MessageService.Send( MessageAction.CrmTaskCategoryUpdatedIcon, MessageTarget.Create(taskCategory.ID), taskCategory.Title); + MessageService.Send(MessageAction.CrmTaskCategoryUpdatedIcon, MessageTarget.Create(taskCategory.ID), taskCategory.Title); return ToTaskCategoryWrapper(taskCategory); } @@ -514,7 +516,7 @@ public IEnumerable UpdateTaskCategoriesOrder(IEnumerable DaoFactory.GetListItemDao().GetByTitle(ListType.TaskCategory, title)).ToList(); DaoFactory.GetListItemDao().ReorderItems(ListType.TaskCategory, titles.ToArray()); - MessageService.Send( MessageAction.CrmTaskCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + MessageService.Send(MessageAction.CrmTaskCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToTaskCategoryWrapper); } @@ -540,12 +542,13 @@ public TaskCategoryWrapper DeleteTaskCategory(int categoryid, int newcategoryid) var listItem = dao.GetByID(categoryid); if (listItem == null) throw new ItemNotFoundException(); - if (dao.GetItemsCount(ListType.TaskCategory) < 2) { + if (dao.GetItemsCount(ListType.TaskCategory) < 2) + { throw new ArgumentException("The last task category cannot be deleted"); } - dao.DeleteItem(ListType.TaskCategory, categoryid, newcategoryid); - MessageService.Send( MessageAction.CrmTaskCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + dao.DeleteItem(ListType.TaskCategory, categoryid, newcategoryid); + MessageService.Send(MessageAction.CrmTaskCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryWrapper(listItem); } @@ -570,15 +573,15 @@ public ContactStatusWrapper CreateContactStatus(string title, string description if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); var listItem = new ListItem - { - Title = title, - Description = description, - Color = color, - SortOrder = sortOrder - }; + { + Title = title, + Description = description, + Color = color, + SortOrder = sortOrder + }; listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.ContactStatus, listItem); - MessageService.Send( MessageAction.ContactTemperatureLevelCreated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.ContactTemperatureLevelCreated, MessageTarget.Create(listItem.ID), listItem.Title); return ToContactStatusWrapper(listItem); } @@ -611,16 +614,16 @@ public ContactStatusWrapper UpdateContactStatus(int id, string title, string des if (!curListItemExist) throw new ItemNotFoundException(); var listItem = new ListItem - { - ID = id, - Title = title, - Description = description, - Color = color, - SortOrder = sortOrder - }; + { + ID = id, + Title = title, + Description = description, + Color = color, + SortOrder = sortOrder + }; DaoFactory.GetListItemDao().EditItem(ListType.ContactStatus, listItem); - MessageService.Send( MessageAction.ContactTemperatureLevelUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.ContactTemperatureLevelUpdated, MessageTarget.Create(listItem.ID), listItem.Title); return ToContactStatusWrapper(listItem); } @@ -650,7 +653,7 @@ public ContactStatusWrapper UpdateContactStatusColor(int id, string color) contactStatus.Color = color; DaoFactory.GetListItemDao().ChangeColor(id, color); - MessageService.Send( MessageAction.ContactTemperatureLevelUpdatedColor, MessageTarget.Create(contactStatus.ID), contactStatus.Title); + MessageService.Send(MessageAction.ContactTemperatureLevelUpdatedColor, MessageTarget.Create(contactStatus.ID), contactStatus.Title); return ToContactStatusWrapper(contactStatus); } @@ -679,7 +682,7 @@ public IEnumerable UpdateContactStatusesOrder(IEnumerable< var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.ContactStatus, title)).ToList(); DaoFactory.GetListItemDao().ReorderItems(ListType.ContactStatus, titles.ToArray()); - MessageService.Send( MessageAction.ContactTemperatureLevelsUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + MessageService.Send(MessageAction.ContactTemperatureLevelsUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToContactStatusWrapper); } @@ -707,14 +710,15 @@ public ContactStatusWrapper DeleteContactStatus(int contactStatusid) var listItem = dao.GetByID(contactStatusid); if (listItem == null) throw new ItemNotFoundException(); - if (dao.GetItemsCount(ListType.ContactStatus) < 2) { + if (dao.GetItemsCount(ListType.ContactStatus) < 2) + { throw new ArgumentException("The last contact status cannot be deleted"); } var contactStatus = ToContactStatusWrapper(listItem); dao.DeleteItem(ListType.ContactStatus, contactStatusid, 0); - MessageService.Send( MessageAction.ContactTemperatureLevelDeleted, MessageTarget.Create(contactStatus.Id), contactStatus.Title); + MessageService.Send(MessageAction.ContactTemperatureLevelDeleted, MessageTarget.Create(contactStatus.Id), contactStatus.Title); return contactStatus; } @@ -757,14 +761,14 @@ public ContactTypeWrapper CreateContactType(string title, int sortOrder) if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); var listItem = new ListItem - { - Title = title, - Description = string.Empty, - SortOrder = sortOrder - }; + { + Title = title, + Description = string.Empty, + SortOrder = sortOrder + }; listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.ContactType, listItem); - MessageService.Send( MessageAction.ContactTypeCreated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.ContactTypeCreated, MessageTarget.Create(listItem.ID), listItem.Title); return ToContactTypeWrapper(listItem); } @@ -795,14 +799,14 @@ public ContactTypeWrapper UpdateContactType(int id, string title, int sortOrder) if (!curListItemExist) throw new ItemNotFoundException(); var listItem = new ListItem - { - ID = id, - Title = title, - SortOrder = sortOrder - }; + { + ID = id, + Title = title, + SortOrder = sortOrder + }; DaoFactory.GetListItemDao().EditItem(ListType.ContactType, listItem); - MessageService.Send( MessageAction.ContactTypeUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.ContactTypeUpdated, MessageTarget.Create(listItem.ID), listItem.Title); return ToContactTypeWrapper(listItem); } @@ -831,7 +835,7 @@ public IEnumerable UpdateContactTypesOrder(IEnumerable DaoFactory.GetListItemDao().GetByTitle(ListType.ContactType, title)).ToList(); DaoFactory.GetListItemDao().ReorderItems(ListType.ContactType, titles.ToArray()); - MessageService.Send( MessageAction.ContactTypesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + MessageService.Send(MessageAction.ContactTypesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToContactTypeWrapper); } @@ -858,15 +862,16 @@ public ContactTypeWrapper DeleteContactType(int contactTypeid) var listItem = dao.GetByID(contactTypeid); if (listItem == null) throw new ItemNotFoundException(); - - if (dao.GetItemsCount(ListType.ContactType) < 2) { + + if (dao.GetItemsCount(ListType.ContactType) < 2) + { throw new ArgumentException("The last contact type cannot be deleted"); } - + var contactType = ToContactTypeWrapper(listItem); dao.DeleteItem(ListType.ContactType, contactTypeid, 0); - MessageService.Send( MessageAction.ContactTypeDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + MessageService.Send(MessageAction.ContactTypeDeleted, MessageTarget.Create(listItem.ID), listItem.Title); return contactType; } @@ -1051,9 +1056,9 @@ public IEnumerable GetDealMilestones() public ContactStatusWrapper ToContactStatusWrapper(ListItem listItem) { var result = new ContactStatusWrapper(listItem) - { - RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, listItem.ID) - }; + { + RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, listItem.ID) + }; return result; } @@ -1061,9 +1066,9 @@ public ContactStatusWrapper ToContactStatusWrapper(ListItem listItem) public ContactTypeWrapper ToContactTypeWrapper(ListItem listItem) { var result = new ContactTypeWrapper(listItem) - { - RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, listItem.ID) - }; + { + RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, listItem.ID) + }; return result; } @@ -1073,7 +1078,7 @@ public HistoryCategoryWrapper ToHistoryCategoryWrapper(ListItem listItem) var result = (HistoryCategoryWrapper)HistoryCategoryWrapperHelper.Get(listItem); result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID); - + return result; } @@ -1082,16 +1087,16 @@ public TaskCategoryWrapper ToTaskCategoryWrapper(ListItem listItem) var result = (TaskCategoryWrapper)TaskCategoryWrapperHelper.Get(listItem); result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID); - + return result; } private DealMilestoneWrapper ToDealMilestoneWrapper(DealMilestone dealMilestone) { var result = new DealMilestoneWrapper(dealMilestone) - { - RelativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(dealMilestone.ID) - }; + { + RelativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(dealMilestone.ID) + }; return result; } } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs index 4e7e6e64d46..4fdd6a61bcf 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs @@ -36,7 +36,9 @@ using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Classes; using ASC.Web.Files.Utils; + using Microsoft.AspNetCore.Http; + using System; using System.Collections; using System.Collections.Generic; @@ -45,6 +47,7 @@ using System.Net.Mime; using System.Text; using System.Text.RegularExpressions; + using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.Api.CRM @@ -78,7 +81,8 @@ public IEnumerable GetHistory( { var entityTypeObj = ToEntityType(entityType); - switch (entityTypeObj) { + switch (entityTypeObj) + { case EntityType.Contact: var contact = DaoFactory.GetContactDao().GetByID(entityId); if (contact == null || !CRMSecurity.CanAccessTo(contact)) @@ -183,7 +187,7 @@ public RelationshipEventWrapper DeleteHistory(int id) var messageAction = GetHistoryDeletedAction(item.EntityType, item.ContactID); var entityTitle = wrapper.Contact == null ? wrapper.Entity.EntityTitle : wrapper.Contact.DisplayName; - MessageService.Send( messageAction, MessageTarget.Create(item.ID), entityTitle, wrapper.Category.Title); + MessageService.Send(messageAction, MessageTarget.Create(item.ID), entityTitle, wrapper.Category.Title); return wrapper; } @@ -200,7 +204,7 @@ public RelationshipEventWrapper DeleteHistory(int id) /// /// File info /// - [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/text")] + [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files/text")] public FileWrapper CreateTextFile(string entityType, int entityid, string title, string content) { if (title == null) throw new ArgumentNullException("title"); @@ -225,7 +229,7 @@ public FileWrapper CreateTextFile(string entityType, int entityid, string t result = SaveFile(folderid, memStream, title); } - AttachFiles(entityType, entityid, new List {(int)result.Id}); + AttachFiles(entityType, entityid, new List { (int)result.Id }); return result; } @@ -253,42 +257,42 @@ public FileWrapper CreateTextFile(string entityType, int entityid, string t /// /// File info /// - [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/upload")] - public FileWrapper UploadFileInCRM( - string entityType, - int entityid, - Stream file, - ContentType contentType, - ContentDisposition contentDisposition, - IEnumerable files, - bool storeOriginalFileFlag - ) - { - FilesSettings.StoreOriginalFilesSetting = storeOriginalFileFlag; - - var folderid = GetRootFolderID(); - - var fileNames = new List(); - - FileWrapper uploadedFile = null; - if (files != null && files.Any()) - { - //For case with multiple files - foreach (var postedFile in files) - { - using var fileStream = postedFile.OpenReadStream(); - uploadedFile = SaveFile(folderid, fileStream, postedFile.FileName); - fileNames.Add(uploadedFile.Title); - } - } - else if (file != null) - { - uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); - fileNames.Add(uploadedFile.Title); - } - - return uploadedFile; - } + //[Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files/upload")] + //public FileWrapper UploadFileInCRM( + // string entityType, + // int entityid, + // Stream file, + // ContentType contentType, + // ContentDisposition contentDisposition, + // IEnumerable files, + // bool storeOriginalFileFlag + // ) + //{ + // FilesSettings.StoreOriginalFilesSetting = storeOriginalFileFlag; + + // var folderid = GetRootFolderID(); + + // var fileNames = new List(); + + // FileWrapper uploadedFile = null; + // if (files != null && files.Any()) + // { + // //For case with multiple files + // foreach (var postedFile in files) + // { + // using var fileStream = postedFile.OpenReadStream(); + // uploadedFile = SaveFile(folderid, fileStream, postedFile.FileName); + // fileNames.Add(uploadedFile.Title); + // } + // } + // else if (file != null) + // { + // uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); + // fileNames.Add(uploadedFile.Title); + // } + + // return uploadedFile; + //} private FileWrapper SaveFile(int folderid, Stream file, string fileName) { @@ -320,122 +324,122 @@ private FileWrapper SaveFile(int folderid, Stream file, string fileName) /// /// Created event /// - [Create(@"history")] - public RelationshipEventWrapper AddHistoryTo( - string entityType, - int entityId, - int contactId, - string content, - int categoryId, - ApiDateTime created, - IEnumerable fileId, - IEnumerable notifyUserList) - { - if (!string.IsNullOrEmpty(entityType) && - !( - string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || - string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0) - ) - throw new ArgumentException(); - - var entityTypeObj = ToEntityType(entityType); - - var entityTitle = ""; - if (contactId > 0) { - var contact = DaoFactory.GetContactDao().GetByID(contactId); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) - throw new ArgumentException(); - entityTitle = contact.GetTitle(); - } - - if (entityTypeObj == EntityType.Case) { - var cases = DaoFactory.GetCasesDao().GetByID(entityId); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) - throw new ArgumentException(); - if (contactId <= 0) - { - entityTitle = cases.Title; - } - } - if (entityTypeObj == EntityType.Opportunity) - { - var deal = DaoFactory.GetDealDao().GetByID(entityId); - if (deal == null || !CRMSecurity.CanAccessTo(deal)) - throw new ArgumentException(); - if (contactId <= 0) - { - entityTitle = deal.Title; - } - } - - var relationshipEvent = new RelationshipEvent - { - CategoryID = categoryId, - EntityType = entityTypeObj, - EntityID = entityId, - Content = content, - ContactID = contactId, - CreateOn = created, - CreateBy = SecurityContext.CurrentAccount.ID - }; - - var category = DaoFactory.GetListItemDao().GetByID(categoryId); - if (category == null) throw new ArgumentException(); - - var item = DaoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent); - - - notifyUserList = notifyUserList != null ? notifyUserList.ToList() : new List(); - var needNotify = notifyUserList.Any(); - - var fileListInfoHashtable = new Hashtable(); - - if (fileId != null) - { - var fileIds = fileId.ToList(); - var files = FilesDaoFactory.GetFileDao().GetFiles(fileIds.ToArray()); - - if (needNotify) - { - foreach (var file in files) - { - var extension = Path.GetExtension(file.Title); - if (extension == null) continue; - - var fileInfo = string.Format("{0} ({1})", file.Title, extension.ToUpper()); - if (!fileListInfoHashtable.ContainsKey(fileInfo)) - { - fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); - } - else - { - fileInfo = string.Format("{0} ({1}, {2})", file.Title, extension.ToUpper(), file.UniqID); - fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); - } - } - } - - DaoFactory.GetRelationshipEventDao().AttachFiles(item.ID, fileIds.ToArray()); - - if (files.Any()) - { - var fileAttachAction = GetFilesAttachAction(entityTypeObj, contactId); - MessageService.Send( fileAttachAction, MessageTarget.Create(item.ID), entityTitle, files.Select(x => x.Title)); - } - } - - if (needNotify) - { - NotifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, DaoFactory, notifyUserList.ToArray()); - } - - var wrapper = RelationshipEventWrapperHelper.Get(item); - - var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); - MessageService.Send( historyCreatedAction, MessageTarget.Create(item.ID), entityTitle, category.Title); - - return wrapper; - } + //[Create(@"history")] + //public RelationshipEventWrapper AddHistoryTo( + // string entityType, + // int entityId, + // int contactId, + // string content, + // int categoryId, + // ApiDateTime created, + // IEnumerable fileId, + // IEnumerable notifyUserList) + //{ + // if (!string.IsNullOrEmpty(entityType) && + // !( + // string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || + // string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0) + // ) + // throw new ArgumentException(); + + // var entityTypeObj = ToEntityType(entityType); + + // var entityTitle = ""; + // if (contactId > 0) { + // var contact = DaoFactory.GetContactDao().GetByID(contactId); + // if (contact == null || !CRMSecurity.CanAccessTo(contact)) + // throw new ArgumentException(); + // entityTitle = contact.GetTitle(); + // } + + // if (entityTypeObj == EntityType.Case) { + // var cases = DaoFactory.GetCasesDao().GetByID(entityId); + // if (cases == null || !CRMSecurity.CanAccessTo(cases)) + // throw new ArgumentException(); + // if (contactId <= 0) + // { + // entityTitle = cases.Title; + // } + // } + // if (entityTypeObj == EntityType.Opportunity) + // { + // var deal = DaoFactory.GetDealDao().GetByID(entityId); + // if (deal == null || !CRMSecurity.CanAccessTo(deal)) + // throw new ArgumentException(); + // if (contactId <= 0) + // { + // entityTitle = deal.Title; + // } + // } + + // var relationshipEvent = new RelationshipEvent + // { + // CategoryID = categoryId, + // EntityType = entityTypeObj, + // EntityID = entityId, + // Content = content, + // ContactID = contactId, + // CreateOn = created, + // CreateBy = SecurityContext.CurrentAccount.ID + // }; + + // var category = DaoFactory.GetListItemDao().GetByID(categoryId); + // if (category == null) throw new ArgumentException(); + + // var item = DaoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent); + + + // notifyUserList = notifyUserList != null ? notifyUserList.ToList() : new List(); + // var needNotify = notifyUserList.Any(); + + // var fileListInfoHashtable = new Hashtable(); + + // if (fileId != null) + // { + // var fileIds = fileId.ToList(); + // var files = FilesDaoFactory.GetFileDao().GetFiles(fileIds.ToArray()); + + // if (needNotify) + // { + // foreach (var file in files) + // { + // var extension = Path.GetExtension(file.Title); + // if (extension == null) continue; + + // var fileInfo = string.Format("{0} ({1})", file.Title, extension.ToUpper()); + // if (!fileListInfoHashtable.ContainsKey(fileInfo)) + // { + // fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); + // } + // else + // { + // fileInfo = string.Format("{0} ({1}, {2})", file.Title, extension.ToUpper(), file.UniqID); + // fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); + // } + // } + // } + + // DaoFactory.GetRelationshipEventDao().AttachFiles(item.ID, fileIds.ToArray()); + + // if (files.Any()) + // { + // var fileAttachAction = GetFilesAttachAction(entityTypeObj, contactId); + // MessageService.Send( fileAttachAction, MessageTarget.Create(item.ID), entityTitle, files.Select(x => x.Title)); + // } + // } + + // if (needNotify) + // { + // NotifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, DaoFactory, notifyUserList.ToArray()); + // } + + // var wrapper = RelationshipEventWrapperHelper.Get(item); + + // var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); + // MessageService.Send( historyCreatedAction, MessageTarget.Create(item.ID), entityTitle, category.Title); + + // return wrapper; + //} /// /// Associates the selected file(s) with the entity with the ID or type specified in the request @@ -448,7 +452,7 @@ public RelationshipEventWrapper AddHistoryTo( /// List of IDs of the files /// Files /// Entity with the file attached - [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files")] + [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files")] public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEnumerable fileids) { if (entityid <= 0 || fileids == null) throw new ArgumentException(); @@ -471,15 +475,15 @@ public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEn case EntityType.Contact: var relationshipEvent1 = DaoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray()); var messageAction = entityObj is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; - MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); return RelationshipEventWrapperHelper.Get(relationshipEvent1); case EntityType.Opportunity: var relationshipEvent2 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); - MessageService.Send( MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + MessageService.Send(MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); return RelationshipEventWrapperHelper.Get(relationshipEvent2); case EntityType.Case: var relationshipEvent3 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); - MessageService.Send( MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + MessageService.Send(MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); return RelationshipEventWrapperHelper.Get(relationshipEvent3); default: throw new ArgumentException(); @@ -510,7 +514,7 @@ public int GetRootFolderID() /// /// File list /// - [Read(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files")] + [Read(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files")] public IEnumerable> GetFiles(string entityType, int entityid) { if (entityid <= 0) throw new ArgumentException(); @@ -520,7 +524,7 @@ public IEnumerable> GetFiles(string entityType, int entityid) switch (entityTypeObj) { case EntityType.Contact: - return DaoFactory.GetRelationshipEventDao().GetAllFiles(new[] {entityid}, EntityType.Any, 0).ConvertAll(file => FileWrapperHelper.Get(file)); + return DaoFactory.GetRelationshipEventDao().GetAllFiles(new[] { entityid }, EntityType.Any, 0).ConvertAll(file => FileWrapperHelper.Get(file)); case EntityType.Opportunity: case EntityType.Case: return DaoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => FileWrapperHelper.Get(file)); @@ -563,7 +567,7 @@ public FileWrapper DeleteCRMFile(int fileid) : GetEntityTitle(evt.EntityType, evt.EntityID, false, out entityObj); var messageAction = GetFilesDetachAction(evt.EntityType, evt.ContactID); - MessageService.Send( messageAction, MessageTarget.Create(file.ID), entityTitle, file.Title); + MessageService.Send(messageAction, MessageTarget.Create(file.ID), entityTitle, file.Title); } return result; @@ -625,11 +629,11 @@ private IEnumerable ToListRelationshipEventWrapper(Lis entityWrappers.Add( string.Format("{0}_{1}", (int)entityType, item.ID), new EntityWrapper - { - EntityId = item.ID, - EntityTitle = item.Title, - EntityType = "opportunity" - }); + { + EntityId = item.ID, + EntityTitle = item.Title, + EntityType = "opportunity" + }); }); break; case EntityType.Case: @@ -641,11 +645,11 @@ private IEnumerable ToListRelationshipEventWrapper(Lis entityWrappers.Add( string.Format("{0}_{1}", (int)entityType, item.ID), new EntityWrapper - { - EntityId = item.ID, - EntityTitle = item.Title, - EntityType = "case" - }); + { + EntityId = item.ID, + EntityTitle = item.Title, + EntityType = "case" + }); }); break; default: @@ -697,9 +701,9 @@ private EntityWrapper ToEntityWrapper(EntityType entityType, int entityID) if (entityID == 0) return null; var result = new EntityWrapper - { - EntityId = entityID - }; + { + EntityId = entityID + }; switch (entityType) { @@ -714,7 +718,7 @@ private EntityWrapper ToEntityWrapper(EntityType entityType, int entityID) break; case EntityType.Opportunity: var dealObj = DaoFactory.GetDealDao().GetByID(entityID); - + if (dealObj == null) return null; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs b/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs index 2bb480f2fa8..2d49610f44c 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs @@ -1,163 +1,163 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Api.Documents; -using ASC.Common.Web; -using ASC.CRM.Core; -using ASC.CRM.Core.Enums; -using ASC.Web.Api.Routing; -using ASC.Web.CRM.Classes; -using ASC.Web.Files.Services.DocumentService; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security; - -namespace ASC.Api.CRM -{ - public partial class CRMController - { - /// Returns a list of all user report files - /// Get report files - /// Reports - /// Report files - /// if user can't create reports - [Read(@"report/files")] - public IEnumerable> GetFiles() - { - if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); - - var reportDao = DaoFactory.GetReportDao(); - - var files = reportDao.GetFiles(); - - if (!files.Any()) - { - var settings = SettingsManager.Load(); - - if (settings.NeedToGenerate) - { - files = reportDao.SaveSampleReportFiles(); - - settings.NeedToGenerate = false; - - SettingsManager.Save(settings); - } - } - - return files.ConvertAll(file => FileWrapperHelper.Get(file)).OrderByDescending(file => file.Id); - } - - /// Delete the report file with the ID specified in the request - /// File ID - /// Delete report file - /// Reports - /// if user can't create reports - /// if fileid les than 0 - /// if file not found - [Delete(@"report/file/{fileid:int}")] - public void DeleteFile(int fileid) - { - if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); - - if (fileid < 0) throw new ArgumentException(); - - var file = DaoFactory.GetReportDao().GetFile(fileid); - - if (file == null) throw new ItemNotFoundException("File not found"); - - DaoFactory.GetReportDao().DeleteFile(fileid); - } - - /// Get the state of the report generation task - /// Get report generation state - /// Reports - /// Report state - /// if user can't create reports - [Read(@"report/status")] - public ReportState GetStatus() - { - if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); - - return DocbuilderReportsUtility.Status(ReportOrigin.CRM, HttpContextAccessor, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); - - } - - /// Terminate the report generation task - /// Terminate report generation - /// Reports - /// if user can't create reports - [Read(@"report/terminate")] - public void Terminate() - { - if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); - - DocbuilderReportsUtility.Terminate(ReportOrigin.CRM, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); - } - - /// Check data availability for a report - /// Report type - /// Time period - /// Managers - /// Check report data - /// Reports - /// Object - /// if user can't create reports - [Create(@"report/check")] - public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) - { - if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); - - return new - { - hasData = ReportHelper.CheckReportData(type, timePeriod, managers), - missingRates = ReportHelper.GetMissingRates(type) - }; - } - - /// Run the report generation task - /// Report type - /// Time period - /// Managers - /// Generate report - /// Reports - /// Report state - /// if user can't create reports - [Create(@"report/generate")] - public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) - { - if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); - - return ReportHelper.RunGenareteReport(type, timePeriod, managers); - } - } -} \ No newline at end of file +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//using ASC.Api.Documents; +//using ASC.Common.Web; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Enums; +//using ASC.Web.Api.Routing; +//using ASC.Web.CRM.Classes; +//using ASC.Web.Files.Services.DocumentService; +//using System; +//using System.Collections.Generic; +//using System.Linq; +//using System.Security; + +//namespace ASC.Api.CRM +//{ +// public partial class CRMController +// { +// /// Returns a list of all user report files +// /// Get report files +// /// Reports +// /// Report files +// /// if user can't create reports +// [Read(@"report/files")] +// public IEnumerable> GetFiles() +// { +// if (!Global.CanCreateReports) +// throw CRMSecurity.CreateSecurityException(); + +// var reportDao = DaoFactory.GetReportDao(); + +// var files = reportDao.GetFiles(); + +// if (!files.Any()) +// { +// var settings = SettingsManager.Load(); + +// if (settings.NeedToGenerate) +// { +// files = reportDao.SaveSampleReportFiles(); + +// settings.NeedToGenerate = false; + +// SettingsManager.Save(settings); +// } +// } + +// return files.ConvertAll(file => FileWrapperHelper.Get(file)).OrderByDescending(file => file.Id); +// } + +// /// Delete the report file with the ID specified in the request +// /// File ID +// /// Delete report file +// /// Reports +// /// if user can't create reports +// /// if fileid les than 0 +// /// if file not found +// [Delete(@"report/file/{fileid:int}")] +// public void DeleteFile(int fileid) +// { +// if (!Global.CanCreateReports) +// throw CRMSecurity.CreateSecurityException(); + +// if (fileid < 0) throw new ArgumentException(); + +// var file = DaoFactory.GetReportDao().GetFile(fileid); + +// if (file == null) throw new ItemNotFoundException("File not found"); + +// DaoFactory.GetReportDao().DeleteFile(fileid); +// } + +// /// Get the state of the report generation task +// /// Get report generation state +// /// Reports +// /// Report state +// /// if user can't create reports +// [Read(@"report/status")] +// public ReportState GetStatus() +// { +// if (!Global.CanCreateReports) +// throw CRMSecurity.CreateSecurityException(); + +// return DocbuilderReportsUtility.Status(ReportOrigin.CRM, HttpContextAccessor, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); + +// } + +// /// Terminate the report generation task +// /// Terminate report generation +// /// Reports +// /// if user can't create reports +// [Read(@"report/terminate")] +// public void Terminate() +// { +// if (!Global.CanCreateReports) +// throw CRMSecurity.CreateSecurityException(); + +// DocbuilderReportsUtility.Terminate(ReportOrigin.CRM, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); +// } + +// /// Check data availability for a report +// /// Report type +// /// Time period +// /// Managers +// /// Check report data +// /// Reports +// /// Object +// /// if user can't create reports +// [Create(@"report/check")] +// public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) +// { +// if (!Global.CanCreateReports) +// throw CRMSecurity.CreateSecurityException(); + +// return new +// { +// hasData = ReportHelper.CheckReportData(type, timePeriod, managers), +// missingRates = ReportHelper.GetMissingRates(type) +// }; +// } + +// /// Run the report generation task +// /// Report type +// /// Time period +// /// Managers +// /// Generate report +// /// Reports +// /// Report state +// /// if user can't create reports +// [Create(@"report/generate")] +// public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) +// { +// if (!Global.CanCreateReports) +// throw CRMSecurity.CreateSecurityException(); + +// return ReportHelper.RunGenareteReport(type, timePeriod, managers); +// } +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs b/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs index 28ba0813fb2..f1823625b21 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs @@ -33,6 +33,7 @@ using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; + using System; using System.Collections.Generic; using System.Linq; @@ -52,14 +53,15 @@ public partial class CRMController /// Tag /// /// - [Read(@"{entityType:(contact|opportunity|case)}/tag/{entityid:int}")] + [Read(@"{entityType:regex(contact|opportunity|case)}/tag/{entityid:int}")] public IEnumerable GetEntityTags(string entityType, int entityid) { if (string.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); var entityTypeObj = ToEntityType(entityType); - switch (entityTypeObj) { + switch (entityTypeObj) + { case EntityType.Contact: case EntityType.Person: case EntityType.Company: @@ -113,7 +115,7 @@ public IEnumerable GetContactTags(int contactid) /// Tag /// /// - [Create(@"{entityType:(contact|opportunity|case)}/tag")] + [Create(@"{entityType:regex(contact|opportunity|case)}/tag")] public string CreateTag(string entityType, string tagName) { if (string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -123,7 +125,7 @@ public string CreateTag(string entityType, string tagName) var messageAction = GetEntityTagCreatedAction(entityTypeObj); DaoFactory.GetTagDao().AddTag(entityTypeObj, tagName); - MessageService.Send( messageAction, tagName); + MessageService.Send(messageAction, tagName); return tagName; } @@ -138,7 +140,7 @@ public string CreateTag(string entityType, string tagName) /// Tag /// /// - [Read(@"{entityType:(contact|opportunity|case)}/tag")] + [Read(@"{entityType:regex(contact|opportunity|case)}/tag")] public IEnumerable GetAllTags(string entityType) { if (string.IsNullOrEmpty(entityType)) throw new ArgumentException(); @@ -149,7 +151,8 @@ public IEnumerable GetAllTags(string entityType) if (tagTitles.Count != relativeItemsCountArrayJSON.Count) throw new ArgumentException(); var result = new List(); - for (var i = 0; i < tagTitles.Count; i++) { + for (var i = 0; i < tagTitles.Count; i++) + { result.Add(new TagWrapper(tagTitles[i], relativeItemsCountArrayJSON[i])); } return result.OrderBy(x => x.Title.Trim(), StringComparer.OrdinalIgnoreCase).ToList(); @@ -167,7 +170,7 @@ public IEnumerable GetAllTags(string entityType) /// /// Tag /// - [Create(@"{entityType:(contact|opportunity|case)}/taglist")] + [Create(@"{entityType:regex(contact|opportunity|case)}/taglist")] public string AddTagToBatch(string entityType, IEnumerable entityid, string tagName) { var ids = entityid.ToList(); @@ -312,7 +315,7 @@ public string AddTagToBatchCases(int contactid, bool? isClosed, IEnumerableTags /// Entity type /// Tags - [Delete(@"{entityType:(contact|opportunity|case)}/tag/unused")] + [Delete(@"{entityType:regex(contact|opportunity|case)}/tag/unused")] public IEnumerable DeleteUnusedTag(string entityType) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); @@ -338,7 +341,7 @@ public IEnumerable DeleteUnusedTag(string entityType) /// /// Tag /// - [Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/tag")] + [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/tag")] public string AddTagTo(string entityType, int entityid, string tagName) { if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -352,7 +355,7 @@ public string AddTagTo(string entityType, int entityid, string tagName) DaoFactory.GetTagDao().AddTagToEntity(entityTypeObj, entityid, tagName); var messageAction = GetTagCreatedAction(entityTypeObj, entityid); - MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, tagName); + MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, tagName); return tagName; } @@ -371,7 +374,7 @@ public string AddTagTo(string entityType, int entityid, string tagName) /// /// Tag /// - [Create(@"{entityType:(company|person)}/{entityid:int}/tag/group")] + [Create(@"{entityType:regex(company|person)}/{entityid:int}/tag/group")] public string AddContactTagToGroup(string entityType, int entityid, string tagName) { if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -441,7 +444,7 @@ public string AddContactTagToGroup(string entityType, int entityid, string tagNa var messageActions = GetTagCreatedGroupAction(entityTypeObj); foreach (var messageAction in messageActions) { - MessageService.Send( messageAction, MessageTarget.Create(contactInst.ID), entityTitle, tagName); + MessageService.Send(messageAction, MessageTarget.Create(contactInst.ID), entityTitle, tagName); } return tagName; @@ -459,7 +462,7 @@ public string AddContactTagToGroup(string entityType, int entityid, string tagNa /// /// Tag /// - [Delete(@"{entityType:(contact|opportunity|case)}/tag")] + [Delete(@"{entityType:regex(contact|opportunity|case)}/tag")] public string DeleteTag(string entityType, string tagName) { if (string.IsNullOrEmpty(entityType) || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -472,7 +475,7 @@ public string DeleteTag(string entityType, string tagName) DaoFactory.GetTagDao().DeleteTag(entityTypeObj, tagName); var messageAction = GetEntityTagDeletedAction(entityTypeObj); - MessageService.Send( messageAction, tagName); + MessageService.Send(messageAction, tagName); return tagName; } @@ -489,7 +492,7 @@ public string DeleteTag(string entityType, string tagName) /// /// Tag /// - [Delete(@"{entityType:(contact|opportunity|case)}/{entityid:int}/tag")] + [Delete(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/tag")] public string DeleteTagFrom(string entityType, int entityid, string tagName) { if (string.IsNullOrEmpty(entityType) || entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -506,7 +509,7 @@ public string DeleteTagFrom(string entityType, int entityid, string tagName) var messageAction = GetTagDeletedAction(entityTypeObj, entityid); - MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, tagName); + MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, tagName); return tagName; } @@ -525,7 +528,7 @@ public string DeleteTagFrom(string entityType, int entityid, string tagName) /// /// Tag /// - [Delete(@"{entityType:(company|person)}/{entityid:int}/tag/group")] + [Delete(@"{entityType:regex(company|person)}/{entityid:int}/tag/group")] public string DeleteContactTagFromGroup(string entityType, int entityid, string tagName) { if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -647,9 +650,9 @@ private static IEnumerable GetTagCreatedGroupAction(EntityType en switch (entityType) { case EntityType.Company: - return new List {MessageAction.CompanyCreatedTag, MessageAction.CompanyCreatedPersonsTag}; + return new List { MessageAction.CompanyCreatedTag, MessageAction.CompanyCreatedPersonsTag }; case EntityType.Person: - return new List {MessageAction.PersonCreatedTag, MessageAction.PersonCreatedCompanyTag}; + return new List { MessageAction.PersonCreatedTag, MessageAction.PersonCreatedCompanyTag }; default: throw new ArgumentException("Invalid entityType: " + entityType); } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs b/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs index e4123110ed8..649815618cd 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs @@ -28,6 +28,7 @@ using ASC.Common.Web; using ASC.CRM.Core.Entities; using ASC.Web.Api.Routing; + using System; using System.Collections.Generic; using System.Linq; @@ -48,16 +49,16 @@ public partial class CRMController /// /// /// false - [Create(@"{entityType:(contact|person|company|opportunity|case)}/tasktemplatecontainer")] + [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/tasktemplatecontainer")] public TaskTemplateContainerWrapper CreateTaskTemplateContainer(string entityType, string title) { if (string.IsNullOrEmpty(title)) throw new ArgumentException(); var taskTemplateContainer = new TaskTemplateContainer - { - EntityType = ToEntityType(entityType), - Title = title - }; + { + EntityType = ToEntityType(entityType), + Title = title + }; taskTemplateContainer.ID = DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(taskTemplateContainer); return ToTaskTemplateContainerWrapper(taskTemplateContainer); @@ -73,7 +74,7 @@ public TaskTemplateContainerWrapper CreateTaskTemplateContainer(string entityTyp /// Task template container list /// /// false - [Read(@"{entityType:(contact|person|company|opportunity|case)}/tasktemplatecontainer")] + [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/tasktemplatecontainer")] public IEnumerable GetTaskTemplateContainers(string entityType) { return ToTaskListTemplateContainerWrapper(DaoFactory.GetTaskTemplateContainerDao().GetItems(ToEntityType(entityType))); @@ -213,16 +214,16 @@ bool deadLineIsFixed if (container == null) throw new ItemNotFoundException(); var item = new TaskTemplate - { - CategoryID = categoryid, - ContainerID = containerid, - DeadLineIsFixed = deadLineIsFixed, - Description = description, - isNotify = isNotify, - ResponsibleID = responsibleid, - Title = title, - Offset = TimeSpan.FromTicks(offsetTicks) - }; + { + CategoryID = categoryid, + ContainerID = containerid, + DeadLineIsFixed = deadLineIsFixed, + Description = description, + isNotify = isNotify, + ResponsibleID = responsibleid, + Title = title, + Offset = TimeSpan.FromTicks(offsetTicks) + }; item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); @@ -269,17 +270,17 @@ bool deadLineIsFixed if (container == null) throw new ItemNotFoundException(); var item = new TaskTemplate - { - CategoryID = categoryid, - ContainerID = containerid, - DeadLineIsFixed = deadLineIsFixed, - Description = description, - isNotify = isNotify, - ResponsibleID = responsibleid, - Title = title, - ID = id, - Offset = TimeSpan.FromTicks(offsetTicks) - }; + { + CategoryID = categoryid, + ContainerID = containerid, + DeadLineIsFixed = deadLineIsFixed, + Description = description, + isNotify = isNotify, + ResponsibleID = responsibleid, + Title = title, + ID = id, + Offset = TimeSpan.FromTicks(offsetTicks) + }; item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); @@ -335,17 +336,17 @@ public TaskTemplateWrapper GetTaskTemplateByID(int id) protected TaskTemplateWrapper ToTaskTemplateWrapper(TaskTemplate taskTemplate) { return new TaskTemplateWrapper - { - Category = GetTaskCategoryByID(taskTemplate.CategoryID), - ContainerID = taskTemplate.ContainerID, - DeadLineIsFixed = taskTemplate.DeadLineIsFixed, - Description = taskTemplate.Description, - Id = taskTemplate.ID, - isNotify = taskTemplate.isNotify, - Title = taskTemplate.Title, - OffsetTicks = taskTemplate.Offset.Ticks, - Responsible = EmployeeWraperHelper.Get(taskTemplate.ResponsibleID) - }; + { + Category = GetTaskCategoryByID(taskTemplate.CategoryID), + ContainerID = taskTemplate.ContainerID, + DeadLineIsFixed = taskTemplate.DeadLineIsFixed, + Description = taskTemplate.Description, + Id = taskTemplate.ID, + isNotify = taskTemplate.isNotify, + Title = taskTemplate.Title, + OffsetTicks = taskTemplate.Offset.Ticks, + Responsible = EmployeeWraperHelper.Get(taskTemplate.ResponsibleID) + }; } protected IEnumerable ToTaskListTemplateContainerWrapper(IEnumerable items) @@ -359,11 +360,11 @@ protected IEnumerable ToTaskListTemplateContainerW foreach (var item in items) { var taskTemplateContainer = new TaskTemplateContainerWrapper - { - Title = item.Title, - EntityType = item.EntityType.ToString(), - Id = item.ID - }; + { + Title = item.Title, + EntityType = item.EntityType.ToString(), + Id = item.ID + }; if (taskTemplateDictionary.ContainsKey(taskTemplateContainer.Id)) { diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs index 74ee25264bc..e30a6249aee 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs @@ -9,6 +9,7 @@ using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.CRM.Services.NotifyService; + using System; using System.Collections.Generic; using System.Linq; @@ -17,7 +18,7 @@ namespace ASC.Api.CRM { public partial class CRMController { - + /// /// Returns the detailed information about the task with the ID specified in the request /// @@ -434,7 +435,7 @@ public IEnumerable CreateTaskGroup( { var contacts = DaoFactory.GetContactDao().GetContacts(contactId); var task = tasks.First(); - MessageService.Send( MessageAction.ContactsCreatedCrmTasks, MessageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title); + MessageService.Send(MessageAction.ContactsCreatedCrmTasks, MessageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title); } return ToTaskListWrapper(tasks); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs index c8fe0d18613..f6af9cc1b1b 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs @@ -33,6 +33,7 @@ using ASC.Web.Api.Routing; using ASC.Web.Core.Utility; using ASC.Web.CRM.Classes; + using System; using System.Collections.Generic; using System.Linq; @@ -113,14 +114,14 @@ public IEnumerable GetSummaryTable(String currency) /// [Update(@"contact/status/settings")] public Boolean? UpdateCRMContactStatusSettings(Boolean? changeContactStatusGroupAuto) - { + { var tenantSettings = SettingsManager.Load(); tenantSettings.ChangeContactStatusGroupAuto = changeContactStatusGroupAuto; SettingsManager.Save(tenantSettings); - MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated); + MessageService.Send(MessageAction.ContactTemperatureLevelSettingsUpdated); return changeContactStatusGroupAuto; } @@ -166,7 +167,7 @@ public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAut SettingsManager.Save(tenantSettings); - MessageService.Send( MessageAction.ContactsTagSettingsUpdated); + MessageService.Send(MessageAction.ContactsTagSettingsUpdated); return addTagToContactGroupAuto; } @@ -218,7 +219,7 @@ public String UpdateOrganisationSettingsCompanyName(String companyName) SettingsManager.Save(tenantSettings); - MessageService.Send( MessageAction.OrganizationProfileUpdatedCompanyName, companyName); + MessageService.Send(MessageAction.OrganizationProfileUpdatedCompanyName, companyName); return companyName; } @@ -248,20 +249,20 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit } var companyAddress = Newtonsoft.Json.JsonConvert.SerializeObject(new - { - type = AddressCategory.Billing.ToString(), - street, - city, - state, - zip, - country - }); + { + type = AddressCategory.Billing.ToString(), + street, + city, + state, + zip, + country + }); tenantSettings.InvoiceSetting.CompanyAddress = companyAddress; SettingsManager.Save(tenantSettings); - MessageService.Send( MessageAction.OrganizationProfileUpdatedAddress); + MessageService.Send(MessageAction.OrganizationProfileUpdatedAddress); return companyAddress; } @@ -305,7 +306,7 @@ public Int32 UpdateOrganisationSettingsLogo(bool reset) SettingsManager.Save(tenantSettings); - MessageService.Send( MessageAction.OrganizationProfileUpdatedInvoiceLogo); + MessageService.Send(MessageAction.OrganizationProfileUpdatedInvoiceLogo); return companyLogoID; } @@ -356,7 +357,7 @@ public string ChangeWebToLeadFormKey() SettingsManager.Save(tenantSettings); - MessageService.Send( MessageAction.WebsiteContactFormUpdatedKey); + MessageService.Send(MessageAction.WebsiteContactFormUpdatedKey); return tenantSettings.WebFormKey.ToString(); } @@ -384,13 +385,13 @@ public CurrencyInfoWrapper UpdateCRMCurrency(String currency) if (cur == null) throw new ArgumentException(); Global.SaveDefaultCurrencySettings(cur); - MessageService.Send( MessageAction.CrmDefaultCurrencyUpdated); + MessageService.Send(MessageAction.CrmDefaultCurrencyUpdated); return CurrencyInfoWrapperHelper.Get(cur); } /// false - [Create(@"{entityType:(contact|opportunity|case|task)}/import/start")] + [Create(@"{entityType:regex(contact|opportunity|case|task)}/import/start")] public string StartImportFromCSV(string entityType, string csvFileURI, string jsonSettings) { EntityType entityTypeObj; @@ -415,13 +416,13 @@ public string StartImportFromCSV(string entityType, string csvFileURI, string js } ImportFromCSVManager.StartImport(entityTypeObj, csvFileURI, jsonSettings); - + return ""; } /// false - [Read(@"{entityType:(contact|opportunity|case|task)}/import/status")] + [Read(@"{entityType:regex(contact|opportunity|case|task)}/import/status")] public IProgressItem GetImportFromCSVStatus(string entityType) { EntityType entityTypeObj; @@ -473,9 +474,9 @@ public IProgressItem GetImportFromCSVStatus(string entityType) //public IProgressItem GetExportStatus() //{ // if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - + // return ExportToCsv.GetStatus(false); - + //} ///// false @@ -512,9 +513,9 @@ public IProgressItem GetImportFromCSVStatus(string entityType) //[Update(@"export/partial/cancel")] //public IProgressItem CancelPartialExport() //{ - + // ExportToCsv.Cancel(true); - + // return ExportToCsv.GetStatus(true); //} @@ -524,7 +525,7 @@ public IProgressItem GetImportFromCSVStatus(string entityType) //public IProgressItem StartPartialExport(string entityType, string base64FilterString) //{ // if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException(); - + // FilterObject filterObject; // String fileName; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs index c34ae3233ed..df97dca0e7c 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs @@ -1,906 +1,906 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; -using ASC.Api.Utils; -using ASC.Common.Web; -using ASC.Core.Tenants; -using ASC.CRM.Core; -using ASC.CRM.Core.Enums; -using ASC.CRM.Resources; -using ASC.Data.Storage; -using ASC.VoipService; -using ASC.VoipService.Dao; -using ASC.VoipService.Twilio; -using ASC.Web.Api.Routing; -using ASC.Web.CRM.Classes; -using ASC.Web.Studio.Utility; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Security; -using SecurityContext = ASC.Core.SecurityContext; - -namespace ASC.Api.CRM -{ - public partial class CRMController - { - /// - /// - /// - /// - /// Voip - /// - /// - /// - [Read(@"voip/numbers/available")] - public IEnumerable GetAvailablePhoneNumbers(PhoneNumberType numberType, string isoCountryCode) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException(); - return VoipProvider.GetAvailablePhoneNumbers(numberType, isoCountryCode); - } +///* +// * +// * (c) Copyright Ascensio System Limited 2010-2018 +// * +// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU +// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). +// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that +// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. +// * +// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR +// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html +// * +// * You can contact Ascensio System SIA by email at sales@onlyoffice.com +// * +// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display +// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. +// * +// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains +// * relevant author attributions when distributing the software. If the display of the logo in its graphic +// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" +// * in every copy of the program you distribute. +// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. +// * +//*/ + + +//using ASC.Api.Core; +//using ASC.Api.CRM.Wrappers; +//using ASC.Api.Utils; +//using ASC.Common.Web; +//using ASC.Core.Tenants; +//using ASC.CRM.Core; +//using ASC.CRM.Core.Enums; +//using ASC.CRM.Resources; +//using ASC.Data.Storage; +//using ASC.VoipService; +//using ASC.VoipService.Dao; +//using ASC.VoipService.Twilio; +//using ASC.Web.Api.Routing; +//using ASC.Web.CRM.Classes; +//using ASC.Web.Studio.Utility; +//using System; +//using System.Collections.Generic; +//using System.Globalization; +//using System.IO; +//using System.Linq; +//using System.Security; +//using SecurityContext = ASC.Core.SecurityContext; + +//namespace ASC.Api.CRM +//{ +// public partial class CRMController +// { +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// /// +// [Read(@"voip/numbers/available")] +// public IEnumerable GetAvailablePhoneNumbers(PhoneNumberType numberType, string isoCountryCode) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException(); +// return VoipProvider.GetAvailablePhoneNumbers(numberType, isoCountryCode); +// } - /// - /// - /// - /// - /// Voip - /// - /// - [Read(@"voip/numbers/unlinked")] - public IEnumerable GetUnlinkedPhoneNumbers() - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var listPhones = VoipProvider.GetExistingPhoneNumbers(); - var buyedPhones = DaoFactory.GetVoipDao().GetNumbers(); - - return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList(); - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Read(@"voip/numbers/existing")] - public IEnumerable GetExistingPhoneNumbers() - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - return DaoFactory.GetVoipDao().GetNumbers(); - } - /// - /// - /// - /// - /// Voip - /// - /// - [Create(@"voip/numbers")] - public VoipPhone BuyNumber(string number) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var newPhone = VoipProvider.BuyNumber(number); - - VoipProvider.CreateQueue(newPhone); - SetDefaultAudio(newPhone); - - VoipProvider.UpdateSettings(newPhone); - return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Create(@"voip/numbers/link")] - public VoipPhone LinkNumber(string id) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var newPhone = VoipProvider.GetPhone(id); - - VoipProvider.CreateQueue(newPhone); - SetDefaultAudio(newPhone); - - VoipProvider.UpdateSettings(newPhone); - - return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); - } - - public void SetDefaultAudio(VoipPhone newPhone) - { - var storage = StorageFactory.GetStorage("", "crm"); - const string path = "default/"; - var files = storage.ListFilesRelative("voip", path, "*.*", true) - .Select(filePath => new - { - path = CommonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()), - audioType = (AudioType)Enum.Parse(typeof (AudioType), Directory.GetParent(filePath).Name, true) - }).ToList(); - - var audio = files.Find(r => r.audioType == AudioType.Greeting); - newPhone.Settings.GreetingAudio = audio != null ? audio.path : ""; - - audio = files.Find(r => r.audioType == AudioType.HoldUp); - newPhone.Settings.HoldAudio = audio != null ? audio.path : ""; - - audio = files.Find(r => r.audioType == AudioType.VoiceMail); - newPhone.Settings.VoiceMail = audio != null ? audio.path : ""; - - audio = files.Find(r => r.audioType == AudioType.Queue); - newPhone.Settings.Queue.WaitUrl = audio != null ? audio.path : ""; - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Delete(@"voip/numbers/{numberId:\w+}")] - public VoipPhone DeleteNumber(string numberId) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var dao = DaoFactory.GetVoipDao(); - var phone = dao.GetNumber(numberId).NotFoundIfNull(); - - VoipProvider.DisablePhone(phone); - dao.DeleteNumber(numberId); - new SignalRHelper(phone.Number, SignalrServiceClient).Reload(); - - return phone; - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Read(@"voip/numbers/{numberId:\w+}")] - public VoipPhone GetNumber(string numberId) - { - return DaoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull(); - } - - /// - /// - /// - /// - /// Voip - /// - [Read(@"voip/numbers/current")] - public VoipPhone GetCurrentNumber() - { - return DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); - } - - /// - /// - /// - /// - /// Voip - /// - [Read(@"voip/token")] - public string GetToken() - { - return VoipProvider.GetToken(GetCurrentNumber().Caller); - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Update(@"voip/numbers/{numberId:\w+}/settings")] - public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var dao = DaoFactory.GetVoipDao(); - var number = dao.GetNumber(numberId).NotFoundIfNull(); - - number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias); - number.Settings.GreetingAudio = Update.IfNotEmptyAndNotEquals(number.Settings.GreetingAudio, greeting); - number.Settings.HoldAudio = Update.IfNotEmptyAndNotEquals(number.Settings.HoldAudio, holdUp); - number.Settings.VoiceMail = Update.IfNotEmptyAndNotEquals(number.Settings.VoiceMail, voiceMail); - number.Settings.WorkingHours = Update.IfNotEmptyAndNotEquals(number.Settings.WorkingHours, workingHours); - - if (!string.IsNullOrEmpty(wait)) - { - number.Settings.Queue.WaitUrl = wait; - } - - if (allowOutgoingCalls.HasValue) - { - number.Settings.AllowOutgoingCalls = allowOutgoingCalls.Value; - if (!number.Settings.AllowOutgoingCalls) - { - number.Settings.Operators.ForEach(r => r.AllowOutgoingCalls = false); - } - } - - if (record.HasValue) - { - number.Settings.Record = record.Value; - if (!number.Settings.Record) - { - number.Settings.Operators.ForEach(r => r.Record = false); - } - } - - dao.SaveOrUpdateNumber(number); - - return number; - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Update(@"voip/numbers/settings")] - public object UpdateSettings(Queue queue, bool pause) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var dao = DaoFactory.GetVoipDao(); - var numbers = dao.GetNumbers(); - - if (queue != null) - { - foreach (var number in numbers) - { - if (number.Settings.Queue == null || string.IsNullOrEmpty(number.Settings.Queue.Id)) - { - var phone = number as TwilioPhone; - if (phone != null) - { - queue = phone.CreateQueue(phone.Number, queue.Size, queue.WaitUrl, queue.WaitTime * 60); - } - - queue.Name = number.Number; - number.Settings.Queue = queue; - } - else - { - var oldQueue = number.Settings.Queue; - oldQueue.Size = Update.IfNotEmptyAndNotEquals(oldQueue.Size, queue.Size); - oldQueue.WaitTime = Update.IfNotEmptyAndNotEquals(oldQueue.WaitTime, queue.WaitTime * 60); - oldQueue.WaitUrl = Update.IfNotEmptyAndNotEquals(oldQueue.WaitUrl, queue.WaitUrl); - } - - number.Settings.Pause = pause; - - dao.SaveOrUpdateNumber(number); - } - } - - return new {queue, pause}; - } - - /// - /// - /// - /// - /// Voip - /// - /// - - [Read(@"voip/numbers/settings")] - public object GetVoipSettings() - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var dao = DaoFactory.GetVoipDao(); - var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null); - if (number != null) - { - return new {queue = number.Settings.Queue, pause = number.Settings.Pause}; - } - - var files = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true); - var file = files.FirstOrDefault(); - return new { queue = new Queue(null, "Default", 5, file != null ? CommonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false }; - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Read(@"voip/uploads")] - public IEnumerable GetUploadedFilesUri() - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var result = new List(); - - foreach (var audioType in Enum.GetNames(typeof (AudioType))) - { - var type = (AudioType)Enum.Parse(typeof (AudioType), audioType); - - var path = audioType.ToLower(); - var store = Global.GetStore(); - var filePaths = store.ListFilesRelative("voip", path, "*", true); - result.AddRange( - filePaths.Select(filePath => - GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type))); - - path = "default/" + audioType.ToLower(); - store = StorageFactory.GetStorage("", "crm"); - filePaths = store.ListFilesRelative("voip", path, "*.*", true); - result.AddRange( - filePaths.Select(filePath => - GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type, true))); - } - - return result; - } - - private VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false) - { - return new VoipUpload - { - Path = CommonLinkUtility.GetFullAbsolutePath(link.ToString()), - Name = fileName, - AudioType = audioType, - IsDefault = isDefault - }; - } - - /// - /// - /// - /// - /// Voip - /// - /// - /// - [Delete(@"voip/uploads")] - public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var store = Global.GetStore(); - var path = Path.Combine(audioType.ToString().ToLower(), fileName); - var result = new VoipUpload - { - AudioType = audioType, - Name = fileName, - Path = CommonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString()) - }; - - if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); - store.Delete("voip", path); - - var dao = DaoFactory.GetVoipDao(); - var numbers = dao.GetNumbers(); - - var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); - if (defAudio == null) return result; - - foreach (var number in numbers) - { - switch (audioType) - { - case AudioType.Greeting: - if (number.Settings.GreetingAudio == result.Path) - { - number.Settings.GreetingAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); - } - break; - case AudioType.HoldUp: - if (number.Settings.HoldAudio == result.Path) - { - number.Settings.HoldAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); - } - break; - case AudioType.Queue: - var queue = number.Settings.Queue; - if (queue != null && queue.WaitUrl == result.Path) - { - queue.WaitUrl = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); - } - break; - case AudioType.VoiceMail: - if (number.Settings.VoiceMail == result.Path) - { - number.Settings.VoiceMail = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); - } - break; - } - - dao.SaveOrUpdateNumber(number); - } - - return result; - } +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Read(@"voip/numbers/unlinked")] +// public IEnumerable GetUnlinkedPhoneNumbers() +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var listPhones = VoipProvider.GetExistingPhoneNumbers(); +// var buyedPhones = DaoFactory.GetVoipDao().GetNumbers(); + +// return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList(); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Read(@"voip/numbers/existing")] +// public IEnumerable GetExistingPhoneNumbers() +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// return DaoFactory.GetVoipDao().GetNumbers(); +// } +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Create(@"voip/numbers")] +// public VoipPhone BuyNumber(string number) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var newPhone = VoipProvider.BuyNumber(number); + +// VoipProvider.CreateQueue(newPhone); +// SetDefaultAudio(newPhone); + +// VoipProvider.UpdateSettings(newPhone); +// return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Create(@"voip/numbers/link")] +// public VoipPhone LinkNumber(string id) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var newPhone = VoipProvider.GetPhone(id); + +// VoipProvider.CreateQueue(newPhone); +// SetDefaultAudio(newPhone); + +// VoipProvider.UpdateSettings(newPhone); + +// return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); +// } + +// public void SetDefaultAudio(VoipPhone newPhone) +// { +// var storage = StorageFactory.GetStorage("", "crm"); +// const string path = "default/"; +// var files = storage.ListFilesRelative("voip", path, "*.*", true) +// .Select(filePath => new +// { +// path = CommonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()), +// audioType = (AudioType)Enum.Parse(typeof (AudioType), Directory.GetParent(filePath).Name, true) +// }).ToList(); + +// var audio = files.Find(r => r.audioType == AudioType.Greeting); +// newPhone.Settings.GreetingAudio = audio != null ? audio.path : ""; + +// audio = files.Find(r => r.audioType == AudioType.HoldUp); +// newPhone.Settings.HoldAudio = audio != null ? audio.path : ""; + +// audio = files.Find(r => r.audioType == AudioType.VoiceMail); +// newPhone.Settings.VoiceMail = audio != null ? audio.path : ""; + +// audio = files.Find(r => r.audioType == AudioType.Queue); +// newPhone.Settings.Queue.WaitUrl = audio != null ? audio.path : ""; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Delete(@"voip/numbers/{numberId:\w+}")] +// public VoipPhone DeleteNumber(string numberId) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var dao = DaoFactory.GetVoipDao(); +// var phone = dao.GetNumber(numberId).NotFoundIfNull(); + +// VoipProvider.DisablePhone(phone); +// dao.DeleteNumber(numberId); +// new SignalRHelper(phone.Number, SignalrServiceClient).Reload(); + +// return phone; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Read(@"voip/numbers/{numberId:\w+}")] +// public VoipPhone GetNumber(string numberId) +// { +// return DaoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull(); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Read(@"voip/numbers/current")] +// public VoipPhone GetCurrentNumber() +// { +// return DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Read(@"voip/token")] +// public string GetToken() +// { +// return VoipProvider.GetToken(GetCurrentNumber().Caller); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Update(@"voip/numbers/{numberId:\w+}/settings")] +// public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var dao = DaoFactory.GetVoipDao(); +// var number = dao.GetNumber(numberId).NotFoundIfNull(); + +// number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias); +// number.Settings.GreetingAudio = Update.IfNotEmptyAndNotEquals(number.Settings.GreetingAudio, greeting); +// number.Settings.HoldAudio = Update.IfNotEmptyAndNotEquals(number.Settings.HoldAudio, holdUp); +// number.Settings.VoiceMail = Update.IfNotEmptyAndNotEquals(number.Settings.VoiceMail, voiceMail); +// number.Settings.WorkingHours = Update.IfNotEmptyAndNotEquals(number.Settings.WorkingHours, workingHours); + +// if (!string.IsNullOrEmpty(wait)) +// { +// number.Settings.Queue.WaitUrl = wait; +// } + +// if (allowOutgoingCalls.HasValue) +// { +// number.Settings.AllowOutgoingCalls = allowOutgoingCalls.Value; +// if (!number.Settings.AllowOutgoingCalls) +// { +// number.Settings.Operators.ForEach(r => r.AllowOutgoingCalls = false); +// } +// } + +// if (record.HasValue) +// { +// number.Settings.Record = record.Value; +// if (!number.Settings.Record) +// { +// number.Settings.Operators.ForEach(r => r.Record = false); +// } +// } + +// dao.SaveOrUpdateNumber(number); + +// return number; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Update(@"voip/numbers/settings")] +// public object UpdateSettings(Queue queue, bool pause) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var dao = DaoFactory.GetVoipDao(); +// var numbers = dao.GetNumbers(); + +// if (queue != null) +// { +// foreach (var number in numbers) +// { +// if (number.Settings.Queue == null || string.IsNullOrEmpty(number.Settings.Queue.Id)) +// { +// var phone = number as TwilioPhone; +// if (phone != null) +// { +// queue = phone.CreateQueue(phone.Number, queue.Size, queue.WaitUrl, queue.WaitTime * 60); +// } + +// queue.Name = number.Number; +// number.Settings.Queue = queue; +// } +// else +// { +// var oldQueue = number.Settings.Queue; +// oldQueue.Size = Update.IfNotEmptyAndNotEquals(oldQueue.Size, queue.Size); +// oldQueue.WaitTime = Update.IfNotEmptyAndNotEquals(oldQueue.WaitTime, queue.WaitTime * 60); +// oldQueue.WaitUrl = Update.IfNotEmptyAndNotEquals(oldQueue.WaitUrl, queue.WaitUrl); +// } + +// number.Settings.Pause = pause; + +// dao.SaveOrUpdateNumber(number); +// } +// } + +// return new {queue, pause}; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// + +// [Read(@"voip/numbers/settings")] +// public object GetVoipSettings() +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var dao = DaoFactory.GetVoipDao(); +// var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null); +// if (number != null) +// { +// return new {queue = number.Settings.Queue, pause = number.Settings.Pause}; +// } + +// var files = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true); +// var file = files.FirstOrDefault(); +// return new { queue = new Queue(null, "Default", 5, file != null ? CommonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false }; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Read(@"voip/uploads")] +// public IEnumerable GetUploadedFilesUri() +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var result = new List(); + +// foreach (var audioType in Enum.GetNames(typeof (AudioType))) +// { +// var type = (AudioType)Enum.Parse(typeof (AudioType), audioType); + +// var path = audioType.ToLower(); +// var store = Global.GetStore(); +// var filePaths = store.ListFilesRelative("voip", path, "*", true); +// result.AddRange( +// filePaths.Select(filePath => +// GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type))); + +// path = "default/" + audioType.ToLower(); +// store = StorageFactory.GetStorage("", "crm"); +// filePaths = store.ListFilesRelative("voip", path, "*.*", true); +// result.AddRange( +// filePaths.Select(filePath => +// GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type, true))); +// } + +// return result; +// } + +// private VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false) +// { +// return new VoipUpload +// { +// Path = CommonLinkUtility.GetFullAbsolutePath(link.ToString()), +// Name = fileName, +// AudioType = audioType, +// IsDefault = isDefault +// }; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// /// +// [Delete(@"voip/uploads")] +// public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var store = Global.GetStore(); +// var path = Path.Combine(audioType.ToString().ToLower(), fileName); +// var result = new VoipUpload +// { +// AudioType = audioType, +// Name = fileName, +// Path = CommonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString()) +// }; + +// if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); +// store.Delete("voip", path); + +// var dao = DaoFactory.GetVoipDao(); +// var numbers = dao.GetNumbers(); + +// var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); +// if (defAudio == null) return result; + +// foreach (var number in numbers) +// { +// switch (audioType) +// { +// case AudioType.Greeting: +// if (number.Settings.GreetingAudio == result.Path) +// { +// number.Settings.GreetingAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); +// } +// break; +// case AudioType.HoldUp: +// if (number.Settings.HoldAudio == result.Path) +// { +// number.Settings.HoldAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); +// } +// break; +// case AudioType.Queue: +// var queue = number.Settings.Queue; +// if (queue != null && queue.WaitUrl == result.Path) +// { +// queue.WaitUrl = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); +// } +// break; +// case AudioType.VoiceMail: +// if (number.Settings.VoiceMail == result.Path) +// { +// number.Settings.VoiceMail = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); +// } +// break; +// } + +// dao.SaveOrUpdateNumber(number); +// } + +// return result; +// } - /// - /// - /// - /// - /// Voip - /// - /// - [Read(@"voip/numbers/{numberId:\w+}/oper")] - public IEnumerable GetOperators(string numberId) - { - return DaoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id); - } - - /// - /// - /// - /// - /// Voip - /// - /// - /// - [Update(@"voip/numbers/{numberId:\w+}/oper")] - public IEnumerable AddOperators(string numberId, IEnumerable operators) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - if (DaoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) - { - throw new ArgumentException("Duplicate", "operators"); - } - - var dao = DaoFactory.GetVoipDao(); - var phone = dao.GetNumber(numberId); - var lastOper = phone.Settings.Operators.LastOrDefault(); - var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100; - - var addedOperators = operators.Select(o => new Agent(o, AnswerType.Client, phone, (startOperId++).ToString(CultureInfo.InvariantCulture))).ToList(); - phone.Settings.Operators.AddRange(addedOperators); - - dao.SaveOrUpdateNumber(phone); - return addedOperators; - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Delete(@"voip/numbers/{numberId:\w+}/oper")] - public Guid DeleteOperator(string numberId, Guid oper) - { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - var dao = DaoFactory.GetVoipDao(); - var phone = dao.GetNumber(numberId); - var startOperId = 100; - - phone.Settings.Operators.RemoveAll(r => r.Id == oper); - phone.Settings.Operators.ToList() - .ForEach(r => - { - r.PhoneNumber = phone.Number; - r.PostFix = startOperId.ToString(CultureInfo.InvariantCulture); - startOperId++; - }); - - dao.SaveOrUpdateNumber(phone); - return oper; - } - - /// - /// - /// - /// - /// Voip - /// - /// - [Update(@"voip/opers/{operatorId}")] - public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber) - { - if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); - - var dao = DaoFactory.GetVoipDao(); - var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); - - var oper = phone.Settings.Operators.Find(r => r.Id == operatorId); - - if (status.HasValue) - { - oper.Status = status.Value; - } - - if (allowOutgoingCalls.HasValue) - { - oper.AllowOutgoingCalls = phone.Settings.AllowOutgoingCalls && allowOutgoingCalls.Value; - } - - if (record.HasValue) - { - oper.Record = phone.Settings.Record && record.Value; - } - - if (answerType.HasValue) - { - oper.Answer = answerType.Value; - } - - if (!string.IsNullOrEmpty(redirectToNumber)) - { - oper.RedirectToNumber = redirectToNumber; - } - - dao.SaveOrUpdateNumber(phone); - - if (allowOutgoingCalls.HasValue) - { - new SignalRHelper(phone.Number, SignalrServiceClient).Reload(operatorId.ToString()); - } - - return oper; - } +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Read(@"voip/numbers/{numberId:\w+}/oper")] +// public IEnumerable GetOperators(string numberId) +// { +// return DaoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// /// +// [Update(@"voip/numbers/{numberId:\w+}/oper")] +// public IEnumerable AddOperators(string numberId, IEnumerable operators) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// if (DaoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) +// { +// throw new ArgumentException("Duplicate", "operators"); +// } + +// var dao = DaoFactory.GetVoipDao(); +// var phone = dao.GetNumber(numberId); +// var lastOper = phone.Settings.Operators.LastOrDefault(); +// var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100; + +// var addedOperators = operators.Select(o => new Agent(o, AnswerType.Client, phone, (startOperId++).ToString(CultureInfo.InvariantCulture))).ToList(); +// phone.Settings.Operators.AddRange(addedOperators); + +// dao.SaveOrUpdateNumber(phone); +// return addedOperators; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Delete(@"voip/numbers/{numberId:\w+}/oper")] +// public Guid DeleteOperator(string numberId, Guid oper) +// { +// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + +// var dao = DaoFactory.GetVoipDao(); +// var phone = dao.GetNumber(numberId); +// var startOperId = 100; + +// phone.Settings.Operators.RemoveAll(r => r.Id == oper); +// phone.Settings.Operators.ToList() +// .ForEach(r => +// { +// r.PhoneNumber = phone.Number; +// r.PostFix = startOperId.ToString(CultureInfo.InvariantCulture); +// startOperId++; +// }); + +// dao.SaveOrUpdateNumber(phone); +// return oper; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Update(@"voip/opers/{operatorId}")] +// public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber) +// { +// if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + +// var dao = DaoFactory.GetVoipDao(); +// var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); + +// var oper = phone.Settings.Operators.Find(r => r.Id == operatorId); + +// if (status.HasValue) +// { +// oper.Status = status.Value; +// } + +// if (allowOutgoingCalls.HasValue) +// { +// oper.AllowOutgoingCalls = phone.Settings.AllowOutgoingCalls && allowOutgoingCalls.Value; +// } + +// if (record.HasValue) +// { +// oper.Record = phone.Settings.Record && record.Value; +// } + +// if (answerType.HasValue) +// { +// oper.Answer = answerType.Value; +// } + +// if (!string.IsNullOrEmpty(redirectToNumber)) +// { +// oper.RedirectToNumber = redirectToNumber; +// } + +// dao.SaveOrUpdateNumber(phone); + +// if (allowOutgoingCalls.HasValue) +// { +// new SignalRHelper(phone.Number, SignalrServiceClient).Reload(operatorId.ToString()); +// } + +// return oper; +// } - /// - /// - /// - /// - /// Voip - /// - /// - [Create(@"voip/call")] - public VoipCallWrapper MakeCall(string to, string contactId) - { - var number = DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); - if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); - - var contactPhone = to.TrimStart('+'); - var contact = string.IsNullOrEmpty(contactId) ? - GetContactsByContactInfo(ContactInfoType.Phone, contactPhone, null, null).FirstOrDefault() : - GetContactByID(Convert.ToInt32(contactId)); - - if (contact == null) - { - contact = ContactWrapperHelper.GetContactWrapper(VoipEngine.CreateContact(contactPhone)); - } - - contact = GetContactWithFotos(contact); +// /// +// /// +// /// +// /// +// /// Voip +// /// +// /// +// [Create(@"voip/call")] +// public VoipCallWrapper MakeCall(string to, string contactId) +// { +// var number = DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); +// if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); + +// var contactPhone = to.TrimStart('+'); +// var contact = string.IsNullOrEmpty(contactId) ? +// GetContactsByContactInfo(ContactInfoType.Phone, contactPhone, null, null).FirstOrDefault() : +// GetContactByID(Convert.ToInt32(contactId)); + +// if (contact == null) +// { +// contact = ContactWrapperHelper.GetContactWrapper(VoipEngine.CreateContact(contactPhone)); +// } + +// contact = GetContactWithFotos(contact); - var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); +// var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); - return VoipCallWrapperHelper.Get(call, contact); +// return VoipCallWrapperHelper.Get(call, contact); - } - - /// - /// - /// - /// - /// Voip - /// - [Create(@"voip/call/{callId:\w+}/answer")] - public VoipCallWrapper AnswerCall(string callId) - { - var dao = DaoFactory.GetVoipDao(); - var call = dao.GetCall(callId).NotFoundIfNull(); - var number = dao.GetCurrentNumber().NotFoundIfNull(); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Create(@"voip/call/{callId:\w+}/answer")] +// public VoipCallWrapper AnswerCall(string callId) +// { +// var dao = DaoFactory.GetVoipDao(); +// var call = dao.GetCall(callId).NotFoundIfNull(); +// var number = dao.GetCurrentNumber().NotFoundIfNull(); - number.AnswerQueueCall(call.Id); +// number.AnswerQueueCall(call.Id); - return VoipCallWrapperHelper.Get(call); - - } - - /// - /// - /// - /// - /// Voip - /// - [Create(@"voip/call/{callId:\w+}/reject")] - public VoipCallWrapper RejectCall(string callId) - { - var dao = DaoFactory.GetVoipDao(); - var call = dao.GetCall(callId).NotFoundIfNull(); - var number = dao.GetCurrentNumber().NotFoundIfNull(); - number.RejectQueueCall(call.Id); - return VoipCallWrapperHelper.Get(call); - } - - /// - /// - /// - /// - /// Voip - /// - [Create(@"voip/call/{callId:\w+}/redirect")] - public VoipCallWrapper ReditectCall(string callId, string to) - { - var dao = DaoFactory.GetVoipDao(); - var call = dao.GetCall(callId).NotFoundIfNull(); - var number = dao.GetCurrentNumber().NotFoundIfNull(); - - if (call.ContactId != 0) - { - var contact = DaoFactory.GetContactDao().GetByID(call.ContactId); - var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact); - - if (!managers.Contains(Guid.Parse(to))) - { - managers.Add(Guid.Parse(to)); - CRMSecurity.SetAccessTo(contact, managers); - } - } - - number.RedirectCall(call.Id, to); - return VoipCallWrapperHelper.Get(call); - } - - /// - /// - /// - /// - /// Voip - /// - [Create(@"voip/call/{callId:\w+}")] - public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) - { - var dao = DaoFactory.GetVoipDao(); +// return VoipCallWrapperHelper.Get(call); + +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Create(@"voip/call/{callId:\w+}/reject")] +// public VoipCallWrapper RejectCall(string callId) +// { +// var dao = DaoFactory.GetVoipDao(); +// var call = dao.GetCall(callId).NotFoundIfNull(); +// var number = dao.GetCurrentNumber().NotFoundIfNull(); +// number.RejectQueueCall(call.Id); +// return VoipCallWrapperHelper.Get(call); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Create(@"voip/call/{callId:\w+}/redirect")] +// public VoipCallWrapper ReditectCall(string callId, string to) +// { +// var dao = DaoFactory.GetVoipDao(); +// var call = dao.GetCall(callId).NotFoundIfNull(); +// var number = dao.GetCurrentNumber().NotFoundIfNull(); + +// if (call.ContactId != 0) +// { +// var contact = DaoFactory.GetContactDao().GetByID(call.ContactId); +// var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact); + +// if (!managers.Contains(Guid.Parse(to))) +// { +// managers.Add(Guid.Parse(to)); +// CRMSecurity.SetAccessTo(contact, managers); +// } +// } + +// number.RedirectCall(call.Id, to); +// return VoipCallWrapperHelper.Get(call); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Create(@"voip/call/{callId:\w+}")] +// public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) +// { +// var dao = DaoFactory.GetVoipDao(); - var call = dao.GetCall(callId) ?? new VoipCall(); - - call.Id = callId; - call.From = Update.IfNotEmptyAndNotEquals(call.From, from); - call.To = Update.IfNotEmptyAndNotEquals(call.To, to); - call.AnsweredBy = Update.IfNotEmptyAndNotEquals(call.AnsweredBy, answeredBy); - - try - { - if (call.ContactId == 0) - { - var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; - if (!string.IsNullOrEmpty(contactId)) - { - call.ContactId = Convert.ToInt32(contactId); - } - else - { - VoipEngine.GetContact(call); - } - - if (call.ContactId == 0) - { - contactPhone = contactPhone.TrimStart('+'); +// var call = dao.GetCall(callId) ?? new VoipCall(); + +// call.Id = callId; +// call.From = Update.IfNotEmptyAndNotEquals(call.From, from); +// call.To = Update.IfNotEmptyAndNotEquals(call.To, to); +// call.AnsweredBy = Update.IfNotEmptyAndNotEquals(call.AnsweredBy, answeredBy); + +// try +// { +// if (call.ContactId == 0) +// { +// var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; +// if (!string.IsNullOrEmpty(contactId)) +// { +// call.ContactId = Convert.ToInt32(contactId); +// } +// else +// { +// VoipEngine.GetContact(call); +// } + +// if (call.ContactId == 0) +// { +// contactPhone = contactPhone.TrimStart('+'); - var person = CreatePerson(contactPhone, TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), null, 0, null, ShareType.None, new List { SecurityContext.CurrentAccount.ID }, null, null); +// var person = CreatePerson(contactPhone, TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), null, 0, null, ShareType.None, new List { SecurityContext.CurrentAccount.ID }, null, null); - DaoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); +// DaoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); - call.ContactId = person.Id; - } - } - } - catch (Exception) - { - - } - - if (status.HasValue) - { - call.Status = status.Value; - } - - if (call.Price == 0 && price.HasValue) - { - call.Price = price.Value; - } - - call = dao.SaveOrUpdateCall(call); - - if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); - try - { - var contact = GetContactByID(call.ContactId); - contact = GetContactWithFotos(contact); - - return VoipCallWrapperHelper.Get(call, contact); - } - catch (Exception) - { - return VoipCallWrapperHelper.Get(call); - } - - } - - /// - /// - /// - /// - /// Voip - /// - [Create(@"voip/price/{callId:\w+}")] - public void SavePrice(string callId) - { - VoipEngine.SaveAdditionalInfo(callId); - } - - /// - /// - /// - /// - /// Voip - /// - [Read(@"voip/call")] - public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) - { - var voipDao = DaoFactory.GetVoipDao(); - - var filter = new VoipCallFilter - { - Type = callType, - FromDate = from != null ? from.UtcTime : (DateTime?)null, - ToDate = to != null ? to.UtcTime.AddDays(1).AddMilliseconds(-1) : (DateTime?)null, - Agent = agent, - Client = client, - ContactID = contactID, - SortBy = ApiContext.SortBy, - SortOrder = !ApiContext.SortDescending, - SearchText = ApiContext.FilterValue, - Offset = ApiContext.StartIndex, - Max = ApiContext.Count, - }; - - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - ApiContext.TotalCount = voipDao.GetCallsCount(filter); - - var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); - var calls = voipDao.GetCalls(filter).Select( - r => - { - ContactWrapper contact; +// call.ContactId = person.Id; +// } +// } +// } +// catch (Exception) +// { + +// } + +// if (status.HasValue) +// { +// call.Status = status.Value; +// } + +// if (call.Price == 0 && price.HasValue) +// { +// call.Price = price.Value; +// } + +// call = dao.SaveOrUpdateCall(call); + +// if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); +// try +// { +// var contact = GetContactByID(call.ContactId); +// contact = GetContactWithFotos(contact); + +// return VoipCallWrapperHelper.Get(call, contact); +// } +// catch (Exception) +// { +// return VoipCallWrapperHelper.Get(call); +// } + +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Create(@"voip/price/{callId:\w+}")] +// public void SavePrice(string callId) +// { +// VoipEngine.SaveAdditionalInfo(callId); +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Read(@"voip/call")] +// public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) +// { +// var voipDao = DaoFactory.GetVoipDao(); + +// var filter = new VoipCallFilter +// { +// Type = callType, +// FromDate = from != null ? from.UtcTime : (DateTime?)null, +// ToDate = to != null ? to.UtcTime.AddDays(1).AddMilliseconds(-1) : (DateTime?)null, +// Agent = agent, +// Client = client, +// ContactID = contactID, +// SortBy = ApiContext.SortBy, +// SortOrder = !ApiContext.SortDescending, +// SearchText = ApiContext.FilterValue, +// Offset = ApiContext.StartIndex, +// Max = ApiContext.Count, +// }; + +// ApiContext.SetDataPaginated(); +// ApiContext.SetDataFiltered(); +// ApiContext.SetDataSorted(); +// ApiContext.TotalCount = voipDao.GetCallsCount(filter); + +// var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); +// var calls = voipDao.GetCalls(filter).Select( +// r => +// { +// ContactWrapper contact; - if (r.ContactId != 0) - { - contact = r.ContactIsCompany - ? (ContactWrapper)new CompanyWrapper() {DisplayName = r.ContactTitle, Id = r.ContactId } - : new PersonWrapper() { - DisplayName = r.ContactTitle, - Id = r.ContactId - }; - - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); +// if (r.ContactId != 0) +// { +// contact = r.ContactIsCompany +// ? (ContactWrapper)new CompanyWrapper() {DisplayName = r.ContactTitle, Id = r.ContactId } +// : new PersonWrapper() { +// DisplayName = r.ContactTitle, +// Id = r.ContactId +// }; + +// contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); - } - else - { - contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; - } +// } +// else +// { +// contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; +// } - return VoipCallWrapperHelper.Get(r, contact); - - }).ToList(); - - return calls; - } - - /// - /// - /// - /// - /// Voip - /// - [Read(@"voip/call/missed")] - public IEnumerable GetMissedCalls() - { - var voipDao = DaoFactory.GetVoipDao(); - var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); - - var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( - r => - { - ContactWrapper contact; +// return VoipCallWrapperHelper.Get(r, contact); + +// }).ToList(); + +// return calls; +// } + +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Read(@"voip/call/missed")] +// public IEnumerable GetMissedCalls() +// { +// var voipDao = DaoFactory.GetVoipDao(); +// var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); + +// var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( +// r => +// { +// ContactWrapper contact; - if (r.ContactId != 0) - { - contact = r.ContactIsCompany - ? (ContactWrapper)new CompanyWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId } - : new PersonWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId }; +// if (r.ContactId != 0) +// { +// contact = r.ContactIsCompany +// ? (ContactWrapper)new CompanyWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId } +// : new PersonWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId }; - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); +// contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); - } - else - { - contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; - } +// } +// else +// { +// contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; +// } - return VoipCallWrapperHelper.Get(r, contact); +// return VoipCallWrapperHelper.Get(r, contact); - }).ToList(); +// }).ToList(); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - ApiContext.TotalCount = calls.Count; +// ApiContext.SetDataPaginated(); +// ApiContext.SetDataFiltered(); +// ApiContext.SetDataSorted(); +// ApiContext.TotalCount = calls.Count; - return calls; - } +// return calls; +// } - /// - /// - /// - /// - /// Voip - /// - [Read(@"voip/call/{callId:\w+}")] - public VoipCallWrapper GetCall(string callId) - { - var call = DaoFactory.GetVoipDao().GetCall(callId); +// /// +// /// +// /// +// /// +// /// Voip +// /// +// [Read(@"voip/call/{callId:\w+}")] +// public VoipCallWrapper GetCall(string callId) +// { +// var call = DaoFactory.GetVoipDao().GetCall(callId); - VoipEngine.GetContact(call); +// VoipEngine.GetContact(call); - if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); +// if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); - var contact = GetContactByID(call.ContactId); - contact = GetContactWithFotos(contact); +// var contact = GetContactByID(call.ContactId); +// contact = GetContactWithFotos(contact); - return VoipCallWrapperHelper.Get(call, contact); - } - - private ContactWrapper GetContactWithFotos(ContactWrapper contact) - { - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); - contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); - - return contact; - } - } -} \ No newline at end of file +// return VoipCallWrapperHelper.Get(call, contact); +// } + +// private ContactWrapper GetContactWithFotos(ContactWrapper contact) +// { +// contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); +// contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); + +// return contact; +// } +// } +//} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Controllers/CRMController.cs index fb3e8522ffa..b88fd836ac1 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.cs @@ -34,6 +34,7 @@ namespace ASC.Api.CRM { + [Scope] [DefaultRoute] [ApiController] public partial class CRMController : ControllerBase @@ -70,7 +71,7 @@ public CRMController(CRMSecurity cRMSecurity, SignalrServiceClient signalrServiceClient, VoipEngine voipEngine, - Web.Files.Classes.FilesSettings filesSettings, + Web.Files.Classes.FilesSettingsHelper filesSettingsHelper, ASC.Files.Core.Data.DaoFactory filesDaoFactory, FileWrapperHelper fileWrapperHelper, @@ -93,7 +94,7 @@ public CRMController(CRMSecurity cRMSecurity, VoipCallWrapperHelper voipCallWrapperHelper, RelationshipEventWrapperHelper relationshipEventWrapperHelper, - DocbuilderReportsUtility docbuilderReportsUtility, + DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper, FactoryIndexerContactInfo factoryIndexerContactInfo, FactoryIndexerCase factoryIndexerCase, @@ -153,12 +154,12 @@ public CRMController(CRMSecurity cRMSecurity, PdfCreator = pdfCreator; FilesDaoFactory = filesDaoFactory; - FilesSettings = filesSettings; + FilesSettingsHelper = filesSettingsHelper; FileUploader = fileUploader; Global = global; ReportHelper = reportHelper; HttpContextAccessor = httpContextAccessor; - DocbuilderReportsUtility = docbuilderReportsUtility; + DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; InvoiceSetting = invoiceSetting; ContactInfoWrapperHelper = contactInfoWrapperHelper; @@ -186,11 +187,11 @@ public CRMController(CRMSecurity cRMSecurity, public VoipCallWrapperHelper VoipCallWrapperHelper { get; } public OrganisationLogoManager OrganisationLogoManager { get; } public InvoiceSetting InvoiceSetting { get; } - public DocbuilderReportsUtility DocbuilderReportsUtility { get; } + public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } public IHttpContextAccessor HttpContextAccessor { get; } public ReportHelper ReportHelper { get; } public FileUploader FileUploader { get; } - public Web.Files.Classes.FilesSettings FilesSettings { get; } + public Web.Files.Classes.FilesSettingsHelper FilesSettingsHelper { get; } public ASC.Files.Core.Data.DaoFactory FilesDaoFactory { get; } public FileWrapperHelper FileWrapperHelper { get; } public RelationshipEventWrapperHelper RelationshipEventWrapperHelper { get; } diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 8ec5cf39277..67e41b60fc1 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -544,6 +544,8 @@ public void DeleteField(int fieldID) var fieldValue = Query(CRMDbContext.FieldValue).FirstOrDefault(x => x.FieldId == fieldID); + FactoryIndexer.Delete(fieldValue); + CRMDbContext.Remove(fieldValue); CRMDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index e9d7d48b413..6313f3fdd44 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -30,7 +30,7 @@ namespace ASC.CRM.Core.Dao { - [Scope] + [Scope(Additional = typeof(DaoFactoryExtension))] public class DaoFactory { public DaoFactory(IServiceProvider serviceProvider) @@ -124,7 +124,6 @@ public CurrencyRateDao GetCurrencyRateDao() public CurrencyInfoDao GetCurrencyInfoDao() { return ServiceProvider.GetService(); - } public ContactInfoDao GetContactInfoDao() @@ -157,6 +156,30 @@ public VoipDao GetVoipDao() return ServiceProvider.GetService(); } } + + public class DaoFactoryExtension + { + public static void Register(DIHelper services) + { + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + } + } + } //TaskDao diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 3d2bb49f606..36402e6a45c 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -52,6 +52,7 @@ namespace ASC.CRM.Core { + [Scope] public class CRMSecurity { public readonly IAction _actionRead = new Action(new Guid("{6F05C382-8BCA-4469-9424-C807A98C40D7}"), "", true, false); diff --git a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs new file mode 100644 index 00000000000..9c0d0a57b8b --- /dev/null +++ b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs @@ -0,0 +1,408 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.Common.Logging; +using ASC.Core; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.MessagingSystem; +using ASC.Web.Core; +using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Configuration; +using ASC.Web.CRM.Core; +using ASC.Web.CRM.Services.NotifyService; + +using Autofac; + +using Microsoft.AspNetCore.Http; + +using Newtonsoft.Json.Linq; + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Text; +using System.Web; + +namespace ASC.Web.CRM.HttpHandlers +{ + public class WebToLeadFromHandler + { + private HttpContext _context; + private readonly RequestDelegate _next; + + public Global Global { get; } + public WebItemSecurity WebItemSecurity { get; } + public SecurityContext SecurityContext { get; } + public CRMSecurity CRMSecurity { get; } + + public WebToLeadFromHandler(RequestDelegate next) + { + _next = next; + } + + private String GetValue(String propertyName) + { + return _context.Request.Form[propertyName]; + } + + private bool CheckPermission() + { + try + { + var webFromKey = GetValue("web_form_key"); + + if (String.IsNullOrEmpty(webFromKey)) + return false; + + var webFromKeyAsGuid = new Guid(webFromKey); + + return TenantSettings.WebFormKey == webFromKeyAsGuid; + } + catch (Exception) + { + return false; + } + } + + public async Task InvokeAsync(HttpContext context) + { + try + { + using (var scope = DIHelper.Resolve()) + { + var daoFactory = scope.Resolve(); + _context = context; + + SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); + + if (!CheckPermission()) + { + throw new Exception(CRMSettingResource.WebToLeadsForm_InvalidKeyException); + } + + var productInfo = WebItemSecurity.GetSecurityInfo(ProductEntryPoint.ID.ToString()); + if (!productInfo.Enabled) + { + throw new Exception(CRMCommonResource.CRMProductIsDisabled); + } + + Contact contact; + + var fieldCollector = new NameValueCollection(); + + var addressTemplate = new JObject(); + foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) + addressTemplate.Add(addressPartName.ToLower(), ""); + var addressTemplateStr = addressTemplate.ToString(); + + var isCompany = false; + + var isCompanyString = GetValue("is_company"); + var firstName = GetValue("firstName"); + var lastName = GetValue("lastName"); + var companyName = GetValue("companyName"); + + if (!String.IsNullOrEmpty(isCompanyString)) + { + if (!Boolean.TryParse(isCompanyString, out isCompany)) + { + throw new ArgumentException(); + } + } + else //old scheme + { + if (!String.IsNullOrEmpty(firstName)) + { + isCompany = false; + } + else if (!String.IsNullOrEmpty(companyName)) + { + isCompany = true; + } + else + { + throw new ArgumentException(); + } + } + + + if (isCompany) + { + contact = new Company(); + + ((Company)contact).CompanyName = companyName; + + fieldCollector.Add(CRMContactResource.CompanyName, companyName); + } + else + { + contact = new Person(); + + ((Person)contact).FirstName = firstName; + ((Person)contact).LastName = lastName; + ((Person)contact).JobTitle = GetValue("jobTitle"); + + fieldCollector.Add(CRMContactResource.FirstName, firstName); + fieldCollector.Add(CRMContactResource.LastName, lastName); + + if (!String.IsNullOrEmpty(GetValue("jobTitle"))) + fieldCollector.Add(CRMContactResource.JobTitle, ((Person)contact).JobTitle); + } + + contact.About = GetValue("about"); + + if (!String.IsNullOrEmpty(contact.About)) + fieldCollector.Add(CRMContactResource.About, contact.About); + + if (!String.IsNullOrEmpty(GetValue("is_shared"))) + { + contact.ShareType = Convert.ToBoolean(GetValue("is_shared")) + ? ShareType.ReadWrite + : ShareType.None; + } + else + { + contact.ShareType = (ShareType)(Convert.ToInt32(GetValue("share_type"))); + } + + contact.ID = daoFactory.GetContactDao().SaveContact(contact); + + var messageAction = contact is Company + ? MessageAction.CompanyCreatedWithWebForm + : MessageAction.PersonCreatedWithWebForm; + MessageService.Send(HttpContext.Current.Request, MessageInitiator.System, messageAction, + MessageTarget.Create(contact.ID), contact.GetTitle()); + + var contactInfos = new List(); + + foreach (var key in _context.Request.Form.AllKeys) + { + if (key.StartsWith("customField_")) + { + var fieldID = Convert.ToInt32(key.Split(new[] { '_' })[1]); + String fieldValue = GetValue(key); + + if (String.IsNullOrEmpty(fieldValue)) continue; + + var customField = daoFactory.GetCustomFieldDao().GetFieldDescription(fieldID); + + if (customField == null || + !(customField.EntityType == EntityType.Contact || + customField.EntityType == EntityType.Company && isCompany || + customField.EntityType == EntityType.Person && !isCompany)) continue; + + if (customField.FieldType == CustomFieldType.CheckBox) + { + fieldValue = fieldValue == "on" || fieldValue == "true" ? "true" : "false"; + } + fieldCollector.Add(customField.Label, fieldValue); + + daoFactory.GetCustomFieldDao().SetFieldValue(isCompany ? EntityType.Company : EntityType.Person, contact.ID, fieldID, fieldValue); + } + else if (key.StartsWith("contactInfo_")) + { + var nameParts = key.Split(new[] { '_' }).Skip(1).ToList(); + var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), nameParts[0]); + var category = Convert.ToInt32(nameParts[1]); + + bool categoryIsExists = Enum.GetValues(ContactInfo.GetCategory(contactInfoType)) + .Cast() + .Any(categoryEnum => (int)categoryEnum == category); + if (!categoryIsExists) + throw new ArgumentException(String.Format("Category for {0} not found", nameParts[0])); + + if (contactInfoType == ContactInfoType.Address) + { + var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), nameParts[2]); + + var findedAddress = + contactInfos.Find( + item => + (category == item.Category) && (item.InfoType == ContactInfoType.Address)); + + if (findedAddress == null) + { + findedAddress = new ContactInfo + { + Category = category, + InfoType = contactInfoType, + Data = addressTemplateStr, + ContactID = contact.ID + }; + + contactInfos.Add(findedAddress); + } + + var addressParts = JObject.Parse(findedAddress.Data); + + addressParts[addressPart.ToString().ToLower()] = GetValue(key); + + findedAddress.Data = addressParts.ToString(); + + continue; + } + + var fieldValue = GetValue(key); + + if (String.IsNullOrEmpty(fieldValue)) continue; + + contactInfos.Add(new ContactInfo + { + Category = category, + InfoType = contactInfoType, + Data = fieldValue, + ContactID = contact.ID, + IsPrimary = true + }); + } + else if (String.Compare(key, "tag", true) == 0) + { + var tags = _context.Request.Form.GetValues("tag"); + + daoFactory.GetTagDao().SetTagToEntity(EntityType.Contact, contact.ID, tags); + } + } + + contactInfos.ForEach( + item => + fieldCollector[item.InfoType.ToLocalizedString()] = + PrepareteDataToView(item.InfoType, item.Data)); + + daoFactory.GetContactInfoDao().SaveList(contactInfos, contact); + + var notifyList = GetValue("notify_list"); + + if (!String.IsNullOrEmpty(notifyList)) + NotifyClient.Instance.SendAboutCreateNewContact( + notifyList + .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(item => new Guid(item)).ToList(), contact.ID, contact.GetTitle(), fieldCollector); + + var managersList = GetValue("managers_list"); + SetPermission(contact, managersList); + + if (contact is Person && !String.IsNullOrEmpty(companyName)) + AssignPersonToCompany((Person)contact, companyName, managersList, daoFactory); + + if (contact is Company && !String.IsNullOrEmpty(firstName) && !String.IsNullOrEmpty(lastName)) + AssignCompanyToPerson((Company)contact, firstName, lastName, managersList, daoFactory); + + SecurityContext.Logout(); + + var newURL = new UriBuilder(GetValue("return_url")).Uri.AbsoluteUri; + context.Response.Buffer = true; + context.Response.Status = "302 Object moved"; + context.Response.AddHeader("Location", newURL); + context.Response.Write(""); + context.Response.Write(String.Format("", newURL)); + context.Response.Write(String.Format("", newURL)); + context.Response.Write(""); + context.Response.Write(""); + } + } + catch (Exception error) + { + LogManager.GetLogger("ASC.CRM").Error(error); + context.Response.StatusCode = 400; + context.Response.Write(HttpUtility.HtmlEncode(error.Message)); + } + } + + private String PrepareteDataToView(ContactInfoType contactInfoType, String data) + { + if (contactInfoType != ContactInfoType.Address) return data; + + var addressParts = JObject.Parse(data); + + var address = new StringBuilder(); + + foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) + address.Append(addressParts[addressPartEnum.ToString().ToLower()] + " "); + + return address.ToString(); + } + + public bool IsReusable + { + get { return false; } + } + + protected void SetPermission(Contact contact, String privateList) + { + if (String.IsNullOrEmpty(privateList)) return; + + var selectedUsers = privateList + .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(item => new Guid(item)).ToList(); + + CRMSecurity.SetAccessTo(contact, selectedUsers); + } + + protected void AssignCompanyToPerson(Company company, String firstName, String lastName, String privateList, DaoFactory daoFactory) + { + var person = new Person + { + FirstName = firstName, + LastName = lastName, + CompanyID = company.ID + }; + person.ID = daoFactory.GetContactDao().SaveContact(person); + SetPermission(person, privateList); + } + + + protected void AssignPersonToCompany(Person person, String companyName, String privateList, DaoFactory daoFactory) + { + Company company; + + var findedCompanies = daoFactory.GetContactDao().GetContactsByName(companyName, true).ToList(); + + if (findedCompanies.Count == 0) + { + company = new Company + { + CompanyName = companyName + }; + + company.ID = daoFactory.GetContactDao().SaveContact(company); + + SetPermission(company, privateList); + } + else + { + company = (Company)findedCompanies[0]; + } + + daoFactory.GetContactDao().AddMember(person.ID, company.ID); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs index bbc09c26b2e..256b98d8585 100644 --- a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs +++ b/products/ASC.CRM/Server/Model/InvoiceWrapper.cs @@ -381,6 +381,7 @@ public InvoiceItemWrapper() public bool CanDelete { get; set; } } + [Scope] public class InvoiceItemWrapperHelper { public InvoiceItemWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index 0127db12fff..6627c27a001 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -3,6 +3,9 @@ using System.IO; using System.Linq; using System.Threading.Tasks; + +using Autofac.Extensions.DependencyInjection; + using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; @@ -17,33 +20,37 @@ public static void Main(string[] args) CreateHostBuilder(args).Build().Run(); } - public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) + public static IHostBuilder CreateHostBuilder(string[] args) + { + return Host.CreateDefaultBuilder(args) + .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }) - .ConfigureAppConfiguration((hostingContext, config) => - { - var buided = config.Build(); - var path = buided["pathToConf"]; - if (!Path.IsPathRooted(path)) + .ConfigureAppConfiguration((hostingContext, config) => { - path = Path.GetFullPath(Path.Combine(hostingContext.HostingEnvironment.ContentRootPath, path)); - } - - config.SetBasePath(path); - config - .AddInMemoryCollection(new Dictionary + var buided = config.Build(); + var path = buided["pathToConf"]; + if (!Path.IsPathRooted(path)) { - {"pathToConf", path} - }) + path = Path.GetFullPath(Path.Combine(hostingContext.HostingEnvironment.ContentRootPath, path)); + } + + config.SetBasePath(path); + config .AddJsonFile("appsettings.json") .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true) .AddJsonFile("storage.json") .AddJsonFile("kafka.json") .AddJsonFile($"kafka.{hostingContext.HostingEnvironment.EnvironmentName}.json", true) - .AddEnvironmentVariables(); - }); + .AddEnvironmentVariables() + .AddCommandLine(args) + .AddInMemoryCollection(new Dictionary + { + {"pathToConf", path} + }); + }); + } } } diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index b02077b40d0..61493bcd2ea 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -43,6 +43,7 @@ namespace ASC.Web.CRM.Classes { + [Scope] public class CurrencyProvider { private readonly ILog _log; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 6627c2af8cb..e969f2a249e 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Security.Authentication; @@ -45,6 +46,7 @@ namespace ASC.Web.CRM.Classes { + [Scope] public class ImportDataCache { public ImportDataCache(TenantManager tenantManager, diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index 9a56a99d8d0..af046500e25 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -24,6 +24,7 @@ */ +using ASC.Common; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.CRM.Core.Enums; @@ -35,7 +36,7 @@ namespace ASC.Web.CRM.Classes { - + [Scope] public class ImportFromCSV { public ImportFromCSV(TenantManager tenantProvider, diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index 06324e52cea..bf7a19307a3 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -33,12 +33,13 @@ using ASC.Core; using Microsoft.AspNetCore.Http; using ASC.CRM.Core.Enums; +using log4net; namespace ASC.Web.CRM.Classes { public class PdfQueueWorker { - private static readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromMinutes(5), true); + private static readonly ProgressQueue Queue = new ProgressQueue(); public static string GetTaskId(int tenantId, int invoiceId) { @@ -61,27 +62,28 @@ public static void TerminateTask(int tenantId, int invoiceId) public static PdfProgressItem StartTask(HttpContext context, int tenantId, Guid userId, int invoiceId) { - lock (Queue.SynchRoot) - { - var task = GetTaskStatus(tenantId, invoiceId); - - if (task != null && task.IsCompleted) - { - Queue.Remove(task); - task = null; - } - - if (task == null) - { - task = new PdfProgressItem(context, tenantId, userId, invoiceId); - Queue.Add(task); - } - - if (!Queue.IsStarted) - Queue.Start(x => x.RunJob()); - - return task; - } + throw new Exception(); + //lock (Queue.SynchRoot) + //{ + // var task = GetTaskStatus(tenantId, invoiceId); + + // if (task != null && task.IsCompleted) + // { + // Queue.Remove(task); + // task = null; + // } + + // if (task == null) + // { + // task = new PdfProgressItem(context, tenantId, userId, invoiceId); + // Queue.Add(task); + // } + + // if (!Queue.IsStarted) + // Queue.Start(x => x.RunJob()); + + // return task; + //} } } @@ -97,15 +99,18 @@ public class PdfProgressItem : IProgressItem public object Error { get; set; } public double Percentage { get; set; } public bool IsCompleted { get; set; } - - + public PdfCreator PdfCreator { get; } + public SecurityContext SecurityContext { get; } + public TenantManager TenantManager { get; } public PdfProgressItem(IHttpContextAccessor httpContextAccessor, int tenantId, Guid userId, int invoiceId) { - _contextUrl = context != null ? context.Request.GetUrlRewriter().ToString() : null; + + + _contextUrl = httpContextAccessor.HttpContext != null ? httpContextAccessor.HttpContext.Request.GetUrlRewriter().ToString() : null; _tenantId = tenantId; _invoiceId = invoiceId; _userId = userId; @@ -124,16 +129,16 @@ public void RunJob() Percentage = 0; Status = ProgressStatus.Started; - CoreContext.TenantManager.SetCurrentTenant(_tenantId); + TenantManager.SetCurrentTenant(_tenantId); SecurityContext.AuthenticateMe(_userId); - if (HttpContext.Current == null && !WorkContext.IsMono) - { - HttpContext.Current = new HttpContext( - new HttpRequest("hack", _contextUrl, string.Empty), - new HttpResponse(new System.IO.StringWriter())); - } + //if (HttpContext.Current == null && !WorkContext.IsMono) + //{ + // HttpContext.Current = new HttpContext( + // new HttpRequest("hack", _contextUrl, string.Empty), + // new HttpResponse(new System.IO.StringWriter())); + //} PdfCreator.CreateAndSaveFile(_invoiceId); @@ -143,6 +148,7 @@ public void RunJob() catch (Exception ex) { LogManager.GetLogger("ASC.Web").Error(ex); + Percentage = 0; Status = ProgressStatus.Failed; Error = ex.Message; @@ -152,11 +158,11 @@ public void RunJob() // fake httpcontext break configuration manager for mono if (!WorkContext.IsMono) { - if (HttpContext.Current != null) - { - new DisposableHttpContext(HttpContext.Current).Dispose(); - HttpContext.Current = null; - } + //if (HttpContext.Current != null) + //{ + // new DisposableHttpContext(HttpContext.Current).Dispose(); + // HttpContext.Current = null; + //} } IsCompleted = true; diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index d1da9803ce9..e221bb6f5e3 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -38,15 +38,16 @@ using System.Collections.Generic; using System.Net; using Microsoft.Extensions.DependencyInjection; - +using ASC.Common; namespace ASC.Web.CRM.Classes { + [Scope] public class ReportHelper { public ReportHelper(TenantUtil tenantUtil, Global global, - DocbuilderReportsUtility docbuilderReportsUtility, + // DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper, SettingsManager settingsManager, DaoFactory daoFactory, IServiceProvider serviceProvider @@ -54,7 +55,6 @@ IServiceProvider serviceProvider { TenantUtil = tenantUtil; Global = global; - DocbuilderReportsUtility = docbuilderReportsUtility; SettingsManager = settingsManager; ServiceProvider = serviceProvider; DaoFactory = daoFactory; @@ -63,7 +63,6 @@ IServiceProvider serviceProvider public DaoFactory DaoFactory { get; } public IServiceProvider ServiceProvider { get; } - public DocbuilderReportsUtility DocbuilderReportsUtility { get; } public Global Global { get; } public SettingsManager SettingsManager { get; } public TenantUtil TenantUtil { get; } From a8ffda6c0fbf4061c5b53eee970792eeef500137 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 5 Mar 2021 23:06:49 +0300 Subject: [PATCH 18/61] crm: migrate from old project --- .../Server/Controllers/CRMController.Cases.cs | 1472 ++++---- .../Controllers/CRMController.Contacts.cs | 115 +- .../Server/Controllers/CRMController.Deals.cs | 1853 ++++++----- .../Controllers/CRMController.Invoices.cs | 2964 +++++++++-------- .../Server/Core/Enums/InvoiceStatus.cs | 3 +- .../Server/Core/Search/BundleSearch.cs | 3 + .../Model/Dto/CreateOrUpdateCasesInDto.cs | 19 + .../Model/Dto/CreateOrUpdateDealInDto.cs | 32 + .../Model/Dto/CreateOrUpdateInvoiceInDto.cs | 30 + .../Dto/CreateOrUpdateInvoiceItemInDto.cs | 21 + .../Dto/CreateOrUpdateInvoiceLineInDto.cs | 20 + .../Model/Dto/CreateOrUpdateInvoiceTax.cs | 14 + .../Model/Dto/CreateOrUpdatePersonInDto.cs | 49 + .../Model/Dto/SaveNumberSettingsInDto.cs | 14 + .../Model/Dto/SetAccessToBatchCasesInDto.cs | 24 + .../Model/Dto/SetAccessToBatchContactInDto.cs | 32 + .../Dto/SetAccessToBatchDealByFilterInDto.cs | 32 + 17 files changed, 3536 insertions(+), 3161 deletions(-) create mode 100644 products/ASC.CRM/Server/Model/Dto/CreateOrUpdateCasesInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/CreateOrUpdateDealInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceItemInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceLineInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceTax.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/CreateOrUpdatePersonInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/SaveNumberSettingsInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/SetAccessToBatchCasesInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/SetAccessToBatchContactInDto.cs create mode 100644 products/ASC.CRM/Server/Model/Dto/SetAccessToBatchDealByFilterInDto.cs diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs index 7ca28329d67..18cbf13129f 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs @@ -1,729 +1,743 @@ -///* -// * -// * (c) Copyright Ascensio System Limited 2010-2018 -// * -// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU -// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). -// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that -// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. -// * -// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR -// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html -// * -// * You can contact Ascensio System SIA by email at sales@onlyoffice.com -// * -// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display -// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. -// * -// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains -// * relevant author attributions when distributing the software. If the display of the logo in its graphic -// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" -// * in every copy of the program you distribute. -// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. -// * -//*/ - - -//using ASC.Api.Collections; -//using ASC.Api.CRM.Wrappers; -//using ASC.Common.Web; -//using ASC.Core; -//using ASC.Core.Users; -//using ASC.CRM.Core; -//using ASC.CRM.Core.Entities; -//using ASC.CRM.Core.Enums; -//using ASC.ElasticSearch; -//using ASC.MessagingSystem; -//using ASC.Web.Api.Routing; -//using ASC.Web.Files.Services.WCFService; -//using System; -//using System.Collections.Generic; -//using System.Linq; - -//namespace ASC.Api.CRM -//{ -// public partial class CRMController -// { -// /// -// /// Close the case with the ID specified in the request -// /// -// /// Close case -// /// Cases -// /// Case ID -// /// -// /// -// /// -// /// Case -// /// -// [Update(@"case/{caseid:int}/close")] -// public CasesWrapper CloseCases(int caseid) -// { -// if (caseid <= 0) throw new ArgumentException(); - -// var cases = DaoFactory.GetCasesDao().CloseCases(caseid); -// if (cases == null) throw new ItemNotFoundException(); - -// MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); - -// return CasesWrapperHelper.Get(cases); -// } - -// /// -// /// Resume the case with the ID specified in the request -// /// -// /// Resume case -// /// Cases -// /// Case ID -// /// -// /// -// /// -// /// Case -// /// -// [Update(@"case/{caseid:int}/reopen")] -// public CasesWrapper ReOpenCases(int caseid) -// { -// if (caseid <= 0) throw new ArgumentException(); - -// var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid); -// if (cases == null) throw new ItemNotFoundException(); - -// MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); - -// return CasesWrapperHelper.Get(cases); -// } - -// /// -// /// Creates the case with the parameters specified in the request -// /// -// /// Create case -// /// Case title -// /// Participants -// /// User field list -// /// Case privacy: private or not -// /// List of users with access to the case -// /// Notify users in accessList about the case -// /// Case -// /// Cases -// /// -// /// -// /// -// /// -// [Create(@"case")] -// public CasesWrapper CreateCases( -// string title, -// IEnumerable members, -// IEnumerable> customFieldList, -// bool isPrivate, -// IEnumerable accessList, -// bool isNotify) -// { -// if (string.IsNullOrEmpty(title)) throw new ArgumentException(); - -// var casesID = DaoFactory.GetCasesDao().CreateCases(title); - -// var cases = new Cases -// { -// ID = casesID, -// Title = title, -// CreateBy = SecurityContext.CurrentAccount.ID, -// CreateOn = DateTime.UtcNow -// }; - -// SetAccessToCases(cases, isPrivate, accessList, isNotify, false); - -// var membersList = members != null ? members.ToList() : new List(); -// if (membersList.Any()) -// { -// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); -// membersList = contacts.Select(m => m.ID).ToList(); -// DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); -// } - -// if (customFieldList != null) -// { -// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); -// foreach (var field in customFieldList) -// { -// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; -// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); -// } -// } - -// return CasesWrapperHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); -// } - -// /// -// /// Updates the selected case with the parameters specified in the request -// /// -// /// Update case -// /// Case ID -// /// Case title -// /// Participants -// /// User field list -// /// Case privacy: private or not -// /// List of users with access to the case -// /// Notify users in accessList about the case -// /// Cases -// /// Case -// /// -// /// -// /// -// /// -// /// -// [Update(@"case/{caseid:int}")] -// public CasesWrapper UpdateCases( -// int caseid, -// string title, -// IEnumerable members, -// IEnumerable> customFieldList, -// bool isPrivate, -// IEnumerable accessList, -// bool isNotify) -// { -// if ((caseid <= 0) || (string.IsNullOrEmpty(title))) throw new ArgumentException(); - -// var cases = DaoFactory.GetCasesDao().GetByID(caseid); -// if (cases == null) throw new ItemNotFoundException(); - -// cases.Title = title; - -// DaoFactory.GetCasesDao().UpdateCases(cases); - -// if (CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) -// { -// SetAccessToCases(cases, isPrivate, accessList, isNotify, false); -// } - -// var membersList = members != null ? members.ToList() : new List(); -// if (membersList.Any()) -// { -// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); -// membersList = contacts.Select(m => m.ID).ToList(); -// DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); -// } - -// if (customFieldList != null) -// { -// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); -// foreach (var field in customFieldList) -// { -// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; -// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); -// } -// } - -// return CasesWrapperHelper.Get(cases); -// } - -// /// -// /// Sets access rights for the selected case with the parameters specified in the request -// /// -// /// Case ID -// /// Case privacy: private or not -// /// List of users with access to the case -// /// Set rights to case -// /// Cases -// /// -// /// -// /// -// /// Case -// /// -// [Update(@"case/{caseid:int}/access")] -// public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) -// { -// if (caseid <= 0) throw new ArgumentException(); - -// var cases = DaoFactory.GetCasesDao().GetByID(caseid); -// if (cases == null) throw new ItemNotFoundException(); - -// if (!(CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); - -// return SetAccessToCases(cases, isPrivate, accessList, false, true); -// } - -// private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) -// { -// var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); -// if (isPrivate && accessListLocal.Any()) -// { -// if (isNotify) -// { -// accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); -// NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, DaoFactory, accessListLocal.ToArray()); -// } - -// if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) -// { -// accessListLocal.Add(SecurityContext.CurrentAccount.ID); -// } - -// CRMSecurity.SetAccessTo(cases, accessListLocal); -// if (isMessageServicSende) -// { -// var users = GetUsersByIdList(accessListLocal); -// MessageService.Send(MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); -// } -// } -// else -// { -// CRMSecurity.MakePublic(cases); -// if (isMessageServicSende) -// { -// MessageService.Send(MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title); -// } -// } - -// return CasesWrapperHelper.Get(cases); -// } - -// /// -// /// Sets access rights for other users to the list of cases with the IDs specified in the request -// /// -// /// Case ID list -// /// Case privacy: private or not -// /// List of users with access -// /// Set case access rights -// /// Cases -// /// -// /// -// /// -// /// Case list -// /// -// [Update(@"case/access")] -// public IEnumerable SetAccessToBatchCases(IEnumerable casesid, bool isPrivate, IEnumerable accessList) -// { -// var result = new List(); - -// var cases = DaoFactory.GetCasesDao().GetCases(casesid); - -// if (!cases.Any()) return new List(); - -// foreach (var c in cases) -// { -// if (c == null) throw new ItemNotFoundException(); - -// if (!(CRMSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - -// SetAccessToCases(c, isPrivate, accessList, false, true); -// result.Add(c); -// } - -// return ToListCasesWrappers(result); -// } - -// /// -// /// Sets access rights for other users to the list of all cases matching the parameters specified in the request -// /// -// /// Contact ID -// /// Case status -// /// Tags -// /// Case privacy: private or not -// /// List of users with access -// /// Set case access rights -// /// Cases -// /// -// /// -// /// -// /// Case list -// /// -// [Update(@"case/filter/access")] -// public IEnumerable SetAccessToBatchCases( -// int contactid, -// bool? isClosed, -// IEnumerable tags, -// bool isPrivate, -// IEnumerable accessList -// ) -// { -// var result = new List(); - -// var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); - -// if (!caseses.Any()) return new List(); - -// foreach (var casese in caseses) -// { -// if (casese == null) throw new ItemNotFoundException(); - -// if (!(CRMSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - -// SetAccessToCases(casese, isPrivate, accessList, false, true); -// result.Add(casese); -// } - -// return ToListCasesWrappers(result); -// } - -// /// -// /// Returns the detailed information about the case with the ID specified in the request -// /// -// /// Get case by ID -// /// Cases -// /// Case ID -// /// -// /// -// [Read(@"case/{caseid:int}")] -// public CasesWrapper GetCaseByID(int caseid) -// { -// if (caseid <= 0) throw new ItemNotFoundException(); - -// var cases = DaoFactory.GetCasesDao().GetByID(caseid); -// if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - -// return CasesWrapperHelper.Get(cases); -// } - -// /// -// /// Returns the list of all cases matching the parameters specified in the request -// /// -// /// Get case list -// /// Contact ID -// /// Case status -// /// Tags -// /// Cases -// /// -// /// Case list -// /// -// [Read(@"case/filter")] -// public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable tags) -// { -// IEnumerable result; -// SortedByType sortBy; -// OrderBy casesOrderBy; - -// var searchString = ApiContext.FilterValue; - -// if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) -// { -// casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); -// } -// else if (string.IsNullOrEmpty(ApiContext.SortBy)) -// { -// casesOrderBy = new OrderBy(SortedByType.Title, true); -// } -// else -// { -// casesOrderBy = null; -// } - -// var fromIndex = (int)ApiContext.StartIndex; -// var count = (int)ApiContext.Count; - -// if (casesOrderBy != null) -// { -// result = ToListCasesWrappers( -// DaoFactory -// .GetCasesDao() -// .GetCases( -// searchString, -// contactid, -// isClosed, -// tags, -// fromIndex, -// count, -// casesOrderBy)).ToList(); - -// ApiContext.SetDataPaginated(); -// ApiContext.SetDataFiltered(); -// ApiContext.SetDataSorted(); -// } -// else -// { -// result = ToListCasesWrappers( -// DaoFactory -// .GetCasesDao() -// .GetCases( -// searchString, contactid, isClosed, -// tags, -// 0, -// 0, -// null)).ToList(); -// } - -// int totalCount; - -// if (result.Count() < count) -// { -// totalCount = fromIndex + result.Count(); -// } -// else -// { -// totalCount = DaoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); -// } - -// ApiContext.SetTotalCount(totalCount); -// return result; -// } - -// /// -// /// Deletes the case with the ID specified in the request -// /// -// /// Delete case -// /// Case ID -// /// Cases -// /// -// /// -// /// -// /// Case -// /// -// [Delete(@"case/{caseid:int}")] -// public CasesWrapper DeleteCase(int caseid) -// { -// if (caseid <= 0) throw new ArgumentException(); - -// var cases = DaoFactory.GetCasesDao().DeleteCases(caseid); - -// if (cases == null) throw new ItemNotFoundException(); - -// MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); - -// return CasesWrapperHelper.Get(cases); -// } - -// /// -// /// Deletes the group of cases with the IDs specified in the request -// /// -// /// Case ID list -// /// -// /// -// /// Delete case group -// /// Cases -// /// -// /// Case list -// /// -// [Update(@"case")] -// public IEnumerable DeleteBatchCases(IEnumerable casesids) -// { -// if (casesids == null) throw new ArgumentException(); - -// casesids = casesids.Distinct(); -// var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); - -// if (caseses == null || !caseses.Any()) return new List(); - -// MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); - -// return ToListCasesWrappers(caseses); -// } - -// /// -// /// Deletes the list of all cases matching the parameters specified in the request -// /// -// /// Contact ID -// /// Case status -// /// Tags -// /// -// /// -// /// Delete case group -// /// Cases -// /// -// /// Case list -// /// -// [Delete(@"case/filter")] -// public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) -// { -// var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); -// if (!caseses.Any()) return new List(); - -// caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); - -// MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); - -// return ToListCasesWrappers(caseses); -// } - -// /// -// /// Returns the list of all contacts associated with the case with the ID specified in the request -// /// -// /// Get all case contacts -// /// Case ID -// /// Cases -// /// Contact list -// /// -// [Read(@"case/{caseid:int}/contact")] -// public IEnumerable GetCasesMembers(int caseid) -// { -// var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); -// return contactIDs == null -// ? new ItemList() -// : ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)); -// } - -// /// -// /// Adds the selected contact to the case with the ID specified in the request -// /// -// /// Add case contact -// /// Cases -// /// Case ID -// /// Contact ID -// /// -// /// -// /// -// /// Participant -// /// -// [Create(@"case/{caseid:int}/contact")] -// public ContactWrapper AddMemberToCases(int caseid, int contactid) -// { -// if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); - -// var cases = DaoFactory.GetCasesDao().GetByID(caseid); -// if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - -// var contact = DaoFactory.GetContactDao().GetByID(contactid); -// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - -// DaoFactory.GetCasesDao().AddMember(caseid, contactid); - -// var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; -// MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); - -// return ToContactWrapper(contact); -// } - -// /// -// /// Delete the selected contact from the case with the ID specified in the request -// /// -// /// Delete case contact -// /// Cases -// /// Case ID -// /// Contact ID -// /// -// /// -// /// -// /// Participant -// /// -// [Delete(@"case/{caseid:int}/contact/{contactid:int}")] -// public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) -// { -// if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); - -// var cases = DaoFactory.GetCasesDao().GetByID(caseid); -// if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - -// var contact = DaoFactory.GetContactDao().GetByID(contactid); -// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - -// var result = ToContactWrapper(contact); - -// DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); - -// var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; -// MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); - -// return result; -// } - -// /// -// /// Returns the list of 30 cases in the CRM module with prefix -// /// -// /// -// /// -// /// Cases -// /// -// /// Cases list -// /// -// /// false -// [Read(@"case/byprefix")] -// public IEnumerable GetCasesByPrefix(string prefix, int contactID) -// { -// var result = new List(); - -// if (contactID > 0) -// { -// var findedCases = DaoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null); - -// foreach (var item in findedCases) -// { -// if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) -// { -// result.Add(CasesWrapperHelper.Get(item)); -// } -// } - -// ApiContext.SetTotalCount(findedCases.Count); -// } -// else -// { -// const int maxItemCount = 30; -// var findedCases = DaoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount); - -// foreach (var item in findedCases) -// { -// result.Add(CasesWrapperHelper.Get(item)); -// } -// } - -// return result; -// } - -// private IEnumerable ToListCasesWrappers(ICollection items) -// { -// if (items == null || items.Count == 0) return new List(); - -// var result = new List(); - -// var contactIDs = new List(); -// var casesIDs = items.Select(item => item.ID).ToArray(); - -// var customFields = DaoFactory.GetCustomFieldDao() -// .GetEnityFields(EntityType.Case, casesIDs) -// .GroupBy(item => item.EntityID) -// .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); - -// var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); - -// foreach (var value in casesMembers.Values) -// { -// contactIDs.AddRange(value); -// } - -// var contacts = DaoFactory -// .GetContactDao() -// .GetContacts(contactIDs.Distinct().ToArray()) -// .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); - -// foreach (var cases in items) -// { -// var casesWrapper = CasesWrapperHelper.Get(cases); - -// casesWrapper.CustomFields = customFields.ContainsKey(cases.ID) -// ? customFields[cases.ID] -// : new List(); - -// casesWrapper.Members = casesMembers.ContainsKey(cases.ID) -// ? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) -// : new List(); - -// result.Add(casesWrapper); -// } - -// return result; -// } - -// private IEnumerable GetUsersByIdList(IEnumerable ids) -// { -// return UserManager.GetUsers().Where(x => ids.Contains(x.ID)); -// } -// } -//} \ No newline at end of file +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Collections; +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Model; +using ASC.ElasticSearch; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.Files.Services.WCFService; + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Close the case with the ID specified in the request + /// + /// Close case + /// Cases + /// Case ID + /// + /// + /// + /// Case + /// + [Update(@"case/{caseid:int}/close")] + public CasesWrapper CloseCases(int caseid) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().CloseCases(caseid); + if (cases == null) throw new ItemNotFoundException(); + + MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); + + return CasesWrapperHelper.Get(cases); + } + + /// + /// Resume the case with the ID specified in the request + /// + /// Resume case + /// Cases + /// Case ID + /// + /// + /// + /// Case + /// + [Update(@"case/{caseid:int}/reopen")] + public CasesWrapper ReOpenCases(int caseid) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid); + if (cases == null) throw new ItemNotFoundException(); + + MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); + + return CasesWrapperHelper.Get(cases); + } + + /// + /// Creates the case with the parameters specified in the request + /// + /// Create case + /// Case title + /// Participants + /// User field list + /// Case privacy: private or not + /// List of users with access to the case + /// Notify users in accessList about the case + /// Case + /// Cases + /// + /// + /// + /// + [Create(@"case")] + public CasesWrapper CreateCases( + CreateOrUpdateCasesInDto inDto) + { + + var title = inDto.Title; + var customFieldList = inDto.CustomFieldList; + var isPrivate = inDto.isPrivate; + var isNotify = inDto.isNotify; + var members = inDto.Members; + var accessList = inDto.accessList; + + if (string.IsNullOrEmpty(title)) throw new ArgumentException(); + + var casesID = DaoFactory.GetCasesDao().CreateCases(title); + + var cases = new Cases + { + ID = casesID, + Title = title, + CreateBy = SecurityContext.CurrentAccount.ID, + CreateOn = DateTime.UtcNow + }; + + SetAccessToCases(cases, isPrivate, accessList, isNotify, false); + + var membersList = members != null ? members.ToList() : new List(); + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); + } + } + + return CasesWrapperHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); + } + + /// + /// Updates the selected case with the parameters specified in the request + /// + /// Update case + /// Case ID + /// Case title + /// Participants + /// User field list + /// Case privacy: private or not + /// List of users with access to the case + /// Notify users in accessList about the case + /// Cases + /// Case + /// + /// + /// + /// + /// + [Update(@"case/{caseid:int}")] + public CasesWrapper UpdateCases( + int caseid, + CreateOrUpdateCasesInDto inDto) + { + var title = inDto.Title; + var isPrivate = inDto.isPrivate; + var isNotify = inDto.isNotify; + var accessList = inDto.accessList; + var members = inDto.Members; + var customFieldList = inDto.CustomFieldList; + + if ((caseid <= 0) || (string.IsNullOrEmpty(title))) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null) throw new ItemNotFoundException(); + + cases.Title = title; + + DaoFactory.GetCasesDao().UpdateCases(cases); + + if (CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) + { + SetAccessToCases(cases, isPrivate, accessList, isNotify, false); + } + + var membersList = members != null ? members.ToList() : new List(); + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); + } + } + + return CasesWrapperHelper.Get(cases); + } + + /// + /// Sets access rights for the selected case with the parameters specified in the request + /// + /// Case ID + /// Case privacy: private or not + /// List of users with access to the case + /// Set rights to case + /// Cases + /// + /// + /// + /// Case + /// + [Update(@"case/{caseid:int}/access")] + public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + + return SetAccessToCases(cases, isPrivate, accessList, false, true); + } + + private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) + { + var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); + if (isPrivate && accessListLocal.Any()) + { + if (isNotify) + { + accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); + NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, DaoFactory, accessListLocal.ToArray()); + } + + if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) + { + accessListLocal.Add(SecurityContext.CurrentAccount.ID); + } + + CRMSecurity.SetAccessTo(cases, accessListLocal); + if (isMessageServicSende) + { + var users = GetUsersByIdList(accessListLocal); + MessageService.Send(MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); + } + } + else + { + CRMSecurity.MakePublic(cases); + if (isMessageServicSende) + { + MessageService.Send(MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title); + } + } + + return CasesWrapperHelper.Get(cases); + } + + /// + /// Sets access rights for other users to the list of cases with the IDs specified in the request + /// + /// Case ID list + /// Case privacy: private or not + /// List of users with access + /// Set case access rights + /// Cases + /// + /// + /// + /// Case list + /// + [Update(@"case/access")] + public IEnumerable SetAccessToBatchCases( + SetAccessToBatchCasesInDto inDto) + { + var casesid = inDto.Casesid; + var isPrivate = inDto.isPrivate; + var accessList = inDto.AccessList; + + var result = new List(); + + var cases = DaoFactory.GetCasesDao().GetCases(casesid); + + if (!cases.Any()) return new List(); + + foreach (var c in cases) + { + if (c == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToCases(c, isPrivate, accessList, false, true); + result.Add(c); + } + + return ToListCasesWrappers(result); + } + + /// + /// Sets access rights for other users to the list of all cases matching the parameters specified in the request + /// + /// Contact ID + /// Case status + /// Tags + /// Case privacy: private or not + /// List of users with access + /// Set case access rights + /// Cases + /// + /// + /// + /// Case list + /// + [Update(@"case/filter/access")] + public IEnumerable SetAccessToBatchCases( + SetAccessToBatchCasesByFilterInDto inDto + ) + { + int contactid = inDto.Contactid; + bool? isClosed = inDto.isClosed; + IEnumerable tags = inDto.Tags; + bool isPrivate = inDto.isPrivate; + IEnumerable accessList = inDto.AccessList; + + var result = new List(); + + var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + + if (!caseses.Any()) return new List(); + + foreach (var casese in caseses) + { + if (casese == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToCases(casese, isPrivate, accessList, false, true); + result.Add(casese); + } + + return ToListCasesWrappers(result); + } + + /// + /// Returns the detailed information about the case with the ID specified in the request + /// + /// Get case by ID + /// Cases + /// Case ID + /// + /// + [Read(@"case/{caseid:int}")] + public CasesWrapper GetCaseByID(int caseid) + { + if (caseid <= 0) throw new ItemNotFoundException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + + return CasesWrapperHelper.Get(cases); + } + + /// + /// Returns the list of all cases matching the parameters specified in the request + /// + /// Get case list + /// Contact ID + /// Case status + /// Tags + /// Cases + /// + /// Case list + /// + [Read(@"case/filter")] + public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable tags) + { + IEnumerable result; + SortedByType sortBy; + OrderBy casesOrderBy; + + var searchString = ApiContext.FilterValue; + + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + { + casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (string.IsNullOrEmpty(ApiContext.SortBy)) + { + casesOrderBy = new OrderBy(SortedByType.Title, true); + } + else + { + casesOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (casesOrderBy != null) + { + result = ToListCasesWrappers( + DaoFactory + .GetCasesDao() + .GetCases( + searchString, + contactid, + isClosed, + tags, + fromIndex, + count, + casesOrderBy)).ToList(); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListCasesWrappers( + DaoFactory + .GetCasesDao() + .GetCases( + searchString, contactid, isClosed, + tags, + 0, + 0, + null)).ToList(); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); + } + + ApiContext.SetTotalCount(totalCount); + return result; + } + + /// + /// Deletes the case with the ID specified in the request + /// + /// Delete case + /// Case ID + /// Cases + /// + /// + /// + /// Case + /// + [Delete(@"case/{caseid:int}")] + public CasesWrapper DeleteCase(int caseid) + { + if (caseid <= 0) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().DeleteCases(caseid); + + if (cases == null) throw new ItemNotFoundException(); + + MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); + + return CasesWrapperHelper.Get(cases); + } + + /// + /// Deletes the group of cases with the IDs specified in the request + /// + /// Case ID list + /// + /// + /// Delete case group + /// Cases + /// + /// Case list + /// + [Update(@"case")] + public IEnumerable DeleteBatchCases(IEnumerable casesids) + { + if (casesids == null) throw new ArgumentException(); + + casesids = casesids.Distinct(); + var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); + + if (caseses == null || !caseses.Any()) return new List(); + + MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); + + return ToListCasesWrappers(caseses); + } + + /// + /// Deletes the list of all cases matching the parameters specified in the request + /// + /// Contact ID + /// Case status + /// Tags + /// + /// + /// Delete case group + /// Cases + /// + /// Case list + /// + [Delete(@"case/filter")] + public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) + { + var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + if (!caseses.Any()) return new List(); + + caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); + + MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); + + return ToListCasesWrappers(caseses); + } + + /// + /// Returns the list of all contacts associated with the case with the ID specified in the request + /// + /// Get all case contacts + /// Case ID + /// Cases + /// Contact list + /// + [Read(@"case/{caseid:int}/contact")] + public IEnumerable GetCasesMembers(int caseid) + { + var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); + return contactIDs == null + ? new ItemList() + : ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)); + } + + /// + /// Adds the selected contact to the case with the ID specified in the request + /// + /// Add case contact + /// Cases + /// Case ID + /// Contact ID + /// + /// + /// + /// Participant + /// + [Create(@"case/{caseid:int}/contact")] + public ContactWrapper AddMemberToCases(int caseid, int contactid) + { + if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + DaoFactory.GetCasesDao().AddMember(caseid, contactid); + + var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; + MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + + return ToContactWrapper(contact); + } + + /// + /// Delete the selected contact from the case with the ID specified in the request + /// + /// Delete case contact + /// Cases + /// Case ID + /// Contact ID + /// + /// + /// + /// Participant + /// + [Delete(@"case/{caseid:int}/contact/{contactid:int}")] + public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) + { + if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var cases = DaoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var result = ToContactWrapper(contact); + + DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); + + var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; + MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + + return result; + } + + /// + /// Returns the list of 30 cases in the CRM module with prefix + /// + /// + /// + /// Cases + /// + /// Cases list + /// + /// false + [Read(@"case/byprefix")] + public IEnumerable GetCasesByPrefix(string prefix, int contactID) + { + var result = new List(); + + if (contactID > 0) + { + var findedCases = DaoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null); + + foreach (var item in findedCases) + { + if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) + { + result.Add(CasesWrapperHelper.Get(item)); + } + } + + ApiContext.SetTotalCount(findedCases.Count); + } + else + { + const int maxItemCount = 30; + var findedCases = DaoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount); + + foreach (var item in findedCases) + { + result.Add(CasesWrapperHelper.Get(item)); + } + } + + return result; + } + + private IEnumerable ToListCasesWrappers(ICollection items) + { + if (items == null || items.Count == 0) return new List(); + + var result = new List(); + + var contactIDs = new List(); + var casesIDs = items.Select(item => item.ID).ToArray(); + + var customFields = DaoFactory.GetCustomFieldDao() + .GetEnityFields(EntityType.Case, casesIDs) + .GroupBy(item => item.EntityID) + .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + + var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); + + foreach (var value in casesMembers.Values) + { + contactIDs.AddRange(value); + } + + var contacts = DaoFactory + .GetContactDao() + .GetContacts(contactIDs.Distinct().ToArray()) + .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); + + foreach (var cases in items) + { + var casesWrapper = CasesWrapperHelper.Get(cases); + + casesWrapper.CustomFields = customFields.ContainsKey(cases.ID) + ? customFields[cases.ID] + : new List(); + + casesWrapper.Members = casesMembers.ContainsKey(cases.ID) + ? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) + : new List(); + + result.Add(casesWrapper); + } + + return result; + } + + private IEnumerable GetUsersByIdList(IEnumerable ids) + { + return UserManager.GetUsers().Where(x => ids.Contains(x.ID)); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs index 801aa9d89cf..9adcd201412 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs @@ -32,6 +32,7 @@ using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Model; using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Models; @@ -42,9 +43,11 @@ using Autofac; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Security; using System.Web; @@ -686,17 +689,18 @@ public PersonWrapper DeletePeopleFromCompany(int companyid, int personid) /// Person /// [Create(@"contact/person")] - public PersonWrapper CreatePerson( - string firstName, - string lastName, - string jobTitle, - int companyId, - string about, - ShareType shareType, - IEnumerable managerList, - IEnumerable> customFieldList, - IEnumerable photo) + public PersonWrapper CreatePerson([FromForm] CreateOrUpdatePersonInDto intDto) { + string firstName = intDto.FirstName; + string lastName = intDto.LastName; + string jobTitle = intDto.JobTitle; + int companyId = intDto.CompanyId; + string about = intDto.About; + ShareType shareType = intDto.ShareType; + IEnumerable managerList = intDto.ManagerList; + IEnumerable> customFieldList = intDto.CustomFieldList; + IEnumerable photo = intDto.Photos; + if (companyId > 0) { var company = DaoFactory.GetContactDao().GetByID(companyId); @@ -732,18 +736,18 @@ public PersonWrapper CreatePerson( } } - var wrapper = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); + var outDto = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); var photoList = photo != null ? photo.ToList() : new List(); if (photoList.Any()) { - wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); + outDto.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); } MessageService.Send(MessageAction.PersonCreated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); - return wrapper; + return outDto; } /// @@ -862,18 +866,18 @@ public ContactWrapper MergeContacts(int fromcontactid, int tocontactid) /// /// [Update(@"contact/person/{personid:int}")] - public PersonWrapper UpdatePerson( - int personid, - string firstName, - string lastName, - string jobTitle, - int companyId, - string about, - ShareType shareType, - IEnumerable managerList, - IEnumerable> customFieldList, - IEnumerable photo) + public PersonWrapper UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdatePersonInDto inDto) { + string firstName = inDto.FirstName; + string lastName = inDto.LastName; + string jobTitle = inDto.JobTitle; + int companyId = inDto.CompanyId; + string about = inDto.About; + ShareType shareType = inDto.ShareType; + IEnumerable managerList = inDto.ManagerList; + IEnumerable> customFieldList = inDto.CustomFieldList; + IEnumerable photo = inDto.Photos; + if (personid <= 0 || string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) throw new ArgumentException(); var peopleInst = new Person @@ -907,18 +911,18 @@ public PersonWrapper UpdatePerson( } } - var wrapper = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); + var outDto = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); var photoList = photo != null ? photo.ToList() : new List(); if (photoList.Any()) { - wrapper.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); + outDto.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); } MessageService.Send(MessageAction.PersonUpdated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); - return wrapper; + return outDto; } /// @@ -937,14 +941,16 @@ public PersonWrapper UpdatePerson( /// [Create(@"contact/company")] public CompanyWrapper CreateCompany( - string companyName, - string about, - IEnumerable personList, - ShareType shareType, - IEnumerable managerList, - IEnumerable> customFieldList, - IEnumerable photo) + [FromForm] CreateOrUpdateCompanyInDto inDto) { + var personList = inDto.PersonList; + string companyName = inDto.CompanyName; + string about = inDto.About; + ShareType shareType = inDto.ShareType; + IEnumerable managerList = inDto.ManagerList; + IEnumerable> customFieldList = inDto.CustomFieldList; + IEnumerable photo = inDto.Photos; + var companyInst = new Company { CompanyName = companyName, @@ -1110,13 +1116,16 @@ public IEnumerable CreatePerson(IEnumerable [Update(@"contact/company/{companyid:int}")] public CompanyWrapper UpdateCompany( - int companyid, - string companyName, - string about, - ShareType shareType, - IEnumerable managerList, - IEnumerable> customFieldList) + [FromQuery]int companyid, + [FromForm] CreateOrUpdateCompanyInDto intDto) { + string companyName = intDto.CompanyName; + string about = intDto.About; + ShareType shareType = intDto.ShareType; + IEnumerable managerList = intDto.ManagerList; + IEnumerable> customFieldList = intDto.CustomFieldList; + IEnumerable photo = intDto.Photos; + var companyInst = new Company { ID = companyid, @@ -1407,8 +1416,13 @@ private void SetAccessToContact(Contact contact, bool isShared, IEnumerable [Update(@"contact/access")] - public IEnumerable SetAccessToBatchContact(IEnumerable contactid, bool isShared, IEnumerable managerList) + public IEnumerable SetAccessToBatchContact( + [FromBody]SetAccessToBatchContactInDto inDto) { + var contactid = inDto.ContactID; + var isShared = inDto.isShared; + var managerList = inDto.ManagerList; + if (contactid == null) throw new ArgumentException(); var result = new List(); @@ -1442,16 +1456,17 @@ public IEnumerable SetAccessToBatchContact(IEnumerable cont /// [Update(@"contact/filter/access")] public IEnumerable SetAccessToBatchContact( - IEnumerable tags, - int? contactStage, - int? contactType, - ContactListViewType contactListView, - ApiDateTime fromDate, - ApiDateTime toDate, - bool isPrivate, - IEnumerable managerList - ) + [FromForm] SetAccessToBatchContactByFilterInDto inDto) { + IEnumerable tags = inDto.Tags; + int? contactStage = inDto.ContactStage; + int? contactType = inDto.ContactType; + ContactListViewType contactListView = inDto.ContactListView; + ApiDateTime fromDate = inDto.FromDate; + ApiDateTime toDate = inDto.ToDate; + bool isPrivate = inDto.isPrivate; + IEnumerable managerList = inDto.ManagerList; + int contactStageInt = contactStage.HasValue ? contactStage.Value : -1; int contactTypeInt = contactType.HasValue ? contactType.Value : -1; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs index 1adc1fe401b..cd818be6a39 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs @@ -1,926 +1,939 @@ -///* -// * -// * (c) Copyright Ascensio System Limited 2010-2018 -// * -// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU -// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). -// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that -// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. -// * -// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR -// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html -// * -// * You can contact Ascensio System SIA by email at sales@onlyoffice.com -// * -// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display -// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. -// * -// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains -// * relevant author attributions when distributing the software. If the display of the logo in its graphic -// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" -// * in every copy of the program you distribute. -// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. -// * -//*/ - - -//using ASC.Api.Collections; -//using ASC.Api.Core; -//using ASC.Api.CRM.Wrappers; -//using ASC.Common.Web; -//using ASC.Core; -//using ASC.Core.Users; -//using ASC.CRM.Core; -//using ASC.CRM.Core.Entities; -//using ASC.CRM.Core.Enums; -//using ASC.MessagingSystem; -//using ASC.Web.Api.Models; -//using ASC.Web.Api.Routing; -//using ASC.Web.CRM.Classes; -//using ASC.Web.Files.Services.WCFService; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using ASC.CRM.Classes; - -//namespace ASC.Api.CRM -//{ -// public partial class CRMController -// { -// /// -// /// Returns the detailed information about the opportunity with the ID specified in the request -// /// -// /// Opportunity ID -// /// -// /// Opportunity -// /// -// /// Get opportunity by ID -// /// Opportunities -// /// -// /// -// [Read(@"opportunity/{opportunityid:int}")] -// public OpportunityWrapper GetDealByID(int opportunityid) -// { -// if (opportunityid <= 0) throw new ArgumentException(); - -// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); -// if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); - -// return OpportunityWrapperHelper.Get(deal); -// } - -// /// -// /// Updates the selected opportunity to the stage with the ID specified in the request -// /// -// /// Opportunity ID -// /// Opportunity stage ID -// /// -// /// Opportunity -// /// -// /// Update opportunity stage -// /// Opportunities -// /// -// /// -// [Update(@"opportunity/{opportunityid:int}/stage/{id:int}")] -// public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) -// { -// if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException(); - -// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); -// if (deal == null || !CRMSecurity.CanEdit(deal)) throw new ItemNotFoundException(); - -// var stage = DaoFactory.GetDealMilestoneDao().GetByID(stageid); -// if (stage == null) throw new ItemNotFoundException(); - -// deal.DealMilestoneID = stageid; -// deal.DealMilestoneProbability = stage.Probability; - -// deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue; -// DaoFactory.GetDealDao().EditDeal(deal); -// MessageService.Send( MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); - -// return OpportunityWrapperHelper.Get(deal); -// } - -// /// -// /// Sets access rights for the selected opportunity with the parameters specified in the request -// /// -// /// Opportunity ID -// /// Opportunity privacy: private or not -// /// List of users with access -// /// Set rights to opportunity -// /// Opportunities -// /// -// /// -// /// -// /// Opportunity -// /// -// [Update(@"opportunity/{opportunityid:int}/access")] -// public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) -// { -// if (opportunityid <= 0) throw new ArgumentException(); - -// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); -// if (deal == null) throw new ItemNotFoundException(); - -// if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); -// return SetAccessToDeal(deal, isPrivate, accessList, false, true); -// } - -// private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) -// { -// var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); -// if (isPrivate && accessListLocal.Count > 0) -// { - -// if (isNotify) -// { -// accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); -// NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, DaoFactory, accessListLocal.ToArray()); -// } - -// if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) -// { -// accessListLocal.Add(SecurityContext.CurrentAccount.ID); -// } - -// CRMSecurity.SetAccessTo(deal, accessListLocal); - -// if (isMessageServicSende) -// { -// var users = GetUsersByIdList(accessListLocal); -// MessageService.Send( MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); -// } -// } -// else -// { -// CRMSecurity.MakePublic(deal); -// if (isMessageServicSende) -// { -// MessageService.Send( MessageAction.OpportunityOpenedAccess, MessageTarget.Create(deal.ID), deal.Title); -// } -// } - -// return OpportunityWrapperHelper.Get(deal); -// } - -// /// -// /// Sets access rights for other users to the list of all opportunities matching the parameters specified in the request -// /// -// /// Opportunity responsible -// /// Opportunity stage ID -// /// Tags -// /// Contact ID -// /// Participation status: take into account opportunities where the contact is a participant or not -// /// Start date -// /// End date -// /// Opportunity stage type -// /// Opportunity privacy: private or not -// /// List of users with access -// /// Set opportunity access rights -// /// Opportunities -// /// -// /// -// /// -// /// Opportunity list -// /// -// [Update(@"opportunity/filter/access")] -// public IEnumerable SetAccessToBatchDeal( -// Guid responsibleid, -// int opportunityStagesid, -// IEnumerable tags, -// int contactid, -// DealMilestoneStatus? stageType, -// bool? contactAlsoIsParticipant, -// ApiDateTime fromDate, -// ApiDateTime toDate, -// bool isPrivate, -// IEnumerable accessList -// ) -// { -// var result = new List(); -// var deals = DaoFactory.GetDealDao() -// .GetDeals(ApiContext.FilterValue, -// responsibleid, -// opportunityStagesid, -// tags, -// contactid, -// stageType, -// contactAlsoIsParticipant, -// fromDate, toDate, 0, 0, null); -// if (!deals.Any()) return Enumerable.Empty(); - -// foreach (var deal in deals) -// { -// if (deal == null) throw new ItemNotFoundException(); - -// if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - -// SetAccessToDeal(deal.ID, isPrivate, accessList); -// result.Add(deal); -// } - -// return ToListOpportunityWrapper(result); -// } - -// /// -// /// Sets access rights for other users to the list of opportunities with the IDs specified in the request -// /// -// /// Opportunity ID list -// /// Opportunity privacy: private or not -// /// List of users with access -// /// Set opportunity access rights -// /// Opportunities -// /// -// /// -// /// -// /// Opportunity list -// /// -// [Update(@"opportunity/access")] -// public IEnumerable SetAccessToBatchDeal(IEnumerable opportunityid, bool isPrivate, IEnumerable accessList) -// { -// if(opportunityid == null) throw new ArgumentException(); +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Collections; +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Common.Web; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.MessagingSystem; +using ASC.Web.Api.Models; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using ASC.Web.Files.Services.WCFService; +using System; +using System.Collections.Generic; +using System.Linq; +using ASC.CRM.Classes; +using ASC.CRM.Model; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the detailed information about the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// + /// Opportunity + /// + /// Get opportunity by ID + /// Opportunities + /// + /// + [Read(@"opportunity/{opportunityid:int}")] + public OpportunityWrapper GetDealByID(int opportunityid) + { + if (opportunityid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); + + return OpportunityWrapperHelper.Get(deal); + } + + /// + /// Updates the selected opportunity to the stage with the ID specified in the request + /// + /// Opportunity ID + /// Opportunity stage ID + /// + /// Opportunity + /// + /// Update opportunity stage + /// Opportunities + /// + /// + [Update(@"opportunity/{opportunityid:int}/stage/{id:int}")] + public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) + { + if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null || !CRMSecurity.CanEdit(deal)) throw new ItemNotFoundException(); + + var stage = DaoFactory.GetDealMilestoneDao().GetByID(stageid); + if (stage == null) throw new ItemNotFoundException(); + + deal.DealMilestoneID = stageid; + deal.DealMilestoneProbability = stage.Probability; + + deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue; + DaoFactory.GetDealDao().EditDeal(deal); + MessageService.Send(MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); + + return OpportunityWrapperHelper.Get(deal); + } + + /// + /// Sets access rights for the selected opportunity with the parameters specified in the request + /// + /// Opportunity ID + /// Opportunity privacy: private or not + /// List of users with access + /// Set rights to opportunity + /// Opportunities + /// + /// + /// + /// Opportunity + /// + [Update(@"opportunity/{opportunityid:int}/access")] + public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) + { + if (opportunityid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + return SetAccessToDeal(deal, isPrivate, accessList, false, true); + } + + private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) + { + var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); + if (isPrivate && accessListLocal.Count > 0) + { + + if (isNotify) + { + accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); + NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, DaoFactory, accessListLocal.ToArray()); + } + + if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) + { + accessListLocal.Add(SecurityContext.CurrentAccount.ID); + } + + CRMSecurity.SetAccessTo(deal, accessListLocal); + + if (isMessageServicSende) + { + var users = GetUsersByIdList(accessListLocal); + MessageService.Send(MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); + } + } + else + { + CRMSecurity.MakePublic(deal); + if (isMessageServicSende) + { + MessageService.Send(MessageAction.OpportunityOpenedAccess, MessageTarget.Create(deal.ID), deal.Title); + } + } + + return OpportunityWrapperHelper.Get(deal); + } + + /// + /// Sets access rights for other users to the list of all opportunities matching the parameters specified in the request + /// + /// Opportunity responsible + /// Opportunity stage ID + /// Tags + /// Contact ID + /// Participation status: take into account opportunities where the contact is a participant or not + /// Start date + /// End date + /// Opportunity stage type + /// Opportunity privacy: private or not + /// List of users with access + /// Set opportunity access rights + /// Opportunities + /// + /// + /// + /// Opportunity list + /// + [Update(@"opportunity/filter/access")] + public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealByFilterInDto inDto) + { + var responsibleid = inDto.Responsibleid; + var opportunityStagesid = inDto.OpportunityStagesid; + var contactid = inDto.Contactid; + var tags = inDto.Tags; + var stageType = inDto.StageType; + var contactAlsoIsParticipant = inDto.ContactAlsoIsParticipant; + var fromDate = inDto.FromDate; + var toDate = inDto.ToDate; + var isPrivate = inDto.isPrivate; + var accessList = inDto.AccessList; + + var result = new List(); -// var result = new List(); - -// var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); - -// if (!deals.Any()) return new List(); - -// foreach (var d in deals) -// { -// if (d == null) throw new ItemNotFoundException(); - -// if (!(CRMSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; - -// SetAccessToDeal(d, isPrivate, accessList, false, true); -// result.Add(d); -// } - -// return ToListOpportunityWrapper(result); -// } - - -// /// -// /// Deletes the group of opportunities with the IDs specified in the request -// /// -// /// Opportunity ID list -// /// -// /// -// /// Delete opportunity group -// /// Opportunities -// /// -// /// Opportunity list -// /// -// [Update(@"opportunity")] -// public IEnumerable DeleteBatchDeals(IEnumerable opportunityids) -// { -// if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); - -// var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); -// MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); - -// return ToListOpportunityWrapper(opportunities); -// } - -// /// -// /// Deletes the list of all opportunities matching the parameters specified in the request -// /// -// /// Opportunity responsible -// /// Opportunity stage ID -// /// Tags -// /// Contact ID -// /// Participation status: take into account opportunities where the contact is a participant or not -// /// Start date -// /// End date -// /// Opportunity stage type -// /// -// /// -// /// Delete opportunity group -// /// Opportunities -// /// -// /// Opportunity list -// /// -// [Delete(@"opportunity/filter")] -// public IEnumerable DeleteBatchDeals( -// Guid responsibleid, -// int opportunityStagesid, -// IEnumerable tags, -// int contactid, -// DealMilestoneStatus? stageType, -// bool? contactAlsoIsParticipant, -// ApiDateTime fromDate, -// ApiDateTime toDate) -// { -// var deals = DaoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, -// responsibleid, -// opportunityStagesid, -// tags, -// contactid, -// stageType, -// contactAlsoIsParticipant, -// fromDate, toDate, 0, 0, null); - -// if (!deals.Any()) return Enumerable.Empty(); - -// deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals); -// MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); - -// return ToListOpportunityWrapper(deals); -// } - -// /// -// /// Returns the list of all opportunities matching the parameters specified in the request -// /// -// /// Opportunity responsible -// /// Opportunity stage ID -// /// Tags -// /// Contact ID -// /// Participation status: take into account opportunities where the contact is a participant or not -// /// Start date -// /// End date -// /// Opportunity stage type -// /// Get opportunity list -// /// Opportunities -// /// -// /// Opportunity list -// /// -// [Read(@"opportunity/filter")] -// public IEnumerable GetDeals( -// Guid responsibleid, -// int opportunityStagesid, -// IEnumerable tags, -// int contactid, -// DealMilestoneStatus? stageType, -// bool? contactAlsoIsParticipant, -// ApiDateTime fromDate, -// ApiDateTime toDate) -// { -// DealSortedByType dealSortedByType; - -// IEnumerable result; - -// var searchString = ApiContext.FilterValue; - -// OrderBy dealsOrderBy; - -// if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) -// { -// dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending); -// } -// else if (string.IsNullOrEmpty(ApiContext.SortBy)) -// { -// dealsOrderBy = new OrderBy(DealSortedByType.Stage, true); -// } -// else -// { -// dealsOrderBy = null; -// } - -// var fromIndex = (int)ApiContext.StartIndex; -// var count = (int)ApiContext.Count; - -// if (dealsOrderBy != null) -// { -// result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( -// searchString, -// responsibleid, -// opportunityStagesid, -// tags, -// contactid, -// stageType, -// contactAlsoIsParticipant, -// fromDate, -// toDate, -// fromIndex, -// count, -// dealsOrderBy)).ToList(); - -// ApiContext.SetDataPaginated(); -// ApiContext.SetDataFiltered(); -// ApiContext.SetDataSorted(); -// } -// else -// { -// result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( -// searchString, -// responsibleid, -// opportunityStagesid, -// tags, -// contactid, -// stageType, -// contactAlsoIsParticipant, -// fromDate, -// toDate, -// 0, 0, null)).ToList(); -// } - - -// int totalCount; - -// if (result.Count() < count) -// { -// totalCount = fromIndex + result.Count(); -// } -// else -// { -// totalCount = DaoFactory -// .GetDealDao() -// .GetDealsCount(searchString, -// responsibleid, -// opportunityStagesid, -// tags, -// contactid, -// stageType, -// contactAlsoIsParticipant, -// fromDate, -// toDate); -// } - -// ApiContext.SetTotalCount(totalCount); - -// return result; -// } - -// /// -// /// Deletes the opportunity with the ID specified in the request -// /// -// /// Opportunity ID -// /// Delete opportunity -// /// Opportunities -// /// -// /// -// /// -// /// Opportunity -// /// -// [Delete(@"opportunity/{opportunityid:int}")] -// public OpportunityWrapper DeleteDeal(int opportunityid) -// { -// if (opportunityid <= 0) throw new ArgumentException(); - -// var deal = DaoFactory.GetDealDao().DeleteDeal(opportunityid); -// if (deal == null) throw new ItemNotFoundException(); - -// MessageService.Send( MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); - -// return OpportunityWrapperHelper.Get(deal); -// } - -// /// -// /// Creates the opportunity with the parameters specified in the request -// /// -// /// Create opportunity -// /// Opportunity primary contact -// /// Participants -// /// Opportunity title -// /// Opportunity description -// /// Opportunity responsible -// /// Bid -// /// Amount of transaction -// /// Currency (Abbreviation) -// /// Period -// /// Stage ID -// /// Opportunity success probability -// /// Actual opportunity closure date -// /// Expected opportunity closure date -// /// User field list -// /// Opportunity privacy: private or not -// /// List of users with access to the opportunity -// /// Notify users in accessList about the opportunity -// /// Opportunities -// /// -// /// Opportunity -// /// -// /// -// [Create(@"opportunity")] -// public OpportunityWrapper CreateDeal( -// int contactid, -// IEnumerable members, -// string title, -// string description, -// Guid responsibleid, -// BidType bidType, -// decimal bidValue, -// string bidCurrencyAbbr, -// int perPeriodValue, -// int stageid, -// int successProbability, -// ApiDateTime actualCloseDate, -// ApiDateTime expectedCloseDate, -// IEnumerable> customFieldList, -// bool isPrivate, -// IEnumerable accessList, -// bool isNotify) -// { -// var deal = new Deal -// { -// Title = title, -// Description = description, -// ResponsibleID = responsibleid, -// BidType = bidType, -// BidValue = bidValue, -// PerPeriodValue = perPeriodValue, -// DealMilestoneID = stageid, -// DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability), -// ContactID = contactid, -// ActualCloseDate = actualCloseDate, -// ExpectedCloseDate = expectedCloseDate, -// BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null, -// }; - -// CRMSecurity.DemandCreateOrUpdate(deal); - -// deal.ID = DaoFactory.GetDealDao().CreateNewDeal(deal); - -// deal.CreateBy = SecurityContext.CurrentAccount.ID; -// deal.CreateOn = DateTime.UtcNow; - -// SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); - -// var membersList = members != null ? members.ToList() : new List(); - -// if (deal.ContactID > 0) -// membersList.Add(deal.ContactID); - -// if (membersList.Any()) -// { -// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); -// membersList = contacts.Select(m => m.ID).ToList(); -// DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); -// } - -// if (customFieldList != null) -// { -// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); -// foreach (var field in customFieldList) -// { -// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; -// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); -// } -// } - -// return OpportunityWrapperHelper.Get(deal); -// } - -// /// -// /// Updates the selected opportunity with the parameters specified in the request -// /// -// /// Update opportunity -// ///Opportunity ID -// ///Opportunity primary contact -// /// Participants -// /// Opportunity title -// /// Opportunity description -// /// Opportunity responsible -// /// Bid -// /// Amount of transaction -// /// Currency (Abbreviation) -// /// Period -// /// Stage ID -// /// Opportunity success probability -// /// Actual opportunity closure date -// /// Expected opportunity closure date -// /// User field list -// /// Opportunity privacy: private or not -// /// List of users with access to the opportunity -// /// Notify users in accessList about the opportunity -// /// Opportunities -// /// -// /// Opportunity -// /// -// /// -// [Update(@"opportunity/{opportunityid:int}")] -// public OpportunityWrapper UpdateDeal( -// int opportunityid, -// int contactid, -// IEnumerable members, -// string title, -// string description, -// Guid responsibleid, -// BidType bidType, -// decimal bidValue, -// string bidCurrencyAbbr, -// int perPeriodValue, -// int stageid, -// int successProbability, -// ApiDateTime actualCloseDate, -// ApiDateTime expectedCloseDate, -// IEnumerable> customFieldList, -// bool isPrivate, -// IEnumerable accessList, -// bool isNotify) -// { -// var deal = DaoFactory.GetDealDao().GetByID(opportunityid); -// if (deal == null) throw new ItemNotFoundException(); - -// deal.Title = title; -// deal.Description = description; -// deal.ResponsibleID = responsibleid; -// deal.BidType = bidType; -// deal.BidValue = bidValue; -// deal.PerPeriodValue = perPeriodValue; -// deal.DealMilestoneID = stageid; -// deal.DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability); -// deal.ContactID = contactid; -// deal.ActualCloseDate = actualCloseDate; -// deal.ExpectedCloseDate = expectedCloseDate; -// deal.BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null; - -// CRMSecurity.DemandCreateOrUpdate(deal); - -// DaoFactory.GetDealDao().EditDeal(deal); - -// deal = DaoFactory.GetDealDao().GetByID(opportunityid); - -// var membersList = members != null ? members.ToList() : new List(); -// if (membersList.Any()) -// { -// var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); -// membersList = contacts.Select(m => m.ID).ToList(); - -// DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); -// } - - -// if (CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) -// { -// SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); -// } - -// if (customFieldList != null) -// { -// var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); -// foreach (var field in customFieldList) -// { -// if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; -// DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); -// } -// } - -// return OpportunityWrapperHelper.Get(deal); -// } - -// /// -// /// Returns the list of all contacts associated with the opportunity with the ID specified in the request -// /// -// /// Opportunity ID -// /// Get all opportunity contacts -// /// Opportunities -// /// Contact list -// /// -// /// -// [Read(@"opportunity/{opportunityid:int}/contact")] -// public IEnumerable GetDealMembers(int opportunityid) -// { -// var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - -// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - -// var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); -// if (contactIDs == null) return new ItemList(); - -// var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); - -// result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); - -// return result; -// } - -// /// -// /// Adds the selected contact to the opportunity with the ID specified in the request -// /// -// /// Opportunity ID -// /// Contact ID -// /// Add opportunity contact -// /// Opportunities -// /// -// /// -// /// Participant -// /// -// [Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] -// public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) -// { -// if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); - -// var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); -// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - -// var contact = DaoFactory.GetContactDao().GetByID(contactid); -// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - -// var result = ToContactWrapper(contact); - -// DaoFactory.GetDealDao().AddMember(opportunityid, contactid); - -// var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; -// MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); - -// return result; -// } - -// /// -// /// Deletes the selected contact from the opportunity with the ID specified in the request -// /// -// /// Opportunity ID -// /// Contact ID -// /// Delete opportunity contact -// /// Opportunities -// /// -// /// -// /// -// /// Participant -// /// -// [Delete(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] -// public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) -// { -// if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); - -// var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); -// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - -// var contact = DaoFactory.GetContactDao().GetByID(contactid); -// if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - -// var result = ToContactWrapper(contact); - -// DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); - -// var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson; -// MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); - -// return result; -// } - -// /// -// /// Returns the list of 30 opportunities in the CRM module with prefix -// /// -// /// -// /// -// /// -// /// Opportunities -// /// -// /// Opportunities list -// /// -// /// false -// [Read(@"opportunity/byprefix")] -// public IEnumerable GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true) -// { -// var result = new List(); - -// if (contactID > 0 && internalSearch) -// { -// var findedDeals = DaoFactory.GetDealDao().GetDealsByContactID(contactID); -// foreach (var item in findedDeals) -// { -// if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) -// { -// result.Add(OpportunityWrapperHelper.Get(item)); -// } -// } - -// ApiContext.SetTotalCount(result.Count); -// } -// else -// { -// const int maxItemCount = 30; -// var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); -// foreach (var item in findedDeals) -// { -// result.Add(OpportunityWrapperHelper.Get(item)); -// } -// } - -// return result; -// } - -// /// -// /// Returns the list of all contact opportunities -// /// -// /// Contact ID -// /// Get opportunity list -// /// Opportunities -// /// -// /// Opportunity list -// /// -// [Read(@"opportunity/bycontact/{contactid:int}")] -// public IEnumerable GetDeals(int contactid) -// { -// var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid); -// return ToListOpportunityWrapper(deals); -// } - -// /// false -// [Update(@"opportunity/{opportunityid:int}/creationdate")] -// public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate) -// { -// var dao = DaoFactory.GetDealDao(); -// var opportunity = dao.GetByID(opportunityid); - -// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) -// throw new ItemNotFoundException(); - -// dao.SetDealCreationDate(opportunityid, creationDate); -// } - -// /// false -// [Update(@"opportunity/{opportunityid:int}/lastmodifeddate")] -// public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDate) -// { -// var dao = DaoFactory.GetDealDao(); -// var opportunity = dao.GetByID(opportunityid); - -// if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) -// throw new ItemNotFoundException(); - -// dao.SetDealLastModifedDate(opportunityid, lastModifedDate); -// } - - -// private IEnumerable ToListOpportunityWrapper(ICollection deals) -// { -// if (deals == null || deals.Count == 0) return new List(); - -// var result = new List(); - -// var contactIDs = new List(); -// var dealIDs = new List(); -// var dealMilestoneIDs = new List(); - -// foreach (var deal in deals) -// { -// contactIDs.Add(deal.ContactID); -// dealIDs.Add(deal.ID); -// dealMilestoneIDs.Add(deal.DealMilestoneID); -// } - -// dealMilestoneIDs = dealMilestoneIDs.Distinct().ToList(); - -// var contacts = new Dictionary(); - -// var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) -// .GroupBy(item => item.EntityID) -// .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); - -// var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) -// .ToDictionary(item => item.ID, item => new DealMilestoneBaseWrapper(item)); - - -// var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); - -// foreach (var value in dealMembers.Values) -// { -// contactIDs.AddRange(value); -// } - -// contactIDs = contactIDs.Distinct().ToList(); - -// if (contactIDs.Count > 0) -// { -// DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item => -// { -// if (item == null) return; -// contacts.Add(item.ID, ContactWrapperHelper.GetContactBaseWrapper(item)); -// }); -// } - -// foreach (var deal in deals) -// { -// var dealWrapper = OpportunityWrapperHelper.Get(deal); - -// if (contacts.ContainsKey(deal.ContactID)) -// { -// dealWrapper.Contact = contacts[deal.ContactID]; -// } - -// dealWrapper.CustomFields = customFields.ContainsKey(deal.ID) -// ? customFields[deal.ID] -// : new List(); - -// dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.Id) -// ? dealMembers[dealWrapper.Id].Where(contacts.ContainsKey).Select(item => contacts[item]) -// : new List(); - -// if (dealMilestones.ContainsKey(deal.DealMilestoneID)) -// { -// dealWrapper.Stage = dealMilestones[deal.DealMilestoneID]; -// } + var deals = DaoFactory.GetDealDao() + .GetDeals(ApiContext.FilterValue, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, toDate, 0, 0, null); + + if (!deals.Any()) return Enumerable.Empty(); + + foreach (var deal in deals) + { + if (deal == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToDeal(deal.ID, isPrivate, accessList); + + result.Add(deal); + + } + + return ToListOpportunityWrapper(result); + } + + /// + /// Sets access rights for other users to the list of opportunities with the IDs specified in the request + /// + /// Opportunity ID list + /// Opportunity privacy: private or not + /// List of users with access + /// Set opportunity access rights + /// Opportunities + /// + /// + /// + /// Opportunity list + /// + [Update(@"opportunity/access")] + public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealInDto inDto) + { + var opportunityid = inDto.Opportunityid; + var isPrivate = inDto.isPrivate; + var accessList = inDto.AccessList; + + if (opportunityid == null) throw new ArgumentException(); + + var result = new List(); + + var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); + + if (!deals.Any()) return new List(); + + foreach (var d in deals) + { + if (d == null) throw new ItemNotFoundException(); + + if (!(CRMSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + + SetAccessToDeal(d, isPrivate, accessList, false, true); + result.Add(d); + } + + return ToListOpportunityWrapper(result); + } + + + /// + /// Deletes the group of opportunities with the IDs specified in the request + /// + /// Opportunity ID list + /// + /// + /// Delete opportunity group + /// Opportunities + /// + /// Opportunity list + /// + [Update(@"opportunity")] + public IEnumerable DeleteBatchDeals(IEnumerable opportunityids) + { + if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); + + var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); + MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); + + return ToListOpportunityWrapper(opportunities); + } + + /// + /// Deletes the list of all opportunities matching the parameters specified in the request + /// + /// Opportunity responsible + /// Opportunity stage ID + /// Tags + /// Contact ID + /// Participation status: take into account opportunities where the contact is a participant or not + /// Start date + /// End date + /// Opportunity stage type + /// + /// + /// Delete opportunity group + /// Opportunities + /// + /// Opportunity list + /// + [Delete(@"opportunity/filter")] + public IEnumerable DeleteBatchDeals( + Guid responsibleid, + int opportunityStagesid, + IEnumerable tags, + int contactid, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + ApiDateTime fromDate, + ApiDateTime toDate) + { + var deals = DaoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, toDate, 0, 0, null); + + if (!deals.Any()) return Enumerable.Empty(); + + deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals); + MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); + + return ToListOpportunityWrapper(deals); + } + + /// + /// Returns the list of all opportunities matching the parameters specified in the request + /// + /// Opportunity responsible + /// Opportunity stage ID + /// Tags + /// Contact ID + /// Participation status: take into account opportunities where the contact is a participant or not + /// Start date + /// End date + /// Opportunity stage type + /// Get opportunity list + /// Opportunities + /// + /// Opportunity list + /// + [Read(@"opportunity/filter")] + public IEnumerable GetDeals( + Guid responsibleid, + int opportunityStagesid, + IEnumerable tags, + int contactid, + DealMilestoneStatus? stageType, + bool? contactAlsoIsParticipant, + ApiDateTime fromDate, + ApiDateTime toDate) + { + DealSortedByType dealSortedByType; + + IEnumerable result; + + var searchString = ApiContext.FilterValue; + + OrderBy dealsOrderBy; + + if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) + { + dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending); + } + else if (string.IsNullOrEmpty(ApiContext.SortBy)) + { + dealsOrderBy = new OrderBy(DealSortedByType.Stage, true); + } + else + { + dealsOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (dealsOrderBy != null) + { + result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( + searchString, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate, + fromIndex, + count, + dealsOrderBy)).ToList(); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( + searchString, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate, + 0, 0, null)).ToList(); + } + + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory + .GetDealDao() + .GetDealsCount(searchString, + responsibleid, + opportunityStagesid, + tags, + contactid, + stageType, + contactAlsoIsParticipant, + fromDate, + toDate); + } + + ApiContext.SetTotalCount(totalCount); + + return result; + } + + /// + /// Deletes the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Delete opportunity + /// Opportunities + /// + /// + /// + /// Opportunity + /// + [Delete(@"opportunity/{opportunityid:int}")] + public OpportunityWrapper DeleteDeal(int opportunityid) + { + if (opportunityid <= 0) throw new ArgumentException(); + + var deal = DaoFactory.GetDealDao().DeleteDeal(opportunityid); + if (deal == null) throw new ItemNotFoundException(); + + MessageService.Send(MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); + + return OpportunityWrapperHelper.Get(deal); + } + + /// + /// Creates the opportunity with the parameters specified in the request + /// + /// Create opportunity + /// Opportunity primary contact + /// Participants + /// Opportunity title + /// Opportunity description + /// Opportunity responsible + /// Bid + /// Amount of transaction + /// Currency (Abbreviation) + /// Period + /// Stage ID + /// Opportunity success probability + /// Actual opportunity closure date + /// Expected opportunity closure date + /// User field list + /// Opportunity privacy: private or not + /// List of users with access to the opportunity + /// Notify users in accessList about the opportunity + /// Opportunities + /// + /// Opportunity + /// + /// + [Create(@"opportunity")] + public OpportunityWrapper CreateDeal(CreateOrUpdateDealInDto inDto) + { + + var title = inDto.Title; + var description = inDto.Description; + var responsibleid = inDto.Responsibleid; + var bidType = inDto.BidType; + var bidValue = inDto.BidValue; + var perPeriodValue = inDto.PerPeriodValue; + var stageid = inDto.Stageid; + var successProbability = inDto.SuccessProbability; + var contactid = inDto.Contactid; + var actualCloseDate = inDto.ActualCloseDate; + var expectedCloseDate = inDto.ExpectedCloseDate; + var bidCurrencyAbbr = inDto.BidCurrencyAbbr; + var isPrivate = inDto.isPrivate; + var isNotify = inDto.isNotify; + var accessList = inDto.AccessList; + var customFieldList = inDto.CustomFieldList; + var members = inDto.Members; + + var deal = new Deal + { + Title = title, + Description = description, + ResponsibleID = responsibleid, + BidType = bidType, + BidValue = bidValue, + PerPeriodValue = perPeriodValue, + DealMilestoneID = stageid, + DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability), + ContactID = contactid, + ActualCloseDate = actualCloseDate, + ExpectedCloseDate = expectedCloseDate, + BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null, + }; + + CRMSecurity.DemandCreateOrUpdate(deal); + + deal.ID = DaoFactory.GetDealDao().CreateNewDeal(deal); + + deal.CreateBy = SecurityContext.CurrentAccount.ID; + deal.CreateOn = DateTime.UtcNow; + + SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); + + var membersList = members != null ? members.ToList() : new List(); + + if (deal.ContactID > 0) + membersList.Add(deal.ContactID); + + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); + } + } + + return OpportunityWrapperHelper.Get(deal); + } + + /// + /// Updates the selected opportunity with the parameters specified in the request + /// + /// Update opportunity + ///Opportunity ID + ///Opportunity primary contact + /// Participants + /// Opportunity title + /// Opportunity description + /// Opportunity responsible + /// Bid + /// Amount of transaction + /// Currency (Abbreviation) + /// Period + /// Stage ID + /// Opportunity success probability + /// Actual opportunity closure date + /// Expected opportunity closure date + /// User field list + /// Opportunity privacy: private or not + /// List of users with access to the opportunity + /// Notify users in accessList about the opportunity + /// Opportunities + /// + /// Opportunity + /// + /// + [Update(@"opportunity/{opportunityid:int}")] + public OpportunityWrapper UpdateDeal( + int opportunityid, CreateOrUpdateDealInDto inDto) + { + + var title = inDto.Title; + var description = inDto.Description; + var responsibleid = inDto.Responsibleid; + var bidType = inDto.BidType; + var bidValue = inDto.BidValue; + var perPeriodValue = inDto.PerPeriodValue; + var stageid = inDto.Stageid; + var successProbability = inDto.SuccessProbability; + var contactid = inDto.Contactid; + var actualCloseDate = inDto.ActualCloseDate; + var expectedCloseDate = inDto.ExpectedCloseDate; + var bidCurrencyAbbr = inDto.BidCurrencyAbbr; + var isPrivate = inDto.isPrivate; + var isNotify = inDto.isNotify; + var accessList = inDto.AccessList; + var customFieldList = inDto.CustomFieldList; + var members = inDto.Members; + + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null) throw new ItemNotFoundException(); + + deal.Title = title; + deal.Description = description; + deal.ResponsibleID = responsibleid; + deal.BidType = bidType; + deal.BidValue = bidValue; + deal.PerPeriodValue = perPeriodValue; + deal.DealMilestoneID = stageid; + deal.DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability); + deal.ContactID = contactid; + deal.ActualCloseDate = actualCloseDate; + deal.ExpectedCloseDate = expectedCloseDate; + deal.BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null; + + CRMSecurity.DemandCreateOrUpdate(deal); + + DaoFactory.GetDealDao().EditDeal(deal); + + deal = DaoFactory.GetDealDao().GetByID(opportunityid); + + var membersList = members != null ? members.ToList() : new List(); + if (membersList.Any()) + { + var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + membersList = contacts.Select(m => m.ID).ToList(); + + DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); + } + + + if (CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) + { + SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); + } + + if (customFieldList != null) + { + var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); + foreach (var field in customFieldList) + { + if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; + DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); + } + } + + return OpportunityWrapperHelper.Get(deal); + } + + /// + /// Returns the list of all contacts associated with the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Get all opportunity contacts + /// Opportunities + /// Contact list + /// + /// + [Read(@"opportunity/{opportunityid:int}/contact")] + public IEnumerable GetDealMembers(int opportunityid) + { + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); + if (contactIDs == null) return new ItemList(); + + var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); + + result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); + + return result; + } + + /// + /// Adds the selected contact to the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Contact ID + /// Add opportunity contact + /// Opportunities + /// + /// + /// Participant + /// + [Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] + public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) + { + if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); + + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var result = ToContactWrapper(contact); + + DaoFactory.GetDealDao().AddMember(opportunityid, contactid); + + var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; + MessageService.Send(messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + + return result; + } + + /// + /// Deletes the selected contact from the opportunity with the ID specified in the request + /// + /// Opportunity ID + /// Contact ID + /// Delete opportunity contact + /// Opportunities + /// + /// + /// + /// Participant + /// + [Delete(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] + public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) + { + if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); + + var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + + var contact = DaoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + + var result = ToContactWrapper(contact); + + DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); + + var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson; + MessageService.Send(messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + + return result; + } + + /// + /// Returns the list of 30 opportunities in the CRM module with prefix + /// + /// + /// + /// + /// Opportunities + /// + /// Opportunities list + /// + /// false + [Read(@"opportunity/byprefix")] + public IEnumerable GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true) + { + var result = new List(); + + if (contactID > 0 && internalSearch) + { + var findedDeals = DaoFactory.GetDealDao().GetDealsByContactID(contactID); + foreach (var item in findedDeals) + { + if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) + { + result.Add(OpportunityWrapperHelper.Get(item)); + } + } + + ApiContext.SetTotalCount(result.Count); + } + else + { + const int maxItemCount = 30; + var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); + foreach (var item in findedDeals) + { + result.Add(OpportunityWrapperHelper.Get(item)); + } + } + + return result; + } + + /// + /// Returns the list of all contact opportunities + /// + /// Contact ID + /// Get opportunity list + /// Opportunities + /// + /// Opportunity list + /// + [Read(@"opportunity/bycontact/{contactid:int}")] + public IEnumerable GetDeals(int contactid) + { + var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid); + return ToListOpportunityWrapper(deals); + } + + /// false + [Update(@"opportunity/{opportunityid:int}/creationdate")] + public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate) + { + var dao = DaoFactory.GetDealDao(); + var opportunity = dao.GetByID(opportunityid); + + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) + throw new ItemNotFoundException(); + + dao.SetDealCreationDate(opportunityid, creationDate); + } + + /// false + [Update(@"opportunity/{opportunityid:int}/lastmodifeddate")] + public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDate) + { + var dao = DaoFactory.GetDealDao(); + var opportunity = dao.GetByID(opportunityid); + + if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) + throw new ItemNotFoundException(); + + dao.SetDealLastModifedDate(opportunityid, lastModifedDate); + } + + + private IEnumerable ToListOpportunityWrapper(ICollection deals) + { + if (deals == null || deals.Count == 0) return new List(); + + var result = new List(); + + var contactIDs = new List(); + var dealIDs = new List(); + var dealMilestoneIDs = new List(); + + foreach (var deal in deals) + { + contactIDs.Add(deal.ContactID); + dealIDs.Add(deal.ID); + dealMilestoneIDs.Add(deal.DealMilestoneID); + } + + dealMilestoneIDs = dealMilestoneIDs.Distinct().ToList(); + + var contacts = new Dictionary(); + + var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) + .GroupBy(item => item.EntityID) + .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + + var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) + .ToDictionary(item => item.ID, item => new DealMilestoneBaseWrapper(item)); + + + var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); + + foreach (var value in dealMembers.Values) + { + contactIDs.AddRange(value); + } + + contactIDs = contactIDs.Distinct().ToList(); + + if (contactIDs.Count > 0) + { + DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item => + { + if (item == null) return; + contacts.Add(item.ID, ContactWrapperHelper.GetContactBaseWrapper(item)); + }); + } + + foreach (var deal in deals) + { + var dealWrapper = OpportunityWrapperHelper.Get(deal); + + if (contacts.ContainsKey(deal.ContactID)) + { + dealWrapper.Contact = contacts[deal.ContactID]; + } + + dealWrapper.CustomFields = customFields.ContainsKey(deal.ID) + ? customFields[deal.ID] + : new List(); + + dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.Id) + ? dealMembers[dealWrapper.Id].Where(contacts.ContainsKey).Select(item => contacts[item]) + : new List(); + + if (dealMilestones.ContainsKey(deal.DealMilestoneID)) + { + dealWrapper.Stage = dealMilestones[deal.DealMilestoneID]; + } -// dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); + dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); -// if (dealWrapper.IsPrivate) -// { -// dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); -// } + if (dealWrapper.IsPrivate) + { + dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); + } -// if (!string.IsNullOrEmpty(deal.BidCurrency)) -// { -// dealWrapper.BidCurrency = CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); -// } + if (!string.IsNullOrEmpty(deal.BidCurrency)) + { + dealWrapper.BidCurrency = CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); + } -// result.Add(dealWrapper); -// } + result.Add(dealWrapper); + } -// return result; -// } -// } -//} \ No newline at end of file + return result; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs index 4e3d1f22775..2b20cec2da5 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs +++ b/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs @@ -1,1469 +1,1511 @@ -///* -// * -// * (c) Copyright Ascensio System Limited 2010-2018 -// * -// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU -// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). -// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that -// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. -// * -// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR -// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html -// * -// * You can contact Ascensio System SIA by email at sales@onlyoffice.com -// * -// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display -// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. -// * -// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains -// * relevant author attributions when distributing the software. If the display of the logo in its graphic -// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" -// * in every copy of the program you distribute. -// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. -// * -//*/ - - -//using ASC.Api.Core; -//using ASC.Api.CRM.Wrappers; -//using ASC.Api.Documents; -//using ASC.Common.Web; -//using ASC.Core; -//using ASC.CRM.Classes; -//using ASC.CRM.Core; -//using ASC.CRM.Core.Entities; -//using ASC.CRM.Core.Enums; -//using ASC.CRM.Resources; -//using ASC.MessagingSystem; -//using ASC.Web.Api.Routing; -//using ASC.Web.CRM.Classes; -//using System; -//using System.Collections.Generic; -//using System.Linq; - -//namespace ASC.Api.CRM -//{ -// public partial class CRMController -// { -// /// -// /// Returns the detailed information about the invoice with the ID specified in the request -// /// -// /// Invoice ID -// /// Get invoice by ID -// /// Invoices -// /// Invoice -// [Read(@"invoice/{invoiceid:int}")] -// public InvoiceWrapper GetInvoiceByID(int invoiceid) -// { -// if (invoiceid <= 0) throw new ArgumentException(); - -// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); -// if (invoice == null) throw new ItemNotFoundException(); - -// if (!CRMSecurity.CanAccessTo(invoice)) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// return InvoiceWrapperHelper.Get(invoice); -// } - -// /// -// /// Returns the detailed information about the invoice sample -// /// -// /// Get invoice sample -// /// Invoices -// /// Invoice -// [Read(@"invoice/sample")] -// public InvoiceWrapper GetInvoiceSample() -// { -// var sample = InvoiceWrapper.GetSample(); -// sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); -// sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; - -// sample.IssueDate = ApiDateTimeHelper.Get(DateTime.UtcNow); -// sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); -// sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow); - -// sample.Currency = CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency); - -// sample.InvoiceLines.First().Quantity = 1; - -// return sample; -// } - -// /// -// /// Returns the json data of the invoice with the ID specified in the request -// /// -// /// Invoice ID -// /// Get invoice json data -// /// Invoices -// /// Json Data -// [Read(@"invoice/jsondata/{invoiceid:int}")] -// public string GetInvoiceJsonData(int invoiceid) -// { -// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); -// if (invoice == null) throw new ItemNotFoundException(); - -// if (!CRMSecurity.CanAccessTo(invoice)) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// return invoice.JsonData; -// } - -// /// -// /// Returns the list of invoices matching the creteria specified in the request -// /// -// /// Invoice status -// /// Invoice issue date from -// /// Invoice issue date to -// /// Invoice due date from -// /// Invoice due date to -// /// Invoice entity type -// /// Invoice entity ID -// /// Invoice currency -// /// Get invoice list -// /// Invoices -// /// Invoice list -// [Read(@"invoice/filter")] -// public IEnumerable GetInvoices( -// InvoiceStatus? status, -// ApiDateTime issueDateFrom, -// ApiDateTime issueDateTo, -// ApiDateTime dueDateFrom, -// ApiDateTime dueDateTo, -// String entityType, -// int entityid, -// String currency -// ) -// { -// if (!String.IsNullOrEmpty(entityType) && !( -// String.Compare(entityType, "contact", true) == 0 || -// String.Compare(entityType, "opportunity", true) == 0 || -// String.Compare(entityType, "case", true) == 0)) -// throw new ArgumentException(); - -// IEnumerable result; - -// InvoiceSortedByType sortBy; - -// OrderBy invoiceOrderBy; - -// var searchString = ApiContext.FilterValue; - -// if (InvoiceSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) -// { -// invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); -// } -// else if (String.IsNullOrEmpty(ApiContext.SortBy)) -// { -// invoiceOrderBy = new OrderBy(InvoiceSortedByType.Number, true); -// } -// else -// { -// invoiceOrderBy = null; -// } - -// var fromIndex = (int)ApiContext.StartIndex; -// var count = (int)ApiContext.Count; - -// if (invoiceOrderBy != null) -// { -// result = ToListInvoiceBaseWrappers( -// DaoFactory.GetInvoiceDao().GetInvoices( -// searchString, -// status, -// issueDateFrom, issueDateTo, -// dueDateFrom, dueDateTo, -// ToEntityType(entityType), entityid, -// currency, -// fromIndex, count, -// invoiceOrderBy)); - -// ApiContext.SetDataPaginated(); -// ApiContext.SetDataFiltered(); -// ApiContext.SetDataSorted(); -// } -// else -// { -// result = ToListInvoiceBaseWrappers( -// DaoFactory.GetInvoiceDao().GetInvoices( -// searchString, -// status, -// issueDateFrom, issueDateTo, -// dueDateFrom, dueDateTo, -// ToEntityType(entityType), entityid, -// currency, -// 0, -// 0, -// null)); -// } - -// int totalCount; - -// if (result.Count() < count) -// { -// totalCount = fromIndex + result.Count(); -// } -// else -// { -// totalCount = DaoFactory.GetInvoiceDao().GetInvoicesCount( -// searchString, -// status, -// issueDateFrom, issueDateTo, -// dueDateFrom, dueDateTo, -// ToEntityType(entityType), entityid, -// currency); -// } - -// ApiContext.SetTotalCount(totalCount); - -// return result; -// } - -// /// -// /// Returns the list of all invoices associated with the entity with the ID and type specified in the request -// /// -// /// Invoice entity type -// /// Invoice entity ID -// /// Get entity invoices -// /// Invoices -// /// Invoice list -// [Read(@"{entityType:(contact|person|company|opportunity)}/invoicelist/{entityid:int}")] -// public IEnumerable GetEntityInvoices(String entityType, int entityid) -// { -// if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); - -// return ToListInvoiceBaseWrappers(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); -// } - -// /// -// /// Updates the status of invoices with the IDs specified in the request -// /// -// /// Invoice ID list -// /// Status -// /// Update invoice group status -// /// Invoices -// /// KeyValuePair of Invoices and InvoiceItems -// [Update(@"invoice/status/{status:[\w\d-]+}")] -// public KeyValuePair,IEnumerable> UpdateInvoiceBatchStatus( -// int[] invoiceids, -// InvoiceStatus status -// ) -// { -// if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); - -// var oldInvoices = DaoFactory.GetInvoiceDao().GetByID(invoiceids).Where(CRMSecurity.CanAccessTo).ToList(); - -// var updatedInvoices = DaoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status); - -// // detect what really changed -// var realUpdatedInvoices = updatedInvoices -// .Select(t => oldInvoices.FirstOrDefault(x => x.ID == t.ID && x.Status != t.Status)) -// .Where(inv => inv != null) -// .ToList(); - -// if (realUpdatedInvoices.Any()) -// { -// MessageService.Send( MessageAction.InvoicesUpdatedStatus, MessageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString()); -// } - -// var invoiceItemsUpdated = new List(); - -// if (status == InvoiceStatus.Sent || status == InvoiceStatus.Rejected) -// { -// var invoiceItemsAll = DaoFactory.GetInvoiceItemDao().GetAll(); -// var invoiceItemsWithTrackInventory = invoiceItemsAll.Where(item => item.TrackInventory).ToList(); - -// if (status == InvoiceStatus.Sent && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) -// { -// foreach (var inv in updatedInvoices) -// { -// if (inv.Status == InvoiceStatus.Sent) -// { -// //could be changed -// var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); -// if (oldInv != null && oldInv.Status == InvoiceStatus.Draft) -// { -// //was changed to Sent -// var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); - -// foreach (var line in invoiceLines) -// { -// var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); -// if (item != null) -// { -// item.StockQuantity -= line.Quantity; -// DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); -// var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); -// if (oldItem != null) -// { -// invoiceItemsUpdated.Remove(oldItem); -// } -// invoiceItemsUpdated.Add(item); -// } -// } -// } -// } -// } -// } - -// if (status == InvoiceStatus.Rejected && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) -// { -// foreach (var inv in updatedInvoices) -// { -// if (inv.Status == InvoiceStatus.Rejected) -// { -// //could be changed -// var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); -// if (oldInv != null && oldInv.Status == InvoiceStatus.Sent) -// { -// //was changed from Sent to Rejectes -// var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); - -// foreach (var line in invoiceLines) -// { -// var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); -// if (item != null) -// { -// item.StockQuantity += line.Quantity; -// DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); -// var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); -// if (oldItem != null) -// { -// invoiceItemsUpdated.Remove(oldItem); -// } -// invoiceItemsUpdated.Add(item); -// } -// } -// } -// } -// } -// } -// } - -// var listInvoiceBaseWrappers = ToListInvoiceBaseWrappers(updatedInvoices); - -// return new KeyValuePair,IEnumerable>(listInvoiceBaseWrappers,invoiceItemsUpdated.ConvertAll(i => InvoiceItemWrapperHelper.Get(i))); -// } - -// /// -// /// Delete the invoice with the ID specified in the request -// /// -// /// Invoice ID -// /// Delete invoice -// /// Invoices -// /// Invoice -// [Delete(@"invoice/{invoiceid:int}")] -// public InvoiceBaseWrapper DeleteInvoice(int invoiceid) -// { -// if (invoiceid <= 0) throw new ArgumentException(); - -// var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); -// if (invoice == null) throw new ItemNotFoundException(); - -// MessageService.Send( MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); - -// return InvoiceBaseWrapperHelper.Get(invoice); - -// } - -// /// -// /// Deletes the group of invoices with the IDs specified in the request -// /// -// /// Invoice ID list -// /// Delete invoice group -// /// Invoices -// /// Invoice list -// [Delete(@"invoice")] -// public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids) -// { -// if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); - -// var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); -// MessageService.Send( MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); - -// return ToListInvoiceBaseWrappers(invoices); -// } - -// /// -// /// Creates the invoice with the parameters (contactId, consigneeId, etc.) specified in the request -// /// -// /// Invoice number -// /// Invoice issue date -// /// Invoice template type -// /// Invoice contact ID -// /// Invoice consignee ID -// /// Invoice entity ID -// /// Invoice billing address ID -// /// Invoice delivery address ID -// /// Invoice due date -// /// Invoice language -// /// Invoice currency -// /// Invoice exchange rate -// /// Invoice purchase order number -// /// Invoice terms -// /// Invoice description -// /// Invoice lines list -// /// Create invoice -// /// Invoices -// /// Invoice -// /// -// /// -// /// -// [Create(@"invoice")] -// public InvoiceWrapper CreateInvoice( -// string number, -// ApiDateTime issueDate, -// int templateType, -// int contactId, -// int consigneeId, -// int entityId, -// int billingAddressID, -// int deliveryAddressID, -// ApiDateTime dueDate, -// string language, -// string currency, -// decimal exchangeRate, -// string purchaseOrderNumber, -// string terms, -// string description, -// IEnumerable invoiceLines -// ) -// { -// var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); -// if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); - -// var invoice = new Invoice -// { -// Status = InvoiceStatus.Draft, -// Number = number, -// IssueDate = issueDate, -// TemplateType = (InvoiceTemplateType)templateType, -// ContactID = contactId, -// ConsigneeID = consigneeId, -// EntityType = EntityType.Opportunity, -// EntityID = entityId, -// DueDate = dueDate, -// Language = language, -// Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null, -// ExchangeRate = exchangeRate, -// PurchaseOrderNumber = purchaseOrderNumber, -// Terms = terms, -// Description = description -// }; - -// CRMSecurity.DemandCreateOrUpdate(invoice); - -// if (billingAddressID > 0) -// { -// var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); -// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) -// throw new ArgumentException(); -// } - -// if (deliveryAddressID > 0) -// { -// var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); -// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) -// throw new ArgumentException(); -// } - - -// invoice.ID = DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); - -// CreateInvoiceLines(invoiceLinesList, invoice); - -// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - -// return InvoiceWrapperHelper.Get(invoice); -// } - - -// private bool IsLinesForInvoiceCorrect(List invoiceLines) -// { -// foreach (var line in invoiceLines) -// { -// if (line.InvoiceItemID <= 0 || -// line.Quantity < 0 || line.Price < 0 || -// line.Discount < 0 || line.Discount > 100 || -// line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0) -// return false; -// if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) -// return false; - -// if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) -// return false; - -// if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) -// return false; -// } -// return true; -// } - -// private List CreateInvoiceLines(List invoiceLines, Invoice invoice) -// { -// var result = new List(); -// for (var i = 0; i < invoiceLines.Count; i++) -// { -// var line = new InvoiceLine -// { -// ID = 0, -// InvoiceID = invoice.ID, -// InvoiceItemID = invoiceLines[i].InvoiceItemID, -// InvoiceTax1ID = invoiceLines[i].InvoiceTax1ID, -// InvoiceTax2ID = invoiceLines[i].InvoiceTax2ID, -// SortOrder = i, -// Description = invoiceLines[i].Description, -// Quantity = invoiceLines[i].Quantity, -// Price = invoiceLines[i].Price, -// Discount = Convert.ToInt32(invoiceLines[i].Discount) -// }; - -// line.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line); -// result.Add(line); -// } -// return result; -// } - -// /// -// /// Updates the selected invoice with the parameters (contactId, consigneeId, etc.) specified in the request -// /// -// /// Invoice ID -// /// Invoice issue date -// /// Invoice template type -// /// Invoice contact ID -// /// Invoice consignee ID -// /// Invoice entity ID -// /// Invoice billing address ID -// /// Invoice delivery address ID -// /// Invoice due date -// /// Invoice language -// /// Invoice currency -// /// Invoice exchange rate -// /// Invoice purchase order number -// /// Invoice terms -// /// Invoice description -// /// Invoice lines list -// /// Update invoice -// /// Invoices -// /// Invoice -// /// -// /// -// /// -// [Update(@"invoice/{id:int}")] -// public InvoiceWrapper UpdateInvoice( -// int id, -// ApiDateTime issueDate, -// int templateType, -// int contactId, -// int consigneeId, -// int entityId, -// int billingAddressID, -// int deliveryAddressID, -// ApiDateTime dueDate, -// string language, -// string currency, -// decimal exchangeRate, -// string purchaseOrderNumber, -// string terms, -// string description, -// IEnumerable invoiceLines) -// { - -// var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); -// if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); - -// var invoice = DaoFactory.GetInvoiceDao().GetByID(id); -// if (invoice == null || !CRMSecurity.CanEdit(invoice)) throw new ItemNotFoundException(); - -// invoice.IssueDate = issueDate; -// invoice.TemplateType = (InvoiceTemplateType)templateType; -// invoice.ContactID = contactId; -// invoice.ConsigneeID = consigneeId; -// invoice.EntityType = EntityType.Opportunity; -// invoice.EntityID = entityId; -// invoice.DueDate = dueDate; -// invoice.Language = language; -// invoice.Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper(): null;; -// invoice.ExchangeRate = exchangeRate; -// invoice.PurchaseOrderNumber = purchaseOrderNumber; -// invoice.Terms = terms; -// invoice.Description = description; -// invoice.JsonData = null; - -// CRMSecurity.DemandCreateOrUpdate(invoice); - -// if (billingAddressID > 0) -// { -// var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); -// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) -// throw new ArgumentException(); -// } - -// if (deliveryAddressID > 0) -// { -// var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); -// if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) -// throw new ArgumentException(); -// } - -// DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); - - -// DaoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID); -// CreateInvoiceLines(invoiceLinesList, invoice); - -// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - -// if (Global.CanDownloadInvoices) -// { -// // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); -// } - -// return InvoiceWrapperHelper.Get(invoice); -// } - -// /// -// /// Returns the pdf file associated with the invoice with the ID specified in the request -// /// -// /// Invoice ID -// /// Get invoice pdf file -// /// Invoices -// /// File -// [Read(@"invoice/{invoiceid:int}/pdf")] -// public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) -// { -// if (invoiceid <= 0) throw new ArgumentException(); - -// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); -// if (invoice == null) throw new ItemNotFoundException(); - -// if (!CRMSecurity.CanAccessTo(invoice)) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// return FileWrapperHelper.Get(Global.GetInvoicePdfExistingOrCreate(invoice, DaoFactory)); -// } - -//public ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory) -//{ -// var existingFile = invoice.GetInvoiceFile(factory); -// if (existingFile != null) -// { -// return existingFile; -// } -// else -// { -// var newFile = PdfCreator.CreateFile(invoice, factory); - -// invoice.FileID = Int32.Parse(newFile.ID.ToString()); - -// factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - -// factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); - -// return newFile; -// } -//} - - -// /// -// /// Returns information about the generation of the pdf file of the invoice -// /// -// /// Invoice ID -// /// Storage Url -// /// Revision ID -// /// Check invoice pdf file -// /// Invoices -// /// ConverterData -// [Create(@"invoice/converter/data")] -// public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, string revisionId) -// { -// if (invoiceId <= 0) throw new ArgumentException(); - -// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); -// if (invoice == null) throw new ItemNotFoundException(); - -// if (!CRMSecurity.CanAccessTo(invoice)) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// var converterData = new ConverterData -// { -// StorageUrl = storageUrl, -// RevisionId = revisionId, -// InvoiceId = invoiceId -// }; - -// var existingFile = invoice.GetInvoiceFile(DaoFactory); -// if (existingFile != null) -// { -// converterData.FileId = invoice.FileID; -// return converterData; -// } - -// if (string.IsNullOrEmpty(storageUrl) || string.IsNullOrEmpty(revisionId)) -// { -// return PdfCreator.StartCreationFileAsync(invoice); -// } -// else -// { -// var convertedFile = PdfCreator.GetConvertedFile(converterData, DaoFactory); -// if (convertedFile != null) -// { -// invoice.FileID = Int32.Parse(convertedFile.ID.ToString()); -// DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); -// DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); - -// converterData.FileId = invoice.FileID; -// return converterData; -// } -// else -// { -// return converterData; -// } -// } -// } - -// /// -// /// Returns the existence of the invoice with the Number specified in the request -// /// -// /// Invoice number -// /// Check invoice existence by number -// /// Invoices -// /// IsExist -// [Read(@"invoice/bynumber/exist")] -// public Boolean GetInvoiceByNumberExistence(string number) -// { -// if (String.IsNullOrEmpty(number)) throw new ArgumentException(); - -// return DaoFactory.GetInvoiceDao().IsExist(number); - -// } - -// /// -// /// Returns the detailed information about the invoice with the Number specified in the request -// /// -// /// Invoice number -// /// Get invoice by number -// /// Invoices -// /// Invoice -// [Read(@"invoice/bynumber")] -// public InvoiceWrapper GetInvoiceByNumber(string number) -// { -// if (String.IsNullOrEmpty(number)) throw new ArgumentException(); - -// var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number); -// if (invoice == null) throw new ItemNotFoundException(); - -// if (!CRMSecurity.CanAccessTo(invoice)) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// return InvoiceWrapperHelper.Get(invoice); -// } - -// /// -// /// Returns the list of invoice items matching the creteria specified in the request -// /// -// /// Status -// /// InventoryStock -// /// Get invoice item list -// /// Invoices -// /// InvoiceItem list -// [Read(@"invoiceitem/filter")] -// public IEnumerable GetInvoiceItems(int status, bool? inventoryStock) -// { -// IEnumerable result; - -// InvoiceItemSortedByType sortBy; - -// OrderBy invoiceOrderBy; - -// var searchString = ApiContext.FilterValue; - -// if (InvoiceItemSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) -// { -// invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); -// } -// else if (String.IsNullOrEmpty(ApiContext.SortBy)) -// { -// invoiceOrderBy = new OrderBy(InvoiceItemSortedByType.Name, true); -// } -// else -// { -// invoiceOrderBy = null; -// } - -// var fromIndex = (int)ApiContext.StartIndex; -// var count = (int)ApiContext.Count; - -// if (invoiceOrderBy != null) -// { -// result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( -// searchString, -// status, -// inventoryStock, -// fromIndex, count, -// invoiceOrderBy) -// .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); - -// ApiContext.SetDataPaginated(); -// ApiContext.SetDataFiltered(); -// ApiContext.SetDataSorted(); -// } -// else -// { -// result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( -// searchString, -// status, -// inventoryStock, -// 0, 0, -// null) -// .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); -// } - -// int totalCount; - -// if (result.Count() < count) -// { -// totalCount = fromIndex + result.Count(); -// } -// else -// { -// totalCount = DaoFactory.GetInvoiceItemDao().GetInvoiceItemsCount( -// searchString, -// status, -// inventoryStock); -// } - -// ApiContext.SetTotalCount(totalCount); - -// return result; -// } - -// /// -// /// Returns the detailed information about the invoice item with the ID specified in the request -// /// -// /// Invoice Item ID -// /// Get invoice item by ID -// /// Invoices -// /// Invoice Item -// [Read(@"invoiceitem/{invoiceitemid:int}")] -// public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) -// { -// if (invoiceitemid <= 0) throw new ArgumentException(); - -// var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); -// if (invoiceItem == null) throw new ItemNotFoundException(); - -// return InvoiceItemWrapperHelper.Get(invoiceItem); -// } - -// /// -// /// Creates the invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request -// /// -// /// Invoice ID -// /// Invoice item ID -// /// First invoice tax ID -// /// Second invoice tax ID -// /// Sort Order -// /// Description -// /// Quantity -// /// Price -// /// Discount -// /// Create invoice line -// /// Invoices -// /// InvoiceLine -// [Create(@"invoiceline")] -// public InvoiceLineWrapper CreateInvoiceLine( -// int invoiceId, -// int invoiceItemId, -// int invoiceTax1Id, -// int invoiceTax2Id, -// int sortOrder, -// string description, -// int quantity, -// decimal price, -// int discount -// ) -// { -// var invoiceLine = new InvoiceLine -// { -// InvoiceID = invoiceId, -// InvoiceItemID = invoiceItemId, -// InvoiceTax1ID = invoiceTax1Id, -// InvoiceTax2ID = invoiceTax2Id, -// SortOrder = sortOrder, -// Description = description, -// Quantity = quantity, -// Price = price, -// Discount = discount -// }; - -// if (invoiceId <= 0) -// throw new ArgumentException(); - -// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); - -// CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); - -// invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); - -// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); -// if (Global.CanDownloadInvoices) -// { -// // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); -// } - -// return InvoiceLineWrapperHelper.Get(invoiceLine); -// } - -// /// -// /// Updates the selected invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request -// /// -// /// Line ID -// /// Invoice ID -// /// Invoice item ID -// /// First invoice tax ID -// /// Second invoice tax ID -// /// Sort Order -// /// Description -// /// Quantity -// /// Price -// /// Discount -// /// Update invoice line -// /// Invoices -// /// InvoiceLine -// [Update(@"invoiceline/{id:int}")] -// public InvoiceLineWrapper UpdateInvoiceLine( -// int id, -// int invoiceId, -// int invoiceItemId, -// int invoiceTax1Id, -// int invoiceTax2Id, -// int sortOrder, -// string description, -// int quantity, -// decimal price, -// int discount -// ) -// { -// if (invoiceId <= 0) -// throw new ArgumentException(); - -// var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); -// if (invoiceLine == null || invoiceLine.InvoiceID != invoiceId) throw new ItemNotFoundException(); - - -// invoiceLine.InvoiceID = invoiceId; -// invoiceLine.InvoiceItemID = invoiceItemId; -// invoiceLine.InvoiceTax1ID = invoiceTax1Id; -// invoiceLine.InvoiceTax2ID = invoiceTax2Id; -// invoiceLine.SortOrder = sortOrder; -// invoiceLine.Description = description; -// invoiceLine.Quantity = quantity; -// invoiceLine.Price = price; -// invoiceLine.Discount = discount; - -// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); -// CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); - -// DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); - -// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - -// if (Global.CanDownloadInvoices) -// { -//// PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); -// } - -// return InvoiceLineWrapperHelper.Get(invoiceLine); -// } - -// /// -// /// Deletes the invoice line with the ID specified in the request -// /// -// /// Line ID -// /// Delete invoice line -// /// Invoices -// /// Line ID -// [Delete(@"invoiceline/{id:int}")] -// public int DeleteInvoiceLine(int id) -// { -// var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); -// if (invoiceLine == null) throw new ItemNotFoundException(); -// if (!DaoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line"); - -// var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID); -// if (invoice == null) throw new ItemNotFoundException(); -// if (!CRMSecurity.CanEdit(invoice)) throw CRMSecurity.CreateSecurityException(); - -// DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); - -// DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - -// if (Global.CanDownloadInvoices) -// { -// // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); -// } - -// return id; -// } - -// /// -// /// Creates the invoice item with the parameters (title, description, price, etc.) specified in the request -// /// -// /// Item title -// /// Item description -// /// Item price -// /// Item stock keeping unit -// /// Item quantity -// /// Item stock quantity -// /// Track inventory -// /// Item first invoice tax ID -// /// Item second invoice tax ID -// /// Create invoice item -// /// Invoices -// /// InvoiceItem -// [Create(@"invoiceitem")] -// public InvoiceItemWrapper CreateInvoiceItem( -// string title, -// string description, -// decimal price, -// string sku, -// int quantity, -// int stockQuantity, -// bool trackInventory, -// int invoiceTax1id, -// int invoiceTax2id) -// { -// if (!CRMSecurity.IsAdmin) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// if (String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); - -// var invoiceItem = new InvoiceItem -// { -// Title = title, -// Description = description, -// Price = price, -// StockKeepingUnit = sku, -// StockQuantity = stockQuantity, -// TrackInventory = trackInventory, -// InvoiceTax1ID = invoiceTax1id, -// InvoiceTax2ID = invoiceTax2id -// }; - -// invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); - -// MessageService.Send( MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - -// return InvoiceItemWrapperHelper.Get(invoiceItem); -// } - -// /// -// /// Updates the selected invoice item with the parameters (title, description, price, etc.) specified in the request -// /// -// /// Item ID -// /// Item title -// /// Item description -// /// Item price -// /// Item stock keeping unit -// /// Item quantity -// /// Item stock quantity -// /// Track inventory -// /// Item first invoice tax ID -// /// Item second invoice tax ID -// /// Update invoice item -// /// Invoices -// /// InvoiceItem -// [Update(@"invoiceitem/{id:int}")] -// public InvoiceItemWrapper UpdateInvoiceItem(int id, -// string title, -// string description, -// decimal price, -// string sku, -// int quantity, -// int stockQuantity, -// bool trackInventory, -// int invoiceTax1id, -// int invoiceTax2id) -// { -// if (!CRMSecurity.IsAdmin) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// if (id <= 0 || String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); - -// if (!DaoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException(); - -// var invoiceItem = new InvoiceItem -// { -// ID = id, -// Title = title, -// Description = description, -// Price = price, -// StockKeepingUnit = sku, -// StockQuantity = stockQuantity, -// TrackInventory = trackInventory, -// InvoiceTax1ID = invoiceTax1id, -// InvoiceTax2ID = invoiceTax2id -// }; - -// invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); -// MessageService.Send( MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - -// return InvoiceItemWrapperHelper.Get(invoiceItem); -// } - -// /// -// /// Deletes the invoice item with the ID specified in the request -// /// -// /// Item ID -// /// Delete invoice item -// /// Invoices -// /// InvoiceItem -// [Delete(@"invoiceitem/{id:int}")] -// public InvoiceItemWrapper DeleteInvoiceItem(int id) -// { -// if (!CRMSecurity.IsAdmin) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// if (id <= 0) throw new ArgumentException(); - -// var invoiceItem = DaoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id); -// if (invoiceItem == null) throw new ItemNotFoundException(); - -// MessageService.Send( MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - -// return InvoiceItemWrapperHelper.Get(invoiceItem); - -// } - -// /// -// /// Deletes the group of invoice items with the IDs specified in the request -// /// -// /// Item ID list -// /// Delete Invoice item group -// /// Invoices -// /// InvoiceItem list -// [Delete(@"invoiceitem")] -// public IEnumerable DeleteBatchItems(IEnumerable ids) -// { -// if (!CRMSecurity.IsAdmin) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// if (ids == null) throw new ArgumentException(); -// ids = ids.Distinct(); - -// var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); -// MessageService.Send( MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); - -// return items.ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); -// } - -// /// -// /// Returns the list of invoice taxes -// /// -// /// Get invoice taxes list -// /// Invoices -// /// InvoiceTax list -// [Read(@"invoice/tax")] -// public IEnumerable GetInvoiceTaxes() -// { -// return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxWrapperHelper.Get(x)); -// } - -// /// -// /// Creates the invoice tax with the parameters (name, description, rate) specified in the request -// /// -// /// Tax name -// /// Tax description -// /// Tax rate -// /// Create invoice tax -// /// Invoices -// /// InvoiceTax -// [Create(@"invoice/tax")] -// public InvoiceTaxWrapper CreateInvoiceTax( -// string name, -// string description, -// decimal rate) -// { -// if (!CRMSecurity.IsAdmin) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// if (String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); -// if (DaoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError); - -// var invoiceTax = new InvoiceTax -// { -// Name = name, -// Description = description, -// Rate = rate -// }; - -// invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); -// MessageService.Send( MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - -// return InvoiceTaxWrapperHelper.Get(invoiceTax); -// } - -// /// -// /// Updates the selected invoice tax with the parameters (name, description, rate) specified in the request -// /// -// /// Tax ID -// /// Tax name -// /// Tax description -// /// Tax rate -// /// Update invoice tax -// /// Invoices -// /// InvoiceTax -// [Update(@"invoice/tax/{id:int}")] -// public InvoiceTaxWrapper UpdateInvoiceTax( -// int id, -// string name, -// string description, -// decimal rate) -// { -// if (!CRMSecurity.IsAdmin) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// if (id <= 0 || String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); - -// if (!DaoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException(); - -// var invoiceTax = new InvoiceTax -// { -// ID = id, -// Name = name, -// Description = description, -// Rate = rate -// }; - -// invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); -// MessageService.Send( MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - -// return InvoiceTaxWrapperHelper.Get(invoiceTax); -// } - -// /// -// /// Delete the invoice tax with the ID specified in the request -// /// -// /// Tax ID -// /// Delete invoice tax -// /// Invoices -// /// InvoiceTax -// [Delete(@"invoice/tax/{id:int}")] -// public InvoiceTaxWrapper DeleteInvoiceTax(int id) -// { -// if (!CRMSecurity.IsAdmin) { -// throw CRMSecurity.CreateSecurityException(); -// } - -// if (id <= 0) throw new ArgumentException(); - -// var invoiceTax = DaoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id); -// if (invoiceTax == null) throw new ItemNotFoundException(); - -// MessageService.Send( MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - -// return InvoiceTaxWrapperHelper.Get(invoiceTax); -// } - -// /// -// /// Get default invoice settings -// /// -// /// Get default invoice settings -// /// Invoices -// /// InvoiceSetting -// [Read(@"invoice/settings")] -// public InvoiceSetting GetSettings() -// { -// return DaoFactory.GetInvoiceDao().GetSettings(); -// } - -// /// -// /// Save default invoice number -// /// -// /// Is autogenerated -// /// Prefix -// /// Number -// /// Save default invoice number -// /// Invoices -// /// InvoiceSetting -// [Update(@"invoice/settings/name")] -// public InvoiceSetting SaveNumberSettings(bool autogenerated, string prefix, string number) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// if (autogenerated && string.IsNullOrEmpty(number)) -// throw new ArgumentException(); - -// if (autogenerated && DaoFactory.GetInvoiceDao().IsExist(prefix + number)) -// throw new ArgumentException(); - -// var invoiceSetting = GetSettings(); - -// invoiceSetting.Autogenerated = autogenerated; -// invoiceSetting.Prefix = prefix; -// invoiceSetting.Number = number; - -// var settings = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); -// MessageService.Send( MessageAction.InvoiceNumberFormatUpdated); - -// return settings; -// } - -// /// -// /// Save default invoice terms -// /// -// /// Terms -// /// Save default invoice terms -// /// Invoices -// /// InvoiceSetting -// [Update(@"invoice/settings/terms")] -// public InvoiceSetting SaveTermsSettings(string terms) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var invoiceSetting = GetSettings(); - -// invoiceSetting.Terms = terms; - -// var result = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); -// MessageService.Send( MessageAction.InvoiceDefaultTermsUpdated); - -// return result; -// } - -// /// false -// [Update(@"invoice/{invoiceid:int}/creationdate")] -// public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate) -// { -// var dao = DaoFactory.GetInvoiceDao(); -// var invoice = dao.GetByID(invoiceid); - -// if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) -// throw new ItemNotFoundException(); - -// dao.SetInvoiceCreationDate(invoiceid, creationDate); -// } - -// /// false -// [Update(@"invoice/{invoiceid:int}/lastmodifeddate")] -// public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate) -// { -// var dao = DaoFactory.GetInvoiceDao(); -// var invoice = dao.GetByID(invoiceid); - -// if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) -// throw new ItemNotFoundException(); +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.Api.CRM.Wrappers; +using ASC.Api.Documents; +using ASC.Common.Web; +using ASC.Core; +using ASC.CRM.Classes; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Model; +using ASC.CRM.Resources; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; + +using Microsoft.AspNetCore.Mvc; + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.Api.CRM +{ + public partial class CRMController + { + /// + /// Returns the detailed information about the invoice with the ID specified in the request + /// + /// Invoice ID + /// Get invoice by ID + /// Invoices + /// Invoice + [Read(@"invoice/{invoiceid:int}")] + public InvoiceWrapper GetInvoiceByID(int invoiceid) + { + if (invoiceid <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) + { + throw CRMSecurity.CreateSecurityException(); + } + + return InvoiceWrapperHelper.Get(invoice); + } + + /// + /// Returns the detailed information about the invoice sample + /// + /// Get invoice sample + /// Invoices + /// Invoice + [Read(@"invoice/sample")] + public InvoiceWrapper GetInvoiceSample() + { + var sample = InvoiceWrapper.GetSample(); + sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); + sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; + + sample.IssueDate = ApiDateTimeHelper.Get(DateTime.UtcNow); + sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); + sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow); + + sample.Currency = CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency); + + sample.InvoiceLines.First().Quantity = 1; + + return sample; + } + + /// + /// Returns the json data of the invoice with the ID specified in the request + /// + /// Invoice ID + /// Get invoice json data + /// Invoices + /// Json Data + [Read(@"invoice/jsondata/{invoiceid:int}")] + public string GetInvoiceJsonData(int invoiceid) + { + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) + { + throw CRMSecurity.CreateSecurityException(); + } + + return invoice.JsonData; + } + + /// + /// Returns the list of invoices matching the creteria specified in the request + /// + /// Invoice status + /// Invoice issue date from + /// Invoice issue date to + /// Invoice due date from + /// Invoice due date to + /// Invoice entity type + /// Invoice entity ID + /// Invoice currency + /// Get invoice list + /// Invoices + /// Invoice list + [Read(@"invoice/filter")] + public IEnumerable GetInvoices( + InvoiceStatus? status, + ApiDateTime issueDateFrom, + ApiDateTime issueDateTo, + ApiDateTime dueDateFrom, + ApiDateTime dueDateTo, + String entityType, + int entityid, + String currency + ) + { + if (!String.IsNullOrEmpty(entityType) && !( + String.Compare(entityType, "contact", true) == 0 || + String.Compare(entityType, "opportunity", true) == 0 || + String.Compare(entityType, "case", true) == 0)) + throw new ArgumentException(); + + IEnumerable result; + + InvoiceSortedByType sortBy; + + OrderBy invoiceOrderBy; + + var searchString = ApiContext.FilterValue; + + if (InvoiceSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) + { + invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (String.IsNullOrEmpty(ApiContext.SortBy)) + { + invoiceOrderBy = new OrderBy(InvoiceSortedByType.Number, true); + } + else + { + invoiceOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (invoiceOrderBy != null) + { + result = ToListInvoiceBaseWrappers( + DaoFactory.GetInvoiceDao().GetInvoices( + searchString, + status, + issueDateFrom, issueDateTo, + dueDateFrom, dueDateTo, + ToEntityType(entityType), entityid, + currency, + fromIndex, count, + invoiceOrderBy)); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = ToListInvoiceBaseWrappers( + DaoFactory.GetInvoiceDao().GetInvoices( + searchString, + status, + issueDateFrom, issueDateTo, + dueDateFrom, dueDateTo, + ToEntityType(entityType), entityid, + currency, + 0, + 0, + null)); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetInvoiceDao().GetInvoicesCount( + searchString, + status, + issueDateFrom, issueDateTo, + dueDateFrom, dueDateTo, + ToEntityType(entityType), entityid, + currency); + } + + ApiContext.SetTotalCount(totalCount); + + return result; + } + + /// + /// Returns the list of all invoices associated with the entity with the ID and type specified in the request + /// + /// Invoice entity type + /// Invoice entity ID + /// Get entity invoices + /// Invoices + /// Invoice list + [Read(@"{entityType:regex(contact|person|company|opportunity)}/invoicelist/{entityid:int}")] + public IEnumerable GetEntityInvoices(String entityType, int entityid) + { + if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); + + return ToListInvoiceBaseWrappers(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); + } + + /// + /// Updates the status of invoices with the IDs specified in the request + /// + /// Invoice ID list + /// Status + /// Update invoice group status + /// Invoices + /// KeyValuePair of Invoices and InvoiceItems + [Update(@"invoice/status/{status:int}")] + public KeyValuePair, IEnumerable> UpdateInvoiceBatchStatus( + int[] invoiceids, + InvoiceStatus status + ) + { + if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); + + var oldInvoices = DaoFactory.GetInvoiceDao().GetByID(invoiceids).Where(CRMSecurity.CanAccessTo).ToList(); + + var updatedInvoices = DaoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status); + + // detect what really changed + var realUpdatedInvoices = updatedInvoices + .Select(t => oldInvoices.FirstOrDefault(x => x.ID == t.ID && x.Status != t.Status)) + .Where(inv => inv != null) + .ToList(); + + if (realUpdatedInvoices.Any()) + { + MessageService.Send(MessageAction.InvoicesUpdatedStatus, MessageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString()); + } + + var invoiceItemsUpdated = new List(); + + if (status == InvoiceStatus.Sent || status == InvoiceStatus.Rejected) + { + var invoiceItemsAll = DaoFactory.GetInvoiceItemDao().GetAll(); + var invoiceItemsWithTrackInventory = invoiceItemsAll.Where(item => item.TrackInventory).ToList(); + + if (status == InvoiceStatus.Sent && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) + { + foreach (var inv in updatedInvoices) + { + if (inv.Status == InvoiceStatus.Sent) + { + //could be changed + var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); + if (oldInv != null && oldInv.Status == InvoiceStatus.Draft) + { + //was changed to Sent + var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + + foreach (var line in invoiceLines) + { + var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); + if (item != null) + { + item.StockQuantity -= line.Quantity; + DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); + var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); + if (oldItem != null) + { + invoiceItemsUpdated.Remove(oldItem); + } + invoiceItemsUpdated.Add(item); + } + } + } + } + } + } + + if (status == InvoiceStatus.Rejected && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) + { + foreach (var inv in updatedInvoices) + { + if (inv.Status == InvoiceStatus.Rejected) + { + //could be changed + var oldInv = oldInvoices.FirstOrDefault(i => i.ID == inv.ID); + if (oldInv != null && oldInv.Status == InvoiceStatus.Sent) + { + //was changed from Sent to Rejectes + var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + + foreach (var line in invoiceLines) + { + var item = invoiceItemsWithTrackInventory.FirstOrDefault(ii => ii.ID == line.InvoiceItemID); + if (item != null) + { + item.StockQuantity += line.Quantity; + DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); + var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); + if (oldItem != null) + { + invoiceItemsUpdated.Remove(oldItem); + } + invoiceItemsUpdated.Add(item); + } + } + } + } + } + } + } + + var listInvoiceBaseWrappers = ToListInvoiceBaseWrappers(updatedInvoices); + + return new KeyValuePair, IEnumerable>(listInvoiceBaseWrappers, invoiceItemsUpdated.ConvertAll(i => InvoiceItemWrapperHelper.Get(i))); + } + + /// + /// Delete the invoice with the ID specified in the request + /// + /// Invoice ID + /// Delete invoice + /// Invoices + /// Invoice + [Delete(@"invoice/{invoiceid:int}")] + public InvoiceBaseWrapper DeleteInvoice(int invoiceid) + { + if (invoiceid <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + MessageService.Send(MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); + + return InvoiceBaseWrapperHelper.Get(invoice); + + } + + /// + /// Deletes the group of invoices with the IDs specified in the request + /// + /// Invoice ID list + /// Delete invoice group + /// Invoices + /// Invoice list + [Delete(@"invoice")] + public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids) + { + if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); + + var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); + MessageService.Send(MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); + + return ToListInvoiceBaseWrappers(invoices); + } + + /// + /// Creates the invoice with the parameters (contactId, consigneeId, etc.) specified in the request + /// + /// Invoice number + /// Invoice issue date + /// Invoice template type + /// Invoice contact ID + /// Invoice consignee ID + /// Invoice entity ID + /// Invoice billing address ID + /// Invoice delivery address ID + /// Invoice due date + /// Invoice language + /// Invoice currency + /// Invoice exchange rate + /// Invoice purchase order number + /// Invoice terms + /// Invoice description + /// Invoice lines list + /// Create invoice + /// Invoices + /// Invoice + /// + /// + /// + [Create(@"invoice")] + public InvoiceWrapper CreateInvoice( + CreateOrUpdateInvoiceInDto inDto + ) + { + string number = inDto.Number; + + ApiDateTime issueDate = inDto.IssueDate; + int templateType = inDto.TemplateType; + int contactId = inDto.ContactId; + int consigneeId = inDto.ConsigneeId; + int entityId = inDto.EntityId; + int billingAddressID = inDto.BillingAddressID; + int deliveryAddressID = inDto.DeliveryAddressID; + ApiDateTime dueDate = inDto.DueDate; + string language = inDto.Language; + string currency = inDto.Currency; + decimal exchangeRate = inDto.ExchangeRate; + string purchaseOrderNumber = inDto.PurchaseOrderNumber; + string terms = inDto.Terms; + string description = inDto.Description; + IEnumerable invoiceLines = inDto.InvoiceLines; + + var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); + if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); + + var invoice = new Invoice + { + Status = InvoiceStatus.Draft, + Number = number, + IssueDate = issueDate, + TemplateType = (InvoiceTemplateType)templateType, + ContactID = contactId, + ConsigneeID = consigneeId, + EntityType = EntityType.Opportunity, + EntityID = entityId, + DueDate = dueDate, + Language = language, + Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper() : null, + ExchangeRate = exchangeRate, + PurchaseOrderNumber = purchaseOrderNumber, + Terms = terms, + Description = description + }; + + CRMSecurity.DemandCreateOrUpdate(invoice); + + if (billingAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) + throw new ArgumentException(); + } + + if (deliveryAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) + throw new ArgumentException(); + } + + + invoice.ID = DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + + CreateInvoiceLines(invoiceLinesList, invoice); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + + return InvoiceWrapperHelper.Get(invoice); + } + + + private bool IsLinesForInvoiceCorrect(List invoiceLines) + { + foreach (var line in invoiceLines) + { + if (line.InvoiceItemID <= 0 || + line.Quantity < 0 || line.Price < 0 || + line.Discount < 0 || line.Discount > 100 || + line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0) + return false; + if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) + return false; + + if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) + return false; + + if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) + return false; + } + return true; + } + + private List CreateInvoiceLines(List invoiceLines, Invoice invoice) + { + var result = new List(); + for (var i = 0; i < invoiceLines.Count; i++) + { + var line = new InvoiceLine + { + ID = 0, + InvoiceID = invoice.ID, + InvoiceItemID = invoiceLines[i].InvoiceItemID, + InvoiceTax1ID = invoiceLines[i].InvoiceTax1ID, + InvoiceTax2ID = invoiceLines[i].InvoiceTax2ID, + SortOrder = i, + Description = invoiceLines[i].Description, + Quantity = invoiceLines[i].Quantity, + Price = invoiceLines[i].Price, + Discount = Convert.ToInt32(invoiceLines[i].Discount) + }; + + line.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line); + result.Add(line); + } + return result; + } + + /// + /// Updates the selected invoice with the parameters (contactId, consigneeId, etc.) specified in the request + /// + /// Invoice ID + /// Invoice issue date + /// Invoice template type + /// Invoice contact ID + /// Invoice consignee ID + /// Invoice entity ID + /// Invoice billing address ID + /// Invoice delivery address ID + /// Invoice due date + /// Invoice language + /// Invoice currency + /// Invoice exchange rate + /// Invoice purchase order number + /// Invoice terms + /// Invoice description + /// Invoice lines list + /// Update invoice + /// Invoices + /// Invoice + /// + /// + /// + [Update(@"invoice/{id:int}")] + public InvoiceWrapper UpdateInvoice( + int id, + CreateOrUpdateInvoiceInDto inDto) + + { + ApiDateTime issueDate = inDto.IssueDate; + int templateType = inDto.TemplateType; + int contactId = inDto.ContactId; + int consigneeId = inDto.ConsigneeId; + int entityId = inDto.EntityId; + int billingAddressID = inDto.BillingAddressID; + int deliveryAddressID = inDto.DeliveryAddressID; + ApiDateTime dueDate = inDto.DueDate; + string language = inDto.Language; + string currency = inDto.Currency; + decimal exchangeRate = inDto.ExchangeRate; + string purchaseOrderNumber = inDto.PurchaseOrderNumber; + string terms = inDto.Terms; + string description = inDto.Description; + IEnumerable invoiceLines = inDto.InvoiceLines; + + var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); + if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(id); + if (invoice == null || !CRMSecurity.CanEdit(invoice)) throw new ItemNotFoundException(); + + invoice.IssueDate = issueDate; + invoice.TemplateType = (InvoiceTemplateType)templateType; + invoice.ContactID = contactId; + invoice.ConsigneeID = consigneeId; + invoice.EntityType = EntityType.Opportunity; + invoice.EntityID = entityId; + invoice.DueDate = dueDate; + invoice.Language = language; + invoice.Currency = !String.IsNullOrEmpty(currency) ? currency.ToUpper() : null; ; + invoice.ExchangeRate = exchangeRate; + invoice.PurchaseOrderNumber = purchaseOrderNumber; + invoice.Terms = terms; + invoice.Description = description; + invoice.JsonData = null; + + CRMSecurity.DemandCreateOrUpdate(invoice); + + if (billingAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) + throw new ArgumentException(); + } + + if (deliveryAddressID > 0) + { + var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); + if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) + throw new ArgumentException(); + } + + DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + + + DaoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID); + CreateInvoiceLines(invoiceLinesList, invoice); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + + if (Global.CanDownloadInvoices) + { + // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return InvoiceWrapperHelper.Get(invoice); + } + + /// + /// Returns the pdf file associated with the invoice with the ID specified in the request + /// + /// Invoice ID + /// Get invoice pdf file + /// Invoices + /// File + [Read(@"invoice/{invoiceid:int}/pdf")] + public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) + { + if (invoiceid <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) + { + throw CRMSecurity.CreateSecurityException(); + } + + return FileWrapperHelper.Get(GetInvoicePdfExistingOrCreate(invoice)); + } + + private ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice) + { + var existingFile = invoice.GetInvoiceFile(DaoFactory); + + if (existingFile != null) + { + return existingFile; + } + else + { + var newFile = PdfCreator.CreateFile(invoice, DaoFactory); + + invoice.FileID = Int32.Parse(newFile.ID.ToString()); + + DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + + DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + + return newFile; + } + } + + + /// + /// Returns information about the generation of the pdf file of the invoice + /// + /// Invoice ID + /// Storage Url + /// Revision ID + /// Check invoice pdf file + /// Invoices + /// ConverterData + [Create(@"invoice/converter/data")] + public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, string revisionId) + { + if (invoiceId <= 0) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) + { + throw CRMSecurity.CreateSecurityException(); + } + + var converterData = new ConverterData + { + StorageUrl = storageUrl, + RevisionId = revisionId, + InvoiceId = invoiceId + }; + + var existingFile = invoice.GetInvoiceFile(DaoFactory); + if (existingFile != null) + { + converterData.FileId = invoice.FileID; + return converterData; + } + + if (string.IsNullOrEmpty(storageUrl) || string.IsNullOrEmpty(revisionId)) + { + return PdfCreator.StartCreationFileAsync(invoice); + } + else + { + var convertedFile = PdfCreator.GetConvertedFile(converterData, DaoFactory); + if (convertedFile != null) + { + invoice.FileID = Int32.Parse(convertedFile.ID.ToString()); + DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + + converterData.FileId = invoice.FileID; + return converterData; + } + else + { + return converterData; + } + } + } + + /// + /// Returns the existence of the invoice with the Number specified in the request + /// + /// Invoice number + /// Check invoice existence by number + /// Invoices + /// IsExist + [Read(@"invoice/bynumber/exist")] + public Boolean GetInvoiceByNumberExistence(string number) + { + if (String.IsNullOrEmpty(number)) throw new ArgumentException(); + + return DaoFactory.GetInvoiceDao().IsExist(number); + + } + + /// + /// Returns the detailed information about the invoice with the Number specified in the request + /// + /// Invoice number + /// Get invoice by number + /// Invoices + /// Invoice + [Read(@"invoice/bynumber")] + public InvoiceWrapper GetInvoiceByNumber(string number) + { + if (String.IsNullOrEmpty(number)) throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number); + if (invoice == null) throw new ItemNotFoundException(); + + if (!CRMSecurity.CanAccessTo(invoice)) + { + throw CRMSecurity.CreateSecurityException(); + } + + return InvoiceWrapperHelper.Get(invoice); + } + + /// + /// Returns the list of invoice items matching the creteria specified in the request + /// + /// Status + /// InventoryStock + /// Get invoice item list + /// Invoices + /// InvoiceItem list + [Read(@"invoiceitem/filter")] + public IEnumerable GetInvoiceItems(int status, bool? inventoryStock) + { + IEnumerable result; + + InvoiceItemSortedByType sortBy; + + OrderBy invoiceOrderBy; + + var searchString = ApiContext.FilterValue; + + if (InvoiceItemSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) + { + invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + } + else if (String.IsNullOrEmpty(ApiContext.SortBy)) + { + invoiceOrderBy = new OrderBy(InvoiceItemSortedByType.Name, true); + } + else + { + invoiceOrderBy = null; + } + + var fromIndex = (int)ApiContext.StartIndex; + var count = (int)ApiContext.Count; + + if (invoiceOrderBy != null) + { + result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( + searchString, + status, + inventoryStock, + fromIndex, count, + invoiceOrderBy) + .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + } + else + { + result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( + searchString, + status, + inventoryStock, + 0, 0, + null) + .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); + } + + int totalCount; + + if (result.Count() < count) + { + totalCount = fromIndex + result.Count(); + } + else + { + totalCount = DaoFactory.GetInvoiceItemDao().GetInvoiceItemsCount( + searchString, + status, + inventoryStock); + } + + ApiContext.SetTotalCount(totalCount); + + return result; + } + + /// + /// Returns the detailed information about the invoice item with the ID specified in the request + /// + /// Invoice Item ID + /// Get invoice item by ID + /// Invoices + /// Invoice Item + [Read(@"invoiceitem/{invoiceitemid:int}")] + public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) + { + if (invoiceitemid <= 0) throw new ArgumentException(); + + var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); + if (invoiceItem == null) throw new ItemNotFoundException(); + + return InvoiceItemWrapperHelper.Get(invoiceItem); + } + + /// + /// Creates the invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request + /// + /// Invoice ID + /// Invoice item ID + /// First invoice tax ID + /// Second invoice tax ID + /// Sort Order + /// Description + /// Quantity + /// Price + /// Discount + /// Create invoice line + /// Invoices + /// InvoiceLine + [Create(@"invoiceline")] + public InvoiceLineWrapper CreateInvoiceLine( + CreateOrUpdateInvoiceLineInDto inDto + ) + { + int invoiceId = inDto.InvoiceId; + int invoiceItemId = inDto.InvoiceItemId; + int invoiceTax1Id = inDto.InvoiceTax1Id; + int invoiceTax2Id = inDto.InvoiceTax2Id; + int sortOrder = inDto.SortOrder; + string description = inDto.Description; + int quantity = inDto.Quantity; + decimal price = inDto.Price; + int discount = inDto.Discount; + + var invoiceLine = new InvoiceLine + { + InvoiceID = invoiceId, + InvoiceItemID = invoiceItemId, + InvoiceTax1ID = invoiceTax1Id, + InvoiceTax2ID = invoiceTax2Id, + SortOrder = sortOrder, + Description = description, + Quantity = quantity, + Price = price, + Discount = discount + }; + + if (invoiceId <= 0) + throw new ArgumentException(); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + + CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + + invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + if (Global.CanDownloadInvoices) + { + // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return InvoiceLineWrapperHelper.Get(invoiceLine); + } + + /// + /// Updates the selected invoice line with the parameters (invoiceId, invoiceItemId, etc.) specified in the request + /// + /// Line ID + /// Invoice ID + /// Invoice item ID + /// First invoice tax ID + /// Second invoice tax ID + /// Sort Order + /// Description + /// Quantity + /// Price + /// Discount + /// Update invoice line + /// Invoices + /// InvoiceLine + [Update(@"invoiceline/{id:int}")] + public InvoiceLineWrapper UpdateInvoiceLine( + int id, + CreateOrUpdateInvoiceLineInDto inDto + ) + { + int invoiceId = inDto.InvoiceId; + int invoiceItemId = inDto.InvoiceItemId; + int invoiceTax1Id = inDto.InvoiceTax1Id; + int invoiceTax2Id = inDto.InvoiceTax2Id; + int sortOrder = inDto.SortOrder; + string description = inDto.Description; + int quantity = inDto.Quantity; + decimal price = inDto.Price; + int discount = inDto.Discount; + + if (invoiceId <= 0) + throw new ArgumentException(); + + var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); + if (invoiceLine == null || invoiceLine.InvoiceID != invoiceId) throw new ItemNotFoundException(); + + + invoiceLine.InvoiceID = invoiceId; + invoiceLine.InvoiceItemID = invoiceItemId; + invoiceLine.InvoiceTax1ID = invoiceTax1Id; + invoiceLine.InvoiceTax2ID = invoiceTax2Id; + invoiceLine.SortOrder = sortOrder; + invoiceLine.Description = description; + invoiceLine.Quantity = quantity; + invoiceLine.Price = price; + invoiceLine.Discount = discount; + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + + DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + + if (Global.CanDownloadInvoices) + { + // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return InvoiceLineWrapperHelper.Get(invoiceLine); + } + + /// + /// Deletes the invoice line with the ID specified in the request + /// + /// Line ID + /// Delete invoice line + /// Invoices + /// Line ID + [Delete(@"invoiceline/{id:int}")] + public int DeleteInvoiceLine(int id) + { + var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); + if (invoiceLine == null) throw new ItemNotFoundException(); + if (!DaoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line"); + + var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID); + if (invoice == null) throw new ItemNotFoundException(); + if (!CRMSecurity.CanEdit(invoice)) throw CRMSecurity.CreateSecurityException(); + + DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); + + DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + + if (Global.CanDownloadInvoices) + { + // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + } + + return id; + } + + /// + /// Creates the invoice item with the parameters (title, description, price, etc.) specified in the request + /// + /// Item title + /// Item description + /// Item price + /// Item stock keeping unit + /// Item quantity + /// Item stock quantity + /// Track inventory + /// Item first invoice tax ID + /// Item second invoice tax ID + /// Create invoice item + /// Invoices + /// InvoiceItem + [Create(@"invoiceitem")] + public InvoiceItemWrapper CreateInvoiceItem( + CreateOrUpdateInvoiceItemInDto inDto + ) + { + string title = inDto.Title; + string description = inDto.Description; + decimal price = inDto.Price; + string sku = inDto.Sku; + int quantity = inDto.Quantity; + int stockQuantity = inDto.StockQuantity; + bool trackInventory = inDto.TrackInventory; + int invoiceTax1id = inDto.InvoiceTax1id; + int invoiceTax2id = inDto.InvoiceTax2id; + + if (!CRMSecurity.IsAdmin) + { + throw CRMSecurity.CreateSecurityException(); + } + + if (String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); + + var invoiceItem = new InvoiceItem + { + Title = title, + Description = description, + Price = price, + StockKeepingUnit = sku, + StockQuantity = stockQuantity, + TrackInventory = trackInventory, + InvoiceTax1ID = invoiceTax1id, + InvoiceTax2ID = invoiceTax2id + }; + + invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + + MessageService.Send(MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + + return InvoiceItemWrapperHelper.Get(invoiceItem); + } + + /// + /// Updates the selected invoice item with the parameters (title, description, price, etc.) specified in the request + /// + /// Item ID + /// Item title + /// Item description + /// Item price + /// Item stock keeping unit + /// Item quantity + /// Item stock quantity + /// Track inventory + /// Item first invoice tax ID + /// Item second invoice tax ID + /// Update invoice item + /// Invoices + /// InvoiceItem + [Update(@"invoiceitem/{id:int}")] + public InvoiceItemWrapper UpdateInvoiceItem(int id, + CreateOrUpdateInvoiceItemInDto inDto + ) + { + string title = inDto.Title; + string description = inDto.Description; + decimal price = inDto.Price; + string sku = inDto.Sku; + int quantity = inDto.Quantity; + int stockQuantity = inDto.StockQuantity; + bool trackInventory = inDto.TrackInventory; + int invoiceTax1id = inDto.InvoiceTax1id; + int invoiceTax2id = inDto.InvoiceTax2id; + + if (!CRMSecurity.IsAdmin) + { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0 || String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); + + if (!DaoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException(); + + var invoiceItem = new InvoiceItem + { + ID = id, + Title = title, + Description = description, + Price = price, + StockKeepingUnit = sku, + StockQuantity = stockQuantity, + TrackInventory = trackInventory, + InvoiceTax1ID = invoiceTax1id, + InvoiceTax2ID = invoiceTax2id + }; + + invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + MessageService.Send(MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + + return InvoiceItemWrapperHelper.Get(invoiceItem); + } + + /// + /// Deletes the invoice item with the ID specified in the request + /// + /// Item ID + /// Delete invoice item + /// Invoices + /// InvoiceItem + [Delete(@"invoiceitem/{id:int}")] + public InvoiceItemWrapper DeleteInvoiceItem(int id) + { + if (!CRMSecurity.IsAdmin) + { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0) throw new ArgumentException(); + + var invoiceItem = DaoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id); + if (invoiceItem == null) throw new ItemNotFoundException(); + + MessageService.Send(MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + + return InvoiceItemWrapperHelper.Get(invoiceItem); + + } + + /// + /// Deletes the group of invoice items with the IDs specified in the request + /// + /// Item ID list + /// Delete Invoice item group + /// Invoices + /// InvoiceItem list + [Delete(@"invoiceitem")] + public IEnumerable DeleteBatchItems(IEnumerable ids) + { + if (!CRMSecurity.IsAdmin) + { + throw CRMSecurity.CreateSecurityException(); + } + + if (ids == null) throw new ArgumentException(); + ids = ids.Distinct(); + + var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); + MessageService.Send(MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); + + return items.ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); + } + + /// + /// Returns the list of invoice taxes + /// + /// Get invoice taxes list + /// Invoices + /// InvoiceTax list + [Read(@"invoice/tax")] + public IEnumerable GetInvoiceTaxes() + { + return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxWrapperHelper.Get(x)); + } + + /// + /// Creates the invoice tax with the parameters (name, description, rate) specified in the request + /// + /// Tax name + /// Tax description + /// Tax rate + /// Create invoice tax + /// Invoices + /// InvoiceTax + [Create(@"invoice/tax")] + public InvoiceTaxWrapper CreateInvoiceTax( + [FromBody] CreateOrUpdateInvoiceTax inDto) + { + string name = inDto.Name; + string description = inDto.Description; + decimal rate = inDto.Rate; + + if (!CRMSecurity.IsAdmin) + { + throw CRMSecurity.CreateSecurityException(); + } + + if (String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); + if (DaoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError); + + var invoiceTax = new InvoiceTax + { + Name = name, + Description = description, + Rate = rate + }; + + invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); + MessageService.Send(MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + + return InvoiceTaxWrapperHelper.Get(invoiceTax); + } + + /// + /// Updates the selected invoice tax with the parameters (name, description, rate) specified in the request + /// + /// Tax ID + /// Tax name + /// Tax description + /// Tax rate + /// Update invoice tax + /// Invoices + /// InvoiceTax + [Update(@"invoice/tax/{id:int}")] + public InvoiceTaxWrapper UpdateInvoiceTax( + int id, + CreateOrUpdateInvoiceTax inDto) + { + string name = inDto.Name; + string description = inDto.Description; + decimal rate = inDto.Rate; + + if (!CRMSecurity.IsAdmin) + { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0 || String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); + + if (!DaoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException(); + + var invoiceTax = new InvoiceTax + { + ID = id, + Name = name, + Description = description, + Rate = rate + }; + + invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); + MessageService.Send(MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + + return InvoiceTaxWrapperHelper.Get(invoiceTax); + } + + /// + /// Delete the invoice tax with the ID specified in the request + /// + /// Tax ID + /// Delete invoice tax + /// Invoices + /// InvoiceTax + [Delete(@"invoice/tax/{id:int}")] + public InvoiceTaxWrapper DeleteInvoiceTax(int id) + { + if (!CRMSecurity.IsAdmin) + { + throw CRMSecurity.CreateSecurityException(); + } + + if (id <= 0) throw new ArgumentException(); + + var invoiceTax = DaoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id); + if (invoiceTax == null) throw new ItemNotFoundException(); + + MessageService.Send(MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + + return InvoiceTaxWrapperHelper.Get(invoiceTax); + } + + /// + /// Get default invoice settings + /// + /// Get default invoice settings + /// Invoices + /// InvoiceSetting + [Read(@"invoice/settings")] + public InvoiceSetting GetSettings() + { + return DaoFactory.GetInvoiceDao().GetSettings(); + } + + /// + /// Save default invoice number + /// + /// Is autogenerated + /// Prefix + /// Number + /// Save default invoice number + /// Invoices + /// InvoiceSetting + [Update(@"invoice/settings/name")] + public InvoiceSetting SaveNumberSettings( + SaveNumberSettingsInDto inDto + ) + { + var autogenerated = inDto.AutoGenerated; + var number = inDto.Number; + var prefix = inDto.Prefix; + + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + if (autogenerated && string.IsNullOrEmpty(number)) + throw new ArgumentException(); + + if (autogenerated && DaoFactory.GetInvoiceDao().IsExist(prefix + number)) + throw new ArgumentException(); + + var invoiceSetting = GetSettings(); + + invoiceSetting.Autogenerated = autogenerated; + invoiceSetting.Prefix = prefix; + invoiceSetting.Number = number; + + var settings = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); + MessageService.Send(MessageAction.InvoiceNumberFormatUpdated); + + return settings; + } + + /// + /// Save default invoice terms + /// + /// Terms + /// Save default invoice terms + /// Invoices + /// InvoiceSetting + [Update(@"invoice/settings/terms")] + public InvoiceSetting SaveTermsSettings(string terms) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var invoiceSetting = GetSettings(); + + invoiceSetting.Terms = terms; + + var result = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); + MessageService.Send(MessageAction.InvoiceDefaultTermsUpdated); + + return result; + } + + /// false + [Update(@"invoice/{invoiceid:int}/creationdate")] + public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate) + { + var dao = DaoFactory.GetInvoiceDao(); + var invoice = dao.GetByID(invoiceid); + + if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) + throw new ItemNotFoundException(); + + dao.SetInvoiceCreationDate(invoiceid, creationDate); + } + + /// false + [Update(@"invoice/{invoiceid:int}/lastmodifeddate")] + public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate) + { + var dao = DaoFactory.GetInvoiceDao(); + var invoice = dao.GetByID(invoiceid); + + if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) + throw new ItemNotFoundException(); + + dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); + } + + private IEnumerable ToListInvoiceBaseWrappers(ICollection items) + { + if (items == null || items.Count == 0) return new List(); + + var result = new List(); + + + var contactIDs = items.Select(item => item.ContactID); + contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID)); + + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) + .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); -// dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); -// } -// private IEnumerable ToListInvoiceBaseWrappers(ICollection items) -// { -// if (items == null || items.Count == 0) return new List(); - -// var result = new List(); - - -// var contactIDs = items.Select(item => item.ContactID); -// contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID)); - -// var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) -// .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); - - -// foreach (var invoice in items) -// { -// var invoiceWrapper = InvoiceBaseWrapperHelper.Get(invoice); + foreach (var invoice in items) + { + var invoiceWrapper = InvoiceBaseWrapperHelper.Get(invoice); -// if (contacts.ContainsKey(invoice.ContactID)) -// { -// invoiceWrapper.Contact = contacts[invoice.ContactID]; -// } + if (contacts.ContainsKey(invoice.ContactID)) + { + invoiceWrapper.Contact = contacts[invoice.ContactID]; + } -// if (contacts.ContainsKey(invoice.ConsigneeID)) -// { -// invoiceWrapper.Consignee = contacts[invoice.ContactID]; -// } + if (contacts.ContainsKey(invoice.ConsigneeID)) + { + invoiceWrapper.Consignee = contacts[invoice.ContactID]; + } -// if (invoice.EntityID > 0) -// { -// invoiceWrapper.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); //Need to optimize -// } + if (invoice.EntityID > 0) + { + invoiceWrapper.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); //Need to optimize + } -// invoiceWrapper.Cost = invoice.GetInvoiceCost(DaoFactory); + invoiceWrapper.Cost = invoice.GetInvoiceCost(DaoFactory); -// result.Add(invoiceWrapper); -// } + result.Add(invoiceWrapper); + } -// return result; -// } -// } -//} \ No newline at end of file + return result; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs b/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs index cdcc18a234a..ce38dac7f79 100644 --- a/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs +++ b/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs @@ -38,4 +38,5 @@ public enum InvoiceStatus Paid = 4, Archived = 5 } -} \ No newline at end of file +} + diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index 2fef47837ab..bf3fe5b3232 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -26,10 +26,13 @@ using System.Collections.Generic; using System.Linq; + +using ASC.Common; using ASC.CRM.Core.EF; namespace ASC.Web.CRM.Core.Search { + [Scope] public class BundleSearch { public BundleSearch(FactoryIndexerContact factoryIndexerContact, diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateCasesInDto.cs b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateCasesInDto.cs new file mode 100644 index 00000000000..ab15f17fbf6 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateCasesInDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using ASC.Api.Collections; + +namespace ASC.CRM.Model +{ + public class CreateOrUpdateCasesInDto + { + public string Title { get; set; } + public IEnumerable Members { get; set; } + public IEnumerable> CustomFieldList { get; set; } + public bool isPrivate { get; set; } + public IEnumerable accessList { get; set; } + public bool isNotify { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateDealInDto.cs b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateDealInDto.cs new file mode 100644 index 00000000000..bbc0e98a876 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateDealInDto.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using ASC.Api.Collections; +using ASC.Api.Core; +using ASC.CRM.Core.Enums; + +namespace ASC.CRM.Model +{ + public class CreateOrUpdateDealInDto + { + public int Contactid { get; set; } + public IEnumerable Members { get; set; } + public string Title { get; set; } + public string Description { get; set; } + public Guid Responsibleid { get; set; } + public BidType BidType { get; set; } + public decimal BidValue { get; set; } + public string BidCurrencyAbbr { get; set; } + public int PerPeriodValue { get; set; } + public int Stageid { get; set; } + public int SuccessProbability { get; set; } + public ApiDateTime ActualCloseDate { get; set; } + public ApiDateTime ExpectedCloseDate { get; set; } + public IEnumerable> CustomFieldList { get; set; } + public bool isPrivate { get; set; } + public IEnumerable AccessList { get; set; } + public bool isNotify { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceInDto.cs b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceInDto.cs new file mode 100644 index 00000000000..ba932801e41 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceInDto.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using ASC.Api.Core; +using ASC.CRM.Core.Entities; + +namespace ASC.CRM.Model +{ + public class CreateOrUpdateInvoiceInDto + { + public string Number { get; set; } + public ApiDateTime IssueDate { get; set; } + public int TemplateType { get; set; } + public int ContactId { get; set; } + public int ConsigneeId { get; set; } + public int EntityId { get; set; } + public int BillingAddressID { get; set; } + public int DeliveryAddressID { get; set; } + public ApiDateTime DueDate { get; set; } + public string Language { get; set; } + public string Currency { get; set; } + public decimal ExchangeRate { get; set; } + public string PurchaseOrderNumber { get; set; } + public string Terms { get; set; } + public string Description { get; set; } + public IEnumerable InvoiceLines { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceItemInDto.cs b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceItemInDto.cs new file mode 100644 index 00000000000..647e63500b9 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceItemInDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ASC.CRM.Model +{ + public class CreateOrUpdateInvoiceItemInDto + { + public string Title { get; set; } + public string Description { get; set; } + public decimal Price { get; set; } + public string Sku { get; set; } + public int Quantity { get; set; } + public int StockQuantity { get; set; } + public bool TrackInventory { get; set; } + public int InvoiceTax1id { get; set; } + public int InvoiceTax2id { get; set; } + + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceLineInDto.cs b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceLineInDto.cs new file mode 100644 index 00000000000..6ff058a5955 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceLineInDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ASC.CRM.Model +{ + public class CreateOrUpdateInvoiceLineInDto + { + public int InvoiceId { get; set; } + public int InvoiceItemId { get; set; } + public int InvoiceTax1Id { get; set; } + public int InvoiceTax2Id { get; set; } + public int SortOrder { get; set; } + public string Description { get; set; } + public int Quantity { get; set; } + public decimal Price { get; set; } + public int Discount { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceTax.cs b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceTax.cs new file mode 100644 index 00000000000..bc348b9845b --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceTax.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ASC.CRM.Model +{ + public class CreateOrUpdateInvoiceTax + { + public string Name { get; set; } + public string Description { get; set; } + public decimal Rate { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdatePersonInDto.cs b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdatePersonInDto.cs new file mode 100644 index 00000000000..5e53cfeb550 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/CreateOrUpdatePersonInDto.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Threading.Tasks; + +using ASC.Api.Collections; +using ASC.CRM.Core.Enums; + +using Microsoft.AspNetCore.Http; + +namespace ASC.CRM.Model +{ + public class CreateOrUpdateContactInDto + { + public string About { get; set; } + + public ShareType ShareType { get; set; } + + public IEnumerable ManagerList { get; set; } + + public IEnumerable> CustomFieldList { get; set; } + + public IEnumerable Photos { get; set; } + } + + public class CreateOrUpdateCompanyInDto : CreateOrUpdateContactInDto + { + [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String CompanyName { get; set; } + + public IEnumerable PersonList { get; set; } + + } + + + public class CreateOrUpdatePersonInDto : CreateOrUpdateContactInDto + { + public String FirstName { get; set; } + + public String LastName { get; set; } + + public String JobTitle { get; set; } + + public int CompanyId { get; set; } + } +} + + diff --git a/products/ASC.CRM/Server/Model/Dto/SaveNumberSettingsInDto.cs b/products/ASC.CRM/Server/Model/Dto/SaveNumberSettingsInDto.cs new file mode 100644 index 00000000000..d1d1dadf5af --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/SaveNumberSettingsInDto.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ASC.CRM.Model +{ + public class SaveNumberSettingsInDto + { + public bool AutoGenerated { get; set; } + public string Prefix { get; set; } + public string Number { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchCasesInDto.cs b/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchCasesInDto.cs new file mode 100644 index 00000000000..27cca054071 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchCasesInDto.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ASC.CRM.Model +{ + public class SetAccessToBatchCasesByFilterInDto + { + public int Contactid { get; set; } + public bool? isClosed { get; set; } + public IEnumerable Tags { get; set; } + public bool isPrivate { get; set; } + public IEnumerable AccessList { get; set; } + + } + + public class SetAccessToBatchCasesInDto + { + public IEnumerable Casesid { get; set; } + public bool isPrivate { get; set; } + public IEnumerable AccessList { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchContactInDto.cs b/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchContactInDto.cs new file mode 100644 index 00000000000..67a11c78a8a --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchContactInDto.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Threading.Tasks; + +using ASC.Api.Core; +using ASC.CRM.Core.Enums; + +namespace ASC.CRM.Model +{ + public class SetAccessToBatchContactByFilterInDto + { + public IEnumerable Tags { get; set; } + public int? ContactStage { get; set; } + public int? ContactType { get; set; } + public ContactListViewType ContactListView { get; set; } + public ApiDateTime FromDate { get; set; } + public ApiDateTime ToDate { get; set; } + public bool isPrivate { get; set; } + public IEnumerable ManagerList { get; set; } + } + + public class SetAccessToBatchContactInDto + { + public IEnumerable ContactID { get; set; } + + public bool isShared { get; set; } + + public IEnumerable ManagerList { get; set; } + } +} diff --git a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchDealByFilterInDto.cs b/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchDealByFilterInDto.cs new file mode 100644 index 00000000000..6870e9f7530 --- /dev/null +++ b/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchDealByFilterInDto.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Threading.Tasks; + +using ASC.Api.Core; +using ASC.CRM.Core.Enums; + +namespace ASC.CRM.Model +{ + public class SetAccessToBatchDealByFilterInDto + { + public Guid Responsibleid { get; set; } + public int OpportunityStagesid { get; set; } + public IEnumerable Tags { get; set; } + public int Contactid { get; set; } + public DealMilestoneStatus? StageType { get; set; } + public bool? ContactAlsoIsParticipant { get; set; } + public ApiDateTime FromDate { get; set; } + public ApiDateTime ToDate { get; set; } + public bool isPrivate { get; set; } + public IEnumerable AccessList { get; set; } + } + + public class SetAccessToBatchDealInDto + { + public IEnumerable Opportunityid { get; set; } + public bool isPrivate { get; set; } + public IEnumerable AccessList { get; set; } + } +} From 7fab0b47d71dd0306bed0a397f298e5318ed6e4d Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 9 Mar 2021 18:37:16 +0300 Subject: [PATCH 19/61] crm: refactoring code --- products/ASC.CRM/Core/ASC.CRM.Core.csproj | 16 + products/ASC.CRM/Server/ASC.CRM.csproj | 28 +- .../{Controllers => Api}/CRMBootstrap.cs | 0 .../{Controllers => Api}/CRMCalendar.cs | 0 .../CRMController.Cases.cs | 110 +++---- .../CRMController.ContactInfo.cs | 68 ++--- .../CRMController.Contacts.cs | 278 +++++++++--------- .../CRMController.CurrencyRates.cs | 33 ++- .../CRMController.CustomFields.cs | 38 +-- .../CRMController.Deals.cs | 126 ++++---- .../CRMController.Invoices.cs | 124 ++++---- .../CRMController.ListItem.cs | 154 +++++----- .../CRMController.RelationshipEvent.cs | 72 ++--- .../CRMController.Reports.cs | 0 .../{Controllers => Api}/CRMController.Tag.cs | 8 +- .../CRMController.TaskTemplate.cs | 58 ++-- .../CRMController.Tasks.cs | 96 +++--- .../CRMController.Utils.cs | 15 +- .../CRMController.Voip.cs | 60 ++-- .../{Controllers => Api}/CRMController.cs | 102 +++---- .../CasesWrapper.cs => ApiModels/CasesDto.cs} | 64 ++-- .../ContactDto.cs} | 217 +++++++------- .../ContactInfoDto.cs} | 20 +- .../CreateOrUpdateCasesInDto.cs | 2 +- .../CreateOrUpdateDealInDto.cs | 2 +- .../CreateOrUpdateInvoiceInDto.cs | 2 +- .../CreateOrUpdateInvoiceItemInDto.cs | 2 +- .../CreateOrUpdateInvoiceLineInDto.cs | 2 +- .../CreateOrUpdateInvoiceTax.cs | 2 +- .../CreateOrUpdatePersonInDto.cs | 4 +- .../CurrencyInfoDto.cs} | 50 ++-- .../CurrencyRateDto.cs} | 18 +- .../CustomFieldDto.cs} | 22 +- .../InvoiceDto.cs} | 222 +++++++------- .../ListItemDto.cs} | 158 +++++----- .../OpportunityDto.cs} | 98 +++--- .../RelationshipEventDto.cs} | 76 ++--- .../ReportDto.cs} | 4 +- .../SaveNumberSettingsInDto.cs | 2 +- .../SetAccessToBatchCasesInDto.cs | 2 +- .../SetAccessToBatchContactInDto.cs | 2 +- .../SetAccessToBatchDealByFilterInDto.cs | 2 +- .../Server/{Model => ApiModels}/Subject.cs | 2 +- .../TaskWrapper.cs => ApiModels/TaskDto.cs} | 102 +++---- .../TaskTemplateContainerDto.cs} | 32 +- .../VoipCallDto.cs} | 16 +- .../ASC.CRM/Server/Classes/CRMSettings.cs | 12 +- .../Server/Core/Dao/RelationshipEventDao.cs | 4 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 8 +- .../Server/Core/Search/BundleSearch.cs | 4 +- 50 files changed, 1272 insertions(+), 1267 deletions(-) create mode 100644 products/ASC.CRM/Core/ASC.CRM.Core.csproj rename products/ASC.CRM/Server/{Controllers => Api}/CRMBootstrap.cs (100%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMCalendar.cs (100%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Cases.cs (88%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.ContactInfo.cs (90%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Contacts.cs (88%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.CurrencyRates.cs (88%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.CustomFields.cs (91%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Deals.cs (89%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Invoices.cs (93%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.ListItem.cs (88%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.RelationshipEvent.cs (92%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Reports.cs (100%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Tag.cs (99%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.TaskTemplate.cs (87%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Tasks.cs (89%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Utils.cs (97%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.Voip.cs (93%) rename products/ASC.CRM/Server/{Controllers => Api}/CRMController.cs (74%) rename products/ASC.CRM/Server/{Model/CasesWrapper.cs => ApiModels/CasesDto.cs} (70%) rename products/ASC.CRM/Server/{Model/ContactWrapper.cs => ApiModels/ContactDto.cs} (63%) rename products/ASC.CRM/Server/{Model/ContactInfoWrapper.cs => ApiModels/ContactInfoDto.cs} (93%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/CreateOrUpdateCasesInDto.cs (94%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/CreateOrUpdateDealInDto.cs (97%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/CreateOrUpdateInvoiceInDto.cs (97%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/CreateOrUpdateInvoiceItemInDto.cs (95%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/CreateOrUpdateInvoiceLineInDto.cs (95%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/CreateOrUpdateInvoiceTax.cs (91%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/CreateOrUpdatePersonInDto.cs (92%) rename products/ASC.CRM/Server/{Model/CurrencyInfoWrapper.cs => ApiModels/CurrencyInfoDto.cs} (69%) rename products/ASC.CRM/Server/{Model/CurrencyRateWrapper.cs => ApiModels/CurrencyRateDto.cs} (86%) rename products/ASC.CRM/Server/{Model/CustomFieldWrapper.cs => ApiModels/CustomFieldDto.cs} (86%) rename products/ASC.CRM/Server/{Model/InvoiceWrapper.cs => ApiModels/InvoiceDto.cs} (68%) rename products/ASC.CRM/Server/{Model/ListItemWrapper.cs => ApiModels/ListItemDto.cs} (66%) rename products/ASC.CRM/Server/{Model/OpportunityWrapper.cs => ApiModels/OpportunityDto.cs} (63%) rename products/ASC.CRM/Server/{Model/RelationshipEventWrapper.cs => ApiModels/RelationshipEventDto.cs} (73%) rename products/ASC.CRM/Server/{Model/ReportWrapper.cs => ApiModels/ReportDto.cs} (96%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/SaveNumberSettingsInDto.cs (91%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/SetAccessToBatchCasesInDto.cs (95%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/SetAccessToBatchContactInDto.cs (96%) rename products/ASC.CRM/Server/{Model/Dto => ApiModels}/SetAccessToBatchDealByFilterInDto.cs (97%) rename products/ASC.CRM/Server/{Model => ApiModels}/Subject.cs (98%) rename products/ASC.CRM/Server/{Model/TaskWrapper.cs => ApiModels/TaskDto.cs} (63%) rename products/ASC.CRM/Server/{Model/TaskTemplateContainerWrapper.cs => ApiModels/TaskTemplateContainerDto.cs} (80%) rename products/ASC.CRM/Server/{Model/VoipCallWrapper.cs => ApiModels/VoipCallDto.cs} (89%) diff --git a/products/ASC.CRM/Core/ASC.CRM.Core.csproj b/products/ASC.CRM/Core/ASC.CRM.Core.csproj new file mode 100644 index 00000000000..0c8cf473251 --- /dev/null +++ b/products/ASC.CRM/Core/ASC.CRM.Core.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 133676bccff..6ba2256cccd 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -23,20 +23,20 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/products/ASC.CRM/Server/Controllers/CRMBootstrap.cs b/products/ASC.CRM/Server/Api/CRMBootstrap.cs similarity index 100% rename from products/ASC.CRM/Server/Controllers/CRMBootstrap.cs rename to products/ASC.CRM/Server/Api/CRMBootstrap.cs diff --git a/products/ASC.CRM/Server/Controllers/CRMCalendar.cs b/products/ASC.CRM/Server/Api/CRMCalendar.cs similarity index 100% rename from products/ASC.CRM/Server/Controllers/CRMCalendar.cs rename to products/ASC.CRM/Server/Api/CRMCalendar.cs diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs b/products/ASC.CRM/Server/Api/CRMController.Cases.cs similarity index 88% rename from products/ASC.CRM/Server/Controllers/CRMController.Cases.cs rename to products/ASC.CRM/Server/Api/CRMController.Cases.cs index 18cbf13129f..e5f0195d21e 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Cases.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Cases.cs @@ -25,14 +25,14 @@ using ASC.Api.Collections; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.Core; using ASC.Core.Users; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.CRM.Model; + using ASC.ElasticSearch; using ASC.MessagingSystem; using ASC.Web.Api.Routing; @@ -58,7 +58,7 @@ public partial class CRMController /// Case /// [Update(@"case/{caseid:int}/close")] - public CasesWrapper CloseCases(int caseid) + public CasesDto CloseCases(int caseid) { if (caseid <= 0) throw new ArgumentException(); @@ -67,7 +67,7 @@ public CasesWrapper CloseCases(int caseid) MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); - return CasesWrapperHelper.Get(cases); + return CasesDtoHelper.Get(cases); } /// @@ -82,7 +82,7 @@ public CasesWrapper CloseCases(int caseid) /// Case /// [Update(@"case/{caseid:int}/reopen")] - public CasesWrapper ReOpenCases(int caseid) + public CasesDto ReOpenCases(int caseid) { if (caseid <= 0) throw new ArgumentException(); @@ -91,7 +91,7 @@ public CasesWrapper ReOpenCases(int caseid) MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); - return CasesWrapperHelper.Get(cases); + return CasesDtoHelper.Get(cases); } /// @@ -121,7 +121,7 @@ public CasesWrapper ReOpenCases(int caseid) /// ]]> /// [Create(@"case")] - public CasesWrapper CreateCases( + public CasesDto CreateCases( CreateOrUpdateCasesInDto inDto) { @@ -164,7 +164,7 @@ public CasesWrapper CreateCases( } } - return CasesWrapperHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); + return CasesDtoHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); } /// @@ -197,7 +197,7 @@ public CasesWrapper CreateCases( /// ]]> /// [Update(@"case/{caseid:int}")] - public CasesWrapper UpdateCases( + public CasesDto UpdateCases( int caseid, CreateOrUpdateCasesInDto inDto) { @@ -240,7 +240,7 @@ public CasesWrapper UpdateCases( } } - return CasesWrapperHelper.Get(cases); + return CasesDtoHelper.Get(cases); } /// @@ -257,7 +257,7 @@ public CasesWrapper UpdateCases( /// Case /// [Update(@"case/{caseid:int}/access")] - public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) + public CasesDto SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) { if (caseid <= 0) throw new ArgumentException(); @@ -269,7 +269,7 @@ public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) + private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) { var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); if (isPrivate && accessListLocal.Any()) @@ -301,7 +301,7 @@ private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable @@ -318,7 +318,7 @@ private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable [Update(@"case/access")] - public IEnumerable SetAccessToBatchCases( + public IEnumerable SetAccessToBatchCases( SetAccessToBatchCasesInDto inDto) { var casesid = inDto.Casesid; @@ -329,7 +329,7 @@ public IEnumerable SetAccessToBatchCases( var cases = DaoFactory.GetCasesDao().GetCases(casesid); - if (!cases.Any()) return new List(); + if (!cases.Any()) return new List(); foreach (var c in cases) { @@ -341,7 +341,7 @@ public IEnumerable SetAccessToBatchCases( result.Add(c); } - return ToListCasesWrappers(result); + return ToListCasesDtos(result); } /// @@ -360,7 +360,7 @@ public IEnumerable SetAccessToBatchCases( /// Case list /// [Update(@"case/filter/access")] - public IEnumerable SetAccessToBatchCases( + public IEnumerable SetAccessToBatchCases( SetAccessToBatchCasesByFilterInDto inDto ) { @@ -374,7 +374,7 @@ SetAccessToBatchCasesByFilterInDto inDto var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); - if (!caseses.Any()) return new List(); + if (!caseses.Any()) return new List(); foreach (var casese in caseses) { @@ -386,7 +386,7 @@ SetAccessToBatchCasesByFilterInDto inDto result.Add(casese); } - return ToListCasesWrappers(result); + return ToListCasesDtos(result); } /// @@ -398,14 +398,14 @@ SetAccessToBatchCasesByFilterInDto inDto /// /// [Read(@"case/{caseid:int}")] - public CasesWrapper GetCaseByID(int caseid) + public CasesDto GetCaseByID(int caseid) { if (caseid <= 0) throw new ItemNotFoundException(); var cases = DaoFactory.GetCasesDao().GetByID(caseid); if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - return CasesWrapperHelper.Get(cases); + return CasesDtoHelper.Get(cases); } /// @@ -420,9 +420,9 @@ public CasesWrapper GetCaseByID(int caseid) /// Case list /// [Read(@"case/filter")] - public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable tags) + public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable tags) { - IEnumerable result; + IEnumerable result; SortedByType sortBy; OrderBy casesOrderBy; @@ -446,7 +446,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumer if (casesOrderBy != null) { - result = ToListCasesWrappers( + result = ToListCasesDtos( DaoFactory .GetCasesDao() .GetCases( @@ -464,7 +464,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumer } else { - result = ToListCasesWrappers( + result = ToListCasesDtos( DaoFactory .GetCasesDao() .GetCases( @@ -502,7 +502,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumer /// Case /// [Delete(@"case/{caseid:int}")] - public CasesWrapper DeleteCase(int caseid) + public CasesDto DeleteCase(int caseid) { if (caseid <= 0) throw new ArgumentException(); @@ -512,7 +512,7 @@ public CasesWrapper DeleteCase(int caseid) MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); - return CasesWrapperHelper.Get(cases); + return CasesDtoHelper.Get(cases); } /// @@ -527,18 +527,18 @@ public CasesWrapper DeleteCase(int caseid) /// Case list /// [Update(@"case")] - public IEnumerable DeleteBatchCases(IEnumerable casesids) + public IEnumerable DeleteBatchCases(IEnumerable casesids) { if (casesids == null) throw new ArgumentException(); casesids = casesids.Distinct(); var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); - if (caseses == null || !caseses.Any()) return new List(); + if (caseses == null || !caseses.Any()) return new List(); MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); - return ToListCasesWrappers(caseses); + return ToListCasesDtos(caseses); } /// @@ -555,16 +555,16 @@ public IEnumerable DeleteBatchCases(IEnumerable casesids) /// Case list /// [Delete(@"case/filter")] - public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) + public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) { var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); - if (!caseses.Any()) return new List(); + if (!caseses.Any()) return new List(); caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); - return ToListCasesWrappers(caseses); + return ToListCasesDtos(caseses); } /// @@ -576,12 +576,12 @@ public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, /// Contact list /// [Read(@"case/{caseid:int}/contact")] - public IEnumerable GetCasesMembers(int caseid) + public IEnumerable GetCasesMembers(int caseid) { var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); return contactIDs == null - ? new ItemList() - : ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)); + ? new ItemList() + : ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)); } /// @@ -597,7 +597,7 @@ public IEnumerable GetCasesMembers(int caseid) /// Participant /// [Create(@"case/{caseid:int}/contact")] - public ContactWrapper AddMemberToCases(int caseid, int contactid) + public ContactDto AddMemberToCases(int caseid, int contactid) { if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -612,7 +612,7 @@ public ContactWrapper AddMemberToCases(int caseid, int contactid) var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); - return ToContactWrapper(contact); + return ToContactDto(contact); } /// @@ -628,7 +628,7 @@ public ContactWrapper AddMemberToCases(int caseid, int contactid) /// Participant /// [Delete(@"case/{caseid:int}/contact/{contactid:int}")] - public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) + public ContactDto DeleteMemberFromCases(int caseid, int contactid) { if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -638,7 +638,7 @@ public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ToContactWrapper(contact); + var result = ToContactDto(contact); DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); @@ -659,9 +659,9 @@ public ContactWrapper DeleteMemberFromCases(int caseid, int contactid) /// /// false [Read(@"case/byprefix")] - public IEnumerable GetCasesByPrefix(string prefix, int contactID) + public IEnumerable GetCasesByPrefix(string prefix, int contactID) { - var result = new List(); + var result = new List(); if (contactID > 0) { @@ -671,7 +671,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) { if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) { - result.Add(CasesWrapperHelper.Get(item)); + result.Add(CasesDtoHelper.Get(item)); } } @@ -684,18 +684,18 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) foreach (var item in findedCases) { - result.Add(CasesWrapperHelper.Get(item)); + result.Add(CasesDtoHelper.Get(item)); } } return result; } - private IEnumerable ToListCasesWrappers(ICollection items) + private IEnumerable ToListCasesDtos(ICollection items) { - if (items == null || items.Count == 0) return new List(); + if (items == null || items.Count == 0) return new List(); - var result = new List(); + var result = new List(); var contactIDs = new List(); var casesIDs = items.Select(item => item.ID).ToArray(); @@ -703,7 +703,7 @@ private IEnumerable ToListCasesWrappers(ICollection items) var customFields = DaoFactory.GetCustomFieldDao() .GetEnityFields(EntityType.Case, casesIDs) .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseDto)); var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); @@ -715,21 +715,21 @@ private IEnumerable ToListCasesWrappers(ICollection items) var contacts = DaoFactory .GetContactDao() .GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); + .ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseDto(x)); foreach (var cases in items) { - var casesWrapper = CasesWrapperHelper.Get(cases); + var casesDto = CasesDtoHelper.Get(cases); - casesWrapper.CustomFields = customFields.ContainsKey(cases.ID) + casesDto.CustomFields = customFields.ContainsKey(cases.ID) ? customFields[cases.ID] - : new List(); + : new List(); - casesWrapper.Members = casesMembers.ContainsKey(cases.ID) + casesDto.Members = casesMembers.ContainsKey(cases.ID) ? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item]) - : new List(); + : new List(); - result.Add(casesWrapper); + result.Add(casesDto); } return result; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs b/products/ASC.CRM/Server/Api/CRMController.ContactInfo.cs similarity index 90% rename from products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs rename to products/ASC.CRM/Server/Api/CRMController.ContactInfo.cs index a867cd16b39..fb3ed973dc7 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ContactInfo.cs +++ b/products/ASC.CRM/Server/Api/CRMController.ContactInfo.cs @@ -24,7 +24,7 @@ */ -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.CRM.Classes; using ASC.CRM.Core; @@ -85,7 +85,7 @@ public IEnumerable GetContactInfoType() /// Contact information /// [Read(@"contact/{contactid:int}/data")] - public IEnumerable GetContactInfo(int contactid) + public IEnumerable GetContactInfo(int contactid) { if (contactid <= 0) throw new ArgumentException(); @@ -95,7 +95,7 @@ public IEnumerable GetContactInfo(int contactid) return DaoFactory.GetContactInfoDao().GetList(contactid, null, null, null) .OrderByDescending(info => info.ID) .ToList() - .ConvertAll(x => ContactInfoWrapperHelper.Get(x)); + .ConvertAll(x => ContactInfoDtoHelper.Get(x)); } /// @@ -108,7 +108,7 @@ public IEnumerable GetContactInfo(int contactid) /// Contact information /// [Read(@"contact/{contactid:int}/data/{id:int}")] - public ContactInfoWrapper GetContactInfoByID(int contactid, int id) + public ContactInfoDto GetContactInfoByID(int contactid, int id) { if (contactid <= 0 || id <= 0) throw new ArgumentException(); @@ -119,7 +119,7 @@ public ContactInfoWrapper GetContactInfoByID(int contactid, int id) if (contactInfo == null || contactInfo.ContactID != contactid) throw new ArgumentException(); - return ContactInfoWrapperHelper.Get(contactInfo); + return ContactInfoDtoHelper.Get(contactInfo); } /// @@ -139,7 +139,7 @@ public ContactInfoWrapper GetContactInfoByID(int contactid, int id) /// /// [Create(@"contact/{contactid:int}/data")] - public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoType, string data, bool isPrimary, string category) + public ContactInfoDto CreateContactInfo(int contactid, ContactInfoType infoType, string data, bool isPrimary, string category) { if (string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); var contact = DaoFactory.GetContactDao().GetByID(contactid); @@ -180,11 +180,11 @@ public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoT MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - var contactInfoWrapper = ContactInfoWrapperHelper.Get(contactInfo); + var contactInfoDto = ContactInfoDtoHelper.Get(contactInfo); - contactInfoWrapper.Id = contactInfoID; + contactInfoDto.Id = contactInfoID; - return contactInfoWrapper; + return contactInfoDto; } /// @@ -202,7 +202,7 @@ public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoT /// /// [Create(@"contact/{contactid:int}/addressdata")] - public ContactInfoWrapper CreateContactInfoAddress(int contactid, Address address) + public ContactInfoDto CreateContactInfoAddress(int contactid, Address address) { if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid"); @@ -239,7 +239,7 @@ public ContactInfoWrapper CreateContactInfoAddress(int contactid, Address addres var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - return ContactInfoWrapperHelper.Get(contactInfo); + return ContactInfoDtoHelper.Get(contactInfo); } /// @@ -261,15 +261,15 @@ public ContactInfoWrapper CreateContactInfoAddress(int contactid, Address addres /// /// false [Create(@"contact/{contactid:int}/batch")] - public IEnumerable CreateBatchContactInfo(int contactid, IEnumerable items) + public IEnumerable CreateBatchContactInfo(int contactid, IEnumerable items) { if (contactid <= 0) throw new ArgumentException(); var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); - var itemsList = items != null ? items.ToList() : new List(); - var contactInfoList = itemsList.Select(FromContactInfoWrapper).ToList(); + var itemsList = items != null ? items.ToList() : new List(); + var contactInfoList = itemsList.Select(FromContactInfoDto).ToList(); foreach (var contactInfo in contactInfoList) { @@ -286,8 +286,8 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEn for (var index = 0; index < itemsList.Count; index++) { - var infoWrapper = itemsList[index]; - infoWrapper.Id = ids[index]; + var infoDto = itemsList[index]; + infoDto.Id = ids[index]; } return itemsList; } @@ -308,7 +308,7 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEn /// Contact information /// [Update(@"contact/{contactid:int}/data/{id:int}")] - public ContactInfoWrapper UpdateContactInfo(int id, int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category) + public ContactInfoDto UpdateContactInfo(int id, int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category) { if (id <= 0 || string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); @@ -350,9 +350,9 @@ public ContactInfoWrapper UpdateContactInfo(int id, int contactid, ContactInfoTy var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - var contactInfoWrapper = ContactInfoWrapperHelper.Get(contactInfo); + var contactInfoDto = ContactInfoDtoHelper.Get(contactInfo); - return contactInfoWrapper; + return contactInfoDto; } /// @@ -369,7 +369,7 @@ public ContactInfoWrapper UpdateContactInfo(int id, int contactid, ContactInfoTy /// Contact information /// [Update(@"contact/{contactid:int}/addressdata/{id:int}")] - public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Address address) + public ContactInfoDto UpdateContactInfoAddress(int id, int contactid, Address address) { if (id <= 0) throw new ArgumentException("Invalid value", "id"); @@ -407,7 +407,7 @@ public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Addres var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - return ContactInfoWrapperHelper.Get(contactInfo); + return ContactInfoDtoHelper.Get(contactInfo); } /// @@ -427,15 +427,15 @@ public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Addres /// /// false [Update(@"contact/{contactid:int}/batch")] - public IEnumerable UpdateBatchContactInfo(int contactid, IEnumerable items) + public IEnumerable UpdateBatchContactInfo(int contactid, IEnumerable items) { if (contactid <= 0) throw new ArgumentException(); var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); - var itemsList = items != null ? items.ToList() : new List(); - var contactInfoList = itemsList.Select(FromContactInfoWrapper).ToList(); + var itemsList = items != null ? items.ToList() : new List(); + var contactInfoList = itemsList.Select(FromContactInfoDto).ToList(); foreach (var contactInfo in contactInfoList) { @@ -453,8 +453,8 @@ public IEnumerable UpdateBatchContactInfo(int contactid, IEn for (var index = 0; index < itemsList.Count; index++) { - var infoWrapper = itemsList[index]; - infoWrapper.Id = ids[index]; + var infoDto = itemsList[index]; + infoDto.Id = ids[index]; } return itemsList; } @@ -494,7 +494,7 @@ public IEnumerable GetContactInfo(int contactid, ContactInfoType infoTyp /// Contact information /// [Delete(@"contact/{contactid:int}/data/{id:int}")] - public ContactInfoWrapper DeleteContactInfo(int contactid, int id) + public ContactInfoDto DeleteContactInfo(int contactid, int id) { if (id <= 0 || contactid <= 0) throw new ArgumentException(); @@ -504,7 +504,7 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); if (contactInfo == null) throw new ItemNotFoundException(); - var wrapper = ContactInfoWrapperHelper.Get(contactInfo); + var wrapper = ContactInfoDtoHelper.Get(contactInfo); DaoFactory.GetContactInfoDao().Delete(id); @@ -515,15 +515,15 @@ public ContactInfoWrapper DeleteContactInfo(int contactid, int id) return wrapper; } - private static ContactInfo FromContactInfoWrapper(ContactInfoWrapper contactInfoWrapper) + private static ContactInfo FromContactInfoDto(ContactInfoDto contactInfoDto) { return new ContactInfo { - ID = contactInfoWrapper.Id, - Category = contactInfoWrapper.Category, - Data = contactInfoWrapper.Data, - InfoType = contactInfoWrapper.InfoType, - IsPrimary = contactInfoWrapper.IsPrimary + ID = contactInfoDto.Id, + Category = contactInfoDto.Category, + Data = contactInfoDto.Data, + InfoType = contactInfoDto.InfoType, + IsPrimary = contactInfoDto.IsPrimary }; } } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs b/products/ASC.CRM/Server/Api/CRMController.Contacts.cs similarity index 88% rename from products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs rename to products/ASC.CRM/Server/Api/CRMController.Contacts.cs index 9adcd201412..55d8752d139 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Contacts.cs @@ -26,13 +26,13 @@ using ASC.Api.Collections; using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Threading.Progress; using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.CRM.Model; + using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Models; @@ -68,21 +68,21 @@ public partial class CRMController /// /// [Read(@"contact/{contactid:int}")] - public ContactWrapper GetContactByID(int contactid) + public ContactDto GetContactByID(int contactid) { if (contactid <= 0) throw new ArgumentException(); var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return ContactWrapperHelper.GetContactWrapper(contact); + return ContactDtoHelper.GetContactDto(contact); } - public IEnumerable GetContactsByID(IEnumerable contactid) + public IEnumerable GetContactsByID(IEnumerable contactid) { var contacts = DaoFactory.GetContactDao().GetContacts(contactid.ToArray()).Where(r => r != null && CRMSecurity.CanAccessTo(r)); - return ToListContactWrapper(contacts.ToList()); + return ToListContactDto(contacts.ToList()); } @@ -99,12 +99,12 @@ public IEnumerable GetContactsByID(IEnumerable contactid) /// /// [Read(@"contact/project/{projectid:int}")] - public IEnumerable GetContactsByProjectID(int projectid) + public IEnumerable GetContactsByProjectID(int projectid) { if (projectid <= 0) throw new ArgumentException(); var contacts = DaoFactory.GetContactDao().GetContactsByProjectID(projectid); - return ToListContactWrapper(contacts.ToList()); + return ToListContactDto(contacts.ToList()); } ///// @@ -118,7 +118,7 @@ public IEnumerable GetContactsByProjectID(int projectid) ///// ///// Contact Info //[Create(@"contact/{contactid:int}/project/{projectid:int}")] - //public ContactWrapper SetRelativeContactToProject(int contactid, int projectid) + //public ContactDto SetRelativeContactToProject(int contactid, int projectid) //{ // if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); @@ -138,7 +138,7 @@ public IEnumerable GetContactsByProjectID(int projectid) // var messageAction = contact is Company ? MessageAction.ProjectLinkedCompany : MessageAction.ProjectLinkedPerson; // MessageService.Send(messageAction, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); - // return ToContactWrapper(contact); + // return ToContactDto(contact); //} ///// @@ -154,7 +154,7 @@ public IEnumerable GetContactsByProjectID(int projectid) ///// Contact list ///// //[Create(@"contact/project/{projectid:int}")] - //public IEnumerable SetRelativeContactListToProject(IEnumerable contactid, int projectid) + //public IEnumerable SetRelativeContactListToProject(IEnumerable contactid, int projectid) //{ // if (contactid == null) throw new ArgumentException(); @@ -179,7 +179,7 @@ public IEnumerable GetContactsByProjectID(int projectid) // MessageService.Send(MessageAction.ProjectLinkedContacts, MessageTarget.Create(contactIds), project.Title, contacts.Select(x => x.GetTitle())); - // return contacts.ConvertAll(ToContactWrapper); + // return contacts.ConvertAll(ToContactDto); //} ///// @@ -193,7 +193,7 @@ public IEnumerable GetContactsByProjectID(int projectid) ///// Contact info ///// //[Delete(@"contact/{contactid:int}/project/{projectid:int}")] - //public ContactBaseWrapper RemoveRelativeContactToProject(int contactid, int projectid) + //public ContactBaseDto RemoveRelativeContactToProject(int contactid, int projectid) //{ // if (contactid <= 0 || projectid <= 0) throw new ArgumentException(); @@ -212,7 +212,7 @@ public IEnumerable GetContactsByProjectID(int projectid) // var action = contact is Company ? MessageAction.ProjectUnlinkedCompany : MessageAction.ProjectUnlinkedPerson; // MessageService.Send(action, MessageTarget.Create(contact.ID), project.Title, contact.GetTitle()); - // return ToContactBaseWrapper(contact); + // return ToContactBaseDto(contact); //} /// @@ -227,7 +227,7 @@ public IEnumerable GetContactsByProjectID(int projectid) /// Opportunity /// [Create(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] - public OpportunityWrapper AddDealToContact(int contactid, int opportunityid) + public OpportunityDto AddDealToContact(int contactid, int opportunityid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -242,7 +242,7 @@ public OpportunityWrapper AddDealToContact(int contactid, int opportunityid) var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; MessageService.Send(messageAction, MessageTarget.Create(contact.ID), opportunity.Title, contact.GetTitle()); - return OpportunityWrapperHelper.Get(opportunity); + return OpportunityDtoHelper.Get(opportunity); } /// @@ -257,7 +257,7 @@ public OpportunityWrapper AddDealToContact(int contactid, int opportunityid) /// Opportunity /// [Delete(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] - public OpportunityWrapper DeleteDealFromContact(int contactid, int opportunityid) + public OpportunityDto DeleteDealFromContact(int contactid, int opportunityid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -269,7 +269,7 @@ public OpportunityWrapper DeleteDealFromContact(int contactid, int opportunityid DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); - return OpportunityWrapperHelper.Get(opportunity); + return OpportunityDtoHelper.Get(opportunity); } /// @@ -289,7 +289,7 @@ public OpportunityWrapper DeleteDealFromContact(int contactid, int opportunityid /// Contact list /// [Read(@"contact/filter")] - public IEnumerable GetContacts( + public IEnumerable GetContacts( IEnumerable tags, int? contactStage, int? contactType, @@ -299,7 +299,7 @@ public IEnumerable GetContacts( ApiDateTime fromDate, ApiDateTime toDate) { - IEnumerable result; + IEnumerable result; OrderBy contactsOrderBy; @@ -328,7 +328,7 @@ public IEnumerable GetContacts( if (contactsOrderBy != null) { - result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts( + result = ToListContactDto(DaoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -347,7 +347,7 @@ public IEnumerable GetContacts( } else { - result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts( + result = ToListContactDto(DaoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -399,9 +399,9 @@ public IEnumerable GetContacts( /// /// false [Read(@"contact/simple/byEmail")] - public IEnumerable SearchContactsByEmail(string term, int maxCount) + public IEnumerable SearchContactsByEmail(string term, int maxCount) { - var result = ToSimpleListContactWrapper(DaoFactory.GetContactDao().SearchContactsByEmail( + var result = ToSimpleListContactDto(DaoFactory.GetContactDao().SearchContactsByEmail( term, maxCount)); @@ -426,7 +426,7 @@ public IEnumerable SearchContactsByEmail(string term, in /// /// false [Read(@"contact/simple/filter")] - public IEnumerable GetSimpleContacts( + public IEnumerable GetSimpleContacts( IEnumerable tags, int? contactStage, int? contactType, @@ -436,7 +436,7 @@ public IEnumerable GetSimpleContacts( ApiDateTime fromDate, ApiDateTime toDate) { - IEnumerable result; + IEnumerable result; OrderBy contactsOrderBy; @@ -463,7 +463,7 @@ public IEnumerable GetSimpleContacts( if (contactsOrderBy != null) { - result = ToSimpleListContactWrapper(DaoFactory.GetContactDao().GetContacts( + result = ToSimpleListContactDto(DaoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -482,7 +482,7 @@ public IEnumerable GetSimpleContacts( } else { - result = ToSimpleListContactWrapper(DaoFactory.GetContactDao().GetContacts( + result = ToSimpleListContactDto(DaoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -535,13 +535,13 @@ public IEnumerable GetSimpleContacts( /// /// false [Read(@"contact/mail")] - public IEnumerable GetContactsForMail(IEnumerable contactids) + public IEnumerable GetContactsForMail(IEnumerable contactids) { if (contactids == null) throw new ArgumentException(); var contacts = DaoFactory.GetContactDao().GetContacts(contactids.ToArray()); - var result = contacts.Select(x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); + var result = contacts.Select(x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); return result; } @@ -562,7 +562,7 @@ public IEnumerable GetContactsForMail(IEnumerable [Delete(@"contact/filter")] - public IEnumerable DeleteBatchContacts( + public IEnumerable DeleteBatchContacts( IEnumerable tags, int? contactStage, int? contactType, @@ -590,7 +590,7 @@ public IEnumerable DeleteBatchContacts( MessageService.Send(MessageAction.ContactsDeleted, MessageTarget.Create(contacts.Select(c => c.ID)), contacts.Select(c => c.GetTitle())); - return contacts.Select(x => ContactWrapperHelper.GetContactBaseWrapper(x)); + return contacts.Select(x => ContactDtoHelper.GetContactBaseDto(x)); } @@ -605,14 +605,14 @@ public IEnumerable DeleteBatchContacts( /// Linked persons /// [Read(@"contact/company/{companyid:int}/person")] - public IEnumerable GetPeopleFromCompany(int companyid) + public IEnumerable GetPeopleFromCompany(int companyid) { if (companyid <= 0) throw new ArgumentException(); var company = DaoFactory.GetContactDao().GetByID(companyid); if (company == null || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); - return ToListContactWrapper(DaoFactory.GetContactDao().GetMembers(companyid).Where(CRMSecurity.CanAccessTo).ToList()); + return ToListContactDto(DaoFactory.GetContactDao().GetMembers(companyid).Where(CRMSecurity.CanAccessTo).ToList()); } /// @@ -628,7 +628,7 @@ public IEnumerable GetPeopleFromCompany(int companyid) /// Person /// [Create(@"contact/company/{companyid:int}/person")] - public PersonWrapper AddPeopleToCompany(int companyid, int personid) + public PersonDto AddPeopleToCompany(int companyid, int personid) { if ((companyid <= 0) || (personid <= 0)) throw new ArgumentException(); @@ -641,7 +641,7 @@ public PersonWrapper AddPeopleToCompany(int companyid, int personid) MessageService.Send(MessageAction.CompanyLinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); - return (PersonWrapper)ContactWrapperHelper.GetContactWrapper(person); + return (PersonDto)ContactDtoHelper.GetContactDto(person); } /// @@ -657,7 +657,7 @@ public PersonWrapper AddPeopleToCompany(int companyid, int personid) /// Person /// [Delete(@"contact/company/{companyid:int}/person")] - public PersonWrapper DeletePeopleFromCompany(int companyid, int personid) + public PersonDto DeletePeopleFromCompany(int companyid, int personid) { if ((companyid <= 0) || (personid <= 0)) throw new ArgumentException(); @@ -669,7 +669,7 @@ public PersonWrapper DeletePeopleFromCompany(int companyid, int personid) MessageService.Send(MessageAction.CompanyUnlinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); - return (PersonWrapper)ContactWrapperHelper.GetContactWrapper(person); + return (PersonDto)ContactDtoHelper.GetContactDto(person); } /// @@ -689,7 +689,7 @@ public PersonWrapper DeletePeopleFromCompany(int companyid, int personid) /// Person /// [Create(@"contact/person")] - public PersonWrapper CreatePerson([FromForm] CreateOrUpdatePersonInDto intDto) + public PersonDto CreatePerson([FromForm] CreateOrUpdatePersonInDto intDto) { string firstName = intDto.FirstName; string lastName = intDto.LastName; @@ -736,7 +736,7 @@ public PersonWrapper CreatePerson([FromForm] CreateOrUpdatePersonInDto intDto) } } - var outDto = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); + var outDto = (PersonDto)ContactDtoHelper.GetContactDto(peopleInst); var photoList = photo != null ? photo.ToList() : new List(); @@ -827,7 +827,7 @@ public string ChangeContactPhoto(int contactid, string photourl) /// Contact /// [Update(@"contact/merge")] - public ContactWrapper MergeContacts(int fromcontactid, int tocontactid) + public ContactDto MergeContacts(int fromcontactid, int tocontactid) { if (fromcontactid <= 0 || tocontactid <= 0) throw new ArgumentException(); @@ -844,7 +844,7 @@ public ContactWrapper MergeContacts(int fromcontactid, int tocontactid) var messageAction = resultContact is Person ? MessageAction.PersonsMerged : MessageAction.CompaniesMerged; MessageService.Send(messageAction, MessageTarget.Create(new[] { fromContact.ID, toContact.ID }), fromContact.GetTitle(), toContact.GetTitle()); - return ContactWrapperHelper.GetContactWrapper(resultContact); + return ContactDtoHelper.GetContactDto(resultContact); } /// @@ -866,7 +866,7 @@ public ContactWrapper MergeContacts(int fromcontactid, int tocontactid) /// /// [Update(@"contact/person/{personid:int}")] - public PersonWrapper UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdatePersonInDto inDto) + public PersonDto UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdatePersonInDto inDto) { string firstName = inDto.FirstName; string lastName = inDto.LastName; @@ -911,7 +911,7 @@ public PersonWrapper UpdatePerson([FromQuery] int personid, [FromForm] CreateOrU } } - var outDto = (PersonWrapper)ContactWrapperHelper.GetContactWrapper(peopleInst); + var outDto = (PersonDto)ContactDtoHelper.GetContactDto(peopleInst); var photoList = photo != null ? photo.ToList() : new List(); @@ -940,7 +940,7 @@ public PersonWrapper UpdatePerson([FromQuery] int personid, [FromForm] CreateOrU /// Company /// [Create(@"contact/company")] - public CompanyWrapper CreateCompany( + public CompanyDto CreateCompany( [FromForm] CreateOrUpdateCompanyInDto inDto) { var personList = inDto.PersonList; @@ -989,7 +989,7 @@ public CompanyWrapper CreateCompany( } } - var wrapper = (CompanyWrapper)ContactWrapperHelper.GetContactWrapper(companyInst); + var wrapper = (CompanyDto)ContactDtoHelper.GetContactDto(companyInst); var photoList = photo != null ? photo.ToList() : new List(); if (photoList.Any()) @@ -1013,7 +1013,7 @@ public CompanyWrapper CreateCompany( /// Contact list /// [Create(@"contact/company/quick")] - public IEnumerable CreateCompany(IEnumerable companyName) + public IEnumerable CreateCompany(IEnumerable companyName) { if (companyName == null) throw new ArgumentException(); @@ -1043,7 +1043,7 @@ public IEnumerable CreateCompany(IEnumerable company CRMSecurity.SetAccessTo(ct, selectedManagers); } - return contacts.ConvertAll(x => ContactWrapperHelper.GetContactBaseWrapper(x)); + return contacts.ConvertAll(x => ContactDtoHelper.GetContactBaseDto(x)); } /// @@ -1063,7 +1063,7 @@ public IEnumerable CreateCompany(IEnumerable company /// Contact list /// [Create(@"contact/person/quick")] - public IEnumerable CreatePerson(IEnumerable> data) + public IEnumerable CreatePerson(IEnumerable> data) { if (data == null) return null; @@ -1096,7 +1096,7 @@ public IEnumerable CreatePerson(IEnumerable x.ID)), contacts.Select(x => x.GetTitle())); - return contacts.ConvertAll(x => ContactWrapperHelper.GetContactBaseWrapper(x)); + return contacts.ConvertAll(x => ContactDtoHelper.GetContactBaseDto(x)); } /// @@ -1115,7 +1115,7 @@ public IEnumerable CreatePerson(IEnumerable [Update(@"contact/company/{companyid:int}")] - public CompanyWrapper UpdateCompany( + public CompanyDto UpdateCompany( [FromQuery]int companyid, [FromForm] CreateOrUpdateCompanyInDto intDto) { @@ -1156,7 +1156,7 @@ public CompanyWrapper UpdateCompany( MessageService.Send(MessageAction.CompanyUpdated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return (CompanyWrapper)ContactWrapperHelper.GetContactWrapper(companyInst); + return (CompanyDto)ContactDtoHelper.GetContactDto(companyInst); } /// @@ -1172,7 +1172,7 @@ public CompanyWrapper UpdateCompany( /// Company /// [Update(@"contact/{contactid:int}/status")] - public ContactWrapper UpdateContactStatus(int contactid, int contactStatusid) + public ContactDto UpdateContactStatus(int contactid, int contactStatusid) { if (contactid <= 0 || contactStatusid < 0) throw new ArgumentException(); @@ -1195,7 +1195,7 @@ public ContactWrapper UpdateContactStatus(int contactid, int contactStatusid) var messageAction = companyInst is Company ? MessageAction.CompanyUpdatedTemperatureLevel : MessageAction.PersonUpdatedTemperatureLevel; MessageService.Send(messageAction, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return ContactWrapperHelper.GetContactWrapper(companyInst); + return ContactDtoHelper.GetContactDto(companyInst); } /// @@ -1211,7 +1211,7 @@ public ContactWrapper UpdateContactStatus(int contactid, int contactStatusid) /// Company /// [Update(@"contact/company/{companyid:int}/status")] - public ContactWrapper UpdateCompanyAndParticipantsStatus(int companyid, int contactStatusid) + public ContactDto UpdateCompanyAndParticipantsStatus(int companyid, int contactStatusid) { if (companyid <= 0 || contactStatusid < 0) throw new ArgumentException(); @@ -1245,7 +1245,7 @@ public ContactWrapper UpdateCompanyAndParticipantsStatus(int companyid, int cont MessageService.Send(MessageAction.CompanyUpdatedTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); MessageService.Send(MessageAction.CompanyUpdatedPersonsTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return ContactWrapperHelper.GetContactWrapper(companyInst); + return ContactDtoHelper.GetContactDto(companyInst); } /// @@ -1261,7 +1261,7 @@ public ContactWrapper UpdateCompanyAndParticipantsStatus(int companyid, int cont /// Person /// [Update(@"contact/person/{personid:int}/status")] - public ContactWrapper UpdatePersonAndItsCompanyStatus(int personid, int contactStatusid) + public ContactDto UpdatePersonAndItsCompanyStatus(int personid, int contactStatusid) { if (personid <= 0 || contactStatusid < 0) throw new ArgumentException(); @@ -1316,7 +1316,7 @@ public ContactWrapper UpdatePersonAndItsCompanyStatus(int personid, int contactS MessageService.Send(MessageAction.PersonUpdatedCompanyTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); personInst = dao.GetByID(personInst.ID); - return ContactWrapperHelper.GetContactWrapper(personInst); + return ContactDtoHelper.GetContactDto(personInst); } /// @@ -1360,7 +1360,7 @@ public IEnumerable GetContactAccessList(int contactid) /// Contact /// [Update(@"contact/{contactid:int}/access")] - public ContactWrapper SetAccessToContact(int contactid, bool isShared, IEnumerable managerList) + public ContactDto SetAccessToContact(int contactid, bool isShared, IEnumerable managerList) { if (contactid <= 0) throw new ArgumentException(); @@ -1371,7 +1371,7 @@ public ContactWrapper SetAccessToContact(int contactid, bool isShared, IEnumerab SetAccessToContact(contact, isShared, managerList, false); - var wrapper = ContactWrapperHelper.GetContactWrapper(contact); + var wrapper = ContactDtoHelper.GetContactDto(contact); return wrapper; } @@ -1416,7 +1416,7 @@ private void SetAccessToContact(Contact contact, bool isShared, IEnumerable [Update(@"contact/access")] - public IEnumerable SetAccessToBatchContact( + public IEnumerable SetAccessToBatchContact( [FromBody]SetAccessToBatchContactInDto inDto) { var contactid = inDto.ContactID; @@ -1425,12 +1425,12 @@ public IEnumerable SetAccessToBatchContact( if (contactid == null) throw new ArgumentException(); - var result = new List(); + var result = new List(); foreach (var id in contactid) { - var contactWrapper = SetAccessToContact(id, isShared, managerList); - result.Add(contactWrapper); + var contactDto = SetAccessToContact(id, isShared, managerList); + result.Add(contactDto); } return result; @@ -1455,7 +1455,7 @@ public IEnumerable SetAccessToBatchContact( /// Contact list /// [Update(@"contact/filter/access")] - public IEnumerable SetAccessToBatchContact( + public IEnumerable SetAccessToBatchContact( [FromForm] SetAccessToBatchContactByFilterInDto inDto) { IEnumerable tags = inDto.Tags; @@ -1482,7 +1482,7 @@ public IEnumerable SetAccessToBatchContact( 0, 0, null); if (!contacts.Any()) - return Enumerable.Empty(); + return Enumerable.Empty(); foreach (var contact in contacts) { @@ -1495,7 +1495,7 @@ public IEnumerable SetAccessToBatchContact( result.Add(contact); } - return ToListContactWrapper(result); + return ToListContactDto(result); } /// @@ -1510,7 +1510,7 @@ public IEnumerable SetAccessToBatchContact( /// Contact /// [Delete(@"contact/{contactid:int}")] - public ContactWrapper DeleteContact(int contactid) + public ContactDto DeleteContact(int contactid) { if (contactid <= 0) throw new ArgumentException(); @@ -1520,7 +1520,7 @@ public ContactWrapper DeleteContact(int contactid) var messageAction = contact is Person ? MessageAction.PersonDeleted : MessageAction.CompanyDeleted; MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - return ContactWrapperHelper.GetContactWrapper(contact); + return ContactDtoHelper.GetContactDto(contact); } /// @@ -1535,14 +1535,14 @@ public ContactWrapper DeleteContact(int contactid) /// Contact list /// [Update(@"contact")] - public IEnumerable DeleteBatchContacts(IEnumerable contactids) + public IEnumerable DeleteBatchContacts(IEnumerable contactids) { if (contactids == null) throw new ArgumentException(); var contacts = DaoFactory.GetContactDao().DeleteBatchContact(contactids.ToArray()); MessageService.Send(MessageAction.ContactsDeleted, MessageTarget.Create(contactids), contacts.Select(c => c.GetTitle())); - return contacts.Select(x => ContactWrapperHelper.GetContactBaseWrapper(x)); + return contacts.Select(x => ContactDtoHelper.GetContactBaseDto(x)); } /// @@ -1558,9 +1558,9 @@ public IEnumerable DeleteBatchContacts(IEnumerable cont /// /// false [Read(@"contact/byprefix")] - public IEnumerable GetContactsByPrefix(string prefix, int searchType, EntityType entityType, int entityID) + public IEnumerable GetContactsByPrefix(string prefix, int searchType, EntityType entityType, int entityID) { - var result = new List(); + var result = new List(); var allContacts = new List(); if (entityID > 0) @@ -1597,7 +1597,7 @@ public IEnumerable GetContactsByPrefix(string prefi } } } - result.AddRange(findedContacts.Select(x => ContactWrapperHelper.GetContactBaseWithPhoneWrapper(x))); + result.AddRange(findedContacts.Select(x => ContactDtoHelper.GetContactBaseWithPhoneDto(x))); ApiContext.SetTotalCount(findedContacts.Count); @@ -1609,7 +1609,7 @@ public IEnumerable GetContactsByPrefix(string prefi allContacts = DaoFactory.GetContactDao().GetContactsByPrefix(prefix, searchType, 0, maxItemCount); - result.AddRange(allContacts.Select(x => ContactWrapperHelper.GetContactBaseWithPhoneWrapper(x))); + result.AddRange(allContacts.Select(x => ContactDtoHelper.GetContactBaseWithPhoneDto(x))); } @@ -1629,13 +1629,13 @@ public IEnumerable GetContactsByPrefix(string prefi /// Contact list /// [Read(@"contact/bycontactinfo")] - public IEnumerable GetContactsByContactInfo(ContactInfoType? infoType, String data, int? category, bool? isPrimary) + public IEnumerable GetContactsByContactInfo(ContactInfoType? infoType, String data, int? category, bool? isPrimary) { if (!infoType.HasValue) throw new ArgumentException(); var ids = DaoFactory.GetContactDao().GetContactIDsByContactInfo(infoType.Value, data, category, isPrimary); - var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => ContactWrapperHelper.GetContactWrapper(x)); + var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => ContactDtoHelper.GetContactDto(x)); return result; } @@ -1786,7 +1786,7 @@ public string DeleteContactAvatar(int contactId, string contactType, bool upload ///// Contacts ///// //[Create(@"contact/socialmediaavatar")] - //public List GetContactSMImagesByNetworks(List socialNetworks) + //public List GetContactSMImagesByNetworks(List socialNetworks) //{ // if (socialNetworks == null || socialNetworks.Count == 0) // { @@ -1913,18 +1913,18 @@ private ContactPhotoManager.PhotoData UploadAvatar(int contactID, string imageUr return ContactPhotoManager.UploadPhotoToTemp(imageUrl, tmpDirName, checkFormat); } - private IEnumerable ToSimpleListContactWrapper(IReadOnlyList itemList) + private IEnumerable ToSimpleListContactDto(IReadOnlyList itemList) { - if (itemList.Count == 0) return new List(); + if (itemList.Count == 0) return new List(); - var result = new List(); + var result = new List(); var personsIDs = new List(); var companyIDs = new List(); var contactIDs = new int[itemList.Count]; var peopleCompanyIDs = new List(); - var peopleCompanyList = new Dictionary(); + var peopleCompanyList = new Dictionary(); var contactDao = DaoFactory.GetContactDao(); @@ -1955,17 +1955,17 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly if (peopleCompanyIDs.Count > 0) { - var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactWrapperHelper.GetContactBaseWrapperQuick(item)); + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactDtoHelper.GetContactBaseDtoQuick(item)); var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); - foreach (var contactBaseWrapperQuick in tmpList) + foreach (var contactBaseDtoQuick in tmpList) { - contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.Id]; - peopleCompanyList.Add(contactBaseWrapperQuick.Id, contactBaseWrapperQuick); + contactBaseDtoQuick.CanDelete = contactBaseDtoQuick.CanEdit && tmpListCanDelete[contactBaseDtoQuick.Id]; + peopleCompanyList.Add(contactBaseDtoQuick.Id, contactBaseDtoQuick); } } - var contactInfos = new Dictionary>(); + var contactInfos = new Dictionary>(); var addresses = new Dictionary>(); @@ -1990,11 +1990,11 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly { if (!contactInfos.ContainsKey(item.ContactID)) { - contactInfos.Add(item.ContactID, new List { ContactInfoWrapperHelper.Get(item) }); + contactInfos.Add(item.ContactID, new List { ContactInfoDtoHelper.Get(item) }); } else { - contactInfos[item.ContactID].Add(ContactInfoWrapperHelper.Get(item)); + contactInfos[item.ContactID].Add(ContactInfoDtoHelper.Get(item)); } } } @@ -2002,37 +2002,37 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly var nearestTasks = DaoFactory.GetTaskDao().GetNearestTask(contactIDs.ToArray()); - IEnumerable taskCategories = new List(); + IEnumerable taskCategories = new List(); if (nearestTasks.Any()) { - taskCategories = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => TaskCategoryWrapperHelper.Get(item)); + taskCategories = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => TaskCategoryDtoHelper.Get(item)); } foreach (var contact in itemList) { - ContactWrapper contactWrapper; + ContactDto contactDto; var person = contact as Person; if (person != null) { var people = person; - var peopleWrapper = ContactWrapperHelper.GetPersonWrapperQuick(people); + var peopleDto = ContactDtoHelper.GetPersonDtoQuick(people); if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) { - peopleWrapper.Company = peopleCompanyList[people.CompanyID]; + peopleDto.Company = peopleCompanyList[people.CompanyID]; } - contactWrapper = peopleWrapper; + contactDto = peopleDto; } else { var company = contact as Company; if (company != null) { - contactWrapper = ContactWrapperHelper.GetCompanyWrapperQuick(company); + contactDto = ContactDtoHelper.GetCompanyDtoQuick(company); } else { @@ -2040,26 +2040,26 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly } } - contactWrapper.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); + contactDto.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); - TaskBaseWrapper taskWrapper = null; + TaskBaseDto taskDto = null; - if (nearestTasks.ContainsKey(contactWrapper.Id)) + if (nearestTasks.ContainsKey(contactDto.Id)) { - var task = nearestTasks[contactWrapper.Id]; + var task = nearestTasks[contactDto.Id]; - taskWrapper = TaskWrapperHelper.GetTaskBaseWrapper(task); + taskDto = TaskDtoHelper.GetTaskBaseDto(task); if (task.CategoryID > 0) { - taskWrapper.Category = taskCategories.First(x => x.Id == task.CategoryID); + taskDto.Category = taskCategories.First(x => x.Id == task.CategoryID); } } - result.Add(new ContactWithTaskWrapper + result.Add(new ContactWithTaskDto { - Contact = contactWrapper, - Task = taskWrapper + Contact = contactDto, + Task = taskDto }); } @@ -2069,9 +2069,9 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly if (result.Count > 0) { var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Contact.Id).ToArray()); - foreach (var contactBaseWrapperQuick in result) + foreach (var contactBaseDtoQuick in result) { - contactBaseWrapperQuick.Contact.CanDelete = contactBaseWrapperQuick.Contact.CanEdit && resultListCanDelete[contactBaseWrapperQuick.Contact.Id]; + contactBaseDtoQuick.Contact.CanDelete = contactBaseDtoQuick.Contact.CanEdit && resultListCanDelete[contactBaseDtoQuick.Contact.Id]; } } @@ -2080,27 +2080,27 @@ private IEnumerable ToSimpleListContactWrapper(IReadOnly return result; } - private ContactWrapper ToContactWrapper(Contact contact) + private ContactDto ToContactDto(Contact contact) { - return ToListContactWrapper(new List + return ToListContactDto(new List { contact }).Single(); } - private IEnumerable ToListContactWrapper(IReadOnlyList itemList) + private IEnumerable ToListContactDto(IReadOnlyList itemList) { - if (itemList.Count == 0) return new List(); + if (itemList.Count == 0) return new List(); - var result = new List(); + var result = new List(); var personsIDs = new List(); var companyIDs = new List(); var contactIDs = new int[itemList.Count]; var peopleCompanyIDs = new List(); - var peopleCompanyList = new Dictionary(); + var peopleCompanyList = new Dictionary(); var contactDao = DaoFactory.GetContactDao(); @@ -2133,31 +2133,31 @@ private IEnumerable ToListContactWrapper(IReadOnlyList if (peopleCompanyIDs.Count > 0) { - var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactWrapperHelper.GetContactBaseWrapperQuick(item)); + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactDtoHelper.GetContactBaseDtoQuick(item)); var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); - foreach (var contactBaseWrapperQuick in tmpList) + foreach (var contactBaseDtoQuick in tmpList) { - contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && tmpListCanDelete[contactBaseWrapperQuick.Id]; - peopleCompanyList.Add(contactBaseWrapperQuick.Id, contactBaseWrapperQuick); + contactBaseDtoQuick.CanDelete = contactBaseDtoQuick.CanEdit && tmpListCanDelete[contactBaseDtoQuick.Id]; + peopleCompanyList.Add(contactBaseDtoQuick.Id, contactBaseDtoQuick); } } var companiesMembersCount = contactDao.GetMembersCount(companyIDs.Distinct().ToArray()); var contactStatusIDs = itemList.Select(item => item.StatusID).Distinct().ToArray(); - var contactInfos = new Dictionary>(); + var contactInfos = new Dictionary>(); var haveLateTask = DaoFactory.GetTaskDao().HaveLateTask(contactIDs); var contactStatus = DaoFactory.GetListItemDao() .GetItems(contactStatusIDs) - .ToDictionary(item => item.ID, item => new ContactStatusBaseWrapper(item)); + .ToDictionary(item => item.ID, item => new ContactStatusBaseDto(item)); var personsCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Person, personsIDs.ToArray()); var companyCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Company, companyIDs.ToArray()); var customFields = personsCustomFields.Union(companyCustomFields) - .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseDto)); var addresses = new Dictionary>(); var taskCount = DaoFactory.GetTaskDao().GetTasksCount(contactIDs); @@ -2177,9 +2177,9 @@ private IEnumerable ToListContactWrapper(IReadOnlyList else { if (!contactInfos.ContainsKey(item.ContactID)) - contactInfos.Add(item.ContactID, new List { ContactInfoWrapperHelper.Get(item) }); + contactInfos.Add(item.ContactID, new List { ContactInfoDtoHelper.Get(item) }); else - contactInfos[item.ContactID].Add(ContactInfoWrapperHelper.Get(item)); + contactInfos[item.ContactID].Add(ContactInfoDtoHelper.Get(item)); } } ); @@ -2187,32 +2187,32 @@ private IEnumerable ToListContactWrapper(IReadOnlyList foreach (var contact in itemList) { - ContactWrapper contactWrapper; + ContactDto contactDto; var person = contact as Person; if (person != null) { var people = person; - var peopleWrapper = ContactWrapperHelper.GetPersonWrapperQuick(people); + var peopleDto = ContactDtoHelper.GetPersonDtoQuick(people); if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) { - peopleWrapper.Company = peopleCompanyList[people.CompanyID]; + peopleDto.Company = peopleCompanyList[people.CompanyID]; } - contactWrapper = peopleWrapper; + contactDto = peopleDto; } else { var company = contact as Company; if (company != null) { - contactWrapper = ContactWrapperHelper.GetCompanyWrapperQuick(company); + contactDto = ContactDtoHelper.GetCompanyDtoQuick(company); - if (companiesMembersCount.ContainsKey(contactWrapper.Id)) + if (companiesMembersCount.ContainsKey(contactDto.Id)) { - ((CompanyWrapper)contactWrapper).PersonsCount = companiesMembersCount[contactWrapper.Id]; + ((CompanyDto)contactDto).PersonsCount = companiesMembersCount[contactDto.Id]; } } else @@ -2223,28 +2223,28 @@ private IEnumerable ToListContactWrapper(IReadOnlyList if (contactTags.ContainsKey(contact.ID)) { - contactWrapper.Tags = contactTags[contact.ID].OrderBy(x => x); + contactDto.Tags = contactTags[contact.ID].OrderBy(x => x); } if (addresses.ContainsKey(contact.ID)) { - contactWrapper.Addresses = addresses[contact.ID]; + contactDto.Addresses = addresses[contact.ID]; } - contactWrapper.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); + contactDto.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); if (contactStatus.ContainsKey(contact.StatusID)) { - contactWrapper.ContactStatus = contactStatus[contact.StatusID]; + contactDto.ContactStatus = contactStatus[contact.StatusID]; } - contactWrapper.HaveLateTasks = haveLateTask.ContainsKey(contact.ID) && haveLateTask[contact.ID]; + contactDto.HaveLateTasks = haveLateTask.ContainsKey(contact.ID) && haveLateTask[contact.ID]; - contactWrapper.CustomFields = customFields.ContainsKey(contact.ID) ? customFields[contact.ID] : new List(); + contactDto.CustomFields = customFields.ContainsKey(contact.ID) ? customFields[contact.ID] : new List(); - contactWrapper.TaskCount = taskCount.ContainsKey(contact.ID) ? taskCount[contact.ID] : 0; + contactDto.TaskCount = taskCount.ContainsKey(contact.ID) ? taskCount[contact.ID] : 0; - result.Add(contactWrapper); + result.Add(contactDto); } #region CanDelete for main contacts @@ -2252,9 +2252,9 @@ private IEnumerable ToListContactWrapper(IReadOnlyList if (result.Count > 0) { var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Id).ToArray()); - foreach (var contactBaseWrapperQuick in result) + foreach (var contactBaseDtoQuick in result) { - contactBaseWrapperQuick.CanDelete = contactBaseWrapperQuick.CanEdit && resultListCanDelete[contactBaseWrapperQuick.Id]; + contactBaseDtoQuick.CanDelete = contactBaseDtoQuick.CanEdit && resultListCanDelete[contactBaseDtoQuick.Id]; } } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs b/products/ASC.CRM/Server/Api/CRMController.CurrencyRates.cs similarity index 88% rename from products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs rename to products/ASC.CRM/Server/Api/CRMController.CurrencyRates.cs index 0d651ac1798..30bfb35d1d6 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.CurrencyRates.cs +++ b/products/ASC.CRM/Server/Api/CRMController.CurrencyRates.cs @@ -25,6 +25,7 @@ using ASC.Core.Common.Settings; +using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Resources; using ASC.MessagingSystem; @@ -51,9 +52,9 @@ public partial class CRMController /// List of currency rates /// [Read(@"currency/rates")] - public IEnumerable GetCurrencyRates() + public IEnumerable GetCurrencyRates() { - return DaoFactory.GetCurrencyRateDao().GetAll().ConvertAll(x => CurrencyRateWrapperHelper.Get(x)); + return DaoFactory.GetCurrencyRateDao().GetAll().ConvertAll(x => CurrencyRateDtoHelper.Get(x)); } /// @@ -66,13 +67,13 @@ public IEnumerable GetCurrencyRates() /// /// [Read(@"currency/rates/{id:int}")] - public CurrencyRateWrapper GetCurrencyRate(int id) + public CurrencyRateDto GetCurrencyRate(int id) { if (id <= 0) throw new ArgumentException(); var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); - return CurrencyRateWrapperHelper.Get(currencyRate); + return CurrencyRateDtoHelper.Get(currencyRate); } /// @@ -85,14 +86,14 @@ public CurrencyRateWrapper GetCurrencyRate(int id) /// /// [Read(@"currency/rates/{fromCurrency}/{toCurrency}")] - public CurrencyRateWrapper GetCurrencyRate(string fromCurrency, string toCurrency) + public CurrencyRateDto GetCurrencyRate(string fromCurrency, string toCurrency) { if (string.IsNullOrEmpty(fromCurrency) || string.IsNullOrEmpty(toCurrency)) throw new ArgumentException(); var currencyRate = DaoFactory.GetCurrencyRateDao().GetByCurrencies(fromCurrency, toCurrency); - return CurrencyRateWrapperHelper.Get(currencyRate); + return CurrencyRateDtoHelper.Get(currencyRate); } /// @@ -102,7 +103,7 @@ public CurrencyRateWrapper GetCurrencyRate(string fromCurrency, string toCurrenc /// Common /// [Create(@"currency/rates")] - public CurrencyRateWrapper CreateCurrencyRate(string fromCurrency, string toCurrency, decimal rate) + public CurrencyRateDto CreateCurrencyRate(string fromCurrency, string toCurrency, decimal rate) { ValidateRate(rate); @@ -118,7 +119,7 @@ public CurrencyRateWrapper CreateCurrencyRate(string fromCurrency, string toCurr currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); - return CurrencyRateWrapperHelper.Get(currencyRate); + return CurrencyRateDtoHelper.Get(currencyRate); } /// @@ -128,7 +129,7 @@ public CurrencyRateWrapper CreateCurrencyRate(string fromCurrency, string toCurr /// Common /// [Update(@"currency/rates/{id:int}")] - public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, string toCurrency, decimal rate) + public CurrencyRateDto UpdateCurrencyRate(int id, string fromCurrency, string toCurrency, decimal rate) { if (id <= 0) throw new ArgumentException(); @@ -149,7 +150,7 @@ public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, strin currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); - return CurrencyRateWrapperHelper.Get(currencyRate); + return CurrencyRateDtoHelper.Get(currencyRate); } /// @@ -159,7 +160,7 @@ public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, strin /// Common /// [Create(@"currency/setrates")] - public List SetCurrencyRates(String currency, List rates) + public List SetCurrencyRates(String currency, List rates) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); @@ -190,7 +191,7 @@ public List SetCurrencyRates(String currency, List CurrencyRateWrapperHelper.Get(x)).ToList(); + return rates.Select(x => CurrencyRateDtoHelper.Get(x)).ToList(); } /// @@ -200,7 +201,7 @@ public List SetCurrencyRates(String currency, ListCommon /// [Create(@"currency/addrates")] - public List AddCurrencyRates(List rates) + public List AddCurrencyRates(List rates) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); @@ -232,7 +233,7 @@ public List AddCurrencyRates(List rates) existingRates.Add(rate); } - return existingRates.Select(x => CurrencyRateWrapperHelper.Get(x)).ToList(); + return existingRates.Select(x => CurrencyRateDtoHelper.Get(x)).ToList(); } /// @@ -242,7 +243,7 @@ public List AddCurrencyRates(List rates) /// Common /// [Delete(@"currency/rates/{id:int}")] - public CurrencyRateWrapper DeleteCurrencyRate(int id) + public CurrencyRateDto DeleteCurrencyRate(int id) { if (id <= 0) throw new ArgumentException(); @@ -254,7 +255,7 @@ public CurrencyRateWrapper DeleteCurrencyRate(int id) DaoFactory.GetCurrencyRateDao().Delete(id); - return CurrencyRateWrapperHelper.Get(currencyRate); + return CurrencyRateDtoHelper.Get(currencyRate); } private void ValidateCurrencyRates(IEnumerable rates) diff --git a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs b/products/ASC.CRM/Server/Api/CRMController.CustomFields.cs similarity index 91% rename from products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs rename to products/ASC.CRM/Server/Api/CRMController.CustomFields.cs index 64c46ae111a..e8d122c6282 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.CustomFields.cs +++ b/products/ASC.CRM/Server/Api/CRMController.CustomFields.cs @@ -24,7 +24,7 @@ */ -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Entities; @@ -54,9 +54,9 @@ public partial class CRMController /// /// [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/definitions")] - public IEnumerable GetCustomFieldDefinitions(string entityType) + public IEnumerable GetCustomFieldDefinitions(string entityType) { - return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldWrapper); + return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldDto); } /// @@ -68,9 +68,9 @@ public IEnumerable GetCustomFieldDefinitions(string entityTy /// User fields /// [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield")] - public IEnumerable GetCustomFieldForSubject(string entityType, int entityid) + public IEnumerable GetCustomFieldForSubject(string entityType, int entityid) { - return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseWrapper); + return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseDto); } /// @@ -86,7 +86,7 @@ public IEnumerable GetCustomFieldForSubject(string entit /// User field /// [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")] - public CustomFieldBaseWrapper SetEntityCustomFieldValue(string entityType, int entityid, int fieldid, string fieldValue) + public CustomFieldBaseDto SetEntityCustomFieldValue(string entityType, int entityid, int fieldid, string fieldValue) { var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); @@ -97,7 +97,7 @@ public CustomFieldBaseWrapper SetEntityCustomFieldValue(string entityType, int e DaoFactory.GetCustomFieldDao().SetFieldValue(entityTypeStr, entityid, fieldid, fieldValue); - return ToCustomFieldBaseWrapper(customField); + return ToCustomFieldBaseDto(customField); } /// @@ -193,7 +193,7 @@ public CustomFieldBaseWrapper SetEntityCustomFieldValue(string entityType, int e /// ]]> /// [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield")] - public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label, int fieldType, int position, string mask) + public CustomFieldDto CreateCustomFieldValue(string entityType, string label, int fieldType, int position, string mask) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); var entityTypeObj = ToEntityType(entityType); @@ -203,7 +203,7 @@ public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label var messageAction = GetCustomFieldCreatedAction(entityTypeObj); MessageService.Send(messageAction, MessageTarget.Create(wrapper.ID), wrapper.Label); - return ToCustomFieldWrapper(DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); + return ToCustomFieldDto(DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); } /// @@ -231,7 +231,7 @@ public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label /// /// [Update(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/{id:int}")] - public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, string label, int fieldType, int position, string mask) + public CustomFieldDto UpdateCustomFieldValue(int id, string entityType, string label, int fieldType, int position, string mask) { if (id <= 0) throw new ArgumentException(); if (!DaoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException(); @@ -255,7 +255,7 @@ public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, stri var messageAction = GetCustomFieldUpdatedAction(entityTypeObj); MessageService.Send(messageAction, MessageTarget.Create(customField.ID), customField.Label); - return ToCustomFieldWrapper(customField); + return ToCustomFieldDto(customField); } /// @@ -271,7 +271,7 @@ public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, stri /// User field /// [Delete(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/{fieldid:int}")] - public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) + public CustomFieldDto DeleteCustomField(string entityType, int fieldid) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); if (fieldid <= 0) throw new ArgumentException(); @@ -279,7 +279,7 @@ public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); if (customField == null) throw new ItemNotFoundException(); - var result = ToCustomFieldWrapper(customField); + var result = ToCustomFieldDto(customField); DaoFactory.GetCustomFieldDao().DeleteField(fieldid); @@ -302,7 +302,7 @@ public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid) /// /// [Update(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/reorder")] - public IEnumerable UpdateCustomFieldsOrder(IEnumerable fieldids, string entityType) + public IEnumerable UpdateCustomFieldsOrder(IEnumerable fieldids, string entityType) { if (fieldids == null) throw new ArgumentException(); if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -319,17 +319,17 @@ public IEnumerable UpdateCustomFieldsOrder(IEnumerable x.Label)); - return customFields.Select(ToCustomFieldBaseWrapper); + return customFields.Select(ToCustomFieldBaseDto); } - private static CustomFieldBaseWrapper ToCustomFieldBaseWrapper(CustomField customField) + private static CustomFieldBaseDto ToCustomFieldBaseDto(CustomField customField) { - return new CustomFieldBaseWrapper(customField); + return new CustomFieldBaseDto(customField); } - private CustomFieldWrapper ToCustomFieldWrapper(CustomField customField) + private CustomFieldDto ToCustomFieldDto(CustomField customField) { - var result = new CustomFieldWrapper(customField) + var result = new CustomFieldDto(customField) { RelativeItemsCount = DaoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID) }; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs b/products/ASC.CRM/Server/Api/CRMController.Deals.cs similarity index 89% rename from products/ASC.CRM/Server/Controllers/CRMController.Deals.cs rename to products/ASC.CRM/Server/Api/CRMController.Deals.cs index cd818be6a39..a575642516d 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Deals.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Deals.cs @@ -26,7 +26,7 @@ using ASC.Api.Collections; using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.Core; using ASC.Core.Users; @@ -42,7 +42,7 @@ using System.Collections.Generic; using System.Linq; using ASC.CRM.Classes; -using ASC.CRM.Model; + namespace ASC.Api.CRM { @@ -60,14 +60,14 @@ public partial class CRMController /// /// [Read(@"opportunity/{opportunityid:int}")] - public OpportunityWrapper GetDealByID(int opportunityid) + public OpportunityDto GetDealByID(int opportunityid) { if (opportunityid <= 0) throw new ArgumentException(); var deal = DaoFactory.GetDealDao().GetByID(opportunityid); if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); - return OpportunityWrapperHelper.Get(deal); + return OpportunityDtoHelper.Get(deal); } /// @@ -83,7 +83,7 @@ public OpportunityWrapper GetDealByID(int opportunityid) /// /// [Update(@"opportunity/{opportunityid:int}/stage/{id:int}")] - public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) + public OpportunityDto UpdateToDealMilestone(int opportunityid, int stageid) { if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException(); @@ -100,7 +100,7 @@ public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) DaoFactory.GetDealDao().EditDeal(deal); MessageService.Send(MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); - return OpportunityWrapperHelper.Get(deal); + return OpportunityDtoHelper.Get(deal); } /// @@ -117,7 +117,7 @@ public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid) /// Opportunity /// [Update(@"opportunity/{opportunityid:int}/access")] - public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) + public OpportunityDto SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable accessList) { if (opportunityid <= 0) throw new ArgumentException(); @@ -128,7 +128,7 @@ public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEn return SetAccessToDeal(deal, isPrivate, accessList, false, true); } - private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) + private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessList, bool isNotify, bool isMessageServicSende) { var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List(); if (isPrivate && accessListLocal.Count > 0) @@ -162,7 +162,7 @@ private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerabl } } - return OpportunityWrapperHelper.Get(deal); + return OpportunityDtoHelper.Get(deal); } /// @@ -186,7 +186,7 @@ private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerabl /// Opportunity list /// [Update(@"opportunity/filter/access")] - public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealByFilterInDto inDto) + public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealByFilterInDto inDto) { var responsibleid = inDto.Responsibleid; var opportunityStagesid = inDto.OpportunityStagesid; @@ -211,7 +211,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDeal contactAlsoIsParticipant, fromDate, toDate, 0, 0, null); - if (!deals.Any()) return Enumerable.Empty(); + if (!deals.Any()) return Enumerable.Empty(); foreach (var deal in deals) { @@ -225,7 +225,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDeal } - return ToListOpportunityWrapper(result); + return ToListOpportunityDto(result); } /// @@ -242,7 +242,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDeal /// Opportunity list /// [Update(@"opportunity/access")] - public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealInDto inDto) + public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealInDto inDto) { var opportunityid = inDto.Opportunityid; var isPrivate = inDto.isPrivate; @@ -254,7 +254,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDeal var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); - if (!deals.Any()) return new List(); + if (!deals.Any()) return new List(); foreach (var d in deals) { @@ -266,7 +266,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDeal result.Add(d); } - return ToListOpportunityWrapper(result); + return ToListOpportunityDto(result); } @@ -282,14 +282,14 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDeal /// Opportunity list /// [Update(@"opportunity")] - public IEnumerable DeleteBatchDeals(IEnumerable opportunityids) + public IEnumerable DeleteBatchDeals(IEnumerable opportunityids) { if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); - return ToListOpportunityWrapper(opportunities); + return ToListOpportunityDto(opportunities); } /// @@ -311,7 +311,7 @@ public IEnumerable DeleteBatchDeals(IEnumerable opportu /// Opportunity list /// [Delete(@"opportunity/filter")] - public IEnumerable DeleteBatchDeals( + public IEnumerable DeleteBatchDeals( Guid responsibleid, int opportunityStagesid, IEnumerable tags, @@ -330,12 +330,12 @@ public IEnumerable DeleteBatchDeals( contactAlsoIsParticipant, fromDate, toDate, 0, 0, null); - if (!deals.Any()) return Enumerable.Empty(); + if (!deals.Any()) return Enumerable.Empty(); deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals); MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); - return ToListOpportunityWrapper(deals); + return ToListOpportunityDto(deals); } /// @@ -355,7 +355,7 @@ public IEnumerable DeleteBatchDeals( /// Opportunity list /// [Read(@"opportunity/filter")] - public IEnumerable GetDeals( + public IEnumerable GetDeals( Guid responsibleid, int opportunityStagesid, IEnumerable tags, @@ -367,7 +367,7 @@ public IEnumerable GetDeals( { DealSortedByType dealSortedByType; - IEnumerable result; + IEnumerable result; var searchString = ApiContext.FilterValue; @@ -391,7 +391,7 @@ public IEnumerable GetDeals( if (dealsOrderBy != null) { - result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( + result = ToListOpportunityDto(DaoFactory.GetDealDao().GetDeals( searchString, responsibleid, opportunityStagesid, @@ -411,7 +411,7 @@ public IEnumerable GetDeals( } else { - result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals( + result = ToListOpportunityDto(DaoFactory.GetDealDao().GetDeals( searchString, responsibleid, opportunityStagesid, @@ -463,7 +463,7 @@ public IEnumerable GetDeals( /// Opportunity /// [Delete(@"opportunity/{opportunityid:int}")] - public OpportunityWrapper DeleteDeal(int opportunityid) + public OpportunityDto DeleteDeal(int opportunityid) { if (opportunityid <= 0) throw new ArgumentException(); @@ -472,7 +472,7 @@ public OpportunityWrapper DeleteDeal(int opportunityid) MessageService.Send(MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); - return OpportunityWrapperHelper.Get(deal); + return OpportunityDtoHelper.Get(deal); } /// @@ -502,7 +502,7 @@ public OpportunityWrapper DeleteDeal(int opportunityid) /// /// [Create(@"opportunity")] - public OpportunityWrapper CreateDeal(CreateOrUpdateDealInDto inDto) + public OpportunityDto CreateDeal(CreateOrUpdateDealInDto inDto) { var title = inDto.Title; @@ -570,7 +570,7 @@ public OpportunityWrapper CreateDeal(CreateOrUpdateDealInDto inDto) } } - return OpportunityWrapperHelper.Get(deal); + return OpportunityDtoHelper.Get(deal); } /// @@ -601,7 +601,7 @@ public OpportunityWrapper CreateDeal(CreateOrUpdateDealInDto inDto) /// /// [Update(@"opportunity/{opportunityid:int}")] - public OpportunityWrapper UpdateDeal( + public OpportunityDto UpdateDeal( int opportunityid, CreateOrUpdateDealInDto inDto) { @@ -670,7 +670,7 @@ public OpportunityWrapper UpdateDeal( } } - return OpportunityWrapperHelper.Get(deal); + return OpportunityDtoHelper.Get(deal); } /// @@ -683,16 +683,16 @@ public OpportunityWrapper UpdateDeal( /// /// [Read(@"opportunity/{opportunityid:int}/contact")] - public IEnumerable GetDealMembers(int opportunityid) + public IEnumerable GetDealMembers(int opportunityid) { var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); - if (contactIDs == null) return new ItemList(); + if (contactIDs == null) return new ItemList(); - var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); + var result = ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); @@ -711,7 +711,7 @@ public IEnumerable GetDealMembers(int opportunityid) /// Participant /// [Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] - public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) + public ContactDto AddMemberToDeal(int opportunityid, int contactid) { if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); @@ -721,7 +721,7 @@ public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ToContactWrapper(contact); + var result = ToContactDto(contact); DaoFactory.GetDealDao().AddMember(opportunityid, contactid); @@ -744,7 +744,7 @@ public ContactWrapper AddMemberToDeal(int opportunityid, int contactid) /// Participant /// [Delete(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] - public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) + public ContactDto DeleteMemberFromDeal(int opportunityid, int contactid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -754,7 +754,7 @@ public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ToContactWrapper(contact); + var result = ToContactDto(contact); DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); @@ -776,9 +776,9 @@ public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid) /// /// false [Read(@"opportunity/byprefix")] - public IEnumerable GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true) + public IEnumerable GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true) { - var result = new List(); + var result = new List(); if (contactID > 0 && internalSearch) { @@ -787,7 +787,7 @@ public IEnumerable GetDealsByPrefix(string prefix, int conta { if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) { - result.Add(OpportunityWrapperHelper.Get(item)); + result.Add(OpportunityDtoHelper.Get(item)); } } @@ -799,7 +799,7 @@ public IEnumerable GetDealsByPrefix(string prefix, int conta var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); foreach (var item in findedDeals) { - result.Add(OpportunityWrapperHelper.Get(item)); + result.Add(OpportunityDtoHelper.Get(item)); } } @@ -816,10 +816,10 @@ public IEnumerable GetDealsByPrefix(string prefix, int conta /// Opportunity list /// [Read(@"opportunity/bycontact/{contactid:int}")] - public IEnumerable GetDeals(int contactid) + public IEnumerable GetDeals(int contactid) { var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid); - return ToListOpportunityWrapper(deals); + return ToListOpportunityDto(deals); } /// false @@ -849,11 +849,11 @@ public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDat } - private IEnumerable ToListOpportunityWrapper(ICollection deals) + private IEnumerable ToListOpportunityDto(ICollection deals) { - if (deals == null || deals.Count == 0) return new List(); + if (deals == null || deals.Count == 0) return new List(); - var result = new List(); + var result = new List(); var contactIDs = new List(); var dealIDs = new List(); @@ -868,14 +868,14 @@ private IEnumerable ToListOpportunityWrapper(ICollection(); + var contacts = new Dictionary(); var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper)); + .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseDto)); var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) - .ToDictionary(item => item.ID, item => new DealMilestoneBaseWrapper(item)); + .ToDictionary(item => item.ID, item => new DealMilestoneBaseDto(item)); var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); @@ -892,45 +892,45 @@ private IEnumerable ToListOpportunityWrapper(ICollection { if (item == null) return; - contacts.Add(item.ID, ContactWrapperHelper.GetContactBaseWrapper(item)); + contacts.Add(item.ID, ContactDtoHelper.GetContactBaseDto(item)); }); } foreach (var deal in deals) { - var dealWrapper = OpportunityWrapperHelper.Get(deal); + var dealDto = OpportunityDtoHelper.Get(deal); if (contacts.ContainsKey(deal.ContactID)) { - dealWrapper.Contact = contacts[deal.ContactID]; + dealDto.Contact = contacts[deal.ContactID]; } - dealWrapper.CustomFields = customFields.ContainsKey(deal.ID) + dealDto.CustomFields = customFields.ContainsKey(deal.ID) ? customFields[deal.ID] - : new List(); + : new List(); - dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.Id) - ? dealMembers[dealWrapper.Id].Where(contacts.ContainsKey).Select(item => contacts[item]) - : new List(); + dealDto.Members = dealMembers.ContainsKey(dealDto.Id) + ? dealMembers[dealDto.Id].Where(contacts.ContainsKey).Select(item => contacts[item]) + : new List(); if (dealMilestones.ContainsKey(deal.DealMilestoneID)) { - dealWrapper.Stage = dealMilestones[deal.DealMilestoneID]; + dealDto.Stage = dealMilestones[deal.DealMilestoneID]; } - dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); + dealDto.IsPrivate = CRMSecurity.IsPrivate(deal); - if (dealWrapper.IsPrivate) + if (dealDto.IsPrivate) { - dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); + dealDto.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); } if (!string.IsNullOrEmpty(deal.BidCurrency)) { - dealWrapper.BidCurrency = CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); + dealDto.BidCurrency = CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); } - result.Add(dealWrapper); + result.Add(dealDto); } return result; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs b/products/ASC.CRM/Server/Api/CRMController.Invoices.cs similarity index 93% rename from products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs rename to products/ASC.CRM/Server/Api/CRMController.Invoices.cs index 2b20cec2da5..b2ecb27692e 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Invoices.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Invoices.cs @@ -25,7 +25,7 @@ using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Api.Documents; using ASC.Common.Web; using ASC.Core; @@ -33,7 +33,7 @@ using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.CRM.Model; + using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; @@ -57,7 +57,7 @@ public partial class CRMController /// Invoices /// Invoice [Read(@"invoice/{invoiceid:int}")] - public InvoiceWrapper GetInvoiceByID(int invoiceid) + public InvoiceDto GetInvoiceByID(int invoiceid) { if (invoiceid <= 0) throw new ArgumentException(); @@ -69,7 +69,7 @@ public InvoiceWrapper GetInvoiceByID(int invoiceid) throw CRMSecurity.CreateSecurityException(); } - return InvoiceWrapperHelper.Get(invoice); + return InvoiceDtoHelper.Get(invoice); } /// @@ -79,9 +79,9 @@ public InvoiceWrapper GetInvoiceByID(int invoiceid) /// Invoices /// Invoice [Read(@"invoice/sample")] - public InvoiceWrapper GetInvoiceSample() + public InvoiceDto GetInvoiceSample() { - var sample = InvoiceWrapper.GetSample(); + var sample = InvoiceDto.GetSample(); sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; @@ -89,7 +89,7 @@ public InvoiceWrapper GetInvoiceSample() sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow); - sample.Currency = CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency); + sample.Currency = CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency); sample.InvoiceLines.First().Quantity = 1; @@ -132,7 +132,7 @@ public string GetInvoiceJsonData(int invoiceid) /// Invoices /// Invoice list [Read(@"invoice/filter")] - public IEnumerable GetInvoices( + public IEnumerable GetInvoices( InvoiceStatus? status, ApiDateTime issueDateFrom, ApiDateTime issueDateTo, @@ -149,7 +149,7 @@ String currency String.Compare(entityType, "case", true) == 0)) throw new ArgumentException(); - IEnumerable result; + IEnumerable result; InvoiceSortedByType sortBy; @@ -175,7 +175,7 @@ String currency if (invoiceOrderBy != null) { - result = ToListInvoiceBaseWrappers( + result = ToListInvoiceBaseDtos( DaoFactory.GetInvoiceDao().GetInvoices( searchString, status, @@ -192,7 +192,7 @@ String currency } else { - result = ToListInvoiceBaseWrappers( + result = ToListInvoiceBaseDtos( DaoFactory.GetInvoiceDao().GetInvoices( searchString, status, @@ -236,11 +236,11 @@ String currency /// Invoices /// Invoice list [Read(@"{entityType:regex(contact|person|company|opportunity)}/invoicelist/{entityid:int}")] - public IEnumerable GetEntityInvoices(String entityType, int entityid) + public IEnumerable GetEntityInvoices(String entityType, int entityid) { if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); - return ToListInvoiceBaseWrappers(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); + return ToListInvoiceBaseDtos(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); } /// @@ -252,7 +252,7 @@ public IEnumerable GetEntityInvoices(String entityType, int /// Invoices /// KeyValuePair of Invoices and InvoiceItems [Update(@"invoice/status/{status:int}")] - public KeyValuePair, IEnumerable> UpdateInvoiceBatchStatus( + public KeyValuePair, IEnumerable> UpdateInvoiceBatchStatus( int[] invoiceids, InvoiceStatus status ) @@ -348,9 +348,9 @@ InvoiceStatus status } } - var listInvoiceBaseWrappers = ToListInvoiceBaseWrappers(updatedInvoices); + var listInvoiceBaseDtos = ToListInvoiceBaseDtos(updatedInvoices); - return new KeyValuePair, IEnumerable>(listInvoiceBaseWrappers, invoiceItemsUpdated.ConvertAll(i => InvoiceItemWrapperHelper.Get(i))); + return new KeyValuePair, IEnumerable>(listInvoiceBaseDtos, invoiceItemsUpdated.ConvertAll(i => InvoiceItemDtoHelper.Get(i))); } /// @@ -361,7 +361,7 @@ InvoiceStatus status /// Invoices /// Invoice [Delete(@"invoice/{invoiceid:int}")] - public InvoiceBaseWrapper DeleteInvoice(int invoiceid) + public InvoiceBaseDto DeleteInvoice(int invoiceid) { if (invoiceid <= 0) throw new ArgumentException(); @@ -370,7 +370,7 @@ public InvoiceBaseWrapper DeleteInvoice(int invoiceid) MessageService.Send(MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); - return InvoiceBaseWrapperHelper.Get(invoice); + return InvoiceBaseDtoHelper.Get(invoice); } @@ -382,14 +382,14 @@ public InvoiceBaseWrapper DeleteInvoice(int invoiceid) /// Invoices /// Invoice list [Delete(@"invoice")] - public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids) + public IEnumerable DeleteBatchInvoices(IEnumerable invoiceids) { if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); MessageService.Send(MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); - return ToListInvoiceBaseWrappers(invoices); + return ToListInvoiceBaseDtos(invoices); } /// @@ -446,7 +446,7 @@ public IEnumerable DeleteBatchInvoices(IEnumerable invo /// ]]> /// [Create(@"invoice")] - public InvoiceWrapper CreateInvoice( + public InvoiceDto CreateInvoice( CreateOrUpdateInvoiceInDto inDto ) { @@ -513,7 +513,7 @@ CreateOrUpdateInvoiceInDto inDto DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - return InvoiceWrapperHelper.Get(invoice); + return InvoiceDtoHelper.Get(invoice); } @@ -617,7 +617,7 @@ private List CreateInvoiceLines(List invoiceLines, Inv /// ]]> /// [Update(@"invoice/{id:int}")] - public InvoiceWrapper UpdateInvoice( + public InvoiceDto UpdateInvoice( int id, CreateOrUpdateInvoiceInDto inDto) @@ -688,7 +688,7 @@ public InvoiceWrapper UpdateInvoice( // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); } - return InvoiceWrapperHelper.Get(invoice); + return InvoiceDtoHelper.Get(invoice); } /// @@ -820,7 +820,7 @@ public Boolean GetInvoiceByNumberExistence(string number) /// Invoices /// Invoice [Read(@"invoice/bynumber")] - public InvoiceWrapper GetInvoiceByNumber(string number) + public InvoiceDto GetInvoiceByNumber(string number) { if (String.IsNullOrEmpty(number)) throw new ArgumentException(); @@ -832,7 +832,7 @@ public InvoiceWrapper GetInvoiceByNumber(string number) throw CRMSecurity.CreateSecurityException(); } - return InvoiceWrapperHelper.Get(invoice); + return InvoiceDtoHelper.Get(invoice); } /// @@ -844,9 +844,9 @@ public InvoiceWrapper GetInvoiceByNumber(string number) /// Invoices /// InvoiceItem list [Read(@"invoiceitem/filter")] - public IEnumerable GetInvoiceItems(int status, bool? inventoryStock) + public IEnumerable GetInvoiceItems(int status, bool? inventoryStock) { - IEnumerable result; + IEnumerable result; InvoiceItemSortedByType sortBy; @@ -878,7 +878,7 @@ public IEnumerable GetInvoiceItems(int status, bool? invento inventoryStock, fromIndex, count, invoiceOrderBy) - .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); + .ConvertAll(x => InvoiceItemDtoHelper.Get(x)); ApiContext.SetDataPaginated(); ApiContext.SetDataFiltered(); @@ -892,7 +892,7 @@ public IEnumerable GetInvoiceItems(int status, bool? invento inventoryStock, 0, 0, null) - .ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); + .ConvertAll(x => InvoiceItemDtoHelper.Get(x)); } int totalCount; @@ -922,14 +922,14 @@ public IEnumerable GetInvoiceItems(int status, bool? invento /// Invoices /// Invoice Item [Read(@"invoiceitem/{invoiceitemid:int}")] - public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) + public InvoiceItemDto GetInvoiceItemByID(int invoiceitemid) { if (invoiceitemid <= 0) throw new ArgumentException(); var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); if (invoiceItem == null) throw new ItemNotFoundException(); - return InvoiceItemWrapperHelper.Get(invoiceItem); + return InvoiceItemDtoHelper.Get(invoiceItem); } /// @@ -948,7 +948,7 @@ public InvoiceItemWrapper GetInvoiceItemByID(int invoiceitemid) /// Invoices /// InvoiceLine [Create(@"invoiceline")] - public InvoiceLineWrapper CreateInvoiceLine( + public InvoiceLineDto CreateInvoiceLine( CreateOrUpdateInvoiceLineInDto inDto ) { @@ -990,7 +990,7 @@ CreateOrUpdateInvoiceLineInDto inDto // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); } - return InvoiceLineWrapperHelper.Get(invoiceLine); + return InvoiceLineDtoHelper.Get(invoiceLine); } /// @@ -1010,7 +1010,7 @@ CreateOrUpdateInvoiceLineInDto inDto /// Invoices /// InvoiceLine [Update(@"invoiceline/{id:int}")] - public InvoiceLineWrapper UpdateInvoiceLine( + public InvoiceLineDto UpdateInvoiceLine( int id, CreateOrUpdateInvoiceLineInDto inDto ) @@ -1054,7 +1054,7 @@ CreateOrUpdateInvoiceLineInDto inDto // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); } - return InvoiceLineWrapperHelper.Get(invoiceLine); + return InvoiceLineDtoHelper.Get(invoiceLine); } /// @@ -1103,7 +1103,7 @@ public int DeleteInvoiceLine(int id) /// Invoices /// InvoiceItem [Create(@"invoiceitem")] - public InvoiceItemWrapper CreateInvoiceItem( + public InvoiceItemDto CreateInvoiceItem( CreateOrUpdateInvoiceItemInDto inDto ) { @@ -1140,7 +1140,7 @@ CreateOrUpdateInvoiceItemInDto inDto MessageService.Send(MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return InvoiceItemWrapperHelper.Get(invoiceItem); + return InvoiceItemDtoHelper.Get(invoiceItem); } /// @@ -1160,7 +1160,7 @@ CreateOrUpdateInvoiceItemInDto inDto /// Invoices /// InvoiceItem [Update(@"invoiceitem/{id:int}")] - public InvoiceItemWrapper UpdateInvoiceItem(int id, + public InvoiceItemDto UpdateInvoiceItem(int id, CreateOrUpdateInvoiceItemInDto inDto ) { @@ -1199,7 +1199,7 @@ CreateOrUpdateInvoiceItemInDto inDto invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); MessageService.Send(MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return InvoiceItemWrapperHelper.Get(invoiceItem); + return InvoiceItemDtoHelper.Get(invoiceItem); } /// @@ -1210,7 +1210,7 @@ CreateOrUpdateInvoiceItemInDto inDto /// Invoices /// InvoiceItem [Delete(@"invoiceitem/{id:int}")] - public InvoiceItemWrapper DeleteInvoiceItem(int id) + public InvoiceItemDto DeleteInvoiceItem(int id) { if (!CRMSecurity.IsAdmin) { @@ -1224,7 +1224,7 @@ public InvoiceItemWrapper DeleteInvoiceItem(int id) MessageService.Send(MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return InvoiceItemWrapperHelper.Get(invoiceItem); + return InvoiceItemDtoHelper.Get(invoiceItem); } @@ -1236,7 +1236,7 @@ public InvoiceItemWrapper DeleteInvoiceItem(int id) /// Invoices /// InvoiceItem list [Delete(@"invoiceitem")] - public IEnumerable DeleteBatchItems(IEnumerable ids) + public IEnumerable DeleteBatchItems(IEnumerable ids) { if (!CRMSecurity.IsAdmin) { @@ -1249,7 +1249,7 @@ public IEnumerable DeleteBatchItems(IEnumerable ids) var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); MessageService.Send(MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); - return items.ConvertAll(x => InvoiceItemWrapperHelper.Get(x)); + return items.ConvertAll(x => InvoiceItemDtoHelper.Get(x)); } /// @@ -1259,9 +1259,9 @@ public IEnumerable DeleteBatchItems(IEnumerable ids) /// Invoices /// InvoiceTax list [Read(@"invoice/tax")] - public IEnumerable GetInvoiceTaxes() + public IEnumerable GetInvoiceTaxes() { - return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxWrapperHelper.Get(x)); + return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxDtoHelper.Get(x)); } /// @@ -1274,7 +1274,7 @@ public IEnumerable GetInvoiceTaxes() /// Invoices /// InvoiceTax [Create(@"invoice/tax")] - public InvoiceTaxWrapper CreateInvoiceTax( + public InvoiceTaxDto CreateInvoiceTax( [FromBody] CreateOrUpdateInvoiceTax inDto) { string name = inDto.Name; @@ -1299,7 +1299,7 @@ public InvoiceTaxWrapper CreateInvoiceTax( invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); MessageService.Send(MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return InvoiceTaxWrapperHelper.Get(invoiceTax); + return InvoiceTaxDtoHelper.Get(invoiceTax); } /// @@ -1313,7 +1313,7 @@ public InvoiceTaxWrapper CreateInvoiceTax( /// Invoices /// InvoiceTax [Update(@"invoice/tax/{id:int}")] - public InvoiceTaxWrapper UpdateInvoiceTax( + public InvoiceTaxDto UpdateInvoiceTax( int id, CreateOrUpdateInvoiceTax inDto) { @@ -1341,7 +1341,7 @@ public InvoiceTaxWrapper UpdateInvoiceTax( invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); MessageService.Send(MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return InvoiceTaxWrapperHelper.Get(invoiceTax); + return InvoiceTaxDtoHelper.Get(invoiceTax); } /// @@ -1352,7 +1352,7 @@ public InvoiceTaxWrapper UpdateInvoiceTax( /// Invoices /// InvoiceTax [Delete(@"invoice/tax/{id:int}")] - public InvoiceTaxWrapper DeleteInvoiceTax(int id) + public InvoiceTaxDto DeleteInvoiceTax(int id) { if (!CRMSecurity.IsAdmin) { @@ -1366,7 +1366,7 @@ public InvoiceTaxWrapper DeleteInvoiceTax(int id) MessageService.Send(MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return InvoiceTaxWrapperHelper.Get(invoiceTax); + return InvoiceTaxDtoHelper.Get(invoiceTax); } /// @@ -1467,42 +1467,42 @@ public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); } - private IEnumerable ToListInvoiceBaseWrappers(ICollection items) + private IEnumerable ToListInvoiceBaseDtos(ICollection items) { - if (items == null || items.Count == 0) return new List(); + if (items == null || items.Count == 0) return new List(); - var result = new List(); + var result = new List(); var contactIDs = items.Select(item => item.ContactID); contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID)); var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); + .ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); foreach (var invoice in items) { - var invoiceWrapper = InvoiceBaseWrapperHelper.Get(invoice); + var invoiceDto = InvoiceBaseDtoHelper.Get(invoice); if (contacts.ContainsKey(invoice.ContactID)) { - invoiceWrapper.Contact = contacts[invoice.ContactID]; + invoiceDto.Contact = contacts[invoice.ContactID]; } if (contacts.ContainsKey(invoice.ConsigneeID)) { - invoiceWrapper.Consignee = contacts[invoice.ContactID]; + invoiceDto.Consignee = contacts[invoice.ContactID]; } if (invoice.EntityID > 0) { - invoiceWrapper.Entity = ToEntityWrapper(invoice.EntityType, invoice.EntityID); //Need to optimize + invoiceDto.Entity = ToEntityDto(invoice.EntityType, invoice.EntityID); //Need to optimize } - invoiceWrapper.Cost = invoice.GetInvoiceCost(DaoFactory); + invoiceDto.Cost = invoice.GetInvoiceCost(DaoFactory); - result.Add(invoiceWrapper); + result.Add(invoiceDto); } return result; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs b/products/ASC.CRM/Server/Api/CRMController.ListItem.cs similarity index 88% rename from products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs rename to products/ASC.CRM/Server/Api/CRMController.ListItem.cs index 9a6c5e6fd41..064520e53ce 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.ListItem.cs +++ b/products/ASC.CRM/Server/Api/CRMController.ListItem.cs @@ -24,7 +24,7 @@ */ -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Entities; @@ -56,7 +56,7 @@ public partial class CRMController /// Opportunity stage /// [Create(@"opportunity/stage")] - public DealMilestoneWrapper CreateDealMilestone( + public DealMilestoneDto CreateDealMilestone( string title, string description, string color, @@ -81,7 +81,7 @@ public DealMilestoneWrapper CreateDealMilestone( dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone); MessageService.Send(MessageAction.OpportunityStageCreated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); - return ToDealMilestoneWrapper(dealMilestone); + return ToDealMilestoneDto(dealMilestone); } /// @@ -101,7 +101,7 @@ public DealMilestoneWrapper CreateDealMilestone( /// Opportunity stage /// [Update(@"opportunity/stage/{id:int}")] - public DealMilestoneWrapper UpdateDealMilestone( + public DealMilestoneDto UpdateDealMilestone( int id, string title, string description, @@ -131,7 +131,7 @@ public DealMilestoneWrapper UpdateDealMilestone( DaoFactory.GetDealMilestoneDao().Edit(dealMilestone); MessageService.Send(MessageAction.OpportunityStageUpdated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); - return ToDealMilestoneWrapper(dealMilestone); + return ToDealMilestoneDto(dealMilestone); } /// @@ -147,7 +147,7 @@ public DealMilestoneWrapper UpdateDealMilestone( /// Opportunity stage /// [Update(@"opportunity/stage/{id:int}/color")] - public DealMilestoneWrapper UpdateDealMilestoneColor(int id, string color) + public DealMilestoneDto UpdateDealMilestoneColor(int id, string color) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -161,7 +161,7 @@ public DealMilestoneWrapper UpdateDealMilestoneColor(int id, string color) DaoFactory.GetDealMilestoneDao().ChangeColor(id, color); MessageService.Send(MessageAction.OpportunityStageUpdatedColor, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); - return ToDealMilestoneWrapper(dealMilestone); + return ToDealMilestoneDto(dealMilestone); } /// @@ -179,7 +179,7 @@ public DealMilestoneWrapper UpdateDealMilestoneColor(int id, string color) /// /// [Update(@"opportunity/stage/reorder")] - public IEnumerable UpdateDealMilestonesOrder(IEnumerable ids) + public IEnumerable UpdateDealMilestonesOrder(IEnumerable ids) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -192,7 +192,7 @@ public IEnumerable UpdateDealMilestonesOrder(IEnumerable x.Title)); - return result.Select(ToDealMilestoneWrapper); + return result.Select(ToDealMilestoneDto); } /// @@ -207,7 +207,7 @@ public IEnumerable UpdateDealMilestonesOrder(IEnumerable [Delete(@"opportunity/stage/{id:int}")] - public DealMilestoneWrapper DeleteDealMilestone(int id) + public DealMilestoneDto DeleteDealMilestone(int id) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -216,7 +216,7 @@ public DealMilestoneWrapper DeleteDealMilestone(int id) var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(id); if (dealMilestone == null) throw new ItemNotFoundException(); - var result = ToDealMilestoneWrapper(dealMilestone); + var result = ToDealMilestoneDto(dealMilestone); DaoFactory.GetDealMilestoneDao().Delete(id); MessageService.Send(MessageAction.OpportunityStageDeleted, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); @@ -236,7 +236,7 @@ public DealMilestoneWrapper DeleteDealMilestone(int id) ///History category /// [Create(@"history/category")] - public HistoryCategoryWrapper CreateHistoryCategory(string title, string description, string imageName, int sortOrder) + public HistoryCategoryDto CreateHistoryCategory(string title, string description, string imageName, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -253,7 +253,7 @@ public HistoryCategoryWrapper CreateHistoryCategory(string title, string descrip listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.HistoryCategory, listItem); MessageService.Send(MessageAction.HistoryEventCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToHistoryCategoryWrapper(listItem); + return ToHistoryCategoryDto(listItem); } /// @@ -270,7 +270,7 @@ public HistoryCategoryWrapper CreateHistoryCategory(string title, string descrip /// /// [Update(@"history/category/{id:int}")] - public HistoryCategoryWrapper UpdateHistoryCategory(int id, string title, string description, string imageName, int sortOrder) + public HistoryCategoryDto UpdateHistoryCategory(int id, string title, string description, string imageName, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -291,7 +291,7 @@ public HistoryCategoryWrapper UpdateHistoryCategory(int id, string title, string DaoFactory.GetListItemDao().EditItem(ListType.HistoryCategory, listItem); MessageService.Send(MessageAction.HistoryEventCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToHistoryCategoryWrapper(listItem); + return ToHistoryCategoryDto(listItem); } /// @@ -307,7 +307,7 @@ public HistoryCategoryWrapper UpdateHistoryCategory(int id, string title, string /// History category /// [Update(@"history/category/{id:int}/icon")] - public HistoryCategoryWrapper UpdateHistoryCategoryIcon(int id, string imageName) + public HistoryCategoryDto UpdateHistoryCategoryIcon(int id, string imageName) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -321,7 +321,7 @@ public HistoryCategoryWrapper UpdateHistoryCategoryIcon(int id, string imageName DaoFactory.GetListItemDao().ChangePicture(id, imageName); MessageService.Send(MessageAction.HistoryEventCategoryUpdatedIcon, MessageTarget.Create(historyCategory.ID), historyCategory.Title); - return ToHistoryCategoryWrapper(historyCategory); + return ToHistoryCategoryDto(historyCategory); } /// @@ -339,7 +339,7 @@ public HistoryCategoryWrapper UpdateHistoryCategoryIcon(int id, string imageName /// /// [Update(@"history/category/reorder")] - public IEnumerable UpdateHistoryCategoriesOrder(IEnumerable titles) + public IEnumerable UpdateHistoryCategoriesOrder(IEnumerable titles) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -350,7 +350,7 @@ public IEnumerable UpdateHistoryCategoriesOrder(IEnumera DaoFactory.GetListItemDao().ReorderItems(ListType.HistoryCategory, titles.ToArray()); MessageService.Send(MessageAction.HistoryEventCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToHistoryCategoryWrapper); + return result.ConvertAll(ToHistoryCategoryDto); } /// @@ -364,7 +364,7 @@ public IEnumerable UpdateHistoryCategoriesOrder(IEnumera /// /// History category [Delete(@"history/category/{id:int}")] - public HistoryCategoryWrapper DeleteHistoryCategory(int id) + public HistoryCategoryDto DeleteHistoryCategory(int id) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -379,7 +379,7 @@ public HistoryCategoryWrapper DeleteHistoryCategory(int id) throw new ArgumentException("The last history category cannot be deleted"); } - var result = ToHistoryCategoryWrapper(listItem); + var result = ToHistoryCategoryDto(listItem); dao.DeleteItem(ListType.HistoryCategory, id, 0); MessageService.Send(MessageAction.HistoryEventCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); @@ -402,7 +402,7 @@ public HistoryCategoryWrapper DeleteHistoryCategory(int id) /// Task category /// [Create(@"task/category")] - public TaskCategoryWrapper CreateTaskCategory(string title, string description, string imageName, int sortOrder) + public TaskCategoryDto CreateTaskCategory(string title, string description, string imageName, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -417,7 +417,7 @@ public TaskCategoryWrapper CreateTaskCategory(string title, string description, listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.TaskCategory, listItem); MessageService.Send(MessageAction.CrmTaskCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToTaskCategoryWrapper(listItem); + return ToTaskCategoryDto(listItem); } /// @@ -438,7 +438,7 @@ public TaskCategoryWrapper CreateTaskCategory(string title, string description, /// Task category /// [Update(@"task/category/{id:int}")] - public TaskCategoryWrapper UpdateTaskCategory(int id, string title, string description, string imageName, int sortOrder) + public TaskCategoryDto UpdateTaskCategory(int id, string title, string description, string imageName, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -459,7 +459,7 @@ public TaskCategoryWrapper UpdateTaskCategory(int id, string title, string descr DaoFactory.GetListItemDao().EditItem(ListType.TaskCategory, listItem); MessageService.Send(MessageAction.CrmTaskCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToTaskCategoryWrapper(listItem); + return ToTaskCategoryDto(listItem); } /// @@ -475,7 +475,7 @@ public TaskCategoryWrapper UpdateTaskCategory(int id, string title, string descr /// Task category /// [Update(@"task/category/{id:int}/icon")] - public TaskCategoryWrapper UpdateTaskCategoryIcon(int id, string imageName) + public TaskCategoryDto UpdateTaskCategoryIcon(int id, string imageName) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -489,7 +489,7 @@ public TaskCategoryWrapper UpdateTaskCategoryIcon(int id, string imageName) DaoFactory.GetListItemDao().ChangePicture(id, imageName); MessageService.Send(MessageAction.CrmTaskCategoryUpdatedIcon, MessageTarget.Create(taskCategory.ID), taskCategory.Title); - return ToTaskCategoryWrapper(taskCategory); + return ToTaskCategoryDto(taskCategory); } /// @@ -507,7 +507,7 @@ public TaskCategoryWrapper UpdateTaskCategoryIcon(int id, string imageName) /// /// [Update(@"task/category/reorder")] - public IEnumerable UpdateTaskCategoriesOrder(IEnumerable titles) + public IEnumerable UpdateTaskCategoriesOrder(IEnumerable titles) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -518,7 +518,7 @@ public IEnumerable UpdateTaskCategoriesOrder(IEnumerable x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToTaskCategoryWrapper); + return result.ConvertAll(ToTaskCategoryDto); } /// @@ -532,7 +532,7 @@ public IEnumerable UpdateTaskCategoriesOrder(IEnumerable /// [Delete(@"task/category/{categoryid:int}")] - public TaskCategoryWrapper DeleteTaskCategory(int categoryid, int newcategoryid) + public TaskCategoryDto DeleteTaskCategory(int categoryid, int newcategoryid) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -550,7 +550,7 @@ public TaskCategoryWrapper DeleteTaskCategory(int categoryid, int newcategoryid) dao.DeleteItem(ListType.TaskCategory, categoryid, newcategoryid); MessageService.Send(MessageAction.CrmTaskCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); - return ToTaskCategoryWrapper(listItem); + return ToTaskCategoryDto(listItem); } /// @@ -568,7 +568,7 @@ public TaskCategoryWrapper DeleteTaskCategory(int categoryid, int newcategoryid) /// Contact status /// [Create(@"contact/status")] - public ContactStatusWrapper CreateContactStatus(string title, string description, string color, int sortOrder) + public ContactStatusDto CreateContactStatus(string title, string description, string color, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -583,7 +583,7 @@ public ContactStatusWrapper CreateContactStatus(string title, string description listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.ContactStatus, listItem); MessageService.Send(MessageAction.ContactTemperatureLevelCreated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToContactStatusWrapper(listItem); + return ToContactStatusDto(listItem); } /// @@ -604,7 +604,7 @@ public ContactStatusWrapper CreateContactStatus(string title, string description /// Contact status /// [Update(@"contact/status/{id:int}")] - public ContactStatusWrapper UpdateContactStatus(int id, string title, string description, string color, int sortOrder) + public ContactStatusDto UpdateContactStatus(int id, string title, string description, string color, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -625,7 +625,7 @@ public ContactStatusWrapper UpdateContactStatus(int id, string title, string des DaoFactory.GetListItemDao().EditItem(ListType.ContactStatus, listItem); MessageService.Send(MessageAction.ContactTemperatureLevelUpdated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToContactStatusWrapper(listItem); + return ToContactStatusDto(listItem); } /// @@ -641,7 +641,7 @@ public ContactStatusWrapper UpdateContactStatus(int id, string title, string des /// Contact status /// [Update(@"contact/status/{id:int}/color")] - public ContactStatusWrapper UpdateContactStatusColor(int id, string color) + public ContactStatusDto UpdateContactStatusColor(int id, string color) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -655,7 +655,7 @@ public ContactStatusWrapper UpdateContactStatusColor(int id, string color) DaoFactory.GetListItemDao().ChangeColor(id, color); MessageService.Send(MessageAction.ContactTemperatureLevelUpdatedColor, MessageTarget.Create(contactStatus.ID), contactStatus.Title); - return ToContactStatusWrapper(contactStatus); + return ToContactStatusDto(contactStatus); } /// @@ -673,7 +673,7 @@ public ContactStatusWrapper UpdateContactStatusColor(int id, string color) /// /// [Update(@"contact/status/reorder")] - public IEnumerable UpdateContactStatusesOrder(IEnumerable titles) + public IEnumerable UpdateContactStatusesOrder(IEnumerable titles) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -684,7 +684,7 @@ public IEnumerable UpdateContactStatusesOrder(IEnumerable< DaoFactory.GetListItemDao().ReorderItems(ListType.ContactStatus, titles.ToArray()); MessageService.Send(MessageAction.ContactTemperatureLevelsUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToContactStatusWrapper); + return result.ConvertAll(ToContactStatusDto); } /// @@ -700,7 +700,7 @@ public IEnumerable UpdateContactStatusesOrder(IEnumerable< /// Contact status /// [Delete(@"contact/status/{contactStatusid:int}")] - public ContactStatusWrapper DeleteContactStatus(int contactStatusid) + public ContactStatusDto DeleteContactStatus(int contactStatusid) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -715,7 +715,7 @@ public ContactStatusWrapper DeleteContactStatus(int contactStatusid) throw new ArgumentException("The last contact status cannot be deleted"); } - var contactStatus = ToContactStatusWrapper(listItem); + var contactStatus = ToContactStatusDto(listItem); dao.DeleteItem(ListType.ContactStatus, contactStatusid, 0); MessageService.Send(MessageAction.ContactTemperatureLevelDeleted, MessageTarget.Create(contactStatus.Id), contactStatus.Title); @@ -733,14 +733,14 @@ public ContactStatusWrapper DeleteContactStatus(int contactStatusid) /// /// [Read(@"contact/status/{contactStatusid:int}")] - public ContactStatusWrapper GetContactStatusByID(int contactStatusid) + public ContactStatusDto GetContactStatusByID(int contactStatusid) { if (contactStatusid <= 0) throw new ArgumentException(); var listItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); if (listItem == null) throw new ItemNotFoundException(); - return ToContactStatusWrapper(listItem); + return ToContactStatusDto(listItem); } /// @@ -756,7 +756,7 @@ public ContactStatusWrapper GetContactStatusByID(int contactStatusid) /// Contact type /// [Create(@"contact/type")] - public ContactTypeWrapper CreateContactType(string title, int sortOrder) + public ContactTypeDto CreateContactType(string title, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -770,7 +770,7 @@ public ContactTypeWrapper CreateContactType(string title, int sortOrder) listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.ContactType, listItem); MessageService.Send(MessageAction.ContactTypeCreated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToContactTypeWrapper(listItem); + return ToContactTypeDto(listItem); } /// @@ -789,7 +789,7 @@ public ContactTypeWrapper CreateContactType(string title, int sortOrder) /// Contact type /// [Update(@"contact/type/{id:int}")] - public ContactTypeWrapper UpdateContactType(int id, string title, int sortOrder) + public ContactTypeDto UpdateContactType(int id, string title, int sortOrder) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -808,7 +808,7 @@ public ContactTypeWrapper UpdateContactType(int id, string title, int sortOrder) DaoFactory.GetListItemDao().EditItem(ListType.ContactType, listItem); MessageService.Send(MessageAction.ContactTypeUpdated, MessageTarget.Create(listItem.ID), listItem.Title); - return ToContactTypeWrapper(listItem); + return ToContactTypeDto(listItem); } /// @@ -826,7 +826,7 @@ public ContactTypeWrapper UpdateContactType(int id, string title, int sortOrder) /// /// [Update(@"contact/type/reorder")] - public IEnumerable UpdateContactTypesOrder(IEnumerable titles) + public IEnumerable UpdateContactTypesOrder(IEnumerable titles) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -837,7 +837,7 @@ public IEnumerable UpdateContactTypesOrder(IEnumerable x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToContactTypeWrapper); + return result.ConvertAll(ToContactTypeDto); } /// @@ -853,7 +853,7 @@ public IEnumerable UpdateContactTypesOrder(IEnumerable [Delete(@"contact/type/{contactTypeid:int}")] - public ContactTypeWrapper DeleteContactType(int contactTypeid) + public ContactTypeDto DeleteContactType(int contactTypeid) { if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); @@ -868,7 +868,7 @@ public ContactTypeWrapper DeleteContactType(int contactTypeid) throw new ArgumentException("The last contact type cannot be deleted"); } - var contactType = ToContactTypeWrapper(listItem); + var contactType = ToContactTypeDto(listItem); dao.DeleteItem(ListType.ContactType, contactTypeid, 0); MessageService.Send(MessageAction.ContactTypeDeleted, MessageTarget.Create(listItem.ID), listItem.Title); @@ -886,14 +886,14 @@ public ContactTypeWrapper DeleteContactType(int contactTypeid) /// /// [Read(@"contact/type/{contactTypeid:int}")] - public ContactTypeWrapper GetContactTypeByID(int contactTypeid) + public ContactTypeDto GetContactTypeByID(int contactTypeid) { if (contactTypeid <= 0) throw new ArgumentException(); var listItem = DaoFactory.GetListItemDao().GetByID(contactTypeid); if (listItem == null) throw new ItemNotFoundException(); - return ToContactTypeWrapper(listItem); + return ToContactTypeDto(listItem); } /// @@ -906,14 +906,14 @@ public ContactTypeWrapper GetContactTypeByID(int contactTypeid) /// /// [Read(@"opportunity/stage/{stageid:int}")] - public DealMilestoneWrapper GetDealMilestoneByID(int stageid) + public DealMilestoneDto GetDealMilestoneByID(int stageid) { if (stageid <= 0) throw new ArgumentException(); var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(stageid); if (dealMilestone == null) throw new ItemNotFoundException(); - return ToDealMilestoneWrapper(dealMilestone); + return ToDealMilestoneDto(dealMilestone); } /// @@ -926,14 +926,14 @@ public DealMilestoneWrapper GetDealMilestoneByID(int stageid) /// /// [Read(@"task/category/{categoryid:int}")] - public TaskCategoryWrapper GetTaskCategoryByID(int categoryid) + public TaskCategoryDto GetTaskCategoryByID(int categoryid) { if (categoryid <= 0) throw new ArgumentException(); var listItem = DaoFactory.GetListItemDao().GetByID(categoryid); if (listItem == null) throw new ItemNotFoundException(); - return ToTaskCategoryWrapper(listItem); + return ToTaskCategoryDto(listItem); } /// @@ -945,9 +945,9 @@ public TaskCategoryWrapper GetTaskCategoryByID(int categoryid) /// List of all history categories /// [Read(@"history/category")] - public IEnumerable GetHistoryCategoryWrapper() + public IEnumerable GetHistoryCategoryDto() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.HistoryCategory).ConvertAll(item => new HistoryCategoryWrapper(item)); + var result = DaoFactory.GetListItemDao().GetItems(ListType.HistoryCategory).ConvertAll(item => new HistoryCategoryDto(item)); var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory); @@ -968,9 +968,9 @@ public IEnumerable GetHistoryCategoryWrapper() /// List of all task categories /// [Read(@"task/category")] - public IEnumerable GetTaskCategories() + public IEnumerable GetTaskCategories() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => (TaskCategoryWrapper)TaskCategoryWrapperHelper.Get(item)); + var result = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => (TaskCategoryDto)TaskCategoryDtoHelper.Get(item)); var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory); @@ -991,9 +991,9 @@ public IEnumerable GetTaskCategories() /// List of all contact statuses /// [Read(@"contact/status")] - public IEnumerable GetContactStatuses() + public IEnumerable GetContactStatuses() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactStatus).ConvertAll(item => new ContactStatusWrapper(item)); + var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactStatus).ConvertAll(item => new ContactStatusDto(item)); var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus); @@ -1014,9 +1014,9 @@ public IEnumerable GetContactStatuses() /// List of all contact types /// [Read(@"contact/type")] - public IEnumerable GetContactTypes() + public IEnumerable GetContactTypes() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactType).ConvertAll(item => new ContactTypeWrapper(item)); + var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactType).ConvertAll(item => new ContactTypeDto(item)); var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType); @@ -1038,9 +1038,9 @@ public IEnumerable GetContactTypes() /// List of all opportunity stages /// [Read(@"opportunity/stage")] - public IEnumerable GetDealMilestones() + public IEnumerable GetDealMilestones() { - var result = DaoFactory.GetDealMilestoneDao().GetAll().ConvertAll(item => new DealMilestoneWrapper(item)); + var result = DaoFactory.GetDealMilestoneDao().GetAll().ConvertAll(item => new DealMilestoneDto(item)); var relativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(); @@ -1053,9 +1053,9 @@ public IEnumerable GetDealMilestones() return result; } - public ContactStatusWrapper ToContactStatusWrapper(ListItem listItem) + public ContactStatusDto ToContactStatusDto(ListItem listItem) { - var result = new ContactStatusWrapper(listItem) + var result = new ContactStatusDto(listItem) { RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, listItem.ID) }; @@ -1063,9 +1063,9 @@ public ContactStatusWrapper ToContactStatusWrapper(ListItem listItem) return result; } - public ContactTypeWrapper ToContactTypeWrapper(ListItem listItem) + public ContactTypeDto ToContactTypeDto(ListItem listItem) { - var result = new ContactTypeWrapper(listItem) + var result = new ContactTypeDto(listItem) { RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, listItem.ID) }; @@ -1073,27 +1073,27 @@ public ContactTypeWrapper ToContactTypeWrapper(ListItem listItem) return result; } - public HistoryCategoryWrapper ToHistoryCategoryWrapper(ListItem listItem) + public HistoryCategoryDto ToHistoryCategoryDto(ListItem listItem) { - var result = (HistoryCategoryWrapper)HistoryCategoryWrapperHelper.Get(listItem); + var result = (HistoryCategoryDto)HistoryCategoryDtoHelper.Get(listItem); result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID); return result; } - public TaskCategoryWrapper ToTaskCategoryWrapper(ListItem listItem) + public TaskCategoryDto ToTaskCategoryDto(ListItem listItem) { - var result = (TaskCategoryWrapper)TaskCategoryWrapperHelper.Get(listItem); + var result = (TaskCategoryDto)TaskCategoryDtoHelper.Get(listItem); result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID); return result; } - private DealMilestoneWrapper ToDealMilestoneWrapper(DealMilestone dealMilestone) + private DealMilestoneDto ToDealMilestoneDto(DealMilestone dealMilestone) { - var result = new DealMilestoneWrapper(dealMilestone) + var result = new DealMilestoneDto(dealMilestone) { RelativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(dealMilestone.ID) }; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs b/products/ASC.CRM/Server/Api/CRMController.RelationshipEvent.cs similarity index 92% rename from products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs rename to products/ASC.CRM/Server/Api/CRMController.RelationshipEvent.cs index 4fdd6a61bcf..51617b96a26 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Api/CRMController.RelationshipEvent.cs @@ -25,7 +25,7 @@ using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Api.Documents; using ASC.Common.Web; using ASC.CRM.Core; @@ -71,7 +71,7 @@ public partial class CRMController /// Event list /// [Read(@"history/filter")] - public IEnumerable GetHistory( + public IEnumerable GetHistory( string entityType, int entityId, int categoryId, @@ -108,7 +108,7 @@ public IEnumerable GetHistory( RelationshipEventByType eventByType; - IEnumerable result; + IEnumerable result; OrderBy eventOrderBy; @@ -127,7 +127,7 @@ public IEnumerable GetHistory( if (eventOrderBy != null) { - result = ToListRelationshipEventWrapper(DaoFactory.GetRelationshipEventDao().GetItems( + result = ToListRelationshipEventDto(DaoFactory.GetRelationshipEventDao().GetItems( ApiContext.FilterValue, entityTypeObj, entityId, @@ -145,7 +145,7 @@ public IEnumerable GetHistory( } else { - result = ToListRelationshipEventWrapper(DaoFactory.GetRelationshipEventDao().GetItems( + result = ToListRelationshipEventDto(DaoFactory.GetRelationshipEventDao().GetItems( ApiContext.FilterValue, entityTypeObj, entityId, @@ -175,13 +175,13 @@ public IEnumerable GetHistory( /// Event /// [Delete(@"history/{id:int}")] - public RelationshipEventWrapper DeleteHistory(int id) + public RelationshipEventDto DeleteHistory(int id) { if (id <= 0) throw new ArgumentException(); var item = DaoFactory.GetRelationshipEventDao().GetByID(id); if (item == null) throw new ItemNotFoundException(); - var wrapper = RelationshipEventWrapperHelper.Get(item); + var wrapper = RelationshipEventDtoHelper.Get(item); DaoFactory.GetRelationshipEventDao().DeleteItem(id); @@ -325,7 +325,7 @@ private FileWrapper SaveFile(int folderid, Stream file, string fileName) /// Created event /// //[Create(@"history")] - //public RelationshipEventWrapper AddHistoryTo( + //public RelationshipEventDto AddHistoryTo( // string entityType, // int entityId, // int contactId, @@ -433,7 +433,7 @@ private FileWrapper SaveFile(int folderid, Stream file, string fileName) // NotifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, DaoFactory, notifyUserList.ToArray()); // } - // var wrapper = RelationshipEventWrapperHelper.Get(item); + // var wrapper = RelationshipEventDtoHelper.Get(item); // var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); // MessageService.Send( historyCreatedAction, MessageTarget.Create(item.ID), entityTitle, category.Title); @@ -453,7 +453,7 @@ private FileWrapper SaveFile(int folderid, Stream file, string fileName) /// Files /// Entity with the file attached [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files")] - public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEnumerable fileids) + public RelationshipEventDto AttachFiles(string entityType, int entityid, IEnumerable fileids) { if (entityid <= 0 || fileids == null) throw new ArgumentException(); @@ -476,15 +476,15 @@ public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEn var relationshipEvent1 = DaoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray()); var messageAction = entityObj is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return RelationshipEventWrapperHelper.Get(relationshipEvent1); + return RelationshipEventDtoHelper.Get(relationshipEvent1); case EntityType.Opportunity: var relationshipEvent2 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); MessageService.Send(MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return RelationshipEventWrapperHelper.Get(relationshipEvent2); + return RelationshipEventDtoHelper.Get(relationshipEvent2); case EntityType.Case: var relationshipEvent3 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); MessageService.Send(MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return RelationshipEventWrapperHelper.Get(relationshipEvent3); + return RelationshipEventDtoHelper.Get(relationshipEvent3); default: throw new ArgumentException(); } @@ -573,16 +573,16 @@ public FileWrapper DeleteCRMFile(int fileid) return result; } - private IEnumerable ToListRelationshipEventWrapper(List itemList) + private IEnumerable ToListRelationshipEventDto(List itemList) { - if (itemList.Count == 0) return new List(); + if (itemList.Count == 0) return new List(); - var result = new List(); + var result = new List(); var contactIDs = new List(); var eventIDs = new List(); var categoryIDs = new List(); - var entityWrappersIDs = new Dictionary>(); + var entityDtosIDs = new Dictionary>(); foreach (var item in itemList) @@ -601,34 +601,34 @@ private IEnumerable ToListRelationshipEventWrapper(Lis if (item.EntityID <= 0) continue; - if (!entityWrappersIDs.ContainsKey(item.EntityType)) + if (!entityDtosIDs.ContainsKey(item.EntityType)) { - entityWrappersIDs.Add(item.EntityType, new List + entityDtosIDs.Add(item.EntityType, new List { item.EntityID }); } - else if (!entityWrappersIDs[item.EntityType].Contains(item.EntityID)) + else if (!entityDtosIDs[item.EntityType].Contains(item.EntityID)) { - entityWrappersIDs[item.EntityType].Add(item.EntityID); + entityDtosIDs[item.EntityType].Add(item.EntityID); } } - var entityWrappers = new Dictionary(); + var entityDtos = new Dictionary(); - foreach (var entityType in entityWrappersIDs.Keys) + foreach (var entityType in entityDtosIDs.Keys) { switch (entityType) { case EntityType.Opportunity: - DaoFactory.GetDealDao().GetDeals(entityWrappersIDs[entityType].Distinct().ToArray()) + DaoFactory.GetDealDao().GetDeals(entityDtosIDs[entityType].Distinct().ToArray()) .ForEach(item => { if (item == null) return; - entityWrappers.Add( + entityDtos.Add( string.Format("{0}_{1}", (int)entityType, item.ID), - new EntityWrapper + new EntityDto { EntityId = item.ID, EntityTitle = item.Title, @@ -637,14 +637,14 @@ private IEnumerable ToListRelationshipEventWrapper(Lis }); break; case EntityType.Case: - DaoFactory.GetCasesDao().GetByID(entityWrappersIDs[entityType].ToArray()) + DaoFactory.GetCasesDao().GetByID(entityDtosIDs[entityType].ToArray()) .ForEach(item => { if (item == null) return; - entityWrappers.Add( + entityDtos.Add( string.Format("{0}_{1}", (int)entityType, item.ID), - new EntityWrapper + new EntityDto { EntityId = item.ID, EntityTitle = item.Title, @@ -657,15 +657,15 @@ private IEnumerable ToListRelationshipEventWrapper(Lis } } - var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => HistoryCategoryWrapperHelper.Get(x)); + var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => HistoryCategoryDtoHelper.Get(x)); var files = DaoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray()); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWrapper(x)); + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseDto(x)); foreach (var item in itemList) { - var eventObjWrap = RelationshipEventWrapperHelper.Get(item); + var eventObjWrap = RelationshipEventDtoHelper.Get(item); if (contacts.ContainsKey(item.ContactID)) { @@ -676,9 +676,9 @@ private IEnumerable ToListRelationshipEventWrapper(Lis { var entityStrKey = string.Format("{0}_{1}", (int)item.EntityType, item.EntityID); - if (entityWrappers.ContainsKey(entityStrKey)) + if (entityDtos.ContainsKey(entityStrKey)) { - eventObjWrap.Entity = entityWrappers[entityStrKey]; + eventObjWrap.Entity = entityDtos[entityStrKey]; } } @@ -696,11 +696,11 @@ private IEnumerable ToListRelationshipEventWrapper(Lis return result; } - private EntityWrapper ToEntityWrapper(EntityType entityType, int entityID) + private EntityDto ToEntityDto(EntityType entityType, int entityID) { if (entityID == 0) return null; - var result = new EntityWrapper + var result = new EntityDto { EntityId = entityID }; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Reports.cs b/products/ASC.CRM/Server/Api/CRMController.Reports.cs similarity index 100% rename from products/ASC.CRM/Server/Controllers/CRMController.Reports.cs rename to products/ASC.CRM/Server/Api/CRMController.Reports.cs diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs b/products/ASC.CRM/Server/Api/CRMController.Tag.cs similarity index 99% rename from products/ASC.CRM/Server/Controllers/CRMController.Tag.cs rename to products/ASC.CRM/Server/Api/CRMController.Tag.cs index f1823625b21..fbed5a94322 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Tag.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Tag.cs @@ -25,7 +25,7 @@ using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Entities; @@ -141,7 +141,7 @@ public string CreateTag(string entityType, string tagName) /// /// [Read(@"{entityType:regex(contact|opportunity|case)}/tag")] - public IEnumerable GetAllTags(string entityType) + public IEnumerable GetAllTags(string entityType) { if (string.IsNullOrEmpty(entityType)) throw new ArgumentException(); var entType = ToEntityType(entityType); @@ -150,10 +150,10 @@ public IEnumerable GetAllTags(string entityType) var relativeItemsCountArrayJSON = DaoFactory.GetTagDao().GetTagsLinkCount(entType).ToList(); if (tagTitles.Count != relativeItemsCountArrayJSON.Count) throw new ArgumentException(); - var result = new List(); + var result = new List(); for (var i = 0; i < tagTitles.Count; i++) { - result.Add(new TagWrapper(tagTitles[i], relativeItemsCountArrayJSON[i])); + result.Add(new TagDto(tagTitles[i], relativeItemsCountArrayJSON[i])); } return result.OrderBy(x => x.Title.Trim(), StringComparer.OrdinalIgnoreCase).ToList(); } diff --git a/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs b/products/ASC.CRM/Server/Api/CRMController.TaskTemplate.cs similarity index 87% rename from products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs rename to products/ASC.CRM/Server/Api/CRMController.TaskTemplate.cs index 649815618cd..f6dd867fd7e 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.TaskTemplate.cs +++ b/products/ASC.CRM/Server/Api/CRMController.TaskTemplate.cs @@ -24,7 +24,7 @@ */ -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.CRM.Core.Entities; using ASC.Web.Api.Routing; @@ -50,7 +50,7 @@ public partial class CRMController /// /// false [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/tasktemplatecontainer")] - public TaskTemplateContainerWrapper CreateTaskTemplateContainer(string entityType, string title) + public TaskTemplateContainerDto CreateTaskTemplateContainer(string entityType, string title) { if (string.IsNullOrEmpty(title)) throw new ArgumentException(); @@ -61,7 +61,7 @@ public TaskTemplateContainerWrapper CreateTaskTemplateContainer(string entityTyp }; taskTemplateContainer.ID = DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(taskTemplateContainer); - return ToTaskTemplateContainerWrapper(taskTemplateContainer); + return ToTaskTemplateContainerDto(taskTemplateContainer); } /// @@ -75,9 +75,9 @@ public TaskTemplateContainerWrapper CreateTaskTemplateContainer(string entityTyp /// /// false [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/tasktemplatecontainer")] - public IEnumerable GetTaskTemplateContainers(string entityType) + public IEnumerable GetTaskTemplateContainers(string entityType) { - return ToTaskListTemplateContainerWrapper(DaoFactory.GetTaskTemplateContainerDao().GetItems(ToEntityType(entityType))); + return ToTaskListTemplateContainerDto(DaoFactory.GetTaskTemplateContainerDao().GetItems(ToEntityType(entityType))); } /// @@ -93,11 +93,11 @@ public IEnumerable GetTaskTemplateContainers(strin /// /// false [Delete(@"tasktemplatecontainer/{containerid:int}")] - public TaskTemplateContainerWrapper DeleteTaskTemplateContainer(int containerid) + public TaskTemplateContainerDto DeleteTaskTemplateContainer(int containerid) { if (containerid <= 0) throw new ArgumentException(); - var result = ToTaskTemplateContainerWrapper(DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid)); + var result = ToTaskTemplateContainerDto(DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid)); if (result == null) throw new ItemNotFoundException(); DaoFactory.GetTaskTemplateContainerDao().Delete(containerid); @@ -119,7 +119,7 @@ public TaskTemplateContainerWrapper DeleteTaskTemplateContainer(int containerid) /// /// false [Update(@"tasktemplatecontainer/{containerid:int}")] - public TaskTemplateContainerWrapper UpdateTaskTemplateContainer(int containerid, string title) + public TaskTemplateContainerDto UpdateTaskTemplateContainer(int containerid, string title) { if (containerid <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); @@ -130,7 +130,7 @@ public TaskTemplateContainerWrapper UpdateTaskTemplateContainer(int containerid, DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(result); - return ToTaskTemplateContainerWrapper(result); + return ToTaskTemplateContainerDto(result); } /// @@ -146,14 +146,14 @@ public TaskTemplateContainerWrapper UpdateTaskTemplateContainer(int containerid, /// /// false [Read(@"tasktemplatecontainer/{containerid:int}")] - public TaskTemplateContainerWrapper GetTaskTemplateContainerByID(int containerid) + public TaskTemplateContainerDto GetTaskTemplateContainerByID(int containerid) { if (containerid <= 0) throw new ArgumentException(); var item = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); if (item == null) throw new ItemNotFoundException(); - return ToTaskTemplateContainerWrapper(item); + return ToTaskTemplateContainerDto(item); } /// @@ -169,14 +169,14 @@ public TaskTemplateContainerWrapper GetTaskTemplateContainerByID(int containerid /// /// false [Read(@"tasktemplatecontainer/{containerid:int}/tasktemplate")] - public IEnumerable GetTaskTemplates(int containerid) + public IEnumerable GetTaskTemplates(int containerid) { if (containerid <= 0) throw new ArgumentException(); var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); if (container == null) throw new ItemNotFoundException(); - return DaoFactory.GetTaskTemplateDao().GetList(containerid).ConvertAll(ToTaskTemplateWrapper); + return DaoFactory.GetTaskTemplateDao().GetList(containerid).ConvertAll(ToTaskTemplateDto); } /// @@ -197,7 +197,7 @@ public IEnumerable GetTaskTemplates(int containerid) /// /// false [Create(@"tasktemplatecontainer/{containerid:int}/tasktemplate")] - public TaskTemplateWrapper CreateTaskTemplate( + public TaskTemplateDto CreateTaskTemplate( int containerid, string title, string description, @@ -227,7 +227,7 @@ bool deadLineIsFixed item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); - return ToTaskTemplateWrapper(item); + return ToTaskTemplateDto(item); } /// @@ -249,7 +249,7 @@ bool deadLineIsFixed /// /// false [Update(@"tasktemplatecontainer/{containerid:int}/tasktemplate")] - public TaskTemplateWrapper UpdateTaskTemplate( + public TaskTemplateDto UpdateTaskTemplate( int id, int containerid, string title, @@ -284,7 +284,7 @@ bool deadLineIsFixed item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); - return ToTaskTemplateWrapper(item); + return ToTaskTemplateDto(item); } /// @@ -298,14 +298,14 @@ bool deadLineIsFixed /// /// false [Delete(@"tasktemplatecontainer/tasktemplate/{id:int}")] - public TaskTemplateWrapper DeleteTaskTemplate(int id) + public TaskTemplateDto DeleteTaskTemplate(int id) { if (id <= 0) throw new ArgumentException(); var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id); if (taskTemplate == null) throw new ItemNotFoundException(); - var result = ToTaskTemplateWrapper(taskTemplate); + var result = ToTaskTemplateDto(taskTemplate); DaoFactory.GetTaskTemplateDao().Delete(id); @@ -323,19 +323,19 @@ public TaskTemplateWrapper DeleteTaskTemplate(int id) /// /// false [Read(@"tasktemplatecontainer/tasktemplate/{id:int}")] - public TaskTemplateWrapper GetTaskTemplateByID(int id) + public TaskTemplateDto GetTaskTemplateByID(int id) { if (id <= 0) throw new ArgumentException(); var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id); if (taskTemplate == null) throw new ItemNotFoundException(); - return ToTaskTemplateWrapper(taskTemplate); + return ToTaskTemplateDto(taskTemplate); } - protected TaskTemplateWrapper ToTaskTemplateWrapper(TaskTemplate taskTemplate) + protected TaskTemplateDto ToTaskTemplateDto(TaskTemplate taskTemplate) { - return new TaskTemplateWrapper + return new TaskTemplateDto { Category = GetTaskCategoryByID(taskTemplate.CategoryID), ContainerID = taskTemplate.ContainerID, @@ -349,17 +349,17 @@ protected TaskTemplateWrapper ToTaskTemplateWrapper(TaskTemplate taskTemplate) }; } - protected IEnumerable ToTaskListTemplateContainerWrapper(IEnumerable items) + protected IEnumerable ToTaskListTemplateContainerDto(IEnumerable items) { - var result = new List(); + var result = new List(); var taskTemplateDictionary = DaoFactory.GetTaskTemplateDao().GetAll() .GroupBy(item => item.ContainerID) - .ToDictionary(x => x.Key, y => y.Select(ToTaskTemplateWrapper)); + .ToDictionary(x => x.Key, y => y.Select(ToTaskTemplateDto)); foreach (var item in items) { - var taskTemplateContainer = new TaskTemplateContainerWrapper + var taskTemplateContainer = new TaskTemplateContainerDto { Title = item.Title, EntityType = item.EntityType.ToString(), @@ -377,9 +377,9 @@ protected IEnumerable ToTaskListTemplateContainerW return result; } - protected TaskTemplateContainerWrapper ToTaskTemplateContainerWrapper(TaskTemplateContainer item) + protected TaskTemplateContainerDto ToTaskTemplateContainerDto(TaskTemplateContainer item) { - return ToTaskListTemplateContainerWrapper(new List + return ToTaskListTemplateContainerDto(new List { item }).FirstOrDefault(); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs b/products/ASC.CRM/Server/Api/CRMController.Tasks.cs similarity index 89% rename from products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs rename to products/ASC.CRM/Server/Api/CRMController.Tasks.cs index e30a6249aee..26100d65262 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Tasks.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Tasks.cs @@ -1,5 +1,5 @@ using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common.Web; using ASC.CRM.Core; using ASC.CRM.Core.Dao; @@ -29,7 +29,7 @@ public partial class CRMController /// /// [Read(@"task/{taskid:int}")] - public TaskWrapper GetTaskByID(int taskid) + public TaskDto GetTaskByID(int taskid) { if (taskid <= 0) throw new ArgumentException(); @@ -41,7 +41,7 @@ public TaskWrapper GetTaskByID(int taskid) throw CRMSecurity.CreateSecurityException(); } - return TaskWrapperHelper.GetTaskWrapper(task); + return TaskDtoHelper.GetTaskDto(task); } /// @@ -61,7 +61,7 @@ public TaskWrapper GetTaskByID(int taskid) /// Task list /// [Read(@"task/filter")] - public IEnumerable GetAllTasks( + public IEnumerable GetAllTasks( Guid responsibleid, int categoryid, bool? isClosed, @@ -82,7 +82,7 @@ public IEnumerable GetAllTasks( var searchText = ApiContext.FilterValue; - IEnumerable result; + IEnumerable result; OrderBy taskOrderBy; @@ -104,7 +104,7 @@ public IEnumerable GetAllTasks( if (taskOrderBy != null) { - result = ToTaskListWrapper( + result = ToTaskListDto( DaoFactory.GetTaskDao() .GetTasks( searchText, @@ -124,7 +124,7 @@ public IEnumerable GetAllTasks( ApiContext.SetDataSorted(); } else - result = ToTaskListWrapper( + result = ToTaskListDto( DaoFactory .GetTaskDao() .GetTasks( @@ -177,7 +177,7 @@ public IEnumerable GetAllTasks( /// Task /// [Update(@"task/{taskid:int}/reopen")] - public TaskWrapper ReOpenTask(int taskid) + public TaskDto ReOpenTask(int taskid) { if (taskid <= 0) throw new ArgumentException(); @@ -187,7 +187,7 @@ public TaskWrapper ReOpenTask(int taskid) MessageService.Send(MessageAction.CrmTaskOpened, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.GetTaskWrapper(task); + return TaskDtoHelper.GetTaskDto(task); } @@ -202,7 +202,7 @@ public TaskWrapper ReOpenTask(int taskid) /// Task /// [Update(@"task/{taskid:int}/close")] - public TaskWrapper CloseTask(int taskid) + public TaskDto CloseTask(int taskid) { if (taskid <= 0) throw new ArgumentException(); @@ -211,7 +211,7 @@ public TaskWrapper CloseTask(int taskid) var task = DaoFactory.GetTaskDao().GetByID(taskid); MessageService.Send(MessageAction.CrmTaskClosed, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.GetTaskWrapper(task); + return TaskDtoHelper.GetTaskDto(task); } @@ -227,7 +227,7 @@ public TaskWrapper CloseTask(int taskid) /// Deleted task /// [Delete(@"task/{taskid:int}")] - public TaskWrapper DeleteTask(int taskid) + public TaskDto DeleteTask(int taskid) { if (taskid <= 0) throw new ArgumentException(); @@ -237,7 +237,7 @@ public TaskWrapper DeleteTask(int taskid) DaoFactory.GetTaskDao().DeleteTask(taskid); MessageService.Send(MessageAction.CrmTaskDeleted, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.GetTaskWrapper(task); + return TaskDtoHelper.GetTaskDto(task); } @@ -259,7 +259,7 @@ public TaskWrapper DeleteTask(int taskid) /// Tasks /// Task [Create(@"task")] - public TaskWrapper CreateTask( + public TaskDto CreateTask( string title, string description, ApiDateTime deadline, @@ -328,7 +328,7 @@ int alertValue MessageService.Send(MessageAction.CrmTaskCreated, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.GetTaskWrapper(task); + return TaskDtoHelper.GetTaskDto(task); } /// @@ -350,7 +350,7 @@ int alertValue /// Tasks /// false [Create(@"contact/task/group")] - public IEnumerable CreateTaskGroup( + public IEnumerable CreateTaskGroup( string title, string description, ApiDateTime deadline, @@ -438,7 +438,7 @@ public IEnumerable CreateTaskGroup( MessageService.Send(MessageAction.ContactsCreatedCrmTasks, MessageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title); } - return ToTaskListWrapper(tasks); + return ToTaskListDto(tasks); } @@ -460,7 +460,7 @@ public IEnumerable CreateTaskGroup( /// Tasks /// Task [Update(@"task/{taskid:int}")] - public TaskWrapper UpdateTask( + public TaskDto UpdateTask( int taskid, string title, string description, @@ -528,7 +528,7 @@ public TaskWrapper UpdateTask( MessageService.Send(MessageAction.CrmTaskUpdated, MessageTarget.Create(task.ID), task.Title); - return TaskWrapperHelper.GetTaskWrapper(task); + return TaskDtoHelper.GetTaskDto(task); } /// false @@ -557,14 +557,14 @@ public void SetTaskLastModifedDate(int taskId, ApiDateTime lastModifedDate) dao.SetTaskLastModifedDate(taskId, lastModifedDate); } - private IEnumerable ToTaskListWrapper(IEnumerable itemList) + private IEnumerable ToTaskListDto(IEnumerable itemList) { - var result = new List(); + var result = new List(); var contactIDs = new List(); var taskIDs = new List(); var categoryIDs = new List(); - var entityWrappersIDs = new Dictionary>(); + var entityDtosIDs = new Dictionary>(); foreach (var item in itemList) { @@ -584,35 +584,35 @@ private IEnumerable ToTaskListWrapper(IEnumerable itemList) { if (item.EntityType != EntityType.Opportunity && item.EntityType != EntityType.Case) continue; - if (!entityWrappersIDs.ContainsKey(item.EntityType)) + if (!entityDtosIDs.ContainsKey(item.EntityType)) { - entityWrappersIDs.Add(item.EntityType, new List + entityDtosIDs.Add(item.EntityType, new List { item.EntityID }); } - else if (!entityWrappersIDs[item.EntityType].Contains(item.EntityID)) + else if (!entityDtosIDs[item.EntityType].Contains(item.EntityID)) { - entityWrappersIDs[item.EntityType].Add(item.EntityID); + entityDtosIDs[item.EntityType].Add(item.EntityID); } } } - var entityWrappers = new Dictionary(); + var entityDtos = new Dictionary(); - foreach (var entityType in entityWrappersIDs.Keys) + foreach (var entityType in entityDtosIDs.Keys) { switch (entityType) { case EntityType.Opportunity: - DaoFactory.GetDealDao().GetDeals(entityWrappersIDs[entityType].Distinct().ToArray()) + DaoFactory.GetDealDao().GetDeals(entityDtosIDs[entityType].Distinct().ToArray()) .ForEach(item => { if (item == null) return; - entityWrappers.Add( + entityDtos.Add( string.Format("{0}_{1}", (int)entityType, item.ID), - new EntityWrapper + new EntityDto { EntityId = item.ID, EntityTitle = item.Title, @@ -621,14 +621,14 @@ private IEnumerable ToTaskListWrapper(IEnumerable itemList) }); break; case EntityType.Case: - DaoFactory.GetCasesDao().GetByID(entityWrappersIDs[entityType].ToArray()) + DaoFactory.GetCasesDao().GetByID(entityDtosIDs[entityType].ToArray()) .ForEach(item => { if (item == null) return; - entityWrappers.Add( + entityDtos.Add( string.Format("{0}_{1}", (int)entityType, item.ID), - new EntityWrapper + new EntityDto { EntityId = item.ID, EntityTitle = item.Title, @@ -639,45 +639,45 @@ private IEnumerable ToTaskListWrapper(IEnumerable itemList) } } - var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => TaskCategoryWrapperHelper.Get(x)); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); - var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactWrapperHelper.GetContactBaseWithEmailWrapper(x)); + var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => TaskCategoryDtoHelper.Get(x)); + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); + var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); foreach (var item in itemList) { - var taskWrapper = TaskWrapperHelper.GetTaskWrapper(item); - taskWrapper.CanEdit = CRMSecurity.CanEdit(item); + var taskDto = TaskDtoHelper.GetTaskDto(item); + taskDto.CanEdit = CRMSecurity.CanEdit(item); if (contacts.ContainsKey(item.ContactID)) { - taskWrapper.Contact = contacts[item.ContactID]; + taskDto.Contact = contacts[item.ContactID]; } if (restrictedContacts.ContainsKey(item.ContactID)) { - taskWrapper.Contact = restrictedContacts[item.ContactID]; + taskDto.Contact = restrictedContacts[item.ContactID]; /*Hide some fields. Should be refactored! */ - taskWrapper.Contact.Currency = null; - taskWrapper.Contact.Email = null; - taskWrapper.Contact.AccessList = null; + taskDto.Contact.Currency = null; + taskDto.Contact.Email = null; + taskDto.Contact.AccessList = null; } if (item.EntityID > 0) { var entityStrKey = string.Format("{0}_{1}", (int)item.EntityType, item.EntityID); - if (entityWrappers.ContainsKey(entityStrKey)) + if (entityDtos.ContainsKey(entityStrKey)) { - taskWrapper.Entity = entityWrappers[entityStrKey]; + taskDto.Entity = entityDtos[entityStrKey]; } } if (categories.ContainsKey(item.CategoryID)) { - taskWrapper.Category = categories[item.CategoryID]; + taskDto.Category = categories[item.CategoryID]; } - result.Add(taskWrapper); + result.Add(taskDto); } return result; diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs b/products/ASC.CRM/Server/Api/CRMController.Utils.cs similarity index 97% rename from products/ASC.CRM/Server/Controllers/CRMController.Utils.cs rename to products/ASC.CRM/Server/Api/CRMController.Utils.cs index f6af9cc1b1b..c2f96ea1a12 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Utils.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Utils.cs @@ -25,6 +25,7 @@ using ASC.Common.Threading.Progress; +using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -52,9 +53,9 @@ public partial class CRMController /// List of available currencies /// [Read(@"settings/currency")] - public IEnumerable GetAvaliableCurrency() + public IEnumerable GetAvaliableCurrency() { - return CurrencyProvider.GetAll().ConvertAll(item => CurrencyInfoWrapperHelper.Get(item)); + return CurrencyProvider.GetAll().ConvertAll(item => CurrencyInfoDtoHelper.Get(item)); } /// @@ -85,9 +86,9 @@ public Decimal ConvertAmount(Decimal amount, String fromcurrency, String tocurre /// /// [Read(@"settings/currency/summarytable")] - public IEnumerable GetSummaryTable(String currency) + public IEnumerable GetSummaryTable(String currency) { - var result = new List(); + var result = new List(); if (string.IsNullOrEmpty(currency)) { @@ -98,7 +99,7 @@ public IEnumerable GetSummaryTable(String currency) if (cur == null) throw new ArgumentException(); var table = CurrencyProvider.MoneyConvert(cur); - table.ToList().ForEach(tableItem => result.Add(CurrencyRateInfoWrapperHelper.Get(tableItem.Key, tableItem.Value))); + table.ToList().ForEach(tableItem => result.Add(CurrencyRateInfoDtoHelper.Get(tableItem.Key, tableItem.Value))); return result; } @@ -372,7 +373,7 @@ public string ChangeWebToLeadFormKey() /// /// [Update(@"settings/currency")] - public CurrencyInfoWrapper UpdateCRMCurrency(String currency) + public CurrencyInfoDto UpdateCRMCurrency(String currency) { if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); @@ -387,7 +388,7 @@ public CurrencyInfoWrapper UpdateCRMCurrency(String currency) Global.SaveDefaultCurrencySettings(cur); MessageService.Send(MessageAction.CrmDefaultCurrencyUpdated); - return CurrencyInfoWrapperHelper.Get(cur); + return CurrencyInfoDtoHelper.Get(cur); } /// false diff --git a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs b/products/ASC.CRM/Server/Api/CRMController.Voip.cs similarity index 93% rename from products/ASC.CRM/Server/Controllers/CRMController.Voip.cs rename to products/ASC.CRM/Server/Api/CRMController.Voip.cs index df97dca0e7c..ef7e14cf397 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.Voip.cs +++ b/products/ASC.CRM/Server/Api/CRMController.Voip.cs @@ -25,7 +25,7 @@ //using ASC.Api.Core; -//using ASC.Api.CRM.Wrappers; +//using ASC.CRM.ApiModels; //using ASC.Api.Utils; //using ASC.Common.Web; //using ASC.Core.Tenants; @@ -595,7 +595,7 @@ // /// // /// // [Create(@"voip/call")] -// public VoipCallWrapper MakeCall(string to, string contactId) +// public VoipCallDto MakeCall(string to, string contactId) // { // var number = DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); // if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); @@ -607,14 +607,14 @@ // if (contact == null) // { -// contact = ContactWrapperHelper.GetContactWrapper(VoipEngine.CreateContact(contactPhone)); +// contact = ContactDtoHelper.GetContactDto(VoipEngine.CreateContact(contactPhone)); // } // contact = GetContactWithFotos(contact); // var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); -// return VoipCallWrapperHelper.Get(call, contact); +// return VoipCallDtoHelper.Get(call, contact); // } @@ -625,7 +625,7 @@ // /// Voip // /// // [Create(@"voip/call/{callId:\w+}/answer")] -// public VoipCallWrapper AnswerCall(string callId) +// public VoipCallDto AnswerCall(string callId) // { // var dao = DaoFactory.GetVoipDao(); // var call = dao.GetCall(callId).NotFoundIfNull(); @@ -633,7 +633,7 @@ // number.AnswerQueueCall(call.Id); -// return VoipCallWrapperHelper.Get(call); +// return VoipCallDtoHelper.Get(call); // } @@ -644,13 +644,13 @@ // /// Voip // /// // [Create(@"voip/call/{callId:\w+}/reject")] -// public VoipCallWrapper RejectCall(string callId) +// public VoipCallDto RejectCall(string callId) // { // var dao = DaoFactory.GetVoipDao(); // var call = dao.GetCall(callId).NotFoundIfNull(); // var number = dao.GetCurrentNumber().NotFoundIfNull(); // number.RejectQueueCall(call.Id); -// return VoipCallWrapperHelper.Get(call); +// return VoipCallDtoHelper.Get(call); // } // /// @@ -660,7 +660,7 @@ // /// Voip // /// // [Create(@"voip/call/{callId:\w+}/redirect")] -// public VoipCallWrapper ReditectCall(string callId, string to) +// public VoipCallDto ReditectCall(string callId, string to) // { // var dao = DaoFactory.GetVoipDao(); // var call = dao.GetCall(callId).NotFoundIfNull(); @@ -679,7 +679,7 @@ // } // number.RedirectCall(call.Id, to); -// return VoipCallWrapperHelper.Get(call); +// return VoipCallDtoHelper.Get(call); // } // /// @@ -689,7 +689,7 @@ // /// Voip // /// // [Create(@"voip/call/{callId:\w+}")] -// public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) +// public VoipCallDto SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) // { // var dao = DaoFactory.GetVoipDao(); @@ -743,17 +743,17 @@ // call = dao.SaveOrUpdateCall(call); -// if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); +// if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); // try // { // var contact = GetContactByID(call.ContactId); // contact = GetContactWithFotos(contact); -// return VoipCallWrapperHelper.Get(call, contact); +// return VoipCallDtoHelper.Get(call, contact); // } // catch (Exception) // { -// return VoipCallWrapperHelper.Get(call); +// return VoipCallDtoHelper.Get(call); // } // } @@ -777,7 +777,7 @@ // /// Voip // /// // [Read(@"voip/call")] -// public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) +// public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) // { // var voipDao = DaoFactory.GetVoipDao(); @@ -805,13 +805,13 @@ // var calls = voipDao.GetCalls(filter).Select( // r => // { -// ContactWrapper contact; +// ContactDto contact; // if (r.ContactId != 0) // { // contact = r.ContactIsCompany -// ? (ContactWrapper)new CompanyWrapper() {DisplayName = r.ContactTitle, Id = r.ContactId } -// : new PersonWrapper() { +// ? (ContactDto)new CompanyDto() {DisplayName = r.ContactTitle, Id = r.ContactId } +// : new PersonDto() { // DisplayName = r.ContactTitle, // Id = r.ContactId // }; @@ -821,10 +821,10 @@ // } // else // { -// contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; +// contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; // } -// return VoipCallWrapperHelper.Get(r, contact); +// return VoipCallDtoHelper.Get(r, contact); // }).ToList(); @@ -838,7 +838,7 @@ // /// Voip // /// // [Read(@"voip/call/missed")] -// public IEnumerable GetMissedCalls() +// public IEnumerable GetMissedCalls() // { // var voipDao = DaoFactory.GetVoipDao(); // var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); @@ -846,23 +846,23 @@ // var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( // r => // { -// ContactWrapper contact; +// ContactDto contact; // if (r.ContactId != 0) // { // contact = r.ContactIsCompany -// ? (ContactWrapper)new CompanyWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId } -// : new PersonWrapper() { DisplayName = r.ContactTitle, Id = r.ContactId }; +// ? (ContactDto)new CompanyDto() { DisplayName = r.ContactTitle, Id = r.ContactId } +// : new PersonDto() { DisplayName = r.ContactTitle, Id = r.ContactId }; // contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); // } // else // { -// contact = new PersonWrapper() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; +// contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; // } -// return VoipCallWrapperHelper.Get(r, contact); +// return VoipCallDtoHelper.Get(r, contact); // }).ToList(); @@ -881,21 +881,21 @@ // /// Voip // /// // [Read(@"voip/call/{callId:\w+}")] -// public VoipCallWrapper GetCall(string callId) +// public VoipCallDto GetCall(string callId) // { // var call = DaoFactory.GetVoipDao().GetCall(callId); // VoipEngine.GetContact(call); -// if (call.ContactId == 0) return VoipCallWrapperHelper.Get(call); +// if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); // var contact = GetContactByID(call.ContactId); // contact = GetContactWithFotos(contact); -// return VoipCallWrapperHelper.Get(call, contact); +// return VoipCallDtoHelper.Get(call, contact); // } -// private ContactWrapper GetContactWithFotos(ContactWrapper contact) +// private ContactDto GetContactWithFotos(ContactDto contact) // { // contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); // contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Api/CRMController.cs similarity index 74% rename from products/ASC.CRM/Server/Controllers/CRMController.cs rename to products/ASC.CRM/Server/Api/CRMController.cs index b88fd836ac1..fc346fbdec6 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.cs +++ b/products/ASC.CRM/Server/Api/CRMController.cs @@ -1,5 +1,5 @@ using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Api.Documents; using ASC.Common; using ASC.Common.Web; @@ -45,7 +45,7 @@ public CRMController(CRMSecurity cRMSecurity, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - TaskWrapperHelper taskWrapperHelper, + TaskDtoHelper taskDtoHelper, SecurityContext securityContext, UserManager userManager, UserFormatter userFormatter, @@ -63,7 +63,7 @@ public CRMController(CRMSecurity cRMSecurity, IHttpContextAccessor httpContextAccessor, InvoiceSetting invoiceSetting, OrganisationLogoManager organisationLogoManager, - ContactWrapperHelper contactBaseWrapperHelper, + ContactDtoHelper contactBaseDtoHelper, ContactPhotoManager contactPhotoManager, CommonLinkUtility commonLinkUtility, StorageFactory storageFactory, @@ -76,24 +76,24 @@ public CRMController(CRMSecurity cRMSecurity, FileWrapperHelper fileWrapperHelper, DisplayUserSettingsHelper displayUserSettingsHelper, - OpportunityWrapperHelper opportunityWrapperHelper, + OpportunityDtoHelper opportunityDtoHelper, EmployeeWraperHelper employeeWraperHelper, ApiDateTimeHelper apiDateTimeHelper, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper, - CurrencyRateInfoWrapperHelper currencyRateInfoWrapperHelper, - CurrencyRateWrapperHelper currencyRateWrapperHelper, - CasesWrapperHelper casesWrapperHelper, - InvoiceWrapperHelper invoiceWrapperHelper, - InvoiceItemWrapperHelper invoiceItemWrapperHelper, - InvoiceBaseWrapperHelper invoiceBaseWrapperHelper, - InvoiceLineWrapperHelper invoiceLineWrapperHelper, - InvoiceTaxWrapperHelper invoiceTaxWrapperHelper, - ContactInfoWrapperHelper contactInfoWrapperHelper, - HistoryCategoryWrapperHelper historyCategoryBaseWrapperHelper, - TaskCategoryWrapperHelper taskCategoryWrapperHelper, - VoipCallWrapperHelper voipCallWrapperHelper, + CurrencyInfoDtoHelper currencyInfoDtoHelper, + CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, + CurrencyRateDtoHelper currencyRateDtoHelper, + CasesDtoHelper casesDtoHelper, + InvoiceDtoHelper invoiceDtoHelper, + InvoiceItemDtoHelper invoiceItemDtoHelper, + InvoiceBaseDtoHelper invoiceBaseDtoHelper, + InvoiceLineDtoHelper invoiceLineDtoHelper, + InvoiceTaxDtoHelper invoiceTaxDtoHelper, + ContactInfoDtoHelper contactInfoDtoHelper, + HistoryCategoryDtoHelper historyCategoryBaseDtoHelper, + TaskCategoryDtoHelper taskCategoryDtoHelper, + VoipCallDtoHelper voipCallDtoHelper, - RelationshipEventWrapperHelper relationshipEventWrapperHelper, + RelationshipEventDtoHelper relationshipEventDtoHelper, DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper, FactoryIndexerContactInfo factoryIndexerContactInfo, @@ -119,30 +119,30 @@ public CRMController(CRMSecurity cRMSecurity, MessageTarget = messageTarget; MessageService = messageService; NotifyClient = notifyClient; - TaskWrapperHelper = taskWrapperHelper; + TaskDtoHelper = taskDtoHelper; SecurityContext = securityContext; UserManager = userManager; UserFormatter = userFormatter; CurrencyProvider = currencyProvider; - OpportunityWrapperHelper = opportunityWrapperHelper; + OpportunityDtoHelper = opportunityDtoHelper; EmployeeWraperHelper = employeeWraperHelper; ApiDateTimeHelper = apiDateTimeHelper; - CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; - CurrencyRateInfoWrapperHelper = currencyRateInfoWrapperHelper; - CurrencyRateWrapperHelper = currencyRateWrapperHelper; - CasesWrapperHelper = casesWrapperHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; + CurrencyRateDtoHelper = currencyRateDtoHelper; + CasesDtoHelper = casesDtoHelper; ServiceProvider = serviceProvider; FactoryIndexerCase = factoryIndexerCase; FactoryIndexerFieldValue = factoryIndexerFieldValue; FactoryIndexerContactInfo = factoryIndexerContactInfo; - InvoiceWrapperHelper = invoiceWrapperHelper; - InvoiceItemWrapperHelper = invoiceItemWrapperHelper; - InvoiceBaseWrapperHelper = invoiceBaseWrapperHelper; - InvoiceLineWrapperHelper = invoiceLineWrapperHelper; - InvoiceTaxWrapperHelper = invoiceTaxWrapperHelper; - RelationshipEventWrapperHelper = relationshipEventWrapperHelper; + InvoiceDtoHelper = invoiceDtoHelper; + InvoiceItemDtoHelper = invoiceItemDtoHelper; + InvoiceBaseDtoHelper = invoiceBaseDtoHelper; + InvoiceLineDtoHelper = invoiceLineDtoHelper; + InvoiceTaxDtoHelper = invoiceTaxDtoHelper; + RelationshipEventDtoHelper = relationshipEventDtoHelper; FileWrapperHelper = fileWrapperHelper; OrganisationLogoManager = organisationLogoManager; @@ -162,10 +162,10 @@ public CRMController(CRMSecurity cRMSecurity, DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; InvoiceSetting = invoiceSetting; - ContactInfoWrapperHelper = contactInfoWrapperHelper; - HistoryCategoryWrapperHelper = historyCategoryBaseWrapperHelper; - ContactWrapperHelper = contactBaseWrapperHelper; - VoipCallWrapperHelper = voipCallWrapperHelper; + ContactInfoDtoHelper = contactInfoDtoHelper; + HistoryCategoryDtoHelper = historyCategoryBaseDtoHelper; + ContactDtoHelper = contactBaseDtoHelper; + VoipCallDtoHelper = voipCallDtoHelper; //ExportToCsv = exportToCsv; ImportFromCSV = importFromCSV; @@ -173,9 +173,9 @@ public CRMController(CRMSecurity cRMSecurity, } public ImportFromCSVManager ImportFromCSVManager { get; } - public TaskCategoryWrapperHelper TaskCategoryWrapperHelper { get; } - public HistoryCategoryWrapperHelper HistoryCategoryWrapperHelper { get; } - public ContactInfoWrapperHelper ContactInfoWrapperHelper { get; } + public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } + public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } + public ContactInfoDtoHelper ContactInfoDtoHelper { get; } public VoipEngine VoipEngine { get; } public SignalrServiceClient SignalrServiceClient { get; } public IVoipProvider VoipProvider { get; } @@ -183,8 +183,8 @@ public CRMController(CRMSecurity cRMSecurity, public StorageFactory StorageFactory { get; } public CommonLinkUtility CommonLinkUtility { get; } public ContactPhotoManager ContactPhotoManager { get; } - public ContactWrapperHelper ContactWrapperHelper { get; } - public VoipCallWrapperHelper VoipCallWrapperHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + public VoipCallDtoHelper VoipCallDtoHelper { get; } public OrganisationLogoManager OrganisationLogoManager { get; } public InvoiceSetting InvoiceSetting { get; } public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } @@ -194,36 +194,36 @@ public CRMController(CRMSecurity cRMSecurity, public Web.Files.Classes.FilesSettingsHelper FilesSettingsHelper { get; } public ASC.Files.Core.Data.DaoFactory FilesDaoFactory { get; } public FileWrapperHelper FileWrapperHelper { get; } - public RelationshipEventWrapperHelper RelationshipEventWrapperHelper { get; } + public RelationshipEventDtoHelper RelationshipEventDtoHelper { get; } public AuthManager AuthManager { get; } public FileSizeComment FileSizeComment { get; } public SetupInfo SetupInfo { get; } public TenantManager TenantManager { get; } public PdfCreator PdfCreator { get; } - public InvoiceTaxWrapperHelper InvoiceTaxWrapperHelper { get; } - public InvoiceLineWrapperHelper InvoiceLineWrapperHelper { get; } - public InvoiceBaseWrapperHelper InvoiceBaseWrapperHelper { get; } - public InvoiceItemWrapperHelper InvoiceItemWrapperHelper { get; } - public InvoiceWrapperHelper InvoiceWrapperHelper { get; } + public InvoiceTaxDtoHelper InvoiceTaxDtoHelper { get; } + public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } + public InvoiceBaseDtoHelper InvoiceBaseDtoHelper { get; } + public InvoiceItemDtoHelper InvoiceItemDtoHelper { get; } + public InvoiceDtoHelper InvoiceDtoHelper { get; } public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } public FactoryIndexerFieldValue FactoryIndexerFieldValue { get; } public FactoryIndexerCase FactoryIndexerCase { get; } public IServiceProvider ServiceProvider { get; } - public CasesWrapperHelper CasesWrapperHelper { get; } - public CurrencyRateWrapperHelper CurrencyRateWrapperHelper { get; } + public CasesDtoHelper CasesDtoHelper { get; } + public CurrencyRateDtoHelper CurrencyRateDtoHelper { get; } public SettingsManager SettingsManager { get; } public Global Global { get; } - public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } - public CurrencyRateInfoWrapperHelper CurrencyRateInfoWrapperHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } + public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - public OpportunityWrapperHelper OpportunityWrapperHelper { get; } + public OpportunityDtoHelper OpportunityDtoHelper { get; } public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public CurrencyProvider CurrencyProvider { get; } public UserFormatter UserFormatter { get; } public UserManager UserManager { get; } public SecurityContext SecurityContext { get; } - public TaskWrapperHelper TaskWrapperHelper { get; } + public TaskDtoHelper TaskDtoHelper { get; } public NotifyClient NotifyClient { get; } private readonly ApiContext ApiContext; diff --git a/products/ASC.CRM/Server/Model/CasesWrapper.cs b/products/ASC.CRM/Server/ApiModels/CasesDto.cs similarity index 70% rename from products/ASC.CRM/Server/Model/CasesWrapper.cs rename to products/ASC.CRM/Server/ApiModels/CasesDto.cs index 30c7091e329..e1eef55285f 100644 --- a/products/ASC.CRM/Server/Model/CasesWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/CasesDto.cs @@ -37,85 +37,71 @@ using System.Linq; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { [DataContract(Name = "case", Namespace = "")] - public class CasesWrapper + public class CasesDto { - public CasesWrapper() + public CasesDto() { } [DataMember(Name = "id")] - public int Id { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public IEnumerable Members { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public EmployeeWraper CreateBy { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ApiDateTime Created { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int Id { get; set; } + public IEnumerable Members { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool IsClosed { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsPrivate { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool IsPrivate { get; set; } public IEnumerable AccessList { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public IEnumerable CustomFields { get; set; } - public static CasesWrapper GetSample() + public bool CanEdit { get; set; } + public IEnumerable CustomFields { get; set; } + public static CasesDto GetSample() { - return new CasesWrapper + return new CasesDto { IsClosed = false, Title = "Exhibition organization", Created = ApiDateTime.GetSample(), CreateBy = EmployeeWraper.GetSample(), IsPrivate = false, - CustomFields = new[] { CustomFieldBaseWrapper.GetSample() }, + CustomFields = new[] { CustomFieldBaseDto.GetSample() }, CanEdit = true }; } } [Scope] - public class CasesWrapperHelper + public class CasesDtoHelper { - public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public CasesDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, - ContactWrapperHelper contactBaseWrapperHelper) + ContactDtoHelper contactBaseDtoHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; DaoFactory = daoFactory; - ContactBaseWrapperHelper = contactBaseWrapperHelper; + ContactBaseDtoHelper = contactBaseDtoHelper; } - public ContactWrapperHelper ContactBaseWrapperHelper { get; } + public ContactDtoHelper ContactBaseDtoHelper { get; } public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - - public CasesWrapper Get(Cases cases) + public CasesDto Get(Cases cases) { - var result = new CasesWrapper + var result = new CasesDto { Title = cases.Title, IsClosed = cases.IsClosed, @@ -135,23 +121,23 @@ public CasesWrapper Get(Cases cases) result.CustomFields = DaoFactory .GetCustomFieldDao() .GetEnityFields(EntityType.Case, cases.ID, false) - .ConvertAll(item => new CustomFieldBaseWrapper(item)); + .ConvertAll(item => new CustomFieldBaseDto(item)); - result.Members = new List(); + result.Members = new List(); var memberIDs = DaoFactory.GetCasesDao().GetMembers(cases.ID); var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); - var membersWrapperList = new List(); + var membersDtoList = new List(); foreach (var member in membersList) { if (member == null) continue; - membersWrapperList.Add(ContactBaseWrapperHelper.GetContactBaseWrapper(member)); + membersDtoList.Add(ContactBaseDtoHelper.GetContactBaseDto(member)); } - result.Members = membersWrapperList; + result.Members = membersDtoList; return result; } diff --git a/products/ASC.CRM/Server/Model/ContactWrapper.cs b/products/ASC.CRM/Server/ApiModels/ContactDto.cs similarity index 63% rename from products/ASC.CRM/Server/Model/ContactWrapper.cs rename to products/ASC.CRM/Server/ApiModels/ContactDto.cs index 70effeb4bca..34f97f319e7 100644 --- a/products/ASC.CRM/Server/Model/ContactWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/ContactDto.cs @@ -25,6 +25,7 @@ using ASC.Api.Core; +using ASC.Api.CRM; using ASC.Common; using ASC.Common.Web; using ASC.CRM.Classes; @@ -41,15 +42,15 @@ using System.Runtime.Serialization; using Contact = ASC.CRM.Core.Entities.Contact; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { /// /// Person /// [DataContract(Name = "person", Namespace = "")] - public class PersonWrapper : ContactWrapper + public class PersonDto : ContactDto { - public PersonWrapper() + public PersonDto() { } @@ -60,22 +61,22 @@ public PersonWrapper() [DataMember(IsRequired = true, EmitDefaultValue = false)] public String LastName { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactBaseWrapper Company { get; set; } + + public ContactBaseDto Company { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } - public new static PersonWrapper GetSample() + public new static PersonDto GetSample() { - return new PersonWrapper + return new PersonDto { IsPrivate = true, IsShared = false, IsCompany = false, FirstName = "Tadjeddine", LastName = "Bachir", - Company = CompanyWrapper.GetSample(), + Company = CompanyDto.GetSample(), Title = "Programmer", About = "", Created = ApiDateTime.GetSample(), @@ -86,15 +87,15 @@ public PersonWrapper() } [Scope] - public class PersonWrapperHelper + public class PersonDtoHelper { - public PersonWrapperHelper() + public PersonDtoHelper() { } - public PersonWrapper Get(Person person) + public PersonDto Get(Person person) { - return new PersonWrapper + return new PersonDto { FirstName = person.FirstName, LastName = person.LastName, @@ -102,9 +103,9 @@ public PersonWrapper Get(Person person) }; } - public PersonWrapper GetQuick(Person person) + public PersonDto GetQuick(Person person) { - return new PersonWrapper + return new PersonDto { FirstName = person.FirstName, LastName = person.LastName, @@ -117,13 +118,13 @@ public PersonWrapper GetQuick(Person person) /// Company /// [DataContract(Name = "company", Namespace = "")] - public class CompanyWrapper : ContactWrapper + public class CompanyDto : ContactDto { - public CompanyWrapper() + public CompanyDto() { } - //public CompanyWrapper(Company company) + //public CompanyDto(Company company) // : base(company) //{ // CompanyName = company.CompanyName; @@ -137,14 +138,14 @@ public CompanyWrapper() public String CompanyName { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] - public IEnumerable Persons { get; set; } + public IEnumerable Persons { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] public int PersonsCount { get; set; } - public new static CompanyWrapper GetSample() + public new static CompanyDto GetSample() { - return new CompanyWrapper + return new CompanyDto { IsPrivate = true, IsShared = false, @@ -157,16 +158,16 @@ public CompanyWrapper() } [DataContract(Name = "contact", Namespace = "")] - [KnownType(typeof(PersonWrapper))] - [KnownType(typeof(CompanyWrapper))] - public abstract class ContactWrapper : ContactBaseWrapper + [KnownType(typeof(PersonDto))] + [KnownType(typeof(CompanyDto))] + public abstract class ContactDto : ContactBaseDto { - public ContactWrapper() + public ContactDto() { } - //protected ContactWrapper(Contact contact) + //protected ContactDto(Contact contact) // : base(contact) //{ // CreateBy = EmployeeWraper.Get(contact.CreateBy); @@ -175,59 +176,59 @@ public ContactWrapper() // Industry = contact.Industry; //} - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable
    Addresses { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String About { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Industry { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactStatusBaseWrapper ContactStatus { get; set; } + + public ContactStatusBaseDto ContactStatus { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactTypeBaseWrapper ContactType { get; set; } + + public ContactTypeBaseDto ContactType { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public IEnumerable CommonData { get; set; } + + public IEnumerable CommonData { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public IEnumerable CustomFields { get; set; } + + public IEnumerable CustomFields { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable Tags { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int TaskCount { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool HaveLateTasks { get; set; } - public new static ContactWrapper GetSample() + public new static ContactDto GetSample() { - return new PersonWrapper + return new PersonDto { IsPrivate = true, IsShared = false, IsCompany = false, FirstName = "Tadjeddine", LastName = "Bachir", - Company = CompanyWrapper.GetSample(), + Company = CompanyDto.GetSample(), Title = "Programmer", About = "", Created = ApiDateTime.GetSample(), CreateBy = EmployeeWraper.GetSample(), - CommonData = new List() { ContactInfoWrapper.GetSample() }, - CustomFields = new List() { CustomFieldBaseWrapper.GetSample() }, + CommonData = new List() { ContactInfoDto.GetSample() }, + CustomFields = new List() { CustomFieldBaseDto.GetSample() }, ShareType = ShareType.None, CanDelete = true, CanEdit = true, @@ -238,18 +239,18 @@ public ContactWrapper() } [DataContract(Name = "contactBase", Namespace = "")] - public class ContactBaseWithEmailWrapper : ContactBaseWrapper + public class ContactBaseWithEmailDto : ContactBaseDto { - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactInfoWrapper Email { get; set; } + + public ContactInfoDto Email { get; set; } } [DataContract(Name = "contactBase", Namespace = "")] - public class ContactBaseWithPhoneWrapper : ContactBaseWrapper + public class ContactBaseWithPhoneDto : ContactBaseDto { - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactInfoWrapper Phone { get; set; } + + public ContactInfoDto Phone { get; set; } } @@ -294,9 +295,9 @@ public class ContactBaseWithPhoneWrapper : ContactBaseWrapper /// Contact base information ///
    [DataContract(Name = "contactBase", Namespace = "")] - public class ContactBaseWrapper + public class ContactBaseDto { - public ContactBaseWrapper() + public ContactBaseDto() { } @@ -305,10 +306,10 @@ public ContactBaseWrapper() [DataMember(Name = "id")] public int Id { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String SmallFotoUrl { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String MediumFotoUrl { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -317,7 +318,7 @@ public ContactBaseWrapper() [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool IsCompany { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable AccessList { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -330,7 +331,7 @@ public ContactBaseWrapper() public ShareType ShareType { get; set; } [DataMember] - public CurrencyInfoWrapper Currency { get; set; } + public CurrencyInfoDto Currency { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool CanEdit { get; set; } @@ -338,9 +339,9 @@ public ContactBaseWrapper() [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool CanDelete { get; set; } - public static ContactBaseWrapper GetSample() + public static ContactBaseDto GetSample() { - return new ContactBaseWrapper + return new ContactBaseDto { IsPrivate = true, IsShared = false, @@ -352,49 +353,49 @@ public static ContactBaseWrapper GetSample() } [DataContract(Name = "contact_task", Namespace = "")] - public class ContactWithTaskWrapper + public class ContactWithTaskDto { - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public TaskBaseWrapper Task { get; set; } + + public TaskBaseDto Task { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactWrapper Contact { get; set; } + + public ContactDto Contact { get; set; } } [Scope] - public class ContactWrapperHelper + public class ContactDtoHelper { - public ContactWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public ContactDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, CurrencyProvider currencyProvider, PathProvider pathProvider, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper, + CurrencyInfoDtoHelper currencyInfoDtoHelper, DaoFactory daoFactory, - ContactInfoWrapperHelper contactInfoWrapperHelper) + ContactInfoDtoHelper contactInfoDtoHelper) { ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWrapperHelper = employeeWraperHelper; + EmployeeDtoHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; CurrencyProvider = currencyProvider; PathProvider = pathProvider; - CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; DaoFactory = daoFactory; - ContactInfoWrapperHelper = contactInfoWrapperHelper; + ContactInfoDtoHelper = contactInfoDtoHelper; } - public ContactInfoWrapperHelper ContactInfoWrapperHelper { get; } + public ContactInfoDtoHelper ContactInfoDtoHelper { get; } public DaoFactory DaoFactory { get; } - public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWrapperHelper { get; } + public EmployeeWraperHelper EmployeeDtoHelper { get; } public CurrencyProvider CurrencyProvider { get; } public PathProvider PathProvider { get; } - public ContactBaseWrapper GetContactBaseWrapperQuick(Contact contact) + public ContactBaseDto GetContactBaseDtoQuick(Contact contact) { - var result = new ContactBaseWrapper + var result = new ContactBaseDto { Id = contact.ID, DisplayName = contact.GetTitle(), @@ -402,7 +403,7 @@ public ContactBaseWrapper GetContactBaseWrapperQuick(Contact contact) IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read, ShareType = contact.ShareType, Currency = !String.IsNullOrEmpty(contact.Currency) ? - CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(contact.Currency)) : null, + CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(contact.Currency)) : null, SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), IsCompany = contact is Company, @@ -413,63 +414,63 @@ public ContactBaseWrapper GetContactBaseWrapperQuick(Contact contact) if (result.IsPrivate) { result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeWrapperHelper.Get(item.Key)); + .Select(item => EmployeeDtoHelper.Get(item.Key)); } return result; } - public ContactBaseWrapper GetContactBaseWrapper(Contact contact) + public ContactBaseDto GetContactBaseDto(Contact contact) { - var result = GetContactBaseWrapperQuick(contact); + var result = GetContactBaseDtoQuick(contact); result.CanDelete = CRMSecurity.CanDelete(contact); return result; } - public ContactBaseWithPhoneWrapper GetContactBaseWithPhoneWrapper(Contact contact) + public ContactBaseWithPhoneDto GetContactBaseWithPhoneDto(Contact contact) { if (contact == null) return null; - var result = (ContactBaseWithPhoneWrapper)GetContactBaseWrapper(contact); + var result = (ContactBaseWithPhoneDto)GetContactBaseDto(contact); - result.Phone = ContactInfoWrapperHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Phone, null, true).FirstOrDefault()); + result.Phone = ContactInfoDtoHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Phone, null, true).FirstOrDefault()); return result; } - public ContactBaseWithEmailWrapper GetContactBaseWithEmailWrapper(Contact contact) + public ContactBaseWithEmailDto GetContactBaseWithEmailDto(Contact contact) { if (contact == null) return null; - var result = (ContactBaseWithEmailWrapper)GetContactBaseWrapper(contact); + var result = (ContactBaseWithEmailDto)GetContactBaseDto(contact); - result.Email = ContactInfoWrapperHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Email, null, true).FirstOrDefault()); + result.Email = ContactInfoDtoHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Email, null, true).FirstOrDefault()); return result; } - public ContactWrapper GetContactWrapper(Contact contact) + public ContactDto GetContactDto(Contact contact) { - ContactWrapper result; + ContactDto result; var person = contact as Person; if (person != null) { - var peopleWrapper = (PersonWrapper)GetContactBaseWrapper(contact); + var peopleDto = (PersonDto)GetContactBaseDto(contact); - peopleWrapper.FirstName = person.FirstName; - peopleWrapper.LastName = person.LastName; - peopleWrapper.Title = person.JobTitle; + peopleDto.FirstName = person.FirstName; + peopleDto.LastName = person.LastName; + peopleDto.Title = person.JobTitle; if (person.CompanyID > 0) { - peopleWrapper.Company = GetContactBaseWrapper(DaoFactory.GetContactDao().GetByID(person.CompanyID)); + peopleDto.Company = GetContactBaseDto(DaoFactory.GetContactDao().GetByID(person.CompanyID)); } - result = peopleWrapper; + result = peopleDto; } else { @@ -477,9 +478,9 @@ public ContactWrapper GetContactWrapper(Contact contact) if (company != null) { - result = (CompanyWrapper)GetContactBaseWrapper(company); - ((CompanyWrapper)result).CompanyName = company.CompanyName; - ((CompanyWrapper)result).PersonsCount = DaoFactory.GetContactDao().GetMembersCount(result.Id); + result = (CompanyDto)GetContactBaseDto(company); + ((CompanyDto)result).CompanyName = company.CompanyName; + ((CompanyDto)result).PersonsCount = DaoFactory.GetContactDao().GetMembersCount(result.Id); } else throw new ArgumentException(); } @@ -489,13 +490,13 @@ public ContactWrapper GetContactWrapper(Contact contact) var listItem = DaoFactory.GetListItemDao().GetByID(contact.StatusID); if (listItem == null) throw new ItemNotFoundException(); - result.ContactStatus = new ContactStatusBaseWrapper(listItem); + result.ContactStatus = new ContactStatusBaseDto(listItem); } result.TaskCount = DaoFactory.GetTaskDao().GetTasksCount(contact.ID); result.HaveLateTasks = DaoFactory.GetTaskDao().HaveLateTask(contact.ID); - var contactInfos = new List(); + var contactInfos = new List(); var addresses = new List
    (); var data = DaoFactory.GetContactInfoDao().GetList(contact.ID, null, null, null); @@ -508,7 +509,7 @@ public ContactWrapper GetContactWrapper(Contact contact) } else { - contactInfos.Add(ContactInfoWrapperHelper.Get(contactInfo)); + contactInfos.Add(ContactInfoDtoHelper.Get(contactInfo)); } } @@ -517,18 +518,18 @@ public ContactWrapper GetContactWrapper(Contact contact) result.CustomFields = DaoFactory.GetCustomFieldDao() .GetEnityFields(contact is Person ? EntityType.Person : EntityType.Company, contact.ID, false) - .ConvertAll(item => new CustomFieldBaseWrapper(item)); + .ConvertAll(item => new CustomFieldBaseDto(item)); return result; } - public CompanyWrapper GetCompanyWrapperQuick(Company company) + public CompanyDto GetCompanyDtoQuick(Company company) { - var result = (CompanyWrapper)GetContactBaseWrapperQuick(company); + var result = (CompanyDto)GetContactBaseDtoQuick(company); result.CompanyName = company.CompanyName; - result.CreateBy = EmployeeWrapperHelper.Get(company.CreateBy); + result.CreateBy = EmployeeDtoHelper.Get(company.CreateBy); result.Created = ApiDateTimeHelper.Get(company.CreateOn); result.About = company.About; result.Industry = company.Industry; @@ -536,11 +537,11 @@ public CompanyWrapper GetCompanyWrapperQuick(Company company) return result; } - public PersonWrapper GetPersonWrapperQuick(Person person) + public PersonDto GetPersonDtoQuick(Person person) { - var result = (PersonWrapper)GetContactBaseWrapperQuick(person); + var result = (PersonDto)GetContactBaseDtoQuick(person); - result.CreateBy = EmployeeWrapperHelper.Get(person.CreateBy); + result.CreateBy = EmployeeDtoHelper.Get(person.CreateBy); result.Created = ApiDateTimeHelper.Get(person.CreateOn); result.About = person.About; result.Industry = person.Industry; diff --git a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs b/products/ASC.CRM/Server/ApiModels/ContactInfoDto.cs similarity index 93% rename from products/ASC.CRM/Server/Model/ContactInfoWrapper.cs rename to products/ASC.CRM/Server/ApiModels/ContactInfoDto.cs index 5914e8cf456..f741d7d9101 100644 --- a/products/ASC.CRM/Server/Model/ContactInfoWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/ContactInfoDto.cs @@ -25,7 +25,7 @@ using ASC.Api.Core; -using ASC.Api.CRM.Wrappers; +using ASC.CRM.ApiModels; using ASC.Common; using ASC.CRM.Classes; using ASC.CRM.Core; @@ -35,7 +35,7 @@ using System; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { /// /// Address @@ -128,9 +128,9 @@ public static Address GetSample() /// Contact information /// [DataContract(Name = "commonDataItem", Namespace = "")] - public class ContactInfoWrapper + public class ContactInfoDto { - public ContactInfoWrapper() + public ContactInfoDto() { } @@ -152,9 +152,9 @@ public ContactInfoWrapper() [DataMember(Order = 5)] public bool IsPrimary { get; set; } - public static ContactInfoWrapper GetSample() + public static ContactInfoDto GetSample() { - return new ContactInfoWrapper + return new ContactInfoDto { IsPrimary = true, Category = (int)ContactInfoBaseCategory.Home, @@ -166,17 +166,17 @@ public static ContactInfoWrapper GetSample() } [Scope] - public class ContactInfoWrapperHelper + public class ContactInfoDtoHelper { - public ContactInfoWrapperHelper() + public ContactInfoDtoHelper() { } - public ContactInfoWrapper Get(ContactInfo contactInfo) + public ContactInfoDto Get(ContactInfo contactInfo) { if (contactInfo == null) return null; - return new ContactInfoWrapper + return new ContactInfoDto { InfoType = contactInfo.InfoType, Category = contactInfo.Category, diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateCasesInDto.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateCasesInDto.cs similarity index 94% rename from products/ASC.CRM/Server/Model/Dto/CreateOrUpdateCasesInDto.cs rename to products/ASC.CRM/Server/ApiModels/CreateOrUpdateCasesInDto.cs index ab15f17fbf6..f0071ed6049 100644 --- a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateCasesInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateCasesInDto.cs @@ -5,7 +5,7 @@ using ASC.Api.Collections; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class CreateOrUpdateCasesInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateDealInDto.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateDealInDto.cs similarity index 97% rename from products/ASC.CRM/Server/Model/Dto/CreateOrUpdateDealInDto.cs rename to products/ASC.CRM/Server/ApiModels/CreateOrUpdateDealInDto.cs index bbc0e98a876..18b5744e616 100644 --- a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateDealInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateDealInDto.cs @@ -7,7 +7,7 @@ using ASC.Api.Core; using ASC.CRM.Core.Enums; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class CreateOrUpdateDealInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceInDto.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceInDto.cs similarity index 97% rename from products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceInDto.cs rename to products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceInDto.cs index ba932801e41..2cae2e927d1 100644 --- a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceInDto.cs @@ -6,7 +6,7 @@ using ASC.Api.Core; using ASC.CRM.Core.Entities; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class CreateOrUpdateInvoiceInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceItemInDto.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceItemInDto.cs similarity index 95% rename from products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceItemInDto.cs rename to products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceItemInDto.cs index 647e63500b9..342e372f2e7 100644 --- a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceItemInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceItemInDto.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Threading.Tasks; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class CreateOrUpdateInvoiceItemInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceLineInDto.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceLineInDto.cs similarity index 95% rename from products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceLineInDto.cs rename to products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceLineInDto.cs index 6ff058a5955..2c3dbdddf68 100644 --- a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceLineInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceLineInDto.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Threading.Tasks; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class CreateOrUpdateInvoiceLineInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceTax.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceTax.cs similarity index 91% rename from products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceTax.cs rename to products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceTax.cs index bc348b9845b..f2e9524e4c6 100644 --- a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdateInvoiceTax.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceTax.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Threading.Tasks; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class CreateOrUpdateInvoiceTax { diff --git a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdatePersonInDto.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs similarity index 92% rename from products/ASC.CRM/Server/Model/Dto/CreateOrUpdatePersonInDto.cs rename to products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs index 5e53cfeb550..d68ce15cfa1 100644 --- a/products/ASC.CRM/Server/Model/Dto/CreateOrUpdatePersonInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs @@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Http; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class CreateOrUpdateContactInDto { @@ -26,7 +26,7 @@ public class CreateOrUpdateContactInDto public class CreateOrUpdateCompanyInDto : CreateOrUpdateContactInDto { - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String CompanyName { get; set; } public IEnumerable PersonList { get; set; } diff --git a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs b/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs similarity index 69% rename from products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs rename to products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs index a5fe23ffe3d..8114de18623 100644 --- a/products/ASC.CRM/Server/Model/CurrencyInfoWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs @@ -29,15 +29,15 @@ using ASC.Common; using ASC.CRM.Core; -namespace ASC.Api.CRM +namespace ASC.CRM.ApiModels { /// /// Currency information /// [DataContract(Name = "currencyInfo", Namespace = "")] - public class CurrencyInfoWrapper + public class CurrencyInfoDto { - public CurrencyInfoWrapper() + public CurrencyInfoDto() { @@ -61,9 +61,9 @@ public CurrencyInfoWrapper() [DataMember] public bool IsBasic { get; set; } - public static CurrencyInfoWrapper GetSample() + public static CurrencyInfoDto GetSample() { - return new CurrencyInfoWrapper + return new CurrencyInfoDto { Title = "Chinese Yuan", Abbreviation = "CNY", @@ -76,18 +76,18 @@ public static CurrencyInfoWrapper GetSample() } [Singletone] - public class CurrencyInfoWrapperHelper + public class CurrencyInfoDtoHelper { - public CurrencyInfoWrapperHelper() + public CurrencyInfoDtoHelper() { } - public CurrencyInfoWrapper Get(CurrencyInfo currencyInfo) + public CurrencyInfoDto Get(CurrencyInfo currencyInfo) { if (currencyInfo == null) return null; - return new CurrencyInfoWrapper + return new CurrencyInfoDto { Abbreviation = currencyInfo.Abbreviation, CultureName = currencyInfo.CultureName, @@ -103,13 +103,13 @@ public CurrencyInfoWrapper Get(CurrencyInfo currencyInfo) /// Currency rate information ///
    [DataContract(Name = "currencyRateInfo", Namespace = "")] - public class CurrencyRateInfoWrapper : CurrencyInfoWrapper + public class CurrencyRateInfoDto : CurrencyInfoDto { - public CurrencyRateInfoWrapper() + public CurrencyRateInfoDto() { } - //public CurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate) + //public CurrencyRateInfoDto(CurrencyInfo currencyInfo, Decimal rate) // : base(currencyInfo) //{ // Rate = rate; @@ -120,27 +120,27 @@ public CurrencyRateInfoWrapper() } [Scope] - public class CurrencyRateInfoWrapperHelper + public class CurrencyRateInfoDtoHelper { - public CurrencyRateInfoWrapperHelper(CurrencyInfoWrapperHelper currencyInfoWrapperHelper) + public CurrencyRateInfoDtoHelper(CurrencyInfoDtoHelper currencyInfoDtoHelper) { - CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; } - public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public CurrencyRateInfoWrapper Get(CurrencyInfo currencyInfo, decimal rate) + public CurrencyRateInfoDto Get(CurrencyInfo currencyInfo, decimal rate) { - var currencyInfoWrapper = CurrencyInfoWrapperHelper.Get(currencyInfo); + var currencyInfoDto = CurrencyInfoDtoHelper.Get(currencyInfo); - return new CurrencyRateInfoWrapper + return new CurrencyRateInfoDto { - Abbreviation = currencyInfoWrapper.Abbreviation, - CultureName = currencyInfoWrapper.CultureName, - Symbol = currencyInfoWrapper.Symbol, - Title = currencyInfoWrapper.Title, - IsConvertable = currencyInfoWrapper.IsConvertable, - IsBasic = currencyInfoWrapper.IsBasic, + Abbreviation = currencyInfoDto.Abbreviation, + CultureName = currencyInfoDto.CultureName, + Symbol = currencyInfoDto.Symbol, + Title = currencyInfoDto.Title, + IsConvertable = currencyInfoDto.IsConvertable, + IsBasic = currencyInfoDto.IsBasic, Rate = rate }; } diff --git a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs b/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs similarity index 86% rename from products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs rename to products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs index 60a8d0b1e60..915fabe7d48 100644 --- a/products/ASC.CRM/Server/Model/CurrencyRateWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs @@ -30,15 +30,15 @@ using ASC.Common; using ASC.CRM.Core; -namespace ASC.Api.CRM +namespace ASC.CRM.ApiModels { /// /// Currency rate /// [DataContract(Name = "currencyRate", Namespace = "")] - public class CurrencyRateWrapper + public class CurrencyRateDto { - public CurrencyRateWrapper() + public CurrencyRateDto() { } @@ -55,9 +55,9 @@ public CurrencyRateWrapper() [DataMember] public decimal Rate { get; set; } - public static CurrencyRateWrapper GetSample() + public static CurrencyRateDto GetSample() { - return new CurrencyRateWrapper + return new CurrencyRateDto { Id = 1, FromCurrency = "EUR", @@ -68,15 +68,15 @@ public static CurrencyRateWrapper GetSample() } [Scope] - public class CurrencyRateWrapperHelper + public class CurrencyRateDtoHelper { - public CurrencyRateWrapperHelper() + public CurrencyRateDtoHelper() { } - public CurrencyRateWrapper Get(CurrencyRate currencyRate) + public CurrencyRateDto Get(CurrencyRate currencyRate) { - return new CurrencyRateWrapper + return new CurrencyRateDto { FromCurrency = currencyRate.FromCurrency, ToCurrency = currencyRate.ToCurrency, diff --git a/products/ASC.CRM/Server/Model/CustomFieldWrapper.cs b/products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs similarity index 86% rename from products/ASC.CRM/Server/Model/CustomFieldWrapper.cs rename to products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs index b3576768ad5..1c8ed59f5a3 100644 --- a/products/ASC.CRM/Server/Model/CustomFieldWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs @@ -30,17 +30,17 @@ using System; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { [DataContract(Name = "customField", Namespace = "")] - public class CustomFieldWrapper : CustomFieldBaseWrapper + public class CustomFieldDto : CustomFieldBaseDto { - public CustomFieldWrapper(int id) + public CustomFieldDto(int id) : base(id) { } - public CustomFieldWrapper(CustomField customField) + public CustomFieldDto(CustomField customField) : base(customField) { } @@ -50,9 +50,9 @@ public CustomFieldWrapper(CustomField customField) [DataMember] public int RelativeItemsCount { get; set; } - public new static CustomFieldWrapper GetSample() + public new static CustomFieldDto GetSample() { - return new CustomFieldWrapper(0) + return new CustomFieldDto(0) { Position = 10, EntityId = 14523423, @@ -69,13 +69,13 @@ public CustomFieldWrapper(CustomField customField) /// User custom fields ///
    [DataContract(Name = "customField", Namespace = "")] - public class CustomFieldBaseWrapper + public class CustomFieldBaseDto { - public CustomFieldBaseWrapper(int id) + public CustomFieldBaseDto(int id) { } - public CustomFieldBaseWrapper(CustomField customField) + public CustomFieldBaseDto(CustomField customField) { EntityId = customField.EntityID; Label = customField.Label; @@ -106,9 +106,9 @@ public CustomFieldBaseWrapper(CustomField customField) [DataMember] public String Mask { get; set; } - public static CustomFieldBaseWrapper GetSample() + public static CustomFieldBaseDto GetSample() { - return new CustomFieldBaseWrapper(0) + return new CustomFieldBaseDto(0) { Position = 10, EntityId = 14523423, diff --git a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs b/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs similarity index 68% rename from products/ASC.CRM/Server/Model/InvoiceWrapper.cs rename to products/ASC.CRM/Server/ApiModels/InvoiceDto.cs index 256b98d8585..8d499a2f0c3 100644 --- a/products/ASC.CRM/Server/Model/InvoiceWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs @@ -38,16 +38,16 @@ using System.Linq; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { /// /// Invoice /// [DataContract(Name = "invoiceBase", Namespace = "")] - public class InvoiceBaseWrapper + public class InvoiceBaseDto { - public InvoiceBaseWrapper() + public InvoiceBaseDto() { } @@ -56,7 +56,7 @@ public InvoiceBaseWrapper() public int Id { get; set; } [DataMember] - public InvoiceStatusWrapper Status { get; set; } + public InvoiceStatusDto Status { get; set; } [DataMember] public string Number { get; set; } @@ -68,13 +68,13 @@ public InvoiceBaseWrapper() public InvoiceTemplateType TemplateType { get; set; } [DataMember] - public ContactBaseWithEmailWrapper Contact { get; set; } + public ContactBaseWithEmailDto Contact { get; set; } [DataMember] - public ContactBaseWithEmailWrapper Consignee { get; set; } + public ContactBaseWithEmailDto Consignee { get; set; } [DataMember] - public EntityWrapper Entity { get; set; } + public EntityDto Entity { get; set; } [DataMember] public ApiDateTime DueDate { get; set; } @@ -83,7 +83,7 @@ public InvoiceBaseWrapper() public string Language { get; set; } [DataMember] - public CurrencyInfoWrapper Currency { get; set; } + public CurrencyInfoDto Currency { get; set; } [DataMember] public decimal ExchangeRate { get; set; } @@ -117,35 +117,35 @@ public InvoiceBaseWrapper() } [Scope] - public class InvoiceBaseWrapperHelper + public class InvoiceBaseDtoHelper { - public InvoiceBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public InvoiceBaseDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, SettingsManager settingsManager, CurrencyProvider currencyProvider, - InvoiceStatusWrapperHelper invoiceStatusWrapperHelper, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper, + InvoiceStatusDtoHelper invoiceStatusDtoHelper, + CurrencyInfoDtoHelper currencyInfoDtoHelper, DaoFactory daoFactory, - ContactWrapperHelper contactWrapperHelper, - EntityWrapperHelper entityWrapperHelper) + ContactDtoHelper contactDtoHelper, + EntityDtoHelper entityDtoHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; SettingsManager = settingsManager; CurrencyProvider = currencyProvider; - InvoiceStatusWrapperHelper = invoiceStatusWrapperHelper; + InvoiceStatusDtoHelper = invoiceStatusDtoHelper; DaoFactory = daoFactory; - CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; - ContactWrapperHelper = contactWrapperHelper; - EntityWrapperHelper = entityWrapperHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + ContactDtoHelper = contactDtoHelper; + EntityDtoHelper = entityDtoHelper; } - public EntityWrapperHelper EntityWrapperHelper { get; } - public ContactWrapperHelper ContactWrapperHelper { get; } - public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } - public InvoiceStatusWrapperHelper InvoiceStatusWrapperHelper { get; } + public EntityDtoHelper EntityDtoHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } + public InvoiceStatusDtoHelper InvoiceStatusDtoHelper { get; } public CurrencyProvider CurrencyProvider { get; } public SettingsManager SettingsManager { get; } public CRMSecurity CRMSecurity { get; } @@ -153,20 +153,20 @@ public InvoiceBaseWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, public EmployeeWraperHelper EmployeeWraperHelper { get; } public DaoFactory DaoFactory { get; } - public InvoiceBaseWrapper Get(Invoice invoice) + public InvoiceBaseDto Get(Invoice invoice) { - var result = new InvoiceBaseWrapper + var result = new InvoiceBaseDto { Id = invoice.ID, - Status = InvoiceStatusWrapperHelper.Get(invoice.Status), + Status = InvoiceStatusDtoHelper.Get(invoice.Status), Number = invoice.Number, IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), TemplateType = invoice.TemplateType, DueDate = ApiDateTimeHelper.Get(invoice.DueDate), Currency = !String.IsNullOrEmpty(invoice.Currency) ? - CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(invoice.Currency)) : - CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency), + CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoice.Currency)) : + CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), ExchangeRate = invoice.ExchangeRate, Language = invoice.Language, PurchaseOrderNumber = invoice.PurchaseOrderNumber, @@ -181,17 +181,17 @@ public InvoiceBaseWrapper Get(Invoice invoice) if (invoice.ContactID > 0) { - result.Contact = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + result.Contact = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); } if (invoice.ConsigneeID > 0) { - result.Consignee = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + result.Consignee = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); } if (invoice.EntityID > 0) { - result.Entity = EntityWrapperHelper.Get(invoice.EntityType, invoice.EntityID); + result.Entity = EntityDtoHelper.Get(invoice.EntityType, invoice.EntityID); } result.Cost = invoice.GetInvoiceCost(DaoFactory); @@ -205,26 +205,26 @@ public InvoiceBaseWrapper Get(Invoice invoice) /// Invoice ///
    [DataContract(Name = "invoice", Namespace = "")] - public class InvoiceWrapper : InvoiceBaseWrapper + public class InvoiceDto : InvoiceBaseDto { - public InvoiceWrapper() + public InvoiceDto() { } [DataMember] - public List InvoiceLines { get; set; } + public List InvoiceLines { get; set; } - public static InvoiceWrapper GetSample() + public static InvoiceDto GetSample() { - return new InvoiceWrapper + return new InvoiceDto { - Status = InvoiceStatusWrapper.GetSample(), + Status = InvoiceStatusDto.GetSample(), Number = string.Empty, IssueDate = ApiDateTime.GetSample(), TemplateType = InvoiceTemplateType.Eur, Language = string.Empty, DueDate = ApiDateTime.GetSample(), - Currency = CurrencyInfoWrapper.GetSample(), + Currency = CurrencyInfoDto.GetSample(), ExchangeRate = (decimal)1.00, PurchaseOrderNumber = string.Empty, Terms = string.Empty, @@ -235,66 +235,66 @@ public static InvoiceWrapper GetSample() CanEdit = true, CanDelete = true, Cost = 0, - InvoiceLines = new List { InvoiceLineWrapper.GetSample() } + InvoiceLines = new List { InvoiceLineDto.GetSample() } }; } } [Scope] - public class InvoiceWrapperHelper + public class InvoiceDtoHelper { - public InvoiceWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public InvoiceDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, SettingsManager settingsManager, CurrencyProvider currencyProvider, - InvoiceStatusWrapperHelper invoiceStatusWrapperHelper, - InvoiceLineWrapperHelper invoiceLineWrapperHelper, + InvoiceStatusDtoHelper invoiceStatusDtoHelper, + InvoiceLineDtoHelper invoiceLineDtoHelper, DaoFactory daoFactory, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper, - CurrencyRateInfoWrapperHelper currencyRateInfoWrapperHelper, - ContactWrapperHelper contactWrapperHelper, - EntityWrapperHelper entityWrapperHelper) + CurrencyInfoDtoHelper currencyInfoDtoHelper, + CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, + ContactDtoHelper contactDtoHelper, + EntityDtoHelper entityDtoHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; SettingsManager = settingsManager; CurrencyProvider = currencyProvider; - InvoiceStatusWrapperHelper = invoiceStatusWrapperHelper; + InvoiceStatusDtoHelper = invoiceStatusDtoHelper; DaoFactory = daoFactory; - InvoiceLineWrapperHelper = invoiceLineWrapperHelper; - CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; - CurrencyRateInfoWrapperHelper = currencyRateInfoWrapperHelper; - ContactWrapperHelper = contactWrapperHelper; - EntityWrapperHelper = entityWrapperHelper; + InvoiceLineDtoHelper = invoiceLineDtoHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; + ContactDtoHelper = contactDtoHelper; + EntityDtoHelper = entityDtoHelper; } - public ContactWrapperHelper ContactWrapperHelper { get; } - public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } - public CurrencyRateInfoWrapperHelper CurrencyRateInfoWrapperHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } + public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } public DaoFactory DaoFactory { get; } - public InvoiceLineWrapperHelper InvoiceLineWrapperHelper { get; } - public InvoiceStatusWrapperHelper InvoiceStatusWrapperHelper { get; } + public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } + public InvoiceStatusDtoHelper InvoiceStatusDtoHelper { get; } public CurrencyProvider CurrencyProvider { get; } public SettingsManager SettingsManager { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } public CRMSecurity CRMSecurity { get; } - public EntityWrapperHelper EntityWrapperHelper { get; } - public InvoiceWrapper Get(Invoice invoice) + public EntityDtoHelper EntityDtoHelper { get; } + public InvoiceDto Get(Invoice invoice) { - var result = new InvoiceWrapper + var result = new InvoiceDto { Id = invoice.ID, - Status = InvoiceStatusWrapperHelper.Get(invoice.Status), + Status = InvoiceStatusDtoHelper.Get(invoice.Status), Number = invoice.Number, IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), TemplateType = invoice.TemplateType, DueDate = ApiDateTimeHelper.Get(invoice.DueDate), Currency = !String.IsNullOrEmpty(invoice.Currency) ? - CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(invoice.Currency)) : - CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency), + CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoice.Currency)) : + CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), ExchangeRate = invoice.ExchangeRate, Language = invoice.Language, PurchaseOrderNumber = invoice.PurchaseOrderNumber, @@ -309,22 +309,22 @@ public InvoiceWrapper Get(Invoice invoice) if (invoice.ContactID > 0) { - result.Contact = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + result.Contact = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); } if (invoice.ConsigneeID > 0) { - result.Consignee = ContactWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + result.Consignee = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); } if (invoice.EntityID > 0) { - result.Entity = EntityWrapperHelper.Get(invoice.EntityType, invoice.EntityID); + result.Entity = EntityDtoHelper.Get(invoice.EntityType, invoice.EntityID); } result.Cost = invoice.GetInvoiceCost(DaoFactory); - result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(x => InvoiceLineWrapperHelper.Get(x)).ToList(); + result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(x => InvoiceLineDtoHelper.Get(x)).ToList(); return result; @@ -335,9 +335,9 @@ public InvoiceWrapper Get(Invoice invoice) /// Invoice Item ///
    [DataContract(Name = "invoiceItem", Namespace = "")] - public class InvoiceItemWrapper + public class InvoiceItemDto { - public InvoiceItemWrapper() + public InvoiceItemDto() { } @@ -354,7 +354,7 @@ public InvoiceItemWrapper() public decimal Price { get; set; } [DataMember] - public CurrencyInfoWrapper Currency { get; set; } + public CurrencyInfoDto Currency { get; set; } [DataMember] public decimal StockQuantity { get; set; } @@ -363,10 +363,10 @@ public InvoiceItemWrapper() public bool TrackInvenory { get; set; } [DataMember] - public InvoiceTaxWrapper InvoiceTax1 { get; set; } + public InvoiceTaxDto InvoiceTax1 { get; set; } [DataMember] - public InvoiceTaxWrapper InvoiceTax2 { get; set; } + public InvoiceTaxDto InvoiceTax2 { get; set; } [DataMember] public ApiDateTime CreateOn { get; set; } @@ -382,16 +382,16 @@ public InvoiceItemWrapper() } [Scope] - public class InvoiceItemWrapperHelper + public class InvoiceItemDtoHelper { - public InvoiceItemWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public InvoiceItemDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, SettingsManager settingsManager, CurrencyProvider currencyProvider, DaoFactory daoFactory, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper, - InvoiceTaxWrapperHelper invoiceTaxWrapperHelper) + CurrencyInfoDtoHelper currencyInfoDtoHelper, + InvoiceTaxDtoHelper invoiceTaxDtoHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; @@ -399,13 +399,13 @@ public InvoiceItemWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, SettingsManager = settingsManager; CurrencyProvider = currencyProvider; DaoFactory = daoFactory; - CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; - InvoiceTaxWrapperHelper = invoiceTaxWrapperHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + InvoiceTaxDtoHelper = invoiceTaxDtoHelper; } - public InvoiceTaxWrapperHelper InvoiceTaxWrapperHelper { get; } + public InvoiceTaxDtoHelper InvoiceTaxDtoHelper { get; } - public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } public DaoFactory DaoFactory { get; } public CurrencyProvider CurrencyProvider { get; } public SettingsManager SettingsManager { get; } @@ -413,9 +413,9 @@ public InvoiceItemWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, public EmployeeWraperHelper EmployeeWraperHelper { get; } public CRMSecurity CRMSecurity { get; } - public InvoiceItemWrapper Get(InvoiceItem invoiceItem) + public InvoiceItemDto Get(InvoiceItem invoiceItem) { - var result = new InvoiceItemWrapper { + var result = new InvoiceItemDto { Title = invoiceItem.Title, StockKeepingUnit = invoiceItem.StockKeepingUnit, @@ -426,19 +426,19 @@ public InvoiceItemWrapper Get(InvoiceItem invoiceItem) CreateOn = ApiDateTimeHelper.Get(invoiceItem.CreateOn), CreateBy = EmployeeWraperHelper.Get(invoiceItem.CreateBy), Currency = !String.IsNullOrEmpty(invoiceItem.Currency) ? - CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(invoiceItem.Currency)) : - CurrencyInfoWrapperHelper.Get(SettingsManager.Load().DefaultCurrency), + CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoiceItem.Currency)) : + CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), CanEdit = CRMSecurity.CanEdit(invoiceItem), CanDelete = CRMSecurity.CanDelete(invoiceItem) }; if (invoiceItem.InvoiceTax1ID > 0) { - result.InvoiceTax1 = InvoiceTaxWrapperHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); + result.InvoiceTax1 = InvoiceTaxDtoHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); } if (invoiceItem.InvoiceTax2ID > 0) { - result.InvoiceTax2 = InvoiceTaxWrapperHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); + result.InvoiceTax2 = InvoiceTaxDtoHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); } return result; @@ -447,11 +447,11 @@ public InvoiceItemWrapper Get(InvoiceItem invoiceItem) } - //public static class InvoiceItemWrapperHelperExtension + //public static class InvoiceItemDtoHelperExtension //{ - // public static DIHelper AddInvoiceItemWrapperHelperService(this DIHelper services) + // public static DIHelper AddInvoiceItemDtoHelperService(this DIHelper services) // { - // services.TryAddTransient(); + // services.TryAddTransient(); // return services.AddCurrencyProviderService() // .AddSettingsManagerService() // .AddApiDateTimeHelper() @@ -464,10 +464,10 @@ public InvoiceItemWrapper Get(InvoiceItem invoiceItem) /// Invoice Tax ///
    [DataContract(Name = "invoiceTax", Namespace = "")] - public class InvoiceTaxWrapper + public class InvoiceTaxDto { - public InvoiceTaxWrapper() + public InvoiceTaxDto() { } @@ -497,9 +497,9 @@ public InvoiceTaxWrapper() } [Scope] - public class InvoiceTaxWrapperHelper + public class InvoiceTaxDtoHelper { - public InvoiceTaxWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public InvoiceTaxDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity) { @@ -512,9 +512,9 @@ public InvoiceTaxWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, public EmployeeWraperHelper EmployeeWraperHelper { get; } public CRMSecurity CRMSecurity { get; } - public InvoiceTaxWrapper Get(InvoiceTax invoiceTax) + public InvoiceTaxDto Get(InvoiceTax invoiceTax) { - return new InvoiceTaxWrapper + return new InvoiceTaxDto { Id = invoiceTax.ID, Name = invoiceTax.Name, @@ -532,9 +532,9 @@ public InvoiceTaxWrapper Get(InvoiceTax invoiceTax) /// Invoice Line ///
    [DataContract(Name = "invoiceLine", Namespace = "")] - public class InvoiceLineWrapper + public class InvoiceLineDto { - public InvoiceLineWrapper() + public InvoiceLineDto() { } @@ -569,9 +569,9 @@ public InvoiceLineWrapper() [DataMember] public decimal Discount { get; set; } - public static InvoiceLineWrapper GetSample() + public static InvoiceLineDto GetSample() { - return new InvoiceLineWrapper + return new InvoiceLineDto { Description = string.Empty, Discount = (decimal)0.00, @@ -586,15 +586,15 @@ public static InvoiceLineWrapper GetSample() } [Singletone] - public class InvoiceLineWrapperHelper + public class InvoiceLineDtoHelper { - public InvoiceLineWrapperHelper() + public InvoiceLineDtoHelper() { } - public InvoiceLineWrapper Get(InvoiceLine invoiceLine) + public InvoiceLineDto Get(InvoiceLine invoiceLine) { - return new InvoiceLineWrapper + return new InvoiceLineDto { Id = invoiceLine.ID, InvoiceID = invoiceLine.InvoiceID, @@ -614,9 +614,9 @@ public InvoiceLineWrapper Get(InvoiceLine invoiceLine) /// Invoice Status ///
    [DataContract(Name = "invoiceStatus", Namespace = "")] - public class InvoiceStatusWrapper + public class InvoiceStatusDto { - public InvoiceStatusWrapper() + public InvoiceStatusDto() { } @@ -627,9 +627,9 @@ public InvoiceStatusWrapper() [DataMember] public string Title { get; set; } - public static InvoiceStatusWrapper GetSample() + public static InvoiceStatusDto GetSample() { - return new InvoiceStatusWrapper + return new InvoiceStatusDto { Id = (int)InvoiceStatus.Draft, Title = InvoiceStatus.Draft.ToLocalizedString() @@ -639,15 +639,15 @@ public static InvoiceStatusWrapper GetSample() } [Singletone] - public class InvoiceStatusWrapperHelper + public class InvoiceStatusDtoHelper { - public InvoiceStatusWrapperHelper() + public InvoiceStatusDtoHelper() { } - public InvoiceStatusWrapper Get(InvoiceStatus status) + public InvoiceStatusDto Get(InvoiceStatus status) { - return new InvoiceStatusWrapper + return new InvoiceStatusDto { Id = (int)status, Title = status.ToLocalizedString() diff --git a/products/ASC.CRM/Server/Model/ListItemWrapper.cs b/products/ASC.CRM/Server/ApiModels/ListItemDto.cs similarity index 66% rename from products/ASC.CRM/Server/Model/ListItemWrapper.cs rename to products/ASC.CRM/Server/ApiModels/ListItemDto.cs index bedd93300be..eae66bab971 100644 --- a/products/ASC.CRM/Server/Model/ListItemWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/ListItemDto.cs @@ -32,20 +32,20 @@ using System; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { #region History Category [DataContract(Name = "historyCategoryBase", Namespace = "")] - public class HistoryCategoryBaseWrapper : ListItemWrapper + public class HistoryCategoryBaseDto : ListItemDto { - public HistoryCategoryBaseWrapper() + public HistoryCategoryBaseDto() { } - public HistoryCategoryBaseWrapper(ListItem listItem) + public HistoryCategoryBaseDto(ListItem listItem) : base(listItem) { } @@ -56,9 +56,9 @@ public HistoryCategoryBaseWrapper(ListItem listItem) [DataMember] public String ImagePath { get; set; } - public static HistoryCategoryBaseWrapper GetSample() + public static HistoryCategoryBaseDto GetSample() { - return new HistoryCategoryBaseWrapper + return new HistoryCategoryBaseDto { Title = "Lunch", SortOrder = 10, @@ -70,23 +70,23 @@ public static HistoryCategoryBaseWrapper GetSample() } [DataContract(Name = "historyCategory", Namespace = "")] - public class HistoryCategoryWrapper : HistoryCategoryBaseWrapper + public class HistoryCategoryDto : HistoryCategoryBaseDto { - public HistoryCategoryWrapper() + public HistoryCategoryDto() { } - public HistoryCategoryWrapper(ListItem listItem) + public HistoryCategoryDto(ListItem listItem) : base(listItem) { } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } - public new static HistoryCategoryWrapper GetSample() + public new static HistoryCategoryDto GetSample() { - return new HistoryCategoryWrapper + return new HistoryCategoryDto { Title = "Lunch", SortOrder = 10, @@ -99,18 +99,18 @@ public HistoryCategoryWrapper(ListItem listItem) } [Scope] - public sealed class HistoryCategoryWrapperHelper + public sealed class HistoryCategoryDtoHelper { - public HistoryCategoryWrapperHelper(WebImageSupplier webImageSupplier) + public HistoryCategoryDtoHelper(WebImageSupplier webImageSupplier) { WebImageSupplier = webImageSupplier; } public WebImageSupplier WebImageSupplier { get; } - public HistoryCategoryBaseWrapper Get(ListItem listItem) + public HistoryCategoryBaseDto Get(ListItem listItem) { - return new HistoryCategoryBaseWrapper(listItem) + return new HistoryCategoryBaseDto(listItem) { ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) }; @@ -122,13 +122,13 @@ public HistoryCategoryBaseWrapper Get(ListItem listItem) #region Deal Milestone [DataContract(Name = "opportunityStagesBase", Namespace = "")] - public class DealMilestoneBaseWrapper : ListItemWrapper + public class DealMilestoneBaseDto : ListItemDto { - public DealMilestoneBaseWrapper() + public DealMilestoneBaseDto() { } - public DealMilestoneBaseWrapper(DealMilestone dealMilestone) + public DealMilestoneBaseDto(DealMilestone dealMilestone) { SuccessProbability = dealMilestone.Probability; StageType = dealMilestone.Status; @@ -143,9 +143,9 @@ public DealMilestoneBaseWrapper(DealMilestone dealMilestone) [DataMember] public DealMilestoneStatus StageType { get; set; } - public static DealMilestoneBaseWrapper GetSample() + public static DealMilestoneBaseDto GetSample() { - return new DealMilestoneBaseWrapper + return new DealMilestoneBaseDto { Title = "Discussion", SortOrder = 2, @@ -158,23 +158,23 @@ public static DealMilestoneBaseWrapper GetSample() } [DataContract(Name = "opportunityStages", Namespace = "")] - public class DealMilestoneWrapper : DealMilestoneBaseWrapper + public class DealMilestoneDto : DealMilestoneBaseDto { - public DealMilestoneWrapper() + public DealMilestoneDto() { } - public DealMilestoneWrapper(DealMilestone dealMilestone) + public DealMilestoneDto(DealMilestone dealMilestone) : base(dealMilestone) { } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } - public new static DealMilestoneWrapper GetSample() + public new static DealMilestoneDto GetSample() { - return new DealMilestoneWrapper + return new DealMilestoneDto { Title = "Discussion", SortOrder = 2, @@ -192,23 +192,23 @@ public DealMilestoneWrapper(DealMilestone dealMilestone) #region Task Category [DataContract(Name = "taskCategoryBase", Namespace = "")] - public class TaskCategoryBaseWrapper : ListItemWrapper + public class TaskCategoryBaseDto : ListItemDto { - public TaskCategoryBaseWrapper() + public TaskCategoryBaseDto() { } - public TaskCategoryBaseWrapper(ListItem listItem) : base(listItem) + public TaskCategoryBaseDto(ListItem listItem) : base(listItem) { } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String ImagePath { get; set; } - public static TaskCategoryBaseWrapper GetSample() + public static TaskCategoryBaseDto GetSample() { - return new TaskCategoryBaseWrapper + return new TaskCategoryBaseDto { Title = "Appointment", SortOrder = 2, @@ -219,23 +219,23 @@ public static TaskCategoryBaseWrapper GetSample() } [DataContract(Name = "taskCategory", Namespace = "")] - public class TaskCategoryWrapper : TaskCategoryBaseWrapper + public class TaskCategoryDto : TaskCategoryBaseDto { - public TaskCategoryWrapper() + public TaskCategoryDto() { } - public TaskCategoryWrapper(ListItem listItem): base(listItem) + public TaskCategoryDto(ListItem listItem): base(listItem) { } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } - public new static TaskCategoryWrapper GetSample() + public new static TaskCategoryDto GetSample() { - return new TaskCategoryWrapper + return new TaskCategoryDto { Id = 30, Title = "Appointment", @@ -249,18 +249,18 @@ public TaskCategoryWrapper(ListItem listItem): base(listItem) [Scope] - public sealed class TaskCategoryWrapperHelper + public sealed class TaskCategoryDtoHelper { - public TaskCategoryWrapperHelper(WebImageSupplier webImageSupplier) + public TaskCategoryDtoHelper(WebImageSupplier webImageSupplier) { WebImageSupplier = webImageSupplier; } public WebImageSupplier WebImageSupplier { get; } - public TaskCategoryBaseWrapper Get(ListItem listItem) + public TaskCategoryBaseDto Get(ListItem listItem) { - return new TaskCategoryBaseWrapper(listItem) + return new TaskCategoryBaseDto(listItem) { ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) }; @@ -278,20 +278,20 @@ public TaskCategoryBaseWrapper Get(ListItem listItem) #region Contact Status [DataContract(Name = "contactStatusBase", Namespace = "")] - public class ContactStatusBaseWrapper : ListItemWrapper + public class ContactStatusBaseDto : ListItemDto { - public ContactStatusBaseWrapper() + public ContactStatusBaseDto() { } - public ContactStatusBaseWrapper(ListItem listItem) + public ContactStatusBaseDto(ListItem listItem) : base(listItem) { } - public static ContactStatusBaseWrapper GetSample() + public static ContactStatusBaseDto GetSample() { - return new ContactStatusBaseWrapper + return new ContactStatusBaseDto { Title = "Cold", SortOrder = 2, @@ -301,23 +301,23 @@ public static ContactStatusBaseWrapper GetSample() } [DataContract(Name = "contactStatus", Namespace = "")] - public class ContactStatusWrapper : ContactStatusBaseWrapper + public class ContactStatusDto : ContactStatusBaseDto { - public ContactStatusWrapper() + public ContactStatusDto() { } - public ContactStatusWrapper(ListItem listItem) + public ContactStatusDto(ListItem listItem) : base(listItem) { } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } - public new static ContactStatusWrapper GetSample() + public new static ContactStatusDto GetSample() { - return new ContactStatusWrapper + return new ContactStatusDto { Title = "Cold", SortOrder = 2, @@ -332,21 +332,21 @@ public ContactStatusWrapper(ListItem listItem) #region Contact Type [DataContract(Name = "contactTypeBase", Namespace = "")] - public class ContactTypeBaseWrapper : ListItemWrapper + public class ContactTypeBaseDto : ListItemDto { - public ContactTypeBaseWrapper() + public ContactTypeBaseDto() { } - public ContactTypeBaseWrapper(ListItem listItem) + public ContactTypeBaseDto(ListItem listItem) : base(listItem) { } - public static ContactTypeBaseWrapper GetSample() + public static ContactTypeBaseDto GetSample() { - return new ContactTypeBaseWrapper + return new ContactTypeBaseDto { Id = 30, Title = "Client", @@ -357,23 +357,23 @@ public static ContactTypeBaseWrapper GetSample() } [DataContract(Name = "contactType", Namespace = "")] - public class ContactTypeWrapper : ContactTypeBaseWrapper + public class ContactTypeDto : ContactTypeBaseDto { - public ContactTypeWrapper() + public ContactTypeDto() { } - public ContactTypeWrapper(ListItem listItem) + public ContactTypeDto(ListItem listItem) : base(listItem) { } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } - public new static ContactTypeWrapper GetSample() + public new static ContactTypeDto GetSample() { - return new ContactTypeWrapper + return new ContactTypeDto { Id= 30, Title = "Client", @@ -388,16 +388,16 @@ public ContactTypeWrapper(ListItem listItem) #region Tags - [DataContract(Name = "tagWrapper", Namespace = "")] - public class TagWrapper + [DataContract(Name = "tagDto", Namespace = "")] + public class TagDto { - public TagWrapper() + public TagDto() { Title = String.Empty; RelativeItemsCount = 0; } - public TagWrapper(String tag, int relativeItemsCount = 0) + public TagDto(String tag, int relativeItemsCount = 0) { Title = tag; RelativeItemsCount = relativeItemsCount; @@ -406,12 +406,12 @@ public TagWrapper(String tag, int relativeItemsCount = 0) [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int RelativeItemsCount { get; set; } - public static TagWrapper GetSample() + public static TagDto GetSample() { - return new TagWrapper + return new TagDto { Title = "Tag", RelativeItemsCount = 1 @@ -422,14 +422,14 @@ public static TagWrapper GetSample() #endregion [DataContract(Name = "listItem", Namespace = "")] - public abstract class ListItemWrapper + public abstract class ListItemDto { - protected ListItemWrapper() + protected ListItemDto() { } - protected ListItemWrapper(ListItem listItem) + protected ListItemDto(ListItem listItem) { Title = listItem.Title; Description = listItem.Description; @@ -440,16 +440,16 @@ protected ListItemWrapper(ListItem listItem) [DataMember(Name = "id")] public int Id { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Color { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int SortOrder { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs b/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs similarity index 63% rename from products/ASC.CRM/Server/Model/OpportunityWrapper.cs rename to products/ASC.CRM/Server/ApiModels/OpportunityDto.cs index 702fbbd9529..424203a836b 100644 --- a/products/ASC.CRM/Server/Model/OpportunityWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs @@ -38,82 +38,82 @@ using System.Linq; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { /// /// Opportunity /// [DataContract(Name = "opportunity", Namespace = "")] - public class OpportunityWrapper + public class OpportunityDto { - public OpportunityWrapper() + public OpportunityDto() { } [DataMember(Name = "id")] public int Id { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public IEnumerable Members { get; set; } + + public IEnumerable Members { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactBaseWrapper Contact { get; set; } + + public ContactBaseDto Contact { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper Responsible { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public BidType BidType { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public decimal BidValue { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public CurrencyInfoWrapper BidCurrency { get; set; } + + public CurrencyInfoDto BidCurrency { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int PerPeriodValue { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public DealMilestoneBaseWrapper Stage { get; set; } + + public DealMilestoneBaseDto Stage { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int SuccessProbability { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime ActualCloseDate { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime ExpectedCloseDate { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool IsPrivate { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable AccessList { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool CanEdit { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public IEnumerable CustomFields { get; set; } + + public IEnumerable CustomFields { get; set; } - public static OpportunityWrapper GetSample() + public static OpportunityDto GetSample() { - return new OpportunityWrapper + return new OpportunityDto { CreateBy = EmployeeWraper.GetSample(), Created = ApiDateTime.GetSample(), @@ -121,49 +121,49 @@ public static OpportunityWrapper GetSample() Title = "Hotel catalogue", Description = "", ExpectedCloseDate = ApiDateTime.GetSample(), - Contact = ContactBaseWrapper.GetSample(), + Contact = ContactBaseDto.GetSample(), IsPrivate = false, SuccessProbability = 65, BidType = BidType.FixedBid, - Stage = DealMilestoneBaseWrapper.GetSample() + Stage = DealMilestoneBaseDto.GetSample() }; } } [Scope] - public class OpportunityWrapperHelper + public class OpportunityDtoHelper { - public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public OpportunityDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, CurrencyProvider currencyProvider, - ContactWrapperHelper contactBaseWrapperHelper, - CurrencyInfoWrapperHelper currencyInfoWrapperHelper + ContactDtoHelper contactBaseDtoHelper, + CurrencyInfoDtoHelper currencyInfoDtoHelper ) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; DaoFactory = daoFactory; - ContactBaseWrapperHelper = contactBaseWrapperHelper; + ContactBaseDtoHelper = contactBaseDtoHelper; CurrencyProvider = currencyProvider; - CurrencyInfoWrapperHelper = currencyInfoWrapperHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; } - public CurrencyInfoWrapperHelper CurrencyInfoWrapperHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } public CurrencyProvider CurrencyProvider {get;} - public ContactWrapperHelper ContactBaseWrapperHelper { get; } + public ContactDtoHelper ContactBaseDtoHelper { get; } public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - public OpportunityWrapper Get(Deal deal) + public OpportunityDto Get(Deal deal) { - var dealWrapper = new OpportunityWrapper + var dealDto = new OpportunityDto { Id = deal.ID, CreateBy = EmployeeWraperHelper.Get(deal.CreateBy), @@ -181,7 +181,7 @@ public OpportunityWrapper Get(Deal deal) }; if (deal.ContactID > 0) - dealWrapper.Contact = ContactBaseWrapperHelper.GetContactBaseWrapper(DaoFactory.GetContactDao().GetByID(deal.ContactID)); + dealDto.Contact = ContactBaseDtoHelper.GetContactBaseDto(DaoFactory.GetContactDao().GetByID(deal.ContactID)); if (deal.DealMilestoneID > 0) { @@ -190,34 +190,34 @@ public OpportunityWrapper Get(Deal deal) if (dealMilestone == null) throw new ItemNotFoundException(); - dealWrapper.Stage = new DealMilestoneBaseWrapper(dealMilestone); + dealDto.Stage = new DealMilestoneBaseDto(dealMilestone); } - dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal) + dealDto.AccessList = CRMSecurity.GetAccessSubjectTo(deal) .Select(item => EmployeeWraperHelper.Get(item.Key)); - dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal); + dealDto.IsPrivate = CRMSecurity.IsPrivate(deal); if (!string.IsNullOrEmpty(deal.BidCurrency)) - dealWrapper.BidCurrency = CurrencyInfoWrapperHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); + dealDto.BidCurrency = CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); - dealWrapper.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseWrapper(item)); + dealDto.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseDto(item)); - dealWrapper.Members = new List(); + dealDto.Members = new List(); var memberIDs = DaoFactory.GetDealDao().GetMembers(deal.ID); var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); - var membersWrapperList = new List(); + var membersDtoList = new List(); foreach (var member in membersList) { if (member == null) continue; - membersWrapperList.Add(ContactBaseWrapperHelper.GetContactBaseWrapper(member)); + membersDtoList.Add(ContactBaseDtoHelper.GetContactBaseDto(member)); } - dealWrapper.Members = membersWrapperList; + dealDto.Members = membersDtoList; - return dealWrapper; + return dealDto; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs b/products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs similarity index 73% rename from products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs rename to products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs index a07f3243041..0dcf507b393 100644 --- a/products/ASC.CRM/Server/Model/RelationshipEventWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs @@ -36,10 +36,10 @@ using System.Collections.Generic; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { [DataContract(Name = "entity", Namespace = "")] - public class EntityWrapper + public class EntityDto { [DataMember] public String EntityType { get; set; } @@ -50,9 +50,9 @@ public class EntityWrapper [DataMember] public String EntityTitle { get; set; } - public static EntityWrapper GetSample() + public static EntityDto GetSample() { - return new EntityWrapper + return new EntityDto { EntityId = 123445, EntityType = "opportunity", @@ -62,20 +62,20 @@ public static EntityWrapper GetSample() } [Scope] - public class EntityWrapperHelper + public class EntityDtoHelper { - public EntityWrapperHelper(DaoFactory daoFactory) + public EntityDtoHelper(DaoFactory daoFactory) { DaoFactory = daoFactory; } public DaoFactory DaoFactory { get; } - public EntityWrapper Get(EntityType entityType, int entityID) + public EntityDto Get(EntityType entityType, int entityID) { if (entityID == 0) return null; - var result = new EntityWrapper + var result = new EntityDto { EntityId = entityID }; @@ -109,9 +109,9 @@ public EntityWrapper Get(EntityType entityType, int entityID) } [DataContract(Name = "historyEvent", Namespace = "")] - public class RelationshipEventWrapper + public class RelationshipEventDto { - public RelationshipEventWrapper() + public RelationshipEventDto() { } @@ -119,7 +119,7 @@ public RelationshipEventWrapper() [DataMember(Name = "id")] public int Id { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] @@ -129,28 +129,28 @@ public RelationshipEventWrapper() public String Content { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] - public HistoryCategoryBaseWrapper Category { get; set; } + public HistoryCategoryBaseDto Category { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactBaseWrapper Contact { get; set; } + + public ContactBaseDto Contact { get; set; } [DataMember] - public EntityWrapper Entity { get; set; } + public EntityDto Entity { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool CanEdit { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public IEnumerable> Files { get; set; } - public static RelationshipEventWrapper GetSample() + public static RelationshipEventDto GetSample() { - return new RelationshipEventWrapper + return new RelationshipEventDto { CanEdit = true, - Category = HistoryCategoryBaseWrapper.GetSample(), - Entity = EntityWrapper.GetSample(), - Contact = ContactBaseWrapper.GetSample(), + Category = HistoryCategoryBaseDto.GetSample(), + Entity = EntityDto.GetSample(), + Contact = ContactBaseDto.GetSample(), Created = ApiDateTime.GetSample(), CreateBy = EmployeeWraper.GetSample(), Files = new[] { FileWrapper.GetSample() }, @@ -160,39 +160,39 @@ public static RelationshipEventWrapper GetSample() } [Scope] - public class RelationshipEventWrapperHelper + public class RelationshipEventDtoHelper { - public RelationshipEventWrapperHelper( + public RelationshipEventDtoHelper( ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - ContactWrapperHelper contactBaseWrapperHelper, + ContactDtoHelper contactBaseDtoHelper, FileWrapperHelper fileWrapperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, - EntityWrapperHelper entityWrapperHelper, - HistoryCategoryWrapperHelper historyCategoryWrapperHelper) + EntityDtoHelper entityDtoHelper, + HistoryCategoryDtoHelper historyCategoryDtoHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; DaoFactory = daoFactory; - ContactBaseWrapperHelper = contactBaseWrapperHelper; + ContactBaseDtoHelper = contactBaseDtoHelper; FileWrapperHelper = fileWrapperHelper; - EntityWrapperHelper = entityWrapperHelper; - HistoryCategoryWrapperHelper = historyCategoryWrapperHelper; + EntityDtoHelper = entityDtoHelper; + HistoryCategoryDtoHelper = historyCategoryDtoHelper; } - public HistoryCategoryWrapperHelper HistoryCategoryWrapperHelper { get; } + public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } public FileWrapperHelper FileWrapperHelper { get; } - public ContactWrapperHelper ContactBaseWrapperHelper { get; } + public ContactDtoHelper ContactBaseDtoHelper { get; } public DaoFactory DaoFactory { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - public EntityWrapperHelper EntityWrapperHelper { get; } - public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) + public EntityDtoHelper EntityDtoHelper { get; } + public RelationshipEventDto Get(RelationshipEvent relationshipEvent) { - var result = new RelationshipEventWrapper + var result = new RelationshipEventDto { Id = relationshipEvent.ID, CreateBy = EmployeeWraperHelper.Get(relationshipEvent.CreateBy), @@ -207,12 +207,12 @@ public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) if (historyCategory != null) { - result.Category = HistoryCategoryWrapperHelper.Get(historyCategory); + result.Category = HistoryCategoryDtoHelper.Get(historyCategory); } if (relationshipEvent.EntityID > 0) { - result.Entity = EntityWrapperHelper.Get(relationshipEvent.EntityType, relationshipEvent.EntityID); + result.Entity = EntityDtoHelper.Get(relationshipEvent.EntityType, relationshipEvent.EntityID); } result.Files = DaoFactory.GetRelationshipEventDao().GetFiles(relationshipEvent.ID).ConvertAll(file => FileWrapperHelper.Get(file)); @@ -222,7 +222,7 @@ public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent) var relativeContact = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); if (relativeContact != null) { - result.Contact = ContactBaseWrapperHelper.GetContactBaseWrapper(relativeContact); + result.Contact = ContactBaseDtoHelper.GetContactBaseDto(relativeContact); } } diff --git a/products/ASC.CRM/Server/Model/ReportWrapper.cs b/products/ASC.CRM/Server/ApiModels/ReportDto.cs similarity index 96% rename from products/ASC.CRM/Server/Model/ReportWrapper.cs rename to products/ASC.CRM/Server/ApiModels/ReportDto.cs index fece76b7da0..f3b16d094e6 100644 --- a/products/ASC.CRM/Server/Model/ReportWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/ReportDto.cs @@ -28,10 +28,10 @@ using System.Collections.Generic; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { [DataContract] - public class ReportWrapper + public class ReportDto { [DataMember] public String ReportTitle { get; set; } diff --git a/products/ASC.CRM/Server/Model/Dto/SaveNumberSettingsInDto.cs b/products/ASC.CRM/Server/ApiModels/SaveNumberSettingsInDto.cs similarity index 91% rename from products/ASC.CRM/Server/Model/Dto/SaveNumberSettingsInDto.cs rename to products/ASC.CRM/Server/ApiModels/SaveNumberSettingsInDto.cs index d1d1dadf5af..0412c80ab60 100644 --- a/products/ASC.CRM/Server/Model/Dto/SaveNumberSettingsInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/SaveNumberSettingsInDto.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Threading.Tasks; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class SaveNumberSettingsInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchCasesInDto.cs b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs similarity index 95% rename from products/ASC.CRM/Server/Model/Dto/SetAccessToBatchCasesInDto.cs rename to products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs index 27cca054071..d9241123bd4 100644 --- a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchCasesInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Threading.Tasks; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class SetAccessToBatchCasesByFilterInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchContactInDto.cs b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchContactInDto.cs similarity index 96% rename from products/ASC.CRM/Server/Model/Dto/SetAccessToBatchContactInDto.cs rename to products/ASC.CRM/Server/ApiModels/SetAccessToBatchContactInDto.cs index 67a11c78a8a..5ff038bdc5b 100644 --- a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchContactInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchContactInDto.cs @@ -7,7 +7,7 @@ using ASC.Api.Core; using ASC.CRM.Core.Enums; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class SetAccessToBatchContactByFilterInDto { diff --git a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchDealByFilterInDto.cs b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchDealByFilterInDto.cs similarity index 97% rename from products/ASC.CRM/Server/Model/Dto/SetAccessToBatchDealByFilterInDto.cs rename to products/ASC.CRM/Server/ApiModels/SetAccessToBatchDealByFilterInDto.cs index 6870e9f7530..b6b052bdba5 100644 --- a/products/ASC.CRM/Server/Model/Dto/SetAccessToBatchDealByFilterInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchDealByFilterInDto.cs @@ -7,7 +7,7 @@ using ASC.Api.Core; using ASC.CRM.Core.Enums; -namespace ASC.CRM.Model +namespace ASC.CRM.ApiModels { public class SetAccessToBatchDealByFilterInDto { diff --git a/products/ASC.CRM/Server/Model/Subject.cs b/products/ASC.CRM/Server/ApiModels/Subject.cs similarity index 98% rename from products/ASC.CRM/Server/Model/Subject.cs rename to products/ASC.CRM/Server/ApiModels/Subject.cs index 81a8dee81f0..2a99be247ca 100644 --- a/products/ASC.CRM/Server/Model/Subject.cs +++ b/products/ASC.CRM/Server/ApiModels/Subject.cs @@ -24,7 +24,7 @@ */ -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { public enum SubjectEnum { diff --git a/products/ASC.CRM/Server/Model/TaskWrapper.cs b/products/ASC.CRM/Server/ApiModels/TaskDto.cs similarity index 63% rename from products/ASC.CRM/Server/Model/TaskWrapper.cs rename to products/ASC.CRM/Server/ApiModels/TaskDto.cs index 4100c1a0540..6edf8629b47 100644 --- a/products/ASC.CRM/Server/Model/TaskWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/TaskDto.cs @@ -34,63 +34,63 @@ using System; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { /// /// Task /// [DataContract(Name = "task", Namespace = "")] - public class TaskWrapper + public class TaskDto { [DataMember(Name = "id")] public int Id { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper CreateBy { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime Created { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public ContactBaseWithEmailWrapper Contact { get; set; } + + public ContactBaseWithEmailDto Contact { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime DeadLine { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int AlertValue { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper Responsible { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool IsClosed { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public TaskCategoryBaseWrapper Category { get; set; } + + public TaskCategoryBaseDto Category { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public EntityWrapper Entity { get; set; } + + public EntityDto Entity { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool CanEdit { get; set; } - public static TaskWrapper GetSample() + public static TaskDto GetSample() { - return new TaskWrapper + return new TaskDto { Created = ApiDateTime.GetSample(), CreateBy = EmployeeWraper.GetSample(), DeadLine = ApiDateTime.GetSample(), IsClosed = false, Responsible = EmployeeWraper.GetSample(), - // Category = TaskCategoryBaseWrapper.GetSample(), + // Category = TaskCategoryBaseDto.GetSample(), CanEdit = true, Title = "Send a commercial offer", AlertValue = 0 @@ -99,52 +99,52 @@ public static TaskWrapper GetSample() } [DataContract(Name = "taskBase", Namespace = "")] - public class TaskBaseWrapper + public class TaskBaseDto { [DataMember(Name = "id")] public int Id { get; set; } - public TaskBaseWrapper() + public TaskBaseDto() { } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public ApiDateTime DeadLine { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public int AlertValue { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public EmployeeWraper Responsible { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool IsClosed { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public TaskCategoryBaseWrapper Category { get; set; } + + public TaskCategoryBaseDto Category { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public EntityWrapper Entity { get; set; } + + public EntityDto Entity { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public bool CanEdit { get; set; } - public static TaskBaseWrapper GetSample() + public static TaskBaseDto GetSample() { - return new TaskBaseWrapper + return new TaskBaseDto { DeadLine = ApiDateTime.GetSample(), IsClosed = false, Responsible = EmployeeWraper.GetSample(), - Category = TaskCategoryBaseWrapper.GetSample(), + Category = TaskCategoryBaseDto.GetSample(), CanEdit = true, Title = "Send a commercial offer", AlertValue = 0 @@ -153,33 +153,33 @@ public static TaskBaseWrapper GetSample() } [Scope] - public class TaskWrapperHelper + public class TaskDtoHelper { - public TaskWrapperHelper(ApiDateTimeHelper apiDateTimeHelper, + public TaskDtoHelper(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, - ContactWrapperHelper contactBaseWrapperHelper, - EntityWrapperHelper entityWrapperHelper) + ContactDtoHelper contactBaseDtoHelper, + EntityDtoHelper entityDtoHelper) { ApiDateTimeHelper = apiDateTimeHelper; EmployeeWraperHelper = employeeWraperHelper; CRMSecurity = cRMSecurity; DaoFactory = daoFactory; - ContactBaseWrapperHelper = contactBaseWrapperHelper; - EntityWrapperHelper = entityWrapperHelper; + ContactBaseDtoHelper = contactBaseDtoHelper; + EntityDtoHelper = entityDtoHelper; } - public ContactWrapperHelper ContactBaseWrapperHelper { get; } + public ContactDtoHelper ContactBaseDtoHelper { get; } public CRMSecurity CRMSecurity { get; } public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } public DaoFactory DaoFactory { get; } - public EntityWrapperHelper EntityWrapperHelper { get; } + public EntityDtoHelper EntityDtoHelper { get; } - public TaskBaseWrapper GetTaskBaseWrapper(Task task) + public TaskBaseDto GetTaskBaseDto(Task task) { - return new TaskBaseWrapper { + return new TaskBaseDto { Title = task.Title, Description = task.Description, DeadLine = ApiDateTimeHelper.Get(task.DeadLine), @@ -189,9 +189,9 @@ public TaskBaseWrapper GetTaskBaseWrapper(Task task) }; } - public TaskWrapper GetTaskWrapper(Task task) + public TaskDto GetTaskDto(Task task) { - var result = new TaskWrapper + var result = new TaskDto { Title = task.Title, Description = task.Description, @@ -205,7 +205,7 @@ public TaskWrapper GetTaskWrapper(Task task) { var categoryItem = DaoFactory.GetListItemDao().GetByID(task.CategoryID); - result.Category = new TaskCategoryWrapper(categoryItem) + result.Category = new TaskCategoryDto(categoryItem) { RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, categoryItem.ID) }; @@ -214,13 +214,13 @@ public TaskWrapper GetTaskWrapper(Task task) if (task.ContactID > 0) { - result.Contact = ContactBaseWrapperHelper.GetContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(task.ContactID)); + result.Contact = ContactBaseDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(task.ContactID)); } if (task.EntityID > 0) { - result.Entity = EntityWrapperHelper.Get(task.EntityType, task.EntityID); + result.Entity = EntityDtoHelper.Get(task.EntityType, task.EntityID); } result.CanEdit = CRMSecurity.CanEdit(task); diff --git a/products/ASC.CRM/Server/Model/TaskTemplateContainerWrapper.cs b/products/ASC.CRM/Server/ApiModels/TaskTemplateContainerDto.cs similarity index 80% rename from products/ASC.CRM/Server/Model/TaskTemplateContainerWrapper.cs rename to products/ASC.CRM/Server/ApiModels/TaskTemplateContainerDto.cs index 52a286131b5..4b8714dbc7e 100644 --- a/products/ASC.CRM/Server/Model/TaskTemplateContainerWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/TaskTemplateContainerDto.cs @@ -29,12 +29,12 @@ using System.Collections.Generic; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { [DataContract(Namespace = "taskTemplateContainer")] - public class TaskTemplateContainerWrapper + public class TaskTemplateContainerDto { - public TaskTemplateContainerWrapper() + public TaskTemplateContainerDto() { } @@ -48,27 +48,27 @@ public TaskTemplateContainerWrapper() [DataMember(IsRequired = true, EmitDefaultValue = true)] public String EntityType { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] - public IEnumerable Items { get; set; } + + public IEnumerable Items { get; set; } - public static TaskTemplateContainerWrapper GetSample() + public static TaskTemplateContainerDto GetSample() { - return new TaskTemplateContainerWrapper + return new TaskTemplateContainerDto { EntityType = "contact", Title = "Birthday greetings", - Items = new List + Items = new List { - TaskTemplateWrapper.GetSample() + TaskTemplateDto.GetSample() } }; } } [DataContract(Namespace = "taskTemplate")] - public class TaskTemplateWrapper + public class TaskTemplateDto { - public TaskTemplateWrapper() + public TaskTemplateDto() { } @@ -82,14 +82,14 @@ public TaskTemplateWrapper() [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = false)] + public String Description { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] public EmployeeWraper Responsible { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] - public TaskCategoryWrapper Category { get; set; } + public TaskCategoryDto Category { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool isNotify { get; set; } @@ -100,12 +100,12 @@ public TaskTemplateWrapper() [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool DeadLineIsFixed { get; set; } - public static TaskTemplateWrapper GetSample() + public static TaskTemplateDto GetSample() { - return new TaskTemplateWrapper + return new TaskTemplateDto { Title = "Send an Email", - Category = TaskCategoryWrapper.GetSample(), + Category = TaskCategoryDto.GetSample(), isNotify = true, Responsible = EmployeeWraper.GetSample(), ContainerID = 12, diff --git a/products/ASC.CRM/Server/Model/VoipCallWrapper.cs b/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs similarity index 89% rename from products/ASC.CRM/Server/Model/VoipCallWrapper.cs rename to products/ASC.CRM/Server/ApiModels/VoipCallDto.cs index b3828cd4bf0..5d2cb245d81 100644 --- a/products/ASC.CRM/Server/Model/VoipCallWrapper.cs +++ b/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs @@ -32,10 +32,10 @@ using System.Linq; using System.Runtime.Serialization; -namespace ASC.Api.CRM.Wrappers +namespace ASC.CRM.ApiModels { [DataContract(Name = "voipCall", Namespace = "")] - public class VoipCallWrapper + public class VoipCallDto { [DataMember(Order = 1)] public string Id { get; set; } @@ -62,10 +62,10 @@ public class VoipCallWrapper public decimal Cost { get; set; } [DataMember(Order = 11)] - public ContactWrapper Contact { get; set; } + public ContactDto Contact { get; set; } [DataMember(Order = 11, EmitDefaultValue = false)] - public IEnumerable Calls { get; set; } + public IEnumerable Calls { get; set; } [DataMember(Order = 13)] public string RecordUrl { get; set; } @@ -76,9 +76,9 @@ public class VoipCallWrapper } [Scope] - public class VoipCallWrapperHelper + public class VoipCallDtoHelper { - public VoipCallWrapperHelper(EmployeeWraperHelper employeeWraper, + public VoipCallDtoHelper(EmployeeWraperHelper employeeWraper, ApiDateTimeHelper apiDateTimeHelper) { EmployeeWraperHelper = employeeWraper; @@ -88,9 +88,9 @@ public VoipCallWrapperHelper(EmployeeWraperHelper employeeWraper, public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - public VoipCallWrapper Get(VoipCall call, ContactWrapper contact = null) + public VoipCallDto Get(VoipCall call, ContactDto contact = null) { - var result = new VoipCallWrapper + var result = new VoipCallDto { Id = call.Id, From = call.From, diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index 19f0480ebdf..a2bb7404bed 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -193,23 +193,23 @@ public CurrencyInfo DefaultCurrency } [DataMember(Name = "ChangeContactStatusGroupAuto")] - public string ChangeContactStatusGroupAutoWrapper { get; set; } + public string ChangeContactStatusGroupAutoDto { get; set; } [IgnoreDataMember] public Boolean? ChangeContactStatusGroupAuto { - get { return string.IsNullOrEmpty(ChangeContactStatusGroupAutoWrapper) ? null : (bool?)bool.Parse(ChangeContactStatusGroupAutoWrapper); } - set { ChangeContactStatusGroupAutoWrapper = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } + get { return string.IsNullOrEmpty(ChangeContactStatusGroupAutoDto) ? null : (bool?)bool.Parse(ChangeContactStatusGroupAutoDto); } + set { ChangeContactStatusGroupAutoDto = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } } [DataMember(Name = "AddTagToContactGroupAuto")] - public string AddTagToContactGroupAutoWrapper { get; set; } + public string AddTagToContactGroupAutoDto { get; set; } [IgnoreDataMember] public Boolean? AddTagToContactGroupAuto { - get { return string.IsNullOrEmpty(AddTagToContactGroupAutoWrapper) ? null : (bool?)bool.Parse(AddTagToContactGroupAutoWrapper); } - set { AddTagToContactGroupAutoWrapper = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } + get { return string.IsNullOrEmpty(AddTagToContactGroupAutoDto) ? null : (bool?)bool.Parse(AddTagToContactGroupAutoDto); } + set { AddTagToContactGroupAutoDto = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } } [DataMember(Name = "WriteMailToHistoryAuto")] diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index f7d8e0c6468..29a7befd287 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -375,8 +375,8 @@ public RelationshipEvent CreateItem(RelationshipEvent item) // if (msg == null) throw new ArgumentException("Mail message cannot be found"); - //var msgResponseWrapper = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg))); - //var msgRequestObj = msgResponseWrapper.Value("response"); + //var msgResponseDto = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg))); + //var msgRequestObj = msgResponseDto.Value("response"); //string messageUrl; //htmlBody = msgRequestObj.Value("htmlBody"); diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index fd50fa720b2..c7297981ac2 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -66,8 +66,8 @@ public SearchDao(DbContextManager dbContextManager, CRMSecurity cRMSecurity, TenantUtil tenantUtil, PathProvider pathProvider, - FactoryIndexerTask tasksWrapperIndexer, - FactoryIndexerInvoice invoicesWrapperIndexer, + FactoryIndexerTask tasksDtoIndexer, + FactoryIndexerInvoice invoicesDtoIndexer, IOptionsMonitor logger, ICache ascCache, WebImageSupplier webImageSupplier, @@ -79,8 +79,8 @@ BundleSearch bundleSearch logger, ascCache) { - FactoryIndexerTask = tasksWrapperIndexer; - FactoryIndexerInvoice = invoicesWrapperIndexer; + FactoryIndexerTask = tasksDtoIndexer; + FactoryIndexerInvoice = invoicesDtoIndexer; CRMSecurity = cRMSecurity; TenantUtil = tenantUtil; PathProvider = pathProvider; diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index bf3fe5b3232..1b4cb7ae0e1 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -37,7 +37,7 @@ public class BundleSearch { public BundleSearch(FactoryIndexerContact factoryIndexerContact, FactoryIndexerContactInfo factoryIndexerContactInfo, - FactoryIndexerFieldValue fieldsWrapperFactoryIndexer, + FactoryIndexerFieldValue factoryIndexerFieldValue, FactoryIndexerEvents factoryIndexerEvents, FactoryIndexerDeal factoryIndexerDeal, FactoryIndexerTask factoryIndexerTask, @@ -46,7 +46,7 @@ public BundleSearch(FactoryIndexerContact factoryIndexerContact, { FactoryIndexerContact = factoryIndexerContact; FactoryIndexerContactInfo = factoryIndexerContactInfo; - FactoryIndexerFieldValue = fieldsWrapperFactoryIndexer; + FactoryIndexerFieldValue = factoryIndexerFieldValue; FactoryIndexerEvents = factoryIndexerEvents; FactoryIndexerDeal = factoryIndexerDeal; FactoryIndexerTask = factoryIndexerTask; From 5e42dab1e9cc634ccc2081522abc9959b8d79982 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 10 Mar 2021 18:38:56 +0300 Subject: [PATCH 20/61] crm: refactoring --- .../ASC.CRM/Server/Api/BaseApiController.cs | 117 +++++++ products/ASC.CRM/Server/Api/CRMController.cs | 297 ------------------ ...Controller.Cases.cs => CasesController.cs} | 51 ++- ...ntactInfo.cs => ContactInfosController.cs} | 35 ++- ...ller.Contacts.cs => ContactsController.cs} | 275 +++++----------- ...ncyRates.cs => CurrencyRatesController.cs} | 32 +- ...tomFields.cs => CustomFieldsController.cs} | 32 +- ...Controller.Deals.cs => DealsController.cs} | 86 +++-- ...ller.Invoices.cs => InvoicesController.cs} | 119 ++++++- ...ler.ListItem.cs => ListItemsController.cs} | 36 ++- ...ent.cs => RelationshipEventsController.cs} | 87 +++-- ...roller.Reports.cs => ReportsController.cs} | 2 +- ...CRMController.Tag.cs => TagsController.cs} | 33 +- ...kTemplate.cs => TaskTemplateController.cs} | 28 +- ...Controller.Tasks.cs => TasksController.cs} | 45 ++- ...Controller.Utils.cs => UtilsController.cs} | 46 ++- ...RMController.Voip.cs => VoipController.cs} | 2 +- .../ASC.CRM/Server/ApiModels/ContactDto.cs | 183 ++++++++++- .../Server/{Api => Classes}/CRMCalendar.cs | 2 +- products/ASC.CRM/Server/Startup.cs | 18 +- 20 files changed, 901 insertions(+), 625 deletions(-) create mode 100644 products/ASC.CRM/Server/Api/BaseApiController.cs delete mode 100644 products/ASC.CRM/Server/Api/CRMController.cs rename products/ASC.CRM/Server/Api/{CRMController.Cases.cs => CasesController.cs} (93%) rename products/ASC.CRM/Server/Api/{CRMController.ContactInfo.cs => ContactInfosController.cs} (94%) rename products/ASC.CRM/Server/Api/{CRMController.Contacts.cs => ContactsController.cs} (91%) rename products/ASC.CRM/Server/Api/{CRMController.CurrencyRates.cs => CurrencyRatesController.cs} (89%) rename products/ASC.CRM/Server/Api/{CRMController.CustomFields.cs => CustomFieldsController.cs} (96%) rename products/ASC.CRM/Server/Api/{CRMController.Deals.cs => DealsController.cs} (93%) rename products/ASC.CRM/Server/Api/{CRMController.Invoices.cs => InvoicesController.cs} (94%) rename products/ASC.CRM/Server/Api/{CRMController.ListItem.cs => ListItemsController.cs} (97%) rename products/ASC.CRM/Server/Api/{CRMController.RelationshipEvent.cs => RelationshipEventsController.cs} (94%) rename products/ASC.CRM/Server/Api/{CRMController.Reports.cs => ReportsController.cs} (99%) rename products/ASC.CRM/Server/Api/{CRMController.Tag.cs => TagsController.cs} (97%) rename products/ASC.CRM/Server/Api/{CRMController.TaskTemplate.cs => TaskTemplateController.cs} (95%) rename products/ASC.CRM/Server/Api/{CRMController.Tasks.cs => TasksController.cs} (95%) rename products/ASC.CRM/Server/Api/{CRMController.Utils.cs => UtilsController.cs} (91%) rename products/ASC.CRM/Server/Api/{CRMController.Voip.cs => VoipController.cs} (99%) rename products/ASC.CRM/Server/{Api => Classes}/CRMCalendar.cs (99%) diff --git a/products/ASC.CRM/Server/Api/BaseApiController.cs b/products/ASC.CRM/Server/Api/BaseApiController.cs new file mode 100644 index 00000000000..4091e049bfb --- /dev/null +++ b/products/ASC.CRM/Server/Api/BaseApiController.cs @@ -0,0 +1,117 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.Core.Convention; +using ASC.Common; +using ASC.Common.Web; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Routing; + +using Microsoft.AspNetCore.Mvc; + +namespace ASC.Api.CRM +{ + [Scope] + [DefaultRoute] + [ApiController] + [ControllerName("crm")] + public abstract class BaseApiController : ControllerBase + { + public BaseApiController(DaoFactory daoFactory, CRMSecurity cRMSecurity) + { + DaoFactory = daoFactory; + CRMSecurity = cRMSecurity; + } + + protected DaoFactory DaoFactory { get; } + protected CRMSecurity CRMSecurity { get; } + + protected static EntityType ToEntityType(string entityTypeStr) + { + EntityType entityType; + + if (string.IsNullOrEmpty(entityTypeStr)) return EntityType.Any; + + switch (entityTypeStr.ToLower()) + { + case "person": + entityType = EntityType.Person; + break; + case "company": + entityType = EntityType.Company; + break; + case "contact": + entityType = EntityType.Contact; + break; + case "opportunity": + entityType = EntityType.Opportunity; + break; + case "case": + entityType = EntityType.Case; + break; + default: + entityType = EntityType.Any; + break; + } + + return entityType; + } + + protected string GetEntityTitle(EntityType entityType, int entityId, bool checkAccess, out DomainObject entity) + { + switch (entityType) + { + case EntityType.Contact: + case EntityType.Company: + case EntityType.Person: + var contact = (entity = DaoFactory.GetContactDao().GetByID(entityId)) as ASC.CRM.Core.Entities.Contact; + if (contact == null || (checkAccess && !CRMSecurity.CanAccessTo(contact))) + throw new ItemNotFoundException(); + return contact.GetTitle(); + case EntityType.Opportunity: + var deal = (entity = DaoFactory.GetDealDao().GetByID(entityId)) as Deal; + if (deal == null || (checkAccess && !CRMSecurity.CanAccessTo(deal))) + throw new ItemNotFoundException(); + return deal.Title; + case EntityType.Case: + var cases = (entity = DaoFactory.GetCasesDao().GetByID(entityId)) as Cases; + if (cases == null || (checkAccess && !CRMSecurity.CanAccessTo(cases))) + throw new ItemNotFoundException(); + return cases.Title; + default: + throw new ArgumentException("Invalid entityType: " + entityType); + } + } + + } +} diff --git a/products/ASC.CRM/Server/Api/CRMController.cs b/products/ASC.CRM/Server/Api/CRMController.cs deleted file mode 100644 index fc346fbdec6..00000000000 --- a/products/ASC.CRM/Server/Api/CRMController.cs +++ /dev/null @@ -1,297 +0,0 @@ -using ASC.Api.Core; -using ASC.CRM.ApiModels; -using ASC.Api.Documents; -using ASC.Common; -using ASC.Common.Web; -using ASC.Core; -using ASC.Core.Common.Settings; -using ASC.Core.Notify.Signalr; -using ASC.Core.Tenants; -using ASC.Core.Users; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.Data.Storage; -using ASC.ElasticSearch; -using ASC.MessagingSystem; -using ASC.VoipService; -using ASC.VoipService.Dao; -using ASC.Web.Api.Models; -using ASC.Web.Api.Routing; -using ASC.Web.Core.Users; -using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Core.Search; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Web.Files.Services.DocumentService; -using ASC.Web.Files.Services.WCFService; -using ASC.Web.Files.Utils; -using ASC.Web.Studio.Core; -using ASC.Web.Studio.Utility; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using System; - -namespace ASC.Api.CRM -{ - [Scope] - [DefaultRoute] - [ApiController] - public partial class CRMController : ControllerBase - { - public CRMController(CRMSecurity cRMSecurity, - DaoFactory daoFactory, - ApiContext apiContext, - MessageTarget messageTarget, - MessageService messageService, - NotifyClient notifyClient, - TaskDtoHelper taskDtoHelper, - SecurityContext securityContext, - UserManager userManager, - UserFormatter userFormatter, - CurrencyProvider currencyProvider, - Global global, - SettingsManager settingsManager, - IServiceProvider serviceProvider, - PdfCreator pdfCreator, - TenantManager tenantManager, - SetupInfo setupInfo, - FileSizeComment fileSizeComment, - AuthManager authManager, - FileUploader fileUploader, - ReportHelper reportHelper, - IHttpContextAccessor httpContextAccessor, - InvoiceSetting invoiceSetting, - OrganisationLogoManager organisationLogoManager, - ContactDtoHelper contactBaseDtoHelper, - ContactPhotoManager contactPhotoManager, - CommonLinkUtility commonLinkUtility, - StorageFactory storageFactory, - TenantUtil tenantUtil, - SignalrServiceClient signalrServiceClient, - VoipEngine voipEngine, - - Web.Files.Classes.FilesSettingsHelper filesSettingsHelper, - ASC.Files.Core.Data.DaoFactory filesDaoFactory, - - FileWrapperHelper fileWrapperHelper, - DisplayUserSettingsHelper displayUserSettingsHelper, - OpportunityDtoHelper opportunityDtoHelper, - EmployeeWraperHelper employeeWraperHelper, - ApiDateTimeHelper apiDateTimeHelper, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, - CurrencyRateDtoHelper currencyRateDtoHelper, - CasesDtoHelper casesDtoHelper, - InvoiceDtoHelper invoiceDtoHelper, - InvoiceItemDtoHelper invoiceItemDtoHelper, - InvoiceBaseDtoHelper invoiceBaseDtoHelper, - InvoiceLineDtoHelper invoiceLineDtoHelper, - InvoiceTaxDtoHelper invoiceTaxDtoHelper, - ContactInfoDtoHelper contactInfoDtoHelper, - HistoryCategoryDtoHelper historyCategoryBaseDtoHelper, - TaskCategoryDtoHelper taskCategoryDtoHelper, - VoipCallDtoHelper voipCallDtoHelper, - - RelationshipEventDtoHelper relationshipEventDtoHelper, - DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper, - - FactoryIndexerContactInfo factoryIndexerContactInfo, - FactoryIndexerCase factoryIndexerCase, - FactoryIndexerFieldValue factoryIndexerFieldValue, - - // ExportToCsv exportToCsv, - ImportFromCSV importFromCSV, - ImportFromCSVManager importFromCSVManager) - { - - VoipEngine = voipEngine; - SignalrServiceClient = signalrServiceClient; - - - TenantUtil = tenantUtil; - StorageFactory = storageFactory; - CommonLinkUtility = commonLinkUtility; - ContactPhotoManager = contactPhotoManager; - DaoFactory = daoFactory; - ApiContext = apiContext; - CRMSecurity = cRMSecurity; - MessageTarget = messageTarget; - MessageService = messageService; - NotifyClient = notifyClient; - TaskDtoHelper = taskDtoHelper; - SecurityContext = securityContext; - UserManager = userManager; - UserFormatter = userFormatter; - CurrencyProvider = currencyProvider; - OpportunityDtoHelper = opportunityDtoHelper; - EmployeeWraperHelper = employeeWraperHelper; - ApiDateTimeHelper = apiDateTimeHelper; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; - CurrencyRateDtoHelper = currencyRateDtoHelper; - CasesDtoHelper = casesDtoHelper; - ServiceProvider = serviceProvider; - - FactoryIndexerCase = factoryIndexerCase; - FactoryIndexerFieldValue = factoryIndexerFieldValue; - FactoryIndexerContactInfo = factoryIndexerContactInfo; - - InvoiceDtoHelper = invoiceDtoHelper; - InvoiceItemDtoHelper = invoiceItemDtoHelper; - InvoiceBaseDtoHelper = invoiceBaseDtoHelper; - InvoiceLineDtoHelper = invoiceLineDtoHelper; - InvoiceTaxDtoHelper = invoiceTaxDtoHelper; - RelationshipEventDtoHelper = relationshipEventDtoHelper; - FileWrapperHelper = fileWrapperHelper; - OrganisationLogoManager = organisationLogoManager; - - SetupInfo = setupInfo; - FileSizeComment = fileSizeComment; - TenantManager = tenantManager; - - AuthManager = authManager; - PdfCreator = pdfCreator; - FilesDaoFactory = filesDaoFactory; - - FilesSettingsHelper = filesSettingsHelper; - FileUploader = fileUploader; - Global = global; - ReportHelper = reportHelper; - HttpContextAccessor = httpContextAccessor; - DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; - InvoiceSetting = invoiceSetting; - - ContactInfoDtoHelper = contactInfoDtoHelper; - HistoryCategoryDtoHelper = historyCategoryBaseDtoHelper; - ContactDtoHelper = contactBaseDtoHelper; - VoipCallDtoHelper = voipCallDtoHelper; - - //ExportToCsv = exportToCsv; - ImportFromCSV = importFromCSV; - ImportFromCSVManager = importFromCSVManager; - } - - public ImportFromCSVManager ImportFromCSVManager { get; } - public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } - public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } - public ContactInfoDtoHelper ContactInfoDtoHelper { get; } - public VoipEngine VoipEngine { get; } - public SignalrServiceClient SignalrServiceClient { get; } - public IVoipProvider VoipProvider { get; } - public TenantUtil TenantUtil { get; } - public StorageFactory StorageFactory { get; } - public CommonLinkUtility CommonLinkUtility { get; } - public ContactPhotoManager ContactPhotoManager { get; } - public ContactDtoHelper ContactDtoHelper { get; } - public VoipCallDtoHelper VoipCallDtoHelper { get; } - public OrganisationLogoManager OrganisationLogoManager { get; } - public InvoiceSetting InvoiceSetting { get; } - public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } - public IHttpContextAccessor HttpContextAccessor { get; } - public ReportHelper ReportHelper { get; } - public FileUploader FileUploader { get; } - public Web.Files.Classes.FilesSettingsHelper FilesSettingsHelper { get; } - public ASC.Files.Core.Data.DaoFactory FilesDaoFactory { get; } - public FileWrapperHelper FileWrapperHelper { get; } - public RelationshipEventDtoHelper RelationshipEventDtoHelper { get; } - public AuthManager AuthManager { get; } - public FileSizeComment FileSizeComment { get; } - public SetupInfo SetupInfo { get; } - public TenantManager TenantManager { get; } - public PdfCreator PdfCreator { get; } - public InvoiceTaxDtoHelper InvoiceTaxDtoHelper { get; } - public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } - public InvoiceBaseDtoHelper InvoiceBaseDtoHelper { get; } - public InvoiceItemDtoHelper InvoiceItemDtoHelper { get; } - public InvoiceDtoHelper InvoiceDtoHelper { get; } - public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } - public FactoryIndexerFieldValue FactoryIndexerFieldValue { get; } - public FactoryIndexerCase FactoryIndexerCase { get; } - public IServiceProvider ServiceProvider { get; } - public CasesDtoHelper CasesDtoHelper { get; } - public CurrencyRateDtoHelper CurrencyRateDtoHelper { get; } - public SettingsManager SettingsManager { get; } - public Global Global { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public OpportunityDtoHelper OpportunityDtoHelper { get; } - public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } - public CurrencyProvider CurrencyProvider { get; } - public UserFormatter UserFormatter { get; } - public UserManager UserManager { get; } - public SecurityContext SecurityContext { get; } - public TaskDtoHelper TaskDtoHelper { get; } - public NotifyClient NotifyClient { get; } - - private readonly ApiContext ApiContext; - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } - public CRMSecurity CRMSecurity { get; } - public DaoFactory DaoFactory { get; } - // public ExportToCsv ExportToCsv { get; } - public ImportFromCSV ImportFromCSV { get; } - - private static EntityType ToEntityType(string entityTypeStr) - { - EntityType entityType; - - if (string.IsNullOrEmpty(entityTypeStr)) return EntityType.Any; - - switch (entityTypeStr.ToLower()) - { - case "person": - entityType = EntityType.Person; - break; - case "company": - entityType = EntityType.Company; - break; - case "contact": - entityType = EntityType.Contact; - break; - case "opportunity": - entityType = EntityType.Opportunity; - break; - case "case": - entityType = EntityType.Case; - break; - default: - entityType = EntityType.Any; - break; - } - - return entityType; - } - - - - - private string GetEntityTitle(EntityType entityType, int entityId, bool checkAccess, out DomainObject entity) - { - switch (entityType) - { - case EntityType.Contact: - case EntityType.Company: - case EntityType.Person: - var conatct = (entity = DaoFactory.GetContactDao().GetByID(entityId)) as ASC.CRM.Core.Entities.Contact; - if (conatct == null || (checkAccess && !CRMSecurity.CanAccessTo(conatct))) - throw new ItemNotFoundException(); - return conatct.GetTitle(); - case EntityType.Opportunity: - var deal = (entity = DaoFactory.GetDealDao().GetByID(entityId)) as Deal; - if (deal == null || (checkAccess && !CRMSecurity.CanAccessTo(deal))) - throw new ItemNotFoundException(); - return deal.Title; - case EntityType.Case: - var cases = (entity = DaoFactory.GetCasesDao().GetByID(entityId)) as Cases; - if (cases == null || (checkAccess && !CRMSecurity.CanAccessTo(cases))) - throw new ItemNotFoundException(); - return cases.Title; - default: - throw new ArgumentException("Invalid entityType: " + entityType); - } - } - } -} diff --git a/products/ASC.CRM/Server/Api/CRMController.Cases.cs b/products/ASC.CRM/Server/Api/CasesController.cs similarity index 93% rename from products/ASC.CRM/Server/Api/CRMController.Cases.cs rename to products/ASC.CRM/Server/Api/CasesController.cs index e5f0195d21e..42d1cff8c34 100644 --- a/products/ASC.CRM/Server/Api/CRMController.Cases.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -41,11 +41,50 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Api.CRM; +using ASC.CRM.Core.Dao; +using ASC.Api.Core; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Core.Users; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class CasesController : BaseApiController { + public CasesController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + NotifyClient notifyClient, + ContactDtoHelper contactBaseDtoHelper, + CasesDtoHelper casesDtoHelper, + SecurityContext securityContext, + DisplayUserSettingsHelper displayUserSettingsHelper, + UserManager userManager) + : base(daoFactory, cRMSecurity) + { + ApiContext = apiContext; + MessageTarget = messageTarget; + MessageService = messageService; + NotifyClient = notifyClient; + ContactDtoHelper = contactBaseDtoHelper; + CasesDtoHelper = casesDtoHelper; + SecurityContext = securityContext; + DisplayUserSettingsHelper = displayUserSettingsHelper; + UserManager = userManager; + } + + public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } + public SecurityContext SecurityContext { get; } + public CasesDtoHelper CasesDtoHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + public NotifyClient NotifyClient { get; } + private ApiContext ApiContext { get; } + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + public UserManager UserManager { get; } + /// /// Close the case with the ID specified in the request /// @@ -581,7 +620,7 @@ public IEnumerable GetCasesMembers(int caseid) var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); return contactIDs == null ? new ItemList() - : ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)); + : ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)); } /// @@ -612,7 +651,7 @@ public ContactDto AddMemberToCases(int caseid, int contactid) var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); - return ToContactDto(contact); + return ContactDtoHelper.ToContactDto(contact); } /// @@ -638,7 +677,7 @@ public ContactDto DeleteMemberFromCases(int caseid, int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ToContactDto(contact); + var result = ContactDtoHelper.ToContactDto(contact); DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); @@ -703,7 +742,7 @@ private IEnumerable ToListCasesDtos(ICollection items) var customFields = DaoFactory.GetCustomFieldDao() .GetEnityFields(EntityType.Case, casesIDs) .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseDto)); + .ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); diff --git a/products/ASC.CRM/Server/Api/CRMController.ContactInfo.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs similarity index 94% rename from products/ASC.CRM/Server/Api/CRMController.ContactInfo.cs rename to products/ASC.CRM/Server/Api/ContactInfosController.cs index fb3ed973dc7..7b5b0e0b1d2 100644 --- a/products/ASC.CRM/Server/Api/CRMController.ContactInfo.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -41,11 +41,40 @@ using System; using System.Collections.Generic; using System.Linq; - -namespace ASC.Api.CRM +using ASC.Api.CRM; +using ASC.CRM.Core.Dao; +using ASC.Api.Core; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Core; +using ASC.Web.Core.Users; + +namespace ASC.CRM.Api { - public partial class CRMController + public class ContactInfosController : BaseApiController { + public ContactInfosController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + NotifyClient notifyClient, + ContactDtoHelper contactBaseDtoHelper, + CasesDtoHelper casesDtoHelper, + SecurityContext securityContext, + DisplayUserSettingsHelper displayUserSettingsHelper, + UserManager userManager, + ContactInfoDtoHelper contactInfoDtoHelper) + : base(daoFactory, cRMSecurity) + { + MessageTarget = messageTarget; + MessageService = messageService; + ContactInfoDtoHelper = contactInfoDtoHelper; + } + + public ContactInfoDtoHelper ContactInfoDtoHelper { get; } + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + /// /// Returns the list of all available contact categories /// diff --git a/products/ASC.CRM/Server/Api/CRMController.Contacts.cs b/products/ASC.CRM/Server/Api/ContactsController.cs similarity index 91% rename from products/ASC.CRM/Server/Api/CRMController.Contacts.cs rename to products/ASC.CRM/Server/Api/ContactsController.cs index 55d8752d139..5e935293ed7 100644 --- a/products/ASC.CRM/Server/Api/CRMController.Contacts.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -24,20 +24,27 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Api.Collections; using ASC.Api.Core; -using ASC.CRM.ApiModels; -using ASC.Common.Threading.Progress; +using ASC.Api.CRM; using ASC.Common.Web; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; - using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Models; using ASC.Web.Api.Routing; using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Studio.Core; using Autofac; @@ -45,19 +52,64 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security; -using System.Web; - using Contact = ASC.CRM.Core.Entities.Contact; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class ContactsController : BaseApiController { + public ContactsController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + NotifyClient notifyClient, + TaskDtoHelper taskDtoHelper, + ContactDtoHelper contactBaseDtoHelper, + TaskCategoryDtoHelper taskCategoryDtoHelper, + SecurityContext securityContext, + OpportunityDtoHelper opportunityDtoHelper, + SetupInfo setupInfo, + UserFormatter userFormatter, + EmployeeWraperHelper employeeWraperHelper, + ContactPhotoManager contactPhotoManager, + FileSizeComment fileSizeComment, + ContactInfoDtoHelper contactInfoDtoHelper) + : base(daoFactory, cRMSecurity) + { + ApiContext = apiContext; + MessageTarget = messageTarget; + MessageService = messageService; + NotifyClient = notifyClient; + TaskDtoHelper = taskDtoHelper; + ContactDtoHelper = contactBaseDtoHelper; + TaskCategoryDtoHelper = taskCategoryDtoHelper; + SecurityContext = securityContext; + OpportunityDtoHelper = opportunityDtoHelper; + SetupInfo = setupInfo; + UserFormatter = userFormatter; + EmployeeWraperHelper = employeeWraperHelper; + ContactPhotoManager = contactPhotoManager; + FileSizeComment = fileSizeComment; + ContactInfoDtoHelper = contactInfoDtoHelper; + } + + public ContactInfoDtoHelper ContactInfoDtoHelper { get; } + public FileSizeComment FileSizeComment { get; } + public ContactPhotoManager ContactPhotoManager { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public UserFormatter UserFormatter { get; } + public SetupInfo SetupInfo { get; } + public SecurityContext SecurityContext { get; } + public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + public TaskDtoHelper TaskDtoHelper { get; } + public NotifyClient NotifyClient { get; } + private ApiContext ApiContext { get; } + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + public OpportunityDtoHelper OpportunityDtoHelper { get; } + /// /// Returns the detailed information about the contact with the ID specified in the request /// @@ -82,7 +134,7 @@ public IEnumerable GetContactsByID(IEnumerable contactid) { var contacts = DaoFactory.GetContactDao().GetContacts(contactid.ToArray()).Where(r => r != null && CRMSecurity.CanAccessTo(r)); - return ToListContactDto(contacts.ToList()); + return ContactDtoHelper.ToListContactDto(contacts.ToList()); } @@ -104,7 +156,7 @@ public IEnumerable GetContactsByProjectID(int projectid) if (projectid <= 0) throw new ArgumentException(); var contacts = DaoFactory.GetContactDao().GetContactsByProjectID(projectid); - return ToListContactDto(contacts.ToList()); + return ContactDtoHelper.ToListContactDto(contacts.ToList()); } ///// @@ -328,7 +380,7 @@ public IEnumerable GetContacts( if (contactsOrderBy != null) { - result = ToListContactDto(DaoFactory.GetContactDao().GetContacts( + result = ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -347,7 +399,7 @@ public IEnumerable GetContacts( } else { - result = ToListContactDto(DaoFactory.GetContactDao().GetContacts( + result = ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -612,7 +664,7 @@ public IEnumerable GetPeopleFromCompany(int companyid) var company = DaoFactory.GetContactDao().GetByID(companyid); if (company == null || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); - return ToListContactDto(DaoFactory.GetContactDao().GetMembers(companyid).Where(CRMSecurity.CanAccessTo).ToList()); + return ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetMembers(companyid).Where(CRMSecurity.CanAccessTo).ToList()); } /// @@ -1495,7 +1547,7 @@ public IEnumerable SetAccessToBatchContact( result.Add(contact); } - return ToListContactDto(result); + return ContactDtoHelper.ToListContactDto(result); } /// @@ -1728,7 +1780,7 @@ public IEnumerable GetContactsByContactInfo(ContactInfoType? infoTyp // return users; // } // catch (Exception ex) { - // throw new SocialMediaUI(DaoFactory).ProcessError(ex, "ASC.Api.CRM.CRMApi.FindTwitterProfiles"); + // throw new SocialMediaUI(DaoFactory).ProcessError(ex, "ASC.CRM.Api.CRMApi.FindTwitterProfiles"); // } //} @@ -2079,188 +2131,5 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList - { - contact - }).Single(); - } - - - private IEnumerable ToListContactDto(IReadOnlyList itemList) - { - if (itemList.Count == 0) return new List(); - - var result = new List(); - - var personsIDs = new List(); - var companyIDs = new List(); - var contactIDs = new int[itemList.Count]; - - var peopleCompanyIDs = new List(); - var peopleCompanyList = new Dictionary(); - - - var contactDao = DaoFactory.GetContactDao(); - - - for (var index = 0; index < itemList.Count; index++) - { - var contact = itemList[index]; - - if (contact is Company) - { - companyIDs.Add(contact.ID); - } - else - { - var person = contact as Person; - if (person != null) - { - personsIDs.Add(person.ID); - - if (person.CompanyID > 0) - { - peopleCompanyIDs.Add(person.CompanyID); - } - } - } - - contactIDs[index] = itemList[index].ID; - } - - if (peopleCompanyIDs.Count > 0) - { - var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactDtoHelper.GetContactBaseDtoQuick(item)); - var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); - - foreach (var contactBaseDtoQuick in tmpList) - { - contactBaseDtoQuick.CanDelete = contactBaseDtoQuick.CanEdit && tmpListCanDelete[contactBaseDtoQuick.Id]; - peopleCompanyList.Add(contactBaseDtoQuick.Id, contactBaseDtoQuick); - } - } - - var companiesMembersCount = contactDao.GetMembersCount(companyIDs.Distinct().ToArray()); - - var contactStatusIDs = itemList.Select(item => item.StatusID).Distinct().ToArray(); - var contactInfos = new Dictionary>(); - - var haveLateTask = DaoFactory.GetTaskDao().HaveLateTask(contactIDs); - var contactStatus = DaoFactory.GetListItemDao() - .GetItems(contactStatusIDs) - .ToDictionary(item => item.ID, item => new ContactStatusBaseDto(item)); - - var personsCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Person, personsIDs.ToArray()); - var companyCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Company, companyIDs.ToArray()); - - var customFields = personsCustomFields.Union(companyCustomFields) - .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseDto)); - - var addresses = new Dictionary>(); - var taskCount = DaoFactory.GetTaskDao().GetTasksCount(contactIDs); - - var contactTags = DaoFactory.GetTagDao().GetEntitiesTags(EntityType.Contact); - - DaoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( - item => - { - if (item.InfoType == ContactInfoType.Address) - { - if (!addresses.ContainsKey(item.ContactID)) - addresses.Add(item.ContactID, new List
    { new Address(item) }); - else - addresses[item.ContactID].Add(new Address(item)); - } - else - { - if (!contactInfos.ContainsKey(item.ContactID)) - contactInfos.Add(item.ContactID, new List { ContactInfoDtoHelper.Get(item) }); - else - contactInfos[item.ContactID].Add(ContactInfoDtoHelper.Get(item)); - } - } - ); - - - foreach (var contact in itemList) - { - ContactDto contactDto; - - var person = contact as Person; - if (person != null) - { - var people = person; - - var peopleDto = ContactDtoHelper.GetPersonDtoQuick(people); - - if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) - { - peopleDto.Company = peopleCompanyList[people.CompanyID]; - } - - contactDto = peopleDto; - } - else - { - var company = contact as Company; - if (company != null) - { - contactDto = ContactDtoHelper.GetCompanyDtoQuick(company); - - if (companiesMembersCount.ContainsKey(contactDto.Id)) - { - ((CompanyDto)contactDto).PersonsCount = companiesMembersCount[contactDto.Id]; - } - } - else - { - throw new ArgumentException(); - } - } - - if (contactTags.ContainsKey(contact.ID)) - { - contactDto.Tags = contactTags[contact.ID].OrderBy(x => x); - } - - if (addresses.ContainsKey(contact.ID)) - { - contactDto.Addresses = addresses[contact.ID]; - } - - contactDto.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); - - if (contactStatus.ContainsKey(contact.StatusID)) - { - contactDto.ContactStatus = contactStatus[contact.StatusID]; - } - - contactDto.HaveLateTasks = haveLateTask.ContainsKey(contact.ID) && haveLateTask[contact.ID]; - - contactDto.CustomFields = customFields.ContainsKey(contact.ID) ? customFields[contact.ID] : new List(); - - contactDto.TaskCount = taskCount.ContainsKey(contact.ID) ? taskCount[contact.ID] : 0; - - result.Add(contactDto); - } - - #region CanDelete for main contacts - - if (result.Count > 0) - { - var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Id).ToArray()); - foreach (var contactBaseDtoQuick in result) - { - contactBaseDtoQuick.CanDelete = contactBaseDtoQuick.CanEdit && resultListCanDelete[contactBaseDtoQuick.Id]; - } - } - - #endregion - - return result; - } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Api/CRMController.CurrencyRates.cs b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs similarity index 89% rename from products/ASC.CRM/Server/Api/CRMController.CurrencyRates.cs rename to products/ASC.CRM/Server/Api/CurrencyRatesController.cs index 30bfb35d1d6..704751891a8 100644 --- a/products/ASC.CRM/Server/Api/CRMController.CurrencyRates.cs +++ b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs @@ -24,22 +24,50 @@ */ +using ASC.Api.Core; +using ASC.Api.CRM; +using ASC.Core; using ASC.Core.Common.Settings; using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; +using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Services.NotifyService; using System; using System.Collections.Generic; using System.Linq; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class CurrencyRatesController : BaseApiController { + public CurrencyRatesController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + MessageService messageService, + CurrencyRateDtoHelper currencyRateDtoHelper, + SettingsManager settingsManager, + Global global, + CurrencyProvider currencyProvider) + : base(daoFactory, cRMSecurity) + { + MessageService = messageService; + CurrencyRateDtoHelper = currencyRateDtoHelper; + SettingsManager = settingsManager; + Global = global; + CurrencyProvider = currencyProvider; + } + + public CurrencyProvider CurrencyProvider { get; } + public SettingsManager SettingsManager { get; } + public Global Global { get; } + public CurrencyRateDtoHelper CurrencyRateDtoHelper { get; } + public MessageService MessageService { get; } + //TABLE `crm_currency_rate` column `rate` DECIMAL(10,2) NOT NULL public const decimal MaxRateValue = (decimal)99999999.99; diff --git a/products/ASC.CRM/Server/Api/CRMController.CustomFields.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs similarity index 96% rename from products/ASC.CRM/Server/Api/CRMController.CustomFields.cs rename to products/ASC.CRM/Server/Api/CustomFieldsController.cs index e8d122c6282..486cfc08ed1 100644 --- a/products/ASC.CRM/Server/Api/CRMController.CustomFields.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -24,25 +24,37 @@ */ -using ASC.CRM.ApiModels; +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.CRM; using ASC.Common.Web; +using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; using ASC.MessagingSystem; using ASC.Web.Api.Routing; -using ASC.Web.CRM.Core.Search; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class CustomFieldsController : BaseApiController { + public CustomFieldsController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + MessageTarget messageTarget, + MessageService messageService) + : base(daoFactory, cRMSecurity) + { + MessageTarget = messageTarget; + MessageService = messageService; + } + + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + /// /// Returns the list of descriptions for all existing user fields /// diff --git a/products/ASC.CRM/Server/Api/CRMController.Deals.cs b/products/ASC.CRM/Server/Api/DealsController.cs similarity index 93% rename from products/ASC.CRM/Server/Api/CRMController.Deals.cs rename to products/ASC.CRM/Server/Api/DealsController.cs index a575642516d..ca1996ff156 100644 --- a/products/ASC.CRM/Server/Api/CRMController.Deals.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -24,30 +24,73 @@ */ -using ASC.Api.Collections; +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Api.Core; -using ASC.CRM.ApiModels; +using ASC.Api.CRM; using ASC.Common.Web; using ASC.Core; using ASC.Core.Users; +using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Api.Models; using ASC.Web.Api.Routing; +using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; -using ASC.Web.Files.Services.WCFService; -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.CRM.Classes; - +using ASC.Web.CRM.Services.NotifyService; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class DealsController : BaseApiController { + public DealsController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + NotifyClient notifyClient, + ContactDtoHelper contactDtoHelper, + ContactInfoDtoHelper contactInfoDtoHelper, + OpportunityDtoHelper opportunityDtoHelper, + CurrencyProvider currencyProvider, + CurrencyInfoDtoHelper currencyInfoDtoHelper, + UserManager userManager, + EmployeeWraperHelper employeeWraperHelper, + DisplayUserSettingsHelper displayUserSettingsHelper) + : base(daoFactory, cRMSecurity) + { + ApiContext = apiContext; + MessageTarget = messageTarget; + MessageService = messageService; + NotifyClient = notifyClient; + OpportunityDtoHelper = opportunityDtoHelper; + CurrencyProvider = currencyProvider; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + UserManager = userManager; + EmployeeWraperHelper = employeeWraperHelper; + DisplayUserSettingsHelper = displayUserSettingsHelper; + ContactDtoHelper = contactDtoHelper; + } + + public ContactDtoHelper ContactDtoHelper { get; } + public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } + public NotifyClient NotifyClient { get; } + private ApiContext ApiContext { get; } + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + public OpportunityDtoHelper OpportunityDtoHelper { get; } + public SecurityContext SecurityContext { get; } + public CurrencyProvider CurrencyProvider { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } + public UserManager UserManager { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + /// /// Returns the detailed information about the opportunity with the ID specified in the request /// @@ -149,7 +192,7 @@ private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable accessListLocal.Contains(x.ID)); MessageService.Send(MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); } } @@ -200,7 +243,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealByFi var accessList = inDto.AccessList; var result = new List(); - + var deals = DaoFactory.GetDealDao() .GetDeals(ApiContext.FilterValue, responsibleid, @@ -210,7 +253,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealByFi stageType, contactAlsoIsParticipant, fromDate, toDate, 0, 0, null); - + if (!deals.Any()) return Enumerable.Empty(); foreach (var deal in deals) @@ -220,9 +263,9 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealByFi if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; SetAccessToDeal(deal.ID, isPrivate, accessList); - + result.Add(deal); - + } return ToListOpportunityDto(result); @@ -622,7 +665,7 @@ public OpportunityDto UpdateDeal( var accessList = inDto.AccessList; var customFieldList = inDto.CustomFieldList; var members = inDto.Members; - + var deal = DaoFactory.GetDealDao().GetByID(opportunityid); if (deal == null) throw new ItemNotFoundException(); @@ -690,9 +733,10 @@ public IEnumerable GetDealMembers(int opportunityid) if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); - if (contactIDs == null) return new ItemList(); + + if (contactIDs == null) return new List(); - var result = ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); + var result = ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); @@ -721,7 +765,7 @@ public ContactDto AddMemberToDeal(int opportunityid, int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ToContactDto(contact); + var result = ContactDtoHelper.ToContactDto(contact); DaoFactory.GetDealDao().AddMember(opportunityid, contactid); @@ -754,7 +798,7 @@ public ContactDto DeleteMemberFromDeal(int opportunityid, int contactid) var contact = DaoFactory.GetContactDao().GetByID(contactid); if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ToContactDto(contact); + var result = ContactDtoHelper.ToContactDto(contact); DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); @@ -872,7 +916,7 @@ private IEnumerable ToListOpportunityDto(ICollection deals var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseDto)); + .ToDictionary(item => item.Key, item => item.Select(x=> new CustomFieldBaseDto(x))); var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) .ToDictionary(item => item.ID, item => new DealMilestoneBaseDto(item)); diff --git a/products/ASC.CRM/Server/Api/CRMController.Invoices.cs b/products/ASC.CRM/Server/Api/InvoicesController.cs similarity index 94% rename from products/ASC.CRM/Server/Api/CRMController.Invoices.cs rename to products/ASC.CRM/Server/Api/InvoicesController.cs index b2ecb27692e..03c230e23e8 100644 --- a/products/ASC.CRM/Server/Api/CRMController.Invoices.cs +++ b/products/ASC.CRM/Server/Api/InvoicesController.cs @@ -44,11 +44,88 @@ using System; using System.Collections.Generic; using System.Linq; +using ASC.Api.CRM; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Core.Users; +using ASC.Core.Common.Settings; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class InvoicesController : BaseApiController { + public InvoicesController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + ContactDtoHelper contactBaseDtoHelper, + InvoiceDtoHelper invoiceDtoHelper, + ApiDateTimeHelper apiDateTimeHelper, + SettingsManager settingsManager, + FileWrapperHelper fileWrapperHelper, + PdfCreator pdfCreator, + CurrencyInfoDtoHelper currencyInfoDtoHelper, + InvoiceBaseDtoHelper invoiceBaseDtoHelper, + InvoiceItemDtoHelper invoiceItemDtoHelper, + Global global, + InvoiceLineDtoHelper invoiceLineDtoHelper, + InvoiceTaxDtoHelper invoiceTaxDtoHelper) + : base(daoFactory, cRMSecurity) + { + ApiContext = apiContext; + MessageTarget = messageTarget; + MessageService = messageService; + ContactDtoHelper = contactBaseDtoHelper; + InvoiceDtoHelper = invoiceDtoHelper; + ApiDateTimeHelper = apiDateTimeHelper; + SettingsManager = settingsManager; + PdfCreator = pdfCreator; + FileWrapperHelper = fileWrapperHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + InvoiceBaseDtoHelper = invoiceBaseDtoHelper; + InvoiceItemDtoHelper = invoiceItemDtoHelper; + Global = global; + InvoiceLineDtoHelper = invoiceLineDtoHelper; + InvoiceTaxDtoHelper = invoiceTaxDtoHelper; + } + + public InvoiceTaxDtoHelper InvoiceTaxDtoHelper { get; } + public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } + public Global Global { get; } + public InvoiceItemDtoHelper InvoiceItemDtoHelper { get; } + public InvoiceBaseDtoHelper InvoiceBaseDtoHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } + public FileWrapperHelper FileWrapperHelper { get; } + public PdfCreator PdfCreator { get; } + public SettingsManager SettingsManager { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public InvoiceDtoHelper InvoiceDtoHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + private ApiContext ApiContext { get; } + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + + + + + + + + + + + + + + + + + + + + + /// /// Returns the detailed information about the invoice with the ID specified in the request /// @@ -1507,5 +1584,43 @@ private IEnumerable ToListInvoiceBaseDtos(ICollection i return result; } + + private EntityDto ToEntityDto(EntityType entityType, int entityID) + { + if (entityID == 0) return null; + + var result = new EntityDto + { + EntityId = entityID + }; + + switch (entityType) + { + case EntityType.Case: + var caseObj = DaoFactory.GetCasesDao().GetByID(entityID); + if (caseObj == null) + return null; + + result.EntityType = "case"; + result.EntityTitle = caseObj.Title; + + break; + case EntityType.Opportunity: + var dealObj = DaoFactory.GetDealDao().GetByID(entityID); + + if (dealObj == null) + return null; + + result.EntityType = "opportunity"; + result.EntityTitle = dealObj.Title; + + break; + default: + return null; + } + + return result; + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Api/CRMController.ListItem.cs b/products/ASC.CRM/Server/Api/ListItemsController.cs similarity index 97% rename from products/ASC.CRM/Server/Api/CRMController.ListItem.cs rename to products/ASC.CRM/Server/Api/ListItemsController.cs index 064520e53ce..667d2c68fb0 100644 --- a/products/ASC.CRM/Server/Api/CRMController.ListItem.cs +++ b/products/ASC.CRM/Server/Api/ListItemsController.cs @@ -24,23 +24,43 @@ */ -using ASC.CRM.ApiModels; +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.CRM; using ASC.Common.Web; +using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Api.Routing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security; - -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class ListItemsController : BaseApiController { + public ListItemsController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + MessageTarget messageTarget, + MessageService messageService, + TaskCategoryDtoHelper taskCategoryDtoHelper, + HistoryCategoryDtoHelper historyCategoryDtoHelper) + : base(daoFactory, cRMSecurity) + { + MessageTarget = messageTarget; + MessageService = messageService; + TaskCategoryDtoHelper = taskCategoryDtoHelper; + HistoryCategoryDtoHelper = historyCategoryDtoHelper; + } + + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } + public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } + /// /// Creates an opportunity stage with the parameters (title, description, success probability, etc.) specified in the request /// diff --git a/products/ASC.CRM/Server/Api/CRMController.RelationshipEvent.cs b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs similarity index 94% rename from products/ASC.CRM/Server/Api/CRMController.RelationshipEvent.cs rename to products/ASC.CRM/Server/Api/RelationshipEventsController.cs index 51617b96a26..f86567dfccd 100644 --- a/products/ASC.CRM/Server/Api/CRMController.RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs @@ -33,27 +33,60 @@ using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Api.Routing; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Web.Files.Classes; using ASC.Web.Files.Utils; -using Microsoft.AspNetCore.Http; - using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net.Mime; using System.Text; using System.Text.RegularExpressions; using OrderBy = ASC.CRM.Core.Entities.OrderBy; +using ASC.Api.CRM; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Core; +using ASC.Web.Core.Users; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class RelationshipEventsController : BaseApiController { + public RelationshipEventsController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + ContactDtoHelper contactBaseDtoHelper, + RelationshipEventDtoHelper relationshipEventDtoHelper, + FileWrapperHelper fileWrapperHelper, + ASC.Files.Core.Data.DaoFactory filesDaoFactory, + FileUploader fileUploader, + HistoryCategoryDtoHelper historyCategoryDtoHelper) + : base(daoFactory, cRMSecurity) + { + ApiContext = apiContext; + MessageTarget = messageTarget; + MessageService = messageService; + ContactDtoHelper = contactBaseDtoHelper; + RelationshipEventDtoHelper = relationshipEventDtoHelper; + FileWrapperHelper = fileWrapperHelper; + FilesDaoFactory = filesDaoFactory; + FileUploader = fileUploader; + HistoryCategoryDtoHelper = historyCategoryDtoHelper; + } + + public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } + public FileUploader FileUploader { get; } + public ASC.Files.Core.Data.DaoFactory FilesDaoFactory { get; set; } + public FileWrapperHelper FileWrapperHelper { get; } + public RelationshipEventDtoHelper RelationshipEventDtoHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + private ApiContext ApiContext { get; } + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + /// /// Returns the list of all events matching the parameters specified in the request /// @@ -696,43 +729,7 @@ private IEnumerable ToListRelationshipEventDto(List /// Returns the list of all tags associated with the entity with the ID and type specified in the request ///
    diff --git a/products/ASC.CRM/Server/Api/CRMController.TaskTemplate.cs b/products/ASC.CRM/Server/Api/TaskTemplateController.cs similarity index 95% rename from products/ASC.CRM/Server/Api/CRMController.TaskTemplate.cs rename to products/ASC.CRM/Server/Api/TaskTemplateController.cs index f6dd867fd7e..832ecceb121 100644 --- a/products/ASC.CRM/Server/Api/CRMController.TaskTemplate.cs +++ b/products/ASC.CRM/Server/Api/TaskTemplateController.cs @@ -32,11 +32,30 @@ using System; using System.Collections.Generic; using System.Linq; - -namespace ASC.Api.CRM +using ASC.Api.CRM; +using ASC.CRM.Core; +using ASC.Api.Core; +using ASC.CRM.Core.Dao; +using ASC.Web.CRM.Services.NotifyService; +using ASC.MessagingSystem; +using ASC.Web.Api.Models; + +namespace ASC.CRM.Api { - public partial class CRMController + public class TaskTemplateController : BaseApiController { + public TaskTemplateController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + EmployeeWraperHelper employeeWraperHelper) + : base(daoFactory, cRMSecurity) + + { + EmployeeWraperHelper = employeeWraperHelper; + } + + public EmployeeWraperHelper EmployeeWraperHelper { get; } + + /// /// Creates a new task template container with the type and title specified in the request /// @@ -335,9 +354,10 @@ public TaskTemplateDto GetTaskTemplateByID(int id) protected TaskTemplateDto ToTaskTemplateDto(TaskTemplate taskTemplate) { + // TODO: set task template category return new TaskTemplateDto { - Category = GetTaskCategoryByID(taskTemplate.CategoryID), +// Category = GetTaskCategoryByID(taskTemplate.CategoryID), ContainerID = taskTemplate.ContainerID, DeadLineIsFixed = taskTemplate.DeadLineIsFixed, Description = taskTemplate.Description, diff --git a/products/ASC.CRM/Server/Api/CRMController.Tasks.cs b/products/ASC.CRM/Server/Api/TasksController.cs similarity index 95% rename from products/ASC.CRM/Server/Api/CRMController.Tasks.cs rename to products/ASC.CRM/Server/Api/TasksController.cs index 26100d65262..311e52b88b8 100644 --- a/products/ASC.CRM/Server/Api/CRMController.Tasks.cs +++ b/products/ASC.CRM/Server/Api/TasksController.cs @@ -1,6 +1,12 @@ -using ASC.Api.Core; -using ASC.CRM.ApiModels; +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.Core; +using ASC.Api.CRM; +using ASC.Common; using ASC.Common.Web; +using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -10,15 +16,38 @@ using ASC.Web.Api.Routing; using ASC.Web.CRM.Services.NotifyService; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class TasksController: BaseApiController { + public TasksController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ApiContext apiContext, + MessageTarget messageTarget, + MessageService messageService, + NotifyClient notifyClient, + TaskDtoHelper taskDtoHelper, + ContactDtoHelper contactBaseDtoHelper, + TaskCategoryDtoHelper taskCategoryDtoHelper) + : base(daoFactory, cRMSecurity) + { + ApiContext = apiContext; + MessageTarget = messageTarget; + MessageService = messageService; + NotifyClient = notifyClient; + TaskDtoHelper = taskDtoHelper; + ContactDtoHelper = contactBaseDtoHelper; + TaskCategoryDtoHelper = taskCategoryDtoHelper; + } + public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } + public ContactDtoHelper ContactDtoHelper { get; } + public TaskDtoHelper TaskDtoHelper { get; } + public NotifyClient NotifyClient { get; } + private ApiContext ApiContext { get; } + public MessageService MessageService { get; } + public MessageTarget MessageTarget { get; } + /// /// Returns the detailed information about the task with the ID specified in the request /// diff --git a/products/ASC.CRM/Server/Api/CRMController.Utils.cs b/products/ASC.CRM/Server/Api/UtilsController.cs similarity index 91% rename from products/ASC.CRM/Server/Api/CRMController.Utils.cs rename to products/ASC.CRM/Server/Api/UtilsController.cs index c2f96ea1a12..e5b76681e17 100644 --- a/products/ASC.CRM/Server/Api/CRMController.Utils.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -24,9 +24,13 @@ */ +using ASC.Api.Core; +using ASC.Api.CRM; using ASC.Common.Threading.Progress; +using ASC.Core.Common.Settings; using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; @@ -34,16 +38,54 @@ using ASC.Web.Api.Routing; using ASC.Web.Core.Utility; using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Services.NotifyService; using System; using System.Collections.Generic; using System.Linq; using System.Security; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { - public partial class CRMController + public class UtilsController : BaseApiController { + public UtilsController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + MessageService messageService, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + CurrencyInfoDtoHelper currencyInfoDtoHelper, + CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, + InvoiceSetting invoiceSetting, + ImportFromCSVManager importFromCSVManager, + OrganisationLogoManager organisationLogoManager, + Global global, + ImportFromCSV importFromCSV) + : base(daoFactory, cRMSecurity) + { + MessageService = messageService; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + CurrencyProvider = currencyProvider; + SettingsManager = settingsManager; + CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; + InvoiceSetting = invoiceSetting; + ImportFromCSVManager = importFromCSVManager; + OrganisationLogoManager = organisationLogoManager; + Global = global; + ImportFromCSV = importFromCSV; + } + + public ImportFromCSV ImportFromCSV { get; } + public Global Global { get; } + public OrganisationLogoManager OrganisationLogoManager { get; } + public ImportFromCSVManager ImportFromCSVManager { get; } + public InvoiceSetting InvoiceSetting { get; } + public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } + public SettingsManager SettingsManager { get; } + public CurrencyProvider CurrencyProvider { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } + public MessageService MessageService { get; } + /// /// Returns the list of all currencies currently available on the portal /// diff --git a/products/ASC.CRM/Server/Api/CRMController.Voip.cs b/products/ASC.CRM/Server/Api/VoipController.cs similarity index 99% rename from products/ASC.CRM/Server/Api/CRMController.Voip.cs rename to products/ASC.CRM/Server/Api/VoipController.cs index ef7e14cf397..43b648df748 100644 --- a/products/ASC.CRM/Server/Api/CRMController.Voip.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -47,7 +47,7 @@ //using System.Security; //using SecurityContext = ASC.Core.SecurityContext; -//namespace ASC.Api.CRM +//namespace ASC.CRM.Api //{ // public partial class CRMController // { diff --git a/products/ASC.CRM/Server/ApiModels/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ContactDto.cs index 34f97f319e7..7ed797d7158 100644 --- a/products/ASC.CRM/Server/ApiModels/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ContactDto.cs @@ -25,7 +25,7 @@ using ASC.Api.Core; -using ASC.Api.CRM; +using ASC.CRM.Api; using ASC.Common; using ASC.Common.Web; using ASC.CRM.Classes; @@ -420,6 +420,187 @@ public ContactBaseDto GetContactBaseDtoQuick(Contact contact) return result; } + public ContactDto ToContactDto(Contact contact) + { + return ToListContactDto(new List + { + contact + }).Single(); + } + + public IEnumerable ToListContactDto(IReadOnlyList itemList) + { + if (itemList.Count == 0) return new List(); + + var result = new List(); + + var personsIDs = new List(); + var companyIDs = new List(); + var contactIDs = new int[itemList.Count]; + + var peopleCompanyIDs = new List(); + var peopleCompanyList = new Dictionary(); + + + var contactDao = DaoFactory.GetContactDao(); + + + for (var index = 0; index < itemList.Count; index++) + { + var contact = itemList[index]; + + if (contact is Company) + { + companyIDs.Add(contact.ID); + } + else + { + var person = contact as Person; + if (person != null) + { + personsIDs.Add(person.ID); + + if (person.CompanyID > 0) + { + peopleCompanyIDs.Add(person.CompanyID); + } + } + } + + contactIDs[index] = itemList[index].ID; + } + + if (peopleCompanyIDs.Count > 0) + { + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => GetContactBaseDtoQuick(item)); + var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); + + foreach (var contactBaseDtoQuick in tmpList) + { + contactBaseDtoQuick.CanDelete = contactBaseDtoQuick.CanEdit && tmpListCanDelete[contactBaseDtoQuick.Id]; + peopleCompanyList.Add(contactBaseDtoQuick.Id, contactBaseDtoQuick); + } + } + + var companiesMembersCount = contactDao.GetMembersCount(companyIDs.Distinct().ToArray()); + + var contactStatusIDs = itemList.Select(item => item.StatusID).Distinct().ToArray(); + var contactInfos = new Dictionary>(); + + var haveLateTask = DaoFactory.GetTaskDao().HaveLateTask(contactIDs); + var contactStatus = DaoFactory.GetListItemDao() + .GetItems(contactStatusIDs) + .ToDictionary(item => item.ID, item => new ContactStatusBaseDto(item)); + + var personsCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Person, personsIDs.ToArray()); + var companyCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Company, companyIDs.ToArray()); + + var customFields = personsCustomFields.Union(companyCustomFields) + .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); + + var addresses = new Dictionary>(); + var taskCount = DaoFactory.GetTaskDao().GetTasksCount(contactIDs); + + var contactTags = DaoFactory.GetTagDao().GetEntitiesTags(EntityType.Contact); + + DaoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( + item => + { + if (item.InfoType == ContactInfoType.Address) + { + if (!addresses.ContainsKey(item.ContactID)) + addresses.Add(item.ContactID, new List
    { new Address(item) }); + else + addresses[item.ContactID].Add(new Address(item)); + } + else + { + if (!contactInfos.ContainsKey(item.ContactID)) + contactInfos.Add(item.ContactID, new List { ContactInfoDtoHelper.Get(item) }); + else + contactInfos[item.ContactID].Add(ContactInfoDtoHelper.Get(item)); + } + } + ); + + + foreach (var contact in itemList) + { + ContactDto contactDto; + + var person = contact as Person; + if (person != null) + { + var people = person; + + var peopleDto = GetPersonDtoQuick(people); + + if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) + { + peopleDto.Company = peopleCompanyList[people.CompanyID]; + } + + contactDto = peopleDto; + } + else + { + var company = contact as Company; + if (company != null) + { + contactDto = GetCompanyDtoQuick(company); + + if (companiesMembersCount.ContainsKey(contactDto.Id)) + { + ((CompanyDto)contactDto).PersonsCount = companiesMembersCount[contactDto.Id]; + } + } + else + { + throw new ArgumentException(); + } + } + + if (contactTags.ContainsKey(contact.ID)) + { + contactDto.Tags = contactTags[contact.ID].OrderBy(x => x); + } + + if (addresses.ContainsKey(contact.ID)) + { + contactDto.Addresses = addresses[contact.ID]; + } + + contactDto.CommonData = contactInfos.ContainsKey(contact.ID) ? contactInfos[contact.ID] : new List(); + + if (contactStatus.ContainsKey(contact.StatusID)) + { + contactDto.ContactStatus = contactStatus[contact.StatusID]; + } + + contactDto.HaveLateTasks = haveLateTask.ContainsKey(contact.ID) && haveLateTask[contact.ID]; + + contactDto.CustomFields = customFields.ContainsKey(contact.ID) ? customFields[contact.ID] : new List(); + + contactDto.TaskCount = taskCount.ContainsKey(contact.ID) ? taskCount[contact.ID] : 0; + + result.Add(contactDto); + } + + #region CanDelete for main contacts + + if (result.Count > 0) + { + var resultListCanDelete = contactDao.CanDelete(result.Select(item => item.Id).ToArray()); + foreach (var contactBaseDtoQuick in result) + { + contactBaseDtoQuick.CanDelete = contactBaseDtoQuick.CanEdit && resultListCanDelete[contactBaseDtoQuick.Id]; + } + } + + #endregion + + return result; + } public ContactBaseDto GetContactBaseDto(Contact contact) { diff --git a/products/ASC.CRM/Server/Api/CRMCalendar.cs b/products/ASC.CRM/Server/Classes/CRMCalendar.cs similarity index 99% rename from products/ASC.CRM/Server/Api/CRMCalendar.cs rename to products/ASC.CRM/Server/Classes/CRMCalendar.cs index 2e60e10580c..85c0285324a 100644 --- a/products/ASC.CRM/Server/Api/CRMCalendar.cs +++ b/products/ASC.CRM/Server/Classes/CRMCalendar.cs @@ -38,7 +38,7 @@ using System.Collections.Generic; using System.Globalization; -namespace ASC.Api.CRM +namespace ASC.CRM.Api { [Scope] public sealed class CRMCalendar : BaseCalendar diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 83769599723..bba1c04e437 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,7 +1,7 @@ using System.Text; using ASC.Api.Core; -using ASC.Api.CRM; +using ASC.CRM.Api; using ASC.Common; using Microsoft.Extensions.Configuration; @@ -23,8 +23,20 @@ public override void ConfigureServices(IServiceCollection services) Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - DIHelper.TryAdd(); - + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); } } } From 561739f490d020d1b1d0983a733b030769ede128 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Sat, 13 Mar 2021 15:22:14 +0300 Subject: [PATCH 21/61] crm: migrate HttpHandler to Middleware --- products/ASC.CRM/Server/ASC.CRM.csproj | 8 - .../ASC.CRM/Server/Api/DealsController.cs | 1 - .../ASC.CRM/Server/ApiModels/ContactDto.cs | 3 + products/ASC.CRM/Server/Classes/Global.cs | 2 +- .../HttpHandlers/ContactPhotoHandler.cs | 70 +-- .../Server/HttpHandlers/FileHandler.cs | 51 ++- .../HttpHandlers/FileUploaderHandler.cs | 73 +-- .../Server/HttpHandlers/ImportFileHandler.cs | 62 ++- .../HttpHandlers/OrganisationLogoHandler.cs | 80 ++-- .../HttpHandlers/WebToLeadFromHandler.cs | 429 ++++++++++-------- products/ASC.CRM/Server/Program.cs | 11 +- .../Server/Properties/launchSettings.json | 10 +- products/ASC.CRM/Server/Startup.cs | 62 ++- 13 files changed, 508 insertions(+), 354 deletions(-) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 6ba2256cccd..d4f6204b13a 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -4,13 +4,6 @@ netcoreapp3.1 - - - - - - - @@ -194,7 +187,6 @@ - diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index ca1996ff156..3d8ed408f8b 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -56,7 +56,6 @@ public DealsController(CRMSecurity cRMSecurity, MessageService messageService, NotifyClient notifyClient, ContactDtoHelper contactDtoHelper, - ContactInfoDtoHelper contactInfoDtoHelper, OpportunityDtoHelper opportunityDtoHelper, CurrencyProvider currencyProvider, CurrencyInfoDtoHelper currencyInfoDtoHelper, diff --git a/products/ASC.CRM/Server/ApiModels/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ContactDto.cs index 7ed797d7158..14af32f0555 100644 --- a/products/ASC.CRM/Server/ApiModels/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ContactDto.cs @@ -638,8 +638,11 @@ public ContactDto GetContactDto(Contact contact) ContactDto result; var person = contact as Person; + if (person != null) { + + var temp = (ContactDto)GetContactBaseDto(contact); var peopleDto = (PersonDto)GetContactBaseDto(contact); peopleDto.FirstName = person.FirstName; diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 98559cb2be7..7526a4161cc 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -48,7 +48,7 @@ namespace ASC.Web.CRM.Classes { - [Transient] + [Scope] public class Global { public Global(StorageFactory storageFactory, diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs index 78a06dd5b79..0c6401ddffb 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs @@ -24,6 +24,10 @@ */ + +using System; +using System.Text.Json; + using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -31,16 +35,15 @@ using ASC.MessagingSystem; using ASC.Web.Core; using ASC.Web.Core.Files; +using ASC.Web.Core.Utility; +using ASC.Web.CRM.Classes; using ASC.Web.CRM.Configuration; using ASC.Web.Studio.Core; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using System; -using System.Threading.Tasks; - -namespace ASC.Web.CRM.Classes +namespace ASC.Web.CRM.HttpHandlers { public class ContactPhotoHandlerMiddleware { @@ -51,66 +54,72 @@ public ContactPhotoHandlerMiddleware(RequestDelegate next) private readonly RequestDelegate _next; - public async Task Invoke(HttpContext context, + public async System.Threading.Tasks.Task Invoke(HttpContext context, SetupInfo setupInfo, CRMSecurity cRMSecurity, FileSizeComment fileSizeComment, WebItemSecurity webItemSecurity, MessageTarget messageTarget, MessageService messageService, - DaoFactory daoFactory) + DaoFactory daoFactory, + ContactPhotoManager contactPhotoManager) { - if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) - throw cRMSecurity.CreateSecurityException(); + //if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) + // throw cRMSecurity.CreateSecurityException(); context.Request.EnableBuffering(); - - - var contactId = Convert.ToInt32(context.Request["contactID"]); + var contactId = Convert.ToInt32(context.Request.Form["contactID"]); + Contact contact = null; if (contactId != 0) { contact = daoFactory.GetContactDao().GetByID(contactId); - if (!cRMSecurity.CanEdit(contact)) - throw cRMSecurity.CreateSecurityException(); + //if (!cRMSecurity.CanEdit(contact)) + // throw cRMSecurity.CreateSecurityException(); } var fileUploadResult = new FileUploadResult(); - if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; + if (context.Request.Form.Files.Count == 0) + { + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); + } - var file = new FileToUpload(context); + var fileName = context.Request.Form.Files[0].FileName; + var contentLength = context.Request.Form.Files[0].Length; - if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) + if (String.IsNullOrEmpty(fileName) || contentLength == 0) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); - if (0 < setupInfo.MaxImageUploadSize && setupInfo.MaxImageUploadSize < file.ContentLength) + if (0 < setupInfo.MaxImageUploadSize && setupInfo.MaxImageUploadSize < contentLength) { fileUploadResult.Success = false; fileUploadResult.Message = fileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false).HtmlEncode(); - return fileUploadResult; + + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } - if (FileUtility.GetFileTypeByFileName(file.FileName) != FileType.Image) + if (FileUtility.GetFileTypeByFileName(fileName) != FileType.Image) { fileUploadResult.Success = false; fileUploadResult.Message = CRMJSResource.ErrorMessage_NotImageSupportFormat.HtmlEncode(); - return fileUploadResult; + + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } - var uploadOnly = Convert.ToBoolean(context.Request["uploadOnly"]); - var tmpDirName = Convert.ToString(context.Request["tmpDirName"]); + var uploadOnly = Convert.ToBoolean(context.Request.Form["uploadOnly"]); + var tmpDirName = Convert.ToString(context.Request.Form["tmpDirName"]); try { ContactPhotoManager.PhotoData photoData; if (contactId != 0) { - photoData = ContactPhotoManager.UploadPhoto(file.InputStream, contactId, uploadOnly); + photoData = contactPhotoManager.UploadPhoto(context.Request.Form.Files[0].OpenReadStream(), contactId, uploadOnly); } else { @@ -118,7 +127,7 @@ public async Task Invoke(HttpContext context, { tmpDirName = Guid.NewGuid().ToString(); } - photoData = ContactPhotoManager.UploadPhotoToTemp(file.InputStream, tmpDirName); + photoData = contactPhotoManager.UploadPhotoToTemp(context.Request.Form.Files[0].OpenReadStream(), tmpDirName); } fileUploadResult.Success = true; @@ -128,7 +137,8 @@ public async Task Invoke(HttpContext context, { fileUploadResult.Success = false; fileUploadResult.Message = e.Message.HtmlEncode(); - return fileUploadResult; + + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } if (contact != null) @@ -139,7 +149,15 @@ public async Task Invoke(HttpContext context, } - return fileUploadResult; + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); + } + } + + public static class ContactPhotoHandlerMiddlewareExtensions + { + public static IApplicationBuilder UseContactPhotoHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs index 0bd1b39ed91..abc7d10da57 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs @@ -28,6 +28,8 @@ using ASC.Common.Logging; using ASC.CRM.Resources; using ASC.Web.CRM.Classes; + +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using System; @@ -36,28 +38,21 @@ namespace ASC.Web.CRM.HttpHandlers { - [Transient] - public class FileHandler + public class FileHandlerMiddleware { - public FileHandler(RequestDelegate next, - Global global, - ContactPhotoManager contactPhotoManager, - IOptionsMonitor logger) + private readonly RequestDelegate _next; + + public FileHandlerMiddleware(RequestDelegate next) { _next = next; - Global = global; - ContactPhotoManager = contactPhotoManager; - Logger = logger.Get("ASC"); } + + public async Task Invoke(HttpContext context, + Global global, + ContactPhotoManager contactPhotoManager) + { + context.Request.EnableBuffering(); - public ILog Logger { get; } - public ContactPhotoManager ContactPhotoManager { get; } - public Global Global { get; } - - private readonly RequestDelegate _next; - - public async Task InvokeAsync(HttpContext context) - { var action = context.Request.Query["action"]; switch (action) @@ -68,18 +63,18 @@ public async Task InvokeAsync(HttpContext context) var isCompany = Convert.ToBoolean(context.Request.Query["isc"]); var photoSize = Convert.ToInt32(context.Request.Query["ps"]); - string photoUrl = string.Empty; + string photoUrl; - switch (photoSize) + switch (photoSize) { case 1: - photoUrl = ContactPhotoManager.GetSmallSizePhoto(contactId, isCompany); + photoUrl = contactPhotoManager.GetSmallSizePhoto(contactId, isCompany); break; case 2: - photoUrl = ContactPhotoManager.GetMediumSizePhoto(contactId, isCompany); + photoUrl = contactPhotoManager.GetMediumSizePhoto(contactId, isCompany); break; case 3: - photoUrl = ContactPhotoManager.GetBigSizePhoto(contactId, isCompany); + photoUrl = contactPhotoManager.GetBigSizePhoto(contactId, isCompany); break; default: throw new Exception(CRMErrorsResource.ContactPhotoSizeUnknown); @@ -98,7 +93,7 @@ public async Task InvokeAsync(HttpContext context) string messageContent = string.Empty; - using (var streamReader = new StreamReader(Global.GetStore().GetReadStream("mail_messages", filePath))) + using (var streamReader = new StreamReader(global.GetStore().GetReadStream("mail_messages", filePath))) { messageContent = streamReader.ReadToEnd(); } @@ -113,4 +108,12 @@ public async Task InvokeAsync(HttpContext context) } } } -} \ No newline at end of file + + public static class FileHandlerMiddlewareExtensions + { + public static IApplicationBuilder UseFileHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs index 390f2f34858..0e550a3abd1 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs @@ -34,67 +34,72 @@ using System; using Microsoft.Extensions.DependencyInjection; using ASC.Web.Core.Utility; +using Microsoft.AspNetCore.Builder; +using System.Threading.Tasks; +using System.Text.Json; -namespace ASC.Web.CRM.Classes +namespace ASC.Web.CRM.HttpHandlers { - public class FileUploaderHandler + public class FileUploaderHandlerMiddleware { - public FileUploaderHandler(SetupInfo setupInfo, + private readonly RequestDelegate _next; + + public FileUploaderHandlerMiddleware(RequestDelegate next) + { + _next = next; + } + public async Task InvokeAsync(HttpContext context, + SetupInfo setupInfo, DaoFactory daoFactory, FileSizeComment fileSizeComment, IServiceProvider serviceProvider, TenantExtra tenantExtra, TenantStatisticsProvider tenantStatisticsProvider) { - SetupInfo = setupInfo; - DaoFactory = daoFactory; - FileSizeComment = fileSizeComment; - ServiceProvider = serviceProvider; - TenantExtra = tenantExtra; - TenantStatisticsProvider = tenantStatisticsProvider; - } - - public TenantExtra TenantExtra { get; } - public TenantStatisticsProvider TenantStatisticsProvider { get; } - public IServiceProvider ServiceProvider { get; } - public FileSizeComment FileSizeComment { get; } - public DaoFactory DaoFactory { get; } - public SetupInfo SetupInfo { get; } + context.Request.EnableBuffering(); - public FileUploadResult ProcessUpload(HttpContext context) - { var fileUploadResult = new FileUploadResult(); - if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; + if (context.Request.Form.Files.Count == 0) + { + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); + } - var file = new FileToUpload(context); - - if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) + var fileName = context.Request.Form.Files[0].FileName; + var contentLength = context.Request.Form.Files[0].Length; + + if (String.IsNullOrEmpty(fileName) || contentLength == 0) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); - if (0 < SetupInfo.MaxUploadSize(TenantExtra, TenantStatisticsProvider) && SetupInfo.MaxUploadSize(TenantExtra, TenantStatisticsProvider) < file.ContentLength) - throw FileSizeComment.FileSizeException; + if (0 < setupInfo.MaxUploadSize(tenantExtra, tenantStatisticsProvider) && setupInfo.MaxUploadSize(tenantExtra, tenantStatisticsProvider) < contentLength) + throw fileSizeComment.FileSizeException; - var fileName = file.FileName.LastIndexOf('\\') != -1 - ? file.FileName.Substring(file.FileName.LastIndexOf('\\') + 1) - : file.FileName; + fileName = fileName.LastIndexOf('\\') != -1 + ? fileName.Substring(fileName.LastIndexOf('\\') + 1) + : fileName; - var document = ServiceProvider.GetService>(); + var document = serviceProvider.GetService>(); document.Title = fileName; - document.FolderID = DaoFactory.GetFileDao().GetRoot(); - document.ContentLength = file.ContentLength; + document.FolderID = daoFactory.GetFileDao().GetRoot(); + document.ContentLength = contentLength; - document = DaoFactory.GetFileDao().SaveFile(document, file.InputStream); + document = daoFactory.GetFileDao().SaveFile(document, context.Request.Form.Files[0].OpenReadStream()); fileUploadResult.Data = document.ID; fileUploadResult.FileName = document.Title; fileUploadResult.FileURL = document.DownloadUrl; fileUploadResult.Success = true; + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); + } + } - return fileUploadResult; - + public static class FileUploaderHandlerMiddlewareExtensions + { + public static IApplicationBuilder UseFileUploaderHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs index 805ea7a5bd6..3c1dea2871f 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs @@ -27,55 +27,67 @@ using ASC.CRM.Core; using ASC.Web.Core; using ASC.Web.Core.Utility; +using ASC.Web.CRM.Classes; using ASC.Web.CRM.Configuration; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using System; +using System.Text.Json; +using System.Threading.Tasks; - -namespace ASC.Web.CRM.Classes +namespace ASC.Web.CRM.HttpHandlers { - public class ImportFileHandler + public class ImportFileHandlerMiddleware { - public ImportFileHandler(WebItemSecurity webItemSecurity, - CRMSecurity cRMSecurity, - Global global) + private readonly RequestDelegate _next; + + public ImportFileHandlerMiddleware( + RequestDelegate next) { - CRMSecurity = cRMSecurity; - WebItemSecurity = webItemSecurity; - Global = global; + _next = next; } - public Global Global { get; } - public CRMSecurity CRMSecurity { get; } - public WebItemSecurity WebItemSecurity { get; } - - public FileUploadResult ProcessUpload(HttpContext context) + public async Task Invoke(HttpContext context, + WebItemSecurity webItemSecurity, + CRMSecurity cRMSecurity, + Global global, + ImportFromCSV importFromCSV) { - if (!WebItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) - throw CRMSecurity.CreateSecurityException(); + if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) + throw cRMSecurity.CreateSecurityException(); var fileUploadResult = new FileUploadResult(); - if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; - - var file = new FileToUpload(context); + if (context.Request.Form.Files.Count == 0) + { + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); + } + var fileName = context.Request.Form.Files[0].FileName; + var contentLength = context.Request.Form.Files[0].Length; + String assignedPath; - Global.GetStore().SaveTemp("temp", out assignedPath, file.InputStream); - - file.InputStream.Position = 0; - - var jObject = ImportFromCSV.GetInfo(file.InputStream, context.Request["importSettings"]); + global.GetStore().SaveTemp("temp", out assignedPath, context.Request.Form.Files[0].OpenReadStream()); + + var jObject = importFromCSV.GetInfo(context.Request.Form.Files[0].OpenReadStream(), context.Request.Form["importSettings"]); jObject.Add("assignedPath", assignedPath); fileUploadResult.Success = true; fileUploadResult.Data = Global.EncodeTo64(jObject.ToString()); - return fileUploadResult; + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); + } + } + + public static class ImportFileHandlerMiddlewareExtensions + { + public static IApplicationBuilder UseImportFileHandlerHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs index c5aca4eed98..62c9824535d 100644 --- a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs @@ -29,76 +29,96 @@ using ASC.CRM.Resources; using ASC.Web.Core.Files; using ASC.Web.Core.Utility; +using ASC.Web.CRM.Classes; using ASC.Web.Studio.Core; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using System; using System.IO; +using System.Text.Json; -namespace ASC.Web.CRM.Classes +namespace ASC.Web.CRM.HttpHandlers { - public class OrganisationLogoHandler + public class OrganisationLogoHandlerMiddleware { - public OrganisationLogoHandler(CRMSecurity cRMSecurity, - SetupInfo setupInfo, - FileSizeComment fileSizeComment) + private readonly RequestDelegate _next; + + public OrganisationLogoHandlerMiddleware( + RequestDelegate next + ) { - CRMSecurity = cRMSecurity; - SetupInfo = setupInfo; - FileSizeComment = fileSizeComment; + _next = next; } - public OrganisationLogoManager OrganisationLogoManager { get; } - public ContactPhotoManager ContactPhotoManager { get; } - public FileSizeComment FileSizeComment { get; } - public SetupInfo SetupInfo { get; } - public CRMSecurity CRMSecurity { get; } - - public FileUploadResult ProcessUpload(HttpContext context) + public async System.Threading.Tasks.Task Invoke(HttpContext context, + CRMSecurity cRMSecurity, + SetupInfo setupInfo, + FileSizeComment fileSizeComment, + ContactPhotoManager contactPhotoManager, + OrganisationLogoManager organisationLogoManager) { - if (!CRMSecurity.IsAdmin) - throw CRMSecurity.CreateSecurityException(); + context.Request.EnableBuffering(); + + if (!cRMSecurity.IsAdmin) + throw cRMSecurity.CreateSecurityException(); var fileUploadResult = new FileUploadResult(); - if (!FileToUpload.HasFilesToUpload(context)) return fileUploadResult; + if (context.Request.Form.Files.Count == 0) + { + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); + } - var file = new FileToUpload(context); + var fileName = context.Request.Form.Files[0].FileName; + var contentLength = context.Request.Form.Files[0].Length; - if (String.IsNullOrEmpty(file.FileName) || file.ContentLength == 0) + if (String.IsNullOrEmpty(fileName) || contentLength == 0) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); - if (0 < SetupInfo.MaxImageUploadSize && SetupInfo.MaxImageUploadSize < file.ContentLength) + if (0 < setupInfo.MaxImageUploadSize && setupInfo.MaxImageUploadSize < contentLength) { fileUploadResult.Success = false; - fileUploadResult.Message = FileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false).HtmlEncode(); - return fileUploadResult; + fileUploadResult.Message = fileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false).HtmlEncode(); + + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } - if (FileUtility.GetFileTypeByFileName(file.FileName) != FileType.Image) + if (FileUtility.GetFileTypeByFileName(fileName) != FileType.Image) { fileUploadResult.Success = false; fileUploadResult.Message = CRMJSResource.ErrorMessage_NotImageSupportFormat.HtmlEncode(); - return fileUploadResult; + + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } try { - var imageData = Global.ToByteArray(file.InputStream); - var imageFormat = ContactPhotoManager.CheckImgFormat(imageData); - var photoUri = OrganisationLogoManager.UploadLogo(imageData, imageFormat); + var imageData = Global.ToByteArray(context.Request.Form.Files[0].OpenReadStream()); + var imageFormat = contactPhotoManager.CheckImgFormat(imageData); + var photoUri = organisationLogoManager.UploadLogo(imageData, imageFormat); fileUploadResult.Success = true; fileUploadResult.Data = photoUri; - return fileUploadResult; + + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } catch (Exception exception) { fileUploadResult.Success = false; fileUploadResult.Message = exception.Message.HtmlEncode(); - return fileUploadResult; + + await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } } } + + public static class OrganisationLogoHandlerMiddlewareExtensions + { + public static IApplicationBuilder UseOrganisationLogoHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs index 9c0d0a57b8b..9e345d2da36 100644 --- a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs @@ -24,9 +24,18 @@ */ -using ASC.Common; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Net; +using System.Text; +using System.Web; + using ASC.Common.Logging; using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -36,35 +45,34 @@ using ASC.Web.Core; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Configuration; -using ASC.Web.CRM.Core; using ASC.Web.CRM.Services.NotifyService; -using Autofac; - +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using System.Text; -using System.Web; - namespace ASC.Web.CRM.HttpHandlers { - public class WebToLeadFromHandler + public class WebToLeadFromHandlerMiddleware { private HttpContext _context; private readonly RequestDelegate _next; - public Global Global { get; } - public WebItemSecurity WebItemSecurity { get; } - public SecurityContext SecurityContext { get; } - public CRMSecurity CRMSecurity { get; } - - public WebToLeadFromHandler(RequestDelegate next) + public Global Global { get; set; } + public WebItemSecurity WebItemSecurity { get; set; } + public SecurityContext SecurityContext { get; set; } + public CRMSecurity CRMSecurity { get; set; } + public MessageTarget MessageTarget { get; set; } + public ILog Logger { get; set; } + public NotifyClient NotifyClient { get; set; } + public MessageService MessageService { get; set; } + public SettingsManager SettingsManager { get; set; } + public DaoFactory DaoFactory { get; set; } + public WebToLeadFromHandlerMiddleware( + RequestDelegate next +) { _next = next; } @@ -85,6 +93,8 @@ private bool CheckPermission() var webFromKeyAsGuid = new Guid(webFromKey); + var TenantSettings = SettingsManager.Load(); + return TenantSettings.WebFormKey == webFromKeyAsGuid; } catch (Exception) @@ -93,247 +103,268 @@ private bool CheckPermission() } } - public async Task InvokeAsync(HttpContext context) + public async System.Threading.Tasks.Task Invoke(HttpContext context, + WebItemSecurity webItemSecurity, + SecurityContext securityContext, + CRMSecurity cRMSecurity, + MessageTarget messageTarget, + MessageService messageService, + Global global, + IOptionsMonitor logger, + NotifyClient notifyClient, + SettingsManager settingsManager, + DaoFactory daoFactory) { try { - using (var scope = DIHelper.Resolve()) - { - var daoFactory = scope.Resolve(); - _context = context; + WebItemSecurity = webItemSecurity; + SecurityContext = securityContext; + CRMSecurity = cRMSecurity; + MessageTarget = messageTarget; + MessageService = messageService; + Global = global; + Logger = logger.Get("ASC.CRM"); + NotifyClient = notifyClient; + SettingsManager = settingsManager; - SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); + _context = context; - if (!CheckPermission()) - { - throw new Exception(CRMSettingResource.WebToLeadsForm_InvalidKeyException); - } + SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); - var productInfo = WebItemSecurity.GetSecurityInfo(ProductEntryPoint.ID.ToString()); - if (!productInfo.Enabled) - { - throw new Exception(CRMCommonResource.CRMProductIsDisabled); - } + if (!CheckPermission()) + { + throw new Exception(CRMSettingResource.WebToLeadsForm_InvalidKeyException); + } - Contact contact; + var productInfo = WebItemSecurity.GetSecurityInfo(ProductEntryPoint.ID.ToString()); + if (!productInfo.Enabled) + { + throw new Exception(CRMCommonResource.CRMProductIsDisabled); + } + + Contact contact; - var fieldCollector = new NameValueCollection(); + var fieldCollector = new NameValueCollection(); - var addressTemplate = new JObject(); - foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) - addressTemplate.Add(addressPartName.ToLower(), ""); - var addressTemplateStr = addressTemplate.ToString(); + var addressTemplate = new JObject(); + foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) + addressTemplate.Add(addressPartName.ToLower(), ""); + var addressTemplateStr = addressTemplate.ToString(); - var isCompany = false; + var isCompany = false; - var isCompanyString = GetValue("is_company"); - var firstName = GetValue("firstName"); - var lastName = GetValue("lastName"); - var companyName = GetValue("companyName"); + var isCompanyString = GetValue("is_company"); + var firstName = GetValue("firstName"); + var lastName = GetValue("lastName"); + var companyName = GetValue("companyName"); - if (!String.IsNullOrEmpty(isCompanyString)) + if (!String.IsNullOrEmpty(isCompanyString)) + { + if (!Boolean.TryParse(isCompanyString, out isCompany)) { - if (!Boolean.TryParse(isCompanyString, out isCompany)) - { - throw new ArgumentException(); - } + throw new ArgumentException(); } - else //old scheme + } + else //old scheme + { + if (!String.IsNullOrEmpty(firstName)) { - if (!String.IsNullOrEmpty(firstName)) - { - isCompany = false; - } - else if (!String.IsNullOrEmpty(companyName)) - { - isCompany = true; - } - else - { - throw new ArgumentException(); - } + isCompany = false; } - - - if (isCompany) + else if (!String.IsNullOrEmpty(companyName)) { - contact = new Company(); - - ((Company)contact).CompanyName = companyName; - - fieldCollector.Add(CRMContactResource.CompanyName, companyName); + isCompany = true; } else { - contact = new Person(); + throw new ArgumentException(); + } + } - ((Person)contact).FirstName = firstName; - ((Person)contact).LastName = lastName; - ((Person)contact).JobTitle = GetValue("jobTitle"); - fieldCollector.Add(CRMContactResource.FirstName, firstName); - fieldCollector.Add(CRMContactResource.LastName, lastName); + if (isCompany) + { + contact = new Company(); - if (!String.IsNullOrEmpty(GetValue("jobTitle"))) - fieldCollector.Add(CRMContactResource.JobTitle, ((Person)contact).JobTitle); - } + ((Company)contact).CompanyName = companyName; - contact.About = GetValue("about"); + fieldCollector.Add(CRMContactResource.CompanyName, companyName); + } + else + { + contact = new Person(); - if (!String.IsNullOrEmpty(contact.About)) - fieldCollector.Add(CRMContactResource.About, contact.About); + ((Person)contact).FirstName = firstName; + ((Person)contact).LastName = lastName; + ((Person)contact).JobTitle = GetValue("jobTitle"); - if (!String.IsNullOrEmpty(GetValue("is_shared"))) - { - contact.ShareType = Convert.ToBoolean(GetValue("is_shared")) - ? ShareType.ReadWrite - : ShareType.None; - } - else - { - contact.ShareType = (ShareType)(Convert.ToInt32(GetValue("share_type"))); - } + fieldCollector.Add(CRMContactResource.FirstName, firstName); + fieldCollector.Add(CRMContactResource.LastName, lastName); - contact.ID = daoFactory.GetContactDao().SaveContact(contact); + if (!String.IsNullOrEmpty(GetValue("jobTitle"))) + fieldCollector.Add(CRMContactResource.JobTitle, ((Person)contact).JobTitle); + } - var messageAction = contact is Company - ? MessageAction.CompanyCreatedWithWebForm - : MessageAction.PersonCreatedWithWebForm; - MessageService.Send(HttpContext.Current.Request, MessageInitiator.System, messageAction, - MessageTarget.Create(contact.ID), contact.GetTitle()); + contact.About = GetValue("about"); - var contactInfos = new List(); + if (!String.IsNullOrEmpty(contact.About)) + fieldCollector.Add(CRMContactResource.About, contact.About); - foreach (var key in _context.Request.Form.AllKeys) - { - if (key.StartsWith("customField_")) - { - var fieldID = Convert.ToInt32(key.Split(new[] { '_' })[1]); - String fieldValue = GetValue(key); + if (!String.IsNullOrEmpty(GetValue("is_shared"))) + { + contact.ShareType = Convert.ToBoolean(GetValue("is_shared")) + ? ShareType.ReadWrite + : ShareType.None; + } + else + { + contact.ShareType = (ShareType)(Convert.ToInt32(GetValue("share_type"))); + } - if (String.IsNullOrEmpty(fieldValue)) continue; + contact.ID = daoFactory.GetContactDao().SaveContact(contact); - var customField = daoFactory.GetCustomFieldDao().GetFieldDescription(fieldID); + var messageAction = contact is Company + ? MessageAction.CompanyCreatedWithWebForm + : MessageAction.PersonCreatedWithWebForm; - if (customField == null || - !(customField.EntityType == EntityType.Contact || - customField.EntityType == EntityType.Company && isCompany || - customField.EntityType == EntityType.Person && !isCompany)) continue; + MessageService.Send(MessageInitiator.System, messageAction, + MessageTarget.Create(contact.ID), contact.GetTitle()); - if (customField.FieldType == CustomFieldType.CheckBox) - { - fieldValue = fieldValue == "on" || fieldValue == "true" ? "true" : "false"; - } - fieldCollector.Add(customField.Label, fieldValue); + var contactInfos = new List(); - daoFactory.GetCustomFieldDao().SetFieldValue(isCompany ? EntityType.Company : EntityType.Person, contact.ID, fieldID, fieldValue); - } - else if (key.StartsWith("contactInfo_")) - { - var nameParts = key.Split(new[] { '_' }).Skip(1).ToList(); - var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), nameParts[0]); - var category = Convert.ToInt32(nameParts[1]); + foreach (var key in _context.Request.Form.Keys) + { + if (key.StartsWith("customField_")) + { + var fieldID = Convert.ToInt32(key.Split(new[] { '_' })[1]); + String fieldValue = GetValue(key); - bool categoryIsExists = Enum.GetValues(ContactInfo.GetCategory(contactInfoType)) - .Cast() - .Any(categoryEnum => (int)categoryEnum == category); - if (!categoryIsExists) - throw new ArgumentException(String.Format("Category for {0} not found", nameParts[0])); + if (String.IsNullOrEmpty(fieldValue)) continue; - if (contactInfoType == ContactInfoType.Address) - { - var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), nameParts[2]); + var customField = daoFactory.GetCustomFieldDao().GetFieldDescription(fieldID); - var findedAddress = - contactInfos.Find( - item => - (category == item.Category) && (item.InfoType == ContactInfoType.Address)); + if (customField == null || + !(customField.EntityType == EntityType.Contact || + customField.EntityType == EntityType.Company && isCompany || + customField.EntityType == EntityType.Person && !isCompany)) continue; - if (findedAddress == null) - { - findedAddress = new ContactInfo - { - Category = category, - InfoType = contactInfoType, - Data = addressTemplateStr, - ContactID = contact.ID - }; + if (customField.FieldType == CustomFieldType.CheckBox) + { + fieldValue = fieldValue == "on" || fieldValue == "true" ? "true" : "false"; + } + fieldCollector.Add(customField.Label, fieldValue); - contactInfos.Add(findedAddress); - } + daoFactory.GetCustomFieldDao().SetFieldValue(isCompany ? EntityType.Company : EntityType.Person, contact.ID, fieldID, fieldValue); + } + else if (key.StartsWith("contactInfo_")) + { + var nameParts = key.Split(new[] { '_' }).Skip(1).ToList(); + var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), nameParts[0]); + var category = Convert.ToInt32(nameParts[1]); - var addressParts = JObject.Parse(findedAddress.Data); + bool categoryIsExists = Enum.GetValues(ContactInfo.GetCategory(contactInfoType)) + .Cast() + .Any(categoryEnum => (int)categoryEnum == category); + if (!categoryIsExists) + throw new ArgumentException(String.Format("Category for {0} not found", nameParts[0])); - addressParts[addressPart.ToString().ToLower()] = GetValue(key); + if (contactInfoType == ContactInfoType.Address) + { + var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), nameParts[2]); + + var findedAddress = + contactInfos.Find( + item => + (category == item.Category) && (item.InfoType == ContactInfoType.Address)); - findedAddress.Data = addressParts.ToString(); + if (findedAddress == null) + { + findedAddress = new ContactInfo + { + Category = category, + InfoType = contactInfoType, + Data = addressTemplateStr, + ContactID = contact.ID + }; - continue; + contactInfos.Add(findedAddress); } - var fieldValue = GetValue(key); + var addressParts = JObject.Parse(findedAddress.Data); - if (String.IsNullOrEmpty(fieldValue)) continue; + addressParts[addressPart.ToString().ToLower()] = GetValue(key); - contactInfos.Add(new ContactInfo - { - Category = category, - InfoType = contactInfoType, - Data = fieldValue, - ContactID = contact.ID, - IsPrimary = true - }); + findedAddress.Data = addressParts.ToString(); + + continue; } - else if (String.Compare(key, "tag", true) == 0) + + var fieldValue = GetValue(key); + + if (String.IsNullOrEmpty(fieldValue)) continue; + + contactInfos.Add(new ContactInfo { - var tags = _context.Request.Form.GetValues("tag"); + Category = category, + InfoType = contactInfoType, + Data = fieldValue, + ContactID = contact.ID, + IsPrimary = true + }); + } + else if (String.Compare(key, "tag", true) == 0) + { + var tags = _context.Request.Form["tag"]; - daoFactory.GetTagDao().SetTagToEntity(EntityType.Contact, contact.ID, tags); - } + daoFactory.GetTagDao().SetTagToEntity(EntityType.Contact, contact.ID, tags); } + } - contactInfos.ForEach( - item => - fieldCollector[item.InfoType.ToLocalizedString()] = - PrepareteDataToView(item.InfoType, item.Data)); + contactInfos.ForEach( + item => + fieldCollector[item.InfoType.ToLocalizedString()] = + PrepareteDataToView(item.InfoType, item.Data)); - daoFactory.GetContactInfoDao().SaveList(contactInfos, contact); + daoFactory.GetContactInfoDao().SaveList(contactInfos, contact); - var notifyList = GetValue("notify_list"); + var notifyList = GetValue("notify_list"); - if (!String.IsNullOrEmpty(notifyList)) - NotifyClient.Instance.SendAboutCreateNewContact( - notifyList - .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) - .Select(item => new Guid(item)).ToList(), contact.ID, contact.GetTitle(), fieldCollector); + if (!String.IsNullOrEmpty(notifyList)) + NotifyClient.SendAboutCreateNewContact( + notifyList + .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(item => new Guid(item)).ToList(), contact.ID, contact.GetTitle(), fieldCollector); - var managersList = GetValue("managers_list"); - SetPermission(contact, managersList); + var managersList = GetValue("managers_list"); + SetPermission(contact, managersList); - if (contact is Person && !String.IsNullOrEmpty(companyName)) - AssignPersonToCompany((Person)contact, companyName, managersList, daoFactory); + if (contact is Person && !String.IsNullOrEmpty(companyName)) + AssignPersonToCompany((Person)contact, companyName, managersList, daoFactory); - if (contact is Company && !String.IsNullOrEmpty(firstName) && !String.IsNullOrEmpty(lastName)) - AssignCompanyToPerson((Company)contact, firstName, lastName, managersList, daoFactory); + if (contact is Company && !String.IsNullOrEmpty(firstName) && !String.IsNullOrEmpty(lastName)) + AssignCompanyToPerson((Company)contact, firstName, lastName, managersList, daoFactory); - SecurityContext.Logout(); + SecurityContext.Logout(); - var newURL = new UriBuilder(GetValue("return_url")).Uri.AbsoluteUri; - context.Response.Buffer = true; - context.Response.Status = "302 Object moved"; - context.Response.AddHeader("Location", newURL); - context.Response.Write(""); - context.Response.Write(String.Format("", newURL)); - context.Response.Write(String.Format("", newURL)); - context.Response.Write(""); - context.Response.Write(""); - } + var newURL = new UriBuilder(GetValue("return_url")).Uri.AbsoluteUri; + + + context.Response.Clear(); + context.Response.StatusCode = (int)HttpStatusCode.Found; + context.Response.Headers.Add("Location", newURL); + + await context.Response.WriteAsync(""); + await context.Response.WriteAsync(String.Format("", newURL)); + await context.Response.WriteAsync(String.Format("", newURL)); + await context.Response.WriteAsync(""); + await context.Response.WriteAsync(""); } catch (Exception error) { - LogManager.GetLogger("ASC.CRM").Error(error); - context.Response.StatusCode = 400; - context.Response.Write(HttpUtility.HtmlEncode(error.Message)); + Logger.Error(error); + context.Response.StatusCode = (int)HttpStatusCode.BadRequest; + + await context.Response.WriteAsync(HttpUtility.HtmlEncode(error.Message)); } } @@ -405,4 +436,12 @@ protected void AssignPersonToCompany(Person person, String companyName, String p daoFactory.GetContactDao().AddMember(person.ID, company.ID); } } + + public static class WebToLeadFromHandlerMiddlewareExtensions + { + public static IApplicationBuilder UseWebToLeadFromHandlerHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index 6627c27a001..b83b1899ade 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -1,15 +1,14 @@ -using System; using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Threading.Tasks; +using ASC.Common.DependencyInjection; + +using Autofac; using Autofac.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; namespace ASC.CRM { @@ -50,6 +49,10 @@ public static IHostBuilder CreateHostBuilder(string[] args) { {"pathToConf", path} }); + }) + .ConfigureContainer((context, builder) => + { + builder.Register(context.Configuration, context.HostingEnvironment.ContentRootPath, false, false); }); } } diff --git a/products/ASC.CRM/Server/Properties/launchSettings.json b/products/ASC.CRM/Server/Properties/launchSettings.json index bc2f01e903f..7a3e9309af3 100644 --- a/products/ASC.CRM/Server/Properties/launchSettings.json +++ b/products/ASC.CRM/Server/Properties/launchSettings.json @@ -14,7 +14,10 @@ "launchBrowser": true, "launchUrl": "weatherforecast", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "$STORAGE_ROOT": "../../../Data", + "log__name": "crm", + "log__dir": "../../../Logs" } }, "Kestrel WebServer": { @@ -22,7 +25,10 @@ "launchBrowser": true, "launchUrl": "api/2.0/crm/task/10", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "$STORAGE_ROOT": "../../../Data", + "log__name": "crm", + "log__dir": "../../../Logs" }, "applicationUrl": "http://localhost:5000" } diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index bba1c04e437..9ececa0ce11 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,9 +1,12 @@ using System.Text; using ASC.Api.Core; -using ASC.CRM.Api; using ASC.Common; +using ASC.CRM.Api; +using ASC.Web.CRM.HttpHandlers; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -19,10 +22,12 @@ public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) public override void ConfigureServices(IServiceCollection services) { - base.ConfigureServices(services); - Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + services.AddMemoryCache(); + + base.ConfigureServices(services); + DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); @@ -37,6 +42,55 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); - } + } + + public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + base.Configure(app, env); + + app.MapWhen( + context => context.Request.Path.ToString().EndsWith("httphandlers/contactphotohandler.ashx"), + appBranch => + { + appBranch.UseContactPhotoHandler(); + }); + + app.MapWhen( + context => context.Request.Path.ToString().EndsWith("httphandlers/filehandler.ashx"), + appBranch => + { + appBranch.UseFileHandler(); + }); + + app.MapWhen( + context => context.Request.Path.ToString().EndsWith("httphandlers/fileuploaderhandler.ashx"), + appBranch => + { + appBranch.UseFileUploaderHandler(); + }); + + app.MapWhen( + context => context.Request.Path.ToString().EndsWith("httphandlers/importfilehandler.ashx"), + appBranch => + { + appBranch.UseImportFileHandlerHandler(); + }); + + app.MapWhen( + context => context.Request.Path.ToString().EndsWith("httphandlers/organisationlogohandler.ashx"), + appBranch => + { + appBranch.UseOrganisationLogoHandler(); + }); + + + app.MapWhen( + context => context.Request.Path.ToString().EndsWith("httphandlers/webtoleadfromhandler.ashx"), + appBranch => + { + appBranch.UseWebToLeadFromHandlerHandler(); + }); + + } } } From 30222afaa430ef8c48a9e8c410cfc6ba98cc0bdf Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Sat, 13 Mar 2021 21:00:08 +0300 Subject: [PATCH 22/61] crm: refactoring --- products/ASC.CRM/Server/ASC.CRM.csproj | 3 + .../Server/Api/ContactInfosController.cs | 7 - .../ASC.CRM/Server/Api/ContactsController.cs | 85 +- .../ASC.CRM/Server/Api/InvoicesController.cs | 34 +- .../ASC.CRM/Server/Api/UtilsController.cs | 229 +- .../ASC.CRM/Server/ApiModels/ContactDto.cs | 80 +- .../ApiModels/CreateOrUpdatePersonInDto.cs | 7 - .../Server/ApiModels/CurrencyInfoDto.cs | 25 +- .../Server/ApiModels/CurrencyRateDto.cs | 13 +- .../Server/ApiModels/CustomFieldDto.cs | 31 +- .../ASC.CRM/Server/ApiModels/InvoiceDto.cs | 124 +- .../ASC.CRM/Server/ApiModels/ListItemDto.cs | 22 +- .../Server/ApiModels/OpportunityDto.cs | 16 +- .../Server/ApiModels/RelationshipEventDto.cs | 14 +- .../ASC.CRM/Server/ApiModels/ReportDto.cs | 15 +- .../ApiModels/SendMailSMTPToContactsInDto.cs | 16 + products/ASC.CRM/Server/ApiModels/TaskDto.cs | 87 +- .../ASC.CRM/Server/Classes/CRMSettings.cs | 36 +- .../Server/Classes/ContactPhotoManager.cs | 7 +- .../Server/Core/Dao/RelationshipEventDao.cs | 22 +- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 2944 ++++++++--------- .../Utils/Import/CSV/ImportDataOperation.cs | 66 +- .../Server/Utils/Import/CSV/ImportFromCSV.cs | 17 +- products/ASC.CRM/Server/Utils/MailSender.cs | 1913 +++++------ .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 107 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 39 +- 26 files changed, 2940 insertions(+), 3019 deletions(-) create mode 100644 products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index d4f6204b13a..898593dadbc 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -33,6 +33,9 @@ + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index 7b5b0e0b1d2..5ff0e35319c 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -54,15 +54,8 @@ public class ContactInfosController : BaseApiController { public ContactInfosController(CRMSecurity cRMSecurity, DaoFactory daoFactory, - ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, - NotifyClient notifyClient, - ContactDtoHelper contactBaseDtoHelper, - CasesDtoHelper casesDtoHelper, - SecurityContext securityContext, - DisplayUserSettingsHelper displayUserSettingsHelper, - UserManager userManager, ContactInfoDtoHelper contactInfoDtoHelper) : base(daoFactory, cRMSecurity) { diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index 5e935293ed7..38e2a2979cf 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -31,6 +31,7 @@ using ASC.Api.Collections; using ASC.Api.Core; using ASC.Api.CRM; +using ASC.Common.Threading.Progress; using ASC.Common.Web; using ASC.Core; using ASC.Core.Users; @@ -74,7 +75,8 @@ public ContactsController(CRMSecurity cRMSecurity, EmployeeWraperHelper employeeWraperHelper, ContactPhotoManager contactPhotoManager, FileSizeComment fileSizeComment, - ContactInfoDtoHelper contactInfoDtoHelper) + ContactInfoDtoHelper contactInfoDtoHelper, + MailSender mailSender) : base(daoFactory, cRMSecurity) { ApiContext = apiContext; @@ -92,8 +94,10 @@ public ContactsController(CRMSecurity cRMSecurity, ContactPhotoManager = contactPhotoManager; FileSizeComment = fileSizeComment; ContactInfoDtoHelper = contactInfoDtoHelper; + MailSender = mailSender; } + public MailSender MailSender { get; } public ContactInfoDtoHelper ContactInfoDtoHelper { get; } public FileSizeComment FileSizeComment { get; } public ContactPhotoManager ContactPhotoManager { get; } @@ -1168,7 +1172,7 @@ public IEnumerable CreatePerson(IEnumerable [Update(@"contact/company/{companyid:int}")] public CompanyDto UpdateCompany( - [FromQuery]int companyid, + [FromQuery] int companyid, [FromForm] CreateOrUpdateCompanyInDto intDto) { string companyName = intDto.CompanyName; @@ -1469,7 +1473,7 @@ private void SetAccessToContact(Contact contact, bool isShared, IEnumerable [Update(@"contact/access")] public IEnumerable SetAccessToBatchContact( - [FromBody]SetAccessToBatchContactInDto inDto) + [FromBody] SetAccessToBatchContactInDto inDto) { var contactid = inDto.ContactID; var isShared = inDto.isShared; @@ -1888,44 +1892,55 @@ public string DeleteContactAvatar(int contactId, string contactType, bool upload // return null; //} - ///// false - //[Create(@"contact/mailsmtp/send")] - //public IProgressItem SendMailSMTPToContacts(List fileIDs, List contactIds, String subject, String body, bool storeInHistory) - //{ - // if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); + /// false + [Create(@"contact/mailsmtp/send")] + public IProgressItem SendMailSMTPToContacts( + SendMailSMTPToContactsInDto inDto) + { + List fileIDs = inDto.FileIDs; + List contactIds = inDto.ContactIds; + String subject = inDto.Subject; + String body = inDto.body; + bool storeInHistory = inDto.StoreInHistory; - // var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()); - // MessageService.Send(MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); + if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); - // return MailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); - //} + var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()); - ///// false - //[Create(@"contact/mailsmtp/preview")] - //public string GetMailSMTPToContactsPreview(string template, int contactId) - //{ - // if (contactId == 0 || String.IsNullOrEmpty(template)) throw new ArgumentException(); + MessageService.Send(MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); - // var manager = new MailTemplateManager(DaoFactory); + return MailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); + } - // return manager.Apply(template, contactId); - //} + /// false + [Create(@"contact/mailsmtp/preview")] + public string GetMailSMTPToContactsPreview(string template, int contactId) + { + if (contactId == 0 || String.IsNullOrEmpty(template)) throw new ArgumentException(); - ///// false - //[Read(@"contact/mailsmtp/status")] - //public IProgressItem GetMailSMTPToContactsStatus() - //{ - // return MailSender.GetStatus(); - //} + var manager = new MailTemplateManager(DaoFactory); - ///// false - //[Update(@"contact/mailsmtp/cancel")] - //public IProgressItem CancelMailSMTPToContacts() - //{ - // var progressItem = MailSender.GetStatus(); - // MailSender.Cancel(); - // return progressItem; - //} + return manager.Apply(template, contactId); + } + + /// false + [Read(@"contact/mailsmtp/status")] + public IProgressItem GetMailSMTPToContactsStatus() + { + return MailSender.GetStatus(); + } + + /// false + [Update(@"contact/mailsmtp/cancel")] + public IProgressItem CancelMailSMTPToContacts() + { + var progressItem = MailSender.GetStatus(); + + MailSender.Cancel(); + + return progressItem; + + } /// false [Update(@"contact/{contactid:int}/creationdate")] @@ -2131,5 +2146,5 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList /// Returns the detailed information about the invoice with the ID specified in the request /// @@ -762,7 +745,7 @@ public InvoiceDto UpdateInvoice( if (Global.CanDownloadInvoices) { - // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(invoice.ID); } return InvoiceDtoHelper.Get(invoice); @@ -1062,9 +1045,10 @@ CreateOrUpdateInvoiceLineInDto inDto invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + if (Global.CanDownloadInvoices) { - // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(invoice.ID); } return InvoiceLineDtoHelper.Get(invoiceLine); @@ -1128,7 +1112,7 @@ CreateOrUpdateInvoiceLineInDto inDto if (Global.CanDownloadInvoices) { - // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(invoice.ID); } return InvoiceLineDtoHelper.Get(invoiceLine); @@ -1158,7 +1142,7 @@ public int DeleteInvoiceLine(int id) if (Global.CanDownloadInvoices) { - // PdfQueueWorker.StartTask(HttpContext.Current, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID, invoice.ID); + PdfQueueWorker.StartTask(invoice.ID); } return id; diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index e5b76681e17..906405ec42a 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -60,7 +60,8 @@ public UtilsController(CRMSecurity cRMSecurity, ImportFromCSVManager importFromCSVManager, OrganisationLogoManager organisationLogoManager, Global global, - ImportFromCSV importFromCSV) + ImportFromCSV importFromCSV, + ExportToCsv exportToCsv) : base(daoFactory, cRMSecurity) { MessageService = messageService; @@ -73,8 +74,10 @@ public UtilsController(CRMSecurity cRMSecurity, OrganisationLogoManager = organisationLogoManager; Global = global; ImportFromCSV = importFromCSV; + ExportToCsv = exportToCsv; } + public ExportToCsv ExportToCsv { get; } public ImportFromCSV ImportFromCSV { get; } public Global Global { get; } public OrganisationLogoManager OrganisationLogoManager { get; } @@ -492,117 +495,117 @@ public IProgressItem GetImportFromCSVStatus(string entityType) return ImportFromCSV.GetStatus(entityTypeObj); } - ///// false - //[Read(@"import/samplerow")] - //public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string jsonSettings) - //{ - // if (String.IsNullOrEmpty(csvFileURI) || indexRow < 0) throw new ArgumentException(); - - // if (!Global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException(); - - // var CSVFileStream = Global.GetStore().GetReadStream("temp", csvFileURI); - - // return ImportFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings); - //} - - ///// false - //[Create(@"import/uploadfake")] - //public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings) - //{ - // return ImportFromCSVManager.ProcessUploadFake(csvFileURI, jsonSettings); - //} - - ///// false - //[Read(@"export/status")] - //public IProgressItem GetExportStatus() - //{ - // if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - // return ExportToCsv.GetStatus(false); - - //} - - ///// false - //[Update(@"export/cancel")] - //public IProgressItem CancelExport() - //{ - // if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - // ExportToCsv.Cancel(false); - - // return ExportToCsv.GetStatus(false); - - //} - - ///// false - //[Create(@"export/start")] - //public IProgressItem StartExport() - //{ - // if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - - // MessageService.Send( MessageAction.CrmAllDataExported); - - // return ExportToCsv.Start(null, CRMSettingResource.Export + ".zip"); - //} - - ///// false - //[Read(@"export/partial/status")] - //public IProgressItem GetPartialExportStatus() - //{ - // return ExportToCsv.GetStatus(true); - //} - - ///// false - //[Update(@"export/partial/cancel")] - //public IProgressItem CancelPartialExport() - //{ - - // ExportToCsv.Cancel(true); - - // return ExportToCsv.GetStatus(true); - - //} - - ///// false - //[Create(@"export/partial/{entityType:(contact|opportunity|case|task|invoiceitem)}/start")] - //public IProgressItem StartPartialExport(string entityType, string base64FilterString) - //{ - // if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException(); - - // FilterObject filterObject; - // String fileName; - - // switch (entityType.ToLower()) - // { - // case "contact": - // filterObject = new ContactFilterObject(base64FilterString); - // fileName = CRMContactResource.Contacts + ".csv"; - // MessageService.Send( MessageAction.ContactsExportedToCsv); - // break; - // case "opportunity": - // filterObject = new DealFilterObject(base64FilterString); - // fileName = CRMCommonResource.DealModuleName + ".csv"; - // MessageService.Send( MessageAction.OpportunitiesExportedToCsv); - // break; - // case "case": - // filterObject = new CasesFilterObject(base64FilterString); - // fileName = CRMCommonResource.CasesModuleName + ".csv"; - // MessageService.Send( MessageAction.CasesExportedToCsv); - // break; - // case "task": - // filterObject = new TaskFilterObject(base64FilterString); - // fileName = CRMCommonResource.TaskModuleName + ".csv"; - // MessageService.Send( MessageAction.CrmTasksExportedToCsv); - // break; - // case "invoiceitem": - // fileName = CRMCommonResource.ProductsAndServices + ".csv"; - // filterObject = new InvoiceItemFilterObject(base64FilterString); - // break; - // default: - // throw new ArgumentException(); - // } - - // return ExportToCsv.Start(filterObject, fileName); - //} + /// false + [Read(@"import/samplerow")] + public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string jsonSettings) + { + if (String.IsNullOrEmpty(csvFileURI) || indexRow < 0) throw new ArgumentException(); + + if (!Global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException(); + + var CSVFileStream = Global.GetStore().GetReadStream("temp", csvFileURI); + + return ImportFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings); + } + + /// false + [Create(@"import/uploadfake")] + public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings) + { + return ImportFromCSVManager.ProcessUploadFake(csvFileURI, jsonSettings); + } + + /// false + [Read(@"export/status")] + public IProgressItem GetExportStatus() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + return ExportToCsv.GetStatus(false); + + } + + /// false + [Update(@"export/cancel")] + public IProgressItem CancelExport() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + ExportToCsv.Cancel(false); + + return ExportToCsv.GetStatus(false); + + } + + /// false + [Create(@"export/start")] + public IProgressItem StartExport() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + MessageService.Send(MessageAction.CrmAllDataExported); + + return ExportToCsv.Start(null, CRMSettingResource.Export + ".zip"); + } + + /// false + [Read(@"export/partial/status")] + public IProgressItem GetPartialExportStatus() + { + return ExportToCsv.GetStatus(true); + } + + /// false + [Update(@"export/partial/cancel")] + public IProgressItem CancelPartialExport() + { + + ExportToCsv.Cancel(true); + + return ExportToCsv.GetStatus(true); + + } + + /// false + [Create(@"export/partial/{entityType:regex(contact|opportunity|case|task|invoiceitem)}/start")] + public IProgressItem StartPartialExport(string entityType, string base64FilterString) + { + if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException(); + + FilterObject filterObject; + String fileName; + + switch (entityType.ToLower()) + { + case "contact": + filterObject = new ContactFilterObject(base64FilterString); + fileName = CRMContactResource.Contacts + ".csv"; + MessageService.Send(MessageAction.ContactsExportedToCsv); + break; + case "opportunity": + filterObject = new DealFilterObject(base64FilterString); + fileName = CRMCommonResource.DealModuleName + ".csv"; + MessageService.Send(MessageAction.OpportunitiesExportedToCsv); + break; + case "case": + filterObject = new CasesFilterObject(base64FilterString); + fileName = CRMCommonResource.CasesModuleName + ".csv"; + MessageService.Send(MessageAction.CasesExportedToCsv); + break; + case "task": + filterObject = new TaskFilterObject(base64FilterString); + fileName = CRMCommonResource.TaskModuleName + ".csv"; + MessageService.Send(MessageAction.CrmTasksExportedToCsv); + break; + case "invoiceitem": + fileName = CRMCommonResource.ProductsAndServices + ".csv"; + filterObject = new InvoiceItemFilterObject(base64FilterString); + break; + default: + throw new ArgumentException(); + } + + return ExportToCsv.Start(filterObject, fileName); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ContactDto.cs index 14af32f0555..2dbb899350f 100644 --- a/products/ASC.CRM/Server/ApiModels/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ContactDto.cs @@ -61,10 +61,10 @@ public PersonDto() [DataMember(IsRequired = true, EmitDefaultValue = false)] public String LastName { get; set; } - + public ContactBaseDto Company { get; set; } - + public String Title { get; set; } public new static PersonDto GetSample() @@ -176,43 +176,21 @@ public ContactDto() // Industry = contact.Industry; //} - - public IEnumerable
    Addresses { get; set; } - - + public IEnumerable
    Addresses { get; set; } public EmployeeWraper CreateBy { get; set; } - - public ApiDateTime Created { get; set; } - - public String About { get; set; } - - public String Industry { get; set; } - - public ContactStatusBaseDto ContactStatus { get; set; } - - public ContactTypeBaseDto ContactType { get; set; } - - public IEnumerable CommonData { get; set; } - - public IEnumerable CustomFields { get; set; } - - public IEnumerable Tags { get; set; } - - public int TaskCount { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool HaveLateTasks { get; set; } - public new static ContactDto GetSample() { return new PersonDto @@ -241,7 +219,6 @@ public ContactDto() [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithEmailDto : ContactBaseDto { - public ContactInfoDto Email { get; set; } } @@ -249,7 +226,6 @@ public class ContactBaseWithEmailDto : ContactBaseDto [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithPhoneDto : ContactBaseDto { - public ContactInfoDto Phone { get; set; } } @@ -306,10 +282,10 @@ public ContactBaseDto() [DataMember(Name = "id")] public int Id { get; set; } - + public String SmallFotoUrl { get; set; } - + public String MediumFotoUrl { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -318,7 +294,7 @@ public ContactBaseDto() [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool IsCompany { get; set; } - + public IEnumerable AccessList { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -330,7 +306,7 @@ public ContactBaseDto() [DataMember(IsRequired = false, EmitDefaultValue = true)] public ShareType ShareType { get; set; } - [DataMember] + public CurrencyInfoDto Currency { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -355,10 +331,10 @@ public static ContactBaseDto GetSample() [DataContract(Name = "contact_task", Namespace = "")] public class ContactWithTaskDto { - + public TaskBaseDto Task { get; set; } - + public ContactDto Contact { get; set; } } @@ -395,21 +371,25 @@ public ContactDtoHelper(ApiDateTimeHelper apiDateTimeHelper, public ContactBaseDto GetContactBaseDtoQuick(Contact contact) { - var result = new ContactBaseDto - { - Id = contact.ID, - DisplayName = contact.GetTitle(), - IsPrivate = CRMSecurity.IsPrivate(contact), - IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read, - ShareType = contact.ShareType, - Currency = !String.IsNullOrEmpty(contact.Currency) ? - CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(contact.Currency)) : null, - SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), - MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(), - IsCompany = contact is Company, - CanEdit = CRMSecurity.CanEdit(contact), - // CanDelete = CRMSecurity.CanDelete(contact), - }; + ContactBaseDto result; + + if (contact is Company) + result = new CompanyDto(); + else + result = new PersonDto(); + + result.Id = contact.ID; + result.DisplayName = contact.GetTitle(); + result.IsPrivate = CRMSecurity.IsPrivate(contact); + result.IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read; + result.ShareType = contact.ShareType; + result.Currency = !String.IsNullOrEmpty(contact.Currency) ? + CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(contact.Currency)) : null; + result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); + result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); + result.IsCompany = contact is Company; + result.CanEdit = CRMSecurity.CanEdit(contact); + // CanDelete = CRMSecurity.CanDelete(contact), if (result.IsPrivate) { @@ -638,11 +618,9 @@ public ContactDto GetContactDto(Contact contact) ContactDto result; var person = contact as Person; - + if (person != null) { - - var temp = (ContactDto)GetContactBaseDto(contact); var peopleDto = (PersonDto)GetContactBaseDto(contact); peopleDto.FirstName = person.FirstName; diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs b/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs index d68ce15cfa1..2a8c14dc5e7 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs @@ -14,13 +14,9 @@ namespace ASC.CRM.ApiModels public class CreateOrUpdateContactInDto { public string About { get; set; } - public ShareType ShareType { get; set; } - public IEnumerable ManagerList { get; set; } - public IEnumerable> CustomFieldList { get; set; } - public IEnumerable Photos { get; set; } } @@ -37,11 +33,8 @@ public class CreateOrUpdateCompanyInDto : CreateOrUpdateContactInDto public class CreateOrUpdatePersonInDto : CreateOrUpdateContactInDto { public String FirstName { get; set; } - public String LastName { get; set; } - public String JobTitle { get; set; } - public int CompanyId { get; set; } } } diff --git a/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs index 8114de18623..e62f4eb1586 100644 --- a/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs @@ -43,24 +43,13 @@ public CurrencyInfoDto() } - [DataMember] - public String Title { get; set; } - - [DataMember] - public String Symbol { get; set; } - - [DataMember] - public String Abbreviation { get; set; } - - [DataMember] - public String CultureName { get; set; } - - [DataMember] - public bool IsConvertable { get; set; } - - [DataMember] + + public String Title { get; set; } + public String Symbol { get; set; } + public String Abbreviation { get; set; } + public String CultureName { get; set; } + public bool IsConvertable { get; set; } public bool IsBasic { get; set; } - public static CurrencyInfoDto GetSample() { return new CurrencyInfoDto @@ -115,7 +104,7 @@ public CurrencyRateInfoDto() // Rate = rate; //} - [DataMember] + public decimal Rate { get; set; } } diff --git a/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs b/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs index 915fabe7d48..3583d37d0a6 100644 --- a/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs @@ -44,17 +44,10 @@ public CurrencyRateDto() [DataMember(Name = "id")] - public int Id { get; set; } - - [DataMember] - public String FromCurrency { get; set; } - - [DataMember] - public String ToCurrency { get; set; } - - [DataMember] + public int Id { get; set; } + public String FromCurrency { get; set; } + public String ToCurrency { get; set; } public decimal Rate { get; set; } - public static CurrencyRateDto GetSample() { return new CurrencyRateDto diff --git a/products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs index 1c8ed59f5a3..e8ba12b4244 100644 --- a/products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs @@ -43,11 +43,7 @@ public CustomFieldDto(int id) public CustomFieldDto(CustomField customField) : base(customField) { - } - - - - [DataMember] + } public int RelativeItemsCount { get; set; } public new static CustomFieldDto GetSample() @@ -86,26 +82,13 @@ public CustomFieldBaseDto(CustomField customField) } [DataMember(Name = "id")] - public int Id { get; set; } - - [DataMember] - public int EntityId { get; set; } - - [DataMember] - public String Label { get; set; } - - [DataMember] - public String FieldValue { get; set; } - - [DataMember] - public CustomFieldType FieldType { get; set; } - - [DataMember] - public int Position { get; set; } - - [DataMember] + public int Id { get; set; } + public int EntityId { get; set; } + public String Label { get; set; } + public String FieldValue { get; set; } + public CustomFieldType FieldType { get; set; } + public int Position { get; set; } public String Mask { get; set; } - public static CustomFieldBaseDto GetSample() { return new CustomFieldBaseDto(0) diff --git a/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs b/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs index 8d499a2f0c3..2c9204531aa 100644 --- a/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs +++ b/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs @@ -55,58 +55,24 @@ public InvoiceBaseDto() [DataMember(Name = "id")] public int Id { get; set; } - [DataMember] - public InvoiceStatusDto Status { get; set; } - - [DataMember] - public string Number { get; set; } - - [DataMember] - public ApiDateTime IssueDate { get; set; } - - [DataMember] - public InvoiceTemplateType TemplateType { get; set; } - - [DataMember] - public ContactBaseWithEmailDto Contact { get; set; } - - [DataMember] - public ContactBaseWithEmailDto Consignee { get; set; } - - [DataMember] - public EntityDto Entity { get; set; } - - [DataMember] - public ApiDateTime DueDate { get; set; } - - [DataMember] - public string Language { get; set; } - - [DataMember] - public CurrencyInfoDto Currency { get; set; } - - [DataMember] - public decimal ExchangeRate { get; set; } - - [DataMember] - public string PurchaseOrderNumber { get; set; } - - [DataMember] - public string Terms { get; set; } - - [DataMember] - public string Description { get; set; } - - [DataMember] - public int FileID { get; set; } - - [DataMember] - public ApiDateTime CreateOn { get; set; } - - [DataMember] - public EmployeeWraper CreateBy { get; set; } - - [DataMember] + + public InvoiceStatusDto Status { get; set; } + public string Number { get; set; } + public ApiDateTime IssueDate { get; set; } + public InvoiceTemplateType TemplateType { get; set; } + public ContactBaseWithEmailDto Contact { get; set; } + public ContactBaseWithEmailDto Consignee { get; set; } + public EntityDto Entity { get; set; } + public ApiDateTime DueDate { get; set; } + public string Language { get; set; } + public CurrencyInfoDto Currency { get; set; } + public decimal ExchangeRate { get; set; } + public string PurchaseOrderNumber { get; set; } + public string Terms { get; set; } + public string Description { get; set; } + public int FileID { get; set; } + public ApiDateTime CreateOn { get; set; } + public EmployeeWraper CreateBy { get; set; } public decimal Cost { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -211,7 +177,7 @@ public InvoiceDto() { } - [DataMember] + public List InvoiceLines { get; set; } public static InvoiceDto GetSample() @@ -341,37 +307,37 @@ public InvoiceItemDto() { } - [DataMember] + public string Title { get; set; } - [DataMember] + public string StockKeepingUnit { get; set; } - [DataMember] + public string Description { get; set; } - [DataMember] + public decimal Price { get; set; } - [DataMember] + public CurrencyInfoDto Currency { get; set; } - [DataMember] + public decimal StockQuantity { get; set; } - [DataMember] + public bool TrackInvenory { get; set; } - [DataMember] + public InvoiceTaxDto InvoiceTax1 { get; set; } - [DataMember] + public InvoiceTaxDto InvoiceTax2 { get; set; } - [DataMember] + public ApiDateTime CreateOn { get; set; } - [DataMember] + public EmployeeWraper CreateBy { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -474,19 +440,19 @@ public InvoiceTaxDto() [DataMember(Name = "id")] public int Id { get; set; } - [DataMember] + public string Name { get; set; } - [DataMember] + public string Description { get; set; } - [DataMember] + public decimal Rate { get; set; } - [DataMember] + public ApiDateTime CreateOn { get; set; } - [DataMember] + public EmployeeWraper CreateBy { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -542,31 +508,31 @@ public InvoiceLineDto() [DataMember(Name = "id")] public int Id { get; set; } - [DataMember] + public int InvoiceID { get; set; } - [DataMember] + public int InvoiceItemID { get; set; } - [DataMember] + public int InvoiceTax1ID { get; set; } - [DataMember] + public int InvoiceTax2ID { get; set; } - [DataMember] + public int SortOrder { get; set; } - [DataMember] + public string Description { get; set; } - [DataMember] + public decimal Quantity { get; set; } - [DataMember] + public decimal Price { get; set; } - [DataMember] + public decimal Discount { get; set; } public static InvoiceLineDto GetSample() @@ -624,7 +590,7 @@ public InvoiceStatusDto() [DataMember(Name = "id")] public int Id { get; set; } - [DataMember] + public string Title { get; set; } public static InvoiceStatusDto GetSample() diff --git a/products/ASC.CRM/Server/ApiModels/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ListItemDto.cs index eae66bab971..4b14bcf3a37 100644 --- a/products/ASC.CRM/Server/ApiModels/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ListItemDto.cs @@ -53,7 +53,7 @@ public HistoryCategoryBaseDto(ListItem listItem) [DataMember(Name = "id")] public int Id { get; set; } - [DataMember] + public String ImagePath { get; set; } public static HistoryCategoryBaseDto GetSample() @@ -137,10 +137,10 @@ public DealMilestoneBaseDto(DealMilestone dealMilestone) Title = dealMilestone.Title; } - [DataMember] + public int SuccessProbability { get; set; } - [DataMember] + public DealMilestoneStatus StageType { get; set; } public static DealMilestoneBaseDto GetSample() @@ -438,18 +438,10 @@ protected ListItemDto(ListItem listItem) } [DataMember(Name = "id")] - public int Id { get; set; } - - - public String Title { get; set; } - - - public String Description { get; set; } - - - public String Color { get; set; } - - + public int Id { get; set; } + public String Title { get; set; } + public String Description { get; set; } + public String Color { get; set; } public int SortOrder { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs index 424203a836b..04d267800d2 100644 --- a/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs +++ b/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs @@ -52,18 +52,10 @@ public OpportunityDto() } [DataMember(Name = "id")] - public int Id { get; set; } - - - public EmployeeWraper CreateBy { get; set; } - - - public ApiDateTime Created { get; set; } - - - public IEnumerable Members { get; set; } - - + public int Id { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public IEnumerable Members { get; set; } public ContactBaseDto Contact { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] diff --git a/products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs b/products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs index 0dcf507b393..51f02183615 100644 --- a/products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs @@ -40,16 +40,10 @@ namespace ASC.CRM.ApiModels { [DataContract(Name = "entity", Namespace = "")] public class EntityDto - { - [DataMember] - public String EntityType { get; set; } - - [DataMember] - public int EntityId { get; set; } - - [DataMember] + { + public String EntityType { get; set; } + public int EntityId { get; set; } public String EntityTitle { get; set; } - public static EntityDto GetSample() { return new EntityDto @@ -134,7 +128,7 @@ public RelationshipEventDto() public ContactBaseDto Contact { get; set; } - [DataMember] + public EntityDto Entity { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ReportDto.cs b/products/ASC.CRM/Server/ApiModels/ReportDto.cs index f3b16d094e6..a6ed356f0e5 100644 --- a/products/ASC.CRM/Server/ApiModels/ReportDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ReportDto.cs @@ -32,17 +32,10 @@ namespace ASC.CRM.ApiModels { [DataContract] public class ReportDto - { - [DataMember] - public String ReportTitle { get; set; } - - [DataMember] - public String ReportDescription { get; set; } - - [DataMember] - public IEnumerable Lables { get; set; } - - [DataMember] + { + public String ReportTitle { get; set; } + public String ReportDescription { get; set; } + public IEnumerable Lables { get; set; } public Object Data { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs b/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs new file mode 100644 index 00000000000..a4d8fbc5494 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ASC.CRM.ApiModels +{ + public class SendMailSMTPToContactsInDto + { + public List FileIDs { get; set; } + public List ContactIds { get; set; } + public String Subject { get; set; } + public String body { get; set; } + public bool StoreInHistory { get; set; } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/TaskDto.cs b/products/ASC.CRM/Server/ApiModels/TaskDto.cs index 6edf8629b47..fbbc307bad3 100644 --- a/products/ASC.CRM/Server/ApiModels/TaskDto.cs +++ b/products/ASC.CRM/Server/ApiModels/TaskDto.cs @@ -43,44 +43,19 @@ namespace ASC.CRM.ApiModels public class TaskDto { [DataMember(Name = "id")] - public int Id { get; set; } - - - public EmployeeWraper CreateBy { get; set; } - - - public ApiDateTime Created { get; set; } - - - public ContactBaseWithEmailDto Contact { get; set; } - - - public String Title { get; set; } - - - public String Description { get; set; } - - - public ApiDateTime DeadLine { get; set; } - - - public int AlertValue { get; set; } - - - public EmployeeWraper Responsible { get; set; } - - - public bool IsClosed { get; set; } - - - public TaskCategoryBaseDto Category { get; set; } - - - public EntityDto Entity { get; set; } - - + public int Id { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public ContactBaseWithEmailDto Contact { get; set; } + public String Title { get; set; } + public String Description { get; set; } + public ApiDateTime DeadLine { get; set; } + public int AlertValue { get; set; } + public EmployeeWraper Responsible { get; set; } + public bool IsClosed { get; set; } + public TaskCategoryBaseDto Category { get; set; } + public EntityDto Entity { get; set; } public bool CanEdit { get; set; } - public static TaskDto GetSample() { return new TaskDto @@ -107,36 +82,16 @@ public class TaskBaseDto public TaskBaseDto() { - } - - - - public String Title { get; set; } - - - public String Description { get; set; } - - - public ApiDateTime DeadLine { get; set; } - - - public int AlertValue { get; set; } - - - public EmployeeWraper Responsible { get; set; } - - - public bool IsClosed { get; set; } - - - public TaskCategoryBaseDto Category { get; set; } - - - public EntityDto Entity { get; set; } - - + } + public String Title { get; set; } + public String Description { get; set; } + public ApiDateTime DeadLine { get; set; } + public int AlertValue { get; set; } + public EmployeeWraper Responsible { get; set; } + public bool IsClosed { get; set; } + public TaskCategoryBaseDto Category { get; set; } + public EntityDto Entity { get; set; } public bool CanEdit { get; set; } - public static TaskBaseDto GetSample() { return new TaskBaseDto diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index a2bb7404bed..f4473d06fd4 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -64,28 +64,28 @@ public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) SenderEmailAddress = smtpSettings.SenderAddress; } - [DataMember] + public String Host { get; set; } - [DataMember] + public int Port { get; set; } - [DataMember] + public bool EnableSSL { get; set; } - [DataMember] + public bool RequiredHostAuthentication { get; set; } - [DataMember] + public String HostLogin { get; set; } - [DataMember] + public String HostPassword { get; set; } - [DataMember] + public String SenderDisplayName { get; set; } - [DataMember] + public String SenderEmailAddress { get; set; } } @@ -123,25 +123,25 @@ public InvoiceSetting DefaultSettings } } - [DataMember] + public bool Autogenerated { get; set; } - [DataMember] + public String Prefix { get; set; } - [DataMember] + public String Number { get; set; } - [DataMember] + public String Terms { get; set; } - [DataMember] + public String CompanyName { get; set; } - [DataMember] + public Int32 CompanyLogoID { get; set; } - [DataMember] + public String CompanyAddress { get; set; } } @@ -163,7 +163,7 @@ public CRMSettings(CoreConfiguration coreConfiguration, [DataMember(Name = "DefaultCurrency")] private string defaultCurrency; - //[DataMember] + // public SMTPServerSetting SMTPServerSetting { get @@ -175,10 +175,10 @@ public SMTPServerSetting SMTPServerSetting [DataMember(Name = "SMTPServerSetting")] public SMTPServerSetting SMTPServerSettingOld { get; set; } - [DataMember] + public InvoiceSetting InvoiceSetting { get; set; } - [DataMember] + public Guid WebFormKey { get; set; } public Guid ID diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs index 3c23480471d..960e8b41450 100644 --- a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -82,13 +82,14 @@ public ContactPhotoManager(Global global, WebImageSupplier webImageSupplier, IOptionsMonitor logger, ICache cache, - ICacheNotify cacheNotify) + ICacheNotify cacheNotify, + WorkerQueueOptionsManager workerQueueOptionsManager ) { Global = global; WebImageSupplier = webImageSupplier; CacheNotify = cacheNotify; Cache = cache; - + ResizeQueue = workerQueueOptionsManager.Value; Logger = logger.Get("ASC.CRM"); CacheNotify.Subscribe((x) => @@ -109,7 +110,7 @@ public ContactPhotoManager(Global global, private const string PhotosBaseDirName = "photos"; private const string PhotosDefaultTmpDirName = "temp"; - private readonly WorkerQueue ResizeQueue = new WorkerQueue(); + private readonly WorkerQueue ResizeQueue; private readonly ICacheNotify CacheNotify; private readonly ICache Cache; diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 29a7befd287..887e148440f 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -657,37 +657,37 @@ public void DeleteItem(RelationshipEvent item) [DataContract] internal class CrmHistoryContent { - [DataMember] + public string to; - [DataMember] + public string from; - [DataMember] + public string cc; - [DataMember] + public string bcc; - [DataMember] + public string subject; - [DataMember] + public bool important; - [DataMember] + public string chain_id; - [DataMember] + public bool is_sended; - [DataMember] + public string date_created; - [DataMember] + public string introduction; - [DataMember] + public long message_id; } diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 2caf3c8cbbe..2f83baaa750 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -1,1477 +1,1475 @@ -///* -// * -// * (c) Copyright Ascensio System Limited 2010-2018 -// * -// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU -// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). -// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that -// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. -// * -// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR -// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html -// * -// * You can contact Ascensio System SIA by email at sales@onlyoffice.com -// * -// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display -// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. -// * -// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains -// * relevant author attributions when distributing the software. If the display of the logo in its graphic -// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" -// * in every copy of the program you distribute. -// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. -// * -//*/ - - -//using ASC.Common; -//using ASC.Common.Caching; -//using ASC.Common.Logging; -//using ASC.Common.Security.Authentication; -//using ASC.Common.Threading.Progress; -//using ASC.Core; -//using ASC.Core.Users; -//using ASC.CRM.Classes; -//using ASC.CRM.Core; -//using ASC.CRM.Core.Dao; -//using ASC.CRM.Core.Entities; -//using ASC.CRM.Core.Enums; -//using ASC.CRM.Resources; -//using ASC.Data.Storage; -//using ASC.Files.Core; -//using ASC.Web.Core.Files; -//using ASC.Web.Core.Users; -//using ASC.Web.CRM.Services.NotifyService; -//using ASC.Web.Files.Classes; -//using ASC.Web.Files.Utils; -//using ASC.Web.Studio.Utility; - -//using ICSharpCode.SharpZipLib.Zip; - -//using Microsoft.Extensions.Options; -//using Newtonsoft.Json.Linq; -//using System; -//using System.Collections.Generic; -//using System.Collections.Specialized; -//using System.Data; -//using System.Globalization; -//using System.IO; -//using System.Linq; -//using System.Text; - -//namespace ASC.Web.CRM.Classes -//{ -// [Singletone] -// public class ExportDataCache -// { -// public ExportDataCache(ICache ascCache) -// { -// Cache = ascCache; -// } - -// public readonly ICache Cache; - -// public String GetStateCacheKey(string key) -// { -// return String.Format("{0}:crm:queue:exporttocsv", key); -// } - -// public String GetCancelCacheKey(string key) -// { -// return String.Format("{0}:crm:queue:exporttocsv:cancel", key); -// } - -// public ExportDataOperation Get(string key) -// { -// return Cache.Get(GetStateCacheKey(key)); -// } - -// public void Insert(string key, ExportDataOperation data) -// { -// Cache.Insert(GetStateCacheKey(key), data, TimeSpan.FromMinutes(1)); -// } - -// public bool CheckCancelFlag(string key) -// { -// var fromCache = Cache.Get(GetCancelCacheKey(key)); - -// return !String.IsNullOrEmpty(fromCache); -// } - -// public void SetCancelFlag(string key) -// { -// Cache.Insert(GetCancelCacheKey(key), "true", TimeSpan.FromMinutes(1)); -// } - -// public void ResetAll(string key) -// { -// Cache.Remove(GetStateCacheKey(key)); -// Cache.Remove(GetCancelCacheKey(key)); -// } -// } - -// public class ExportDataOperation : IProgressItem -// { -// public ExportDataOperation(UserManager userManager, -// FileUtility fileUtility, -// SecurityContext securityContext, -// IOptionsMonitor logger, -// TenantManager tenantManager, -// Global global, -// ExportDataCache exportDataCache, -// CommonLinkUtility commonLinkUtility, -// DisplayUserSettings displayUserSettings, -// NotifyClient notifyClient, -// DaoFactory daoFactory, -// FileUploader fileUploader, -// GlobalFolder globalFolder, -// FileMarker fileMarker, -// IDaoFactory fileDaoFactory, -// FilesLinkUtility filesLinkUtility, -// DisplayUserSettingsHelper displayUserSettingsHelper) -// { -// DaoFactory = daoFactory; -// UserManager = userManager; -// FileUtility = fileUtility; -// FileUploader = fileUploader; - -// _tenantId = tenantManager.GetCurrentTenant().TenantId; - -// _author = securityContext.CurrentAccount; -// _dataStore = global.GetStore(); -// _notifyClient = notifyClient; -// _filterObject = filterObject; - -// _log = logger.Get("ASC.CRM"); - -// Id = ExportToCsv.GetKey(filterObject != null); -// Status = ProgressStatus.Queued; -// Error = null; -// Percentage = 0; -// IsCompleted = false; -// FileName = fileName ?? CRMSettingResource.Export + (filterObject == null ? ".zip" : ".csv"); -// FileUrl = null; - -// ExportDataCache = exportDataCache; -// SecurityContext = securityContext; - -// CommonLinkUtility = commonLinkUtility; -// GlobalFolder = globalFolder; -// FileMarker = fileMarker; -// FileDaoFactory = fileDaoFactory; -// FilesLinkUtility = filesLinkUtility; -// DisplayUserSettingsHelper = displayUserSettingsHelper; -// } - -// public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } -// public FilesLinkUtility FilesLinkUtility { get; } -// public FileMarker FileMarker { get; } -// public IDaoFactory FileDaoFactory { get; } -// public GlobalFolder GlobalFolder { get; } -// public FileUploader FileUploader { get; } -// public TenantManager TenantManager { get; } -// public CommonLinkUtility CommonLinkUtility { get; } -// public SecurityContext SecurityContext { get; } -// public DaoFactory DaoFactory { get; } -// public ExportDataCache ExportDataCache { get; } -// public UserManager UserManager { get; } -// public FileUtility FileUtility { get; } - -// private readonly int _tenantId; - -// private readonly IAccount _author; - -// private readonly IDataStore _dataStore; - -// private readonly NotifyClient _notifyClient; - -// private readonly FilterObject _filterObject; - -// private readonly ILog _log; - -// private int _totalCount; - -// public override bool Equals(object obj) -// { -// if (obj == null) return false; - -// var exportDataOperation = obj as ExportDataOperation; - -// if (exportDataOperation == null) return false; - -// return Id == exportDataOperation.Id; -// } - -// public override int GetHashCode() -// { -// return Id.GetHashCode(); -// } - -// public object Clone() -// { -// var cloneObj = new ExportDataOperation -// { -// Id = Id, -// Status = Status, -// Error = Error, -// Percentage = Percentage, -// IsCompleted = IsCompleted, -// FileName = FileName, -// FileUrl = FileUrl -// }; - -// return cloneObj; -// } - -// public object Id { get; set; } - -// public object Status { get; set; } - -// public object Error { get; set; } - -// public double Percentage { get; set; } +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Common.Security.Authentication; +using ASC.Common.Threading.Progress; +using ASC.Core; +using ASC.Core.Users; +using ASC.CRM.Classes; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Data.Storage; +using ASC.Files.Core; +using ASC.Web.Core.Files; +using ASC.Web.Core.Users; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Classes; +using ASC.Web.Files.Utils; +using ASC.Web.Studio.Utility; +using ASC.Web.Core.Calendars; + +using ICSharpCode.SharpZipLib.Zip; + +using Microsoft.Extensions.Options; + +using Newtonsoft.Json.Linq; + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +namespace ASC.Web.CRM.Classes +{ + [Singletone] + public class ExportDataCache + { + public ExportDataCache(ICache ascCache) + { + Cache = ascCache; + } + + public readonly ICache Cache; + + public String GetStateCacheKey(string key) + { + return String.Format("{0}:crm:queue:exporttocsv", key); + } + + public String GetCancelCacheKey(string key) + { + return String.Format("{0}:crm:queue:exporttocsv:cancel", key); + } + + public ExportDataOperation Get(string key) + { + return Cache.Get(GetStateCacheKey(key)); + } + + public void Insert(string key, ExportDataOperation data) + { + Cache.Insert(GetStateCacheKey(key), data, TimeSpan.FromMinutes(1)); + } + + public bool CheckCancelFlag(string key) + { + var fromCache = Cache.Get(GetCancelCacheKey(key)); + + return !String.IsNullOrEmpty(fromCache); + } + + public void SetCancelFlag(string key) + { + Cache.Insert(GetCancelCacheKey(key), "true", TimeSpan.FromMinutes(1)); + } + + public void ResetAll(string key) + { + Cache.Remove(GetStateCacheKey(key)); + Cache.Remove(GetCancelCacheKey(key)); + } + } + + [Transient] + public class ExportDataOperation : IProgressItem + { + public ExportDataOperation(UserManager userManager, + FileUtility fileUtility, + SecurityContext securityContext, + IOptionsMonitor logger, + TenantManager tenantManager, + Global global, + ExportDataCache exportDataCache, + CommonLinkUtility commonLinkUtility, + NotifyClient notifyClient, + DaoFactory daoFactory, + FileUploader fileUploader, + GlobalFolder globalFolder, + FileMarker fileMarker, + IDaoFactory fileDaoFactory, + FilesLinkUtility filesLinkUtility, + DisplayUserSettingsHelper displayUserSettingsHelper) + { + DaoFactory = daoFactory; + UserManager = userManager; + FileUtility = fileUtility; + FileUploader = fileUploader; + + _tenantId = tenantManager.GetCurrentTenant().TenantId; + + _author = securityContext.CurrentAccount; + _dataStore = global.GetStore(); + _notifyClient = notifyClient; + + _log = logger.Get("ASC.CRM"); + + Status = ProgressStatus.Queued; + Error = null; + Percentage = 0; + IsCompleted = false; + FileUrl = null; + + ExportDataCache = exportDataCache; + SecurityContext = securityContext; + + CommonLinkUtility = commonLinkUtility; + GlobalFolder = globalFolder; + FileMarker = fileMarker; + FileDaoFactory = fileDaoFactory; + FilesLinkUtility = filesLinkUtility; + DisplayUserSettingsHelper = displayUserSettingsHelper; + } + + public void Configure(object id, FilterObject filterObject, string fileName) + { + FileName = fileName ?? CRMSettingResource.Export + (filterObject == null ? ".zip" : ".csv"); + _filterObject = filterObject; + Id = id; + } + + + public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } + public FilesLinkUtility FilesLinkUtility { get; } + public FileMarker FileMarker { get; } + public IDaoFactory FileDaoFactory { get; } + public GlobalFolder GlobalFolder { get; } + public FileUploader FileUploader { get; } + public TenantManager TenantManager { get; } + public CommonLinkUtility CommonLinkUtility { get; } + public SecurityContext SecurityContext { get; } + public DaoFactory DaoFactory { get; } + public ExportDataCache ExportDataCache { get; } + public UserManager UserManager { get; } + public FileUtility FileUtility { get; } + + private readonly int _tenantId; + + private readonly IAccount _author; -// public bool IsCompleted { get; set; } + private readonly IDataStore _dataStore; -// public string FileName { get; set; } + private readonly NotifyClient _notifyClient; -// public string FileUrl { get; set; } - -// private String WrapDoubleQuote(String value) -// { -// return "\"" + value.Trim().Replace("\"", "\"\"") + "\""; -// } - -// private String DataTableToCsv(DataTable dataTable) -// { -// var result = new StringBuilder(); - -// var columnsCount = dataTable.Columns.Count; - -// for (var index = 0; index < columnsCount; index++) -// { -// if (index != columnsCount - 1) -// result.Append(dataTable.Columns[index].Caption + ","); -// else -// result.Append(dataTable.Columns[index].Caption); -// } - -// result.Append(Environment.NewLine); - -// foreach (DataRow row in dataTable.Rows) -// { -// for (var i = 0; i < columnsCount; i++) -// { -// var itemValue = WrapDoubleQuote(row[i].ToString()); - -// if (i != columnsCount - 1) -// result.Append(itemValue + ","); -// else -// result.Append(itemValue); -// } - -// result.Append(Environment.NewLine); -// } - -// return result.ToString(); -// } - -// public void RunJob() -// { -// try -// { -// Status = ProgressStatus.Started; - -// TenantManager.SetCurrentTenant(_tenantId); -// SecurityContext.AuthenticateMe(_author); - -// var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); - -// System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; -// System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; - -// _log.Debug("Start Export Data"); - -// ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); - -// if (_filterObject == null) -// ExportAllData(daoFactory); -// else -// ExportPartData(daoFactory); - -// Complete(100, ProgressStatus.Done, null); - -// _log.Debug("Export is completed"); -// } -// catch (OperationCanceledException) -// { -// Complete(0, ProgressStatus.Done, null); - -// _log.Debug("Export is cancel"); -// } -// catch (Exception ex) -// { -// Complete(0, ProgressStatus.Failed, ex.Message); - -// _log.Error(ex); -// } -// finally -// { -// ExportDataCache.ResetAll((string)Id); -// } -// } - -// private void Complete(double percentage, ProgressStatus status, object error) -// { -// IsCompleted = true; -// Percentage = percentage; -// Status = status; -// Error = error; - -// ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); -// } - -// private void ExportAllData(DaoFactory daoFactory) -// { -// using (var stream = TempStream.Create()) -// { -// var contactDao = daoFactory.GetContactDao(); -// var contactInfoDao = daoFactory.GetContactInfoDao(); -// var dealDao = daoFactory.GetDealDao(); -// var casesDao = daoFactory.GetCasesDao(); -// var taskDao = daoFactory.GetTaskDao(); -// var historyDao = daoFactory.GetRelationshipEventDao(); -// var invoiceItemDao = daoFactory.GetInvoiceItemDao(); - -// _totalCount += contactDao.GetAllContactsCount(); -// _totalCount += dealDao.GetDealsCount(); -// _totalCount += casesDao.GetCasesCount(); -// _totalCount += taskDao.GetAllTasksCount(); -// _totalCount += historyDao.GetAllItemsCount(); -// _totalCount += invoiceItemDao.GetInvoiceItemsCount(); - -// using (var zipStream = new ZipOutputStream(stream)) -// { -// zipStream.PutNextEntry(new ZipEntry(CRMContactResource.Contacts + ".csv")); - -// var contactData = contactDao.GetAllContacts(); -// var contactInfos = new StringDictionary(); - -// contactInfoDao.GetAll() -// .ForEach(item => -// { -// var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, (int)item.InfoType, item.Category); -// if (contactInfos.ContainsKey(contactInfoKey)) -// { -// contactInfos[contactInfoKey] += "," + item.Data; -// } -// else -// { -// contactInfos.Add(contactInfoKey, item.Data); -// } -// }); - -// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportContactsToCsv(contactData, contactInfos, daoFactory)))) -// { -// zipEntryData.CopyTo(zipStream); -// } - -// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.DealModuleName + ".csv")); - -// var dealData = dealDao.GetAllDeals(); - -// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportDealsToCsv(dealData, daoFactory)))) -// { -// zipEntryData.CopyTo(zipStream); -// } - -// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.CasesModuleName + ".csv")); - -// var casesData = casesDao.GetAllCases(); - -// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportCasesToCsv(casesData, daoFactory)))) -// { -// zipEntryData.CopyTo(zipStream); -// } - - -// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.TaskModuleName + ".csv")); - -// var taskData = taskDao.GetAllTasks(); - -// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportTasksToCsv(taskData, daoFactory)))) -// { -// zipEntryData.CopyTo(zipStream); -// } - -// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.History + ".csv")); - -// var historyData = historyDao.GetAllItems(); - -// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportHistoryToCsv(historyData, daoFactory)))) -// { -// zipEntryData.CopyTo(zipStream); -// } - -// zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.ProductsAndServices + ".csv")); - -// var invoiceItemData = invoiceItemDao.GetAll(); - -// using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportInvoiceItemsToCsv(invoiceItemData, daoFactory)))) -// { -// zipEntryData.CopyTo(zipStream); -// } - -// zipStream.Flush(); -// zipStream.Close(); - -// stream.Position = 0; -// } - -// FileUrl = CommonLinkUtility.GetFullAbsolutePath(_dataStore.SavePrivate(String.Empty, FileName, stream, DateTime.Now.AddDays(1))); - -// _notifyClient.SendAboutExportCompleted(_author.ID, FileName, FileUrl); -// } -// } - -// private void ExportPartData(DaoFactory daoFactory) -// { -// var items = _filterObject.GetItemsByFilter(daoFactory); - -// string fileContent; - -// _totalCount = items.Count; - -// if (_totalCount == 0) -// throw new ArgumentException(CRMErrorsResource.ExportToCSVDataEmpty); - -// if (items is List) -// { -// var contactInfoDao = daoFactory.GetContactInfoDao(); - -// var contacts = (List)items; - -// var contactInfos = new StringDictionary(); - -// contactInfoDao.GetAll(contacts.Select(item => item.ID).ToArray()) -// .ForEach(item => -// { -// var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, -// (int)item.InfoType, -// item.Category); - -// if (contactInfos.ContainsKey(contactInfoKey)) -// contactInfos[contactInfoKey] += "," + item.Data; -// else -// contactInfos.Add(contactInfoKey, item.Data); -// }); - -// fileContent = ExportContactsToCsv(contacts, contactInfos, daoFactory); -// } -// else if (items is List) -// { -// fileContent = ExportDealsToCsv((List)items, daoFactory); -// } -// else if (items is List) -// { -// fileContent = ExportCasesToCsv((List)items, daoFactory); -// } -// else if (items is List) -// { -// fileContent = ExportHistoryToCsv((List)items, daoFactory); -// } -// else if (items is List) -// { -// fileContent = ExportTasksToCsv((List)items, daoFactory); -// } -// else if (items is List) -// { -// fileContent = ExportInvoiceItemsToCsv((List)items, daoFactory); -// } -// else -// throw new ArgumentException(); - -// FileUrl = SaveCsvFileInMyDocument(FileName, fileContent); -// } - -// private String ExportContactsToCsv(IReadOnlyCollection contacts, StringDictionary contactInfos, DaoFactory daoFactory) -// { -// var key = (string)Id; -// var listItemDao = daoFactory.GetListItemDao(); -// var tagDao = daoFactory.GetTagDao(); -// var customFieldDao = daoFactory.GetCustomFieldDao(); -// var contactDao = daoFactory.GetContactDao(); - -// var dataTable = new DataTable(); - -// dataTable.Columns.AddRange(new[] -// { -// new DataColumn -// { -// Caption = CRMCommonResource.TypeCompanyOrPerson, -// ColumnName = "company/person" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.FirstName, -// ColumnName = "firstname" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.LastName, -// ColumnName = "lastname" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.CompanyName, -// ColumnName = "companyname" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.JobTitle, -// ColumnName = "jobtitle" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.About, -// ColumnName = "about" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.ContactStage, -// ColumnName = "contact_stage" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.ContactType, -// ColumnName = "contact_type" -// }, -// new DataColumn -// { -// Caption = CRMContactResource.ContactTagList, -// ColumnName = "contact_tag_list" -// } -// }); - -// foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) -// foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) -// { -// var localTitle = String.Format("{1} ({0})", categoryEnum.ToLocalizedString().ToLower(), infoTypeEnum.ToLocalizedString()); - -// if (infoTypeEnum == ContactInfoType.Address) -// dataTable.Columns.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) -// select new DataColumn -// { -// Caption = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString().ToLower()), -// ColumnName = String.Format("contactInfo_{0}_{1}_{2}", (int)infoTypeEnum, categoryEnum, (int)addressPartEnum) -// }).ToArray()); - -// else -// dataTable.Columns.Add(new DataColumn -// { -// Caption = localTitle, -// ColumnName = String.Format("contactInfo_{0}_{1}", (int)infoTypeEnum, categoryEnum) -// }); -// } - -// var fieldsDescription = customFieldDao.GetFieldsDescription(EntityType.Company); - -// customFieldDao.GetFieldsDescription(EntityType.Person).ForEach(item => -// { -// var alreadyContains = fieldsDescription.Any(field => field.ID == item.ID); - -// if (!alreadyContains) -// fieldsDescription.Add(item); -// }); - -// fieldsDescription.ForEach( -// item => -// { -// if (item.FieldType == CustomFieldType.Heading) return; - -// dataTable.Columns.Add( -// new DataColumn -// { -// Caption = item.Label, -// ColumnName = "customField_" + item.ID -// } -// ); -// }); - -// var customFieldEntity = new Dictionary>(); - -// var entityFields = customFieldDao.GetEnityFields(EntityType.Company, 0, false); - -// customFieldDao.GetEnityFields(EntityType.Person, 0, false).ForEach(item => -// { -// var alreadyContains = entityFields.Any(field => field.ID == item.ID && field.EntityID == item.EntityID); - -// if (!alreadyContains) -// entityFields.Add(item); -// }); - -// entityFields.ForEach( -// item => -// { -// if (!customFieldEntity.ContainsKey(item.EntityID)) -// customFieldEntity.Add(item.EntityID, new List { item }); -// else -// customFieldEntity[item.EntityID].Add(item); -// }); - -// var tags = tagDao.GetEntitiesTags(EntityType.Contact); - -// foreach (var contact in contacts) -// { -// if (ExportDataCache.CheckCancelFlag(key)) -// { -// ExportDataCache.ResetAll(key); - -// throw new OperationCanceledException(); -// } - -// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - -// Percentage += 1.0 * 100 / _totalCount; - -// var isCompany = contact is Company; - -// var compPersType = (isCompany) ? CRMContactResource.Company : CRMContactResource.Person; - -// var contactTags = String.Empty; - -// if (tags.ContainsKey(contact.ID)) -// contactTags = String.Join(",", tags[contact.ID].OrderBy(x => x)); - -// String firstName; -// String lastName; - -// String companyName; -// String title; - -// if (contact is Company) -// { -// firstName = String.Empty; -// lastName = String.Empty; -// title = String.Empty; -// companyName = ((Company)contact).CompanyName; -// } -// else -// { -// var people = (Person)contact; - -// firstName = people.FirstName; -// lastName = people.LastName; -// title = people.JobTitle; - -// companyName = String.Empty; - -// if (people.CompanyID > 0) -// { -// var personCompany = contacts.SingleOrDefault(item => item.ID == people.CompanyID) ?? -// contactDao.GetByID(people.CompanyID); - -// if (personCompany != null) -// companyName = personCompany.GetTitle(); -// } -// } - -// var contactStatus = String.Empty; - -// if (contact.StatusID > 0) -// { - -// var listItem = listItemDao.GetByID(contact.StatusID); - -// if (listItem != null) -// contactStatus = listItem.Title; -// } - -// var contactType = String.Empty; - -// if (contact.ContactTypeID > 0) -// { - -// var listItem = listItemDao.GetByID(contact.ContactTypeID); - -// if (listItem != null) -// contactType = listItem.Title; -// } - -// var dataRowItems = new List -// { -// compPersType, -// firstName, -// lastName, -// companyName, -// title, -// contact.About, -// contactStatus, -// contactType, -// contactTags -// }; - -// foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) -// foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) -// { -// var contactInfoKey = String.Format("{0}_{1}_{2}", contact.ID, -// (int)infoTypeEnum, -// Convert.ToInt32(categoryEnum)); - -// var columnValue = ""; - -// if (contactInfos.ContainsKey(contactInfoKey)) -// columnValue = contactInfos[contactInfoKey]; - -// if (infoTypeEnum == ContactInfoType.Address) -// { -// if (!String.IsNullOrEmpty(columnValue)) -// { -// var addresses = JArray.Parse(String.Concat("[", columnValue, "]")); - -// dataRowItems.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) -// select String.Join(",", addresses.Select(item => (String)item.SelectToken(addressPartEnum.ToString().ToLower())).ToArray())).ToArray()); -// } -// else -// { -// dataRowItems.AddRange(new[] { "", "", "", "", "" }); -// } -// } -// else -// { -// dataRowItems.Add(columnValue); -// } -// } - -// var dataRow = dataTable.Rows.Add(dataRowItems.ToArray()); - -// if (customFieldEntity.ContainsKey(contact.ID)) -// customFieldEntity[contact.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); -// } - -// return DataTableToCsv(dataTable); -// } - -// private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) -// { -// var key = (string)Id; -// var tagDao = daoFactory.GetTagDao(); -// var customFieldDao = daoFactory.GetCustomFieldDao(); -// var dealMilestoneDao = daoFactory.GetDealMilestoneDao(); -// var contactDao = daoFactory.GetContactDao(); - -// var dataTable = new DataTable(); - -// dataTable.Columns.AddRange(new[] -// { -// new DataColumn -// { -// Caption = CRMDealResource.NameDeal, -// ColumnName = "title" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.ClientDeal, -// ColumnName = "client_deal" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.DescriptionDeal, -// ColumnName = "description" -// }, -// new DataColumn -// { -// Caption = CRMCommonResource.Currency, -// ColumnName = "currency" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.DealAmount, -// ColumnName = "amount" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.BidType, -// ColumnName = "bid_type" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.BidTypePeriod, -// ColumnName = "bid_type_period" -// }, -// new DataColumn -// { -// Caption = CRMJSResource.ExpectedCloseDate, -// ColumnName = "expected_close_date" -// }, -// new DataColumn -// { -// Caption = CRMJSResource.ActualCloseDate, -// ColumnName = "actual_close_date" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.ResponsibleDeal, -// ColumnName = "responsible_deal" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.CurrentDealMilestone, -// ColumnName = "current_deal_milestone" -// }, -// new DataColumn -// { -// Caption = CRMDealResource.DealMilestoneType, -// ColumnName = "deal_milestone_type" -// }, -// new DataColumn -// { -// Caption = (CRMDealResource.ProbabilityOfWinning + " %"), -// ColumnName = "probability_of_winning" -// }, -// new DataColumn -// { -// Caption = (CRMDealResource.DealTagList), -// ColumnName = "tag_list" -// } -// }); - -// customFieldDao.GetFieldsDescription(EntityType.Opportunity).ForEach( -// item => -// { -// if (item.FieldType == CustomFieldType.Heading) return; - -// dataTable.Columns.Add(new DataColumn -// { -// Caption = item.Label, -// ColumnName = "customField_" + item.ID -// }); -// }); - -// var customFieldEntity = new Dictionary>(); - -// customFieldDao.GetEnityFields(EntityType.Opportunity, 0, false).ForEach( -// item => -// { -// if (!customFieldEntity.ContainsKey(item.EntityID)) -// customFieldEntity.Add(item.EntityID, new List { item }); -// else -// customFieldEntity[item.EntityID].Add(item); -// }); - -// var tags = tagDao.GetEntitiesTags(EntityType.Opportunity); - -// foreach (var deal in deals) -// { -// if (ExportDataCache.CheckCancelFlag(key)) -// { -// ExportDataCache.ResetAll(key); - -// throw new OperationCanceledException(); -// } - -// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - -// Percentage += 1.0 * 100 / _totalCount; - -// var contactTags = String.Empty; - -// if (tags.ContainsKey(deal.ID)) -// contactTags = String.Join(",", tags[deal.ID].OrderBy(x => x)); - -// String bidType; - -// switch (deal.BidType) -// { -// case BidType.FixedBid: -// bidType = CRMDealResource.BidType_FixedBid; -// break; -// case BidType.PerDay: -// bidType = CRMDealResource.BidType_PerDay; -// break; -// case BidType.PerHour: -// bidType = CRMDealResource.BidType_PerHour; -// break; -// case BidType.PerMonth: -// bidType = CRMDealResource.BidType_PerMonth; -// break; -// case BidType.PerWeek: -// bidType = CRMDealResource.BidType_PerWeek; -// break; -// case BidType.PerYear: -// bidType = CRMDealResource.BidType_PerYear; -// break; -// default: -// throw new ArgumentException(); -// } - -// var currentDealMilestone = dealMilestoneDao.GetByID(deal.DealMilestoneID); -// var currentDealMilestoneStatus = currentDealMilestone.Status.ToLocalizedString(); -// var contactTitle = String.Empty; - -// if (deal.ContactID != 0) -// contactTitle = contactDao.GetByID(deal.ContactID).GetTitle(); - -// var dataRow = dataTable.Rows.Add(new object[] -// { -// deal.Title, -// contactTitle, -// deal.Description, -// deal.BidCurrency, -// deal.BidValue.ToString(CultureInfo.InvariantCulture), -// bidType, -// deal.PerPeriodValue == 0 ? "" : deal.PerPeriodValue.ToString(CultureInfo.InvariantCulture), -// deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern), -// deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern), -// UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(DisplayUserSettingsHelper), -// currentDealMilestone.Title, -// currentDealMilestoneStatus, -// deal.DealMilestoneProbability.ToString(CultureInfo.InvariantCulture), -// contactTags -// }); - -// if (customFieldEntity.ContainsKey(deal.ID)) -// customFieldEntity[deal.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); -// } - -// return DataTableToCsv(dataTable); -// } - -// private String ExportCasesToCsv(IEnumerable cases, DaoFactory daoFactory) -// { -// var key = (string)Id; -// var tagDao = daoFactory.GetTagDao(); -// var customFieldDao = daoFactory.GetCustomFieldDao(); - -// var dataTable = new DataTable(); - -// dataTable.Columns.AddRange(new[] -// { -// new DataColumn -// { -// Caption = CRMCasesResource.CaseTitle, -// ColumnName = "title" -// }, -// new DataColumn(CRMCasesResource.CasesTagList) -// { -// Caption = CRMCasesResource.CasesTagList, -// ColumnName = "tag_list" -// } -// }); - -// customFieldDao.GetFieldsDescription(EntityType.Case).ForEach( -// item => -// { -// if (item.FieldType == CustomFieldType.Heading) return; - -// dataTable.Columns.Add(new DataColumn -// { -// Caption = item.Label, -// ColumnName = "customField_" + item.ID -// }); -// }); - -// var customFieldEntity = new Dictionary>(); - -// customFieldDao.GetEnityFields(EntityType.Case, 0, false).ForEach( -// item => -// { -// if (!customFieldEntity.ContainsKey(item.EntityID)) -// customFieldEntity.Add(item.EntityID, new List { item }); -// else -// customFieldEntity[item.EntityID].Add(item); -// }); - -// var tags = tagDao.GetEntitiesTags(EntityType.Case); - -// foreach (var item in cases) -// { -// if (ExportDataCache.CheckCancelFlag(key)) -// { -// ExportDataCache.ResetAll(key); - -// throw new OperationCanceledException(); -// } - -// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - -// Percentage += 1.0 * 100 / _totalCount; - -// var contactTags = String.Empty; - -// if (tags.ContainsKey(item.ID)) -// contactTags = String.Join(",", tags[item.ID].OrderBy(x => x)); - -// var dataRow = dataTable.Rows.Add(new object[] -// { -// item.Title, -// contactTags -// }); - -// if (customFieldEntity.ContainsKey(item.ID)) -// customFieldEntity[item.ID].ForEach(row => dataRow["customField_" + row.ID] = row.Value); -// } - -// return DataTableToCsv(dataTable); -// } - -// private String ExportHistoryToCsv(IEnumerable events, DaoFactory daoFactory) -// { -// var key = (string)Id; -// var listItemDao = daoFactory.GetListItemDao(); -// var dealDao = daoFactory.GetDealDao(); -// var casesDao = daoFactory.GetCasesDao(); -// var contactDao = daoFactory.GetContactDao(); - -// var dataTable = new DataTable(); - -// dataTable.Columns.AddRange(new[] -// { -// new DataColumn -// { -// Caption = (CRMContactResource.Content), -// ColumnName = "content" -// }, -// new DataColumn -// { -// Caption = (CRMCommonResource.Category), -// ColumnName = "category" -// }, -// new DataColumn -// { -// Caption = (CRMContactResource.ContactTitle), -// ColumnName = "contact_title" -// }, -// new DataColumn -// { -// Caption = (CRMContactResource.RelativeEntity), -// ColumnName = "relative_entity" -// }, -// new DataColumn -// { -// Caption = (CRMCommonResource.Author), -// ColumnName = "author" -// }, -// new DataColumn -// { -// Caption = (CRMCommonResource.CreateDate), -// ColumnName = "create_date" -// } -// }); - -// foreach (var item in events) -// { -// if (ExportDataCache.CheckCancelFlag(key)) -// { -// ExportDataCache.ResetAll(key); - -// throw new OperationCanceledException(); -// } - -// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - -// Percentage += 1.0 * 100 / _totalCount; - -// var entityTitle = String.Empty; - -// if (item.EntityID > 0) -// switch (item.EntityType) -// { -// case EntityType.Case: -// var casesObj = casesDao.GetByID(item.EntityID); - -// if (casesObj != null) -// entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, -// casesObj.Title); -// break; -// case EntityType.Opportunity: -// var dealObj = dealDao.GetByID(item.EntityID); - -// if (dealObj != null) -// entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, -// dealObj.Title); -// break; -// } - -// var contactTitle = String.Empty; - -// if (item.ContactID > 0) -// { -// var contactObj = contactDao.GetByID(item.ContactID); - -// if (contactObj != null) -// contactTitle = contactObj.GetTitle(); -// } - -// var categoryTitle = String.Empty; - -// if (item.CategoryID > 0) -// { -// var categoryObj = listItemDao.GetByID(item.CategoryID); - -// if (categoryObj != null) -// categoryTitle = categoryObj.Title; - -// } -// else if (item.CategoryID == (int)HistoryCategorySystem.TaskClosed) -// categoryTitle = HistoryCategorySystem.TaskClosed.ToLocalizedString(); -// else if (item.CategoryID == (int)HistoryCategorySystem.FilesUpload) -// categoryTitle = HistoryCategorySystem.FilesUpload.ToLocalizedString(); -// else if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) -// categoryTitle = HistoryCategorySystem.MailMessage.ToLocalizedString(); - -// dataTable.Rows.Add(new object[] -// { -// item.Content, -// categoryTitle, -// contactTitle, -// entityTitle, -// UserManager.GetUsers(item.CreateBy).DisplayUserName(DisplayUserSettingsHelper), -// item.CreateOn.ToShortString() -// }); -// } - -// return DataTableToCsv(dataTable); -// } - -// private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) -// { -// var key = (string)Id; -// var listItemDao = daoFactory.GetListItemDao(); -// var dealDao = daoFactory.GetDealDao(); -// var casesDao = daoFactory.GetCasesDao(); -// var contactDao = daoFactory.GetContactDao(); - -// var dataTable = new DataTable(); - -// dataTable.Columns.AddRange(new[] -// { -// new DataColumn -// { -// Caption = (CRMTaskResource.TaskTitle), -// ColumnName = "title" -// }, -// new DataColumn -// { -// Caption = (CRMTaskResource.Description), -// ColumnName = "description" -// }, -// new DataColumn -// { -// Caption = (CRMTaskResource.DueDate), -// ColumnName = "due_date" -// }, -// new DataColumn -// { -// Caption = (CRMTaskResource.Responsible), -// ColumnName = "responsible" -// }, -// new DataColumn -// { -// Caption = (CRMContactResource.ContactTitle), -// ColumnName = "contact_title" -// }, -// new DataColumn -// { -// Caption = (CRMTaskResource.TaskStatus), -// ColumnName = "task_status" -// }, -// new DataColumn -// { -// Caption = (CRMTaskResource.TaskCategory), -// ColumnName = "task_category" -// }, -// new DataColumn -// { -// Caption = (CRMContactResource.RelativeEntity), -// ColumnName = "relative_entity" -// }, -// new DataColumn -// { -// Caption = (CRMCommonResource.Alert), -// ColumnName = "alert_value" -// } -// }); - -// foreach (var item in tasks) -// { -// if (ExportDataCache.CheckCancelFlag(key)) -// { -// ExportDataCache.ResetAll(key); - -// throw new OperationCanceledException(); -// } - -// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - -// Percentage += 1.0 * 100 / _totalCount; - -// var entityTitle = String.Empty; - -// if (item.EntityID > 0) -// switch (item.EntityType) -// { -// case EntityType.Case: -// var caseObj = casesDao.GetByID(item.EntityID); - -// if (caseObj != null) -// entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, caseObj.Title); -// break; -// case EntityType.Opportunity: -// var dealObj = dealDao.GetByID(item.EntityID); - -// if (dealObj != null) -// entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, dealObj.Title); -// break; -// } - -// var contactTitle = String.Empty; - -// if (item.ContactID > 0) -// { -// var contact = contactDao.GetByID(item.ContactID); - -// if (contact != null) -// contactTitle = contact.GetTitle(); -// } - -// dataTable.Rows.Add(new object[] -// { -// item.Title, -// item.Description, -// item.DeadLine == DateTime.MinValue -// ? "" + private FilterObject _filterObject; + + private readonly ILog _log; + + private int _totalCount; + + public override bool Equals(object obj) + { + if (obj == null) return false; + + var exportDataOperation = obj as ExportDataOperation; + + if (exportDataOperation == null) return false; + + return Id == exportDataOperation.Id; + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + + public object Clone() + { + return MemberwiseClone(); + } + + public object Id { get; set; } + + public object Status { get; set; } + + public object Error { get; set; } + + public double Percentage { get; set; } + + public bool IsCompleted { get; set; } + + public string FileName { get; set; } + + public string FileUrl { get; set; } + + private String WrapDoubleQuote(String value) + { + return "\"" + value.Trim().Replace("\"", "\"\"") + "\""; + } + + private String DataTableToCsv(DataTable dataTable) + { + var result = new StringBuilder(); + + var columnsCount = dataTable.Columns.Count; + + for (var index = 0; index < columnsCount; index++) + { + if (index != columnsCount - 1) + result.Append(dataTable.Columns[index].Caption + ","); + else + result.Append(dataTable.Columns[index].Caption); + } + + result.Append(Environment.NewLine); + + foreach (DataRow row in dataTable.Rows) + { + for (var i = 0; i < columnsCount; i++) + { + var itemValue = WrapDoubleQuote(row[i].ToString()); + + if (i != columnsCount - 1) + result.Append(itemValue + ","); + else + result.Append(itemValue); + } + + result.Append(Environment.NewLine); + } + + return result.ToString(); + } + + public void RunJob() + { + try + { + Status = ProgressStatus.Started; + + TenantManager.SetCurrentTenant(_tenantId); + SecurityContext.AuthenticateMe(_author); + + var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + + System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; + System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; + + _log.Debug("Start Export Data"); + + ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); + + if (_filterObject == null) + ExportAllData(DaoFactory); + else + ExportPartData(DaoFactory); + + Complete(100, ProgressStatus.Done, null); + + _log.Debug("Export is completed"); + } + catch (OperationCanceledException) + { + Complete(0, ProgressStatus.Done, null); + + _log.Debug("Export is cancel"); + } + catch (Exception ex) + { + Complete(0, ProgressStatus.Failed, ex.Message); + + _log.Error(ex); + } + finally + { + ExportDataCache.ResetAll((string)Id); + } + } + + private void Complete(double percentage, ProgressStatus status, object error) + { + IsCompleted = true; + Percentage = percentage; + Status = status; + Error = error; + + ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); + } + + private void ExportAllData(DaoFactory daoFactory) + { + using (var stream = TempStream.Create()) + { + var contactDao = daoFactory.GetContactDao(); + var contactInfoDao = daoFactory.GetContactInfoDao(); + var dealDao = daoFactory.GetDealDao(); + var casesDao = daoFactory.GetCasesDao(); + var taskDao = daoFactory.GetTaskDao(); + var historyDao = daoFactory.GetRelationshipEventDao(); + var invoiceItemDao = daoFactory.GetInvoiceItemDao(); + + _totalCount += contactDao.GetAllContactsCount(); + _totalCount += dealDao.GetDealsCount(); + _totalCount += casesDao.GetCasesCount(); + _totalCount += taskDao.GetAllTasksCount(); + _totalCount += historyDao.GetAllItemsCount(); + _totalCount += invoiceItemDao.GetInvoiceItemsCount(); + + using (var zipStream = new ZipOutputStream(stream)) + { + zipStream.PutNextEntry(new ZipEntry(CRMContactResource.Contacts + ".csv")); + + var contactData = contactDao.GetAllContacts(); + var contactInfos = new StringDictionary(); + + contactInfoDao.GetAll() + .ForEach(item => + { + var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, (int)item.InfoType, item.Category); + if (contactInfos.ContainsKey(contactInfoKey)) + { + contactInfos[contactInfoKey] += "," + item.Data; + } + else + { + contactInfos.Add(contactInfoKey, item.Data); + } + }); + + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportContactsToCsv(contactData, contactInfos, daoFactory)))) + { + zipEntryData.CopyTo(zipStream); + } + + zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.DealModuleName + ".csv")); + + var dealData = dealDao.GetAllDeals(); + + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportDealsToCsv(dealData, daoFactory)))) + { + zipEntryData.CopyTo(zipStream); + } + + zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.CasesModuleName + ".csv")); + + var casesData = casesDao.GetAllCases(); + + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportCasesToCsv(casesData, daoFactory)))) + { + zipEntryData.CopyTo(zipStream); + } + + + zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.TaskModuleName + ".csv")); + + var taskData = taskDao.GetAllTasks(); + + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportTasksToCsv(taskData, daoFactory)))) + { + zipEntryData.CopyTo(zipStream); + } + + zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.History + ".csv")); + + var historyData = historyDao.GetAllItems(); + + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportHistoryToCsv(historyData, daoFactory)))) + { + zipEntryData.CopyTo(zipStream); + } + + zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.ProductsAndServices + ".csv")); + + var invoiceItemData = invoiceItemDao.GetAll(); + + using (var zipEntryData = new MemoryStream(Encoding.UTF8.GetBytes(ExportInvoiceItemsToCsv(invoiceItemData, daoFactory)))) + { + zipEntryData.CopyTo(zipStream); + } + + zipStream.Flush(); + zipStream.Close(); + + stream.Position = 0; + } + + FileUrl = CommonLinkUtility.GetFullAbsolutePath(_dataStore.SavePrivate(String.Empty, FileName, stream, DateTime.Now.AddDays(1))); + + _notifyClient.SendAboutExportCompleted(_author.ID, FileName, FileUrl); + } + } + + private void ExportPartData(DaoFactory daoFactory) + { + var items = _filterObject.GetItemsByFilter(daoFactory); + + string fileContent; + + _totalCount = items.Count; + + if (_totalCount == 0) + throw new ArgumentException(CRMErrorsResource.ExportToCSVDataEmpty); + + if (items is List) + { + var contactInfoDao = daoFactory.GetContactInfoDao(); + + var contacts = (List)items; + + var contactInfos = new StringDictionary(); + + contactInfoDao.GetAll(contacts.Select(item => item.ID).ToArray()) + .ForEach(item => + { + var contactInfoKey = String.Format("{0}_{1}_{2}", item.ContactID, + (int)item.InfoType, + item.Category); + + if (contactInfos.ContainsKey(contactInfoKey)) + contactInfos[contactInfoKey] += "," + item.Data; + else + contactInfos.Add(contactInfoKey, item.Data); + }); + + fileContent = ExportContactsToCsv(contacts, contactInfos, daoFactory); + } + else if (items is List) + { + fileContent = ExportDealsToCsv((List)items, daoFactory); + } + else if (items is List) + { + fileContent = ExportCasesToCsv((List)items, daoFactory); + } + else if (items is List) + { + fileContent = ExportHistoryToCsv((List)items, daoFactory); + } + else if (items is List) + { + fileContent = ExportTasksToCsv((List)items, daoFactory); + } + else if (items is List) + { + fileContent = ExportInvoiceItemsToCsv((List)items, daoFactory); + } + else + throw new ArgumentException(); + + FileUrl = SaveCsvFileInMyDocument(FileName, fileContent); + } + + private String ExportContactsToCsv(IReadOnlyCollection contacts, StringDictionary contactInfos, DaoFactory daoFactory) + { + var key = (string)Id; + var listItemDao = daoFactory.GetListItemDao(); + var tagDao = daoFactory.GetTagDao(); + var customFieldDao = daoFactory.GetCustomFieldDao(); + var contactDao = daoFactory.GetContactDao(); + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = CRMCommonResource.TypeCompanyOrPerson, + ColumnName = "company/person" + }, + new DataColumn + { + Caption = CRMContactResource.FirstName, + ColumnName = "firstname" + }, + new DataColumn + { + Caption = CRMContactResource.LastName, + ColumnName = "lastname" + }, + new DataColumn + { + Caption = CRMContactResource.CompanyName, + ColumnName = "companyname" + }, + new DataColumn + { + Caption = CRMContactResource.JobTitle, + ColumnName = "jobtitle" + }, + new DataColumn + { + Caption = CRMContactResource.About, + ColumnName = "about" + }, + new DataColumn + { + Caption = CRMContactResource.ContactStage, + ColumnName = "contact_stage" + }, + new DataColumn + { + Caption = CRMContactResource.ContactType, + ColumnName = "contact_type" + }, + new DataColumn + { + Caption = CRMContactResource.ContactTagList, + ColumnName = "contact_tag_list" + } + }); + + foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) + foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) + { + var localTitle = String.Format("{1} ({0})", categoryEnum.ToLocalizedString().ToLower(), infoTypeEnum.ToLocalizedString()); + + if (infoTypeEnum == ContactInfoType.Address) + dataTable.Columns.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) + select new DataColumn + { + Caption = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString().ToLower()), + ColumnName = String.Format("contactInfo_{0}_{1}_{2}", (int)infoTypeEnum, categoryEnum, (int)addressPartEnum) + }).ToArray()); + + else + dataTable.Columns.Add(new DataColumn + { + Caption = localTitle, + ColumnName = String.Format("contactInfo_{0}_{1}", (int)infoTypeEnum, categoryEnum) + }); + } + + var fieldsDescription = customFieldDao.GetFieldsDescription(EntityType.Company); + + customFieldDao.GetFieldsDescription(EntityType.Person).ForEach(item => + { + var alreadyContains = fieldsDescription.Any(field => field.ID == item.ID); + + if (!alreadyContains) + fieldsDescription.Add(item); + }); + + fieldsDescription.ForEach( + item => + { + if (item.FieldType == CustomFieldType.Heading) return; + + dataTable.Columns.Add( + new DataColumn + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + } + ); + }); + + var customFieldEntity = new Dictionary>(); + + var entityFields = customFieldDao.GetEnityFields(EntityType.Company, 0, false); + + customFieldDao.GetEnityFields(EntityType.Person, 0, false).ForEach(item => + { + var alreadyContains = entityFields.Any(field => field.ID == item.ID && field.EntityID == item.EntityID); + + if (!alreadyContains) + entityFields.Add(item); + }); + + entityFields.ForEach( + item => + { + if (!customFieldEntity.ContainsKey(item.EntityID)) + customFieldEntity.Add(item.EntityID, new List { item }); + else + customFieldEntity[item.EntityID].Add(item); + }); + + var tags = tagDao.GetEntitiesTags(EntityType.Contact); + + foreach (var contact in contacts) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var isCompany = contact is Company; + + var compPersType = (isCompany) ? CRMContactResource.Company : CRMContactResource.Person; + + var contactTags = String.Empty; + + if (tags.ContainsKey(contact.ID)) + contactTags = String.Join(",", tags[contact.ID].OrderBy(x => x)); + + String firstName; + String lastName; + + String companyName; + String title; + + if (contact is Company) + { + firstName = String.Empty; + lastName = String.Empty; + title = String.Empty; + companyName = ((Company)contact).CompanyName; + } + else + { + var people = (Person)contact; + + firstName = people.FirstName; + lastName = people.LastName; + title = people.JobTitle; + + companyName = String.Empty; + + if (people.CompanyID > 0) + { + var personCompany = contacts.SingleOrDefault(item => item.ID == people.CompanyID) ?? + contactDao.GetByID(people.CompanyID); + + if (personCompany != null) + companyName = personCompany.GetTitle(); + } + } + + var contactStatus = String.Empty; + + if (contact.StatusID > 0) + { + + var listItem = listItemDao.GetByID(contact.StatusID); + + if (listItem != null) + contactStatus = listItem.Title; + } + + var contactType = String.Empty; + + if (contact.ContactTypeID > 0) + { + + var listItem = listItemDao.GetByID(contact.ContactTypeID); + + if (listItem != null) + contactType = listItem.Title; + } + + var dataRowItems = new List + { + compPersType, + firstName, + lastName, + companyName, + title, + contact.About, + contactStatus, + contactType, + contactTags + }; + + foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) + foreach (Enum categoryEnum in Enum.GetValues(ContactInfo.GetCategory(infoTypeEnum))) + { + var contactInfoKey = String.Format("{0}_{1}_{2}", contact.ID, + (int)infoTypeEnum, + Convert.ToInt32(categoryEnum)); + + var columnValue = ""; + + if (contactInfos.ContainsKey(contactInfoKey)) + columnValue = contactInfos[contactInfoKey]; + + if (infoTypeEnum == ContactInfoType.Address) + { + if (!String.IsNullOrEmpty(columnValue)) + { + var addresses = JArray.Parse(String.Concat("[", columnValue, "]")); + + dataRowItems.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) + select String.Join(",", addresses.Select(item => (String)item.SelectToken(addressPartEnum.ToString().ToLower())).ToArray())).ToArray()); + } + else + { + dataRowItems.AddRange(new[] { "", "", "", "", "" }); + } + } + else + { + dataRowItems.Add(columnValue); + } + } + + var dataRow = dataTable.Rows.Add(dataRowItems.ToArray()); + + if (customFieldEntity.ContainsKey(contact.ID)) + customFieldEntity[contact.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); + } + + return DataTableToCsv(dataTable); + } + + private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) + { + var key = (string)Id; + var tagDao = daoFactory.GetTagDao(); + var customFieldDao = daoFactory.GetCustomFieldDao(); + var dealMilestoneDao = daoFactory.GetDealMilestoneDao(); + var contactDao = daoFactory.GetContactDao(); + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = CRMDealResource.NameDeal, + ColumnName = "title" + }, + new DataColumn + { + Caption = CRMDealResource.ClientDeal, + ColumnName = "client_deal" + }, + new DataColumn + { + Caption = CRMDealResource.DescriptionDeal, + ColumnName = "description" + }, + new DataColumn + { + Caption = CRMCommonResource.Currency, + ColumnName = "currency" + }, + new DataColumn + { + Caption = CRMDealResource.DealAmount, + ColumnName = "amount" + }, + new DataColumn + { + Caption = CRMDealResource.BidType, + ColumnName = "bid_type" + }, + new DataColumn + { + Caption = CRMDealResource.BidTypePeriod, + ColumnName = "bid_type_period" + }, + new DataColumn + { + Caption = CRMJSResource.ExpectedCloseDate, + ColumnName = "expected_close_date" + }, + new DataColumn + { + Caption = CRMJSResource.ActualCloseDate, + ColumnName = "actual_close_date" + }, + new DataColumn + { + Caption = CRMDealResource.ResponsibleDeal, + ColumnName = "responsible_deal" + }, + new DataColumn + { + Caption = CRMDealResource.CurrentDealMilestone, + ColumnName = "current_deal_milestone" + }, + new DataColumn + { + Caption = CRMDealResource.DealMilestoneType, + ColumnName = "deal_milestone_type" + }, + new DataColumn + { + Caption = (CRMDealResource.ProbabilityOfWinning + " %"), + ColumnName = "probability_of_winning" + }, + new DataColumn + { + Caption = (CRMDealResource.DealTagList), + ColumnName = "tag_list" + } + }); + + customFieldDao.GetFieldsDescription(EntityType.Opportunity).ForEach( + item => + { + if (item.FieldType == CustomFieldType.Heading) return; + + dataTable.Columns.Add(new DataColumn + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + }); + }); + + var customFieldEntity = new Dictionary>(); + + customFieldDao.GetEnityFields(EntityType.Opportunity, 0, false).ForEach( + item => + { + if (!customFieldEntity.ContainsKey(item.EntityID)) + customFieldEntity.Add(item.EntityID, new List { item }); + else + customFieldEntity[item.EntityID].Add(item); + }); + + var tags = tagDao.GetEntitiesTags(EntityType.Opportunity); + + foreach (var deal in deals) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var contactTags = String.Empty; + + if (tags.ContainsKey(deal.ID)) + contactTags = String.Join(",", tags[deal.ID].OrderBy(x => x)); + + String bidType; + + switch (deal.BidType) + { + case BidType.FixedBid: + bidType = CRMDealResource.BidType_FixedBid; + break; + case BidType.PerDay: + bidType = CRMDealResource.BidType_PerDay; + break; + case BidType.PerHour: + bidType = CRMDealResource.BidType_PerHour; + break; + case BidType.PerMonth: + bidType = CRMDealResource.BidType_PerMonth; + break; + case BidType.PerWeek: + bidType = CRMDealResource.BidType_PerWeek; + break; + case BidType.PerYear: + bidType = CRMDealResource.BidType_PerYear; + break; + default: + throw new ArgumentException(); + } + + var currentDealMilestone = dealMilestoneDao.GetByID(deal.DealMilestoneID); + var currentDealMilestoneStatus = currentDealMilestone.Status.ToLocalizedString(); + var contactTitle = String.Empty; + + if (deal.ContactID != 0) + contactTitle = contactDao.GetByID(deal.ContactID).GetTitle(); + + var dataRow = dataTable.Rows.Add(new object[] + { + deal.Title, + contactTitle, + deal.Description, + deal.BidCurrency, + deal.BidValue.ToString(CultureInfo.InvariantCulture), + bidType, + deal.PerPeriodValue == 0 ? "" : deal.PerPeriodValue.ToString(CultureInfo.InvariantCulture), + deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(), + deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(), + //deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern), + //deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern), + UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(DisplayUserSettingsHelper), + currentDealMilestone.Title, + currentDealMilestoneStatus, + deal.DealMilestoneProbability.ToString(CultureInfo.InvariantCulture), + contactTags + }); + + if (customFieldEntity.ContainsKey(deal.ID)) + customFieldEntity[deal.ID].ForEach(item => dataRow["customField_" + item.ID] = item.Value); + } + + return DataTableToCsv(dataTable); + } + + private String ExportCasesToCsv(IEnumerable cases, DaoFactory daoFactory) + { + var key = (string)Id; + var tagDao = daoFactory.GetTagDao(); + var customFieldDao = daoFactory.GetCustomFieldDao(); + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = CRMCasesResource.CaseTitle, + ColumnName = "title" + }, + new DataColumn(CRMCasesResource.CasesTagList) + { + Caption = CRMCasesResource.CasesTagList, + ColumnName = "tag_list" + } + }); + + customFieldDao.GetFieldsDescription(EntityType.Case).ForEach( + item => + { + if (item.FieldType == CustomFieldType.Heading) return; + + dataTable.Columns.Add(new DataColumn + { + Caption = item.Label, + ColumnName = "customField_" + item.ID + }); + }); + + var customFieldEntity = new Dictionary>(); + + customFieldDao.GetEnityFields(EntityType.Case, 0, false).ForEach( + item => + { + if (!customFieldEntity.ContainsKey(item.EntityID)) + customFieldEntity.Add(item.EntityID, new List { item }); + else + customFieldEntity[item.EntityID].Add(item); + }); + + var tags = tagDao.GetEntitiesTags(EntityType.Case); + + foreach (var item in cases) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var contactTags = String.Empty; + + if (tags.ContainsKey(item.ID)) + contactTags = String.Join(",", tags[item.ID].OrderBy(x => x)); + + var dataRow = dataTable.Rows.Add(new object[] + { + item.Title, + contactTags + }); + + if (customFieldEntity.ContainsKey(item.ID)) + customFieldEntity[item.ID].ForEach(row => dataRow["customField_" + row.ID] = row.Value); + } + + return DataTableToCsv(dataTable); + } + + private String ExportHistoryToCsv(IEnumerable events, DaoFactory daoFactory) + { + var key = (string)Id; + var listItemDao = daoFactory.GetListItemDao(); + var dealDao = daoFactory.GetDealDao(); + var casesDao = daoFactory.GetCasesDao(); + var contactDao = daoFactory.GetContactDao(); + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = (CRMContactResource.Content), + ColumnName = "content" + }, + new DataColumn + { + Caption = (CRMCommonResource.Category), + ColumnName = "category" + }, + new DataColumn + { + Caption = (CRMContactResource.ContactTitle), + ColumnName = "contact_title" + }, + new DataColumn + { + Caption = (CRMContactResource.RelativeEntity), + ColumnName = "relative_entity" + }, + new DataColumn + { + Caption = (CRMCommonResource.Author), + ColumnName = "author" + }, + new DataColumn + { + Caption = (CRMCommonResource.CreateDate), + ColumnName = "create_date" + } + }); + + foreach (var item in events) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var entityTitle = String.Empty; + + if (item.EntityID > 0) + switch (item.EntityType) + { + case EntityType.Case: + var casesObj = casesDao.GetByID(item.EntityID); + + if (casesObj != null) + entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, + casesObj.Title); + break; + case EntityType.Opportunity: + var dealObj = dealDao.GetByID(item.EntityID); + + if (dealObj != null) + entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, + dealObj.Title); + break; + } + + var contactTitle = String.Empty; + + if (item.ContactID > 0) + { + var contactObj = contactDao.GetByID(item.ContactID); + + if (contactObj != null) + contactTitle = contactObj.GetTitle(); + } + + var categoryTitle = String.Empty; + + if (item.CategoryID > 0) + { + var categoryObj = listItemDao.GetByID(item.CategoryID); + + if (categoryObj != null) + categoryTitle = categoryObj.Title; + + } + else if (item.CategoryID == (int)HistoryCategorySystem.TaskClosed) + categoryTitle = HistoryCategorySystem.TaskClosed.ToLocalizedString(); + else if (item.CategoryID == (int)HistoryCategorySystem.FilesUpload) + categoryTitle = HistoryCategorySystem.FilesUpload.ToLocalizedString(); + else if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) + categoryTitle = HistoryCategorySystem.MailMessage.ToLocalizedString(); + + dataTable.Rows.Add(new object[] + { + item.Content, + categoryTitle, + contactTitle, + entityTitle, + UserManager.GetUsers(item.CreateBy).DisplayUserName(DisplayUserSettingsHelper), + // item.CreateOn.ToShortString() + item.CreateOn + }); + } + + return DataTableToCsv(dataTable); + } + + private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) + { + var key = (string)Id; + var listItemDao = daoFactory.GetListItemDao(); + var dealDao = daoFactory.GetDealDao(); + var casesDao = daoFactory.GetCasesDao(); + var contactDao = daoFactory.GetContactDao(); + + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = (CRMTaskResource.TaskTitle), + ColumnName = "title" + }, + new DataColumn + { + Caption = (CRMTaskResource.Description), + ColumnName = "description" + }, + new DataColumn + { + Caption = (CRMTaskResource.DueDate), + ColumnName = "due_date" + }, + new DataColumn + { + Caption = (CRMTaskResource.Responsible), + ColumnName = "responsible" + }, + new DataColumn + { + Caption = (CRMContactResource.ContactTitle), + ColumnName = "contact_title" + }, + new DataColumn + { + Caption = (CRMTaskResource.TaskStatus), + ColumnName = "task_status" + }, + new DataColumn + { + Caption = (CRMTaskResource.TaskCategory), + ColumnName = "task_category" + }, + new DataColumn + { + Caption = (CRMContactResource.RelativeEntity), + ColumnName = "relative_entity" + }, + new DataColumn + { + Caption = (CRMCommonResource.Alert), + ColumnName = "alert_value" + } + }); + + foreach (var item in tasks) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var entityTitle = String.Empty; + + if (item.EntityID > 0) + switch (item.EntityType) + { + case EntityType.Case: + var caseObj = casesDao.GetByID(item.EntityID); + + if (caseObj != null) + entityTitle = String.Format("{0}: {1}", CRMCasesResource.Case, caseObj.Title); + break; + case EntityType.Opportunity: + var dealObj = dealDao.GetByID(item.EntityID); + + if (dealObj != null) + entityTitle = String.Format("{0}: {1}", CRMDealResource.Deal, dealObj.Title); + break; + } + + var contactTitle = String.Empty; + + if (item.ContactID > 0) + { + var contact = contactDao.GetByID(item.ContactID); + + if (contact != null) + contactTitle = contact.GetTitle(); + } + + dataTable.Rows.Add(new object[] + { + item.Title, + item.Description, + item.DeadLine == DateTime.MinValue + ? "" // : item.DeadLine.ToShortString(), -// UserManager.GetUsers(item.ResponsibleID).DisplayUserName(false,), -// contactTitle, -// item.IsClosed -// ? CRMTaskResource.TaskStatus_Closed -// : CRMTaskResource.TaskStatus_Open, -// listItemDao.GetByID(item.CategoryID).Title, -// entityTitle, -// item.AlertValue.ToString(CultureInfo.InvariantCulture) -// }); -// } - -// return DataTableToCsv(dataTable); -// } - -// private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, DaoFactory daoFactory) -// { -// var key = (string)Id; -// var taxes = daoFactory.GetInvoiceTaxDao().GetAll(); -// var dataTable = new DataTable(); - -// dataTable.Columns.AddRange(new[] -// { -// new DataColumn -// { -// Caption = (CRMInvoiceResource.InvoiceItemName), -// ColumnName = "title" -// }, -// new DataColumn -// { -// Caption = (CRMSettingResource.Description), -// ColumnName = "description" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.StockKeepingUnit), -// ColumnName = "sku" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.InvoiceItemPrice), -// ColumnName = "price" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.FormInvoiceItemStockQuantity), -// ColumnName = "stock_quantity" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.TrackInventory), -// ColumnName = "track_inventory" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.Currency), -// ColumnName = "currency" -// }, - -// new DataColumn -// { -// Caption = (CRMInvoiceResource.InvoiceTax1Name), -// ColumnName = "tax1_name" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.InvoiceTax1Rate), -// ColumnName = "tax1_rate" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.InvoiceTax2Name), -// ColumnName = "tax2_name" -// }, -// new DataColumn -// { -// Caption = (CRMInvoiceResource.InvoiceTax2Rate), -// ColumnName = "tax2_rate" -// } - -// }); - - -// foreach (var item in invoiceItems) -// { -// if (ExportDataCache.CheckCancelFlag(key)) -// { -// ExportDataCache.ResetAll(key); - -// throw new OperationCanceledException(); -// } - -// ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - -// Percentage += 1.0 * 100 / _totalCount; - -// var tax1 = item.InvoiceTax1ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax1ID) : null; -// var tax2 = item.InvoiceTax2ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax2ID) : null; - -// dataTable.Rows.Add(new object[] -// { -// item.Title, -// item.Description, -// item.StockKeepingUnit, -// item.Price.ToString(CultureInfo.InvariantCulture), -// item.StockQuantity.ToString(CultureInfo.InvariantCulture), -// item.TrackInventory.ToString(), -// item.Currency, -// tax1 != null ? tax1.Name : "", -// tax1 != null ? tax1.Rate.ToString(CultureInfo.InvariantCulture) : "", -// tax2 != null ? tax2.Name : "", -// tax2 != null ? tax2.Rate.ToString(CultureInfo.InvariantCulture) : "" -// }); -// } - -// return DataTableToCsv(dataTable); -// } - -// private String SaveCsvFileInMyDocument(String title, String data) -// { -// string fileUrl; - -// using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(data))) -// { -// var file = FileUploader.Exec(GlobalFolder.GetFolderMy(FileMarker, FileDaoFactory).ToString(), title, memStream.Length, memStream, true); - -// if (FileUtility.CanWebView(title) || FileUtility.CanWebEdit(title)) -// { -// fileUrl = FilesLinkUtility.GetFileWebEditorUrl(file.ID); -// fileUrl += string.Format("&options={{\"delimiter\":{0},\"codePage\":{1}}}", -// (int)FileUtility.CsvDelimiter.Comma, -// Encoding.UTF8.CodePage); -// } -// else -// { -// fileUrl = FilesLinkUtility.GetFileDownloadUrl(file.ID); -// } -// } - -// return fileUrl; -// } -// } - -// public class ExportToCsv -// { -// private readonly object Locker = new object(); - -// private readonly ProgressQueue Queue = new ProgressQueue(1, TimeSpan.FromSeconds(60), true); - -// public ExportToCsv(SecurityContext securityContext, -// ExportDataCache exportDataCache, -// TenantManager tenantManager) -// { -// SecurityContext = securityContext; -// ExportDataCache = exportDataCache; -// TenantID = tenantManager.GetCurrentTenant().TenantId; -// } - -// protected int TenantID { get; private set; } - -// public ExportDataCache ExportDataCache { get; } - -// public SecurityContext SecurityContext { get; } - -// public IProgressItem GetStatus(bool partialDataExport) -// { -// var key = GetKey(partialDataExport); - -// return Queue.GetStatus(key) ?? ExportDataCache.Get(key); -// } - -// public IProgressItem Start(FilterObject filterObject, string fileName) -// { -// lock (Locker) -// { -// var key = GetKey(filterObject != null); - -// var operation = Queue.GetStatus(key); - -// if (operation == null) -// { -// var fromCache = ExportDataCache.Get(key); - -// if (fromCache != null) -// return fromCache; -// } - -// if (operation == null) -// { -// operation = new ExportDataOperation(filterObject, fileName); - -// Queue.Add(operation); -// } - -// if (!Queue.IsStarted) -// Queue.Start(x => x.RunJob()); - -// return operation; -// } -// } - -// public void Cancel(bool partialDataExport) -// { -// lock (Locker) -// { -// var key = GetKey(partialDataExport); - -// var findedItem = Queue.GetItems().FirstOrDefault(elem => (string)elem.Id == key); - -// if (findedItem != null) -// { -// Queue.Remove(findedItem); -// } - -// ExportDataCache.SetCancelFlag(key); -// } -// } - -// public string GetKey(bool partialDataExport) -// { -// return string.Format("{0}_{1}", TenantID, -// partialDataExport ? SecurityContext.CurrentAccount.ID : Guid.Empty); -// } - -// public String ExportItems(FilterObject filterObject, string fileName) -// { -// var operation = new ExportDataOperation(filterObject, fileName); - -// operation.RunJob(); - -// return operation.FileUrl; -// } -// } -//} \ No newline at end of file + : item.DeadLine.ToString(), + UserManager.GetUsers(item.ResponsibleID).DisplayUserName(DisplayUserSettingsHelper), + contactTitle, + item.IsClosed + ? CRMTaskResource.TaskStatus_Closed + : CRMTaskResource.TaskStatus_Open, + listItemDao.GetByID(item.CategoryID).Title, + entityTitle, + item.AlertValue.ToString(CultureInfo.InvariantCulture) + }); + } + + return DataTableToCsv(dataTable); + } + + private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, DaoFactory daoFactory) + { + var key = (string)Id; + var taxes = daoFactory.GetInvoiceTaxDao().GetAll(); + var dataTable = new DataTable(); + + dataTable.Columns.AddRange(new[] + { + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceItemName), + ColumnName = "title" + }, + new DataColumn + { + Caption = (CRMSettingResource.Description), + ColumnName = "description" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.StockKeepingUnit), + ColumnName = "sku" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceItemPrice), + ColumnName = "price" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.FormInvoiceItemStockQuantity), + ColumnName = "stock_quantity" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.TrackInventory), + ColumnName = "track_inventory" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.Currency), + ColumnName = "currency" + }, + + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax1Name), + ColumnName = "tax1_name" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax1Rate), + ColumnName = "tax1_rate" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax2Name), + ColumnName = "tax2_name" + }, + new DataColumn + { + Caption = (CRMInvoiceResource.InvoiceTax2Rate), + ColumnName = "tax2_rate" + } + + }); + + + foreach (var item in invoiceItems) + { + if (ExportDataCache.CheckCancelFlag(key)) + { + ExportDataCache.ResetAll(key); + + throw new OperationCanceledException(); + } + + ExportDataCache.Insert(key, (ExportDataOperation)Clone()); + + Percentage += 1.0 * 100 / _totalCount; + + var tax1 = item.InvoiceTax1ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax1ID) : null; + var tax2 = item.InvoiceTax2ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax2ID) : null; + + dataTable.Rows.Add(new object[] + { + item.Title, + item.Description, + item.StockKeepingUnit, + item.Price.ToString(CultureInfo.InvariantCulture), + item.StockQuantity.ToString(CultureInfo.InvariantCulture), + item.TrackInventory.ToString(), + item.Currency, + tax1 != null ? tax1.Name : "", + tax1 != null ? tax1.Rate.ToString(CultureInfo.InvariantCulture) : "", + tax2 != null ? tax2.Name : "", + tax2 != null ? tax2.Rate.ToString(CultureInfo.InvariantCulture) : "" + }); + } + + return DataTableToCsv(dataTable); + } + + private String SaveCsvFileInMyDocument(String title, String data) + { + string fileUrl; + + using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(data))) + { + var file = FileUploader.Exec(GlobalFolder.GetFolderMy(FileMarker, FileDaoFactory).ToString(), title, memStream.Length, memStream, true); + + if (FileUtility.CanWebView(title) || FileUtility.CanWebEdit(title)) + { + fileUrl = FilesLinkUtility.GetFileWebEditorUrl(file.ID); + fileUrl += string.Format("&options={{\"delimiter\":{0},\"codePage\":{1}}}", + (int)FileUtility.CsvDelimiter.Comma, + Encoding.UTF8.CodePage); + } + else + { + fileUrl = FilesLinkUtility.GetFileDownloadUrl(file.ID); + } + } + + return fileUrl; + } + } + + public class ExportToCsv + { + private readonly object Locker = new object(); + + private readonly ProgressQueue Queue; + + public ExportToCsv(SecurityContext securityContext, + ExportDataCache exportDataCache, + TenantManager tenantManager, + ProgressQueueOptionsManager progressQueueOptionsManager, + ExportDataOperation exportDataOperation) + { + SecurityContext = securityContext; + ExportDataCache = exportDataCache; + TenantID = tenantManager.GetCurrentTenant().TenantId; + Queue = progressQueueOptionsManager.Value; + ExportDataOperation = exportDataOperation; + } + + protected int TenantID { get; private set; } + + public ExportDataOperation ExportDataOperation { get; } + public ExportDataCache ExportDataCache { get; } + + public SecurityContext SecurityContext { get; } + + public IProgressItem GetStatus(bool partialDataExport) + { + var key = GetKey(partialDataExport); + + return Queue.GetStatus(key) ?? ExportDataCache.Get(key); + } + + public IProgressItem Start(FilterObject filterObject, string fileName) + { + lock (Locker) + { + var key = GetKey(filterObject != null); + + var operation = Queue.GetStatus(key); + + if (operation == null) + { + var fromCache = ExportDataCache.Get(key); + + if (fromCache != null) + return fromCache; + } + + if (operation == null) + { + + ExportDataOperation.Configure(key,filterObject, fileName); + + Queue.Add(ExportDataOperation); + } + + if (!Queue.IsStarted) + Queue.Start(x => x.RunJob()); + + return operation; + } + } + + public void Cancel(bool partialDataExport) + { + lock (Locker) + { + var key = GetKey(partialDataExport); + + var findedItem = Queue.GetItems().FirstOrDefault(elem => (string)elem.Id == key); + + if (findedItem != null) + { + Queue.Remove(findedItem); + } + + ExportDataCache.SetCancelFlag(key); + } + } + + public string GetKey(bool partialDataExport) + { + return string.Format("{0}_{1}", TenantID, + partialDataExport ? SecurityContext.CurrentAccount.ID : Guid.Empty); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index e969f2a249e..1a7491ccf41 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -113,13 +113,28 @@ public void ResetAll(EntityType entityType, int tenantId = -1) } } + [Transient] public partial class ImportDataOperation : IProgressItem { - public ImportDataOperation(EntityType entityType, - string CSVFileURI, - string importSettingsJSON, - SecurityContext securityContext, - Global global, + private readonly ILog _log; + + private readonly IDataStore _dataStore; + + private readonly IAccount _author; + + private readonly int _tenantID; + + private string _CSVFileURI; + + private ImportCSVSettings _importSettings; + + private EntityType _entityType; + + private string[] _columns; + + private bool _IsConfigure; + + public ImportDataOperation(Global global, TenantManager tenantManager, IOptionsMonitor logger, UserManager userManager, @@ -128,17 +143,14 @@ public ImportDataOperation(EntityType entityType, NotifyClient notifyClient, SettingsManager settingsManager, CurrencyProvider currencyProvider, - DaoFactory daoFactory - ) + DaoFactory daoFactory, + SecurityContext securityContext + ) { ImportDataCache = importDataCache; - _entityType = entityType; - _CSVFileURI = CSVFileURI; UserManager = userManager; - if (!String.IsNullOrEmpty(importSettingsJSON)) - _importSettings = new ImportCSVSettings(importSettingsJSON); SecurityContext = securityContext; _dataStore = global.GetStore(); @@ -158,6 +170,20 @@ DaoFactory daoFactory DaoFactory = daoFactory; } + public void Configure(EntityType entityType, + string CSVFileURI, + string importSettingsJSON) + { + + _entityType = entityType; + _CSVFileURI = CSVFileURI; + + if (!String.IsNullOrEmpty(importSettingsJSON)) + _importSettings = new ImportCSVSettings(importSettingsJSON); + + _IsConfigure = true; + } + public CurrencyProvider CurrencyProvider { get; } public NotifyClient NotifyClient { get; } @@ -178,21 +204,6 @@ DaoFactory daoFactory public ILog LogManager { get; } - private readonly ILog _log; - - private readonly IDataStore _dataStore; - - private readonly IAccount _author; - - private readonly int _tenantID; - - private readonly string _CSVFileURI; - - private readonly ImportCSVSettings _importSettings; - - private readonly EntityType _entityType; - - private string[] _columns; public override bool Equals(object obj) { @@ -255,6 +266,9 @@ public void RunJob() { try { + if (!_IsConfigure) + throw new Exception("Is not configure. Please, call configure method."); + TenantManager.SetCurrentTenant(_tenantID); SecurityContext.AuthenticateMe(_author); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index af046500e25..4ed06d5d07d 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -40,21 +40,26 @@ namespace ASC.Web.CRM.Classes public class ImportFromCSV { public ImportFromCSV(TenantManager tenantProvider, - ImportDataCache importDataCache) + ImportDataCache importDataCache, + ProgressQueueOptionsManager progressQueueOptionsManager, + ImportDataOperation importDataOperation) { TenantId = tenantProvider.GetCurrentTenant().TenantId; ImportDataCache = importDataCache; + _importQueue = progressQueueOptionsManager.Value; + ImportDataOperation = importDataOperation; } + public ImportDataOperation ImportDataOperation { get; } + public ImportDataCache ImportDataCache { get; } public int TenantId { get; } private readonly object _syncObj = new object(); - private readonly ProgressQueue _importQueue = new ProgressQueue(); - // 3, TimeSpan.FromSeconds(15), true); - + private readonly ProgressQueue _importQueue; + public readonly int MaxRoxCount = 10000; public int GetQuotas() @@ -137,9 +142,9 @@ public IProgressItem Start(EntityType entityType, String CSVFileURI, String impo if (fromCache != null) return fromCache; - // operation = new ImportDataOperation(entityType, CSVFileURI, importSettingsJSON); + ImportDataOperation.Configure(entityType, CSVFileURI, importSettingsJSON); - // _importQueue.Add(operation); + _importQueue.Add(ImportDataOperation); } if (!_importQueue.IsStarted) diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index 0709c8f7f96..d9dc0344683 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -1,387 +1,408 @@ -///* -// * -// * (c) Copyright Ascensio System Limited 2010-2018 -// * -// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU -// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). -// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that -// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. -// * -// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR -// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html -// * -// * You can contact Ascensio System SIA by email at sales@onlyoffice.com -// * -// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display -// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. -// * -// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains -// * relevant author attributions when distributing the software. If the display of the logo in its graphic -// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" -// * in every copy of the program you distribute. -// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. -// * -//*/ - - -//#region Import - -//using ASC.Common.Caching; -//using ASC.Common.Logging; -//using ASC.Common.Threading.Progress; -//using ASC.Core; -//using ASC.Core.Common.Settings; -//using ASC.Core.Tenants; -//using ASC.CRM.Classes; -//using ASC.CRM.Core; -//using ASC.CRM.Core.Dao; -//using ASC.CRM.Core.Entities; -//using ASC.CRM.Core.Enums; -//using ASC.CRM.Resources; -//using ASC.Web.CRM.Core; -//using ASC.Web.Files.Api; -//using Autofac; -//using MailKit; -//using MailKit.Net.Smtp; -//using MailKit.Security; -//using Microsoft.Extensions.Configuration; -//using Microsoft.Extensions.Options; -//using MimeKit; -//using Newtonsoft.Json.Linq; -//using System; -//using System.Collections.Generic; -//using System.IO; -//using System.Linq; -//using System.Net.Sockets; -//using System.Runtime.Serialization; -//using System.Text; -//using System.Text.RegularExpressions; -//using System.Threading; -//using File = System.IO.File; -//using SmtpClient = MailKit.Net.Smtp.SmtpClient; - -//#endregion - -//namespace ASC.Web.CRM.Classes -//{ -// public class SendBatchEmailsOperation : IProgressItem, IDisposable -// { -// private readonly bool _storeInHistory; -// private readonly ILog _log; -// private readonly SMTPServerSetting _smtpSetting; -// private readonly Guid _currUser; -// private readonly int _tenantID; -// private readonly List _contactID; -// private readonly String _subject; -// private readonly String _bodyTempate; -// private readonly List _fileID; -// private int historyCategory; -// private double _exactPercentageValue = 0; - -// public object Id { get; set; } -// public object Status { get; set; } -// public object Error { get; set; } -// public double Percentage { get; set; } -// public bool IsCompleted { get; set; } - -// private SendBatchEmailsOperation() -// { -// } - -// public SendBatchEmailsOperation( -// List fileID, -// List contactID, -// String subject, -// String bodyTempate, -// bool storeInHistory, -// TenantUtil tenantUtil, -// IOptionsMonitor logger, -// Global global, -// SecurityContext securityContext, -// TenantManager tenantManager, -// UserManager userManager, -// AuthManager authManager, -// SettingsManager settingsManager, -// MailSenderDataCache mailSenderDataCache -// ) -// { -// TenantUtil = tenantUtil; -// SecurityContext = securityContext; - -// Percentage = 0; - -// _fileID = fileID; -// _contactID = contactID; -// _subject = subject; -// _bodyTempate = bodyTempate; - -// _log = logger.Get("ASC.CRM.MailSender"); - -// _tenantID = tenantManager.GetCurrentTenant().TenantId; -// _smtpSetting = settingsManager.Load().SMTPServerSetting; -// _currUser = SecurityContext.CurrentAccount.ID; -// _storeInHistory = storeInHistory; - -// Status = new -// { -// RecipientCount = _contactID.Count, -// EstimatedTime = 0, -// DeliveryCount = 0 -// }; - -// AuthManager = authManager; -// UserManager = userManager; -// MailSenderDataCache = mailSenderDataCache; -// } - -// public FilesIntegration FilesIntegration { get; } - -// public MailSenderDataCache MailSenderDataCache { get; } -// public AuthManager AuthManager { get; } - -// public UserManager UserManager { get; } - -// public TenantManager TenantManager { get; } - -// public SecurityContext SecurityContext { get; } - -// public TenantUtil TenantUtil { get; } - -// private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) -// { -// if (contactID == 0 || String.IsNullOrEmpty(content)) return; - -// var historyEvent = new RelationshipEvent() -// { -// ContactID = contactID, -// Content = content, -// CreateBy = _currUser, -// CreateOn = TenantUtil.DateTimeNow(), -// }; -// if (historyCategory == 0) -// { -// var listItemDao = _daoFactory.GetListItemDao(); - -// // HACK -// var listItem = listItemDao.GetItems(ListType.HistoryCategory).Find(item => item.AdditionalParams == "event_category_email.png"); -// if (listItem == null) -// { -// listItemDao.CreateItem( -// ListType.HistoryCategory, -// new ListItem { AdditionalParams = "event_category_email.png", Title = CRMCommonResource.HistoryCategory_Note }); -// } -// historyCategory = listItem.ID; -// } - -// historyEvent.CategoryID = historyCategory; - -// var relationshipEventDao = _daoFactory.GetRelationshipEventDao(); - -// historyEvent = relationshipEventDao.CreateItem(historyEvent); - -// if (historyEvent.ID > 0 && _fileID != null && _fileID.Count > 0) -// { -// relationshipEventDao.AttachFiles(historyEvent.ID, _fileID.ToArray()); -// } -// } - -// public void RunJob() -// { -// SmtpClient smtpClient = null; -// try -// { -// TenantManager.SetCurrentTenant(_tenantID); -// SecurityContext.AuthenticateMe(AuthManager.GetAccountByID(_tenantID, _currUser)); - -// smtpClient = GetSmtpClient(); - -// var userCulture = UserManager.GetUsers(_currUser).GetCulture(); - -// Thread.CurrentThread.CurrentCulture = userCulture; -// Thread.CurrentThread.CurrentUICulture = userCulture; +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Common.Threading.Progress; +using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.Core.Tenants; +using ASC.CRM.Classes; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.CRM.Core; +using ASC.Web.Files.Api; + +using Autofac; + +using MailKit; +using MailKit.Net.Smtp; +using MailKit.Security; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +using MimeKit; + +using Newtonsoft.Json.Linq; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; + +using File = System.IO.File; +using SmtpClient = MailKit.Net.Smtp.SmtpClient; + +#endregion + +namespace ASC.Web.CRM.Classes +{ + [Transient] + public class SendBatchEmailsOperation : IProgressItem, IDisposable + { + private bool _storeInHistory; + private readonly ILog _log; + private readonly SMTPServerSetting _smtpSetting; + private readonly Guid _currUser; + private readonly int _tenantID; + private List _contactID; + private String _subject; + private String _bodyTempate; + private List _fileID; + private int historyCategory; + private double _exactPercentageValue = 0; + + public object Id { get; set; } + public object Status { get; set; } + public object Error { get; set; } + public double Percentage { get; set; } + public bool IsCompleted { get; set; } + + private SendBatchEmailsOperation() + { + } + + public SendBatchEmailsOperation( + TenantUtil tenantUtil, + IOptionsMonitor logger, + Global global, + SecurityContext securityContext, + TenantManager tenantManager, + UserManager userManager, + AuthManager authManager, + SettingsManager settingsManager, + MailSenderDataCache mailSenderDataCache, + DaoFactory daoFactory + ) + { + TenantUtil = tenantUtil; + SecurityContext = securityContext; + + Percentage = 0; + + _log = logger.Get("ASC.CRM.MailSender"); + + _tenantID = tenantManager.GetCurrentTenant().TenantId; + _smtpSetting = settingsManager.Load().SMTPServerSetting; + _currUser = SecurityContext.CurrentAccount.ID; + + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = 0, + DeliveryCount = 0 + }; + + AuthManager = authManager; + UserManager = userManager; + MailSenderDataCache = mailSenderDataCache; + DaoFactory = daoFactory; + } + + public DaoFactory DaoFactory { get; } + public FilesIntegration FilesIntegration { get; } + public MailSenderDataCache MailSenderDataCache { get; } + public AuthManager AuthManager { get; } + public UserManager UserManager { get; } + public TenantManager TenantManager { get; } + public SecurityContext SecurityContext { get; } + public TenantUtil TenantUtil { get; } + + public void Configure(List fileID, + List contactID, + String subject, + String bodyTempate, + bool storeInHistory) + { + _fileID = fileID ?? new List(); + _contactID = contactID ?? new List(); + _subject = subject; + _bodyTempate = bodyTempate; + _storeInHistory = storeInHistory; + } + + private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) + { + if (contactID == 0 || String.IsNullOrEmpty(content)) return; + + var historyEvent = new RelationshipEvent() + { + ContactID = contactID, + Content = content, + CreateBy = _currUser, + CreateOn = TenantUtil.DateTimeNow(), + }; + if (historyCategory == 0) + { + var listItemDao = _daoFactory.GetListItemDao(); + + // HACK + var listItem = listItemDao.GetItems(ListType.HistoryCategory).Find(item => item.AdditionalParams == "event_category_email.png"); + if (listItem == null) + { + listItemDao.CreateItem( + ListType.HistoryCategory, + new ListItem { AdditionalParams = "event_category_email.png", Title = CRMCommonResource.HistoryCategory_Note }); + } + historyCategory = listItem.ID; + } + + historyEvent.CategoryID = historyCategory; + + var relationshipEventDao = _daoFactory.GetRelationshipEventDao(); + + historyEvent = relationshipEventDao.CreateItem(historyEvent); + + if (historyEvent.ID > 0 && _fileID != null && _fileID.Count > 0) + { + relationshipEventDao.AttachFiles(historyEvent.ID, _fileID.ToArray()); + } + } + + public void RunJob() + { + SmtpClient smtpClient = null; + try + { + TenantManager.SetCurrentTenant(_tenantID); + SecurityContext.AuthenticateMe(AuthManager.GetAccountByID(_tenantID, _currUser)); + + smtpClient = GetSmtpClient(); + + var userCulture = UserManager.GetUsers(_currUser).GetCulture(); + + Thread.CurrentThread.CurrentCulture = userCulture; + Thread.CurrentThread.CurrentUICulture = userCulture; + + var contactCount = _contactID.Count; + + if (contactCount == 0) + { + Complete(); + return; + } + + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); + + var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); + var filePaths = new List(); + var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + + foreach (var fileID in _fileID) + { + var fileObj = fileDao.GetFile(fileID); + if (fileObj == null) continue; + using (var fileStream = fileDao.GetFileStream(fileObj)) + { + var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), + "crm/files/mailsender/"); + + if (!Directory.Exists(directoryPath)) + { + Directory.CreateDirectory(directoryPath); + } + + var filePath = Path.Combine(directoryPath, fileObj.Title); + + using (var newFileStream = File.Create(filePath)) + { + fileStream.CopyTo(newFileStream); + } + + filePaths.Add(filePath); + + } + } + + var templateManager = new MailTemplateManager(DaoFactory); + var deliveryCount = 0; + + try + { + Error = string.Empty; + foreach (var contactID in _contactID) + { + _exactPercentageValue += 100.0 / contactCount; + Percentage = Math.Round(_exactPercentageValue); -// var contactCount = _contactID.Count; + if (IsCompleted) break; // User selected cancel -// if (contactCount == 0) -// { -// Complete(); -// return; -// } + var contactInfoDao = DaoFactory.GetContactInfoDao(); -// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); + var startDate = DateTime.Now; -// var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); -// var filePaths = new List(); -// var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + var contactEmails = contactInfoDao.GetList(contactID, ContactInfoType.Email, null, true); + if (contactEmails.Count == 0) + { + continue; + } -// foreach (var fileID in _fileID) -// { -// var fileObj = fileDao.GetFile(fileID); -// if (fileObj == null) continue; -// using (var fileStream = fileDao.GetFileStream(fileObj)) -// { -// var directoryPath = Path.Combine(Path.GetTempPath(), "teamlab", _tenantID.ToString(), -// "crm/files/mailsender/"); + var recipientEmail = contactEmails[0].Data; -// if (!Directory.Exists(directoryPath)) -// { -// Directory.CreateDirectory(directoryPath); -// } + if (!recipientEmail.TestEmailRegex()) + { + Error += string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail) + + "
    "; + continue; + } -// var filePath = Path.Combine(directoryPath, fileObj.Title); + var to = new MailboxAddress(recipientEmail); -// using (var newFileStream = File.Create(filePath)) -// { -// fileStream.StreamCopyTo(newFileStream); -// } + var mimeMessage = new MimeMessage + { + Subject = _subject + }; + + mimeMessage.From.Add(from); + mimeMessage.To.Add(to); + + var bodyBuilder = new BodyBuilder + { + HtmlBody = templateManager.Apply(_bodyTempate, contactID) + }; -// filePaths.Add(filePath); + foreach (var filePath in filePaths) + { + bodyBuilder.Attachments.Add(filePath); + } -// } -// } + mimeMessage.Body = bodyBuilder.ToMessageBody(); -// var templateManager = new MailTemplateManager(DaoFactory); -// var deliveryCount = 0; + mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); -// try -// { -// Error = string.Empty; -// foreach (var contactID in _contactID) -// { -// _exactPercentageValue += 100.0 / contactCount; -// Percentage = Math.Round(_exactPercentageValue); + _log.Debug(GetLoggerRow(mimeMessage)); -// if (IsCompleted) break; // User selected cancel + var success = false; -// var contactInfoDao = DaoFactory.GetContactInfoDao(); + try + { + smtpClient.Send(mimeMessage); -// var startDate = DateTime.Now; + success = true; + } + catch (SmtpCommandException ex) + { + _log.Error(Error, ex); -// var contactEmails = contactInfoDao.GetList(contactID, ContactInfoType.Email, null, true); -// if (contactEmails.Count == 0) -// { -// continue; -// } + Error += string.Format(CRMCommonResource.MailSender_FailedDeliverException, recipientEmail) + "
    "; + } -// var recipientEmail = contactEmails[0].Data; + if (success) + { + if (_storeInHistory) + { + AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), DaoFactory); + } -// if (!recipientEmail.TestEmailRegex()) -// { -// Error += string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail) + -// "
    "; -// continue; -// } + var endDate = DateTime.Now; + var waitInterval = endDate.Subtract(startDate); -// var to = new MailboxAddress(recipientEmail); + deliveryCount++; -// var mimeMessage = new MimeMessage -// { -// Subject = _subject -// }; - -// mimeMessage.From.Add(from); -// mimeMessage.To.Add(to); - -// var bodyBuilder = new BodyBuilder -// { -// HtmlBody = templateManager.Apply(_bodyTempate, contactID) -// }; + var estimatedTime = + TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); -// foreach (var filePath in filePaths) -// { -// bodyBuilder.Attachments.Add(filePath); -// } + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = estimatedTime.ToString(), + DeliveryCount = deliveryCount + }; + } -// mimeMessage.Body = bodyBuilder.ToMessageBody(); + if (MailSenderDataCache.CheckCancelFlag()) + { + MailSenderDataCache.ResetAll(); -// mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); + throw new OperationCanceledException(); + } -// _log.Debug(GetLoggerRow(mimeMessage)); + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); -// var success = false; + if (Percentage > 100) + { + Percentage = 100; -// try -// { -// smtpClient.Send(mimeMessage); + if (MailSenderDataCache.CheckCancelFlag()) + { + MailSenderDataCache.ResetAll(); -// success = true; -// } -// catch (SmtpCommandException ex) -// { -// _log.Error(Error, ex); + throw new OperationCanceledException(); + } -// Error += string.Format(CRMCommonResource.MailSender_FailedDeliverException, recipientEmail) + "
    "; -// } + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); -// if (success) -// { -// if (_storeInHistory) -// { -// AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), DaoFactory); -// } + } + } + } + catch (OperationCanceledException) + { + _log.Debug("cancel mail sender"); + } + finally + { + foreach (var filePath in filePaths) + { + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + } + } -// var endDate = DateTime.Now; -// var waitInterval = endDate.Subtract(startDate); + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = TimeSpan.Zero.ToString(), + DeliveryCount = deliveryCount + }; -// deliveryCount++; -// var estimatedTime = -// TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); -// Status = new -// { -// RecipientCount = _contactID.Count, -// EstimatedTime = estimatedTime.ToString(), -// DeliveryCount = deliveryCount -// }; -// } -// if (MailSenderDataCache.CheckCancelFlag()) -// { -// MailSenderDataCache.ResetAll(); -// throw new OperationCanceledException(); -// } -// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); -// if (Percentage > 100) -// { -// Percentage = 100; -// if (MailSenderDataCache.CheckCancelFlag()) -// { -// MailSenderDataCache.ResetAll(); -// throw new OperationCanceledException(); -// } -// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); -// } -// } -// } -// catch (OperationCanceledException) -// { -// _log.Debug("cancel mail sender"); -// } -// finally -// { -// foreach (var filePath in filePaths) -// { -// if (File.Exists(filePath)) -// { -// File.Delete(filePath); -// } -// } -// } -// Status = new -// { -// RecipientCount = _contactID.Count, -// EstimatedTime = TimeSpan.Zero.ToString(), -// DeliveryCount = deliveryCount -// }; @@ -406,680 +427,676 @@ + } + catch (SocketException e) + { + Error = e.Message; + _log.Error(Error); + } + finally + { + if (smtpClient != null) + { + smtpClient.Dispose(); + } + Complete(); + } + } + public string GetLoggerRow(MimeMessage mailMessage) + { + if (mailMessage == null) + return String.Empty; + var result = new StringBuilder(); + result.AppendLine("From:" + mailMessage.From); + result.AppendLine("To:" + mailMessage.To[0]); + result.AppendLine("Subject:" + mailMessage.Subject); + result.AppendLine("Body:" + mailMessage.Body); + result.AppendLine("TenantID:" + _tenantID); + foreach (var attachment in mailMessage.Attachments) + { + result.AppendLine("Attachment: " + attachment.ContentDisposition.FileName); + } + return result.ToString(); + } + public object Clone() + { + var cloneObj = new SendBatchEmailsOperation(); + cloneObj.Error = Error; + cloneObj.Id = Id; + cloneObj.IsCompleted = IsCompleted; + cloneObj.Percentage = Percentage; + cloneObj.Status = Status; + return cloneObj; + } + private void DeleteFiles() + { + if (_fileID == null || _fileID.Count == 0) return; + var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + foreach (var fileID in _fileID) + { + var fileObj = fileDao.GetFile(fileID); + if (fileObj == null) continue; -// } -// catch (SocketException e) -// { -// Error = e.Message; -// _log.Error(Error); -// } -// finally -// { -// if (smtpClient != null) -// { -// smtpClient.Dispose(); -// } -// Complete(); -// } -// } + fileDao.DeleteFile(fileObj.ID); + } -// public string GetLoggerRow(MimeMessage mailMessage) -// { -// if (mailMessage == null) -// return String.Empty; + } -// var result = new StringBuilder(); + private SmtpClient GetSmtpClient() + { + var client = new SmtpClient + { + ServerCertificateValidationCallback = (sender, certificate, chain, errors) => + WorkContext.IsMono || MailKit.MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), + Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds + }; -// result.AppendLine("From:" + mailMessage.From); -// result.AppendLine("To:" + mailMessage.To[0]); -// result.AppendLine("Subject:" + mailMessage.Subject); -// result.AppendLine("Body:" + mailMessage.Body); -// result.AppendLine("TenantID:" + _tenantID); + client.Connect(_smtpSetting.Host, _smtpSetting.Port, + _smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); -// foreach (var attachment in mailMessage.Attachments) -// { -// result.AppendLine("Attachment: " + attachment.ContentDisposition.FileName); -// } + if (_smtpSetting.RequiredHostAuthentication) + { + client.Authenticate(_smtpSetting.HostLogin, _smtpSetting.HostPassword); + } -// return result.ToString(); -// } + return client; + } -// public object Clone() -// { -// var cloneObj = new SendBatchEmailsOperation(); + private void Complete() + { + IsCompleted = true; + Percentage = 100; + _log.Debug("Completed"); + + MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); + + Thread.Sleep(10000); + MailSenderDataCache.ResetAll(); + } + + public override bool Equals(object obj) + { + if (obj == null || !(obj is SendBatchEmailsOperation)) return false; + + var curOperation = (SendBatchEmailsOperation)obj; + return (curOperation.Id == Id) && (curOperation._tenantID == _tenantID); + } + + public override int GetHashCode() + { + return Id.GetHashCode() ^ _tenantID.GetHashCode(); + } + + public void Dispose() + { + DeleteFiles(); + } + } + + public class MailSenderDataCache + { + public MailSenderDataCache(TenantManager tenantManager, + ICache cache ) + { + TenantID = tenantManager.GetCurrentTenant().TenantId; + Cache = cache; + } + + public int TenantID { get; } + + public readonly ICache Cache; + + public string GetStateCacheKey() + { + return string.Format("{0}:crm:queue:sendbatchemails", TenantID); + } + + public string GetCancelCacheKey() + { + return string.Format("{0}:crm:queue:sendbatchemails:cancel", TenantID); + } + + public SendBatchEmailsOperation Get() + { + return Cache.Get(GetStateCacheKey()); + } + + public void Insert(SendBatchEmailsOperation data) + { + Cache.Insert(GetStateCacheKey(), data, TimeSpan.FromMinutes(1)); + } + + public bool CheckCancelFlag() + { + var fromCache = Cache.Get(GetCancelCacheKey()); + + if (!String.IsNullOrEmpty(fromCache)) + return true; + + return false; + + } + + public void SetCancelFlag() + { + Cache.Insert(GetCancelCacheKey(), "true", TimeSpan.FromMinutes(1)); + } + + public void ResetAll() + { + Cache.Remove(GetStateCacheKey()); + Cache.Remove(GetCancelCacheKey()); + } + } + + [Scope] + public class MailSender + { + private readonly Object _syncObj = new Object(); + private readonly ProgressQueue _mailQueue; + private readonly int quotas = 50; + + public MailSender( + IConfiguration configuration, + TenantManager tenantManager, + SettingsManager settingsManager, + MailSenderDataCache mailSenderDataCache, + ProgressQueueOptionsManager progressQueueOptionsManager, + SendBatchEmailsOperation sendBatchEmailsOperation + ) + { + SendBatchEmailsOperation = sendBatchEmailsOperation; + TenantID = tenantManager.GetCurrentTenant().TenantId; + MailSenderDataCache = mailSenderDataCache; + _mailQueue = progressQueueOptionsManager.Value; + + int parsed; + + if (int.TryParse(configuration["crm:mailsender:quotas"], out parsed)) + { + quotas = parsed; + } + + TenantManager = tenantManager; + SettingsManager = settingsManager; + + // LogManager = logger.Get(); + } + + public TenantManager TenantManager { get; } + public SettingsManager SettingsManager { get; } + public SendBatchEmailsOperation SendBatchEmailsOperation { get; } + public MailSenderDataCache MailSenderDataCache { get; } + public int TenantID { get; } + + public IOptionsMonitor LogManager { get; } + + public int GetQuotas() + { + return quotas; + } + + public IProgressItem Start(List fileID, List contactID, String subject, String bodyTemplate, bool storeInHistory) + { + lock (_syncObj) + { + var operation = _mailQueue.GetStatus(TenantID); + + if (operation == null) + { + var mailSender = MailSenderDataCache.Get(); + + if (mailSender != null) + return mailSender; + } + + if (operation == null) + { + if (fileID == null) + { + fileID = new List(); + } + if (contactID == null || contactID.Count == 0 || + String.IsNullOrEmpty(subject) || String.IsNullOrEmpty(bodyTemplate)) + { + return null; + } + + if (contactID.Count > GetQuotas()) + { + contactID = contactID.Take(GetQuotas()).ToList(); + } + + SendBatchEmailsOperation.Configure(fileID, contactID, subject, bodyTemplate, storeInHistory); + + _mailQueue.Add(operation); + } + + if (!_mailQueue.IsStarted) + { + _mailQueue.Start(x => x.RunJob()); + } + return operation; + } + } + + private SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) + { + var client = new SmtpClient + { + ServerCertificateValidationCallback = (sender, certificate, chain, errors) => MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), + Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds + }; + + client.Connect(smtpSetting.Host, smtpSetting.Port, + smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); + + if (smtpSetting.RequiredHostAuthentication) + { + client.Authenticate(smtpSetting.HostLogin, smtpSetting.HostPassword); + } + + return client; + } + + public void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) + { + var log = LogManager.Get("ASC.CRM.MailSender"); + + if (!recipientEmail.TestEmailRegex()) + { + throw new Exception(string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail)); + } + + TenantManager.SetCurrentTenant(TenantID); + var smtpSetting = SettingsManager.Load().SMTPServerSetting; + + ThreadPool.QueueUserWorkItem(_ => + { + try + { + var toAddress = new MailboxAddress(recipientEmail); + var fromAddress = new MailboxAddress(smtpSetting.SenderDisplayName, smtpSetting.SenderEmailAddress); + + var mimeMessage = new MimeMessage + { + Subject = mailSubj + }; + + mimeMessage.From.Add(fromAddress); + + mimeMessage.To.Add(toAddress); + + var bodyBuilder = new BodyBuilder + { + TextBody = mailBody + }; + + mimeMessage.Body = bodyBuilder.ToMessageBody(); + + mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); + + using (var smtpClient = GetSmtpClient(smtpSetting)) + { + smtpClient.Send(FormatOptions.Default, mimeMessage, CancellationToken.None); + } + } + catch (Exception ex) + { + log.Error(ex); + } + }); + } + + public IProgressItem GetStatus() + { + var result = _mailQueue.GetStatus(TenantID); -// cloneObj.Error = Error; -// cloneObj.Id = Id; -// cloneObj.IsCompleted = IsCompleted; -// cloneObj.Percentage = Percentage; -// cloneObj.Status = Status; + if (result == null) + return MailSenderDataCache.Get(); -// return cloneObj; -// } + return result; + } -// private void DeleteFiles() -// { -// if (_fileID == null || _fileID.Count == 0) return; + public void Cancel() + { + lock (_syncObj) + { + var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantID); -// var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + if (findedItem.Any()) + { + _mailQueue.Remove(findedItem.ElementAt(0)); -// foreach (var fileID in _fileID) -// { -// var fileObj = fileDao.GetFile(fileID); -// if (fileObj == null) continue; + MailSenderDataCache.ResetAll(); + } + else + { + MailSenderDataCache.SetCancelFlag(); + } + } + } + } -// fileDao.DeleteFile(fileObj.ID); -// } + [Serializable] + [DataContract] + public class MailTemplateTag + { + [DataMember(Name = "sysname")] + public String SysName { get; set; } -// } + [DataMember(Name = "display_name")] + public String DisplayName { get; set; } -// private SmtpClient GetSmtpClient() -// { -// var client = new SmtpClient -// { -// ServerCertificateValidationCallback = (sender, certificate, chain, errors) => -// WorkContext.IsMono || MailKit.MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), -// Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds -// }; + [DataMember(Name = "category")] + public String Category { get; set; } -// client.Connect(_smtpSetting.Host, _smtpSetting.Port, -// _smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); + [DataMember(Name = "is_company")] + public bool isCompany { get; set; } -// if (_smtpSetting.RequiredHostAuthentication) -// { -// client.Authenticate(_smtpSetting.HostLogin, _smtpSetting.HostPassword); -// } + [DataMember(Name = "name")] + public String Name { get; set; } + } -// return client; -// } + public class MailTemplateManager + { + private readonly Dictionary> _templateTagsCache = new Dictionary>(); -// private void Complete() -// { -// IsCompleted = true; -// Percentage = 100; -// _log.Debug("Completed"); + private readonly DaoFactory _daoFactory; -// MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - -// Thread.Sleep(10000); -// MailSenderDataCache.ResetAll(); -// } - -// public override bool Equals(object obj) -// { -// if (obj == null || !(obj is SendBatchEmailsOperation)) return false; - -// var curOperation = (SendBatchEmailsOperation)obj; -// return (curOperation.Id == Id) && (curOperation._tenantID == _tenantID); -// } - -// public override int GetHashCode() -// { -// return Id.GetHashCode() ^ _tenantID.GetHashCode(); -// } - -// public void Dispose() -// { -// DeleteFiles(); -// } -// } - -// public class MailSenderDataCache -// { -// public MailSenderDataCache(TenantManager tenantManager) -// { -// TenantID = tenantManager.GetCurrentTenant().TenantId; -// } - -// public int TenantID { get; } - -// public readonly ICache Cache = ICache.Memory; - -// public string GetStateCacheKey() -// { -// return string.Format("{0}:crm:queue:sendbatchemails", TenantID); -// } - -// public string GetCancelCacheKey() -// { -// return string.Format("{0}:crm:queue:sendbatchemails:cancel", TenantID); -// } - -// public SendBatchEmailsOperation Get() -// { -// return Cache.Get(GetStateCacheKey()); -// } - -// public void Insert(SendBatchEmailsOperation data) -// { -// Cache.Insert(GetStateCacheKey(), data, TimeSpan.FromMinutes(1)); -// } - -// public bool CheckCancelFlag() -// { -// var fromCache = Cache.Get(GetCancelCacheKey()); - -// if (!String.IsNullOrEmpty(fromCache)) -// return true; - -// return false; - -// } - -// public void SetCancelFlag() -// { -// Cache.Insert(GetCancelCacheKey(), "true", TimeSpan.FromMinutes(1)); -// } - -// public void ResetAll() -// { -// Cache.Remove(GetStateCacheKey()); -// Cache.Remove(GetCancelCacheKey()); -// } -// } - -// public class MailSender -// { -// private readonly Object _syncObj = new Object(); -// private readonly ProgressQueue _mailQueue = new ProgressQueue(2, TimeSpan.FromSeconds(60), true); -// private readonly int quotas = 50; - -// public MailSender( -// IConfiguration configuration, -// TenantManager tenantManager, -// SettingsManager settingsManager, -// MailSenderDataCache mailSenderDataCache -// ) -// { -// TenantID = tenantManager.GetCurrentTenant().TenantId; -// MailSenderDataCache = mailSenderDataCache; - -// int parsed; - -// if (int.TryParse(configuration["crm:mailsender:quotas"], out parsed)) -// { -// quotas = parsed; -// } - -// TenantManager = tenantManager; -// SettingsManager = settingsManager; - -// // LogManager = logger.Get(); -// } - -// public TenantManager TenantManager { get; } -// public SettingsManager SettingsManager { get; } - -// public MailSenderDataCache MailSenderDataCache { get; } -// public int TenantID { get; } - -// public IOptionsMonitor LogManager { get; } - -// public int GetQuotas() -// { -// return quotas; -// } - -// public IProgressItem Start(List fileID, List contactID, String subject, String bodyTemplate, bool storeInHistory) -// { -// lock (_syncObj) -// { -// var operation = _mailQueue.GetStatus(TenantID); - -// if (operation == null) -// { -// var mailSender = MailSenderDataCache.Get(); - -// if (mailSender != null) -// return mailSender; -// } - -// if (operation == null) -// { -// if (fileID == null) -// { -// fileID = new List(); -// } -// if (contactID == null || contactID.Count == 0 || -// String.IsNullOrEmpty(subject) || String.IsNullOrEmpty(bodyTemplate)) -// { -// return null; -// } - -// if (contactID.Count > GetQuotas()) -// { -// contactID = contactID.Take(GetQuotas()).ToList(); -// } - -// operation = new SendBatchEmailsOperation(fileID, contactID, subject, bodyTemplate, storeInHistory); -// _mailQueue.Add(operation); -// } - -// if (!_mailQueue.IsStarted) -// { -// _mailQueue.Start(x => x.RunJob()); -// } -// return operation; -// } -// } - -// private SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) -// { -// var client = new SmtpClient -// { -// ServerCertificateValidationCallback = (sender, certificate, chain, errors) => MailService.DefaultServerCertificateValidationCallback(sender, certificate, chain, errors), -// Timeout = (int)TimeSpan.FromSeconds(30).TotalMilliseconds -// }; - -// client.Connect(smtpSetting.Host, smtpSetting.Port, -// smtpSetting.EnableSSL ? SecureSocketOptions.Auto : SecureSocketOptions.None); - -// if (smtpSetting.RequiredHostAuthentication) -// { -// client.Authenticate(smtpSetting.HostLogin, smtpSetting.HostPassword); -// } - -// return client; -// } - -// public void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) -// { -// var log = LogManager.Get("ASC.CRM.MailSender"); - -// if (!recipientEmail.TestEmailRegex()) -// { -// throw new Exception(string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail)); -// } - -// TenantManager.SetCurrentTenant(TenantID); -// var smtpSetting = SettingsManager.Load().SMTPServerSetting; - -// ThreadPool.QueueUserWorkItem(_ => -// { -// try -// { -// var toAddress = new MailboxAddress(recipientEmail); -// var fromAddress = new MailboxAddress(smtpSetting.SenderDisplayName, smtpSetting.SenderEmailAddress); - -// var mimeMessage = new MimeMessage -// { -// Subject = mailSubj -// }; - -// mimeMessage.From.Add(fromAddress); - -// mimeMessage.To.Add(toAddress); - -// var bodyBuilder = new BodyBuilder -// { -// TextBody = mailBody -// }; - -// mimeMessage.Body = bodyBuilder.ToMessageBody(); - -// mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); - -// using (var smtpClient = GetSmtpClient(smtpSetting)) -// { -// smtpClient.Send(FormatOptions.Default, mimeMessage, CancellationToken.None); -// } -// } -// catch (Exception ex) -// { -// log.Error(ex); -// } -// }); -// } - -// public IProgressItem GetStatus() -// { -// var result = _mailQueue.GetStatus(TenantID); - -// if (result == null) -// return MailSenderDataCache.Get(); - -// return result; -// } + public MailTemplateManager(DaoFactory daoFactory) + { + _daoFactory = daoFactory; + } -// public void Cancel() -// { -// lock (_syncObj) -// { -// var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantID); + private IEnumerable GetTagsFrom(String template) + { + if (_templateTagsCache.ContainsKey(template)) return _templateTagsCache[template]; -// if (findedItem.Any()) -// { -// _mailQueue.Remove(findedItem.ElementAt(0)); + var tags = GetAllTags(); -// MailSenderDataCache.ResetAll(); -// } -// else -// { -// MailSenderDataCache.SetCancelFlag(); -// } -// } -// } -// } + var result = new List(); -// [Serializable] -// [DataContract] -// public class MailTemplateTag -// { -// [DataMember(Name = "sysname")] -// public String SysName { get; set; } + var _regex = new Regex("\\$\\((Person|Company)\\.[^<>\\)]*\\)"); -// [DataMember(Name = "display_name")] -// public String DisplayName { get; set; } -// [DataMember(Name = "category")] -// public String Category { get; set; } + if (!_regex.IsMatch(template)) + return new List(); -// [DataMember(Name = "is_company")] -// public bool isCompany { get; set; } + foreach (Match match in _regex.Matches(template)) + { + var findedTag = tags.Find(item => String.Compare(item.Name, match.Value) == 0); -// [DataMember(Name = "name")] -// public String Name { get; set; } -// } + if (findedTag == null) continue; -// public class MailTemplateManager -// { -// private readonly Dictionary> _templateTagsCache = new Dictionary>(); + if (!result.Contains(findedTag)) + result.Add(findedTag); + } -// private readonly DaoFactory _daoFactory; + _templateTagsCache.Add(template, result); -// public MailTemplateManager(DaoFactory daoFactory) -// { -// _daoFactory = daoFactory; -// } + return result; + } -// private IEnumerable GetTagsFrom(String template) -// { -// if (_templateTagsCache.ContainsKey(template)) return _templateTagsCache[template]; + private String Apply(String template, IEnumerable templateTags, int contactID) + { + var result = template; -// var tags = GetAllTags(); -// var result = new List(); + var contactDao = _daoFactory.GetContactDao(); + var contactInfoDao = _daoFactory.GetContactInfoDao(); + var customFieldDao = _daoFactory.GetCustomFieldDao(); -// var _regex = new Regex("\\$\\((Person|Company)\\.[^<>\\)]*\\)"); + var contact = contactDao.GetByID(contactID); + if (contact == null) + throw new ArgumentException(CRMErrorsResource.ContactNotFound); -// if (!_regex.IsMatch(template)) -// return new List(); + foreach (var tag in templateTags) + { + var tagParts = tag.SysName.Split(new[] { '_' }); -// foreach (Match match in _regex.Matches(template)) -// { -// var findedTag = tags.Find(item => String.Compare(item.Name, match.Value) == 0); + var source = tagParts[0]; -// if (findedTag == null) continue; + var tagValue = String.Empty; -// if (!result.Contains(findedTag)) -// result.Add(findedTag); -// } + switch (source) + { + case "common": -// _templateTagsCache.Add(template, result); + if (contact is Person) + { -// return result; -// } + var person = (Person)contact; -// private String Apply(String template, IEnumerable templateTags, int contactID) -// { -// var result = template; + switch (tagParts[1]) + { + case "firstName": + tagValue = person.FirstName; -// var contactDao = _daoFactory.GetContactDao(); -// var contactInfoDao = _daoFactory.GetContactInfoDao(); -// var customFieldDao = _daoFactory.GetCustomFieldDao(); + break; + case "lastName": + tagValue = person.LastName; -// var contact = contactDao.GetByID(contactID); + break; + case "jobTitle": + tagValue = person.JobTitle; + break; + case "companyName": + var relativeCompany = contactDao.GetByID(((Person)contact).CompanyID); -// if (contact == null) -// throw new ArgumentException(CRMErrorsResource.ContactNotFound); + if (relativeCompany != null) + tagValue = relativeCompany.GetTitle(); -// foreach (var tag in templateTags) -// { -// var tagParts = tag.SysName.Split(new[] { '_' }); -// var source = tagParts[0]; + break; + default: + tagValue = String.Empty; + break; -// var tagValue = String.Empty; + } -// switch (source) -// { -// case "common": + } + else + { -// if (contact is Person) -// { + var company = (Company)contact; -// var person = (Person)contact; + switch (tagParts[1]) + { + case "companyName": + tagValue = company.CompanyName; + break; + default: + tagValue = String.Empty; + break; + } + } -// switch (tagParts[1]) -// { + break; + case "customField": + var tagID = Convert.ToInt32(tagParts[tagParts.Length - 1]); -// case "firstName": -// tagValue = person.FirstName; + var entityType = contact is Company ? EntityType.Company : EntityType.Person; -// break; -// case "lastName": -// tagValue = person.LastName; + tagValue = customFieldDao.GetValue(entityType, contactID, tagID); -// break; -// case "jobTitle": -// tagValue = person.JobTitle; -// break; -// case "companyName": -// var relativeCompany = contactDao.GetByID(((Person)contact).CompanyID); + break; + case "contactInfo": + var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), tagParts[1]); + var category = Convert.ToInt32(tagParts[2]); + var contactInfos = contactInfoDao.GetList(contactID, contactInfoType, category, true); -// if (relativeCompany != null) -// tagValue = relativeCompany.GetTitle(); + if (contactInfos == null || contactInfos.Count == 0) break; + var contactInfo = contactInfos[0]; -// break; -// default: -// tagValue = String.Empty; -// break; - -// } - -// } -// else -// { - -// var company = (Company)contact; - -// switch (tagParts[1]) -// { -// case "companyName": -// tagValue = company.CompanyName; -// break; -// default: -// tagValue = String.Empty; -// break; -// } -// } - -// break; -// case "customField": -// var tagID = Convert.ToInt32(tagParts[tagParts.Length - 1]); - -// var entityType = contact is Company ? EntityType.Company : EntityType.Person; - -// tagValue = customFieldDao.GetValue(entityType, contactID, tagID); - -// break; -// case "contactInfo": -// var contactInfoType = (ContactInfoType)Enum.Parse(typeof(ContactInfoType), tagParts[1]); -// var category = Convert.ToInt32(tagParts[2]); -// var contactInfos = contactInfoDao.GetList(contactID, contactInfoType, category, true); - -// if (contactInfos == null || contactInfos.Count == 0) break; - -// var contactInfo = contactInfos[0]; - -// if (contactInfoType == ContactInfoType.Address) -// { -// var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), tagParts[3]); - -// tagValue = JObject.Parse(contactInfo.Data)[addressPart.ToString().ToLower()].Value(); - -// } -// else -// tagValue = contactInfo.Data; - -// break; -// default: -// throw new ArgumentException(tag.SysName); -// } - -// result = result.Replace(tag.Name, tagValue); -// } - -// return result; -// } - -// public String Apply(String template, int contactID) -// { -// return Apply(template, GetTagsFrom(template), contactID); -// } - -// private String ToTagName(String value, bool isCompany) -// { -// return String.Format("$({0}.{1})", isCompany ? "Company" : "Person", value); -// } - -// private List GetAllTags() -// { -// return GetTags(true).Union(GetTags(false)).ToList(); -// } - -// public List GetTags(bool isCompany) -// { -// var result = new List(); - -// if (isCompany) -// { - -// result.Add(new MailTemplateTag -// { -// DisplayName = CRMContactResource.CompanyName, -// SysName = "common_companyName", -// Category = CRMContactResource.GeneralInformation, -// isCompany = isCompany, -// Name = ToTagName("Company Name", isCompany) -// }); - -// } -// else -// { -// result.Add(new MailTemplateTag -// { -// DisplayName = CRMContactResource.FirstName, -// SysName = "common_firstName", -// Category = CRMContactResource.GeneralInformation, -// isCompany = false, -// Name = ToTagName("First Name", isCompany) -// }); - -// result.Add(new MailTemplateTag -// { -// DisplayName = CRMContactResource.LastName, -// SysName = "common_lastName", -// Category = CRMContactResource.GeneralInformation, -// isCompany = false, -// Name = ToTagName("Last Name", isCompany) -// }); - -// result.Add(new MailTemplateTag -// { -// DisplayName = CRMContactResource.JobTitle, -// SysName = "common_jobTitle", -// Category = CRMContactResource.GeneralInformation, -// isCompany = false, -// Name = ToTagName("Job Title", isCompany) -// }); - - -// result.Add(new MailTemplateTag -// { -// DisplayName = CRMContactResource.CompanyName, -// SysName = "common_companyName", -// Category = CRMContactResource.GeneralInformation, -// isCompany = false, -// Name = ToTagName("Company Name", isCompany) -// }); - -// } - -// foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) -// { - -// var localName = String.Format("contactInfo_{0}_{1}", infoTypeEnum, ContactInfo.GetDefaultCategory(infoTypeEnum)); -// var localTitle = infoTypeEnum.ToLocalizedString(); - -// if (infoTypeEnum == ContactInfoType.Address) -// foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) -// result.Add(new MailTemplateTag -// { -// SysName = String.Format(localName + "_{0}_{1}", addressPartEnum, (int)AddressCategory.Work), -// DisplayName = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString()), -// Category = CRMContactResource.GeneralInformation, -// isCompany = isCompany, -// Name = ToTagName(String.Format("{0} {1}", infoTypeEnum.ToString(), addressPartEnum.ToString()), isCompany) -// }); -// else -// result.Add(new MailTemplateTag -// { -// SysName = localName, -// DisplayName = localTitle, -// Category = CRMContactResource.GeneralInformation, -// isCompany = isCompany, -// Name = ToTagName(infoTypeEnum.ToString(), isCompany) -// }); -// } - -// var entityType = isCompany ? EntityType.Company : EntityType.Person; - -// var customFieldsDao = _daoFactory.GetCustomFieldDao(); - -// var customFields = customFieldsDao.GetFieldsDescription(entityType); - -// var category = CRMContactResource.GeneralInformation; - -// foreach (var customField in customFields) -// { -// if (customField.FieldType == CustomFieldType.SelectBox) continue; -// if (customField.FieldType == CustomFieldType.CheckBox) continue; - -// if (customField.FieldType == CustomFieldType.Heading) -// { -// if (!String.IsNullOrEmpty(customField.Label)) -// category = customField.Label; - -// continue; -// } - -// result.Add(new MailTemplateTag -// { -// SysName = "customField_" + customField.ID, -// DisplayName = customField.Label.HtmlEncode(), -// Category = category, -// isCompany = isCompany, -// Name = ToTagName(customField.Label, isCompany) -// }); -// } - -// return result; -// } - -// } -//} \ No newline at end of file + if (contactInfoType == ContactInfoType.Address) + { + var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), tagParts[3]); + + tagValue = JObject.Parse(contactInfo.Data)[addressPart.ToString().ToLower()].Value(); + + } + else + tagValue = contactInfo.Data; + + break; + default: + throw new ArgumentException(tag.SysName); + } + + result = result.Replace(tag.Name, tagValue); + } + + return result; + } + + public String Apply(String template, int contactID) + { + return Apply(template, GetTagsFrom(template), contactID); + } + + private String ToTagName(String value, bool isCompany) + { + return String.Format("$({0}.{1})", isCompany ? "Company" : "Person", value); + } + + private List GetAllTags() + { + return GetTags(true).Union(GetTags(false)).ToList(); + } + + public List GetTags(bool isCompany) + { + var result = new List(); + + if (isCompany) + { + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.CompanyName, + SysName = "common_companyName", + Category = CRMContactResource.GeneralInformation, + isCompany = isCompany, + Name = ToTagName("Company Name", isCompany) + }); + + } + else + { + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.FirstName, + SysName = "common_firstName", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("First Name", isCompany) + }); + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.LastName, + SysName = "common_lastName", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("Last Name", isCompany) + }); + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.JobTitle, + SysName = "common_jobTitle", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("Job Title", isCompany) + }); + + + result.Add(new MailTemplateTag + { + DisplayName = CRMContactResource.CompanyName, + SysName = "common_companyName", + Category = CRMContactResource.GeneralInformation, + isCompany = false, + Name = ToTagName("Company Name", isCompany) + }); + + } + + foreach (ContactInfoType infoTypeEnum in Enum.GetValues(typeof(ContactInfoType))) + { + + var localName = String.Format("contactInfo_{0}_{1}", infoTypeEnum, ContactInfo.GetDefaultCategory(infoTypeEnum)); + var localTitle = infoTypeEnum.ToLocalizedString(); + + if (infoTypeEnum == ContactInfoType.Address) + foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) + result.Add(new MailTemplateTag + { + SysName = String.Format(localName + "_{0}_{1}", addressPartEnum, (int)AddressCategory.Work), + DisplayName = String.Format(localTitle + " {0}", addressPartEnum.ToLocalizedString()), + Category = CRMContactResource.GeneralInformation, + isCompany = isCompany, + Name = ToTagName(String.Format("{0} {1}", infoTypeEnum.ToString(), addressPartEnum.ToString()), isCompany) + }); + else + result.Add(new MailTemplateTag + { + SysName = localName, + DisplayName = localTitle, + Category = CRMContactResource.GeneralInformation, + isCompany = isCompany, + Name = ToTagName(infoTypeEnum.ToString(), isCompany) + }); + } + + var entityType = isCompany ? EntityType.Company : EntityType.Person; + + var customFieldsDao = _daoFactory.GetCustomFieldDao(); + + var customFields = customFieldsDao.GetFieldsDescription(entityType); + + var category = CRMContactResource.GeneralInformation; + + foreach (var customField in customFields) + { + if (customField.FieldType == CustomFieldType.SelectBox) continue; + if (customField.FieldType == CustomFieldType.CheckBox) continue; + + if (customField.FieldType == CustomFieldType.Heading) + { + if (!String.IsNullOrEmpty(customField.Label)) + category = customField.Label; + + continue; + } + + result.Add(new MailTemplateTag + { + SysName = "customField_" + customField.ID, + DisplayName = customField.Label.HtmlEncode(), + Category = category, + isCompany = isCompany, + Name = ToTagName(customField.Label, isCompany) + }); + } + + return result; + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index bf7a19307a3..6085912bf3a 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -34,25 +34,43 @@ using Microsoft.AspNetCore.Http; using ASC.CRM.Core.Enums; using log4net; +using ASC.Common; namespace ASC.Web.CRM.Classes -{ +{ + [Transient] public class PdfQueueWorker { - private static readonly ProgressQueue Queue = new ProgressQueue(); + private readonly ProgressQueue Queue; + private readonly int tenantId; + private readonly Guid userId; + + public PdfQueueWorker(ProgressQueueOptionsManager progressQueueOptionsManager, + PdfProgressItem pdfProgressItem, + TenantManager tenantProvider, + SecurityContext securityContext) + { + Queue = progressQueueOptionsManager.Value; + PdfProgressItem = pdfProgressItem; + tenantId = tenantProvider.GetCurrentTenant().TenantId; + userId = securityContext.CurrentAccount.ID; + } - public static string GetTaskId(int tenantId, int invoiceId) + public PdfProgressItem PdfProgressItem { get; } + + public string GetTaskId(int tenantId, int invoiceId) { return string.Format("{0}_{1}", tenantId, invoiceId); } - public static PdfProgressItem GetTaskStatus(int tenantId, int invoiceId) + public PdfProgressItem GetTaskStatus(int tenantId, int invoiceId) { var id = GetTaskId(tenantId, invoiceId); + return Queue.GetStatus(id) as PdfProgressItem; } - public static void TerminateTask(int tenantId, int invoiceId) + public void TerminateTask(int invoiceId) { var item = GetTaskStatus(tenantId, invoiceId); @@ -60,39 +78,42 @@ public static void TerminateTask(int tenantId, int invoiceId) Queue.Remove(item); } - public static PdfProgressItem StartTask(HttpContext context, int tenantId, Guid userId, int invoiceId) + public PdfProgressItem StartTask(int invoiceId) { - throw new Exception(); - //lock (Queue.SynchRoot) - //{ - // var task = GetTaskStatus(tenantId, invoiceId); - - // if (task != null && task.IsCompleted) - // { - // Queue.Remove(task); - // task = null; - // } - - // if (task == null) - // { - // task = new PdfProgressItem(context, tenantId, userId, invoiceId); - // Queue.Add(task); - // } - - // if (!Queue.IsStarted) - // Queue.Start(x => x.RunJob()); - - // return task; - //} + lock (Queue.SynchRoot) + { + var task = GetTaskStatus(tenantId, invoiceId); + + if (task != null && task.IsCompleted) + { + Queue.Remove(task); + task = null; + } + + if (task == null) + { + + PdfProgressItem.Configure(GetTaskId(tenantId, invoiceId), tenantId, userId, invoiceId); + + Queue.Add(PdfProgressItem); + + } + + if (!Queue.IsStarted) + Queue.Start(x => x.RunJob()); + + return task; + } } } + [Transient] public class PdfProgressItem : IProgressItem { private readonly string _contextUrl; - private readonly int _tenantId; - private readonly int _invoiceId; - private readonly Guid _userId; + private int _tenantId; + private int _invoiceId; + private Guid _userId; public object Id { get; set; } public object Status { get; set; } @@ -103,23 +124,25 @@ public class PdfProgressItem : IProgressItem public SecurityContext SecurityContext { get; } public TenantManager TenantManager { get; } - public PdfProgressItem(IHttpContextAccessor httpContextAccessor, - int tenantId, + public PdfProgressItem(IHttpContextAccessor httpContextAccessor) + { + _contextUrl = httpContextAccessor.HttpContext != null ? httpContextAccessor.HttpContext.Request.GetUrlRewriter().ToString() : null; + + Status = ProgressStatus.Queued; + Error = null; + Percentage = 0; + IsCompleted = false; + } + + public void Configure(object id, + int tenantId, Guid userId, int invoiceId) { - - - _contextUrl = httpContextAccessor.HttpContext != null ? httpContextAccessor.HttpContext.Request.GetUrlRewriter().ToString() : null; + Id = id; _tenantId = tenantId; _invoiceId = invoiceId; _userId = userId; - - Id = PdfQueueWorker.GetTaskId(tenantId, invoiceId); - Status = ProgressStatus.Queued; - Error = null; - Percentage = 0; - IsCompleted = false; } public void RunJob() diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index e221bb6f5e3..dfa5fd783dc 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -39,34 +39,46 @@ using System.Net; using Microsoft.Extensions.DependencyInjection; using ASC.Common; +using ASC.Core; +using Microsoft.AspNetCore.Http; namespace ASC.Web.CRM.Classes { [Scope] public class ReportHelper { - public ReportHelper(TenantUtil tenantUtil, + public ReportHelper(TenantManager tenantManager, + TenantUtil tenantUtil, Global global, - // DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper, + DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper, SettingsManager settingsManager, DaoFactory daoFactory, - IServiceProvider serviceProvider + SecurityContext securityContext, + IServiceProvider serviceProvider, + IHttpContextAccessor httpContextAccessor ) { + TenantManager = tenantManager; TenantUtil = tenantUtil; Global = global; SettingsManager = settingsManager; ServiceProvider = serviceProvider; DaoFactory = daoFactory; + DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; + SecurityContext = securityContext; + HttpContext = httpContextAccessor; } + public IHttpContextAccessor HttpContext { get; } + public SecurityContext SecurityContext { get; } + public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } public DaoFactory DaoFactory { get; } public IServiceProvider ServiceProvider { get; } public Global Global { get; } public SettingsManager SettingsManager { get; } public TenantUtil TenantUtil { get; } - + public TenantManager TenantManager { get; } private string GetFileName(ReportType reportType) { string reportName; @@ -233,17 +245,26 @@ public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod tim var tmpFileName = DocbuilderReportsUtility.TmpFileName; var script = GetReportScript(reportData, reportType, tmpFileName); + if (string.IsNullOrEmpty(script)) throw new Exception(CRMReportResource.ErrorNullReportScript); - // ServiceProvider.GetService() + var reportStateData = new ReportStateData( + GetFileName(reportType), + tmpFileName, + script, + (int)reportType, + ReportOrigin.CRM, + SaveReportFile, + null, + TenantManager.GetCurrentTenant().TenantId, + SecurityContext.CurrentAccount.ID); - // var state = new ReportState(GetFileName(reportType), tmpFileName, script, (int)reportType, ReportOrigin.CRM, SaveReportFile, null); + var state = new ReportState(ServiceProvider, reportStateData, HttpContext); - // DocbuilderReportsUtility.Enqueue(state); + DocbuilderReportsUtilityHelper.Enqueue(state); - // return state; - throw new NotImplementedException(); + return state; } } } \ No newline at end of file From 4902cb6a7483a145ccdc985485e716563f4af4a4 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 15 Mar 2021 14:36:22 +0300 Subject: [PATCH 23/61] crm: refactoring. migrate ReportsController and VoIPController --- products/ASC.CRM/Server/Api/CRMBootstrap.cs | 58 - .../ASC.CRM/Server/Api/CasesController.cs | 29 +- .../Server/Api/ContactInfosController.cs | 3 +- .../ASC.CRM/Server/Api/ContactsController.cs | 13 +- .../ASC.CRM/Server/Api/DealsController.cs | 4 +- .../ASC.CRM/Server/Api/ReportsController.cs | 358 ++-- products/ASC.CRM/Server/Api/VoipController.cs | 1889 +++++++++-------- .../ASC.CRM/Server/ApiModels/ContactDto.cs | 7 - .../Server/ApiModels/OpportunityDto.cs | 48 +- .../ApiModels/SendMailSMTPToContactsInDto.cs | 2 +- .../ApiModels/SetAccessToBatchCasesInDto.cs | 2 +- .../ASC.CRM/Server/ApiModels/VoipCallDto.cs | 27 +- .../Server/Configuration/ProductEntryPoint.cs | 22 +- .../Server/Configuration/SearchHandler.cs | 70 - products/ASC.CRM/Server/Program.cs | 18 + products/ASC.CRM/Server/Startup.cs | 2 + 16 files changed, 1239 insertions(+), 1313 deletions(-) delete mode 100644 products/ASC.CRM/Server/Api/CRMBootstrap.cs delete mode 100644 products/ASC.CRM/Server/Configuration/SearchHandler.cs diff --git a/products/ASC.CRM/Server/Api/CRMBootstrap.cs b/products/ASC.CRM/Server/Api/CRMBootstrap.cs deleted file mode 100644 index 9106fcb5988..00000000000 --- a/products/ASC.CRM/Server/Api/CRMBootstrap.cs +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using System.Collections.Generic; -using ASC.Api.Interfaces; -using ASC.Core; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.Web.Core; -using ASC.Web.Core.Calendars; -using ASC.Web.Files.Api; - -namespace ASC.Api.CRM -{ - public class CRMBootstrap : IApiBootstrapper - { - public void Configure() - { - if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) - { - FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider()); - } - - //Register prodjects' calendar events - CalendarManager.Instance.RegistryCalendarProvider(userid => - { - if (WebItemSecurity.IsAvailableForUser(WebItemManager.CRMProductID, userid)) - { - return new List {new CRMCalendar(userid)}; - } - return new List(); - }); - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index 42d1cff8c34..3bc31c1f346 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -46,6 +46,7 @@ using ASC.Api.Core; using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Core.Users; +using Microsoft.AspNetCore.Mvc; namespace ASC.CRM.Api { @@ -97,7 +98,7 @@ public CasesController(CRMSecurity cRMSecurity, /// Case /// [Update(@"case/{caseid:int}/close")] - public CasesDto CloseCases(int caseid) + public CasesDto CloseCases([FromQuery] int caseid) { if (caseid <= 0) throw new ArgumentException(); @@ -121,7 +122,7 @@ public CasesDto CloseCases(int caseid) /// Case /// [Update(@"case/{caseid:int}/reopen")] - public CasesDto ReOpenCases(int caseid) + public CasesDto ReOpenCases([FromQuery] int caseid) { if (caseid <= 0) throw new ArgumentException(); @@ -160,8 +161,7 @@ public CasesDto ReOpenCases(int caseid) /// ]]> /// [Create(@"case")] - public CasesDto CreateCases( - CreateOrUpdateCasesInDto inDto) + public CasesDto CreateCases([FromForm] CreateOrUpdateCasesInDto inDto) { var title = inDto.Title; @@ -236,9 +236,7 @@ public CasesDto CreateCases( /// ]]> /// [Update(@"case/{caseid:int}")] - public CasesDto UpdateCases( - int caseid, - CreateOrUpdateCasesInDto inDto) + public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCasesInDto inDto) { var title = inDto.Title; var isPrivate = inDto.isPrivate; @@ -296,7 +294,7 @@ public CasesDto UpdateCases( /// Case /// [Update(@"case/{caseid:int}/access")] - public CasesDto SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) + public CasesDto SetAccessToCases([FromQuery] int caseid, bool isPrivate, IEnumerable accessList) { if (caseid <= 0) throw new ArgumentException(); @@ -357,10 +355,9 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable /// Case list /// [Update(@"case/access")] - public IEnumerable SetAccessToBatchCases( - SetAccessToBatchCasesInDto inDto) + public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCasesInDto inDto) { - var casesid = inDto.Casesid; + var casesid = inDto.CasesId; var isPrivate = inDto.isPrivate; var accessList = inDto.AccessList; @@ -399,9 +396,7 @@ public IEnumerable SetAccessToBatchCases( /// Case list /// [Update(@"case/filter/access")] - public IEnumerable SetAccessToBatchCases( - SetAccessToBatchCasesByFilterInDto inDto - ) + public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCasesByFilterInDto inDto) { int contactid = inDto.Contactid; bool? isClosed = inDto.isClosed; @@ -437,7 +432,7 @@ SetAccessToBatchCasesByFilterInDto inDto /// /// [Read(@"case/{caseid:int}")] - public CasesDto GetCaseByID(int caseid) + public CasesDto GetCaseByID([FromQuery] int caseid) { if (caseid <= 0) throw new ItemNotFoundException(); @@ -541,7 +536,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable /// Case /// [Delete(@"case/{caseid:int}")] - public CasesDto DeleteCase(int caseid) + public CasesDto DeleteCase([FromQuery] int caseid) { if (caseid <= 0) throw new ArgumentException(); @@ -566,7 +561,7 @@ public CasesDto DeleteCase(int caseid) /// Case list /// [Update(@"case")] - public IEnumerable DeleteBatchCases(IEnumerable casesids) + public IEnumerable DeleteBatchCases([FromForm] IEnumerable casesids) { if (casesids == null) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index 5ff0e35319c..2db0b58f2bd 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -47,6 +47,7 @@ using ASC.Web.CRM.Services.NotifyService; using ASC.Core; using ASC.Web.Core.Users; +using Microsoft.AspNetCore.Mvc; namespace ASC.CRM.Api { @@ -330,7 +331,7 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEnumer /// Contact information /// [Update(@"contact/{contactid:int}/data/{id:int}")] - public ContactInfoDto UpdateContactInfo(int id, int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category) + public ContactInfoDto UpdateContactInfo([FromQuery] int id, [FromQuery] int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category) { if (id <= 0 || string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index 38e2a2979cf..7534b63546c 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -124,7 +124,7 @@ public ContactsController(CRMSecurity cRMSecurity, /// /// [Read(@"contact/{contactid:int}")] - public ContactDto GetContactByID(int contactid) + public ContactDto GetContactByID([FromQuery] int contactid) { if (contactid <= 0) throw new ArgumentException(); @@ -155,7 +155,7 @@ public IEnumerable GetContactsByID(IEnumerable contactid) /// /// [Read(@"contact/project/{projectid:int}")] - public IEnumerable GetContactsByProjectID(int projectid) + public IEnumerable GetContactsByProjectID([FromQuery] int projectid) { if (projectid <= 0) throw new ArgumentException(); @@ -283,7 +283,7 @@ public IEnumerable GetContactsByProjectID(int projectid) /// Opportunity /// [Create(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] - public OpportunityDto AddDealToContact(int contactid, int opportunityid) + public OpportunityDto AddDealToContact([FromQuery] int contactid, [FromQuery] int opportunityid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -313,7 +313,7 @@ public OpportunityDto AddDealToContact(int contactid, int opportunityid) /// Opportunity /// [Delete(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] - public OpportunityDto DeleteDealFromContact(int contactid, int opportunityid) + public OpportunityDto DeleteDealFromContact([FromQuery] int contactid, [FromQuery] int opportunityid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -996,8 +996,7 @@ public PersonDto UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdat /// Company /// [Create(@"contact/company")] - public CompanyDto CreateCompany( - [FromForm] CreateOrUpdateCompanyInDto inDto) + public CompanyDto CreateCompany([FromForm] CreateOrUpdateCompanyInDto inDto) { var personList = inDto.PersonList; string companyName = inDto.CompanyName; @@ -1900,7 +1899,7 @@ public IProgressItem SendMailSMTPToContacts( List fileIDs = inDto.FileIDs; List contactIds = inDto.ContactIds; String subject = inDto.Subject; - String body = inDto.body; + String body = inDto.Body; bool storeInHistory = inDto.StoreInHistory; if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index 3d8ed408f8b..66dab22d0bc 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -45,6 +45,8 @@ using ASC.Web.CRM.Classes; using ASC.Web.CRM.Services.NotifyService; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class DealsController : BaseApiController @@ -228,7 +230,7 @@ private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable [Update(@"opportunity/filter/access")] - public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealByFilterInDto inDto) + public IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBatchDealByFilterInDto inDto) { var responsibleid = inDto.Responsibleid; var opportunityStagesid = inDto.OpportunityStagesid; diff --git a/products/ASC.CRM/Server/Api/ReportsController.cs b/products/ASC.CRM/Server/Api/ReportsController.cs index 9c91156e1e0..ea73d1e080e 100644 --- a/products/ASC.CRM/Server/Api/ReportsController.cs +++ b/products/ASC.CRM/Server/Api/ReportsController.cs @@ -1,163 +1,195 @@ -///* -// * -// * (c) Copyright Ascensio System Limited 2010-2018 -// * -// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU -// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). -// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that -// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. -// * -// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR -// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html -// * -// * You can contact Ascensio System SIA by email at sales@onlyoffice.com -// * -// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display -// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. -// * -// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains -// * relevant author attributions when distributing the software. If the display of the logo in its graphic -// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" -// * in every copy of the program you distribute. -// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. -// * -//*/ - - -//using ASC.Api.Documents; -//using ASC.Common.Web; -//using ASC.CRM.Core; -//using ASC.CRM.Core.Enums; -//using ASC.Web.Api.Routing; -//using ASC.Web.CRM.Classes; -//using ASC.Web.Files.Services.DocumentService; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Security; - -//namespace ASC.CRM.Api -//{ -// public partial class CRMController -// { -// /// Returns a list of all user report files -// /// Get report files -// /// Reports -// /// Report files -// /// if user can't create reports -// [Read(@"report/files")] -// public IEnumerable> GetFiles() -// { -// if (!Global.CanCreateReports) -// throw CRMSecurity.CreateSecurityException(); - -// var reportDao = DaoFactory.GetReportDao(); - -// var files = reportDao.GetFiles(); - -// if (!files.Any()) -// { -// var settings = SettingsManager.Load(); - -// if (settings.NeedToGenerate) -// { -// files = reportDao.SaveSampleReportFiles(); - -// settings.NeedToGenerate = false; - -// SettingsManager.Save(settings); -// } -// } - -// return files.ConvertAll(file => FileWrapperHelper.Get(file)).OrderByDescending(file => file.Id); -// } - -// /// Delete the report file with the ID specified in the request -// /// File ID -// /// Delete report file -// /// Reports -// /// if user can't create reports -// /// if fileid les than 0 -// /// if file not found -// [Delete(@"report/file/{fileid:int}")] -// public void DeleteFile(int fileid) -// { -// if (!Global.CanCreateReports) -// throw CRMSecurity.CreateSecurityException(); - -// if (fileid < 0) throw new ArgumentException(); - -// var file = DaoFactory.GetReportDao().GetFile(fileid); - -// if (file == null) throw new ItemNotFoundException("File not found"); - -// DaoFactory.GetReportDao().DeleteFile(fileid); -// } - -// /// Get the state of the report generation task -// /// Get report generation state -// /// Reports -// /// Report state -// /// if user can't create reports -// [Read(@"report/status")] -// public ReportState GetStatus() -// { -// if (!Global.CanCreateReports) -// throw CRMSecurity.CreateSecurityException(); - -// return DocbuilderReportsUtility.Status(ReportOrigin.CRM, HttpContextAccessor, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); - -// } - -// /// Terminate the report generation task -// /// Terminate report generation -// /// Reports -// /// if user can't create reports -// [Read(@"report/terminate")] -// public void Terminate() -// { -// if (!Global.CanCreateReports) -// throw CRMSecurity.CreateSecurityException(); - -// DocbuilderReportsUtility.Terminate(ReportOrigin.CRM, TenantManager.GetCurrentTenant().TenantId, SecurityContext.CurrentAccount.ID); -// } - -// /// Check data availability for a report -// /// Report type -// /// Time period -// /// Managers -// /// Check report data -// /// Reports -// /// Object -// /// if user can't create reports -// [Create(@"report/check")] -// public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) -// { -// if (!Global.CanCreateReports) -// throw CRMSecurity.CreateSecurityException(); - -// return new -// { -// hasData = ReportHelper.CheckReportData(type, timePeriod, managers), -// missingRates = ReportHelper.GetMissingRates(type) -// }; -// } - -// /// Run the report generation task -// /// Report type -// /// Time period -// /// Managers -// /// Generate report -// /// Reports -// /// Report state -// /// if user can't create reports -// [Create(@"report/generate")] -// public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) -// { -// if (!Global.CanCreateReports) -// throw CRMSecurity.CreateSecurityException(); - -// return ReportHelper.RunGenareteReport(type, timePeriod, managers); -// } -// } -//} \ No newline at end of file +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.CRM; +using ASC.Api.Documents; +using ASC.Common.Web; +using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Enums; +using ASC.MessagingSystem; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using ASC.Web.Files.Services.DocumentService; + +using Microsoft.AspNetCore.Http; + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ASC.CRM.Api +{ + public class ReportsController : BaseApiController + { + public ReportsController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + SettingsManager settingsManager, + Global global, + ReportHelper reportHelper, + FileWrapperHelper fileWrapperHelper, + DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper + ) + : base(daoFactory, cRMSecurity) + { + SettingsManager = settingsManager; + Global = global; + ReportHelper = reportHelper; + FileWrapperHelper = fileWrapperHelper; + DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; + } + + public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } + + public FileWrapperHelper FileWrapperHelper { get; } + public ReportHelper ReportHelper { get; } + public Global Global { get; } + public SettingsManager SettingsManager { get; } + + /// Returns a list of all user report files + /// Get report files + /// Reports + /// Report files + /// if user can't create reports + [Read(@"report/files")] + public IEnumerable> GetFiles() + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + var reportDao = DaoFactory.GetReportDao(); + + var files = reportDao.GetFiles(); + + if (!files.Any()) + { + var settings = SettingsManager.Load(); + + if (settings.NeedToGenerate) + { + files = reportDao.SaveSampleReportFiles(); + + settings.NeedToGenerate = false; + + SettingsManager.Save(settings); + } + } + + return files.ConvertAll(file => FileWrapperHelper.Get(file)).OrderByDescending(file => file.Id); + } + + /// Delete the report file with the ID specified in the request + /// File ID + /// Delete report file + /// Reports + /// if user can't create reports + /// if fileid les than 0 + /// if file not found + [Delete(@"report/file/{fileid:int}")] + public void DeleteFile(int fileid) + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + if (fileid < 0) throw new ArgumentException(); + + var file = DaoFactory.GetReportDao().GetFile(fileid); + + if (file == null) throw new ItemNotFoundException("File not found"); + + DaoFactory.GetReportDao().DeleteFile(fileid); + } + + /// Get the state of the report generation task + /// Get report generation state + /// Reports + /// Report state + /// if user can't create reports + [Read(@"report/status")] + public ReportState GetStatus() + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + return DocbuilderReportsUtilityHelper.Status(ReportOrigin.CRM); + + } + + /// Terminate the report generation task + /// Terminate report generation + /// Reports + /// if user can't create reports + [Read(@"report/terminate")] + public void Terminate() + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + DocbuilderReportsUtilityHelper.Terminate(ReportOrigin.CRM); + } + + /// Check data availability for a report + /// Report type + /// Time period + /// Managers + /// Check report data + /// Reports + /// Object + /// if user can't create reports + [Create(@"report/check")] + public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + return new + { + hasData = ReportHelper.CheckReportData(type, timePeriod, managers), + missingRates = ReportHelper.GetMissingRates(type) + }; + } + + /// Run the report generation task + /// Report type + /// Time period + /// Managers + /// Generate report + /// Reports + /// Report state + /// if user can't create reports + [Create(@"report/generate")] + public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) + { + if (!Global.CanCreateReports) + throw CRMSecurity.CreateSecurityException(); + + return ReportHelper.RunGenareteReport(type, timePeriod, managers); + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index 43b648df748..3a8390f82b4 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -1,906 +1,983 @@ -///* -// * -// * (c) Copyright Ascensio System Limited 2010-2018 -// * -// * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU -// * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). -// * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that -// * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. -// * -// * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR -// * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html -// * -// * You can contact Ascensio System SIA by email at sales@onlyoffice.com -// * -// * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display -// * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. -// * -// * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains -// * relevant author attributions when distributing the software. If the display of the logo in its graphic -// * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" -// * in every copy of the program you distribute. -// * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. -// * -//*/ - - -//using ASC.Api.Core; -//using ASC.CRM.ApiModels; -//using ASC.Api.Utils; -//using ASC.Common.Web; -//using ASC.Core.Tenants; -//using ASC.CRM.Core; -//using ASC.CRM.Core.Enums; -//using ASC.CRM.Resources; -//using ASC.Data.Storage; -//using ASC.VoipService; -//using ASC.VoipService.Dao; -//using ASC.VoipService.Twilio; -//using ASC.Web.Api.Routing; -//using ASC.Web.CRM.Classes; -//using ASC.Web.Studio.Utility; -//using System; -//using System.Collections.Generic; -//using System.Globalization; -//using System.IO; -//using System.Linq; -//using System.Security; -//using SecurityContext = ASC.Core.SecurityContext; - -//namespace ASC.CRM.Api -//{ -// public partial class CRMController -// { -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// /// -// [Read(@"voip/numbers/available")] -// public IEnumerable GetAvailablePhoneNumbers(PhoneNumberType numberType, string isoCountryCode) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException(); -// return VoipProvider.GetAvailablePhoneNumbers(numberType, isoCountryCode); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Read(@"voip/numbers/unlinked")] -// public IEnumerable GetUnlinkedPhoneNumbers() -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var listPhones = VoipProvider.GetExistingPhoneNumbers(); -// var buyedPhones = DaoFactory.GetVoipDao().GetNumbers(); - -// return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList(); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Read(@"voip/numbers/existing")] -// public IEnumerable GetExistingPhoneNumbers() -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// return DaoFactory.GetVoipDao().GetNumbers(); -// } -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Create(@"voip/numbers")] -// public VoipPhone BuyNumber(string number) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var newPhone = VoipProvider.BuyNumber(number); - -// VoipProvider.CreateQueue(newPhone); -// SetDefaultAudio(newPhone); - -// VoipProvider.UpdateSettings(newPhone); -// return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Create(@"voip/numbers/link")] -// public VoipPhone LinkNumber(string id) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var newPhone = VoipProvider.GetPhone(id); - -// VoipProvider.CreateQueue(newPhone); -// SetDefaultAudio(newPhone); - -// VoipProvider.UpdateSettings(newPhone); - -// return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); -// } - -// public void SetDefaultAudio(VoipPhone newPhone) -// { -// var storage = StorageFactory.GetStorage("", "crm"); -// const string path = "default/"; -// var files = storage.ListFilesRelative("voip", path, "*.*", true) -// .Select(filePath => new -// { -// path = CommonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()), -// audioType = (AudioType)Enum.Parse(typeof (AudioType), Directory.GetParent(filePath).Name, true) -// }).ToList(); - -// var audio = files.Find(r => r.audioType == AudioType.Greeting); -// newPhone.Settings.GreetingAudio = audio != null ? audio.path : ""; - -// audio = files.Find(r => r.audioType == AudioType.HoldUp); -// newPhone.Settings.HoldAudio = audio != null ? audio.path : ""; - -// audio = files.Find(r => r.audioType == AudioType.VoiceMail); -// newPhone.Settings.VoiceMail = audio != null ? audio.path : ""; - -// audio = files.Find(r => r.audioType == AudioType.Queue); -// newPhone.Settings.Queue.WaitUrl = audio != null ? audio.path : ""; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Delete(@"voip/numbers/{numberId:\w+}")] -// public VoipPhone DeleteNumber(string numberId) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var dao = DaoFactory.GetVoipDao(); -// var phone = dao.GetNumber(numberId).NotFoundIfNull(); - -// VoipProvider.DisablePhone(phone); -// dao.DeleteNumber(numberId); -// new SignalRHelper(phone.Number, SignalrServiceClient).Reload(); - -// return phone; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Read(@"voip/numbers/{numberId:\w+}")] -// public VoipPhone GetNumber(string numberId) -// { -// return DaoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull(); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Read(@"voip/numbers/current")] -// public VoipPhone GetCurrentNumber() -// { -// return DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Read(@"voip/token")] -// public string GetToken() -// { -// return VoipProvider.GetToken(GetCurrentNumber().Caller); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Update(@"voip/numbers/{numberId:\w+}/settings")] -// public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var dao = DaoFactory.GetVoipDao(); -// var number = dao.GetNumber(numberId).NotFoundIfNull(); - -// number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias); -// number.Settings.GreetingAudio = Update.IfNotEmptyAndNotEquals(number.Settings.GreetingAudio, greeting); -// number.Settings.HoldAudio = Update.IfNotEmptyAndNotEquals(number.Settings.HoldAudio, holdUp); -// number.Settings.VoiceMail = Update.IfNotEmptyAndNotEquals(number.Settings.VoiceMail, voiceMail); -// number.Settings.WorkingHours = Update.IfNotEmptyAndNotEquals(number.Settings.WorkingHours, workingHours); - -// if (!string.IsNullOrEmpty(wait)) -// { -// number.Settings.Queue.WaitUrl = wait; -// } - -// if (allowOutgoingCalls.HasValue) -// { -// number.Settings.AllowOutgoingCalls = allowOutgoingCalls.Value; -// if (!number.Settings.AllowOutgoingCalls) -// { -// number.Settings.Operators.ForEach(r => r.AllowOutgoingCalls = false); -// } -// } - -// if (record.HasValue) -// { -// number.Settings.Record = record.Value; -// if (!number.Settings.Record) -// { -// number.Settings.Operators.ForEach(r => r.Record = false); -// } -// } - -// dao.SaveOrUpdateNumber(number); - -// return number; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Update(@"voip/numbers/settings")] -// public object UpdateSettings(Queue queue, bool pause) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var dao = DaoFactory.GetVoipDao(); -// var numbers = dao.GetNumbers(); - -// if (queue != null) -// { -// foreach (var number in numbers) -// { -// if (number.Settings.Queue == null || string.IsNullOrEmpty(number.Settings.Queue.Id)) -// { -// var phone = number as TwilioPhone; -// if (phone != null) -// { -// queue = phone.CreateQueue(phone.Number, queue.Size, queue.WaitUrl, queue.WaitTime * 60); -// } - -// queue.Name = number.Number; -// number.Settings.Queue = queue; -// } -// else -// { -// var oldQueue = number.Settings.Queue; -// oldQueue.Size = Update.IfNotEmptyAndNotEquals(oldQueue.Size, queue.Size); -// oldQueue.WaitTime = Update.IfNotEmptyAndNotEquals(oldQueue.WaitTime, queue.WaitTime * 60); -// oldQueue.WaitUrl = Update.IfNotEmptyAndNotEquals(oldQueue.WaitUrl, queue.WaitUrl); -// } - -// number.Settings.Pause = pause; - -// dao.SaveOrUpdateNumber(number); -// } -// } - -// return new {queue, pause}; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// - -// [Read(@"voip/numbers/settings")] -// public object GetVoipSettings() -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var dao = DaoFactory.GetVoipDao(); -// var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null); -// if (number != null) -// { -// return new {queue = number.Settings.Queue, pause = number.Settings.Pause}; -// } - -// var files = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true); -// var file = files.FirstOrDefault(); -// return new { queue = new Queue(null, "Default", 5, file != null ? CommonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false }; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Read(@"voip/uploads")] -// public IEnumerable GetUploadedFilesUri() -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var result = new List(); - -// foreach (var audioType in Enum.GetNames(typeof (AudioType))) -// { -// var type = (AudioType)Enum.Parse(typeof (AudioType), audioType); - -// var path = audioType.ToLower(); -// var store = Global.GetStore(); -// var filePaths = store.ListFilesRelative("voip", path, "*", true); -// result.AddRange( -// filePaths.Select(filePath => -// GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type))); - -// path = "default/" + audioType.ToLower(); -// store = StorageFactory.GetStorage("", "crm"); -// filePaths = store.ListFilesRelative("voip", path, "*.*", true); -// result.AddRange( -// filePaths.Select(filePath => -// GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type, true))); -// } - -// return result; -// } - -// private VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false) -// { -// return new VoipUpload -// { -// Path = CommonLinkUtility.GetFullAbsolutePath(link.ToString()), -// Name = fileName, -// AudioType = audioType, -// IsDefault = isDefault -// }; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// /// -// [Delete(@"voip/uploads")] -// public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var store = Global.GetStore(); -// var path = Path.Combine(audioType.ToString().ToLower(), fileName); -// var result = new VoipUpload -// { -// AudioType = audioType, -// Name = fileName, -// Path = CommonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString()) -// }; - -// if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); -// store.Delete("voip", path); - -// var dao = DaoFactory.GetVoipDao(); -// var numbers = dao.GetNumbers(); - -// var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); -// if (defAudio == null) return result; - -// foreach (var number in numbers) -// { -// switch (audioType) -// { -// case AudioType.Greeting: -// if (number.Settings.GreetingAudio == result.Path) -// { -// number.Settings.GreetingAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); -// } -// break; -// case AudioType.HoldUp: -// if (number.Settings.HoldAudio == result.Path) -// { -// number.Settings.HoldAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); -// } -// break; -// case AudioType.Queue: -// var queue = number.Settings.Queue; -// if (queue != null && queue.WaitUrl == result.Path) -// { -// queue.WaitUrl = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); -// } -// break; -// case AudioType.VoiceMail: -// if (number.Settings.VoiceMail == result.Path) -// { -// number.Settings.VoiceMail = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); -// } -// break; -// } - -// dao.SaveOrUpdateNumber(number); -// } - -// return result; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Read(@"voip/numbers/{numberId:\w+}/oper")] -// public IEnumerable GetOperators(string numberId) -// { -// return DaoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// /// -// [Update(@"voip/numbers/{numberId:\w+}/oper")] -// public IEnumerable AddOperators(string numberId, IEnumerable operators) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// if (DaoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) -// { -// throw new ArgumentException("Duplicate", "operators"); -// } - -// var dao = DaoFactory.GetVoipDao(); -// var phone = dao.GetNumber(numberId); -// var lastOper = phone.Settings.Operators.LastOrDefault(); -// var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100; - -// var addedOperators = operators.Select(o => new Agent(o, AnswerType.Client, phone, (startOperId++).ToString(CultureInfo.InvariantCulture))).ToList(); -// phone.Settings.Operators.AddRange(addedOperators); - -// dao.SaveOrUpdateNumber(phone); -// return addedOperators; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Delete(@"voip/numbers/{numberId:\w+}/oper")] -// public Guid DeleteOperator(string numberId, Guid oper) -// { -// if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); - -// var dao = DaoFactory.GetVoipDao(); -// var phone = dao.GetNumber(numberId); -// var startOperId = 100; - -// phone.Settings.Operators.RemoveAll(r => r.Id == oper); -// phone.Settings.Operators.ToList() -// .ForEach(r => -// { -// r.PhoneNumber = phone.Number; -// r.PostFix = startOperId.ToString(CultureInfo.InvariantCulture); -// startOperId++; -// }); - -// dao.SaveOrUpdateNumber(phone); -// return oper; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Update(@"voip/opers/{operatorId}")] -// public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber) -// { -// if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); - -// var dao = DaoFactory.GetVoipDao(); -// var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); - -// var oper = phone.Settings.Operators.Find(r => r.Id == operatorId); - -// if (status.HasValue) -// { -// oper.Status = status.Value; -// } - -// if (allowOutgoingCalls.HasValue) -// { -// oper.AllowOutgoingCalls = phone.Settings.AllowOutgoingCalls && allowOutgoingCalls.Value; -// } - -// if (record.HasValue) -// { -// oper.Record = phone.Settings.Record && record.Value; -// } - -// if (answerType.HasValue) -// { -// oper.Answer = answerType.Value; -// } - -// if (!string.IsNullOrEmpty(redirectToNumber)) -// { -// oper.RedirectToNumber = redirectToNumber; -// } - -// dao.SaveOrUpdateNumber(phone); - -// if (allowOutgoingCalls.HasValue) -// { -// new SignalRHelper(phone.Number, SignalrServiceClient).Reload(operatorId.ToString()); -// } - -// return oper; -// } - - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// /// -// [Create(@"voip/call")] -// public VoipCallDto MakeCall(string to, string contactId) -// { -// var number = DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); -// if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); - -// var contactPhone = to.TrimStart('+'); -// var contact = string.IsNullOrEmpty(contactId) ? -// GetContactsByContactInfo(ContactInfoType.Phone, contactPhone, null, null).FirstOrDefault() : -// GetContactByID(Convert.ToInt32(contactId)); - -// if (contact == null) -// { -// contact = ContactDtoHelper.GetContactDto(VoipEngine.CreateContact(contactPhone)); -// } - -// contact = GetContactWithFotos(contact); - -// var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); - -// return VoipCallDtoHelper.Get(call, contact); - -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Create(@"voip/call/{callId:\w+}/answer")] -// public VoipCallDto AnswerCall(string callId) -// { -// var dao = DaoFactory.GetVoipDao(); -// var call = dao.GetCall(callId).NotFoundIfNull(); -// var number = dao.GetCurrentNumber().NotFoundIfNull(); - -// number.AnswerQueueCall(call.Id); - -// return VoipCallDtoHelper.Get(call); - -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Create(@"voip/call/{callId:\w+}/reject")] -// public VoipCallDto RejectCall(string callId) -// { -// var dao = DaoFactory.GetVoipDao(); -// var call = dao.GetCall(callId).NotFoundIfNull(); -// var number = dao.GetCurrentNumber().NotFoundIfNull(); -// number.RejectQueueCall(call.Id); -// return VoipCallDtoHelper.Get(call); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Create(@"voip/call/{callId:\w+}/redirect")] -// public VoipCallDto ReditectCall(string callId, string to) -// { -// var dao = DaoFactory.GetVoipDao(); -// var call = dao.GetCall(callId).NotFoundIfNull(); -// var number = dao.GetCurrentNumber().NotFoundIfNull(); - -// if (call.ContactId != 0) -// { -// var contact = DaoFactory.GetContactDao().GetByID(call.ContactId); -// var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact); - -// if (!managers.Contains(Guid.Parse(to))) -// { -// managers.Add(Guid.Parse(to)); -// CRMSecurity.SetAccessTo(contact, managers); -// } -// } - -// number.RedirectCall(call.Id, to); -// return VoipCallDtoHelper.Get(call); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Create(@"voip/call/{callId:\w+}")] -// public VoipCallDto SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) -// { -// var dao = DaoFactory.GetVoipDao(); - -// var call = dao.GetCall(callId) ?? new VoipCall(); - -// call.Id = callId; -// call.From = Update.IfNotEmptyAndNotEquals(call.From, from); -// call.To = Update.IfNotEmptyAndNotEquals(call.To, to); -// call.AnsweredBy = Update.IfNotEmptyAndNotEquals(call.AnsweredBy, answeredBy); - -// try -// { -// if (call.ContactId == 0) -// { -// var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; -// if (!string.IsNullOrEmpty(contactId)) -// { -// call.ContactId = Convert.ToInt32(contactId); -// } -// else -// { -// VoipEngine.GetContact(call); -// } - -// if (call.ContactId == 0) -// { -// contactPhone = contactPhone.TrimStart('+'); - -// var person = CreatePerson(contactPhone, TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), null, 0, null, ShareType.None, new List { SecurityContext.CurrentAccount.ID }, null, null); - -// DaoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); - -// call.ContactId = person.Id; -// } -// } -// } -// catch (Exception) -// { - -// } - -// if (status.HasValue) -// { -// call.Status = status.Value; -// } - -// if (call.Price == 0 && price.HasValue) -// { -// call.Price = price.Value; -// } - -// call = dao.SaveOrUpdateCall(call); - -// if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); -// try -// { -// var contact = GetContactByID(call.ContactId); -// contact = GetContactWithFotos(contact); - -// return VoipCallDtoHelper.Get(call, contact); -// } -// catch (Exception) -// { -// return VoipCallDtoHelper.Get(call); -// } - -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Create(@"voip/price/{callId:\w+}")] -// public void SavePrice(string callId) -// { -// VoipEngine.SaveAdditionalInfo(callId); -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Read(@"voip/call")] -// public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) -// { -// var voipDao = DaoFactory.GetVoipDao(); - -// var filter = new VoipCallFilter -// { -// Type = callType, -// FromDate = from != null ? from.UtcTime : (DateTime?)null, -// ToDate = to != null ? to.UtcTime.AddDays(1).AddMilliseconds(-1) : (DateTime?)null, -// Agent = agent, -// Client = client, -// ContactID = contactID, -// SortBy = ApiContext.SortBy, -// SortOrder = !ApiContext.SortDescending, -// SearchText = ApiContext.FilterValue, -// Offset = ApiContext.StartIndex, -// Max = ApiContext.Count, -// }; - -// ApiContext.SetDataPaginated(); -// ApiContext.SetDataFiltered(); -// ApiContext.SetDataSorted(); -// ApiContext.TotalCount = voipDao.GetCallsCount(filter); - -// var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); -// var calls = voipDao.GetCalls(filter).Select( -// r => -// { -// ContactDto contact; - -// if (r.ContactId != 0) -// { -// contact = r.ContactIsCompany -// ? (ContactDto)new CompanyDto() {DisplayName = r.ContactTitle, Id = r.ContactId } -// : new PersonDto() { -// DisplayName = r.ContactTitle, -// Id = r.ContactId -// }; - -// contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); - -// } -// else -// { -// contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; -// } - -// return VoipCallDtoHelper.Get(r, contact); - -// }).ToList(); - -// return calls; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Read(@"voip/call/missed")] -// public IEnumerable GetMissedCalls() -// { -// var voipDao = DaoFactory.GetVoipDao(); -// var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); - -// var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( -// r => -// { -// ContactDto contact; - -// if (r.ContactId != 0) -// { -// contact = r.ContactIsCompany -// ? (ContactDto)new CompanyDto() { DisplayName = r.ContactTitle, Id = r.ContactId } -// : new PersonDto() { DisplayName = r.ContactTitle, Id = r.ContactId }; - -// contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); - -// } -// else -// { -// contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; -// } - -// return VoipCallDtoHelper.Get(r, contact); - -// }).ToList(); - -// ApiContext.SetDataPaginated(); -// ApiContext.SetDataFiltered(); -// ApiContext.SetDataSorted(); -// ApiContext.TotalCount = calls.Count; - -// return calls; -// } - -// /// -// /// -// /// -// /// -// /// Voip -// /// -// [Read(@"voip/call/{callId:\w+}")] -// public VoipCallDto GetCall(string callId) -// { -// var call = DaoFactory.GetVoipDao().GetCall(callId); - -// VoipEngine.GetContact(call); - -// if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); - -// var contact = GetContactByID(call.ContactId); -// contact = GetContactWithFotos(contact); - -// return VoipCallDtoHelper.Get(call, contact); -// } - -// private ContactDto GetContactWithFotos(ContactDto contact) -// { -// contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); -// contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); - -// return contact; -// } -// } -//} \ No newline at end of file +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Security; + +using ASC.Api.Core; +using ASC.Api.CRM; +using ASC.Api.Utils; +using ASC.Common.Web; +using ASC.Core.Notify.Signalr; +using ASC.Core.Tenants; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Data.Storage; +using ASC.VoipService; +using ASC.VoipService.Dao; +using ASC.VoipService.Twilio; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Classes; +using ASC.Web.Studio.Utility; + +using SecurityContext = ASC.Core.SecurityContext; + +namespace ASC.CRM.Api +{ + public class VoIPController : BaseApiController + { + public VoIPController(CRMSecurity cRMSecurity, + DaoFactory daoFactory, + Global global, + ContactPhotoManager contactPhotoManager, + StorageFactory storageFactory, + CommonLinkUtility commonLinkUtility, + SecurityContext securityContext, + VoipCallDtoHelper voipCallDtoHelper, + TenantUtil tenantUtil, + VoipEngine voipEngine, + ApiContext apiContext, + ContactDtoHelper contactDtoHelper, + SignalrServiceClient signalrServiceClient) + : base(daoFactory, cRMSecurity) + { + Global = global; + ContactPhotoManager = contactPhotoManager; + StorageFactory = storageFactory; + CommonLinkUtility = commonLinkUtility; + SecurityContext = securityContext; + VoipCallDtoHelper = voipCallDtoHelper; + TenantUtil = tenantUtil; + VoipEngine = voipEngine; + ApiContext = apiContext; + ContactDtoHelper = contactDtoHelper; + SignalrServiceClient = signalrServiceClient; + } + + public SignalrServiceClient SignalrServiceClient { get; } + public ApiContext ApiContext { get; } + public VoipEngine VoipEngine { get; } + public TenantUtil TenantUtil { get; } + public ContactDtoHelper ContactDtoHelper { get; } + public VoipCallDtoHelper VoipCallDtoHelper { get; } + public SecurityContext SecurityContext { get; } + public CommonLinkUtility CommonLinkUtility { get; } + public StorageFactory StorageFactory { get; } + public ContactPhotoManager ContactPhotoManager { get; } + public Global Global { get; } + + /// + /// + /// + /// + /// Voip + /// + /// + /// + [Read(@"voip/numbers/available")] + public IEnumerable GetAvailablePhoneNumbers(PhoneNumberType numberType, string isoCountryCode) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException(); + + return DaoFactory.GetVoipDao().GetProvider().GetAvailablePhoneNumbers(numberType, isoCountryCode); + + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/unlinked")] + public IEnumerable GetUnlinkedPhoneNumbers() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var listPhones = DaoFactory.GetVoipDao().GetProvider().GetExistingPhoneNumbers(); + var buyedPhones = DaoFactory.GetVoipDao().GetNumbers(); + + return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList(); + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/existing")] + public IEnumerable GetExistingPhoneNumbers() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + return DaoFactory.GetVoipDao().GetNumbers(); + } + /// + /// + /// + /// + /// Voip + /// + /// + [Create(@"voip/numbers")] + public VoipPhone BuyNumber(string number) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var newPhone = DaoFactory.GetVoipDao().GetProvider().BuyNumber(number); + + DaoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone); + SetDefaultAudio(newPhone); + + DaoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone); + return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Create(@"voip/numbers/link")] + public VoipPhone LinkNumber(string id) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var newPhone = DaoFactory.GetVoipDao().GetProvider().GetPhone(id); + + DaoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone); + SetDefaultAudio(newPhone); + + DaoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone); + + return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); + } + + public void SetDefaultAudio(VoipPhone newPhone) + { + var storage = StorageFactory.GetStorage("", "crm"); + const string path = "default/"; + var files = storage.ListFilesRelative("voip", path, "*.*", true) + .Select(filePath => new + { + path = CommonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()), + audioType = (AudioType)Enum.Parse(typeof(AudioType), Directory.GetParent(filePath).Name, true) + }).ToList(); + + var audio = files.Find(r => r.audioType == AudioType.Greeting); + newPhone.Settings.GreetingAudio = audio != null ? audio.path : ""; + + audio = files.Find(r => r.audioType == AudioType.HoldUp); + newPhone.Settings.HoldAudio = audio != null ? audio.path : ""; + + audio = files.Find(r => r.audioType == AudioType.VoiceMail); + newPhone.Settings.VoiceMail = audio != null ? audio.path : ""; + + audio = files.Find(r => r.audioType == AudioType.Queue); + newPhone.Settings.Queue.WaitUrl = audio != null ? audio.path : ""; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Delete(@"voip/numbers/{numberId:regex(\w+)}")] + public VoipPhone DeleteNumber(string numberId) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.GetVoipDao(); + var phone = dao.GetNumber(numberId).NotFoundIfNull(); + + DaoFactory.GetVoipDao().GetProvider().DisablePhone(phone); + dao.DeleteNumber(numberId); + + new SignalRHelper(phone.Number, SignalrServiceClient).Reload(); + + return phone; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/{numberId:regex(\w+)}")] + public VoipPhone GetNumber(string numberId) + { + return DaoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull(); + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/numbers/current")] + public VoipPhone GetCurrentNumber() + { + return DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/token")] + public string GetToken() + { + return DaoFactory.GetVoipDao().GetProvider().GetToken(GetCurrentNumber().Caller); + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Update(@"voip/numbers/{numberId:regex(\w+)}/settings")] + public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.GetVoipDao(); + var number = dao.GetNumber(numberId).NotFoundIfNull(); + + number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias); + number.Settings.GreetingAudio = Update.IfNotEmptyAndNotEquals(number.Settings.GreetingAudio, greeting); + number.Settings.HoldAudio = Update.IfNotEmptyAndNotEquals(number.Settings.HoldAudio, holdUp); + number.Settings.VoiceMail = Update.IfNotEmptyAndNotEquals(number.Settings.VoiceMail, voiceMail); + number.Settings.WorkingHours = Update.IfNotEmptyAndNotEquals(number.Settings.WorkingHours, workingHours); + + if (!string.IsNullOrEmpty(wait)) + { + number.Settings.Queue.WaitUrl = wait; + } + + if (allowOutgoingCalls.HasValue) + { + number.Settings.AllowOutgoingCalls = allowOutgoingCalls.Value; + if (!number.Settings.AllowOutgoingCalls) + { + number.Settings.Operators.ForEach(r => r.AllowOutgoingCalls = false); + } + } + + if (record.HasValue) + { + number.Settings.Record = record.Value; + if (!number.Settings.Record) + { + number.Settings.Operators.ForEach(r => r.Record = false); + } + } + + dao.SaveOrUpdateNumber(number); + + return number; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Update(@"voip/numbers/settings")] + public object UpdateSettings(Queue queue, bool pause) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.GetVoipDao(); + var numbers = dao.GetNumbers(); + + if (queue != null) + { + foreach (var number in numbers) + { + if (number.Settings.Queue == null || string.IsNullOrEmpty(number.Settings.Queue.Id)) + { + var phone = number as TwilioPhone; + if (phone != null) + { + queue = phone.CreateQueue(phone.Number, queue.Size, queue.WaitUrl, queue.WaitTime * 60); + } + + queue.Name = number.Number; + number.Settings.Queue = queue; + } + else + { + var oldQueue = number.Settings.Queue; + oldQueue.Size = Update.IfNotEmptyAndNotEquals(oldQueue.Size, queue.Size); + oldQueue.WaitTime = Update.IfNotEmptyAndNotEquals(oldQueue.WaitTime, queue.WaitTime * 60); + oldQueue.WaitUrl = Update.IfNotEmptyAndNotEquals(oldQueue.WaitUrl, queue.WaitUrl); + } + + number.Settings.Pause = pause; + + dao.SaveOrUpdateNumber(number); + } + } + + return new { queue, pause }; + } + + /// + /// + /// + /// + /// Voip + /// + /// + + [Read(@"voip/numbers/settings")] + public object GetVoipSettings() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.GetVoipDao(); + var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null); + if (number != null) + { + return new { queue = number.Settings.Queue, pause = number.Settings.Pause }; + } + + var files = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true); + var file = files.FirstOrDefault(); + return new { queue = new Queue(null, "Default", 5, file != null ? CommonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false }; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/uploads")] + public IEnumerable GetUploadedFilesUri() + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var result = new List(); + + foreach (var audioType in Enum.GetNames(typeof(AudioType))) + { + var type = (AudioType)Enum.Parse(typeof(AudioType), audioType); + + var path = audioType.ToLower(); + var store = Global.GetStore(); + var filePaths = store.ListFilesRelative("voip", path, "*", true); + result.AddRange( + filePaths.Select(filePath => + GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type))); + + path = "default/" + audioType.ToLower(); + store = StorageFactory.GetStorage("", "crm"); + filePaths = store.ListFilesRelative("voip", path, "*.*", true); + result.AddRange( + filePaths.Select(filePath => + GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type, true))); + } + + return result; + } + + private VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false) + { + return new VoipUpload + { + Path = CommonLinkUtility.GetFullAbsolutePath(link.ToString()), + Name = fileName, + AudioType = audioType, + IsDefault = isDefault + }; + } + + /// + /// + /// + /// + /// Voip + /// + /// + /// + [Delete(@"voip/uploads")] + public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var store = Global.GetStore(); + var path = Path.Combine(audioType.ToString().ToLower(), fileName); + var result = new VoipUpload + { + AudioType = audioType, + Name = fileName, + Path = CommonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString()) + }; + + if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); + store.Delete("voip", path); + + var dao = DaoFactory.GetVoipDao(); + var numbers = dao.GetNumbers(); + + var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); + if (defAudio == null) return result; + + foreach (var number in numbers) + { + switch (audioType) + { + case AudioType.Greeting: + if (number.Settings.GreetingAudio == result.Path) + { + number.Settings.GreetingAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + case AudioType.HoldUp: + if (number.Settings.HoldAudio == result.Path) + { + number.Settings.HoldAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + case AudioType.Queue: + var queue = number.Settings.Queue; + if (queue != null && queue.WaitUrl == result.Path) + { + queue.WaitUrl = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + case AudioType.VoiceMail: + if (number.Settings.VoiceMail == result.Path) + { + number.Settings.VoiceMail = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + } + break; + } + + dao.SaveOrUpdateNumber(number); + } + + return result; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Read(@"voip/numbers/{numberId:regex(\w+)}/oper")] + public IEnumerable GetOperators(string numberId) + { + return DaoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id); + } + + /// + /// + /// + /// + /// Voip + /// + /// + /// + [Update(@"voip/numbers/{numberId:regex(\w+)}/oper")] + public IEnumerable AddOperators(string numberId, IEnumerable operators) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + if (DaoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) + { + throw new ArgumentException("Duplicate", "operators"); + } + + var dao = DaoFactory.GetVoipDao(); + var phone = dao.GetNumber(numberId); + var lastOper = phone.Settings.Operators.LastOrDefault(); + var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100; + + var addedOperators = operators.Select(o => new Agent(o, AnswerType.Client, phone, (startOperId++).ToString(CultureInfo.InvariantCulture))).ToList(); + phone.Settings.Operators.AddRange(addedOperators); + + dao.SaveOrUpdateNumber(phone); + return addedOperators; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Delete(@"voip/numbers/{numberId:regex(\w+)}/oper")] + public Guid DeleteOperator(string numberId, Guid oper) + { + if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.GetVoipDao(); + var phone = dao.GetNumber(numberId); + var startOperId = 100; + + phone.Settings.Operators.RemoveAll(r => r.Id == oper); + phone.Settings.Operators.ToList() + .ForEach(r => + { + r.PhoneNumber = phone.Number; + r.PostFix = startOperId.ToString(CultureInfo.InvariantCulture); + startOperId++; + }); + + dao.SaveOrUpdateNumber(phone); + return oper; + } + + /// + /// + /// + /// + /// Voip + /// + /// + [Update(@"voip/opers/{operatorId}")] + public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber) + { + if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + + var dao = DaoFactory.GetVoipDao(); + var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); + + var oper = phone.Settings.Operators.Find(r => r.Id == operatorId); + + if (status.HasValue) + { + oper.Status = status.Value; + } + + if (allowOutgoingCalls.HasValue) + { + oper.AllowOutgoingCalls = phone.Settings.AllowOutgoingCalls && allowOutgoingCalls.Value; + } + + if (record.HasValue) + { + oper.Record = phone.Settings.Record && record.Value; + } + + if (answerType.HasValue) + { + oper.Answer = answerType.Value; + } + + if (!string.IsNullOrEmpty(redirectToNumber)) + { + oper.RedirectToNumber = redirectToNumber; + } + + dao.SaveOrUpdateNumber(phone); + + if (allowOutgoingCalls.HasValue) + { + new SignalRHelper(phone.Number, SignalrServiceClient).Reload(operatorId.ToString()); + } + + return oper; + } + + + /// + /// + /// + /// + /// Voip + /// + /// + [Create(@"voip/call")] + public VoipCallDto MakeCall(string to, string contactId) + { + var number = DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); + + if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); + + var contactPhone = to.TrimStart('+'); + + ContactDto contact; + + if (String.IsNullOrEmpty(contactId)) + { + var ids = DaoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone, null, null); + + contact = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => ContactDtoHelper.GetContactDto(x)).FirstOrDefault(); + + } + else + { + contact = ContactDtoHelper.GetContactDto(DaoFactory.GetContactDao().GetByID(Convert.ToInt32(contactId))); + } + + if (contact == null) + { + contact = ContactDtoHelper.GetContactDto(VoipEngine.CreateContact(contactPhone)); + } + + contact = GetContactWithFotos(contact); + + var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); + + return VoipCallDtoHelper.Get(call, contact); + + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:regex(\w+)}/answer")] + public VoipCallDto AnswerCall(string callId) + { + var dao = DaoFactory.GetVoipDao(); + var call = dao.GetCall(callId).NotFoundIfNull(); + var number = dao.GetCurrentNumber().NotFoundIfNull(); + + number.AnswerQueueCall(call.Id); + + return VoipCallDtoHelper.Get(call); + + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:regex(\w+)}/reject")] + public VoipCallDto RejectCall(string callId) + { + var dao = DaoFactory.GetVoipDao(); + var call = dao.GetCall(callId).NotFoundIfNull(); + var number = dao.GetCurrentNumber().NotFoundIfNull(); + + number.RejectQueueCall(call.Id); + + return VoipCallDtoHelper.Get(call); + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:regex(\w+)}/redirect")] + public VoipCallDto ReditectCall(string callId, string to) + { + var dao = DaoFactory.GetVoipDao(); + var call = dao.GetCall(callId).NotFoundIfNull(); + var number = dao.GetCurrentNumber().NotFoundIfNull(); + + if (call.ContactId != 0) + { + var contact = DaoFactory.GetContactDao().GetByID(call.ContactId); + var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact); + + if (!managers.Contains(Guid.Parse(to))) + { + managers.Add(Guid.Parse(to)); + CRMSecurity.SetAccessTo(contact, managers); + } + } + + number.RedirectCall(call.Id, to); + return VoipCallDtoHelper.Get(call); + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/call/{callId:regex(\w+)}")] + public VoipCallDto SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) + { + var dao = DaoFactory.GetVoipDao(); + + var call = dao.GetCall(callId) ?? new VoipCall(); + + call.Id = callId; + call.From = Update.IfNotEmptyAndNotEquals(call.From, from); + call.To = Update.IfNotEmptyAndNotEquals(call.To, to); + call.AnsweredBy = Update.IfNotEmptyAndNotEquals(call.AnsweredBy, answeredBy); + + try + { + if (call.ContactId == 0) + { + var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; + if (!string.IsNullOrEmpty(contactId)) + { + call.ContactId = Convert.ToInt32(contactId); + } + else + { + VoipEngine.GetContact(call); + } + + if (call.ContactId == 0) + { + contactPhone = contactPhone.TrimStart('+'); + + var peopleInst = new Person + { + FirstName = contactPhone, + LastName = TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), + ShareType = ShareType.None + }; + + peopleInst.ID = DaoFactory.GetContactDao().SaveContact(peopleInst); + + CRMSecurity.SetAccessTo(peopleInst, new List { SecurityContext.CurrentAccount.ID }); + + var person = (PersonDto)ContactDtoHelper.GetContactDto(peopleInst); + + DaoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); + + call.ContactId = person.Id; + } + } + } + catch (Exception) + { + + } + + if (status.HasValue) + { + call.Status = status.Value; + } + + if (call.Price == 0 && price.HasValue) + { + call.Price = price.Value; + } + + call = dao.SaveOrUpdateCall(call); + + if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); + + try + { + var contact = ContactDtoHelper.GetContactDto(DaoFactory.GetContactDao().GetByID(call.ContactId)); + contact = GetContactWithFotos(contact); + + return VoipCallDtoHelper.Get(call, contact); + } + catch (Exception) + { + return VoipCallDtoHelper.Get(call); + } + + } + + /// + /// + /// + /// + /// Voip + /// + [Create(@"voip/price/{callId:regex(\w+)}")] + public void SavePrice(string callId) + { + VoipEngine.SaveAdditionalInfo(callId); + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/call")] + public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) + { + var voipDao = DaoFactory.GetVoipDao(); + + var filter = new VoipCallFilter + { + Type = callType, + FromDate = from != null ? from.UtcTime : (DateTime?)null, + ToDate = to != null ? to.UtcTime.AddDays(1).AddMilliseconds(-1) : (DateTime?)null, + Agent = agent, + Client = client, + ContactID = contactID, + SortBy = ApiContext.SortBy, + SortOrder = !ApiContext.SortDescending, + SearchText = ApiContext.FilterValue, + Offset = ApiContext.StartIndex, + Max = ApiContext.Count, + }; + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + ApiContext.TotalCount = voipDao.GetCallsCount(filter); + + var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); + var calls = voipDao.GetCalls(filter).Select( + r => + { + ContactDto contact; + + if (r.ContactId != 0) + { + contact = r.ContactIsCompany + ? (ContactDto)new CompanyDto() { DisplayName = r.ContactTitle, Id = r.ContactId } + : new PersonDto() + { + DisplayName = r.ContactTitle, + Id = r.ContactId + }; + + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + + } + else + { + contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; + } + + return VoipCallDtoHelper.Get(r, contact); + + }).ToList(); + + return calls; + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/call/missed")] + public IEnumerable GetMissedCalls() + { + var voipDao = DaoFactory.GetVoipDao(); + var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); + + var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( + r => + { + ContactDto contact; + + if (r.ContactId != 0) + { + contact = r.ContactIsCompany + ? (ContactDto)new CompanyDto() { DisplayName = r.ContactTitle, Id = r.ContactId } + : new PersonDto() { DisplayName = r.ContactTitle, Id = r.ContactId }; + + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + + } + else + { + contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; + } + + return VoipCallDtoHelper.Get(r, contact); + + }).ToList(); + + ApiContext.SetDataPaginated(); + ApiContext.SetDataFiltered(); + ApiContext.SetDataSorted(); + ApiContext.TotalCount = calls.Count; + + return calls; + } + + /// + /// + /// + /// + /// Voip + /// + [Read(@"voip/call/{callId:regex(\w+)}")] + public VoipCallDto GetCall(string callId) + { + var call = DaoFactory.GetVoipDao().GetCall(callId); + + VoipEngine.GetContact(call); + + if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); + + var contact = ContactDtoHelper.GetContactDto(DaoFactory.GetContactDao().GetByID(call.ContactId)); + + contact = GetContactWithFotos(contact); + + return VoipCallDtoHelper.Get(call, contact); + } + + private ContactDto GetContactWithFotos(ContactDto contact) + { + contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); + + return contact; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ContactDto.cs index 2dbb899350f..d14b0682aef 100644 --- a/products/ASC.CRM/Server/ApiModels/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ContactDto.cs @@ -278,14 +278,9 @@ public ContactBaseDto() } - [DataMember(Name = "id")] public int Id { get; set; } - - public String SmallFotoUrl { get; set; } - - public String MediumFotoUrl { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] @@ -293,8 +288,6 @@ public ContactBaseDto() [DataMember(IsRequired = false, EmitDefaultValue = true)] public bool IsCompany { get; set; } - - public IEnumerable AccessList { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] diff --git a/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs index 04d267800d2..9cc02cdd47c 100644 --- a/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs +++ b/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs @@ -59,48 +59,24 @@ public OpportunityDto() public ContactBaseDto Contact { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] - public String Title { get; set; } - - - public String Description { get; set; } - - - public EmployeeWraper Responsible { get; set; } - - - public BidType BidType { get; set; } - - - public decimal BidValue { get; set; } - - - public CurrencyInfoDto BidCurrency { get; set; } - - - public int PerPeriodValue { get; set; } - - - public DealMilestoneBaseDto Stage { get; set; } - - - public int SuccessProbability { get; set; } - - - public ApiDateTime ActualCloseDate { get; set; } - - + public String Title { get; set; } + public String Description { get; set; } + public EmployeeWraper Responsible { get; set; } + public BidType BidType { get; set; } + public decimal BidValue { get; set; } + public CurrencyInfoDto BidCurrency { get; set; } + public int PerPeriodValue { get; set; } + public DealMilestoneBaseDto Stage { get; set; } + public int SuccessProbability { get; set; } + public ApiDateTime ActualCloseDate { get; set; } public ApiDateTime ExpectedCloseDate { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsPrivate { get; set; } - - + public bool IsPrivate { get; set; } public IEnumerable AccessList { get; set; } [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - - + public bool CanEdit { get; set; } public IEnumerable CustomFields { get; set; } public static OpportunityDto GetSample() diff --git a/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs b/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs index a4d8fbc5494..4b506f1744f 100644 --- a/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs @@ -10,7 +10,7 @@ public class SendMailSMTPToContactsInDto public List FileIDs { get; set; } public List ContactIds { get; set; } public String Subject { get; set; } - public String body { get; set; } + public String Body { get; set; } public bool StoreInHistory { get; set; } } } diff --git a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs index d9241123bd4..c6811fcbb9c 100644 --- a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs @@ -17,7 +17,7 @@ public class SetAccessToBatchCasesByFilterInDto public class SetAccessToBatchCasesInDto { - public IEnumerable Casesid { get; set; } + public IEnumerable CasesId { get; set; } public bool isPrivate { get; set; } public IEnumerable AccessList { get; set; } } diff --git a/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs b/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs index 5d2cb245d81..65dd47c03b2 100644 --- a/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs +++ b/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs @@ -28,6 +28,7 @@ using ASC.Common; using ASC.VoipService; using ASC.Web.Api.Models; + using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; @@ -37,40 +38,17 @@ namespace ASC.CRM.ApiModels [DataContract(Name = "voipCall", Namespace = "")] public class VoipCallDto { - [DataMember(Order = 1)] public string Id { get; set; } - - [DataMember(Order = 2)] public string From { get; set; } - - [DataMember(Order = 3)] public string To { get; set; } - - [DataMember(Order = 4)] public VoipCallStatus? Status { get; set; } - - [DataMember(Order = 5)] public EmployeeWraper AnsweredBy { get; set; } - - [DataMember(Order = 6)] public ApiDateTime DialDate { get; set; } - - [DataMember(Order = 7)] public int DialDuration { get; set; } - - [DataMember(Order = 10)] public decimal Cost { get; set; } - - [DataMember(Order = 11)] public ContactDto Contact { get; set; } - - [DataMember(Order = 11, EmitDefaultValue = false)] public IEnumerable Calls { get; set; } - - [DataMember(Order = 13)] public string RecordUrl { get; set; } - - [DataMember(Order = 14)] public int RecordDuration { get; set; } } @@ -87,7 +65,6 @@ public VoipCallDtoHelper(EmployeeWraperHelper employeeWraper, public ApiDateTimeHelper ApiDateTimeHelper { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - public VoipCallDto Get(VoipCall call, ContactDto contact = null) { var result = new VoipCallDto @@ -97,7 +74,7 @@ public VoipCallDto Get(VoipCall call, ContactDto contact = null) To = call.To, Status = call.Status, AnsweredBy = EmployeeWraperHelper.Get(call.AnsweredBy), - DialDate = ApiDateTimeHelper.Get(call.DialDate), + DialDate = ApiDateTimeHelper.Get(call.DialDate), DialDuration = call.DialDuration, Cost = call.Price + call.ChildCalls.Sum(r => r.Price) + call.VoipRecord.Price, Contact = contact, diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index e419fc89b17..01b51d2f6e1 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -76,32 +76,19 @@ public ProductEntryPoint(SecurityContext securityContext, private static bool registered; public FileSecurityProvider FileSecurityProvider { get; } - - public CoreConfiguration CoreConfiguration { get; } - public ILog Logger { get; } - - public SettingsManager SettingsManager { get; } - - + public SettingsManager SettingsManager { get; } public FilesIntegration FilesIntegration { get; } - public DaoFactory DaoFactory { get; } - public PathProvider PathProvider { get; } - - public SecurityContext SecurityContext { get; } - + public SecurityContext SecurityContext { get; } public UserManager UserManager { get; } // TODO: CRM: Реализовать проперти ApiURL public override string ApiURL => throw new NotImplementedException(); - public override Guid ProductID { get { return ID; } } - public override string Name { get { return CRMCommonResource.ProductName; } } - public override string Description { get @@ -116,15 +103,10 @@ public override string Description } public override string StartURL { get { return PathProvider.StartURL(); } } - public override string HelpURL { get { return string.Concat(PathProvider.BaseVirtualPath, "help.aspx"); } } - public override string ProductClassName { get { return "crm"; } } - public override bool Visible { get { return true; } } - public override ProductContext Context { get { return context; } } - public string ModuleSysName { get; set; } public override void Init() diff --git a/products/ASC.CRM/Server/Configuration/SearchHandler.cs b/products/ASC.CRM/Server/Configuration/SearchHandler.cs deleted file mode 100644 index 7f154d780a6..00000000000 --- a/products/ASC.CRM/Server/Configuration/SearchHandler.cs +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Web.Core.ModuleManagement.Common; -using ASC.Web.Core.Utility.Skins; -using ASC.Web.CRM.Core; -using Autofac; -using System; - -namespace ASC.Web.CRM.Configuration -{ - public class SearchHandler : BaseSearchHandlerEx - { - public override Guid ProductID - { - get { return ProductEntryPoint.ID; } - } - - public override Guid ModuleID - { - get { return ProductID; } - } - - public override ImageOptions Logo - { - get { return new ImageOptions { ImageFileName = "search_in_module.png", PartID = ProductID }; } - } - - public override string SearchName - { - get { return CRMContactResource.Search; } - } - - public override IItemControl Control - { - get { return new ResultsView(); } - } - - public override SearchResultItem[] Search(string searchText) - { - using (var scope = DIHelper.Resolve()) - { - return scope.Resolve().SearchDao.Search(searchText); - } - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index b83b1899ade..263f37afdc8 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -54,6 +54,24 @@ public static IHostBuilder CreateHostBuilder(string[] args) { builder.Register(context.Configuration, context.HostingEnvironment.ContentRootPath, false, false); }); + + + //if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) + //{ + // FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider()); + //} + + ////Register prodjects' calendar events + //CalendarManager.Instance.RegistryCalendarProvider(userid => + //{ + // if (WebItemSecurity.IsAvailableForUser(WebItemManager.CRMProductID, userid)) + // { + // return new List { new CRMCalendar(userid) }; + // } + // return new List(); + //}); + + } } } diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 9ececa0ce11..7793075b76b 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -38,10 +38,12 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); + DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); + DIHelper.TryAdd(); } public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) From 19b9067d65b454fb21dc717cb869260c41119ae8 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 17 Mar 2021 14:50:13 +0300 Subject: [PATCH 24/61] crm: refactoring --- products/ASC.CRM/Server/ASC.CRM.csproj | 3 +- .../ASC.CRM/Server/Api/CasesController.cs | 41 +- .../ASC.CRM/Server/Api/ContactsController.cs | 28 +- .../ASC.CRM/Server/Api/DealsController.cs | 8 +- .../ASC.CRM/Server/Api/InvoicesController.cs | 96 +-- .../ASC.CRM/Server/Api/TasksController.cs | 98 +-- products/ASC.CRM/Server/ApiModels/CasesDto.cs | 147 ----- .../ASC.CRM/Server/ApiModels/InvoiceDto.cs | 623 ------------------ .../CreateOrUpdateCasesRequestDto.cs} | 2 +- .../CreateOrUpdateDealRequestDto.cs} | 2 +- .../CreateOrUpdateInvoiceItemRequestDto.cs} | 2 +- .../CreateOrUpdateInvoiceLineRequestDto.cs} | 2 +- .../CreateOrUpdateInvoiceRequestDto.cs} | 2 +- .../CreateOrUpdateInvoiceTaxRequestDto.cs} | 2 +- .../CreateOrUpdatePersonRequestDto.cs} | 10 +- .../SaveNumberSettingsRequestDto.cs} | 2 +- .../SendMailSMTPToContactsRequestDto.cs} | 2 +- .../SetAccessToBatchCasesRequestDto.cs} | 2 +- .../SetAccessToBatchContactRequestDto.cs} | 4 +- ...SetAccessToBatchDealByFilterRequestDto.cs} | 4 +- .../Server/ApiModels/ResponsesDto/CasesDto.cs | 80 +++ .../ApiModels/ResponsesDto/ContactDto.cs | 311 +++++++++ .../{ => ResponsesDto}/ContactInfoDto.cs | 24 - .../{ => ResponsesDto}/CurrencyInfoDto.cs | 57 +- .../{ => ResponsesDto}/CurrencyRateDto.cs | 19 - .../{ => ResponsesDto}/CustomFieldDto.cs | 0 .../ApiModels/ResponsesDto/InvoiceDto.cs | 99 +++ .../ResponsesDto/InvoiceDtoHelper.cs | 130 ++++ .../ApiModels/ResponsesDto/InvoiceItemDto.cs | 62 ++ .../ApiModels/ResponsesDto/InvoiceLineDto.cs | 61 ++ .../ResponsesDto/InvoiceStatusDto.cs | 51 ++ .../ApiModels/ResponsesDto/InvoiceTaxDto.cs | 72 ++ .../{ => ResponsesDto}/ListItemDto.cs | 43 +- .../ApiModels/ResponsesDto/OpportunityDto.cs | 94 +++ .../RelationshipEventDto.cs | 0 .../ApiModels/{ => ResponsesDto}/ReportDto.cs | 0 .../ApiModels/{ => ResponsesDto}/TaskDto.cs | 98 +-- .../TaskTemplateContainerDto.cs | 6 +- .../ApiModels/ResponsesDto/VoipCallDto.cs | 54 ++ .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 6 + products/ASC.CRM/Server/Core/Dao/DealDao.cs | 41 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 58 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 199 +++--- products/ASC.CRM/Server/Core/EF/DbTask.cs | 2 +- .../Server/Core/Entities/CurrencyInfo.cs | 9 - products/ASC.CRM/Server/Core/Entities/Deal.cs | 11 +- .../Server/Core/Entities/InvoiceTax.cs | 9 +- products/ASC.CRM/Server/Core/Entities/Task.cs | 31 +- .../ContactDtoHelper.cs} | 310 +-------- .../Server/Helpers/ContactInfoDtoHelper.cs | 55 ++ .../Server/Helpers/CurrencyInfoDtoHelper.cs | 54 ++ .../Server/Helpers/CurrencyRateDtoHelper.cs | 49 ++ .../Helpers/CurrencyRateInfoDtoHelper.cs | 58 ++ .../Helpers/HistoryCategoryDtoHelper.cs | 52 ++ .../Server/Helpers/InvoiceBaseDtoHelper.cs | 123 ++++ .../Server/Helpers/InvoiceLineDtoHelper.cs | 55 ++ .../Server/Helpers/InvoiceStatusDtoHelper.cs | 48 ++ .../OpportunityDtoHelper.cs} | 79 +-- .../Server/Helpers/TaskCategoryDtoHelper.cs | 52 ++ .../VoipCallDtoHelper.cs} | 35 +- .../ASC.CRM/Server/Mapping/Common/IMapFrom.cs | 34 + .../Server/Mapping/Common/MappingProfile.cs | 60 ++ .../TypeConverter/CasesDtoTypeConverter.cs | 112 ++++ .../InvoiceItemDtoTypeConverter.cs | 109 +++ .../TypeConverter/InvoiceTaxTypeConverter.cs | 73 ++ .../TypeConverter/TaskDtoTypeConverter.cs | 125 ++++ products/ASC.CRM/Server/Startup.cs | 5 + 67 files changed, 2451 insertions(+), 1744 deletions(-) delete mode 100644 products/ASC.CRM/Server/ApiModels/CasesDto.cs delete mode 100644 products/ASC.CRM/Server/ApiModels/InvoiceDto.cs rename products/ASC.CRM/Server/ApiModels/{CreateOrUpdateCasesInDto.cs => RequestsDto/CreateOrUpdateCasesRequestDto.cs} (91%) rename products/ASC.CRM/Server/ApiModels/{CreateOrUpdateDealInDto.cs => RequestsDto/CreateOrUpdateDealRequestDto.cs} (95%) rename products/ASC.CRM/Server/ApiModels/{CreateOrUpdateInvoiceItemInDto.cs => RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs} (91%) rename products/ASC.CRM/Server/ApiModels/{CreateOrUpdateInvoiceLineInDto.cs => RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs} (91%) rename products/ASC.CRM/Server/ApiModels/{CreateOrUpdateInvoiceInDto.cs => RequestsDto/CreateOrUpdateInvoiceRequestDto.cs} (95%) rename products/ASC.CRM/Server/ApiModels/{CreateOrUpdateInvoiceTax.cs => RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs} (84%) rename products/ASC.CRM/Server/ApiModels/{CreateOrUpdatePersonInDto.cs => RequestsDto/CreateOrUpdatePersonRequestDto.cs} (79%) rename products/ASC.CRM/Server/ApiModels/{SaveNumberSettingsInDto.cs => RequestsDto/SaveNumberSettingsRequestDto.cs} (85%) rename products/ASC.CRM/Server/ApiModels/{SendMailSMTPToContactsInDto.cs => RequestsDto/SendMailSMTPToContactsRequestDto.cs} (88%) rename products/ASC.CRM/Server/ApiModels/{SetAccessToBatchCasesInDto.cs => RequestsDto/SetAccessToBatchCasesRequestDto.cs} (92%) rename products/ASC.CRM/Server/ApiModels/{SetAccessToBatchContactInDto.cs => RequestsDto/SetAccessToBatchContactRequestDto.cs} (88%) rename products/ASC.CRM/Server/ApiModels/{SetAccessToBatchDealByFilterInDto.cs => RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs} (89%) create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/ContactInfoDto.cs (90%) rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/CurrencyInfoDto.cs (64%) rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/CurrencyRateDto.cs (83%) rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/CustomFieldDto.cs (100%) create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/ListItemDto.cs (89%) create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/RelationshipEventDto.cs (100%) rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/ReportDto.cs (100%) rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/TaskDto.cs (57%) rename products/ASC.CRM/Server/ApiModels/{ => ResponsesDto}/TaskTemplateContainerDto.cs (95%) create mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs rename products/ASC.CRM/Server/{ApiModels/ContactDto.cs => Helpers/ContactDtoHelper.cs} (67%) create mode 100644 products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs create mode 100644 products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs create mode 100644 products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs create mode 100644 products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs create mode 100644 products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs create mode 100644 products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs create mode 100644 products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs create mode 100644 products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs rename products/ASC.CRM/Server/{ApiModels/OpportunityDto.cs => Helpers/OpportunityDtoHelper.cs} (65%) create mode 100644 products/ASC.CRM/Server/Helpers/TaskCategoryDtoHelper.cs rename products/ASC.CRM/Server/{ApiModels/VoipCallDto.cs => Helpers/VoipCallDtoHelper.cs} (70%) create mode 100644 products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs create mode 100644 products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 898593dadbc..cd10a82868b 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -33,8 +33,7 @@ - - + all diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index 3bc31c1f346..38d87e7eb64 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -47,11 +47,14 @@ using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Core.Users; using Microsoft.AspNetCore.Mvc; +using AutoMapper; namespace ASC.CRM.Api { public class CasesController : BaseApiController { + private IMapper _mapper; + public CasesController(CRMSecurity cRMSecurity, DaoFactory daoFactory, ApiContext apiContext, @@ -59,10 +62,10 @@ public CasesController(CRMSecurity cRMSecurity, MessageService messageService, NotifyClient notifyClient, ContactDtoHelper contactBaseDtoHelper, - CasesDtoHelper casesDtoHelper, SecurityContext securityContext, DisplayUserSettingsHelper displayUserSettingsHelper, - UserManager userManager) + UserManager userManager, + IMapper mapper) : base(daoFactory, cRMSecurity) { ApiContext = apiContext; @@ -70,15 +73,14 @@ public CasesController(CRMSecurity cRMSecurity, MessageService = messageService; NotifyClient = notifyClient; ContactDtoHelper = contactBaseDtoHelper; - CasesDtoHelper = casesDtoHelper; SecurityContext = securityContext; DisplayUserSettingsHelper = displayUserSettingsHelper; UserManager = userManager; + _mapper = mapper; } public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public SecurityContext SecurityContext { get; } - public CasesDtoHelper CasesDtoHelper { get; } public ContactDtoHelper ContactDtoHelper { get; } public NotifyClient NotifyClient { get; } private ApiContext ApiContext { get; } @@ -106,8 +108,9 @@ public CasesDto CloseCases([FromQuery] int caseid) if (cases == null) throw new ItemNotFoundException(); MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); + - return CasesDtoHelper.Get(cases); + return _mapper.Map(cases); } /// @@ -130,8 +133,8 @@ public CasesDto ReOpenCases([FromQuery] int caseid) if (cases == null) throw new ItemNotFoundException(); MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); - - return CasesDtoHelper.Get(cases); + + return _mapper.Map(cases); } /// @@ -161,7 +164,7 @@ public CasesDto ReOpenCases([FromQuery] int caseid) /// ]]> /// [Create(@"case")] - public CasesDto CreateCases([FromForm] CreateOrUpdateCasesInDto inDto) + public CasesDto CreateCases([FromForm] CreateOrUpdateCasesRequestDto inDto) { var title = inDto.Title; @@ -203,7 +206,9 @@ public CasesDto CreateCases([FromForm] CreateOrUpdateCasesInDto inDto) } } - return CasesDtoHelper.Get(DaoFactory.GetCasesDao().GetByID(casesID)); + var casesToResult = DaoFactory.GetCasesDao().GetByID(casesID); + + return _mapper.Map(casesToResult); } /// @@ -236,7 +241,7 @@ public CasesDto CreateCases([FromForm] CreateOrUpdateCasesInDto inDto) /// ]]> /// [Update(@"case/{caseid:int}")] - public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCasesInDto inDto) + public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCasesRequestDto inDto) { var title = inDto.Title; var isPrivate = inDto.isPrivate; @@ -277,7 +282,7 @@ public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCas } } - return CasesDtoHelper.Get(cases); + return _mapper.Map(cases); } /// @@ -338,7 +343,7 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable } } - return CasesDtoHelper.Get(cases); + return _mapper.Map(cases); } /// @@ -355,7 +360,7 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable /// Case list /// [Update(@"case/access")] - public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCasesInDto inDto) + public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCasesRequestDto inDto) { var casesid = inDto.CasesId; var isPrivate = inDto.isPrivate; @@ -439,7 +444,7 @@ public CasesDto GetCaseByID([FromQuery] int caseid) var cases = DaoFactory.GetCasesDao().GetByID(caseid); if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - return CasesDtoHelper.Get(cases); + return _mapper.Map(cases); } /// @@ -546,7 +551,7 @@ public CasesDto DeleteCase([FromQuery] int caseid) MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); - return CasesDtoHelper.Get(cases); + return _mapper.Map(cases); } /// @@ -705,7 +710,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) { if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) { - result.Add(CasesDtoHelper.Get(item)); + result.Add(_mapper.Map(item)); } } @@ -718,7 +723,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) foreach (var item in findedCases) { - result.Add(CasesDtoHelper.Get(item)); + result.Add(_mapper.Map(item)); } } @@ -753,7 +758,7 @@ private IEnumerable ToListCasesDtos(ICollection items) foreach (var cases in items) { - var casesDto = CasesDtoHelper.Get(cases); + var casesDto = _mapper.Map(cases); casesDto.CustomFields = customFields.ContainsKey(cases.ID) ? customFields[cases.ID] diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index 7534b63546c..799cc50fd3f 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -50,6 +50,8 @@ using Autofac; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -59,13 +61,15 @@ namespace ASC.CRM.Api { public class ContactsController : BaseApiController { + + private readonly IMapper _mapper; + public ContactsController(CRMSecurity cRMSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - TaskDtoHelper taskDtoHelper, ContactDtoHelper contactBaseDtoHelper, TaskCategoryDtoHelper taskCategoryDtoHelper, SecurityContext securityContext, @@ -76,14 +80,14 @@ public ContactsController(CRMSecurity cRMSecurity, ContactPhotoManager contactPhotoManager, FileSizeComment fileSizeComment, ContactInfoDtoHelper contactInfoDtoHelper, - MailSender mailSender) + MailSender mailSender, + IMapper mapper) : base(daoFactory, cRMSecurity) { ApiContext = apiContext; MessageTarget = messageTarget; MessageService = messageService; NotifyClient = notifyClient; - TaskDtoHelper = taskDtoHelper; ContactDtoHelper = contactBaseDtoHelper; TaskCategoryDtoHelper = taskCategoryDtoHelper; SecurityContext = securityContext; @@ -95,6 +99,7 @@ public ContactsController(CRMSecurity cRMSecurity, FileSizeComment = fileSizeComment; ContactInfoDtoHelper = contactInfoDtoHelper; MailSender = mailSender; + _mapper = mapper; } public MailSender MailSender { get; } @@ -107,7 +112,6 @@ public ContactsController(CRMSecurity cRMSecurity, public SecurityContext SecurityContext { get; } public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } public ContactDtoHelper ContactDtoHelper { get; } - public TaskDtoHelper TaskDtoHelper { get; } public NotifyClient NotifyClient { get; } private ApiContext ApiContext { get; } public MessageService MessageService { get; } @@ -745,7 +749,7 @@ public PersonDto DeletePeopleFromCompany(int companyid, int personid) /// Person /// [Create(@"contact/person")] - public PersonDto CreatePerson([FromForm] CreateOrUpdatePersonInDto intDto) + public PersonDto CreatePerson([FromForm] CreateOrUpdatePersonRequestDto intDto) { string firstName = intDto.FirstName; string lastName = intDto.LastName; @@ -922,7 +926,7 @@ public ContactDto MergeContacts(int fromcontactid, int tocontactid) /// /// [Update(@"contact/person/{personid:int}")] - public PersonDto UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdatePersonInDto inDto) + public PersonDto UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdatePersonRequestDto inDto) { string firstName = inDto.FirstName; string lastName = inDto.LastName; @@ -996,7 +1000,7 @@ public PersonDto UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdat /// Company /// [Create(@"contact/company")] - public CompanyDto CreateCompany([FromForm] CreateOrUpdateCompanyInDto inDto) + public CompanyDto CreateCompany([FromForm] CreateOrUpdateCompanyRequestDto inDto) { var personList = inDto.PersonList; string companyName = inDto.CompanyName; @@ -1172,7 +1176,7 @@ public IEnumerable CreatePerson(IEnumerable [Update(@"contact/access")] public IEnumerable SetAccessToBatchContact( - [FromBody] SetAccessToBatchContactInDto inDto) + [FromBody] SetAccessToBatchContactRequestDto inDto) { var contactid = inDto.ContactID; var isShared = inDto.isShared; @@ -1511,7 +1515,7 @@ public IEnumerable SetAccessToBatchContact( /// [Update(@"contact/filter/access")] public IEnumerable SetAccessToBatchContact( - [FromForm] SetAccessToBatchContactByFilterInDto inDto) + [FromForm] SetAccessToBatchContactByFilterRequestDto inDto) { IEnumerable tags = inDto.Tags; int? contactStage = inDto.ContactStage; @@ -1894,7 +1898,7 @@ public string DeleteContactAvatar(int contactId, string contactType, bool upload /// false [Create(@"contact/mailsmtp/send")] public IProgressItem SendMailSMTPToContacts( - SendMailSMTPToContactsInDto inDto) + SendMailSMTPToContactsRequestDto inDto) { List fileIDs = inDto.FileIDs; List contactIds = inDto.ContactIds; @@ -2114,7 +2118,7 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList(task); if (task.CategoryID > 0) { diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index 66dab22d0bc..436fa491768 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -230,7 +230,7 @@ private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable [Update(@"opportunity/filter/access")] - public IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBatchDealByFilterInDto inDto) + public IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBatchDealByFilterRequestDto inDto) { var responsibleid = inDto.Responsibleid; var opportunityStagesid = inDto.OpportunityStagesid; @@ -286,7 +286,7 @@ public IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBa /// Opportunity list /// [Update(@"opportunity/access")] - public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealInDto inDto) + public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealRequestDto inDto) { var opportunityid = inDto.Opportunityid; var isPrivate = inDto.isPrivate; @@ -546,7 +546,7 @@ public OpportunityDto DeleteDeal(int opportunityid) /// /// [Create(@"opportunity")] - public OpportunityDto CreateDeal(CreateOrUpdateDealInDto inDto) + public OpportunityDto CreateDeal(CreateOrUpdateDealRequestDto inDto) { var title = inDto.Title; @@ -646,7 +646,7 @@ public OpportunityDto CreateDeal(CreateOrUpdateDealInDto inDto) /// [Update(@"opportunity/{opportunityid:int}")] public OpportunityDto UpdateDeal( - int opportunityid, CreateOrUpdateDealInDto inDto) + int opportunityid, CreateOrUpdateDealRequestDto inDto) { var title = inDto.Title; diff --git a/products/ASC.CRM/Server/Api/InvoicesController.cs b/products/ASC.CRM/Server/Api/InvoicesController.cs index 5b2cdf5c7d7..1e60741bafc 100644 --- a/products/ASC.CRM/Server/Api/InvoicesController.cs +++ b/products/ASC.CRM/Server/Api/InvoicesController.cs @@ -24,36 +24,35 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Api.Core; -using ASC.CRM.ApiModels; +using ASC.Api.CRM; using ASC.Api.Documents; using ASC.Common.Web; -using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.CRM.ApiModels; using ASC.CRM.Classes; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; - using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.CRM.Classes; -using Microsoft.AspNetCore.Mvc; +using AutoMapper; -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.Api.CRM; -using ASC.CRM.Core.Dao; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Web.Core.Users; -using ASC.Core.Common.Settings; +using Microsoft.AspNetCore.Mvc; namespace ASC.CRM.Api { public class InvoicesController : BaseApiController { + private readonly IMapper _mapper; public InvoicesController(CRMSecurity cRMSecurity, DaoFactory daoFactory, ApiContext apiContext, @@ -67,11 +66,10 @@ public InvoicesController(CRMSecurity cRMSecurity, PdfCreator pdfCreator, CurrencyInfoDtoHelper currencyInfoDtoHelper, InvoiceBaseDtoHelper invoiceBaseDtoHelper, - InvoiceItemDtoHelper invoiceItemDtoHelper, Global global, InvoiceLineDtoHelper invoiceLineDtoHelper, - InvoiceTaxDtoHelper invoiceTaxDtoHelper, - PdfQueueWorker pdfQueueWorker) + PdfQueueWorker pdfQueueWorker, + IMapper mapper) : base(daoFactory, cRMSecurity) { ApiContext = apiContext; @@ -85,18 +83,15 @@ public InvoicesController(CRMSecurity cRMSecurity, FileWrapperHelper = fileWrapperHelper; CurrencyInfoDtoHelper = currencyInfoDtoHelper; InvoiceBaseDtoHelper = invoiceBaseDtoHelper; - InvoiceItemDtoHelper = invoiceItemDtoHelper; Global = global; InvoiceLineDtoHelper = invoiceLineDtoHelper; - InvoiceTaxDtoHelper = invoiceTaxDtoHelper; PdfQueueWorker = pdfQueueWorker; + _mapper = mapper; } public PdfQueueWorker PdfQueueWorker { get; } - public InvoiceTaxDtoHelper InvoiceTaxDtoHelper { get; } public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } public Global Global { get; } - public InvoiceItemDtoHelper InvoiceItemDtoHelper { get; } public InvoiceBaseDtoHelper InvoiceBaseDtoHelper { get; } public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } public FileWrapperHelper FileWrapperHelper { get; } @@ -393,12 +388,16 @@ InvoiceStatus status if (item != null) { item.StockQuantity += line.Quantity; + DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); + var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); + if (oldItem != null) { invoiceItemsUpdated.Remove(oldItem); } + invoiceItemsUpdated.Add(item); } } @@ -410,7 +409,9 @@ InvoiceStatus status var listInvoiceBaseDtos = ToListInvoiceBaseDtos(updatedInvoices); - return new KeyValuePair, IEnumerable>(listInvoiceBaseDtos, invoiceItemsUpdated.ConvertAll(i => InvoiceItemDtoHelper.Get(i))); + return new KeyValuePair, IEnumerable>( + listInvoiceBaseDtos, + _mapper.Map, List>(invoiceItemsUpdated)); } /// @@ -426,6 +427,7 @@ public InvoiceBaseDto DeleteInvoice(int invoiceid) if (invoiceid <= 0) throw new ArgumentException(); var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); + if (invoice == null) throw new ItemNotFoundException(); MessageService.Send(MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); @@ -507,7 +509,7 @@ public IEnumerable DeleteBatchInvoices(IEnumerable invoicei /// [Create(@"invoice")] public InvoiceDto CreateInvoice( - CreateOrUpdateInvoiceInDto inDto + CreateOrUpdateInvoiceRequestDto inDto ) { string number = inDto.Number; @@ -679,7 +681,7 @@ private List CreateInvoiceLines(List invoiceLines, Inv [Update(@"invoice/{id:int}")] public InvoiceDto UpdateInvoice( int id, - CreateOrUpdateInvoiceInDto inDto) + CreateOrUpdateInvoiceRequestDto inDto) { ApiDateTime issueDate = inDto.IssueDate; @@ -932,27 +934,30 @@ public IEnumerable GetInvoiceItems(int status, bool? inventorySt if (invoiceOrderBy != null) { - result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( + var resultFromDao = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( searchString, status, inventoryStock, fromIndex, count, - invoiceOrderBy) - .ConvertAll(x => InvoiceItemDtoHelper.Get(x)); + invoiceOrderBy); + result = _mapper.Map, List>(resultFromDao); + ApiContext.SetDataPaginated(); ApiContext.SetDataFiltered(); ApiContext.SetDataSorted(); } else { - result = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( + var resultFromDao = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( searchString, status, inventoryStock, 0, 0, - null) - .ConvertAll(x => InvoiceItemDtoHelper.Get(x)); + null); + + result = _mapper.Map, List>(resultFromDao); + } int totalCount; @@ -989,7 +994,7 @@ public InvoiceItemDto GetInvoiceItemByID(int invoiceitemid) var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); if (invoiceItem == null) throw new ItemNotFoundException(); - return InvoiceItemDtoHelper.Get(invoiceItem); + return _mapper.Map(invoiceItem); } /// @@ -1009,7 +1014,7 @@ public InvoiceItemDto GetInvoiceItemByID(int invoiceitemid) /// InvoiceLine [Create(@"invoiceline")] public InvoiceLineDto CreateInvoiceLine( - CreateOrUpdateInvoiceLineInDto inDto + CreateOrUpdateInvoiceLineRequestDto inDto ) { int invoiceId = inDto.InvoiceId; @@ -1073,7 +1078,7 @@ CreateOrUpdateInvoiceLineInDto inDto [Update(@"invoiceline/{id:int}")] public InvoiceLineDto UpdateInvoiceLine( int id, - CreateOrUpdateInvoiceLineInDto inDto + CreateOrUpdateInvoiceLineRequestDto inDto ) { int invoiceId = inDto.InvoiceId; @@ -1165,7 +1170,7 @@ public int DeleteInvoiceLine(int id) /// InvoiceItem [Create(@"invoiceitem")] public InvoiceItemDto CreateInvoiceItem( - CreateOrUpdateInvoiceItemInDto inDto + CreateOrUpdateInvoiceItemRequestDto inDto ) { string title = inDto.Title; @@ -1201,7 +1206,7 @@ CreateOrUpdateInvoiceItemInDto inDto MessageService.Send(MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return InvoiceItemDtoHelper.Get(invoiceItem); + return _mapper.Map(invoiceItem); } /// @@ -1222,7 +1227,7 @@ CreateOrUpdateInvoiceItemInDto inDto /// InvoiceItem [Update(@"invoiceitem/{id:int}")] public InvoiceItemDto UpdateInvoiceItem(int id, - CreateOrUpdateInvoiceItemInDto inDto + CreateOrUpdateInvoiceItemRequestDto inDto ) { string title = inDto.Title; @@ -1260,7 +1265,7 @@ CreateOrUpdateInvoiceItemInDto inDto invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); MessageService.Send(MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return InvoiceItemDtoHelper.Get(invoiceItem); + return _mapper.Map(invoiceItem); } /// @@ -1285,7 +1290,7 @@ public InvoiceItemDto DeleteInvoiceItem(int id) MessageService.Send(MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); - return InvoiceItemDtoHelper.Get(invoiceItem); + return _mapper.Map(invoiceItem); } @@ -1308,9 +1313,10 @@ public IEnumerable DeleteBatchItems(IEnumerable ids) ids = ids.Distinct(); var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); + MessageService.Send(MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); - return items.ConvertAll(x => InvoiceItemDtoHelper.Get(x)); + return _mapper.Map, List>(items); } /// @@ -1322,7 +1328,9 @@ public IEnumerable DeleteBatchItems(IEnumerable ids) [Read(@"invoice/tax")] public IEnumerable GetInvoiceTaxes() { - return DaoFactory.GetInvoiceTaxDao().GetAll().ConvertAll(x => InvoiceTaxDtoHelper.Get(x)); + var responceFromDao = DaoFactory.GetInvoiceTaxDao().GetAll(); + + return _mapper.Map, List>(responceFromDao); } /// @@ -1336,7 +1344,7 @@ public IEnumerable GetInvoiceTaxes() /// InvoiceTax [Create(@"invoice/tax")] public InvoiceTaxDto CreateInvoiceTax( - [FromBody] CreateOrUpdateInvoiceTax inDto) + [FromBody] CreateOrUpdateInvoiceTaxRequestDto inDto) { string name = inDto.Name; string description = inDto.Description; @@ -1360,7 +1368,7 @@ public InvoiceTaxDto CreateInvoiceTax( invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); MessageService.Send(MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return InvoiceTaxDtoHelper.Get(invoiceTax); + return _mapper.Map(invoiceTax); } /// @@ -1376,7 +1384,7 @@ public InvoiceTaxDto CreateInvoiceTax( [Update(@"invoice/tax/{id:int}")] public InvoiceTaxDto UpdateInvoiceTax( int id, - CreateOrUpdateInvoiceTax inDto) + CreateOrUpdateInvoiceTaxRequestDto inDto) { string name = inDto.Name; string description = inDto.Description; @@ -1402,7 +1410,7 @@ public InvoiceTaxDto UpdateInvoiceTax( invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); MessageService.Send(MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return InvoiceTaxDtoHelper.Get(invoiceTax); + return _mapper.Map(invoiceTax); } /// @@ -1427,7 +1435,7 @@ public InvoiceTaxDto DeleteInvoiceTax(int id) MessageService.Send(MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); - return InvoiceTaxDtoHelper.Get(invoiceTax); + return _mapper.Map(invoiceTax); } /// @@ -1453,7 +1461,7 @@ public InvoiceSetting GetSettings() /// InvoiceSetting [Update(@"invoice/settings/name")] public InvoiceSetting SaveNumberSettings( - SaveNumberSettingsInDto inDto + SaveNumberSettingsRequestDto inDto ) { var autogenerated = inDto.AutoGenerated; diff --git a/products/ASC.CRM/Server/Api/TasksController.cs b/products/ASC.CRM/Server/Api/TasksController.cs index 311e52b88b8..4a198ba31db 100644 --- a/products/ASC.CRM/Server/Api/TasksController.cs +++ b/products/ASC.CRM/Server/Api/TasksController.cs @@ -16,37 +16,39 @@ using ASC.Web.Api.Routing; using ASC.Web.CRM.Services.NotifyService; +using AutoMapper; + namespace ASC.CRM.Api { public class TasksController: BaseApiController { + private readonly IMapper _mapper; + private readonly TaskCategoryDtoHelper _taskCategoryDtoHelper; + private readonly ContactDtoHelper _contactDtoHelper; + private readonly NotifyClient _notifyClient; + private readonly ApiContext _apiContext; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + public TasksController(CRMSecurity cRMSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - TaskDtoHelper taskDtoHelper, ContactDtoHelper contactBaseDtoHelper, - TaskCategoryDtoHelper taskCategoryDtoHelper) + TaskCategoryDtoHelper taskCategoryDtoHelper, + IMapper mapper) : base(daoFactory, cRMSecurity) { - ApiContext = apiContext; - MessageTarget = messageTarget; - MessageService = messageService; - NotifyClient = notifyClient; - TaskDtoHelper = taskDtoHelper; - ContactDtoHelper = contactBaseDtoHelper; - TaskCategoryDtoHelper = taskCategoryDtoHelper; + _apiContext = apiContext; + _messageTarget = messageTarget; + _messageService = messageService; + _notifyClient = notifyClient; + _contactDtoHelper = contactBaseDtoHelper; + _taskCategoryDtoHelper = taskCategoryDtoHelper; + _mapper = mapper; } - - public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } - public ContactDtoHelper ContactDtoHelper { get; } - public TaskDtoHelper TaskDtoHelper { get; } - public NotifyClient NotifyClient { get; } - private ApiContext ApiContext { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } /// /// Returns the detailed information about the task with the ID specified in the request @@ -70,7 +72,7 @@ public TaskDto GetTaskByID(int taskid) throw CRMSecurity.CreateSecurityException(); } - return TaskDtoHelper.GetTaskDto(task); + return _mapper.Map(task); } /// @@ -109,17 +111,17 @@ public IEnumerable GetAllTasks( ) throw new ArgumentException(); - var searchText = ApiContext.FilterValue; + var searchText = _apiContext.FilterValue; IEnumerable result; OrderBy taskOrderBy; - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out taskSortedByType)) + if (ASC.CRM.Classes.EnumExtension.TryParse(_apiContext.SortBy, true, out taskSortedByType)) { - taskOrderBy = new OrderBy(taskSortedByType, !ApiContext.SortDescending); + taskOrderBy = new OrderBy(taskSortedByType, !_apiContext.SortDescending); } - else if (string.IsNullOrEmpty(ApiContext.SortBy)) + else if (string.IsNullOrEmpty(_apiContext.SortBy)) { taskOrderBy = new OrderBy(TaskSortedByType.DeadLine, true); } @@ -128,8 +130,8 @@ public IEnumerable GetAllTasks( taskOrderBy = null; } - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; + var fromIndex = (int)_apiContext.StartIndex; + var count = (int)_apiContext.Count; if (taskOrderBy != null) { @@ -148,9 +150,9 @@ public IEnumerable GetAllTasks( count, taskOrderBy)).ToList(); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else result = ToTaskListDto( @@ -190,7 +192,7 @@ public IEnumerable GetAllTasks( entityid); } - ApiContext.SetTotalCount(totalCount); + _apiContext.SetTotalCount(totalCount); return result; } @@ -214,10 +216,9 @@ public TaskDto ReOpenTask(int taskid) var task = DaoFactory.GetTaskDao().GetByID(taskid); - MessageService.Send(MessageAction.CrmTaskOpened, MessageTarget.Create(task.ID), task.Title); - - return TaskDtoHelper.GetTaskDto(task); + _messageService.Send(MessageAction.CrmTaskOpened, _messageTarget.Create(task.ID), task.Title); + return _mapper.Map(task); } /// @@ -238,9 +239,9 @@ public TaskDto CloseTask(int taskid) DaoFactory.GetTaskDao().CloseTask(taskid); var task = DaoFactory.GetTaskDao().GetByID(taskid); - MessageService.Send(MessageAction.CrmTaskClosed, MessageTarget.Create(task.ID), task.Title); + _messageService.Send(MessageAction.CrmTaskClosed, _messageTarget.Create(task.ID), task.Title); - return TaskDtoHelper.GetTaskDto(task); + return _mapper.Map(task); } @@ -264,9 +265,9 @@ public TaskDto DeleteTask(int taskid) if (task == null) throw new ItemNotFoundException(); DaoFactory.GetTaskDao().DeleteTask(taskid); - MessageService.Send(MessageAction.CrmTaskDeleted, MessageTarget.Create(task.ID), task.Title); + _messageService.Send(MessageAction.CrmTaskDeleted, _messageTarget.Create(task.ID), task.Title); - return TaskDtoHelper.GetTaskDto(task); + return _mapper.Map(task); } @@ -352,12 +353,12 @@ int alertValue } } - NotifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null); + _notifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null); } - MessageService.Send(MessageAction.CrmTaskCreated, MessageTarget.Create(task.ID), task.Title); + _messageService.Send(MessageAction.CrmTaskCreated, _messageTarget.Create(task.ID), task.Title); - return TaskDtoHelper.GetTaskDto(task); + return _mapper.Map(task); } /// @@ -457,14 +458,14 @@ public IEnumerable CreateTaskGroup( } } - NotifyClient.SendAboutResponsibleByTask(tasks[i], taskCategory, taskContact, taskCase, taskDeal, null); + _notifyClient.SendAboutResponsibleByTask(tasks[i], taskCategory, taskContact, taskCase, taskDeal, null); } if (tasks.Any()) { var contacts = DaoFactory.GetContactDao().GetContacts(contactId); var task = tasks.First(); - MessageService.Send(MessageAction.ContactsCreatedCrmTasks, MessageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title); + _messageService.Send(MessageAction.ContactsCreatedCrmTasks, _messageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title); } return ToTaskListDto(tasks); @@ -552,12 +553,12 @@ public TaskDto UpdateTask( } } - NotifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null); + _notifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null); } - MessageService.Send(MessageAction.CrmTaskUpdated, MessageTarget.Create(task.ID), task.Title); + _messageService.Send(MessageAction.CrmTaskUpdated, _messageTarget.Create(task.ID), task.Title); - return TaskDtoHelper.GetTaskDto(task); + return _mapper.Map(task); } /// false @@ -668,13 +669,14 @@ private IEnumerable ToTaskListDto(IEnumerable itemList) } } - var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => TaskCategoryDtoHelper.Get(x)); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); - var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); + var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => _taskCategoryDtoHelper.Get(x)); + var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => _contactDtoHelper.GetContactBaseWithEmailDto(x)); + var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => _contactDtoHelper.GetContactBaseWithEmailDto(x)); foreach (var item in itemList) { - var taskDto = TaskDtoHelper.GetTaskDto(item); + var taskDto = _mapper.Map(item); + taskDto.CanEdit = CRMSecurity.CanEdit(item); if (contacts.ContainsKey(item.ContactID)) @@ -711,8 +713,6 @@ private IEnumerable ToTaskListDto(IEnumerable itemList) return result; } - - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/CasesDto.cs b/products/ASC.CRM/Server/ApiModels/CasesDto.cs deleted file mode 100644 index e1eef55285f..00000000000 --- a/products/ASC.CRM/Server/ApiModels/CasesDto.cs +++ /dev/null @@ -1,147 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Api.Core; -using ASC.Common; -using ASC.Core.Users; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.Web.Api.Models; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; - -namespace ASC.CRM.ApiModels -{ - [DataContract(Name = "case", Namespace = "")] - public class CasesDto - { - public CasesDto() - { - } - - - [DataMember(Name = "id")] - public int Id { get; set; } - public IEnumerable Members { get; set; } - public EmployeeWraper CreateBy { get; set; } - public ApiDateTime Created { get; set; } - public String Title { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsClosed { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsPrivate { get; set; } - public IEnumerable AccessList { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - public IEnumerable CustomFields { get; set; } - public static CasesDto GetSample() - { - return new CasesDto - { - IsClosed = false, - Title = "Exhibition organization", - Created = ApiDateTime.GetSample(), - CreateBy = EmployeeWraper.GetSample(), - IsPrivate = false, - CustomFields = new[] { CustomFieldBaseDto.GetSample() }, - CanEdit = true - }; - } - } - - [Scope] - public class CasesDtoHelper - { - public CasesDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - DaoFactory daoFactory, - ContactDtoHelper contactBaseDtoHelper) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - DaoFactory = daoFactory; - ContactBaseDtoHelper = contactBaseDtoHelper; - } - - public ContactDtoHelper ContactBaseDtoHelper { get; } - public DaoFactory DaoFactory { get; } - public CRMSecurity CRMSecurity { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public CasesDto Get(Cases cases) - { - var result = new CasesDto - { - Title = cases.Title, - IsClosed = cases.IsClosed, - IsPrivate = CRMSecurity.IsPrivate(cases), - Created = ApiDateTimeHelper.Get(cases.CreateOn), - CreateBy = EmployeeWraperHelper.Get(cases.CreateBy), - CanEdit = CRMSecurity.CanEdit(cases) - }; - - if (result.IsPrivate) - { - result.AccessList = CRMSecurity.GetAccessSubjectTo(cases) - .SkipWhile(item => item.Key == Constants.GroupEveryone.ID) - .Select(item => EmployeeWraperHelper.Get(item.Key)); - } - - result.CustomFields = DaoFactory - .GetCustomFieldDao() - .GetEnityFields(EntityType.Case, cases.ID, false) - .ConvertAll(item => new CustomFieldBaseDto(item)); - - result.Members = new List(); - - var memberIDs = DaoFactory.GetCasesDao().GetMembers(cases.ID); - var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); - - var membersDtoList = new List(); - - foreach (var member in membersList) - { - if (member == null) continue; - - membersDtoList.Add(ContactBaseDtoHelper.GetContactBaseDto(member)); - } - - result.Members = membersDtoList; - - return result; - } - } -} - - diff --git a/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs b/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs deleted file mode 100644 index 2c9204531aa..00000000000 --- a/products/ASC.CRM/Server/ApiModels/InvoiceDto.cs +++ /dev/null @@ -1,623 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - -using ASC.Api.Core; -using ASC.Common; -using ASC.Core.Common.Settings; -using ASC.CRM.Classes; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.Web.Api.Models; -using ASC.Web.CRM.Classes; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; - -namespace ASC.CRM.ApiModels -{ - - /// - /// Invoice - /// - [DataContract(Name = "invoiceBase", Namespace = "")] - public class InvoiceBaseDto - { - public InvoiceBaseDto() - { - - } - - [DataMember(Name = "id")] - public int Id { get; set; } - - - public InvoiceStatusDto Status { get; set; } - public string Number { get; set; } - public ApiDateTime IssueDate { get; set; } - public InvoiceTemplateType TemplateType { get; set; } - public ContactBaseWithEmailDto Contact { get; set; } - public ContactBaseWithEmailDto Consignee { get; set; } - public EntityDto Entity { get; set; } - public ApiDateTime DueDate { get; set; } - public string Language { get; set; } - public CurrencyInfoDto Currency { get; set; } - public decimal ExchangeRate { get; set; } - public string PurchaseOrderNumber { get; set; } - public string Terms { get; set; } - public string Description { get; set; } - public int FileID { get; set; } - public ApiDateTime CreateOn { get; set; } - public EmployeeWraper CreateBy { get; set; } - public decimal Cost { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanDelete { get; set; } - } - - [Scope] - public class InvoiceBaseDtoHelper - { - public InvoiceBaseDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - SettingsManager settingsManager, - CurrencyProvider currencyProvider, - InvoiceStatusDtoHelper invoiceStatusDtoHelper, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - DaoFactory daoFactory, - ContactDtoHelper contactDtoHelper, - EntityDtoHelper entityDtoHelper) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - SettingsManager = settingsManager; - CurrencyProvider = currencyProvider; - InvoiceStatusDtoHelper = invoiceStatusDtoHelper; - DaoFactory = daoFactory; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - ContactDtoHelper = contactDtoHelper; - EntityDtoHelper = entityDtoHelper; - } - - public EntityDtoHelper EntityDtoHelper { get; } - public ContactDtoHelper ContactDtoHelper { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public InvoiceStatusDtoHelper InvoiceStatusDtoHelper { get; } - public CurrencyProvider CurrencyProvider { get; } - public SettingsManager SettingsManager { get; } - public CRMSecurity CRMSecurity { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public DaoFactory DaoFactory { get; } - - public InvoiceBaseDto Get(Invoice invoice) - { - - var result = new InvoiceBaseDto - { - Id = invoice.ID, - Status = InvoiceStatusDtoHelper.Get(invoice.Status), - Number = invoice.Number, - IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), - TemplateType = invoice.TemplateType, - DueDate = ApiDateTimeHelper.Get(invoice.DueDate), - Currency = !String.IsNullOrEmpty(invoice.Currency) ? - CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoice.Currency)) : - CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), - ExchangeRate = invoice.ExchangeRate, - Language = invoice.Language, - PurchaseOrderNumber = invoice.PurchaseOrderNumber, - Terms = invoice.Terms, - Description = invoice.Description, - FileID = invoice.FileID, - CreateOn = ApiDateTimeHelper.Get(invoice.CreateOn), - CreateBy = EmployeeWraperHelper.Get(invoice.CreateBy), - CanEdit = CRMSecurity.CanEdit(invoice), - CanDelete = CRMSecurity.CanDelete(invoice) - }; - - if (invoice.ContactID > 0) - { - result.Contact = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); - } - - if (invoice.ConsigneeID > 0) - { - result.Consignee = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); - } - - if (invoice.EntityID > 0) - { - result.Entity = EntityDtoHelper.Get(invoice.EntityType, invoice.EntityID); - } - - result.Cost = invoice.GetInvoiceCost(DaoFactory); - - return result; - - } - } - - /// - /// Invoice - /// - [DataContract(Name = "invoice", Namespace = "")] - public class InvoiceDto : InvoiceBaseDto - { - public InvoiceDto() - { - } - - - public List InvoiceLines { get; set; } - - public static InvoiceDto GetSample() - { - return new InvoiceDto - { - Status = InvoiceStatusDto.GetSample(), - Number = string.Empty, - IssueDate = ApiDateTime.GetSample(), - TemplateType = InvoiceTemplateType.Eur, - Language = string.Empty, - DueDate = ApiDateTime.GetSample(), - Currency = CurrencyInfoDto.GetSample(), - ExchangeRate = (decimal)1.00, - PurchaseOrderNumber = string.Empty, - Terms = string.Empty, - Description = string.Empty, - FileID = -1, - CreateOn = ApiDateTime.GetSample(), - CreateBy = EmployeeWraper.GetSample(), - CanEdit = true, - CanDelete = true, - Cost = 0, - InvoiceLines = new List { InvoiceLineDto.GetSample() } - }; - } - } - - [Scope] - public class InvoiceDtoHelper - { - public InvoiceDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - SettingsManager settingsManager, - CurrencyProvider currencyProvider, - InvoiceStatusDtoHelper invoiceStatusDtoHelper, - InvoiceLineDtoHelper invoiceLineDtoHelper, - DaoFactory daoFactory, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, - ContactDtoHelper contactDtoHelper, - EntityDtoHelper entityDtoHelper) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - SettingsManager = settingsManager; - CurrencyProvider = currencyProvider; - InvoiceStatusDtoHelper = invoiceStatusDtoHelper; - DaoFactory = daoFactory; - InvoiceLineDtoHelper = invoiceLineDtoHelper; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; - ContactDtoHelper = contactDtoHelper; - EntityDtoHelper = entityDtoHelper; - } - - public ContactDtoHelper ContactDtoHelper { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } - public DaoFactory DaoFactory { get; } - public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } - public InvoiceStatusDtoHelper InvoiceStatusDtoHelper { get; } - public CurrencyProvider CurrencyProvider { get; } - public SettingsManager SettingsManager { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public CRMSecurity CRMSecurity { get; } - public EntityDtoHelper EntityDtoHelper { get; } - public InvoiceDto Get(Invoice invoice) - { - var result = new InvoiceDto - { - Id = invoice.ID, - Status = InvoiceStatusDtoHelper.Get(invoice.Status), - Number = invoice.Number, - IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), - TemplateType = invoice.TemplateType, - DueDate = ApiDateTimeHelper.Get(invoice.DueDate), - Currency = !String.IsNullOrEmpty(invoice.Currency) ? - CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoice.Currency)) : - CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), - ExchangeRate = invoice.ExchangeRate, - Language = invoice.Language, - PurchaseOrderNumber = invoice.PurchaseOrderNumber, - Terms = invoice.Terms, - Description = invoice.Description, - FileID = invoice.FileID, - CreateOn = ApiDateTimeHelper.Get(invoice.CreateOn), - CreateBy = EmployeeWraperHelper.Get(invoice.CreateBy), - CanEdit = CRMSecurity.CanEdit(invoice), - CanDelete = CRMSecurity.CanDelete(invoice), - }; - - if (invoice.ContactID > 0) - { - result.Contact = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); - } - - if (invoice.ConsigneeID > 0) - { - result.Consignee = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); - } - - if (invoice.EntityID > 0) - { - result.Entity = EntityDtoHelper.Get(invoice.EntityType, invoice.EntityID); - } - - result.Cost = invoice.GetInvoiceCost(DaoFactory); - - result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(x => InvoiceLineDtoHelper.Get(x)).ToList(); - - return result; - - } - } - - /// - /// Invoice Item - /// - [DataContract(Name = "invoiceItem", Namespace = "")] - public class InvoiceItemDto - { - public InvoiceItemDto() - { - } - - - public string Title { get; set; } - - - public string StockKeepingUnit { get; set; } - - - public string Description { get; set; } - - - public decimal Price { get; set; } - - - public CurrencyInfoDto Currency { get; set; } - - - public decimal StockQuantity { get; set; } - - - public bool TrackInvenory { get; set; } - - - public InvoiceTaxDto InvoiceTax1 { get; set; } - - - public InvoiceTaxDto InvoiceTax2 { get; set; } - - - public ApiDateTime CreateOn { get; set; } - - - public EmployeeWraper CreateBy { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanDelete { get; set; } - } - - [Scope] - public class InvoiceItemDtoHelper - { - public InvoiceItemDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - SettingsManager settingsManager, - CurrencyProvider currencyProvider, - DaoFactory daoFactory, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - InvoiceTaxDtoHelper invoiceTaxDtoHelper) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - SettingsManager = settingsManager; - CurrencyProvider = currencyProvider; - DaoFactory = daoFactory; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - InvoiceTaxDtoHelper = invoiceTaxDtoHelper; - } - - public InvoiceTaxDtoHelper InvoiceTaxDtoHelper { get; } - - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public DaoFactory DaoFactory { get; } - public CurrencyProvider CurrencyProvider { get; } - public SettingsManager SettingsManager { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public CRMSecurity CRMSecurity { get; } - - public InvoiceItemDto Get(InvoiceItem invoiceItem) - { - var result = new InvoiceItemDto { - - Title = invoiceItem.Title, - StockKeepingUnit = invoiceItem.StockKeepingUnit, - Description = invoiceItem.Description, - Price = invoiceItem.Price, - StockQuantity = invoiceItem.StockQuantity, - TrackInvenory = invoiceItem.TrackInventory, - CreateOn = ApiDateTimeHelper.Get(invoiceItem.CreateOn), - CreateBy = EmployeeWraperHelper.Get(invoiceItem.CreateBy), - Currency = !String.IsNullOrEmpty(invoiceItem.Currency) ? - CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoiceItem.Currency)) : - CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), - CanEdit = CRMSecurity.CanEdit(invoiceItem), - CanDelete = CRMSecurity.CanDelete(invoiceItem) - }; - - if (invoiceItem.InvoiceTax1ID > 0) - { - result.InvoiceTax1 = InvoiceTaxDtoHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax1ID)); - } - if (invoiceItem.InvoiceTax2ID > 0) - { - result.InvoiceTax2 = InvoiceTaxDtoHelper.Get(DaoFactory.GetInvoiceTaxDao().GetByID(invoiceItem.InvoiceTax2ID)); - } - - return result; - - } - - } - - //public static class InvoiceItemDtoHelperExtension - //{ - // public static DIHelper AddInvoiceItemDtoHelperService(this DIHelper services) - // { - // services.TryAddTransient(); - // return services.AddCurrencyProviderService() - // .AddSettingsManagerService() - // .AddApiDateTimeHelper() - // .AddEmployeeWraper() - // .AddCRMSecurityService(); - // } - //} - - /// - /// Invoice Tax - /// - [DataContract(Name = "invoiceTax", Namespace = "")] - public class InvoiceTaxDto - { - - public InvoiceTaxDto() - { - } - - [DataMember(Name = "id")] - public int Id { get; set; } - - - public string Name { get; set; } - - - public string Description { get; set; } - - - public decimal Rate { get; set; } - - - public ApiDateTime CreateOn { get; set; } - - - public EmployeeWraper CreateBy { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanDelete { get; set; } - } - - [Scope] - public class InvoiceTaxDtoHelper - { - public InvoiceTaxDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - } - - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public CRMSecurity CRMSecurity { get; } - - public InvoiceTaxDto Get(InvoiceTax invoiceTax) - { - return new InvoiceTaxDto - { - Id = invoiceTax.ID, - Name = invoiceTax.Name, - Description = invoiceTax.Description, - Rate = invoiceTax.Rate, - CreateOn = ApiDateTimeHelper.Get(invoiceTax.CreateOn), - CreateBy = EmployeeWraperHelper.Get(invoiceTax.CreateBy), - CanEdit = CRMSecurity.CanEdit(invoiceTax), - CanDelete = CRMSecurity.CanDelete(invoiceTax) - }; - } - } - - /// - /// Invoice Line - /// - [DataContract(Name = "invoiceLine", Namespace = "")] - public class InvoiceLineDto - { - public InvoiceLineDto() - { - } - - - [DataMember(Name = "id")] - public int Id { get; set; } - - - public int InvoiceID { get; set; } - - - public int InvoiceItemID { get; set; } - - - public int InvoiceTax1ID { get; set; } - - - public int InvoiceTax2ID { get; set; } - - - public int SortOrder { get; set; } - - - public string Description { get; set; } - - - public decimal Quantity { get; set; } - - - public decimal Price { get; set; } - - - public decimal Discount { get; set; } - - public static InvoiceLineDto GetSample() - { - return new InvoiceLineDto - { - Description = string.Empty, - Discount = (decimal)0.00, - InvoiceID = 0, - InvoiceItemID = 0, - InvoiceTax1ID = 0, - InvoiceTax2ID = 0, - Price = (decimal)0.00, - Quantity = 0 - }; - } - } - - [Singletone] - public class InvoiceLineDtoHelper - { - public InvoiceLineDtoHelper() - { - } - - public InvoiceLineDto Get(InvoiceLine invoiceLine) - { - return new InvoiceLineDto - { - Id = invoiceLine.ID, - InvoiceID = invoiceLine.InvoiceID, - InvoiceItemID = invoiceLine.InvoiceItemID, - InvoiceTax1ID = invoiceLine.InvoiceTax1ID, - InvoiceTax2ID = invoiceLine.InvoiceTax2ID, - SortOrder = invoiceLine.SortOrder, - Description = invoiceLine.Description, - Quantity = invoiceLine.Quantity, - Price = invoiceLine.Price, - Discount = invoiceLine.Discount - }; - } - } - - /// - /// Invoice Status - /// - [DataContract(Name = "invoiceStatus", Namespace = "")] - public class InvoiceStatusDto - { - public InvoiceStatusDto() - { - - } - - [DataMember(Name = "id")] - public int Id { get; set; } - - - public string Title { get; set; } - - public static InvoiceStatusDto GetSample() - { - return new InvoiceStatusDto - { - Id = (int)InvoiceStatus.Draft, - Title = InvoiceStatus.Draft.ToLocalizedString() - }; - } - - } - - [Singletone] - public class InvoiceStatusDtoHelper - { - public InvoiceStatusDtoHelper() - { - } - - public InvoiceStatusDto Get(InvoiceStatus status) - { - return new InvoiceStatusDto - { - Id = (int)status, - Title = status.ToLocalizedString() - }; - } - } -} diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateCasesInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateCasesRequestDto.cs similarity index 91% rename from products/ASC.CRM/Server/ApiModels/CreateOrUpdateCasesInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateCasesRequestDto.cs index f0071ed6049..86d54590080 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateCasesInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateCasesRequestDto.cs @@ -7,7 +7,7 @@ namespace ASC.CRM.ApiModels { - public class CreateOrUpdateCasesInDto + public class CreateOrUpdateCasesRequestDto { public string Title { get; set; } public IEnumerable Members { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateDealInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateDealRequestDto.cs similarity index 95% rename from products/ASC.CRM/Server/ApiModels/CreateOrUpdateDealInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateDealRequestDto.cs index 18b5744e616..04851776b45 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateDealInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateDealRequestDto.cs @@ -9,7 +9,7 @@ namespace ASC.CRM.ApiModels { - public class CreateOrUpdateDealInDto + public class CreateOrUpdateDealRequestDto { public int Contactid { get; set; } public IEnumerable Members { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceItemInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs similarity index 91% rename from products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceItemInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs index 342e372f2e7..b3b21e8ffd0 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceItemInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.ApiModels { - public class CreateOrUpdateInvoiceItemInDto + public class CreateOrUpdateInvoiceItemRequestDto { public string Title { get; set; } public string Description { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceLineInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs similarity index 91% rename from products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceLineInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs index 2c3dbdddf68..1bb449b5b19 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceLineInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.ApiModels { - public class CreateOrUpdateInvoiceLineInDto + public class CreateOrUpdateInvoiceLineRequestDto { public int InvoiceId { get; set; } public int InvoiceItemId { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceRequestDto.cs similarity index 95% rename from products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceRequestDto.cs index 2cae2e927d1..6ae9ed5b0bc 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceRequestDto.cs @@ -8,7 +8,7 @@ namespace ASC.CRM.ApiModels { - public class CreateOrUpdateInvoiceInDto + public class CreateOrUpdateInvoiceRequestDto { public string Number { get; set; } public ApiDateTime IssueDate { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceTax.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs similarity index 84% rename from products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceTax.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs index f2e9524e4c6..df87334dc49 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdateInvoiceTax.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.ApiModels { - public class CreateOrUpdateInvoiceTax + public class CreateOrUpdateInvoiceTaxRequestDto { public string Name { get; set; } public string Description { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdatePersonRequestDto.cs similarity index 79% rename from products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdatePersonRequestDto.cs index 2a8c14dc5e7..4b1e6d2eae6 100644 --- a/products/ASC.CRM/Server/ApiModels/CreateOrUpdatePersonInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdatePersonRequestDto.cs @@ -11,7 +11,7 @@ namespace ASC.CRM.ApiModels { - public class CreateOrUpdateContactInDto + public class CreateOrUpdateContactRequestDto { public string About { get; set; } public ShareType ShareType { get; set; } @@ -20,17 +20,15 @@ public class CreateOrUpdateContactInDto public IEnumerable Photos { get; set; } } - public class CreateOrUpdateCompanyInDto : CreateOrUpdateContactInDto - { - + public class CreateOrUpdateCompanyRequestDto : CreateOrUpdateContactRequestDto + { public String CompanyName { get; set; } public IEnumerable PersonList { get; set; } } - - public class CreateOrUpdatePersonInDto : CreateOrUpdateContactInDto + public class CreateOrUpdatePersonRequestDto : CreateOrUpdateContactRequestDto { public String FirstName { get; set; } public String LastName { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/SaveNumberSettingsInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SaveNumberSettingsRequestDto.cs similarity index 85% rename from products/ASC.CRM/Server/ApiModels/SaveNumberSettingsInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/SaveNumberSettingsRequestDto.cs index 0412c80ab60..c0c0aaed49e 100644 --- a/products/ASC.CRM/Server/ApiModels/SaveNumberSettingsInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SaveNumberSettingsRequestDto.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.ApiModels { - public class SaveNumberSettingsInDto + public class SaveNumberSettingsRequestDto { public bool AutoGenerated { get; set; } public string Prefix { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SendMailSMTPToContactsRequestDto.cs similarity index 88% rename from products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/SendMailSMTPToContactsRequestDto.cs index 4b506f1744f..95c09cda49a 100644 --- a/products/ASC.CRM/Server/ApiModels/SendMailSMTPToContactsInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SendMailSMTPToContactsRequestDto.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.ApiModels { - public class SendMailSMTPToContactsInDto + public class SendMailSMTPToContactsRequestDto { public List FileIDs { get; set; } public List ContactIds { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchCasesRequestDto.cs similarity index 92% rename from products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchCasesRequestDto.cs index c6811fcbb9c..3327804876c 100644 --- a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchCasesInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchCasesRequestDto.cs @@ -15,7 +15,7 @@ public class SetAccessToBatchCasesByFilterInDto } - public class SetAccessToBatchCasesInDto + public class SetAccessToBatchCasesRequestDto { public IEnumerable CasesId { get; set; } public bool isPrivate { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchContactInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchContactRequestDto.cs similarity index 88% rename from products/ASC.CRM/Server/ApiModels/SetAccessToBatchContactInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchContactRequestDto.cs index 5ff038bdc5b..50ac917a9c7 100644 --- a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchContactInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchContactRequestDto.cs @@ -9,7 +9,7 @@ namespace ASC.CRM.ApiModels { - public class SetAccessToBatchContactByFilterInDto + public class SetAccessToBatchContactByFilterRequestDto { public IEnumerable Tags { get; set; } public int? ContactStage { get; set; } @@ -21,7 +21,7 @@ public class SetAccessToBatchContactByFilterInDto public IEnumerable ManagerList { get; set; } } - public class SetAccessToBatchContactInDto + public class SetAccessToBatchContactRequestDto { public IEnumerable ContactID { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchDealByFilterInDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs similarity index 89% rename from products/ASC.CRM/Server/ApiModels/SetAccessToBatchDealByFilterInDto.cs rename to products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs index b6b052bdba5..dbd7d78998e 100644 --- a/products/ASC.CRM/Server/ApiModels/SetAccessToBatchDealByFilterInDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs @@ -9,7 +9,7 @@ namespace ASC.CRM.ApiModels { - public class SetAccessToBatchDealByFilterInDto + public class SetAccessToBatchDealByFilterRequestDto { public Guid Responsibleid { get; set; } public int OpportunityStagesid { get; set; } @@ -23,7 +23,7 @@ public class SetAccessToBatchDealByFilterInDto public IEnumerable AccessList { get; set; } } - public class SetAccessToBatchDealInDto + public class SetAccessToBatchDealRequestDto { public IEnumerable Opportunityid { get; set; } public bool isPrivate { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs new file mode 100644 index 00000000000..eb21b729b35 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs @@ -0,0 +1,80 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Mapping; +using ASC.Web.Api.Models; + +using AutoMapper; + +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + [DataContract(Name = "case", Namespace = "")] + public class CasesDto : IMapFrom + { + public CasesDto() + { + } + + + [DataMember(Name = "id")] + public int Id { get; set; } + public IEnumerable Members { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public String Title { get; set; } + public bool IsClosed { get; set; } + public bool IsPrivate { get; set; } + public IEnumerable AccessList { get; set; } + public bool CanEdit { get; set; } + public IEnumerable CustomFields { get; set; } + public static CasesDto GetSample() + { + return new CasesDto + { + IsClosed = false, + Title = "Exhibition organization", + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + IsPrivate = false, + CustomFields = new[] { CustomFieldBaseDto.GetSample() }, + CanEdit = true + }; + } + + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } + } +} + + diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs new file mode 100644 index 00000000000..2c5c3ef8b1b --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -0,0 +1,311 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.CRM.Api; +using ASC.Common; +using ASC.CRM.Classes; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using Contact = ASC.CRM.Core.Entities.Contact; + +namespace ASC.CRM.ApiModels +{ + /// + /// Person + /// + [DataContract(Name = "person", Namespace = "")] + public class PersonDto : ContactDto + { + public PersonDto() + { + + } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String FirstName { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String LastName { get; set; } + + + public ContactBaseDto Company { get; set; } + + + public String Title { get; set; } + + public new static PersonDto GetSample() + { + return new PersonDto + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + FirstName = "Tadjeddine", + LastName = "Bachir", + Company = CompanyDto.GetSample(), + Title = "Programmer", + About = "", + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + ShareType = ShareType.None + }; + } + } + + [Scope] + public class PersonDtoHelper + { + public PersonDtoHelper() + { + } + + public PersonDto Get(Person person) + { + return new PersonDto + { + FirstName = person.FirstName, + LastName = person.LastName, + Title = person.JobTitle + }; + } + + public PersonDto GetQuick(Person person) + { + return new PersonDto + { + FirstName = person.FirstName, + LastName = person.LastName, + Title = person.JobTitle + }; + } + } + + /// + /// Company + /// + [DataContract(Name = "company", Namespace = "")] + public class CompanyDto : ContactDto + { + public CompanyDto() + { + } + + //public CompanyDto(Company company) + // : base(company) + //{ + // CompanyName = company.CompanyName; + // // PersonsCount = Global.DaoFactory.ContactDao.GetMembersCount(company.ID); + //} + + + + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String CompanyName { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public IEnumerable Persons { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public int PersonsCount { get; set; } + + public new static CompanyDto GetSample() + { + return new CompanyDto + { + IsPrivate = true, + IsShared = false, + IsCompany = true, + About = "", + CompanyName = "Food and Culture Project", + PersonsCount = 0 + }; + } + } + + [DataContract(Name = "contact", Namespace = "")] + [KnownType(typeof(PersonDto))] + [KnownType(typeof(CompanyDto))] + public abstract class ContactDto : ContactBaseDto + { + public ContactDto() + { + + } + + //protected ContactDto(Contact contact) + // : base(contact) + //{ + // CreateBy = EmployeeWraper.Get(contact.CreateBy); + // Created = (ApiDateTime)contact.CreateOn; + // About = contact.About; + // Industry = contact.Industry; + //} + + + public IEnumerable
    Addresses { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public String About { get; set; } + public String Industry { get; set; } + public ContactStatusBaseDto ContactStatus { get; set; } + public ContactTypeBaseDto ContactType { get; set; } + public IEnumerable CommonData { get; set; } + public IEnumerable CustomFields { get; set; } + public IEnumerable Tags { get; set; } + public int TaskCount { get; set; } + + + public bool HaveLateTasks { get; set; } + public new static ContactDto GetSample() + { + return new PersonDto + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + FirstName = "Tadjeddine", + LastName = "Bachir", + Company = CompanyDto.GetSample(), + Title = "Programmer", + About = "", + Created = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + CommonData = new List() { ContactInfoDto.GetSample() }, + CustomFields = new List() { CustomFieldBaseDto.GetSample() }, + ShareType = ShareType.None, + CanDelete = true, + CanEdit = true, + TaskCount = 0, + HaveLateTasks = false + }; + } + } + + [DataContract(Name = "contactBase", Namespace = "")] + public class ContactBaseWithEmailDto : ContactBaseDto + { + public ContactInfoDto Email { get; set; } + } + + + [DataContract(Name = "contactBase", Namespace = "")] + public class ContactBaseWithPhoneDto : ContactBaseDto + { + public ContactInfoDto Phone { get; set; } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /// + /// Contact base information + /// + [DataContract(Name = "contactBase", Namespace = "")] + public class ContactBaseDto + { + public ContactBaseDto() + { + + } + + [DataMember(Name = "id")] + public int Id { get; set; } + public String SmallFotoUrl { get; set; } + public String MediumFotoUrl { get; set; } + public String DisplayName { get; set; } + public bool IsCompany { get; set; } + public IEnumerable AccessList { get; set; } + public bool IsPrivate { get; set; } + public bool IsShared { get; set; } + public ShareType ShareType { get; set; } + public CurrencyInfoDto Currency { get; set; } + public bool CanEdit { get; set; } + public bool CanDelete { get; set; } + public static ContactBaseDto GetSample() + { + return new ContactBaseDto + { + IsPrivate = true, + IsShared = false, + IsCompany = false, + DisplayName = "Tadjeddine Bachir", + SmallFotoUrl = "url to foto" + }; + } + } + + [DataContract(Name = "contact_task", Namespace = "")] + public class ContactWithTaskDto + { + + public TaskBaseDto Task { get; set; } + + + public ContactDto Contact { get; set; } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ContactInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs similarity index 90% rename from products/ASC.CRM/Server/ApiModels/ContactInfoDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs index f741d7d9101..eab908b59c2 100644 --- a/products/ASC.CRM/Server/ApiModels/ContactInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs @@ -164,28 +164,4 @@ public static ContactInfoDto GetSample() }; } } - - [Scope] - public class ContactInfoDtoHelper - { - public ContactInfoDtoHelper() - { - } - - public ContactInfoDto Get(ContactInfo contactInfo) - { - if (contactInfo == null) return null; - - return new ContactInfoDto - { - InfoType = contactInfo.InfoType, - Category = contactInfo.Category, - CategoryName = contactInfo.CategoryToString(), - Data = contactInfo.Data, - IsPrimary = contactInfo.IsPrimary, - Id = contactInfo.ID - }; - } - - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs similarity index 64% rename from products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs index e62f4eb1586..a4f6bc85e77 100644 --- a/products/ASC.CRM/Server/ApiModels/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs @@ -26,8 +26,8 @@ using System; using System.Runtime.Serialization; + using ASC.Common; -using ASC.CRM.Core; namespace ASC.CRM.ApiModels { @@ -41,9 +41,7 @@ public CurrencyInfoDto() { - } - - + } public String Title { get; set; } public String Symbol { get; set; } public String Abbreviation { get; set; } @@ -63,30 +61,6 @@ public static CurrencyInfoDto GetSample() }; } } - - [Singletone] - public class CurrencyInfoDtoHelper - { - public CurrencyInfoDtoHelper() - { - } - - - public CurrencyInfoDto Get(CurrencyInfo currencyInfo) - { - if (currencyInfo == null) return null; - - return new CurrencyInfoDto - { - Abbreviation = currencyInfo.Abbreviation, - CultureName = currencyInfo.CultureName, - Symbol = currencyInfo.Symbol, - Title = currencyInfo.Title, - IsConvertable = currencyInfo.IsConvertable, - IsBasic = currencyInfo.IsBasic - }; - } - } /// /// Currency rate information @@ -107,31 +81,4 @@ public CurrencyRateInfoDto() public decimal Rate { get; set; } } - - [Scope] - public class CurrencyRateInfoDtoHelper - { - public CurrencyRateInfoDtoHelper(CurrencyInfoDtoHelper currencyInfoDtoHelper) - { - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - } - - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - - public CurrencyRateInfoDto Get(CurrencyInfo currencyInfo, decimal rate) - { - var currencyInfoDto = CurrencyInfoDtoHelper.Get(currencyInfo); - - return new CurrencyRateInfoDto - { - Abbreviation = currencyInfoDto.Abbreviation, - CultureName = currencyInfoDto.CultureName, - Symbol = currencyInfoDto.Symbol, - Title = currencyInfoDto.Title, - IsConvertable = currencyInfoDto.IsConvertable, - IsBasic = currencyInfoDto.IsBasic, - Rate = rate - }; - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs similarity index 83% rename from products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs index 3583d37d0a6..b9ac941bf2c 100644 --- a/products/ASC.CRM/Server/ApiModels/CurrencyRateDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs @@ -28,7 +28,6 @@ using System.Runtime.Serialization; using ASC.Common; -using ASC.CRM.Core; namespace ASC.CRM.ApiModels { @@ -59,22 +58,4 @@ public static CurrencyRateDto GetSample() }; } } - - [Scope] - public class CurrencyRateDtoHelper - { - public CurrencyRateDtoHelper() - { - } - - public CurrencyRateDto Get(CurrencyRate currencyRate) - { - return new CurrencyRateDto - { - FromCurrency = currencyRate.FromCurrency, - ToCurrency = currencyRate.ToCurrency, - Rate = currencyRate.Rate - }; - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs similarity index 100% rename from products/ASC.CRM/Server/ApiModels/CustomFieldDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs new file mode 100644 index 00000000000..adbb0886f8f --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs @@ -0,0 +1,99 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Api.Core; +using ASC.Common; +using ASC.CRM.Classes; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; + +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + /// + /// Invoice + /// + [DataContract(Name = "invoiceBase", Namespace = "")] + public class InvoiceBaseDto + { + public int Id { get; set; } + public InvoiceStatusDto Status { get; set; } + public string Number { get; set; } + public ApiDateTime IssueDate { get; set; } + public InvoiceTemplateType TemplateType { get; set; } + public ContactBaseWithEmailDto Contact { get; set; } + public ContactBaseWithEmailDto Consignee { get; set; } + public EntityDto Entity { get; set; } + public ApiDateTime DueDate { get; set; } + public string Language { get; set; } + public CurrencyInfoDto Currency { get; set; } + public decimal ExchangeRate { get; set; } + public string PurchaseOrderNumber { get; set; } + public string Terms { get; set; } + public string Description { get; set; } + public int FileID { get; set; } + public ApiDateTime CreateOn { get; set; } + public EmployeeWraper CreateBy { get; set; } + public decimal Cost { get; set; } + public bool CanEdit { get; set; } + public bool CanDelete { get; set; } + } + + /// + /// Invoice + /// + [DataContract(Name = "invoice", Namespace = "")] + public class InvoiceDto : InvoiceBaseDto + { + public List InvoiceLines { get; set; } + + public static InvoiceDto GetSample() + { + return new InvoiceDto + { + Status = InvoiceStatusDto.GetSample(), + Number = string.Empty, + IssueDate = ApiDateTime.GetSample(), + TemplateType = InvoiceTemplateType.Eur, + Language = string.Empty, + DueDate = ApiDateTime.GetSample(), + Currency = CurrencyInfoDto.GetSample(), + ExchangeRate = (decimal)1.00, + PurchaseOrderNumber = string.Empty, + Terms = string.Empty, + Description = string.Empty, + FileID = -1, + CreateOn = ApiDateTime.GetSample(), + CreateBy = EmployeeWraper.GetSample(), + CanEdit = true, + CanDelete = true, + Cost = 0, + InvoiceLines = new List { InvoiceLineDto.GetSample() } + }; + } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs new file mode 100644 index 00000000000..36e08ec0d16 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs @@ -0,0 +1,130 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Api.Core; +using ASC.Common; +using ASC.Core.Common.Settings; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; + +using System; +using System.Linq; + +namespace ASC.CRM.ApiModels +{ + [Scope] + public class InvoiceDtoHelper + { + public InvoiceDtoHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + InvoiceStatusDtoHelper invoiceStatusDtoHelper, + InvoiceLineDtoHelper invoiceLineDtoHelper, + DaoFactory daoFactory, + CurrencyInfoDtoHelper currencyInfoDtoHelper, + CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, + ContactDtoHelper contactDtoHelper, + EntityDtoHelper entityDtoHelper) + { + ApiDateTimeHelper = apiDateTimeHelper; + EmployeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + SettingsManager = settingsManager; + CurrencyProvider = currencyProvider; + InvoiceStatusDtoHelper = invoiceStatusDtoHelper; + DaoFactory = daoFactory; + InvoiceLineDtoHelper = invoiceLineDtoHelper; + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; + ContactDtoHelper = contactDtoHelper; + EntityDtoHelper = entityDtoHelper; + } + + public ContactDtoHelper ContactDtoHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } + public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } + public DaoFactory DaoFactory { get; } + public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } + public InvoiceStatusDtoHelper InvoiceStatusDtoHelper { get; } + public CurrencyProvider CurrencyProvider { get; } + public SettingsManager SettingsManager { get; } + public ApiDateTimeHelper ApiDateTimeHelper { get; } + public EmployeeWraperHelper EmployeeWraperHelper { get; } + public CRMSecurity CRMSecurity { get; } + public EntityDtoHelper EntityDtoHelper { get; } + public InvoiceDto Get(Invoice invoice) + { + var result = new InvoiceDto + { + Id = invoice.ID, + Status = InvoiceStatusDtoHelper.Get(invoice.Status), + Number = invoice.Number, + IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), + TemplateType = invoice.TemplateType, + DueDate = ApiDateTimeHelper.Get(invoice.DueDate), + Currency = !String.IsNullOrEmpty(invoice.Currency) ? + CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoice.Currency)) : + CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), + ExchangeRate = invoice.ExchangeRate, + Language = invoice.Language, + PurchaseOrderNumber = invoice.PurchaseOrderNumber, + Terms = invoice.Terms, + Description = invoice.Description, + FileID = invoice.FileID, + CreateOn = ApiDateTimeHelper.Get(invoice.CreateOn), + CreateBy = EmployeeWraperHelper.Get(invoice.CreateBy), + CanEdit = CRMSecurity.CanEdit(invoice), + CanDelete = CRMSecurity.CanDelete(invoice), + }; + + if (invoice.ContactID > 0) + { + result.Contact = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); + } + + if (invoice.ConsigneeID > 0) + { + result.Consignee = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + } + + if (invoice.EntityID > 0) + { + result.Entity = EntityDtoHelper.Get(invoice.EntityType, invoice.EntityID); + } + + result.Cost = invoice.GetInvoiceCost(DaoFactory); + + result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(x => InvoiceLineDtoHelper.Get(x)).ToList(); + + return result; + + } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs new file mode 100644 index 00000000000..562c0536470 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs @@ -0,0 +1,62 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Api.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Mapping; +using ASC.Web.Api.Models; + +using AutoMapper; + +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + /// + /// Invoice Item + /// + [DataContract(Name = "invoiceItem", Namespace = "")] + public class InvoiceItemDto : IMapFrom + { + public string Title { get; set; } + public string StockKeepingUnit { get; set; } + public string Description { get; set; } + public decimal Price { get; set; } + public CurrencyInfoDto Currency { get; set; } + public decimal StockQuantity { get; set; } + public bool TrackInvenory { get; set; } + public InvoiceTaxDto InvoiceTax1 { get; set; } + public InvoiceTaxDto InvoiceTax2 { get; set; } + public ApiDateTime CreateOn { get; set; } + public EmployeeWraper CreateBy { get; set; } + public bool CanEdit { get; set; } + public bool CanDelete { get; set; } + + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs new file mode 100644 index 00000000000..722832987f6 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs @@ -0,0 +1,61 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + /// + /// Invoice Line + /// + [DataContract(Name = "invoiceLine", Namespace = "")] + public class InvoiceLineDto + { + public int Id { get; set; } + public int InvoiceID { get; set; } + public int InvoiceItemID { get; set; } + public int InvoiceTax1ID { get; set; } + public int InvoiceTax2ID { get; set; } + public int SortOrder { get; set; } + public string Description { get; set; } + public decimal Quantity { get; set; } + public decimal Price { get; set; } + public decimal Discount { get; set; } + public static InvoiceLineDto GetSample() + { + return new InvoiceLineDto + { + Description = string.Empty, + Discount = (decimal)0.00, + InvoiceID = 0, + InvoiceItemID = 0, + InvoiceTax1ID = 0, + InvoiceTax2ID = 0, + Price = (decimal)0.00, + Quantity = 0 + }; + } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs new file mode 100644 index 00000000000..d09e770fcd3 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs @@ -0,0 +1,51 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.CRM.Classes; +using ASC.CRM.Core.Enums; + +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + /// + /// Invoice Status + /// + [DataContract(Name = "invoiceStatus", Namespace = "")] + public class InvoiceStatusDto + { + public int Id { get; set; } + public string Title { get; set; } + public static InvoiceStatusDto GetSample() + { + return new InvoiceStatusDto + { + Id = (int)InvoiceStatus.Draft, + Title = InvoiceStatus.Draft.ToLocalizedString() + }; + } + + } +} diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs new file mode 100644 index 00000000000..5eea296d1ba --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs @@ -0,0 +1,72 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Api.Core; +using ASC.CRM.Core.Entities; +using ASC.CRM.Mapping; +using ASC.Web.Api.Models; + +using AutoMapper; + +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + //public static class InvoiceItemDtoHelperExtension + //{ + // public static DIHelper AddInvoiceItemDtoHelperService(this DIHelper services) + // { + // services.TryAddTransient(); + // return services.AddCurrencyProviderService() + // .AddSettingsManagerService() + // .AddApiDateTimeHelper() + // .AddEmployeeWraper() + // .AddCRMSecurityService(); + // } + //} + + /// + /// Invoice Tax + /// + [DataContract(Name = "invoiceTax", Namespace = "")] + public class InvoiceTaxDto: IMapFrom + { + public int Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public decimal Rate { get; set; } + public ApiDateTime CreateOn { get; set; } + public EmployeeWraper CreateBy { get; set; } + public bool CanEdit { get; set; } + public bool CanDelete { get; set; } + + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } + + + } +} diff --git a/products/ASC.CRM/Server/ApiModels/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs similarity index 89% rename from products/ASC.CRM/Server/ApiModels/ListItemDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index 4b14bcf3a37..119544fe7b3 100644 --- a/products/ASC.CRM/Server/ApiModels/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -24,11 +24,9 @@ */ -using ASC.Common; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.Web.Core.Utility.Skins; -using ASC.Web.CRM.Configuration; + using System; using System.Runtime.Serialization; @@ -98,25 +96,6 @@ public HistoryCategoryDto(ListItem listItem) } } - [Scope] - public sealed class HistoryCategoryDtoHelper - { - public HistoryCategoryDtoHelper(WebImageSupplier webImageSupplier) - { - WebImageSupplier = webImageSupplier; - } - - public WebImageSupplier WebImageSupplier { get; } - - public HistoryCategoryBaseDto Get(ListItem listItem) - { - return new HistoryCategoryBaseDto(listItem) - { - ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) - }; - } - } - #endregion #region Deal Milestone @@ -248,26 +227,6 @@ public TaskCategoryDto(ListItem listItem): base(listItem) } - [Scope] - public sealed class TaskCategoryDtoHelper - { - public TaskCategoryDtoHelper(WebImageSupplier webImageSupplier) - { - WebImageSupplier = webImageSupplier; - } - - public WebImageSupplier WebImageSupplier { get; } - - public TaskCategoryBaseDto Get(ListItem listItem) - { - return new TaskCategoryBaseDto(listItem) - { - ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) - }; - } - } - - diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs new file mode 100644 index 00000000000..7005491841a --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs @@ -0,0 +1,94 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; + +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + /// + /// Opportunity + /// + [DataContract(Name = "opportunity", Namespace = "")] + public class OpportunityDto + { + + public OpportunityDto() + { + } + + [DataMember(Name = "id")] + public int Id { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public IEnumerable Members { get; set; } + public ContactBaseDto Contact { get; set; } + + [DataMember(IsRequired = true, EmitDefaultValue = false)] + public String Title { get; set; } + public String Description { get; set; } + public EmployeeWraper Responsible { get; set; } + public BidType BidType { get; set; } + public decimal BidValue { get; set; } + public CurrencyInfoDto BidCurrency { get; set; } + public int PerPeriodValue { get; set; } + public DealMilestoneBaseDto Stage { get; set; } + public int SuccessProbability { get; set; } + public ApiDateTime ActualCloseDate { get; set; } + public ApiDateTime ExpectedCloseDate { get; set; } + + + public bool IsPrivate { get; set; } + public IEnumerable AccessList { get; set; } + + + public bool CanEdit { get; set; } + public IEnumerable CustomFields { get; set; } + + public static OpportunityDto GetSample() + { + return new OpportunityDto + { + CreateBy = EmployeeWraper.GetSample(), + Created = ApiDateTime.GetSample(), + Responsible = EmployeeWraper.GetSample(), + Title = "Hotel catalogue", + Description = "", + ExpectedCloseDate = ApiDateTime.GetSample(), + Contact = ContactBaseDto.GetSample(), + IsPrivate = false, + SuccessProbability = 65, + BidType = BidType.FixedBid, + Stage = DealMilestoneBaseDto.GetSample() + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs similarity index 100% rename from products/ASC.CRM/Server/ApiModels/RelationshipEventDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs diff --git a/products/ASC.CRM/Server/ApiModels/ReportDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs similarity index 100% rename from products/ASC.CRM/Server/ApiModels/ReportDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs diff --git a/products/ASC.CRM/Server/ApiModels/TaskDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs similarity index 57% rename from products/ASC.CRM/Server/ApiModels/TaskDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs index fbbc307bad3..b3ffe0cc949 100644 --- a/products/ASC.CRM/Server/ApiModels/TaskDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs @@ -30,7 +30,11 @@ using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; using ASC.Web.Api.Models; + +using AutoMapper; + using System; using System.Runtime.Serialization; @@ -40,15 +44,14 @@ namespace ASC.CRM.ApiModels /// Task /// [DataContract(Name = "task", Namespace = "")] - public class TaskDto + public class TaskDto : IMapFrom { - [DataMember(Name = "id")] public int Id { get; set; } public EmployeeWraper CreateBy { get; set; } public ApiDateTime Created { get; set; } public ContactBaseWithEmailDto Contact { get; set; } - public String Title { get; set; } - public String Description { get; set; } + public string Title { get; set; } + public string Description { get; set; } public ApiDateTime DeadLine { get; set; } public int AlertValue { get; set; } public EmployeeWraper Responsible { get; set; } @@ -71,18 +74,16 @@ public static TaskDto GetSample() AlertValue = 0 }; } + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } } [DataContract(Name = "taskBase", Namespace = "")] public class TaskBaseDto { - [DataMember(Name = "id")] public int Id { get; set; } - - public TaskBaseDto() - { - - } public String Title { get; set; } public String Description { get; set; } public ApiDateTime DeadLine { get; set; } @@ -106,81 +107,4 @@ public static TaskBaseDto GetSample() }; } } - - [Scope] - public class TaskDtoHelper - { - public TaskDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - DaoFactory daoFactory, - ContactDtoHelper contactBaseDtoHelper, - EntityDtoHelper entityDtoHelper) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - DaoFactory = daoFactory; - ContactBaseDtoHelper = contactBaseDtoHelper; - EntityDtoHelper = entityDtoHelper; - } - - public ContactDtoHelper ContactBaseDtoHelper { get; } - public CRMSecurity CRMSecurity { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public DaoFactory DaoFactory { get; } - public EntityDtoHelper EntityDtoHelper { get; } - - public TaskBaseDto GetTaskBaseDto(Task task) - { - return new TaskBaseDto { - Title = task.Title, - Description = task.Description, - DeadLine = ApiDateTimeHelper.Get(task.DeadLine), - Responsible = EmployeeWraperHelper.Get(task.ResponsibleID), - IsClosed = task.IsClosed, - AlertValue = task.AlertValue - }; - } - - public TaskDto GetTaskDto(Task task) - { - var result = new TaskDto - { - Title = task.Title, - Description = task.Description, - DeadLine = ApiDateTimeHelper.Get(task.DeadLine), - Responsible = EmployeeWraperHelper.Get(task.ResponsibleID), - IsClosed = task.IsClosed, - AlertValue = task.AlertValue - }; - - if (task.CategoryID > 0) - { - var categoryItem = DaoFactory.GetListItemDao().GetByID(task.CategoryID); - - result.Category = new TaskCategoryDto(categoryItem) - { - RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, categoryItem.ID) - }; - - } - - if (task.ContactID > 0) - { - result.Contact = ContactBaseDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(task.ContactID)); - } - - if (task.EntityID > 0) - { - - result.Entity = EntityDtoHelper.Get(task.EntityType, task.EntityID); - } - - result.CanEdit = CRMSecurity.CanEdit(task); - - return result; - } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/TaskTemplateContainerDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs similarity index 95% rename from products/ASC.CRM/Server/ApiModels/TaskTemplateContainerDto.cs rename to products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs index 4b8714dbc7e..4d36f711b47 100644 --- a/products/ASC.CRM/Server/ApiModels/TaskTemplateContainerDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs @@ -91,13 +91,13 @@ public TaskTemplateDto() [DataMember(IsRequired = true, EmitDefaultValue = false)] public TaskCategoryDto Category { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool isNotify { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = true)] + public long OffsetTicks { get; set; } - [DataMember(IsRequired = false, EmitDefaultValue = true)] + public bool DeadLineIsFixed { get; set; } public static TaskTemplateDto GetSample() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs new file mode 100644 index 00000000000..38a0f483e2e --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs @@ -0,0 +1,54 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Api.Core; +using ASC.VoipService; +using ASC.Web.Api.Models; + +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; + +namespace ASC.CRM.ApiModels +{ + [DataContract(Name = "voipCall", Namespace = "")] + public class VoipCallDto + { + public string Id { get; set; } + public string From { get; set; } + public string To { get; set; } + public VoipCallStatus? Status { get; set; } + public EmployeeWraper AnsweredBy { get; set; } + public ApiDateTime DialDate { get; set; } + public int DialDuration { get; set; } + public decimal Cost { get; set; } + public ContactDto Contact { get; set; } + public IEnumerable Calls { get; set; } + public string RecordUrl { get; set; } + public int RecordDuration { get; set; } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 6313f3fdd44..9f91abb2d02 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -177,6 +177,12 @@ public static void Register(DIHelper services) services.TryAdd(); services.TryAdd(); services.TryAdd(); + + + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); + services.TryAdd(); } } diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 5ce580f8018..8719ce3af50 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -38,6 +38,9 @@ using ASC.Files.Core; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; + +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -63,6 +66,7 @@ public CachedDealDao(DbContextManager dbContextManager, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, ICache ascCache, + IMapper mapper, BundleSearch bundleSearch) : base(dbContextManager, tenantManager, @@ -72,6 +76,7 @@ public CachedDealDao(DbContextManager dbContextManager, filesIntegration, logger, ascCache, + mapper, bundleSearch) { _dealCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal"); @@ -115,6 +120,8 @@ private void ResetCache(int dealID) [Scope] public class DealDao : AbstractDao { + private readonly IMapper _mapper; + public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -123,6 +130,7 @@ public DealDao(DbContextManager dbContextManager, FilesIntegration filesIntegration, IOptionsMonitor logger, ICache ascCache, + IMapper mapper, BundleSearch bundleSearch) : base(dbContextManager, tenantManager, @@ -134,6 +142,7 @@ public DealDao(DbContextManager dbContextManager, FactoryIndexer = factoryIndexer; FilesIntegration = filesIntegration; BundleSearch = bundleSearch; + _mapper = mapper; } public BundleSearch BundleSearch { get; } @@ -176,9 +185,9 @@ public virtual List GetDeals(int[] id) { if (id == null || !id.Any()) return new List(); - return Query(CRMDbContext.Deals).Where(x => id.Contains(x.Id)) + return _mapper.ProjectTo(Query(CRMDbContext.Deals) + .Where(x => id.Contains(x.Id))) .ToList() - .ConvertAll(ToDeal) .FindAll(CRMSecurity.CanAccessTo); } @@ -737,7 +746,7 @@ private List GetCrudeDeals( } - return sqlQuery.ToList().ConvertAll(ToDeal); + return _mapper.ProjectTo(sqlQuery).ToList(); } public List GetDealsByContactID(int contactID) @@ -786,7 +795,7 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta sqlQuery = sqlQuery.OrderBy(x => x.Title); - return sqlQuery.ToList().ConvertAll(ToDeal).FindAll(CRMSecurity.CanAccessTo); + return _mapper.ProjectTo(sqlQuery).ToList().FindAll(CRMSecurity.CanAccessTo); } public virtual Deal DeleteDeal(int dealID) @@ -878,30 +887,6 @@ private void DeleteBatchDealsExecute(List deals) } - private Deal ToDeal(DbDeal dbDeal) - { - if (dbDeal == null) return null; - - return new Deal - { - ID = dbDeal.Id, - Title = dbDeal.Title, - Description = dbDeal.Description, - ResponsibleID = dbDeal.ResponsibleId, - ContactID = dbDeal.ContactId, - BidCurrency = dbDeal.BidCurrency, - BidValue = dbDeal.BidValue, - BidType = dbDeal.BidType, - DealMilestoneID = dbDeal.DealMilestoneId, - ExpectedCloseDate = dbDeal.ExpectedCloseDate, - PerPeriodValue = dbDeal.PerPeriodValue, - DealMilestoneProbability = dbDeal.DealMilestoneProbability, - CreateOn = TenantUtil.DateTimeFromUtc(dbDeal.CreateOn), - CreateBy = dbDeal.CreateBy, - ActualCloseDate = Convert.ToDateTime(dbDeal.ActualCloseDate) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(dbDeal.ActualCloseDate)) - }; - } - public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) { var deals = GetDeals(String.Empty, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index dfdca57bd60..ae6b77ec411 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -33,6 +33,9 @@ using ASC.Core.Tenants; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; + +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using System; @@ -48,16 +51,20 @@ public class CachedInvoiceTaxDao : InvoiceTaxDao public CachedInvoiceTaxDao(DbContextManager dbContextManager, TenantManager tenantManager, + TenantUtil tenantUtil, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) : base(dbContextManager, tenantManager, + tenantUtil, securityContext, logger, - ascCache) + ascCache, + mapper) { _invoiceTaxCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_tax"); @@ -97,12 +104,16 @@ private void ResetCache(int invoiceTaxID) [Scope] public class InvoiceTaxDao : AbstractDao { + private readonly IMapper _mapper; + public InvoiceTaxDao( DbContextManager dbContextManager, TenantManager tenantManager, + TenantUtil tenantUtil, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) : base(dbContextManager, tenantManager, @@ -110,7 +121,8 @@ ICache ascCache logger, ascCache) { - + TenantUtil = tenantUtil; + _mapper = mapper; } public TenantUtil TenantUtil { get; } @@ -136,9 +148,7 @@ public Boolean CanDelete(int invoiceTaxID) public virtual List GetAll() { - return Query(CRMDbContext.InvoiceTax) - .ToList() - .ConvertAll(ToInvoiceTax); + return _mapper.Map,List>(Query(CRMDbContext.InvoiceTax).ToList()); } public DateTime GetMaxLastModified() @@ -152,15 +162,18 @@ public DateTime GetMaxLastModified() public virtual List GetByID(int[] ids) { - return Query(CRMDbContext.InvoiceTax) + var result = Query(CRMDbContext.InvoiceTax) .Where(x => ids.Contains(x.Id)) - .ToList() - .ConvertAll(ToInvoiceTax); + .ToList(); + + return _mapper.Map, List>(result); } public virtual InvoiceTax GetByID(int id) { - return ToInvoiceTax(CRMDbContext.InvoiceTax.FirstOrDefault(x => x.Id == id)); + var invoiceTax = CRMDbContext.InvoiceTax.FirstOrDefault(x => x.Id == id); + + return _mapper.Map(invoiceTax); } public virtual InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) @@ -247,28 +260,7 @@ public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) /* _cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ return invoiceTax; - } - - private InvoiceTax ToInvoiceTax(DbInvoiceTax dbInvoiceTax) - { - if (dbInvoiceTax == null) return null; - - var result = new InvoiceTax - { - ID = dbInvoiceTax.Id, - Name = dbInvoiceTax.Name, - Description = dbInvoiceTax.Description, - Rate = dbInvoiceTax.Rate, - CreateOn = TenantUtil.DateTimeFromUtc(dbInvoiceTax.CreateOn), - CreateBy = dbInvoiceTax.CreateBy, - LastModifedBy = dbInvoiceTax.LastModifedBy - }; - - if (dbInvoiceTax.LastModifedOn.HasValue) - result.LastModifedOn = TenantUtil.DateTimeFromUtc(result.LastModifedOn.Value); - - return result; - } + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index bb7192fcc4e..88cee0af20d 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -36,9 +36,13 @@ using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; + +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; + using System; using System.Collections.Generic; using System.Globalization; @@ -62,7 +66,8 @@ public CachedTaskDao(DbContextManager dbContextManager, ICache ascCache, IHttpContextAccessor httpContextAccessor, DbContextManager userDbContext, - DbContextManager coreDbContext + DbContextManager coreDbContext, + IMapper mapper ) : base(dbContextManager, tenantManager, @@ -73,7 +78,8 @@ DbContextManager coreDbContext logger, ascCache, userDbContext, - coreDbContext + coreDbContext, + mapper ) { _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_task"); @@ -119,6 +125,7 @@ private void ResetCache(int taskID) [Scope] public class TaskDao : AbstractDao { + private readonly IMapper _mapper; public TaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -128,8 +135,8 @@ public TaskDao(DbContextManager dbContextManager, IOptionsMonitor logger, ICache ascCache, DbContextManager userDbContext, - DbContextManager coreDbContext - ) : + DbContextManager coreDbContext, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, @@ -141,6 +148,7 @@ DbContextManager coreDbContext FactoryIndexer = factoryIndexer; UserDbContext = userDbContext.Value; CoreDbContext = coreDbContext.Value; + _mapper = mapper; } public CoreDbContext CoreDbContext { get; } @@ -195,11 +203,11 @@ public void CloseTask(int taskId) public virtual Task GetByID(int taskID) { - var crmTask = CRMDbContext.Tasks.Where(x => x.Id == taskID).SingleOrDefault(); + var dbTask = CRMDbContext.Tasks.Where(x => x.Id == taskID).SingleOrDefault(); - if (crmTask == default(DbTask)) return null; + if (dbTask == default(DbTask)) return null; - return ToTask(crmTask); + return _mapper.Map(dbTask); } public List GetTasks(EntityType entityType, int entityID, bool? onlyActiveTask) @@ -214,11 +222,10 @@ public int GetAllTasksCount() public List GetAllTasks() { - return Query(CRMDbContext.Tasks) + return _mapper.ProjectTo(Query(CRMDbContext.Tasks) .OrderBy(x => x.Deadline) - .OrderBy(x => x.Title) + .OrderBy(x => x.Title)) .ToList() - .ConvertAll(ToTask) .FindAll(CRMSecurity.CanAccessTo); } @@ -373,7 +380,7 @@ private List GetCrudeTasks( } } - return sqlQuery.ToList().ConvertAll(ToTask); + return _mapper.ProjectTo(sqlQuery).ToList(); } public int GetTasksCount( @@ -469,7 +476,7 @@ public int GetTasksCount( // (x, y) => new { x, y }) // .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) // .Where(x => - + // x.y == null || // x.y.IsShared == null || // x.y.IsShared.Value == ShareType.Read || @@ -507,7 +514,7 @@ public int GetTasksCount( // idsFromAcl.Contains(x.y.Id)) // .Select(x => x.x.Id) // .ToList()); - + //Logger.DebugFormat("End GetTasksCount: {0}. count tasks with entityId and only close contacts", DateTime.Now.ToString()); @@ -665,82 +672,82 @@ private IQueryable GetDbTaskByFilters( switch ((TaskSortedByType)orderBy.SortedBy) { case TaskSortedByType.Title: - { - if (orderBy.IsAsc) - sqlQuery = sqlQuery.OrderBy(x => x.Title) - .ThenBy(x => x.Deadline); - else - sqlQuery = sqlQuery.OrderByDescending(x => x.Title) - .ThenBy(x => x.Deadline); - } + { + if (orderBy.IsAsc) + sqlQuery = sqlQuery.OrderBy(x => x.Title) + .ThenBy(x => x.Deadline); + else + sqlQuery = sqlQuery.OrderByDescending(x => x.Title) + .ThenBy(x => x.Deadline); + } - break; + break; case TaskSortedByType.DeadLine: - { - if (orderBy.IsAsc) - sqlQuery = sqlQuery.OrderBy(x => x.Deadline) - .ThenBy(x => x.Title); - else - sqlQuery = sqlQuery.OrderByDescending(x => x.Deadline) - .ThenBy(x => x.Title); - } - break; + { + if (orderBy.IsAsc) + sqlQuery = sqlQuery.OrderBy(x => x.Deadline) + .ThenBy(x => x.Title); + else + sqlQuery = sqlQuery.OrderByDescending(x => x.Deadline) + .ThenBy(x => x.Title); + } + break; case TaskSortedByType.Category: - { - if (orderBy.IsAsc) - sqlQuery = sqlQuery.OrderBy(x => x.CategoryId) - .ThenBy(x => x.Deadline) - .ThenBy(x => x.Title); - else - sqlQuery = sqlQuery.OrderByDescending(x => x.CategoryId) - .ThenBy(x => x.Deadline) - .ThenBy(x => x.Title); - } + { + if (orderBy.IsAsc) + sqlQuery = sqlQuery.OrderBy(x => x.CategoryId) + .ThenBy(x => x.Deadline) + .ThenBy(x => x.Title); + else + sqlQuery = sqlQuery.OrderByDescending(x => x.CategoryId) + .ThenBy(x => x.Deadline) + .ThenBy(x => x.Title); + } - break; + break; case TaskSortedByType.ContactManager: - { - sqlQuery = sqlQuery.GroupJoin(UserDbContext.Users.Where(x => x.Tenant == TenantID), - x => x.ResponsibleId, - y => y.Id, - (x, y) => new { x, y } - ) - .SelectMany(x => x.y.DefaultIfEmpty(), (x,y) => new { x.x,y }) - .OrderBy("x.y.LastName", orderBy.IsAsc) - .OrderBy("x.y.FirstName", orderBy.IsAsc) - .OrderBy(x => x.x.Deadline) - .OrderBy(x => x.x.Title) - .Select(x => x.x); - } + { + sqlQuery = sqlQuery.GroupJoin(UserDbContext.Users.Where(x => x.Tenant == TenantID), + x => x.ResponsibleId, + y => y.Id, + (x, y) => new { x, y } + ) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }) + .OrderBy("x.y.LastName", orderBy.IsAsc) + .OrderBy("x.y.FirstName", orderBy.IsAsc) + .OrderBy(x => x.x.Deadline) + .OrderBy(x => x.x.Title) + .Select(x => x.x); + } - break; + break; case TaskSortedByType.Contact: + { + var subSqlQuery = sqlQuery.GroupJoin(CRMDbContext.Contacts, + x => x.ContactId, + y => y.Id, + (x, y) => new { x, y } + ) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }); + + if (orderBy.IsAsc) { - var subSqlQuery = sqlQuery.GroupJoin(CRMDbContext.Contacts, - x => x.ContactId, - y => y.Id, - (x, y) => new { x, y } - ) - .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { x.x, y }); - - if (orderBy.IsAsc) - { - subSqlQuery = subSqlQuery.OrderBy(x => x.y != null ? x.y.DisplayName : "") - .ThenBy(x => x.x.Deadline) - .ThenBy(x => x.x.Title); - } - else - { - subSqlQuery = subSqlQuery.OrderByDescending(x => x.y != null ? x.y.DisplayName : "") - .ThenBy(x => x.x.Deadline) - .ThenBy(x => x.x.Title); - - } - - sqlQuery = subSqlQuery.Select(x => x.x); - - break; + subSqlQuery = subSqlQuery.OrderBy(x => x.y != null ? x.y.DisplayName : "") + .ThenBy(x => x.x.Deadline) + .ThenBy(x => x.x.Title); } + else + { + subSqlQuery = subSqlQuery.OrderByDescending(x => x.y != null ? x.y.DisplayName : "") + .ThenBy(x => x.x.Deadline) + .ThenBy(x => x.x.Title); + + } + + sqlQuery = subSqlQuery.Select(x => x.x); + + break; + } } } else @@ -758,7 +765,7 @@ public Dictionary GetNearestTask(int[] contactID) return Query(CRMDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed) .GroupBy(x => x.ContactId) - .ToDictionary(x => x.Key, y => ToTask(y.Single(x => x.Id == y.Min(x => x.Id)))); + .ToDictionary(x => x.Key, y => _mapper.Map(y.Single(x => x.Id == y.Min(x => x.Id)))); } public IEnumerable GetResponsibles(int categoryID) @@ -865,7 +872,7 @@ private Task SaveOrUpdateTaskInDb(Task newTask) var itemToUpdate = Query(CRMDbContext.Tasks).FirstOrDefault(x => x.Id == newTask.ID); - var oldTask = ToTask(itemToUpdate); + var oldTask = _mapper.Map(itemToUpdate); CRMSecurity.DemandEdit(oldTask); @@ -895,7 +902,7 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.IsClosed = oldTask.IsClosed; } - + FactoryIndexer.Index(Query(CRMDbContext.Tasks).Where(x => x.Id == newTask.ID).Single()); return newTask; @@ -1155,31 +1162,5 @@ public void SetTaskLastModifedDate(int taskId, DateTime lastModifedDate) // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); } - - public Task ToTask(DbTask dbTask) - { - if (dbTask == null) return null; - - return new Task - { - ID = dbTask.Id, - AlertValue = dbTask.AlertValue, - CategoryID = dbTask.CategoryId, - ContactID = dbTask.ContactId, - CreateBy = dbTask.CreateBy, - CreateOn = TenantUtil.DateTimeFromUtc(dbTask.CreateOn), - DeadLine = TenantUtil.DateTimeFromUtc(dbTask.Deadline), - Description = dbTask.Description, - IsClosed = dbTask.IsClosed, - EntityID = dbTask.EntityId, - EntityType = dbTask.EntityType, - LastModifedBy = dbTask.LastModifedBy, - LastModifedOn = dbTask.LastModifedOn, - ResponsibleID = dbTask.ResponsibleId, - Title = dbTask.Title - }; - - } } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs index a6f536feeb2..7362d651de8 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -87,7 +87,7 @@ public Expression> SearchContentFields } } } - + public static class DbTaskExtension { public static ModelBuilderWrapper AddDbTask(this ModelBuilderWrapper modelBuilder) diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index 505569f9842..97e85838977 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -49,19 +49,10 @@ public String Title } } - [DataMember(Name = "symbol")] public string Symbol { get; set; } - - [DataMember(Name = "abbreviation")] public string Abbreviation { get; set; } - - [DataMember(Name = "cultureName")] public string CultureName { get; set; } - - [DataMember(Name = "isConvertable")] public bool IsConvertable { get; set; } - - [DataMember(Name = "isBasic")] public bool IsBasic { get; set; } public CurrencyInfo(string resourceKey, string abbreviation, string symbol, string cultureName, bool isConvertable, bool isBasic) diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index 515ea7cb5e0..4a5d31859e8 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -27,12 +27,16 @@ using System; using System.Runtime.Serialization; using ASC.Common.Security; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; + +using AutoMapper; namespace ASC.CRM.Core.Entities { [DataContract] - public class Deal : DomainObject, ISecurityObjectId + public class Deal : DomainObject, ISecurityObjectId, IMapFrom { public Guid CreateBy { get; set; } @@ -111,5 +115,10 @@ public Type ObjectType { get { return GetType(); } } + + public void Mapping(Profile profile) + { + profile.CreateMap(); + } } } diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs index 48c42fd4607..0842696d9e0 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -27,12 +27,15 @@ using System; using System.Runtime.Serialization; using ASC.Common.Security; +using ASC.CRM.Core.EF; +using ASC.CRM.Mapping; +using AutoMapper; namespace ASC.CRM.Core.Entities { [DataContract] - public class InvoiceTax : DomainObject, ISecurityObjectId + public class InvoiceTax : DomainObject, ISecurityObjectId, IMapFrom { [DataMember(Name = "name")] public string Name { get; set; } @@ -65,5 +68,9 @@ public Type ObjectType { get { return GetType(); } } + public void Mapping(Profile profile) + { + profile.CreateMap(); + } } } diff --git a/products/ASC.CRM/Server/Core/Entities/Task.cs b/products/ASC.CRM/Server/Core/Entities/Task.cs index b91a42b4c06..37275a0cc42 100644 --- a/products/ASC.CRM/Server/Core/Entities/Task.cs +++ b/products/ASC.CRM/Server/Core/Entities/Task.cs @@ -27,54 +27,49 @@ #region Usings using System; + using ASC.Common.Security; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; + +using AutoMapper; #endregion namespace ASC.CRM.Core.Entities { - public class Task : DomainObject, ISecurityObjectId + public class Task : DomainObject, ISecurityObjectId, IMapFrom { - public Guid CreateBy { get; set; } - public DateTime CreateOn { get; set; } - public Guid? LastModifedBy { get; set; } - public DateTime? LastModifedOn { get; set; } - public int ContactID { get; set; } - public Contact Contact { get; set; } - public string Title { get; set; } - public string Description { get; set; } - public DateTime DeadLine { get; set; } - public Guid ResponsibleID { get; set; } - public bool IsClosed { get; set; } - public int CategoryID { get; set; } - public EntityType EntityType { get; set; } - public int EntityID { get; set; } - public int AlertValue { get; set; } - public object SecurityId { get { return ID; } } - public Type ObjectType { get { return GetType(); } } + + public void Mapping(Profile profile) + { + profile.CreateMap(); +// .ForMember(x => x.CreateOn, x => x.ConvertUsing()) +// .ForMember(x => x.LastModifedOn, x => x.ConvertUsing()); + } } } diff --git a/products/ASC.CRM/Server/ApiModels/ContactDto.cs b/products/ASC.CRM/Server/Helpers/ContactDtoHelper.cs similarity index 67% rename from products/ASC.CRM/Server/ApiModels/ContactDto.cs rename to products/ASC.CRM/Server/Helpers/ContactDtoHelper.cs index d14b0682aef..c74961e8a37 100644 --- a/products/ASC.CRM/Server/ApiModels/ContactDto.cs +++ b/products/ASC.CRM/Server/Helpers/ContactDtoHelper.cs @@ -1,4 +1,4 @@ -/* +/* * * (c) Copyright Ascensio System Limited 2010-2018 * @@ -25,10 +25,8 @@ using ASC.Api.Core; -using ASC.CRM.Api; using ASC.Common; using ASC.Common.Web; -using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -36,301 +34,15 @@ using ASC.Web.Api.Models; using ASC.Web.CRM; using ASC.Web.CRM.Classes; + using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; + using Contact = ASC.CRM.Core.Entities.Contact; namespace ASC.CRM.ApiModels { - /// - /// Person - /// - [DataContract(Name = "person", Namespace = "")] - public class PersonDto : ContactDto - { - public PersonDto() - { - - } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] - public String FirstName { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] - public String LastName { get; set; } - - - public ContactBaseDto Company { get; set; } - - - public String Title { get; set; } - - public new static PersonDto GetSample() - { - return new PersonDto - { - IsPrivate = true, - IsShared = false, - IsCompany = false, - FirstName = "Tadjeddine", - LastName = "Bachir", - Company = CompanyDto.GetSample(), - Title = "Programmer", - About = "", - Created = ApiDateTime.GetSample(), - CreateBy = EmployeeWraper.GetSample(), - ShareType = ShareType.None - }; - } - } - - [Scope] - public class PersonDtoHelper - { - public PersonDtoHelper() - { - } - - public PersonDto Get(Person person) - { - return new PersonDto - { - FirstName = person.FirstName, - LastName = person.LastName, - Title = person.JobTitle - }; - } - - public PersonDto GetQuick(Person person) - { - return new PersonDto - { - FirstName = person.FirstName, - LastName = person.LastName, - Title = person.JobTitle - }; - } - } - - /// - /// Company - /// - [DataContract(Name = "company", Namespace = "")] - public class CompanyDto : ContactDto - { - public CompanyDto() - { - } - - //public CompanyDto(Company company) - // : base(company) - //{ - // CompanyName = company.CompanyName; - // // PersonsCount = Global.DaoFactory.ContactDao.GetMembersCount(company.ID); - //} - - - - - [DataMember(IsRequired = true, EmitDefaultValue = false)] - public String CompanyName { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] - public IEnumerable Persons { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] - public int PersonsCount { get; set; } - - public new static CompanyDto GetSample() - { - return new CompanyDto - { - IsPrivate = true, - IsShared = false, - IsCompany = true, - About = "", - CompanyName = "Food and Culture Project", - PersonsCount = 0 - }; - } - } - - [DataContract(Name = "contact", Namespace = "")] - [KnownType(typeof(PersonDto))] - [KnownType(typeof(CompanyDto))] - public abstract class ContactDto : ContactBaseDto - { - public ContactDto() - { - - } - - //protected ContactDto(Contact contact) - // : base(contact) - //{ - // CreateBy = EmployeeWraper.Get(contact.CreateBy); - // Created = (ApiDateTime)contact.CreateOn; - // About = contact.About; - // Industry = contact.Industry; - //} - - - public IEnumerable
    Addresses { get; set; } - public EmployeeWraper CreateBy { get; set; } - public ApiDateTime Created { get; set; } - public String About { get; set; } - public String Industry { get; set; } - public ContactStatusBaseDto ContactStatus { get; set; } - public ContactTypeBaseDto ContactType { get; set; } - public IEnumerable CommonData { get; set; } - public IEnumerable CustomFields { get; set; } - public IEnumerable Tags { get; set; } - public int TaskCount { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool HaveLateTasks { get; set; } - public new static ContactDto GetSample() - { - return new PersonDto - { - IsPrivate = true, - IsShared = false, - IsCompany = false, - FirstName = "Tadjeddine", - LastName = "Bachir", - Company = CompanyDto.GetSample(), - Title = "Programmer", - About = "", - Created = ApiDateTime.GetSample(), - CreateBy = EmployeeWraper.GetSample(), - CommonData = new List() { ContactInfoDto.GetSample() }, - CustomFields = new List() { CustomFieldBaseDto.GetSample() }, - ShareType = ShareType.None, - CanDelete = true, - CanEdit = true, - TaskCount = 0, - HaveLateTasks = false - }; - } - } - - [DataContract(Name = "contactBase", Namespace = "")] - public class ContactBaseWithEmailDto : ContactBaseDto - { - public ContactInfoDto Email { get; set; } - } - - - [DataContract(Name = "contactBase", Namespace = "")] - public class ContactBaseWithPhoneDto : ContactBaseDto - { - public ContactInfoDto Phone { get; set; } - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /// - /// Contact base information - /// - [DataContract(Name = "contactBase", Namespace = "")] - public class ContactBaseDto - { - public ContactBaseDto() - { - - } - - [DataMember(Name = "id")] - public int Id { get; set; } - public String SmallFotoUrl { get; set; } - public String MediumFotoUrl { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public String DisplayName { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsCompany { get; set; } - public IEnumerable AccessList { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsPrivate { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsShared { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public ShareType ShareType { get; set; } - - - public CurrencyInfoDto Currency { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanDelete { get; set; } - - public static ContactBaseDto GetSample() - { - return new ContactBaseDto - { - IsPrivate = true, - IsShared = false, - IsCompany = false, - DisplayName = "Tadjeddine Bachir", - SmallFotoUrl = "url to foto" - }; - } - } - - [DataContract(Name = "contact_task", Namespace = "")] - public class ContactWithTaskDto - { - - public TaskBaseDto Task { get; set; } - - - public ContactDto Contact { get; set; } - } - [Scope] public class ContactDtoHelper { @@ -353,14 +65,14 @@ public ContactDtoHelper(ApiDateTimeHelper apiDateTimeHelper, ContactInfoDtoHelper = contactInfoDtoHelper; } - public ContactInfoDtoHelper ContactInfoDtoHelper { get; } - public DaoFactory DaoFactory { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public CRMSecurity CRMSecurity { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeDtoHelper { get; } - public CurrencyProvider CurrencyProvider { get; } - public PathProvider PathProvider { get; } + public ContactInfoDtoHelper ContactInfoDtoHelper; + public DaoFactory DaoFactory; + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper; + public CRMSecurity CRMSecurity; + public ApiDateTimeHelper ApiDateTimeHelper; + public EmployeeWraperHelper EmployeeDtoHelper; + public CurrencyProvider CurrencyProvider; + public PathProvider PathProvider; public ContactBaseDto GetContactBaseDtoQuick(Contact contact) { diff --git a/products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs new file mode 100644 index 00000000000..b92df989c21 --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs @@ -0,0 +1,55 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.CRM.Core; + +namespace ASC.CRM.ApiModels +{ + [Scope] + public class ContactInfoDtoHelper + { + public ContactInfoDtoHelper() + { + } + + public ContactInfoDto Get(ContactInfo contactInfo) + { + if (contactInfo == null) return null; + + return new ContactInfoDto + { + InfoType = contactInfo.InfoType, + Category = contactInfo.Category, + CategoryName = contactInfo.CategoryToString(), + Data = contactInfo.Data, + IsPrimary = contactInfo.IsPrimary, + Id = contactInfo.ID + }; + } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs new file mode 100644 index 00000000000..d712023a10a --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs @@ -0,0 +1,54 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.CRM.Core; + +namespace ASC.CRM.ApiModels +{ + [Singletone] + public class CurrencyInfoDtoHelper + { + public CurrencyInfoDtoHelper() + { + } + + public CurrencyInfoDto Get(CurrencyInfo currencyInfo) + { + if (currencyInfo == null) return null; + + return new CurrencyInfoDto + { + Abbreviation = currencyInfo.Abbreviation, + CultureName = currencyInfo.CultureName, + Symbol = currencyInfo.Symbol, + Title = currencyInfo.Title, + IsConvertable = currencyInfo.IsConvertable, + IsBasic = currencyInfo.IsBasic + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs new file mode 100644 index 00000000000..825db22db3d --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs @@ -0,0 +1,49 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.CRM.Core; + +namespace ASC.CRM.ApiModels +{ + [Scope] + public class CurrencyRateDtoHelper + { + public CurrencyRateDtoHelper() + { + } + + public CurrencyRateDto Get(CurrencyRate currencyRate) + { + return new CurrencyRateDto + { + FromCurrency = currencyRate.FromCurrency, + ToCurrency = currencyRate.ToCurrency, + Rate = currencyRate.Rate + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs new file mode 100644 index 00000000000..bc52d3c97c3 --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs @@ -0,0 +1,58 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.CRM.Core; + +namespace ASC.CRM.ApiModels +{ + [Scope] + public class CurrencyRateInfoDtoHelper + { + public CurrencyRateInfoDtoHelper(CurrencyInfoDtoHelper currencyInfoDtoHelper) + { + CurrencyInfoDtoHelper = currencyInfoDtoHelper; + } + + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper; + + public CurrencyRateInfoDto Get(CurrencyInfo currencyInfo, decimal rate) + { + var currencyInfoDto = CurrencyInfoDtoHelper.Get(currencyInfo); + + return new CurrencyRateInfoDto + { + Abbreviation = currencyInfoDto.Abbreviation, + CultureName = currencyInfoDto.CultureName, + Symbol = currencyInfoDto.Symbol, + Title = currencyInfoDto.Title, + IsConvertable = currencyInfoDto.IsConvertable, + IsBasic = currencyInfoDto.IsBasic, + Rate = rate + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs b/products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs new file mode 100644 index 00000000000..d8fa4c8231f --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs @@ -0,0 +1,52 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.CRM.Core.Entities; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM.Configuration; + +namespace ASC.CRM.ApiModels +{ + [Scope] + public sealed class HistoryCategoryDtoHelper + { + public HistoryCategoryDtoHelper(WebImageSupplier webImageSupplier) + { + WebImageSupplier = webImageSupplier; + } + + public WebImageSupplier WebImageSupplier; + + public HistoryCategoryBaseDto Get(ListItem listItem) + { + return new HistoryCategoryBaseDto(listItem) + { + ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs b/products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs new file mode 100644 index 00000000000..b2ff6f772e8 --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs @@ -0,0 +1,123 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Api.Core; +using ASC.Common; +using ASC.Core.Common.Settings; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; + +using System; + +namespace ASC.CRM.ApiModels +{ + [Scope] + public class InvoiceBaseDtoHelper + { + private EntityDtoHelper _entityDtoHelper; + private ContactDtoHelper _contactDtoHelper; + private CurrencyInfoDtoHelper _currencyInfoDtoHelper; + private InvoiceStatusDtoHelper _invoiceStatusDtoHelper; + private CurrencyProvider _currencyProvider; + private SettingsManager _settingsManager; + private CRMSecurity CRMSecurity; + private ApiDateTimeHelper _apiDateTimeHelper; + private EmployeeWraperHelper _employeeWraperHelper; + private DaoFactory _daoFactory; + + public InvoiceBaseDtoHelper(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + InvoiceStatusDtoHelper invoiceStatusDtoHelper, + CurrencyInfoDtoHelper currencyInfoDtoHelper, + DaoFactory daoFactory, + ContactDtoHelper contactDtoHelper, + EntityDtoHelper entityDtoHelper) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + CRMSecurity = cRMSecurity; + _settingsManager = settingsManager; + _currencyProvider = currencyProvider; + _invoiceStatusDtoHelper = invoiceStatusDtoHelper; + _daoFactory = daoFactory; + _currencyInfoDtoHelper = currencyInfoDtoHelper; + _contactDtoHelper = contactDtoHelper; + _entityDtoHelper = entityDtoHelper; + } + + public InvoiceBaseDto Get(Invoice invoice) + { + + var result = new InvoiceBaseDto + { + Id = invoice.ID, + Status = _invoiceStatusDtoHelper.Get(invoice.Status), + Number = invoice.Number, + IssueDate = _apiDateTimeHelper.Get(invoice.IssueDate), + TemplateType = invoice.TemplateType, + DueDate = _apiDateTimeHelper.Get(invoice.DueDate), + Currency = !String.IsNullOrEmpty(invoice.Currency) ? + _currencyInfoDtoHelper.Get(_currencyProvider.Get(invoice.Currency)) : + _currencyInfoDtoHelper.Get(_settingsManager.Load().DefaultCurrency), + ExchangeRate = invoice.ExchangeRate, + Language = invoice.Language, + PurchaseOrderNumber = invoice.PurchaseOrderNumber, + Terms = invoice.Terms, + Description = invoice.Description, + FileID = invoice.FileID, + CreateOn = _apiDateTimeHelper.Get(invoice.CreateOn), + CreateBy = _employeeWraperHelper.Get(invoice.CreateBy), + CanEdit = CRMSecurity.CanEdit(invoice), + CanDelete = CRMSecurity.CanDelete(invoice) + }; + + if (invoice.ContactID > 0) + { + result.Contact = _contactDtoHelper.GetContactBaseWithEmailDto(_daoFactory.GetContactDao().GetByID(invoice.ContactID)); + } + + if (invoice.ConsigneeID > 0) + { + result.Consignee = _contactDtoHelper.GetContactBaseWithEmailDto(_daoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); + } + + if (invoice.EntityID > 0) + { + result.Entity = _entityDtoHelper.Get(invoice.EntityType, invoice.EntityID); + } + + result.Cost = invoice.GetInvoiceCost(_daoFactory); + + return result; + + } + } +} diff --git a/products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs b/products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs new file mode 100644 index 00000000000..73a865fd18c --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs @@ -0,0 +1,55 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Common; +using ASC.CRM.Core.Entities; + +namespace ASC.CRM.ApiModels +{ + [Singletone] + public class InvoiceLineDtoHelper + { + public InvoiceLineDtoHelper() + { + } + + public InvoiceLineDto Get(InvoiceLine invoiceLine) + { + return new InvoiceLineDto + { + Id = invoiceLine.ID, + InvoiceID = invoiceLine.InvoiceID, + InvoiceItemID = invoiceLine.InvoiceItemID, + InvoiceTax1ID = invoiceLine.InvoiceTax1ID, + InvoiceTax2ID = invoiceLine.InvoiceTax2ID, + SortOrder = invoiceLine.SortOrder, + Description = invoiceLine.Description, + Quantity = invoiceLine.Quantity, + Price = invoiceLine.Price, + Discount = invoiceLine.Discount + }; + } + } +} diff --git a/products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs b/products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs new file mode 100644 index 00000000000..763a1ecf32e --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs @@ -0,0 +1,48 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Common; +using ASC.CRM.Classes; +using ASC.CRM.Core.Enums; + +namespace ASC.CRM.ApiModels +{ + [Singletone] + public class InvoiceStatusDtoHelper + { + public InvoiceStatusDtoHelper() + { + } + + public InvoiceStatusDto Get(InvoiceStatus status) + { + return new InvoiceStatusDto + { + Id = (int)status, + Title = status.ToLocalizedString() + }; + } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs b/products/ASC.CRM/Server/Helpers/OpportunityDtoHelper.cs similarity index 65% rename from products/ASC.CRM/Server/ApiModels/OpportunityDto.cs rename to products/ASC.CRM/Server/Helpers/OpportunityDtoHelper.cs index 9cc02cdd47c..4a8cb7f956c 100644 --- a/products/ASC.CRM/Server/ApiModels/OpportunityDto.cs +++ b/products/ASC.CRM/Server/Helpers/OpportunityDtoHelper.cs @@ -1,4 +1,4 @@ -/* +/* * * (c) Copyright Ascensio System Limited 2010-2018 * @@ -33,72 +33,12 @@ using ASC.CRM.Core.Enums; using ASC.Web.Api.Models; using ASC.Web.CRM.Classes; -using System; + using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; namespace ASC.CRM.ApiModels { - /// - /// Opportunity - /// - [DataContract(Name = "opportunity", Namespace = "")] - public class OpportunityDto - { - - public OpportunityDto() - { - } - - [DataMember(Name = "id")] - public int Id { get; set; } - public EmployeeWraper CreateBy { get; set; } - public ApiDateTime Created { get; set; } - public IEnumerable Members { get; set; } - public ContactBaseDto Contact { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] - public String Title { get; set; } - public String Description { get; set; } - public EmployeeWraper Responsible { get; set; } - public BidType BidType { get; set; } - public decimal BidValue { get; set; } - public CurrencyInfoDto BidCurrency { get; set; } - public int PerPeriodValue { get; set; } - public DealMilestoneBaseDto Stage { get; set; } - public int SuccessProbability { get; set; } - public ApiDateTime ActualCloseDate { get; set; } - public ApiDateTime ExpectedCloseDate { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool IsPrivate { get; set; } - public IEnumerable AccessList { get; set; } - - [DataMember(IsRequired = false, EmitDefaultValue = true)] - public bool CanEdit { get; set; } - public IEnumerable CustomFields { get; set; } - - public static OpportunityDto GetSample() - { - return new OpportunityDto - { - CreateBy = EmployeeWraper.GetSample(), - Created = ApiDateTime.GetSample(), - Responsible = EmployeeWraper.GetSample(), - Title = "Hotel catalogue", - Description = "", - ExpectedCloseDate = ApiDateTime.GetSample(), - Contact = ContactBaseDto.GetSample(), - IsPrivate = false, - SuccessProbability = 65, - BidType = BidType.FixedBid, - Stage = DealMilestoneBaseDto.GetSample() - }; - } - } - - [Scope] public class OpportunityDtoHelper { @@ -120,14 +60,13 @@ CurrencyInfoDtoHelper currencyInfoDtoHelper CurrencyInfoDtoHelper = currencyInfoDtoHelper; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public CurrencyProvider CurrencyProvider {get;} - public ContactDtoHelper ContactBaseDtoHelper { get; } - public DaoFactory DaoFactory { get; } - - public CRMSecurity CRMSecurity { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } + public CurrencyInfoDtoHelper CurrencyInfoDtoHelper; + public CurrencyProvider CurrencyProvider; + public ContactDtoHelper ContactBaseDtoHelper; + public DaoFactory DaoFactory; + public CRMSecurity CRMSecurity; + public ApiDateTimeHelper ApiDateTimeHelper; + public EmployeeWraperHelper EmployeeWraperHelper; public OpportunityDto Get(Deal deal) { diff --git a/products/ASC.CRM/Server/Helpers/TaskCategoryDtoHelper.cs b/products/ASC.CRM/Server/Helpers/TaskCategoryDtoHelper.cs new file mode 100644 index 00000000000..9b248fd91e4 --- /dev/null +++ b/products/ASC.CRM/Server/Helpers/TaskCategoryDtoHelper.cs @@ -0,0 +1,52 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using ASC.Common; +using ASC.CRM.Core.Entities; +using ASC.Web.Core.Utility.Skins; +using ASC.Web.CRM.Configuration; + +namespace ASC.CRM.ApiModels +{ + [Scope] + public sealed class TaskCategoryDtoHelper + { + public TaskCategoryDtoHelper(WebImageSupplier webImageSupplier) + { + WebImageSupplier = webImageSupplier; + } + + public WebImageSupplier WebImageSupplier; + + public TaskCategoryBaseDto Get(ListItem listItem) + { + return new TaskCategoryBaseDto(listItem) + { + ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs b/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs similarity index 70% rename from products/ASC.CRM/Server/ApiModels/VoipCallDto.cs rename to products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs index 65dd47c03b2..2e12ab2b8ff 100644 --- a/products/ASC.CRM/Server/ApiModels/VoipCallDto.cs +++ b/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs @@ -1,4 +1,4 @@ -/* +/* * * (c) Copyright Ascensio System Limited 2010-2018 * @@ -29,42 +29,23 @@ using ASC.VoipService; using ASC.Web.Api.Models; -using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; namespace ASC.CRM.ApiModels { - [DataContract(Name = "voipCall", Namespace = "")] - public class VoipCallDto - { - public string Id { get; set; } - public string From { get; set; } - public string To { get; set; } - public VoipCallStatus? Status { get; set; } - public EmployeeWraper AnsweredBy { get; set; } - public ApiDateTime DialDate { get; set; } - public int DialDuration { get; set; } - public decimal Cost { get; set; } - public ContactDto Contact { get; set; } - public IEnumerable Calls { get; set; } - public string RecordUrl { get; set; } - public int RecordDuration { get; set; } - - } - [Scope] public class VoipCallDtoHelper { + private ApiDateTimeHelper _apiDateTimeHelper; + private EmployeeWraperHelper _employeeWraperHelper; + public VoipCallDtoHelper(EmployeeWraperHelper employeeWraper, ApiDateTimeHelper apiDateTimeHelper) { - EmployeeWraperHelper = employeeWraper; - ApiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraper; + _apiDateTimeHelper = apiDateTimeHelper; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } public VoipCallDto Get(VoipCall call, ContactDto contact = null) { var result = new VoipCallDto @@ -73,8 +54,8 @@ public VoipCallDto Get(VoipCall call, ContactDto contact = null) From = call.From, To = call.To, Status = call.Status, - AnsweredBy = EmployeeWraperHelper.Get(call.AnsweredBy), - DialDate = ApiDateTimeHelper.Get(call.DialDate), + AnsweredBy = _employeeWraperHelper.Get(call.AnsweredBy), + DialDate = _apiDateTimeHelper.Get(call.DialDate), DialDuration = call.DialDuration, Cost = call.Price + call.ChildCalls.Sum(r => r.Price) + call.VoipRecord.Price, Contact = contact, diff --git a/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs b/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs new file mode 100644 index 00000000000..2caca450d47 --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs @@ -0,0 +1,34 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public interface IMapFrom + { + void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType()); + } +} diff --git a/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs b/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs new file mode 100644 index 00000000000..7847a48360f --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs @@ -0,0 +1,60 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System; +using System.Linq; +using System.Reflection; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public class MappingProfile : Profile + { + public MappingProfile() + { + ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly()); + } + + private void ApplyMappingsFromAssembly(Assembly assembly) + { + var types = assembly.GetExportedTypes() + .Where(t => t.GetInterfaces().Any(i => + i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>))) + .ToList(); + + foreach (var type in types) + { + var instance = Activator.CreateInstance(type); + + var methodInfo = type.GetMethod("Mapping") + ?? type.GetInterface("IMapFrom`1").GetMethod("Mapping"); + + methodInfo?.Invoke(instance, new object[] { this }); + + } + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs new file mode 100644 index 00000000000..7f11135c59c --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs @@ -0,0 +1,112 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.Core; +using ASC.Core.Users; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public class CasesDtoTypeConverter : ITypeConverter + { + private readonly ContactDtoHelper _contactBaseDtoHelper; + private readonly DaoFactory _daoFactory; + private readonly CRMSecurity _CRMSecurity; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + + public CasesDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ContactDtoHelper contactBaseDtoHelper) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _CRMSecurity = cRMSecurity; + _daoFactory = daoFactory; + _contactBaseDtoHelper = contactBaseDtoHelper; + } + + public CasesDto Convert(Cases source, CasesDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new CasesDto(); + + result.Title = source.Title; + result.IsClosed = source.IsClosed; + result.IsPrivate = _CRMSecurity.IsPrivate(source); + result.Created = _apiDateTimeHelper.Get(source.CreateOn); + result.CreateBy = _employeeWraperHelper.Get(source.CreateBy); + result.CanEdit = _CRMSecurity.CanEdit(source); + + if (result.IsPrivate) + { + result.AccessList = _CRMSecurity.GetAccessSubjectTo(source) + .SkipWhile(item => item.Key == Constants.GroupEveryone.ID) + .Select(item => _employeeWraperHelper.Get(item.Key)); + } + + result.CustomFields = _daoFactory + .GetCustomFieldDao() + .GetEnityFields(EntityType.Case, source.ID, false) + .ConvertAll(item => new CustomFieldBaseDto(item)); + + result.Members = new List(); + + var memberIDs = _daoFactory.GetCasesDao().GetMembers(source.ID); + var membersList = _daoFactory.GetContactDao().GetContacts(memberIDs); + + var membersDtoList = new List(); + + foreach (var member in membersList) + { + if (member == null) continue; + + membersDtoList.Add(_contactBaseDtoHelper.GetContactBaseDto(member)); + } + + result.Members = membersDtoList; + + return destination; + } + } +} + + diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs new file mode 100644 index 00000000000..a4954ae8078 --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs @@ -0,0 +1,109 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using ASC.Api.Core; +using ASC.Common; +using ASC.Core.Common.Settings; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; + +using AutoMapper; + +using System; + +namespace ASC.CRM.Mapping +{ + public class InvoiceItemDtoTypeConverter : ITypeConverter + { + private CurrencyInfoDtoHelper _currencyInfoDtoHelper; + private DaoFactory _daoFactory; + private CurrencyProvider _currencyProvider; + private SettingsManager _settingsManager; + private ApiDateTimeHelper _apiDateTimeHelper; + private EmployeeWraperHelper _employeeWraperHelper; + private CRMSecurity _CRMSecurity; + + public InvoiceItemDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + DaoFactory daoFactory, + CurrencyInfoDtoHelper currencyInfoDtoHelper) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _CRMSecurity = cRMSecurity; + _settingsManager = settingsManager; + _currencyProvider = currencyProvider; + _daoFactory = daoFactory; + _currencyInfoDtoHelper = currencyInfoDtoHelper; + } + + public InvoiceItemDto Convert(InvoiceItem source, InvoiceItemDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new InvoiceItemDto + { + + Title = source.Title, + StockKeepingUnit = source.StockKeepingUnit, + Description = source.Description, + Price = source.Price, + StockQuantity = source.StockQuantity, + TrackInvenory = source.TrackInventory, + CreateOn = _apiDateTimeHelper.Get(source.CreateOn), + CreateBy = _employeeWraperHelper.Get(source.CreateBy), + Currency = !String.IsNullOrEmpty(source.Currency) ? + _currencyInfoDtoHelper.Get(_currencyProvider.Get(source.Currency)) : + _currencyInfoDtoHelper.Get(_settingsManager.Load().DefaultCurrency), + CanEdit = _CRMSecurity.CanEdit(source), + CanDelete = _CRMSecurity.CanDelete(source) + }; + + if (source.InvoiceTax1ID > 0) + { + var invoiceTax1ID = _daoFactory.GetInvoiceTaxDao().GetByID(source.InvoiceTax1ID); + + result.InvoiceTax1 = context.Mapper.Map(invoiceTax1ID); + } + + if (source.InvoiceTax2ID > 0) + { + var invoiceTax2ID = _daoFactory.GetInvoiceTaxDao().GetByID(source.InvoiceTax2ID); + + result.InvoiceTax2 = context.Mapper.Map(invoiceTax2ID); + } + + return result; + } + } +} diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs new file mode 100644 index 00000000000..ec86eb42750 --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs @@ -0,0 +1,73 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System; + +using ASC.Api.Core; +using ASC.Common; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public class InvoiceTaxTypeConverter : ITypeConverter + { + private ApiDateTimeHelper _apiDateTimeHelper; + private EmployeeWraperHelper _employeeWraperHelper; + private CRMSecurity _CRMSecurity; + + public InvoiceTaxTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _CRMSecurity = cRMSecurity; + } + + public InvoiceTaxDto Convert(InvoiceTax source, InvoiceTaxDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new InvoiceTaxDto(); + + result.Id = source.ID; + result.Name = source.Name; + result.Description = source.Description; + result.Rate = source.Rate; + result.CreateOn = _apiDateTimeHelper.Get(source.CreateOn); + result.CreateBy = _employeeWraperHelper.Get(source.CreateBy); + result.CanEdit = _CRMSecurity.CanEdit(source); + result.CanDelete = _CRMSecurity.CanDelete(source); + + return result; + } + } +} diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs new file mode 100644 index 00000000000..634f7d0e2ef --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs @@ -0,0 +1,125 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System; + +using ASC.Api.Core; +using ASC.Common; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public class TaskDtoTypeConverter : ITypeConverter, + ITypeConverter + { + private readonly ContactDtoHelper _contactBaseDtoHelper; + private readonly CRMSecurity _CRMSecurity; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly DaoFactory _daoFactory; + private readonly EntityDtoHelper _entityDtoHelper; + + public TaskDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + DaoFactory daoFactory, + ContactDtoHelper contactBaseDtoHelper, + EntityDtoHelper entityDtoHelper) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _CRMSecurity = cRMSecurity; + _daoFactory = daoFactory; + _contactBaseDtoHelper = contactBaseDtoHelper; + _entityDtoHelper = entityDtoHelper; + + } + + public TaskDto Convert(Task source, TaskDto destination, ResolutionContext context) + { + var result = new TaskDto + { + Title = source.Title, + Description = source.Description, + DeadLine = _apiDateTimeHelper.Get(source.DeadLine), + Responsible = _employeeWraperHelper.Get(source.ResponsibleID), + IsClosed = source.IsClosed, + AlertValue = source.AlertValue, + Created = _apiDateTimeHelper.Get(source.CreateOn) + }; + + if (source.CategoryID > 0) + { + var categoryItem = _daoFactory.GetListItemDao().GetByID(source.CategoryID); + + result.Category = new TaskCategoryDto(categoryItem) + { + RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, categoryItem.ID) + }; + + } + + if (source.ContactID > 0) + { + result.Contact = _contactBaseDtoHelper.GetContactBaseWithEmailDto(_daoFactory.GetContactDao().GetByID(source.ContactID)); + } + + if (source.EntityID > 0) + { + + result.Entity = _entityDtoHelper.Get(source.EntityType, source.EntityID); + } + + result.CanEdit = _CRMSecurity.CanEdit(source); + + return result; + } + + public TaskBaseDto Convert(Task source, TaskBaseDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + return new TaskBaseDto + { + Title = source.Title, + Description = source.Description, + DeadLine = _apiDateTimeHelper.Get(source.DeadLine), + Responsible = _employeeWraperHelper.Get(source.ResponsibleID), + IsClosed = source.IsClosed, + AlertValue = source.AlertValue + }; + } + } +} + + diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 7793075b76b..a2c16992f0f 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,8 +1,11 @@ +using System.Reflection; using System.Text; using ASC.Api.Core; using ASC.Common; using ASC.CRM.Api; +using ASC.CRM.Core; +using ASC.CRM.Mapping; using ASC.Web.CRM.HttpHandlers; using Microsoft.AspNetCore.Builder; @@ -44,6 +47,8 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); + + services.AddAutoMapper(Assembly.GetExecutingAssembly()); } public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) From 6da70a14491bc68bf618c7672b1c3a8d9785e67e Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 19 Mar 2021 19:56:26 +0300 Subject: [PATCH 25/61] crm: refactoring --- .../ASC.CRM/Server/Api/BaseApiController.cs | 34 +- .../ASC.CRM/Server/Api/CasesController.cs | 157 +++--- .../Server/Api/ContactInfosController.cs | 145 +++-- .../ASC.CRM/Server/Api/ContactsController.cs | 511 +++++++++--------- .../Server/Api/CurrencyRatesController.cs | 68 ++- .../Server/Api/CustomFieldsController.cs | 64 ++- .../ASC.CRM/Server/Api/DealsController.cs | 176 +++--- .../ASC.CRM/Server/Api/InvoicesController.cs | 439 ++++++++------- .../ASC.CRM/Server/Api/ListItemsController.cs | 178 +++--- .../Api/RelationshipEventsController.cs | 108 ++-- .../ASC.CRM/Server/Api/ReportsController.cs | 40 +- products/ASC.CRM/Server/Api/TagsController.cs | 104 ++-- .../Server/Api/TaskTemplateController.cs | 64 +-- .../ASC.CRM/Server/Api/TasksController.cs | 92 ++-- .../ASC.CRM/Server/Api/UtilsController.cs | 49 +- products/ASC.CRM/Server/Api/VoipController.cs | 134 ++--- .../CreateOrUpdateCasesRequestDto.cs | 2 - .../CreateOrUpdateDealRequestDto.cs | 2 - .../CreateOrUpdateInvoiceItemRequestDto.cs | 7 +- .../CreateOrUpdateInvoiceLineRequestDto.cs | 7 +- .../CreateOrUpdateInvoiceRequestDto.cs | 5 +- .../CreateOrUpdateInvoiceTaxRequestDto.cs | 7 +- .../CreateOrUpdatePersonRequestDto.cs | 7 +- .../SaveNumberSettingsRequestDto.cs | 7 +- .../SendMailSMTPToContactsRequestDto.cs | 2 - .../SetAccessToBatchCasesRequestDto.cs | 2 - .../SetAccessToBatchContactRequestDto.cs | 7 +- .../SetAccessToBatchDealByFilterRequestDto.cs | 3 - .../Server/ApiModels/ResponsesDto/CasesDto.cs | 26 +- .../ApiModels/ResponsesDto/ContactDto.cs | 86 +-- .../ApiModels/ResponsesDto/ContactInfoDto.cs | 20 +- .../ApiModels/ResponsesDto/CurrencyInfoDto.cs | 29 +- .../ApiModels/ResponsesDto/CurrencyRateDto.cs | 19 +- .../ApiModels/ResponsesDto/CustomFieldDto.cs | 55 +- .../ApiModels/ResponsesDto/InvoiceDto.cs | 59 +- .../ResponsesDto/InvoiceDtoHelper.cs | 130 ----- .../ApiModels/ResponsesDto/InvoiceItemDto.cs | 30 +- .../ApiModels/ResponsesDto/InvoiceLineDto.cs | 23 +- .../ResponsesDto/InvoiceStatusDto.cs | 15 +- .../ApiModels/ResponsesDto/InvoiceTaxDto.cs | 20 +- .../ApiModels/ResponsesDto/ListItemDto.cs | 198 +++---- .../ApiModels/ResponsesDto/OpportunityDto.cs | 46 +- .../ResponsesDto/RelationshipEventDto.cs | 107 +--- .../ApiModels/ResponsesDto/ReportDto.cs | 8 +- .../Server/ApiModels/ResponsesDto/TaskDto.cs | 50 +- .../ResponsesDto/TaskTemplateContainerDto.cs | 47 +- .../ApiModels/ResponsesDto/VoipCallDto.cs | 7 +- products/ASC.CRM/Server/ApiModels/Subject.cs | 2 +- .../ASC.CRM/Server/Classes/CRMCalendar.cs | 8 +- .../ASC.CRM/Server/Classes/CRMSettings.cs | 83 +-- products/ASC.CRM/Server/Classes/CSVReader.cs | 4 +- .../Server/Classes/CSVReaderExtension.cs | 1 - .../Server/Classes/ContactPhotoManager.cs | 18 +- products/ASC.CRM/Server/Classes/Global.cs | 33 +- .../Server/Classes/ImportFromCSVManager.cs | 14 +- .../Server/Classes/InvoiceFormattedData.cs | 12 +- .../Server/Classes/LocalizedEnumConverter.cs | 22 +- .../Server/Classes/OrganisationLogoManager.cs | 8 +- .../ASC.CRM/Server/Classes/PathProvider.cs | 10 +- .../ASC.CRM/Server/Classes/SignalRHelper.cs | 5 +- .../ASC.CRM/Server/Classes/StringConverter.cs | 2 +- .../Server/Classes/SubscriptionManager.cs | 10 +- .../CRMsSpaceUsageStatManager.cs | 9 +- .../Server/Configuration/ProductEntryPoint.cs | 293 +++++----- .../Server/Configuration/VoipModule.cs | 14 +- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 43 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 35 +- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 150 ++--- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 80 +-- .../Server/Core/Dao/CurrencyInfoDao.cs | 14 +- .../Server/Core/Dao/CurrencyRateDao.cs | 31 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 24 +- .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 6 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 134 ++--- .../Server/Core/Dao/DealMilestoneDao.cs | 9 +- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 6 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 51 +- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 36 +- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 35 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 21 +- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 138 ++--- .../Server/Core/Dao/RelationshipEventDao.cs | 56 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 34 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 17 +- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 62 ++- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 39 +- .../Core/Dao/TaskTemplateContainerDao.cs | 36 +- products/ASC.CRM/Server/Core/DomainObject.cs | 7 +- .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 10 +- products/ASC.CRM/Server/Core/EF/DbCase.cs | 10 +- products/ASC.CRM/Server/Core/EF/DbContact.cs | 42 +- .../ASC.CRM/Server/Core/EF/DbContactInfo.cs | 26 +- .../ASC.CRM/Server/Core/EF/DbCurrencyRate.cs | 4 +- products/ASC.CRM/Server/Core/EF/DbDeal.cs | 9 +- .../ASC.CRM/Server/Core/EF/DbEntityContact.cs | 11 +- .../ASC.CRM/Server/Core/EF/DbFieldValue.cs | 21 +- products/ASC.CRM/Server/Core/EF/DbInvoice.cs | 54 +- products/ASC.CRM/Server/Core/EF/DbListItem.cs | 17 +- products/ASC.CRM/Server/Core/EF/DbProjects.cs | 5 +- .../Server/Core/EF/DbRelationshipEvent.cs | 30 +- products/ASC.CRM/Server/Core/EF/DbTag.cs | 9 +- products/ASC.CRM/Server/Core/EF/DbTask.cs | 18 +- .../Server/Core/EF/DbTaskTemplateTask.cs | 2 +- .../ASC.CRM/Server/Core/Entities/Cases.cs | 1 + .../ASC.CRM/Server/Core/Entities/Contact.cs | 4 +- .../Server/Core/Entities/ContactInfo.cs | 5 +- .../Server/Core/Entities/CurrencyInfo.cs | 5 +- .../Server/Core/Entities/CustomField.cs | 10 +- products/ASC.CRM/Server/Core/Entities/Deal.cs | 9 +- .../Server/Core/Entities/DealMilestone.cs | 7 +- .../ASC.CRM/Server/Core/Entities/Filter.cs | 11 +- .../ASC.CRM/Server/Core/Entities/Invoice.cs | 9 +- .../Server/Core/Entities/InvoiceItem.cs | 1 + .../Server/Core/Entities/InvoiceLine.cs | 3 - .../Server/Core/Entities/InvoiceTax.cs | 7 +- .../ASC.CRM/Server/Core/Entities/ListItem.cs | 4 +- .../Server/Core/Entities/ListItemHistory.cs | 5 +- .../ASC.CRM/Server/Core/Entities/OrderBy.cs | 4 +- .../Server/Core/Entities/RelationshipEvent.cs | 24 +- .../ASC.CRM/Server/Core/Entities/Report.cs | 3 +- products/ASC.CRM/Server/Core/Entities/Task.cs | 4 +- .../Core/Entities/TaskTemplateContainer.cs | 8 +- .../Core/Enums/ContactInfoCategoryEnum.cs | 9 +- .../Server/Core/Enums/ContactInfoTypeEnum.cs | 1 + .../Core/Enums/ContactListViewTypeEnum.cs | 1 + .../Server/Core/Enums/CustomFieldTypeEnum.cs | 1 + .../Server/Core/Enums/DealMilestoneStatus.cs | 3 +- .../Server/Core/Enums/EntityTypeEnum.cs | 5 +- .../Server/Core/Enums/InvoiceStatus.cs | 3 +- .../Core/Enums/InvoiceTemplateTypeEnum.cs | 1 + .../ASC.CRM/Server/Core/Enums/ListTypeEnum.cs | 3 +- .../Server/Core/Enums/SortedByTypeEnum.cs | 2 +- .../Server/Core/Search/BundleSearch.cs | 6 +- .../Server/Core/Search/FactoryIndexerCase.cs | 4 +- .../Core/Search/FactoryIndexerContact.cs | 2 - .../Core/Search/FactoryIndexerContactInfo.cs | 22 +- .../Core/Search/FactoryIndexerFieldValue.cs | 4 +- .../Core/Search/FactoryIndexerInvoice.cs | 4 +- .../Server/Core/Search/FactoryIndexerTask.cs | 4 +- .../Security/CRMSecurityObjectProvider.cs | 42 +- .../Server/Core/Security/CRMSecutiry.cs | 93 ++-- .../Core/Security/FileSecurityProvider.cs | 7 +- .../Server/Helpers/ContactInfoDtoHelper.cs | 55 -- .../Server/Helpers/CurrencyInfoDtoHelper.cs | 54 -- .../Server/Helpers/CurrencyRateDtoHelper.cs | 49 -- .../Helpers/CurrencyRateInfoDtoHelper.cs | 12 +- .../Server/Helpers/InvoiceBaseDtoHelper.cs | 123 ----- .../Server/Helpers/InvoiceLineDtoHelper.cs | 55 -- .../Server/Helpers/InvoiceStatusDtoHelper.cs | 48 -- .../Server/Helpers/OpportunityDtoHelper.cs | 130 ----- .../Server/Helpers/VoipCallDtoHelper.cs | 8 +- .../HttpHandlers/ContactPhotoHandler.cs | 9 +- .../Server/HttpHandlers/FileHandler.cs | 82 ++- .../HttpHandlers/FileUploaderHandler.cs | 20 +- .../Server/HttpHandlers/ImportFileHandler.cs | 14 +- .../HttpHandlers/OrganisationLogoHandler.cs | 8 +- .../ASC.CRM/Server/Mapping/Common/IMapFrom.cs | 2 +- .../Server/Mapping/Common/MappingProfile.cs | 6 +- .../TypeConverter/CasesDtoTypeConverter.cs | 7 +- .../TypeConverter/ContactDtoTypeConverter.cs} | 397 +++++++------- .../InvoiceBaseDtoTypeConverter.cs | 116 ++++ .../TypeConverter/InvoiceDtoTypeConverter.cs | 117 ++++ .../InvoiceItemDtoTypeConverter.cs | 34 +- .../TypeConverter/InvoiceTaxTypeConverter.cs | 7 +- .../OpportunityDtoTypeConverter.cs | 124 +++++ .../RelationshipEventDtoTypeConverter.cs | 115 ++++ .../TaskCategoryDtoTypeConverter.cs} | 23 +- .../TypeConverter/TaskDtoTypeConverter.cs | 11 +- .../Services/NotifyService/NotifyClient.cs | 57 +- .../Services/NotifyService/NotifyConstants.cs | 2 +- .../Services/NotifyService/NotifySource.cs | 4 +- products/ASC.CRM/Server/Startup.cs | 12 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 20 +- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 21 +- .../Server/Utils/Import/CSV/ImportBase.cs | 1 - .../Utils/Import/CSV/ImportCSVSettings.cs | 6 +- .../Server/Utils/Import/CSV/ImportCases.cs | 17 +- .../Server/Utils/Import/CSV/ImportContacts.cs | 115 ++-- .../Utils/Import/CSV/ImportDataOperation.cs | 12 +- .../Server/Utils/Import/CSV/ImportDeals.cs | 27 +- .../Server/Utils/Import/CSV/ImportFromCSV.cs | 11 +- .../Server/Utils/Import/CSV/ImportTasks.cs | 14 +- products/ASC.CRM/Server/Utils/MailSender.cs | 38 +- products/ASC.CRM/Server/Utils/PdfCreator.cs | 32 +- .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 18 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 19 +- 186 files changed, 3683 insertions(+), 3986 deletions(-) delete mode 100644 products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs delete mode 100644 products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs delete mode 100644 products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs delete mode 100644 products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs delete mode 100644 products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs delete mode 100644 products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs delete mode 100644 products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs delete mode 100644 products/ASC.CRM/Server/Helpers/OpportunityDtoHelper.cs rename products/ASC.CRM/Server/{Helpers/ContactDtoHelper.cs => Mapping/TypeConverter/ContactDtoTypeConverter.cs} (56%) create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs rename products/ASC.CRM/Server/{Helpers/TaskCategoryDtoHelper.cs => Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs} (72%) diff --git a/products/ASC.CRM/Server/Api/BaseApiController.cs b/products/ASC.CRM/Server/Api/BaseApiController.cs index 4091e049bfb..7eb43680df8 100644 --- a/products/ASC.CRM/Server/Api/BaseApiController.cs +++ b/products/ASC.CRM/Server/Api/BaseApiController.cs @@ -24,19 +24,18 @@ */ using System; -using System.Collections.Generic; -using System.Linq; using ASC.Api.Core.Convention; using ASC.Common; using ASC.Common.Web; -using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.Api.Routing; +using AutoMapper; + using Microsoft.AspNetCore.Mvc; namespace ASC.Api.CRM @@ -47,14 +46,19 @@ namespace ASC.Api.CRM [ControllerName("crm")] public abstract class BaseApiController : ControllerBase { - public BaseApiController(DaoFactory daoFactory, CRMSecurity cRMSecurity) + protected IMapper _mapper; + protected DaoFactory _daoFactory; + protected CRMSecurity _crmSecurity; + + public BaseApiController(DaoFactory daoFactory, + CRMSecurity cRMSecurity, + IMapper mapper) { - DaoFactory = daoFactory; - CRMSecurity = cRMSecurity; + _daoFactory = daoFactory; + _crmSecurity = cRMSecurity; + _mapper = mapper; } - protected DaoFactory DaoFactory { get; } - protected CRMSecurity CRMSecurity { get; } protected static EntityType ToEntityType(string entityTypeStr) { @@ -86,7 +90,7 @@ protected static EntityType ToEntityType(string entityTypeStr) return entityType; } - + protected string GetEntityTitle(EntityType entityType, int entityId, bool checkAccess, out DomainObject entity) { switch (entityType) @@ -94,18 +98,18 @@ protected string GetEntityTitle(EntityType entityType, int entityId, bool checkA case EntityType.Contact: case EntityType.Company: case EntityType.Person: - var contact = (entity = DaoFactory.GetContactDao().GetByID(entityId)) as ASC.CRM.Core.Entities.Contact; - if (contact == null || (checkAccess && !CRMSecurity.CanAccessTo(contact))) + var contact = (entity = _daoFactory.GetContactDao().GetByID(entityId)) as ASC.CRM.Core.Entities.Contact; + if (contact == null || (checkAccess && !_crmSecurity.CanAccessTo(contact))) throw new ItemNotFoundException(); return contact.GetTitle(); case EntityType.Opportunity: - var deal = (entity = DaoFactory.GetDealDao().GetByID(entityId)) as Deal; - if (deal == null || (checkAccess && !CRMSecurity.CanAccessTo(deal))) + var deal = (entity = _daoFactory.GetDealDao().GetByID(entityId)) as Deal; + if (deal == null || (checkAccess && !_crmSecurity.CanAccessTo(deal))) throw new ItemNotFoundException(); return deal.Title; case EntityType.Case: - var cases = (entity = DaoFactory.GetCasesDao().GetByID(entityId)) as Cases; - if (cases == null || (checkAccess && !CRMSecurity.CanAccessTo(cases))) + var cases = (entity = _daoFactory.GetCasesDao().GetByID(entityId)) as Cases; + if (cases == null || (checkAccess && !_crmSecurity.CanAccessTo(cases))) throw new ItemNotFoundException(); return cases.Title; default: diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index 38d87e7eb64..284aba48235 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -24,55 +24,52 @@ */ -using ASC.Api.Collections; -using ASC.CRM.ApiModels; +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.Core; +using ASC.Api.CRM; using ASC.Common.Web; using ASC.Core; using ASC.Core.Users; +using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; - using ASC.ElasticSearch; using ASC.MessagingSystem; using ASC.Web.Api.Routing; +using ASC.Web.Core.Users; +using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Services.WCFService; -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.Api.CRM; -using ASC.CRM.Core.Dao; -using ASC.Api.Core; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Web.Core.Users; -using Microsoft.AspNetCore.Mvc; using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class CasesController : BaseApiController { - private IMapper _mapper; - public CasesController(CRMSecurity cRMSecurity, + public CasesController(CRMSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - ContactDtoHelper contactBaseDtoHelper, SecurityContext securityContext, DisplayUserSettingsHelper displayUserSettingsHelper, UserManager userManager, IMapper mapper) - : base(daoFactory, cRMSecurity) + : base(daoFactory, crmSecurity, mapper) { ApiContext = apiContext; MessageTarget = messageTarget; MessageService = messageService; NotifyClient = notifyClient; - ContactDtoHelper = contactBaseDtoHelper; SecurityContext = securityContext; DisplayUserSettingsHelper = displayUserSettingsHelper; UserManager = userManager; @@ -81,7 +78,6 @@ public CasesController(CRMSecurity cRMSecurity, public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public SecurityContext SecurityContext { get; } - public ContactDtoHelper ContactDtoHelper { get; } public NotifyClient NotifyClient { get; } private ApiContext ApiContext { get; } public MessageService MessageService { get; } @@ -100,15 +96,15 @@ public CasesController(CRMSecurity cRMSecurity, /// Case /// [Update(@"case/{caseid:int}/close")] - public CasesDto CloseCases([FromQuery] int caseid) + public CasesDto CloseCases(int caseid) { if (caseid <= 0) throw new ArgumentException(); - var cases = DaoFactory.GetCasesDao().CloseCases(caseid); + var cases = _daoFactory.GetCasesDao().CloseCases(caseid); if (cases == null) throw new ItemNotFoundException(); MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); - + return _mapper.Map(cases); } @@ -125,15 +121,15 @@ public CasesDto CloseCases([FromQuery] int caseid) /// Case /// [Update(@"case/{caseid:int}/reopen")] - public CasesDto ReOpenCases([FromQuery] int caseid) + public CasesDto ReOpenCases(int caseid) { if (caseid <= 0) throw new ArgumentException(); - var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid); + var cases = _daoFactory.GetCasesDao().ReOpenCases(caseid); if (cases == null) throw new ItemNotFoundException(); MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); - + return _mapper.Map(cases); } @@ -176,7 +172,7 @@ public CasesDto CreateCases([FromForm] CreateOrUpdateCasesRequestDto inDto) if (string.IsNullOrEmpty(title)) throw new ArgumentException(); - var casesID = DaoFactory.GetCasesDao().CreateCases(title); + var casesID = _daoFactory.GetCasesDao().CreateCases(title); var cases = new Cases { @@ -191,22 +187,22 @@ public CasesDto CreateCases([FromForm] CreateOrUpdateCasesRequestDto inDto) var membersList = members != null ? members.ToList() : new List(); if (membersList.Any()) { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + var contacts = _daoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(_crmSecurity.CanAccessTo).ToList(); membersList = contacts.Select(m => m.ID).ToList(); - DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); + _daoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); } if (customFieldList != null) { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); + var existingCustomFieldList = _daoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); } } - var casesToResult = DaoFactory.GetCasesDao().GetByID(casesID); + var casesToResult = _daoFactory.GetCasesDao().GetByID(casesID); return _mapper.Map(casesToResult); } @@ -241,7 +237,7 @@ public CasesDto CreateCases([FromForm] CreateOrUpdateCasesRequestDto inDto) /// ]]> /// [Update(@"case/{caseid:int}")] - public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCasesRequestDto inDto) + public CasesDto UpdateCases(int caseid, [FromForm] CreateOrUpdateCasesRequestDto inDto) { var title = inDto.Title; var isPrivate = inDto.isPrivate; @@ -252,14 +248,14 @@ public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCas if ((caseid <= 0) || (string.IsNullOrEmpty(title))) throw new ArgumentException(); - var cases = DaoFactory.GetCasesDao().GetByID(caseid); + var cases = _daoFactory.GetCasesDao().GetByID(caseid); if (cases == null) throw new ItemNotFoundException(); cases.Title = title; - DaoFactory.GetCasesDao().UpdateCases(cases); + _daoFactory.GetCasesDao().UpdateCases(cases); - if (CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) + if (_crmSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) { SetAccessToCases(cases, isPrivate, accessList, isNotify, false); } @@ -267,18 +263,18 @@ public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCas var membersList = members != null ? members.ToList() : new List(); if (membersList.Any()) { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + var contacts = _daoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(_crmSecurity.CanAccessTo).ToList(); membersList = contacts.Select(m => m.ID).ToList(); - DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); + _daoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray()); } if (customFieldList != null) { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); + var existingCustomFieldList = _daoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList(); foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value); } } @@ -299,14 +295,14 @@ public CasesDto UpdateCases([FromQuery] int caseid, [FromForm] CreateOrUpdateCas /// Case /// [Update(@"case/{caseid:int}/access")] - public CasesDto SetAccessToCases([FromQuery] int caseid, bool isPrivate, IEnumerable accessList) + public CasesDto SetAccessToCases(int caseid, bool isPrivate, IEnumerable accessList) { if (caseid <= 0) throw new ArgumentException(); - var cases = DaoFactory.GetCasesDao().GetByID(caseid); + var cases = _daoFactory.GetCasesDao().GetByID(caseid); if (cases == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); return SetAccessToCases(cases, isPrivate, accessList, false, true); } @@ -319,7 +315,7 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable if (isNotify) { accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); - NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, DaoFactory, accessListLocal.ToArray()); + NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, _daoFactory, accessListLocal.ToArray()); } if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) @@ -327,7 +323,7 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable accessListLocal.Add(SecurityContext.CurrentAccount.ID); } - CRMSecurity.SetAccessTo(cases, accessListLocal); + _crmSecurity.SetAccessTo(cases, accessListLocal); if (isMessageServicSende) { var users = GetUsersByIdList(accessListLocal); @@ -336,7 +332,7 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable } else { - CRMSecurity.MakePublic(cases); + _crmSecurity.MakePublic(cases); if (isMessageServicSende) { MessageService.Send(MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title); @@ -368,7 +364,7 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa var result = new List(); - var cases = DaoFactory.GetCasesDao().GetCases(casesid); + var cases = _daoFactory.GetCasesDao().GetCases(casesid); if (!cases.Any()) return new List(); @@ -376,7 +372,7 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa { if (c == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; SetAccessToCases(c, isPrivate, accessList, false, true); result.Add(c); @@ -411,7 +407,7 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa var result = new List(); - var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + var caseses = _daoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); if (!caseses.Any()) return new List(); @@ -419,7 +415,7 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa { if (casese == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; SetAccessToCases(casese, isPrivate, accessList, false, true); result.Add(casese); @@ -437,12 +433,12 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa /// /// [Read(@"case/{caseid:int}")] - public CasesDto GetCaseByID([FromQuery] int caseid) + public CasesDto GetCaseByID(int caseid) { if (caseid <= 0) throw new ItemNotFoundException(); - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + var cases = _daoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !_crmSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); return _mapper.Map(cases); } @@ -486,7 +482,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable if (casesOrderBy != null) { result = ToListCasesDtos( - DaoFactory + _daoFactory .GetCasesDao() .GetCases( searchString, @@ -504,7 +500,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable else { result = ToListCasesDtos( - DaoFactory + _daoFactory .GetCasesDao() .GetCases( searchString, contactid, isClosed, @@ -522,7 +518,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable } else { - totalCount = DaoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); + totalCount = _daoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); } ApiContext.SetTotalCount(totalCount); @@ -541,11 +537,11 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable /// Case /// [Delete(@"case/{caseid:int}")] - public CasesDto DeleteCase([FromQuery] int caseid) + public CasesDto DeleteCase(int caseid) { if (caseid <= 0) throw new ArgumentException(); - var cases = DaoFactory.GetCasesDao().DeleteCases(caseid); + var cases = _daoFactory.GetCasesDao().DeleteCases(caseid); if (cases == null) throw new ItemNotFoundException(); @@ -571,7 +567,7 @@ public IEnumerable DeleteBatchCases([FromForm] IEnumerable casesi if (casesids == null) throw new ArgumentException(); casesids = casesids.Distinct(); - var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); + var caseses = _daoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray()); if (caseses == null || !caseses.Any()) return new List(); @@ -596,10 +592,10 @@ public IEnumerable DeleteBatchCases([FromForm] IEnumerable casesi [Delete(@"case/filter")] public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) { - var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + var caseses = _daoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); if (!caseses.Any()) return new List(); - caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses); + caseses = _daoFactory.GetCasesDao().DeleteBatchCases(caseses); MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); @@ -617,10 +613,12 @@ public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEn [Read(@"case/{caseid:int}/contact")] public IEnumerable GetCasesMembers(int caseid) { - var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid); + var contactIDs = _daoFactory.GetCasesDao().GetMembers(caseid); + var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs); + return contactIDs == null ? new ItemList() - : ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)); + : _mapper.Map, List>(contacts); } /// @@ -640,18 +638,18 @@ public ContactDto AddMemberToCases(int caseid, int contactid) { if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + var cases = _daoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !_crmSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - DaoFactory.GetCasesDao().AddMember(caseid, contactid); + _daoFactory.GetCasesDao().AddMember(caseid, contactid); var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); - return ContactDtoHelper.ToContactDto(contact); + return _mapper.Map(contact); } /// @@ -671,17 +669,18 @@ public ContactDto DeleteMemberFromCases(int caseid, int contactid) { if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); - var cases = DaoFactory.GetCasesDao().GetByID(caseid); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); + var cases = _daoFactory.GetCasesDao().GetByID(caseid); + if (cases == null || !_crmSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ContactDtoHelper.ToContactDto(contact); + var result = _mapper.Map(contact); - DaoFactory.GetCasesDao().RemoveMember(caseid, contactid); + _daoFactory.GetCasesDao().RemoveMember(caseid, contactid); var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; + MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); return result; @@ -704,7 +703,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) if (contactID > 0) { - var findedCases = DaoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null); + var findedCases = _daoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null); foreach (var item in findedCases) { @@ -719,7 +718,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) else { const int maxItemCount = 30; - var findedCases = DaoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount); + var findedCases = _daoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount); foreach (var item in findedCases) { @@ -739,22 +738,22 @@ private IEnumerable ToListCasesDtos(ICollection items) var contactIDs = new List(); var casesIDs = items.Select(item => item.ID).ToArray(); - var customFields = DaoFactory.GetCustomFieldDao() + var customFields = _daoFactory.GetCustomFieldDao() .GetEnityFields(EntityType.Case, casesIDs) .GroupBy(item => item.EntityID) .ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); - var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs); + var casesMembers = _daoFactory.GetCasesDao().GetMembers(casesIDs); foreach (var value in casesMembers.Values) { contactIDs.AddRange(value); } - var contacts = DaoFactory + var contacts = _daoFactory .GetContactDao() .GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseDto(x)); + .ToDictionary(item => item.ID, x => _mapper.Map(x)); foreach (var cases in items) { diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index 2db0b58f2bd..292cea8b131 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -24,51 +24,47 @@ */ -using ASC.CRM.ApiModels; +using System; +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.CRM; using ASC.Common.Web; +using ASC.CRM.ApiModels; using ASC.CRM.Classes; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; using ASC.MessagingSystem; using ASC.Web.Api.Routing; -using ASC.Web.CRM.Core.Search; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; +using AutoMapper; -using System; -using System.Collections.Generic; -using System.Linq; -using ASC.Api.CRM; -using ASC.CRM.Core.Dao; -using ASC.Api.Core; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Core; -using ASC.Web.Core.Users; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + namespace ASC.CRM.Api { public class ContactInfosController : BaseApiController { + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + public ContactInfosController(CRMSecurity cRMSecurity, DaoFactory daoFactory, MessageTarget messageTarget, MessageService messageService, - ContactInfoDtoHelper contactInfoDtoHelper) - : base(daoFactory, cRMSecurity) + IMapper mapper) + : base(daoFactory, cRMSecurity, mapper) { - MessageTarget = messageTarget; - MessageService = messageService; - ContactInfoDtoHelper = contactInfoDtoHelper; + _messageTarget = messageTarget; + _messageService = messageService; } - public ContactInfoDtoHelper ContactInfoDtoHelper { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } - + /// /// Returns the list of all available contact categories /// @@ -112,13 +108,15 @@ public IEnumerable GetContactInfo(int contactid) { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return DaoFactory.GetContactInfoDao().GetList(contactid, null, null, null) + var sourceData = _daoFactory.GetContactInfoDao().GetList(contactid, null, null, null) .OrderByDescending(info => info.ID) - .ToList() - .ConvertAll(x => ContactInfoDtoHelper.Get(x)); + .ToList(); + + return _mapper.Map, List>(sourceData); } /// @@ -135,14 +133,14 @@ public ContactInfoDto GetContactInfoByID(int contactid, int id) { if (contactid <= 0 || id <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + var contactInfo = _daoFactory.GetContactInfoDao().GetByID(id); if (contactInfo == null || contactInfo.ContactID != contactid) throw new ArgumentException(); - return ContactInfoDtoHelper.Get(contactInfo); + return _mapper.Map(contactInfo); } /// @@ -165,16 +163,16 @@ public ContactInfoDto GetContactInfoByID(int contactid, int id) public ContactInfoDto CreateContactInfo(int contactid, ContactInfoType infoType, string data, bool isPrimary, string category) { if (string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); + var contact = _daoFactory.GetContactDao().GetByID(contactid); if (contact == null) throw new ItemNotFoundException(); if (infoType == ContactInfoType.Twitter) { - if (!CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + if (!_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); } else { - if (!CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + if (!_crmSecurity.CanEdit(contact)) throw new ItemNotFoundException(); } var categoryType = ContactInfo.GetCategory(infoType); @@ -197,13 +195,12 @@ public ContactInfoDto CreateContactInfo(int contactid, ContactInfoType infoType, throw new ArgumentException(); } - var contactInfoID = DaoFactory.GetContactInfoDao().Save(contactInfo); + var contactInfoID = _daoFactory.GetContactInfoDao().Save(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(contact.ID), contact.GetTitle()); - - var contactInfoDto = ContactInfoDtoHelper.Get(contactInfo); + var contactInfoDto = _mapper.Map(contactInfo); contactInfoDto.Id = contactInfoID; @@ -229,9 +226,9 @@ public ContactInfoDto CreateContactInfoAddress(int contactid, Address address) { if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid"); - var contact = DaoFactory.GetContactDao().GetByID(contactid); + var contact = _daoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + if (contact == null || !_crmSecurity.CanEdit(contact)) throw new ItemNotFoundException(); if (address == null) throw new ArgumentException("Value cannot be null", "address"); @@ -257,12 +254,12 @@ public ContactInfoDto CreateContactInfoAddress(int contactid, Address address) Data = JsonConvert.SerializeObject(address, settings) }; - contactInfo.ID = DaoFactory.GetContactInfoDao().Save(contactInfo); + contactInfo.ID = _daoFactory.GetContactInfoDao().Save(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(contact.ID), contact.GetTitle()); - return ContactInfoDtoHelper.Get(contactInfo); + return _mapper.Map(contactInfo); } /// @@ -288,8 +285,8 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEnumer { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanEdit(contact)) throw new ItemNotFoundException(); var itemsList = items != null ? items.ToList() : new List(); var contactInfoList = itemsList.Select(FromContactInfoDto).ToList(); @@ -305,7 +302,7 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEnumer contactInfo.ContactID = contactid; } - var ids = DaoFactory.GetContactInfoDao().SaveList(contactInfoList, contact); + var ids = _daoFactory.GetContactInfoDao().SaveList(contactInfoList, contact); for (var index = 0; index < itemsList.Count; index++) { @@ -331,14 +328,14 @@ public IEnumerable CreateBatchContactInfo(int contactid, IEnumer /// Contact information /// [Update(@"contact/{contactid:int}/data/{id:int}")] - public ContactInfoDto UpdateContactInfo([FromQuery] int id, [FromQuery] int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category) + public ContactInfoDto UpdateContactInfo(int id, int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category) { if (id <= 0 || string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanEdit(contact)) throw new ItemNotFoundException(); - var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + var contactInfo = _daoFactory.GetContactInfoDao().GetByID(id); if (infoType != null) { @@ -368,12 +365,13 @@ public ContactInfoDto UpdateContactInfo([FromQuery] int id, [FromQuery] int cont throw new ArgumentException(); } - DaoFactory.GetContactInfoDao().Update(contactInfo); + _daoFactory.GetContactInfoDao().Update(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - var contactInfoDto = ContactInfoDtoHelper.Get(contactInfo); + _messageService.Send(messageAction, _messageTarget.Create(contact.ID), contact.GetTitle()); + + var contactInfoDto = _mapper.Map(contactInfo); return contactInfoDto; } @@ -396,15 +394,15 @@ public ContactInfoDto UpdateContactInfoAddress(int id, int contactid, Address ad { if (id <= 0) throw new ArgumentException("Invalid value", "id"); - var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + var contactInfo = _daoFactory.GetContactInfoDao().GetByID(id); if (contactInfo == null || contactInfo.InfoType != ContactInfoType.Address) throw new ItemNotFoundException(); if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid"); - var contact = DaoFactory.GetContactDao().GetByID(contactid); + var contact = _daoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanEdit(contact) || contactInfo.ContactID != contactid) throw new ItemNotFoundException(); + if (contact == null || !_crmSecurity.CanEdit(contact) || contactInfo.ContactID != contactid) throw new ItemNotFoundException(); if (address == null) throw new ArgumentException("Value cannot be null", "address"); @@ -425,12 +423,13 @@ public ContactInfoDto UpdateContactInfoAddress(int id, int contactid, Address ad contactInfo.Category = address.Category; contactInfo.Data = JsonConvert.SerializeObject(address, settings); - DaoFactory.GetContactInfoDao().Update(contactInfo); + _daoFactory.GetContactInfoDao().Update(contactInfo); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); - return ContactInfoDtoHelper.Get(contactInfo); + _messageService.Send(messageAction, _messageTarget.Create(contact.ID), contact.GetTitle()); + + return _mapper.Map(contactInfo); } /// @@ -454,8 +453,8 @@ public IEnumerable UpdateBatchContactInfo(int contactid, IEnumer { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanEdit(contact)) throw new ItemNotFoundException(); var itemsList = items != null ? items.ToList() : new List(); var contactInfoList = itemsList.Select(FromContactInfoDto).ToList(); @@ -471,8 +470,8 @@ public IEnumerable UpdateBatchContactInfo(int contactid, IEnumer contactInfo.ContactID = contactid; } - DaoFactory.GetContactInfoDao().DeleteByContact(contactid); - var ids = DaoFactory.GetContactInfoDao().SaveList(contactInfoList, contact); + _daoFactory.GetContactInfoDao().DeleteByContact(contactid); + var ids = _daoFactory.GetContactInfoDao().SaveList(contactInfoList, contact); for (var index = 0; index < itemsList.Count; index++) { @@ -497,10 +496,10 @@ public IEnumerable GetContactInfo(int contactid, ContactInfoType infoTyp { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return DaoFactory.GetContactInfoDao().GetListData(contactid, infoType); + return _daoFactory.GetContactInfoDao().GetListData(contactid, infoType); } @@ -521,19 +520,19 @@ public ContactInfoDto DeleteContactInfo(int contactid, int id) { if (id <= 0 || contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanEdit(contact)) throw new ItemNotFoundException(); - var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id); + var contactInfo = _daoFactory.GetContactInfoDao().GetByID(id); if (contactInfo == null) throw new ItemNotFoundException(); - var wrapper = ContactInfoDtoHelper.Get(contactInfo); + var wrapper = _mapper.Map(contactInfo); - DaoFactory.GetContactInfoDao().Delete(id); + _daoFactory.GetContactInfoDao().Delete(id); var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(contact.ID), contact.GetTitle()); return wrapper; } diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index 799cc50fd3f..e234e8dd362 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -61,62 +61,48 @@ namespace ASC.CRM.Api { public class ContactsController : BaseApiController { - - private readonly IMapper _mapper; - - public ContactsController(CRMSecurity cRMSecurity, + private readonly MailSender _mailSender; + private readonly FileSizeComment _fileSizeComment; + private readonly ContactPhotoManager _contactPhotoManager; + private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly UserFormatter _userFormatter; + private readonly SetupInfo _setupInfo; + private readonly SecurityContext _securityContext; + private readonly NotifyClient _notifyClient; + private readonly ApiContext _apiContext; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + + public ContactsController(CRMSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - ContactDtoHelper contactBaseDtoHelper, - TaskCategoryDtoHelper taskCategoryDtoHelper, SecurityContext securityContext, - OpportunityDtoHelper opportunityDtoHelper, SetupInfo setupInfo, UserFormatter userFormatter, EmployeeWraperHelper employeeWraperHelper, ContactPhotoManager contactPhotoManager, FileSizeComment fileSizeComment, - ContactInfoDtoHelper contactInfoDtoHelper, MailSender mailSender, IMapper mapper) - : base(daoFactory, cRMSecurity) + : base(daoFactory, crmSecurity, mapper) { - ApiContext = apiContext; - MessageTarget = messageTarget; - MessageService = messageService; - NotifyClient = notifyClient; - ContactDtoHelper = contactBaseDtoHelper; - TaskCategoryDtoHelper = taskCategoryDtoHelper; - SecurityContext = securityContext; - OpportunityDtoHelper = opportunityDtoHelper; - SetupInfo = setupInfo; - UserFormatter = userFormatter; - EmployeeWraperHelper = employeeWraperHelper; - ContactPhotoManager = contactPhotoManager; - FileSizeComment = fileSizeComment; - ContactInfoDtoHelper = contactInfoDtoHelper; - MailSender = mailSender; + _apiContext = apiContext; + _messageTarget = messageTarget; + _messageService = messageService; + _notifyClient = notifyClient; + _securityContext = securityContext; + _setupInfo = setupInfo; + _userFormatter = userFormatter; + _employeeWraperHelper = employeeWraperHelper; + _contactPhotoManager = contactPhotoManager; + _fileSizeComment = fileSizeComment; + _mailSender = mailSender; _mapper = mapper; } - public MailSender MailSender { get; } - public ContactInfoDtoHelper ContactInfoDtoHelper { get; } - public FileSizeComment FileSizeComment { get; } - public ContactPhotoManager ContactPhotoManager { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public UserFormatter UserFormatter { get; } - public SetupInfo SetupInfo { get; } - public SecurityContext SecurityContext { get; } - public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } - public ContactDtoHelper ContactDtoHelper { get; } - public NotifyClient NotifyClient { get; } - private ApiContext ApiContext { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } - public OpportunityDtoHelper OpportunityDtoHelper { get; } /// /// Returns the detailed information about the contact with the ID specified in the request @@ -128,22 +114,21 @@ public ContactsController(CRMSecurity cRMSecurity, /// /// [Read(@"contact/{contactid:int}")] - public ContactDto GetContactByID([FromQuery] int contactid) + public ContactDto GetContactByID(int contactid) { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return ContactDtoHelper.GetContactDto(contact); + return _mapper.Map(contact); } public IEnumerable GetContactsByID(IEnumerable contactid) { - var contacts = DaoFactory.GetContactDao().GetContacts(contactid.ToArray()).Where(r => r != null && CRMSecurity.CanAccessTo(r)); - - return ContactDtoHelper.ToListContactDto(contacts.ToList()); + var contacts = _daoFactory.GetContactDao().GetContacts(contactid.ToArray()).Where(r => r != null && _crmSecurity.CanAccessTo(r)).ToList(); + return _mapper.Map, List>(contacts); } /// @@ -159,12 +144,14 @@ public IEnumerable GetContactsByID(IEnumerable contactid) /// /// [Read(@"contact/project/{projectid:int}")] - public IEnumerable GetContactsByProjectID([FromQuery] int projectid) + public IEnumerable GetContactsByProjectID(int projectid) { if (projectid <= 0) throw new ArgumentException(); - var contacts = DaoFactory.GetContactDao().GetContactsByProjectID(projectid); - return ContactDtoHelper.ToListContactDto(contacts.ToList()); + var contacts = _daoFactory.GetContactDao().GetContactsByProjectID(projectid); + + return _mapper.Map, List>(contacts.ToList()); + } ///// @@ -287,22 +274,23 @@ public IEnumerable GetContactsByProjectID([FromQuery] int projectid) /// Opportunity /// [Create(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] - public OpportunityDto AddDealToContact([FromQuery] int contactid, [FromQuery] int opportunityid) + public OpportunityDto AddDealToContact(int contactid, [FromQuery] int opportunityid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + var opportunity = _daoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !_crmSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - DaoFactory.GetDealDao().AddMember(opportunityid, contactid); + _daoFactory.GetDealDao().AddMember(opportunityid, contactid); var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), opportunity.Title, contact.GetTitle()); - return OpportunityDtoHelper.Get(opportunity); + _messageService.Send(messageAction, _messageTarget.Create(contact.ID), opportunity.Title, contact.GetTitle()); + + return _mapper.Map(opportunity); } /// @@ -317,19 +305,19 @@ public OpportunityDto AddDealToContact([FromQuery] int contactid, [FromQuery] in /// Opportunity /// [Delete(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] - public OpportunityDto DeleteDealFromContact([FromQuery] int contactid, [FromQuery] int opportunityid) + public OpportunityDto DeleteDealFromContact(int contactid, int opportunityid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + var opportunity = _daoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !_crmSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); + _daoFactory.GetDealDao().RemoveMember(opportunityid, contactid); - return OpportunityDtoHelper.Get(opportunity); + return _mapper.Map(opportunity); } /// @@ -350,14 +338,14 @@ public OpportunityDto DeleteDealFromContact([FromQuery] int contactid, [FromQuer /// [Read(@"contact/filter")] public IEnumerable GetContacts( - IEnumerable tags, - int? contactStage, - int? contactType, - ContactListViewType contactListView, - Guid? responsibleid, - bool? isShared, - ApiDateTime fromDate, - ApiDateTime toDate) + [FromQuery] IEnumerable tags, + [FromQuery] int? contactStage, + [FromQuery] int? contactType, + [FromQuery] ContactListViewType contactListView, + [FromQuery] Guid? responsibleid, + [FromQuery] bool? isShared, + [FromQuery] ApiDateTime fromDate, + [FromQuery] ApiDateTime toDate) { IEnumerable result; @@ -365,13 +353,15 @@ public IEnumerable GetContacts( ContactSortedByType sortBy; - var searchString = ApiContext.FilterValue; + + + var searchString = _apiContext.FilterValue; - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + if (ASC.CRM.Classes.EnumExtension.TryParse(_apiContext.SortBy, true, out sortBy)) { - contactsOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + contactsOrderBy = new OrderBy(sortBy, !_apiContext.SortDescending); } - else if (String.IsNullOrEmpty(ApiContext.SortBy)) + else if (String.IsNullOrEmpty(_apiContext.SortBy)) { contactsOrderBy = new OrderBy(ContactSortedByType.Created, false); } @@ -381,14 +371,14 @@ public IEnumerable GetContacts( } - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; + var fromIndex = (int)_apiContext.StartIndex; + var count = (int)_apiContext.Count; var contactStageInt = contactStage.HasValue ? contactStage.Value : -1; var contactTypeInt = contactType.HasValue ? contactType.Value : -1; if (contactsOrderBy != null) { - result = ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts( + result = _mapper.Map, List>(_daoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -401,13 +391,13 @@ public IEnumerable GetContacts( contactsOrderBy, responsibleid, isShared)); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else { - result = ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts( + result = _mapper.Map, List>(_daoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -430,7 +420,7 @@ public IEnumerable GetContacts( } else { - totalCount = DaoFactory.GetContactDao().GetContactsCount( + totalCount = _daoFactory.GetContactDao().GetContactsCount( searchString, tags, contactStageInt, @@ -442,7 +432,7 @@ public IEnumerable GetContacts( isShared); } - ApiContext.SetTotalCount(totalCount); + _apiContext.SetTotalCount(totalCount); return result; } @@ -461,7 +451,7 @@ public IEnumerable GetContacts( [Read(@"contact/simple/byEmail")] public IEnumerable SearchContactsByEmail(string term, int maxCount) { - var result = ToSimpleListContactDto(DaoFactory.GetContactDao().SearchContactsByEmail( + var result = ToSimpleListContactDto(_daoFactory.GetContactDao().SearchContactsByEmail( term, maxCount)); @@ -502,12 +492,12 @@ public IEnumerable GetSimpleContacts( ContactSortedByType sortBy; - var searchString = ApiContext.FilterValue; - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + var searchString = _apiContext.FilterValue; + if (ASC.CRM.Classes.EnumExtension.TryParse(_apiContext.SortBy, true, out sortBy)) { - contactsOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + contactsOrderBy = new OrderBy(sortBy, !_apiContext.SortDescending); } - else if (String.IsNullOrEmpty(ApiContext.SortBy)) + else if (String.IsNullOrEmpty(_apiContext.SortBy)) { contactsOrderBy = new OrderBy(ContactSortedByType.DisplayName, true); } @@ -516,14 +506,14 @@ public IEnumerable GetSimpleContacts( contactsOrderBy = null; } - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; + var fromIndex = (int)_apiContext.StartIndex; + var count = (int)_apiContext.Count; var contactStageInt = contactStage.HasValue ? contactStage.Value : -1; var contactTypeInt = contactType.HasValue ? contactType.Value : -1; if (contactsOrderBy != null) { - result = ToSimpleListContactDto(DaoFactory.GetContactDao().GetContacts( + result = ToSimpleListContactDto(_daoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -536,13 +526,13 @@ public IEnumerable GetSimpleContacts( contactsOrderBy, responsibleid, isShared)); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else { - result = ToSimpleListContactDto(DaoFactory.GetContactDao().GetContacts( + result = ToSimpleListContactDto(_daoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -565,7 +555,7 @@ public IEnumerable GetSimpleContacts( } else { - totalCount = DaoFactory.GetContactDao().GetContactsCount( + totalCount = _daoFactory.GetContactDao().GetContactsCount( searchString, tags, contactStageInt, @@ -577,7 +567,7 @@ public IEnumerable GetSimpleContacts( isShared); } - ApiContext.SetTotalCount(totalCount); + _apiContext.SetTotalCount(totalCount); return result; } @@ -599,9 +589,9 @@ public IEnumerable GetContactsForMail(IEnumerable { if (contactids == null) throw new ArgumentException(); - var contacts = DaoFactory.GetContactDao().GetContacts(contactids.ToArray()); + var contacts = _daoFactory.GetContactDao().GetContacts(contactids.ToArray()); - var result = contacts.Select(x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); + var result = contacts.Select(x => _mapper.Map(x)); return result; } @@ -634,8 +624,8 @@ public IEnumerable DeleteBatchContacts( int contactTypeInt = contactType.HasValue ? contactType.Value : -1; - var contacts = DaoFactory.GetContactDao().GetContacts( - ApiContext.FilterValue, + var contacts = _daoFactory.GetContactDao().GetContacts( + _apiContext.FilterValue, tags, contactStageInt, contactTypeInt, @@ -646,11 +636,11 @@ public IEnumerable DeleteBatchContacts( 0, null); - contacts = DaoFactory.GetContactDao().DeleteBatchContact(contacts); + contacts = _daoFactory.GetContactDao().DeleteBatchContact(contacts); - MessageService.Send(MessageAction.ContactsDeleted, MessageTarget.Create(contacts.Select(c => c.ID)), contacts.Select(c => c.GetTitle())); + _messageService.Send(MessageAction.ContactsDeleted, _messageTarget.Create(contacts.Select(c => c.ID)), contacts.Select(c => c.GetTitle())); - return contacts.Select(x => ContactDtoHelper.GetContactBaseDto(x)); + return contacts.Select(x => _mapper.Map(x)); } @@ -669,10 +659,12 @@ public IEnumerable GetPeopleFromCompany(int companyid) { if (companyid <= 0) throw new ArgumentException(); - var company = DaoFactory.GetContactDao().GetByID(companyid); - if (company == null || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + var company = _daoFactory.GetContactDao().GetByID(companyid); + if (company == null || !_crmSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); - return ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetMembers(companyid).Where(CRMSecurity.CanAccessTo).ToList()); + var contacts = _daoFactory.GetContactDao().GetMembers(companyid).Where(_crmSecurity.CanAccessTo).ToList(); + + return _mapper.Map, List>(contacts); } /// @@ -692,16 +684,16 @@ public PersonDto AddPeopleToCompany(int companyid, int personid) { if ((companyid <= 0) || (personid <= 0)) throw new ArgumentException(); - var company = DaoFactory.GetContactDao().GetByID(companyid); - var person = DaoFactory.GetContactDao().GetByID(personid); + var company = _daoFactory.GetContactDao().GetByID(companyid); + var person = _daoFactory.GetContactDao().GetByID(personid); - if (person == null || company == null || !CRMSecurity.CanAccessTo(person) || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + if (person == null || company == null || !_crmSecurity.CanAccessTo(person) || !_crmSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); - DaoFactory.GetContactDao().AddMember(personid, companyid); + _daoFactory.GetContactDao().AddMember(personid, companyid); - MessageService.Send(MessageAction.CompanyLinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); + _messageService.Send(MessageAction.CompanyLinkedPerson, _messageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); - return (PersonDto)ContactDtoHelper.GetContactDto(person); + return (PersonDto)_mapper.Map(person); } /// @@ -721,15 +713,15 @@ public PersonDto DeletePeopleFromCompany(int companyid, int personid) { if ((companyid <= 0) || (personid <= 0)) throw new ArgumentException(); - var company = DaoFactory.GetContactDao().GetByID(companyid); - var person = DaoFactory.GetContactDao().GetByID(personid); - if (person == null || company == null || !CRMSecurity.CanAccessTo(person) || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + var company = _daoFactory.GetContactDao().GetByID(companyid); + var person = _daoFactory.GetContactDao().GetByID(personid); + if (person == null || company == null || !_crmSecurity.CanAccessTo(person) || !_crmSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); - DaoFactory.GetContactDao().RemoveMember(personid); + _daoFactory.GetContactDao().RemoveMember(personid); - MessageService.Send(MessageAction.CompanyUnlinkedPerson, MessageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); + _messageService.Send(MessageAction.CompanyUnlinkedPerson, _messageTarget.Create(new[] { company.ID, person.ID }), company.GetTitle(), person.GetTitle()); - return (PersonDto)ContactDtoHelper.GetContactDto(person); + return (PersonDto)_mapper.Map(person); } /// @@ -763,8 +755,8 @@ public PersonDto CreatePerson([FromForm] CreateOrUpdatePersonRequestDto intDto) if (companyId > 0) { - var company = DaoFactory.GetContactDao().GetByID(companyId); - if (company == null || !CRMSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); + var company = _daoFactory.GetContactDao().GetByID(companyId); + if (company == null || !_crmSecurity.CanAccessTo(company)) throw new ItemNotFoundException(); } var peopleInst = new Person @@ -777,14 +769,14 @@ public PersonDto CreatePerson([FromForm] CreateOrUpdatePersonRequestDto intDto) ShareType = shareType }; - peopleInst.ID = DaoFactory.GetContactDao().SaveContact(peopleInst); - peopleInst.CreateBy = SecurityContext.CurrentAccount.ID; + peopleInst.ID = _daoFactory.GetContactDao().SaveContact(peopleInst); + peopleInst.CreateBy = _securityContext.CurrentAccount.ID; peopleInst.CreateOn = DateTime.UtcNow; var managerListLocal = managerList != null ? managerList.ToList() : new List(); if (managerListLocal.Any()) { - CRMSecurity.SetAccessTo(peopleInst, managerListLocal); + _crmSecurity.SetAccessTo(peopleInst, managerListLocal); } if (customFieldList != null) @@ -792,11 +784,11 @@ public PersonDto CreatePerson([FromForm] CreateOrUpdatePersonRequestDto intDto) foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Person, peopleInst.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Person, peopleInst.ID, field.Key, field.Value); } } - var outDto = (PersonDto)ContactDtoHelper.GetContactDto(peopleInst); + var outDto = (PersonDto)_mapper.Map(peopleInst); var photoList = photo != null ? photo.ToList() : new List(); @@ -805,7 +797,7 @@ public PersonDto CreatePerson([FromForm] CreateOrUpdatePersonRequestDto intDto) outDto.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); } - MessageService.Send(MessageAction.PersonCreated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); + _messageService.Send(MessageAction.PersonCreated, _messageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); return outDto; } @@ -827,9 +819,9 @@ public string ChangeContactPhoto(int contactid, IEnumerable photo) if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); + var contact = _daoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); var firstPhoto = photo != null ? photo.FirstOrDefault() : null; @@ -844,11 +836,11 @@ public string ChangeContactPhoto(int contactid, IEnumerable photo) !fileStream.CanRead) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); - if (SetupInfo.MaxImageUploadSize > 0 && - SetupInfo.MaxImageUploadSize < firstPhoto.Length) - throw new Exception(FileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false)); + if (_setupInfo.MaxImageUploadSize > 0 && + _setupInfo.MaxImageUploadSize < firstPhoto.Length) + throw new Exception(_fileSizeComment.GetFileImageSizeNote(CRMCommonResource.ErrorMessage_UploadFileSize, false)); - return ContactPhotoManager.UploadPhoto(fileStream, contactid, false).Url; + return _contactPhotoManager.UploadPhoto(fileStream, contactid, false).Url; } /// @@ -867,10 +859,10 @@ public string ChangeContactPhoto(int contactid, string photourl) { if (contactid <= 0 || string.IsNullOrEmpty(photourl)) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return ContactPhotoManager.UploadPhoto(photourl, contactid, false).Url; + return _contactPhotoManager.UploadPhoto(photourl, contactid, false).Url; } /// @@ -891,20 +883,20 @@ public ContactDto MergeContacts(int fromcontactid, int tocontactid) { if (fromcontactid <= 0 || tocontactid <= 0) throw new ArgumentException(); - var fromContact = DaoFactory.GetContactDao().GetByID(fromcontactid); - var toContact = DaoFactory.GetContactDao().GetByID(tocontactid); + var fromContact = _daoFactory.GetContactDao().GetByID(fromcontactid); + var toContact = _daoFactory.GetContactDao().GetByID(tocontactid); if (fromContact == null || toContact == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanEdit(fromContact) || !CRMSecurity.CanEdit(toContact)) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.CanEdit(fromContact) || !_crmSecurity.CanEdit(toContact)) throw _crmSecurity.CreateSecurityException(); - DaoFactory.GetContactDao().MergeDublicate(fromcontactid, tocontactid); - var resultContact = DaoFactory.GetContactDao().GetByID(tocontactid); + _daoFactory.GetContactDao().MergeDublicate(fromcontactid, tocontactid); + var resultContact = _daoFactory.GetContactDao().GetByID(tocontactid); var messageAction = resultContact is Person ? MessageAction.PersonsMerged : MessageAction.CompaniesMerged; - MessageService.Send(messageAction, MessageTarget.Create(new[] { fromContact.ID, toContact.ID }), fromContact.GetTitle(), toContact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(new[] { fromContact.ID, toContact.ID }), fromContact.GetTitle(), toContact.GetTitle()); - return ContactDtoHelper.GetContactDto(resultContact); + return _mapper.Map(resultContact); } /// @@ -951,27 +943,27 @@ public PersonDto UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdat ShareType = shareType }; - DaoFactory.GetContactDao().UpdateContact(peopleInst); + _daoFactory.GetContactDao().UpdateContact(peopleInst); - peopleInst = (Person)DaoFactory.GetContactDao().GetByID(peopleInst.ID); + peopleInst = (Person)_daoFactory.GetContactDao().GetByID(peopleInst.ID); var managerListLocal = managerList != null ? managerList.ToList() : new List(); if (managerListLocal.Any()) { - CRMSecurity.SetAccessTo(peopleInst, managerListLocal); + _crmSecurity.SetAccessTo(peopleInst, managerListLocal); } if (customFieldList != null) { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Person).Select(fd => fd.ID).ToList(); + var existingCustomFieldList = _daoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Person).Select(fd => fd.ID).ToList(); foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Person, peopleInst.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Person, peopleInst.ID, field.Key, field.Value); } } - var outDto = (PersonDto)ContactDtoHelper.GetContactDto(peopleInst); + var outDto = (PersonDto)_mapper.Map(peopleInst); var photoList = photo != null ? photo.ToList() : new List(); @@ -980,7 +972,7 @@ public PersonDto UpdatePerson([FromQuery] int personid, [FromForm] CreateOrUpdat outDto.SmallFotoUrl = ChangeContactPhoto(peopleInst.ID, photoList); } - MessageService.Send(MessageAction.PersonUpdated, MessageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); + _messageService.Send(MessageAction.PersonUpdated, _messageTarget.Create(peopleInst.ID), peopleInst.GetTitle()); return outDto; } @@ -1017,16 +1009,16 @@ public CompanyDto CreateCompany([FromForm] CreateOrUpdateCompanyRequestDto inDto ShareType = shareType }; - companyInst.ID = DaoFactory.GetContactDao().SaveContact(companyInst); - companyInst.CreateBy = SecurityContext.CurrentAccount.ID; + companyInst.ID = _daoFactory.GetContactDao().SaveContact(companyInst); + companyInst.CreateBy = _securityContext.CurrentAccount.ID; companyInst.CreateOn = DateTime.UtcNow; if (personList != null) { foreach (var personID in personList) { - var person = DaoFactory.GetContactDao().GetByID(personID); - if (person == null || !CRMSecurity.CanAccessTo(person)) continue; + var person = _daoFactory.GetContactDao().GetByID(personID); + if (person == null || !_crmSecurity.CanAccessTo(person)) continue; AddPeopleToCompany(companyInst.ID, personID); } @@ -1035,20 +1027,20 @@ public CompanyDto CreateCompany([FromForm] CreateOrUpdateCompanyRequestDto inDto var managerListLocal = managerList != null ? managerList.ToList() : new List(); if (managerListLocal.Any()) { - CRMSecurity.SetAccessTo(companyInst, managerListLocal); + _crmSecurity.SetAccessTo(companyInst, managerListLocal); } if (customFieldList != null) { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Company).Select(fd => fd.ID).ToList(); + var existingCustomFieldList = _daoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Company).Select(fd => fd.ID).ToList(); foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Company, companyInst.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Company, companyInst.ID, field.Key, field.Value); } } - var wrapper = (CompanyDto)ContactDtoHelper.GetContactDto(companyInst); + var wrapper = (CompanyDto)_mapper.Map(companyInst); var photoList = photo != null ? photo.ToList() : new List(); if (photoList.Any()) @@ -1056,7 +1048,7 @@ public CompanyDto CreateCompany([FromForm] CreateOrUpdateCompanyRequestDto inDto wrapper.SmallFotoUrl = ChangeContactPhoto(companyInst.ID, photoList); } - MessageService.Send(MessageAction.CompanyCreated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + _messageService.Send(MessageAction.CompanyCreated, _messageTarget.Create(companyInst.ID), companyInst.GetTitle()); return wrapper; } @@ -1093,16 +1085,16 @@ public IEnumerable CreateCompany(IEnumerable companyName if (contacts.Count == 0) return null; - DaoFactory.GetContactDao().SaveContactList(contacts); + _daoFactory.GetContactDao().SaveContactList(contacts); - var selectedManagers = new List { SecurityContext.CurrentAccount.ID }; + var selectedManagers = new List { _securityContext.CurrentAccount.ID }; foreach (var ct in contacts) { - CRMSecurity.SetAccessTo(ct, selectedManagers); + _crmSecurity.SetAccessTo(ct, selectedManagers); } - return contacts.ConvertAll(x => ContactDtoHelper.GetContactBaseDto(x)); + return contacts.ConvertAll(x => _mapper.Map(x)); } /// @@ -1144,18 +1136,18 @@ public IEnumerable CreatePerson(IEnumerable { SecurityContext.CurrentAccount.ID }; + var selectedManagers = new List { _securityContext.CurrentAccount.ID }; foreach (var ct in contacts) { - CRMSecurity.SetAccessTo(ct, selectedManagers); + _crmSecurity.SetAccessTo(ct, selectedManagers); } - MessageService.Send(MessageAction.PersonsCreated, MessageTarget.Create(contacts.Select(x => x.ID)), contacts.Select(x => x.GetTitle())); + _messageService.Send(MessageAction.PersonsCreated, _messageTarget.Create(contacts.Select(x => x.ID)), contacts.Select(x => x.GetTitle())); - return contacts.ConvertAll(x => ContactDtoHelper.GetContactBaseDto(x)); + return contacts.ConvertAll(x => _mapper.Map(x)); } /// @@ -1175,7 +1167,7 @@ public IEnumerable CreatePerson(IEnumerable [Update(@"contact/company/{companyid:int}")] public CompanyDto UpdateCompany( - [FromQuery] int companyid, + int companyid, [FromForm] CreateOrUpdateCompanyRequestDto intDto) { string companyName = intDto.CompanyName; @@ -1193,29 +1185,29 @@ public CompanyDto UpdateCompany( ShareType = shareType }; - DaoFactory.GetContactDao().UpdateContact(companyInst); + _daoFactory.GetContactDao().UpdateContact(companyInst); - companyInst = (Company)DaoFactory.GetContactDao().GetByID(companyInst.ID); + companyInst = (Company)_daoFactory.GetContactDao().GetByID(companyInst.ID); var managerListLocal = managerList != null ? managerList.ToList() : new List(); if (managerListLocal.Any()) { - CRMSecurity.SetAccessTo(companyInst, managerListLocal); + _crmSecurity.SetAccessTo(companyInst, managerListLocal); } if (customFieldList != null) { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Company).Select(fd => fd.ID).ToList(); + var existingCustomFieldList = _daoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Company).Select(fd => fd.ID).ToList(); foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Company, companyInst.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Company, companyInst.ID, field.Key, field.Value); } } - MessageService.Send(MessageAction.CompanyUpdated, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + _messageService.Send(MessageAction.CompanyUpdated, _messageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return (CompanyDto)ContactDtoHelper.GetContactDto(companyInst); + return (CompanyDto)_mapper.Map(companyInst); } /// @@ -1235,26 +1227,26 @@ public ContactDto UpdateContactStatus(int contactid, int contactStatusid) { if (contactid <= 0 || contactStatusid < 0) throw new ArgumentException(); - var dao = DaoFactory.GetContactDao(); + var dao = _daoFactory.GetContactDao(); if (contactStatusid > 0) { - var curListItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); + var curListItem = _daoFactory.GetListItemDao().GetByID(contactStatusid); if (curListItem == null) throw new ItemNotFoundException(); } var companyInst = dao.GetByID(contactid); - if (companyInst == null || !CRMSecurity.CanAccessTo(companyInst)) throw new ItemNotFoundException(); + if (companyInst == null || !_crmSecurity.CanAccessTo(companyInst)) throw new ItemNotFoundException(); - if (!CRMSecurity.CanEdit(companyInst)) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.CanEdit(companyInst)) throw _crmSecurity.CreateSecurityException(); dao.UpdateContactStatus(new List { companyInst.ID }, contactStatusid); companyInst.StatusID = contactStatusid; var messageAction = companyInst is Company ? MessageAction.CompanyUpdatedTemperatureLevel : MessageAction.PersonUpdatedTemperatureLevel; - MessageService.Send(messageAction, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return ContactDtoHelper.GetContactDto(companyInst); + return _mapper.Map(companyInst); } /// @@ -1274,16 +1266,16 @@ public ContactDto UpdateCompanyAndParticipantsStatus(int companyid, int contactS { if (companyid <= 0 || contactStatusid < 0) throw new ArgumentException(); - var dao = DaoFactory.GetContactDao(); + var dao = _daoFactory.GetContactDao(); if (contactStatusid > 0) { - var curListItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); + var curListItem = _daoFactory.GetListItemDao().GetByID(contactStatusid); if (curListItem == null) throw new ItemNotFoundException(); } var companyInst = dao.GetByID(companyid); - if (companyInst == null || !CRMSecurity.CanAccessTo(companyInst)) throw new ItemNotFoundException(); + if (companyInst == null || !_crmSecurity.CanAccessTo(companyInst)) throw new ItemNotFoundException(); if (companyInst is Person) throw new Exception(CRMErrorsResource.ContactIsNotCompany); @@ -1293,7 +1285,7 @@ public ContactDto UpdateCompanyAndParticipantsStatus(int companyid, int contactS var members = dao.GetMembersIDsAndShareType(companyInst.ID); foreach (var m in members) { - if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + if (_crmSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) { forUpdateStatus.Add(m.Key); } @@ -1301,10 +1293,10 @@ public ContactDto UpdateCompanyAndParticipantsStatus(int companyid, int contactS dao.UpdateContactStatus(forUpdateStatus, contactStatusid); - MessageService.Send(MessageAction.CompanyUpdatedTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); - MessageService.Send(MessageAction.CompanyUpdatedPersonsTemperatureLevel, MessageTarget.Create(companyInst.ID), companyInst.GetTitle()); + _messageService.Send(MessageAction.CompanyUpdatedTemperatureLevel, _messageTarget.Create(companyInst.ID), companyInst.GetTitle()); + _messageService.Send(MessageAction.CompanyUpdatedPersonsTemperatureLevel, _messageTarget.Create(companyInst.ID), companyInst.GetTitle()); - return ContactDtoHelper.GetContactDto(companyInst); + return _mapper.Map(companyInst); } /// @@ -1326,14 +1318,14 @@ public ContactDto UpdatePersonAndItsCompanyStatus(int personid, int contactStatu if (contactStatusid > 0) { - var curListItem = DaoFactory.GetListItemDao().GetByID(contactStatusid); + var curListItem = _daoFactory.GetListItemDao().GetByID(contactStatusid); if (curListItem == null) throw new ItemNotFoundException(); } - var dao = DaoFactory.GetContactDao(); + var dao = _daoFactory.GetContactDao(); var personInst = dao.GetByID(personid); - if (personInst == null || !CRMSecurity.CanAccessTo(personInst)) throw new ItemNotFoundException(); + if (personInst == null || !_crmSecurity.CanAccessTo(personInst)) throw new ItemNotFoundException(); if (personInst is Company) throw new Exception(CRMErrorsResource.ContactIsNotPerson); @@ -1345,7 +1337,7 @@ public ContactDto UpdatePersonAndItsCompanyStatus(int personid, int contactStatu var companyInst = dao.GetByID(companyID); if (companyInst == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(companyInst)) + if (!_crmSecurity.CanAccessTo(companyInst)) { forUpdateStatus.Add(personInst.ID); dao.UpdateContactStatus(forUpdateStatus, contactStatusid); @@ -1357,7 +1349,7 @@ public ContactDto UpdatePersonAndItsCompanyStatus(int personid, int contactStatu var members = dao.GetMembersIDsAndShareType(companyInst.ID); foreach (var m in members) { - if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + if (_crmSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) { forUpdateStatus.Add(m.Key); } @@ -1371,11 +1363,11 @@ public ContactDto UpdatePersonAndItsCompanyStatus(int personid, int contactStatu dao.UpdateContactStatus(forUpdateStatus, contactStatusid); } - MessageService.Send(MessageAction.PersonUpdatedTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); - MessageService.Send(MessageAction.PersonUpdatedCompanyTemperatureLevel, MessageTarget.Create(personInst.ID), personInst.GetTitle()); + _messageService.Send(MessageAction.PersonUpdatedTemperatureLevel, _messageTarget.Create(personInst.ID), personInst.GetTitle()); + _messageService.Send(MessageAction.PersonUpdatedCompanyTemperatureLevel, _messageTarget.Create(personInst.ID), personInst.GetTitle()); personInst = dao.GetByID(personInst.ID); - return ContactDtoHelper.GetContactDto(personInst); + return _mapper.Map(personInst); } /// @@ -1392,15 +1384,15 @@ public IEnumerable GetContactAccessList(int contactid) { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); + var contact = _daoFactory.GetContactDao().GetByID(contactid); if (contact == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(contact)) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.CanAccessTo(contact)) throw _crmSecurity.CreateSecurityException(); - return CRMSecurity.IsPrivate(contact) - ? CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeWraperHelper.Get(item.Key)) + return _crmSecurity.IsPrivate(contact) + ? _crmSecurity.GetAccessSubjectTo(contact) + .Select(item => _employeeWraperHelper.Get(item.Key)) : new List(); } @@ -1423,14 +1415,14 @@ public ContactDto SetAccessToContact(int contactid, bool isShared, IEnumerable(contact); return wrapper; } @@ -1442,23 +1434,23 @@ private void SetAccessToContact(Contact contact, bool isShared, IEnumerable n != SecurityContext.CurrentAccount.ID).ToArray(); + var notifyUsers = managerListLocal.Where(n => n != _securityContext.CurrentAccount.ID).ToArray(); if (contact is Person) - NotifyClient.SendAboutSetAccess(EntityType.Person, contact.ID, DaoFactory, notifyUsers); + _notifyClient.SendAboutSetAccess(EntityType.Person, contact.ID, _daoFactory, notifyUsers); else - NotifyClient.SendAboutSetAccess(EntityType.Company, contact.ID, DaoFactory, notifyUsers); + _notifyClient.SendAboutSetAccess(EntityType.Company, contact.ID, _daoFactory, notifyUsers); } - CRMSecurity.SetAccessTo(contact, managerListLocal); + _crmSecurity.SetAccessTo(contact, managerListLocal); } else { - CRMSecurity.MakePublic(contact); + _crmSecurity.MakePublic(contact); } - DaoFactory.GetContactDao().MakePublic(contact.ID, isShared); + _daoFactory.GetContactDao().MakePublic(contact.ID, isShared); } /// @@ -1531,8 +1523,8 @@ public IEnumerable SetAccessToBatchContact( var result = new List(); - var contacts = DaoFactory.GetContactDao().GetContacts( - ApiContext.FilterValue, + var contacts = _daoFactory.GetContactDao().GetContacts( + _apiContext.FilterValue, tags, contactStageInt, contactTypeInt, @@ -1548,13 +1540,13 @@ public IEnumerable SetAccessToBatchContact( if (contact == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanEdit(contact)) continue; + if (!_crmSecurity.CanEdit(contact)) continue; SetAccessToContact(contact, isPrivate, managerList, false); result.Add(contact); } - return ContactDtoHelper.ToListContactDto(result); + return _mapper.Map, List>(result); } /// @@ -1573,13 +1565,13 @@ public ContactDto DeleteContact(int contactid) { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().DeleteContact(contactid); + var contact = _daoFactory.GetContactDao().DeleteContact(contactid); if (contact == null) throw new ItemNotFoundException(); var messageAction = contact is Person ? MessageAction.PersonDeleted : MessageAction.CompanyDeleted; - MessageService.Send(messageAction, MessageTarget.Create(contact.ID), contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(contact.ID), contact.GetTitle()); - return ContactDtoHelper.GetContactDto(contact); + return _mapper.Map(contact); } /// @@ -1598,10 +1590,10 @@ public IEnumerable DeleteBatchContacts(IEnumerable contacti { if (contactids == null) throw new ArgumentException(); - var contacts = DaoFactory.GetContactDao().DeleteBatchContact(contactids.ToArray()); - MessageService.Send(MessageAction.ContactsDeleted, MessageTarget.Create(contactids), contacts.Select(c => c.GetTitle())); + var contacts = _daoFactory.GetContactDao().DeleteBatchContact(contactids.ToArray()); + _messageService.Send(MessageAction.ContactsDeleted, _messageTarget.Create(contactids), contacts.Select(c => c.GetTitle())); - return contacts.Select(x => ContactDtoHelper.GetContactBaseDto(x)); + return contacts.Select(x => _mapper.Map(x)); } /// @@ -1628,10 +1620,10 @@ public IEnumerable GetContactsByPrefix(string prefix, i switch (entityType) { case EntityType.Opportunity: - allContacts = DaoFactory.GetContactDao().GetContacts(DaoFactory.GetDealDao().GetMembers(entityID)); + allContacts = _daoFactory.GetContactDao().GetContacts(_daoFactory.GetDealDao().GetMembers(entityID)); break; case EntityType.Case: - allContacts = DaoFactory.GetContactDao().GetContacts(DaoFactory.GetCasesDao().GetMembers(entityID)); + allContacts = _daoFactory.GetContactDao().GetContacts(_daoFactory.GetCasesDao().GetMembers(entityID)); break; } @@ -1642,7 +1634,7 @@ public IEnumerable GetContactsByPrefix(string prefix, i { var people = person; - if (UserFormatter.GetUserName(people.FirstName, people.LastName).IndexOf(prefix, StringComparison.Ordinal) != -1) + if (_userFormatter.GetUserName(people.FirstName, people.LastName).IndexOf(prefix, StringComparison.Ordinal) != -1) { findedContacts.Add(person); } @@ -1656,19 +1648,20 @@ public IEnumerable GetContactsByPrefix(string prefix, i } } } - result.AddRange(findedContacts.Select(x => ContactDtoHelper.GetContactBaseWithPhoneDto(x))); + result.AddRange(findedContacts.Select(x => _mapper.Map(x))); - ApiContext.SetTotalCount(findedContacts.Count); + _apiContext.SetTotalCount(findedContacts.Count); } else { const int maxItemCount = 30; + if (searchType < -1 || searchType > 3) throw new ArgumentException(); - allContacts = DaoFactory.GetContactDao().GetContactsByPrefix(prefix, searchType, 0, maxItemCount); + allContacts = _daoFactory.GetContactDao().GetContactsByPrefix(prefix, searchType, 0, maxItemCount); - result.AddRange(allContacts.Select(x => ContactDtoHelper.GetContactBaseWithPhoneDto(x))); + result.AddRange(allContacts.Select(x => _mapper.Map(x))); } @@ -1692,9 +1685,9 @@ public IEnumerable GetContactsByContactInfo(ContactInfoType? infoTyp { if (!infoType.HasValue) throw new ArgumentException(); - var ids = DaoFactory.GetContactDao().GetContactIDsByContactInfo(infoType.Value, data, category, isPrimary); + var ids = _daoFactory.GetContactDao().GetContactIDsByContactInfo(infoType.Value, data, category, isPrimary); - var result = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => ContactDtoHelper.GetContactDto(x)); + var result = _daoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => _mapper.Map(x)); return result; } @@ -1806,10 +1799,10 @@ public string DeleteContactAvatar(int contactId, string contactType, bool upload if (contactId != 0) { - var contact = DaoFactory.GetContactDao().GetByID(contactId); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactId); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - if (!CRMSecurity.CanEdit(contact)) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.CanEdit(contact)) throw _crmSecurity.CreateSecurityException(); isCompany = contact is Company; } @@ -1820,8 +1813,8 @@ public string DeleteContactAvatar(int contactId, string contactType, bool upload if (!uploadOnly) { - ContactPhotoManager.DeletePhoto(contactId); - return ContactPhotoManager.GetBigSizePhoto(0, isCompany); + _contactPhotoManager.DeletePhoto(contactId); + return _contactPhotoManager.GetBigSizePhoto(0, isCompany); } return ""; } @@ -1908,11 +1901,11 @@ public IProgressItem SendMailSMTPToContacts( if (contactIds == null || contactIds.Count == 0 || String.IsNullOrEmpty(body)) throw new ArgumentException(); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIds.ToArray()); + var contacts = _daoFactory.GetContactDao().GetContacts(contactIds.ToArray()); - MessageService.Send(MessageAction.CrmSmtpMailSent, MessageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); + _messageService.Send(MessageAction.CrmSmtpMailSent, _messageTarget.Create(contactIds), contacts.Select(c => c.GetTitle())); - return MailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); + return _mailSender.Start(fileIDs, contactIds, subject, body, storeInHistory); } /// false @@ -1921,7 +1914,7 @@ public string GetMailSMTPToContactsPreview(string template, int contactId) { if (contactId == 0 || String.IsNullOrEmpty(template)) throw new ArgumentException(); - var manager = new MailTemplateManager(DaoFactory); + var manager = new MailTemplateManager(_daoFactory); return manager.Apply(template, contactId); } @@ -1930,16 +1923,16 @@ public string GetMailSMTPToContactsPreview(string template, int contactId) [Read(@"contact/mailsmtp/status")] public IProgressItem GetMailSMTPToContactsStatus() { - return MailSender.GetStatus(); + return _mailSender.GetStatus(); } /// false [Update(@"contact/mailsmtp/cancel")] public IProgressItem CancelMailSMTPToContacts() { - var progressItem = MailSender.GetStatus(); + var progressItem = _mailSender.GetStatus(); - MailSender.Cancel(); + _mailSender.Cancel(); return progressItem; @@ -1949,10 +1942,10 @@ public IProgressItem CancelMailSMTPToContacts() [Update(@"contact/{contactid:int}/creationdate")] public void SetContactCreationDate(int contactId, ApiDateTime creationDate) { - var dao = DaoFactory.GetContactDao(); + var dao = _daoFactory.GetContactDao(); var contact = dao.GetByID(contactId); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); dao.SetContactCreationDate(contactId, creationDate); @@ -1962,10 +1955,10 @@ public void SetContactCreationDate(int contactId, ApiDateTime creationDate) [Update(@"contact/{contactid:int}/lastmodifeddate")] public void SetContactLastModifedDate(int contactId, ApiDateTime lastModifedDate) { - var dao = DaoFactory.GetContactDao(); + var dao = _daoFactory.GetContactDao(); var contact = dao.GetByID(contactId); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); dao.SetContactLastModifedDate(contactId, lastModifedDate); @@ -1976,11 +1969,11 @@ private ContactPhotoManager.PhotoData UploadAvatar(int contactID, string imageUr { if (contactID != 0) { - return ContactPhotoManager.UploadPhoto(imageUrl, contactID, uploadOnly, checkFormat); + return _contactPhotoManager.UploadPhoto(imageUrl, contactID, uploadOnly, checkFormat); } if (string.IsNullOrEmpty(tmpDirName) || tmpDirName == "null") tmpDirName = null; - return ContactPhotoManager.UploadPhotoToTemp(imageUrl, tmpDirName, checkFormat); + return _contactPhotoManager.UploadPhotoToTemp(imageUrl, tmpDirName, checkFormat); } private IEnumerable ToSimpleListContactDto(IReadOnlyList itemList) @@ -1996,7 +1989,7 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList(); var peopleCompanyList = new Dictionary(); - var contactDao = DaoFactory.GetContactDao(); + var contactDao = _daoFactory.GetContactDao(); for (var index = 0; index < itemList.Count; index++) { @@ -2025,7 +2018,7 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList 0) { - var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => ContactDtoHelper.GetContactBaseDtoQuick(item)); + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => _mapper.Map(item)); var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); foreach (var contactBaseDtoQuick in tmpList) @@ -2039,7 +2032,7 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList>(); - DaoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( + _daoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( item => { if (item.InfoType == ContactInfoType.Address) @@ -2060,23 +2053,23 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList { ContactInfoDtoHelper.Get(item) }); + contactInfos.Add(item.ContactID, new List { _mapper.Map(item) }); } else { - contactInfos[item.ContactID].Add(ContactInfoDtoHelper.Get(item)); + contactInfos[item.ContactID].Add(_mapper.Map(item)); } } } ); - var nearestTasks = DaoFactory.GetTaskDao().GetNearestTask(contactIDs.ToArray()); + var nearestTasks = _daoFactory.GetTaskDao().GetNearestTask(contactIDs.ToArray()); IEnumerable taskCategories = new List(); if (nearestTasks.Any()) { - taskCategories = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => TaskCategoryDtoHelper.Get(item)); + taskCategories = _daoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => _mapper.Map(item)); } foreach (var contact in itemList) @@ -2088,7 +2081,7 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList(people); if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) { @@ -2102,7 +2095,7 @@ private IEnumerable ToSimpleListContactDto(IReadOnlyList(company); } else { diff --git a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs index 704751891a8..a28b745390d 100644 --- a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs +++ b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs @@ -24,9 +24,11 @@ */ -using ASC.Api.Core; +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Api.CRM; -using ASC.Core; using ASC.Core.Common.Settings; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -34,29 +36,24 @@ using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; -using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Services.NotifyService; -using System; -using System.Collections.Generic; -using System.Linq; +using AutoMapper; namespace ASC.CRM.Api { public class CurrencyRatesController : BaseApiController { - public CurrencyRatesController(CRMSecurity cRMSecurity, + public CurrencyRatesController(CRMSecurity crmSecurity, DaoFactory daoFactory, MessageService messageService, - CurrencyRateDtoHelper currencyRateDtoHelper, SettingsManager settingsManager, Global global, - CurrencyProvider currencyProvider) - : base(daoFactory, cRMSecurity) + CurrencyProvider currencyProvider, + IMapper mapper) + : base(daoFactory, crmSecurity, mapper) { MessageService = messageService; - CurrencyRateDtoHelper = currencyRateDtoHelper; SettingsManager = settingsManager; Global = global; CurrencyProvider = currencyProvider; @@ -65,7 +62,6 @@ public CurrencyRatesController(CRMSecurity cRMSecurity, public CurrencyProvider CurrencyProvider { get; } public SettingsManager SettingsManager { get; } public Global Global { get; } - public CurrencyRateDtoHelper CurrencyRateDtoHelper { get; } public MessageService MessageService { get; } //TABLE `crm_currency_rate` column `rate` DECIMAL(10,2) NOT NULL @@ -82,7 +78,7 @@ public CurrencyRatesController(CRMSecurity cRMSecurity, [Read(@"currency/rates")] public IEnumerable GetCurrencyRates() { - return DaoFactory.GetCurrencyRateDao().GetAll().ConvertAll(x => CurrencyRateDtoHelper.Get(x)); + return _daoFactory.GetCurrencyRateDao().GetAll().ConvertAll(x => _mapper.Map(x)); } /// @@ -99,9 +95,9 @@ public CurrencyRateDto GetCurrencyRate(int id) { if (id <= 0) throw new ArgumentException(); - var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); + var currencyRate = _daoFactory.GetCurrencyRateDao().GetByID(id); - return CurrencyRateDtoHelper.Get(currencyRate); + return _mapper.Map(currencyRate); } /// @@ -119,9 +115,9 @@ public CurrencyRateDto GetCurrencyRate(string fromCurrency, string toCurrency) if (string.IsNullOrEmpty(fromCurrency) || string.IsNullOrEmpty(toCurrency)) throw new ArgumentException(); - var currencyRate = DaoFactory.GetCurrencyRateDao().GetByCurrencies(fromCurrency, toCurrency); + var currencyRate = _daoFactory.GetCurrencyRateDao().GetByCurrencies(fromCurrency, toCurrency); - return CurrencyRateDtoHelper.Get(currencyRate); + return _mapper.Map(currencyRate); } /// @@ -144,10 +140,10 @@ public CurrencyRateDto CreateCurrencyRate(string fromCurrency, string toCurrency Rate = rate }; - currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); + currencyRate.ID = _daoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); - return CurrencyRateDtoHelper.Get(currencyRate); + return _mapper.Map(currencyRate); } /// @@ -166,7 +162,7 @@ public CurrencyRateDto UpdateCurrencyRate(int id, string fromCurrency, string to ValidateCurrencies(new[] { fromCurrency, toCurrency }); - var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); + var currencyRate = _daoFactory.GetCurrencyRateDao().GetByID(id); if (currencyRate == null) throw new ArgumentException(); @@ -175,10 +171,10 @@ public CurrencyRateDto UpdateCurrencyRate(int id, string fromCurrency, string to currencyRate.ToCurrency = toCurrency; currencyRate.Rate = rate; - currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); + currencyRate.ID = _daoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); - return CurrencyRateDtoHelper.Get(currencyRate); + return _mapper.Map(currencyRate); } /// @@ -190,8 +186,8 @@ public CurrencyRateDto UpdateCurrencyRate(int id, string fromCurrency, string to [Create(@"currency/setrates")] public List SetCurrencyRates(String currency, List rates) { - if (!CRMSecurity.IsAdmin) - throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) + throw _crmSecurity.CreateSecurityException(); if (string.IsNullOrEmpty(currency)) throw new ArgumentException(); @@ -212,14 +208,14 @@ public List SetCurrencyRates(String currency, List CurrencyRateDtoHelper.Get(x)).ToList(); + return rates.Select(x => _mapper.Map(x)).ToList(); } /// @@ -231,12 +227,12 @@ public List SetCurrencyRates(String currency, List AddCurrencyRates(List rates) { - if (!CRMSecurity.IsAdmin) - throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) + throw _crmSecurity.CreateSecurityException(); ValidateCurrencyRates(rates); - var existingRates = DaoFactory.GetCurrencyRateDao().GetAll(); + var existingRates = _daoFactory.GetCurrencyRateDao().GetAll(); foreach (var rate in rates) { @@ -248,7 +244,7 @@ public List AddCurrencyRates(List rates) continue; existingRate.Rate = rate.Rate; - DaoFactory.GetCurrencyRateDao().SaveOrUpdate(existingRate); + _daoFactory.GetCurrencyRateDao().SaveOrUpdate(existingRate); MessageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); exist = true; break; @@ -256,12 +252,12 @@ public List AddCurrencyRates(List rates) if (exist) continue; - rate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(rate); + rate.ID = _daoFactory.GetCurrencyRateDao().SaveOrUpdate(rate); MessageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); existingRates.Add(rate); } - return existingRates.Select(x => CurrencyRateDtoHelper.Get(x)).ToList(); + return existingRates.Select(x => _mapper.Map(x)).ToList(); } /// @@ -276,14 +272,14 @@ public CurrencyRateDto DeleteCurrencyRate(int id) if (id <= 0) throw new ArgumentException(); - var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id); + var currencyRate = _daoFactory.GetCurrencyRateDao().GetByID(id); if (currencyRate == null) throw new ArgumentException(); - DaoFactory.GetCurrencyRateDao().Delete(id); + _daoFactory.GetCurrencyRateDao().Delete(id); - return CurrencyRateDtoHelper.Get(currencyRate); + return _mapper.Map(currencyRate); } private void ValidateCurrencyRates(IEnumerable rates) diff --git a/products/ASC.CRM/Server/Api/CustomFieldsController.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs index 486cfc08ed1..f286d006e78 100644 --- a/products/ASC.CRM/Server/Api/CustomFieldsController.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -38,22 +38,26 @@ using ASC.MessagingSystem; using ASC.Web.Api.Routing; +using AutoMapper; + namespace ASC.CRM.Api { public class CustomFieldsController : BaseApiController { - public CustomFieldsController(CRMSecurity cRMSecurity, + private MessageService _messageService; + private MessageTarget _messageTarget; + + public CustomFieldsController(CRMSecurity crmSecurity, DaoFactory daoFactory, MessageTarget messageTarget, - MessageService messageService) - : base(daoFactory, cRMSecurity) + MessageService messageService, + IMapper mapper) + : base(daoFactory, crmSecurity, mapper) { - MessageTarget = messageTarget; - MessageService = messageService; + _messageTarget = messageTarget; + _messageService = messageService; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } /// /// Returns the list of descriptions for all existing user fields @@ -68,7 +72,7 @@ public CustomFieldsController(CRMSecurity cRMSecurity, [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/definitions")] public IEnumerable GetCustomFieldDefinitions(string entityType) { - return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldDto); + return _daoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldDto); } /// @@ -82,7 +86,7 @@ public IEnumerable GetCustomFieldDefinitions(string entityType) [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield")] public IEnumerable GetCustomFieldForSubject(string entityType, int entityid) { - return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseDto); + return _daoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseDto); } /// @@ -100,14 +104,14 @@ public IEnumerable GetCustomFieldForSubject(string entityTyp [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")] public CustomFieldBaseDto SetEntityCustomFieldValue(string entityType, int entityid, int fieldid, string fieldValue) { - var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); + var customField = _daoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); var entityTypeStr = ToEntityType(entityType); customField.EntityID = entityid; customField.Value = fieldValue; - DaoFactory.GetCustomFieldDao().SetFieldValue(entityTypeStr, entityid, fieldid, fieldValue); + _daoFactory.GetCustomFieldDao().SetFieldValue(entityTypeStr, entityid, fieldid, fieldValue); return ToCustomFieldBaseDto(customField); } @@ -207,15 +211,15 @@ public CustomFieldBaseDto SetEntityCustomFieldValue(string entityType, int entit [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield")] public CustomFieldDto CreateCustomFieldValue(string entityType, string label, int fieldType, int position, string mask) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); var entityTypeObj = ToEntityType(entityType); - var fieldID = DaoFactory.GetCustomFieldDao().CreateField(entityTypeObj, label, (CustomFieldType)fieldType, mask); - var wrapper = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID); + var fieldID = _daoFactory.GetCustomFieldDao().CreateField(entityTypeObj, label, (CustomFieldType)fieldType, mask); + var wrapper = _daoFactory.GetCustomFieldDao().GetFieldDescription(fieldID); var messageAction = GetCustomFieldCreatedAction(entityTypeObj); - MessageService.Send(messageAction, MessageTarget.Create(wrapper.ID), wrapper.Label); + _messageService.Send(messageAction, _messageTarget.Create(wrapper.ID), wrapper.Label); - return ToCustomFieldDto(DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); + return ToCustomFieldDto(_daoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); } /// @@ -246,7 +250,7 @@ public CustomFieldDto CreateCustomFieldValue(string entityType, string label, in public CustomFieldDto UpdateCustomFieldValue(int id, string entityType, string label, int fieldType, int position, string mask) { if (id <= 0) throw new ArgumentException(); - if (!DaoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException(); + if (!_daoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException(); var entityTypeObj = ToEntityType(entityType); @@ -260,12 +264,12 @@ public CustomFieldDto UpdateCustomFieldValue(int id, string entityType, string l Position = position }; - DaoFactory.GetCustomFieldDao().EditItem(customField); + _daoFactory.GetCustomFieldDao().EditItem(customField); - customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(id); + customField = _daoFactory.GetCustomFieldDao().GetFieldDescription(id); var messageAction = GetCustomFieldUpdatedAction(entityTypeObj); - MessageService.Send(messageAction, MessageTarget.Create(customField.ID), customField.Label); + _messageService.Send(messageAction, _messageTarget.Create(customField.ID), customField.Label); return ToCustomFieldDto(customField); } @@ -285,18 +289,18 @@ public CustomFieldDto UpdateCustomFieldValue(int id, string entityType, string l [Delete(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/{fieldid:int}")] public CustomFieldDto DeleteCustomField(string entityType, int fieldid) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (fieldid <= 0) throw new ArgumentException(); - var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); + var customField = _daoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); if (customField == null) throw new ItemNotFoundException(); var result = ToCustomFieldDto(customField); - DaoFactory.GetCustomFieldDao().DeleteField(fieldid); + _daoFactory.GetCustomFieldDao().DeleteField(fieldid); var messageAction = GetCustomFieldDeletedAction(ToEntityType(entityType)); - MessageService.Send(messageAction, MessageTarget.Create(customField.ID), result.Label); + _messageService.Send(messageAction, _messageTarget.Create(customField.ID), result.Label); return result; } @@ -317,19 +321,19 @@ public CustomFieldDto DeleteCustomField(string entityType, int fieldid) public IEnumerable UpdateCustomFieldsOrder(IEnumerable fieldids, string entityType) { if (fieldids == null) throw new ArgumentException(); - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); var customFields = new List(); foreach (var id in fieldids) { - if (!DaoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException(); - customFields.Add(DaoFactory.GetCustomFieldDao().GetFieldDescription(id)); + if (!_daoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException(); + customFields.Add(_daoFactory.GetCustomFieldDao().GetFieldDescription(id)); } - DaoFactory.GetCustomFieldDao().ReorderFields(fieldids.ToArray()); + _daoFactory.GetCustomFieldDao().ReorderFields(fieldids.ToArray()); var messageAction = GetCustomFieldsUpdatedOrderAction(ToEntityType(entityType)); - MessageService.Send(messageAction, MessageTarget.Create(fieldids), customFields.Select(x => x.Label)); + _messageService.Send(messageAction, _messageTarget.Create(fieldids), customFields.Select(x => x.Label)); return customFields.Select(ToCustomFieldBaseDto); } @@ -343,7 +347,7 @@ private CustomFieldDto ToCustomFieldDto(CustomField customField) { var result = new CustomFieldDto(customField) { - RelativeItemsCount = DaoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID) + RelativeItemsCount = _daoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID) }; return result; } diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index 436fa491768..183f9a22e50 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -45,6 +45,8 @@ using ASC.Web.CRM.Classes; using ASC.Web.CRM.Services.NotifyService; +using AutoMapper; + using Microsoft.AspNetCore.Mvc; namespace ASC.CRM.Api @@ -57,38 +59,30 @@ public DealsController(CRMSecurity cRMSecurity, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - ContactDtoHelper contactDtoHelper, - OpportunityDtoHelper opportunityDtoHelper, CurrencyProvider currencyProvider, - CurrencyInfoDtoHelper currencyInfoDtoHelper, UserManager userManager, EmployeeWraperHelper employeeWraperHelper, - DisplayUserSettingsHelper displayUserSettingsHelper) - : base(daoFactory, cRMSecurity) + DisplayUserSettingsHelper displayUserSettingsHelper, + IMapper mapper) + : base(daoFactory, cRMSecurity, mapper) { ApiContext = apiContext; MessageTarget = messageTarget; MessageService = messageService; NotifyClient = notifyClient; - OpportunityDtoHelper = opportunityDtoHelper; CurrencyProvider = currencyProvider; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; UserManager = userManager; EmployeeWraperHelper = employeeWraperHelper; DisplayUserSettingsHelper = displayUserSettingsHelper; - ContactDtoHelper = contactDtoHelper; } - public ContactDtoHelper ContactDtoHelper { get; } public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } public NotifyClient NotifyClient { get; } private ApiContext ApiContext { get; } public MessageService MessageService { get; } public MessageTarget MessageTarget { get; } - public OpportunityDtoHelper OpportunityDtoHelper { get; } public SecurityContext SecurityContext { get; } public CurrencyProvider CurrencyProvider { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } public UserManager UserManager { get; } public EmployeeWraperHelper EmployeeWraperHelper { get; } @@ -108,10 +102,10 @@ public OpportunityDto GetDealByID(int opportunityid) { if (opportunityid <= 0) throw new ArgumentException(); - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); - if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); + var deal = _daoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null || !_crmSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); - return OpportunityDtoHelper.Get(deal); + return _mapper.Map(deal); } /// @@ -131,20 +125,20 @@ public OpportunityDto UpdateToDealMilestone(int opportunityid, int stageid) { if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException(); - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); - if (deal == null || !CRMSecurity.CanEdit(deal)) throw new ItemNotFoundException(); + var deal = _daoFactory.GetDealDao().GetByID(opportunityid); + if (deal == null || !_crmSecurity.CanEdit(deal)) throw new ItemNotFoundException(); - var stage = DaoFactory.GetDealMilestoneDao().GetByID(stageid); + var stage = _daoFactory.GetDealMilestoneDao().GetByID(stageid); if (stage == null) throw new ItemNotFoundException(); deal.DealMilestoneID = stageid; deal.DealMilestoneProbability = stage.Probability; deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue; - DaoFactory.GetDealDao().EditDeal(deal); + _daoFactory.GetDealDao().EditDeal(deal); MessageService.Send(MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); - return OpportunityDtoHelper.Get(deal); + return _mapper.Map(deal); } /// @@ -165,10 +159,10 @@ public OpportunityDto SetAccessToDeal(int opportunityid, bool isPrivate, IEnumer { if (opportunityid <= 0) throw new ArgumentException(); - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + var deal = _daoFactory.GetDealDao().GetByID(opportunityid); if (deal == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); return SetAccessToDeal(deal, isPrivate, accessList, false, true); } @@ -181,7 +175,7 @@ private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable u != SecurityContext.CurrentAccount.ID).ToList(); - NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, DaoFactory, accessListLocal.ToArray()); + NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, _daoFactory, accessListLocal.ToArray()); } if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) @@ -189,7 +183,7 @@ private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable(deal); } /// @@ -245,7 +239,7 @@ public IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBa var result = new List(); - var deals = DaoFactory.GetDealDao() + var deals = _daoFactory.GetDealDao() .GetDeals(ApiContext.FilterValue, responsibleid, opportunityStagesid, @@ -261,7 +255,7 @@ public IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBa { if (deal == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; SetAccessToDeal(deal.ID, isPrivate, accessList); @@ -296,7 +290,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealRequ var result = new List(); - var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); + var deals = _daoFactory.GetDealDao().GetDeals(opportunityid.ToArray()); if (!deals.Any()) return new List(); @@ -304,7 +298,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealRequ { if (d == null) throw new ItemNotFoundException(); - if (!(CRMSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; SetAccessToDeal(d, isPrivate, accessList, false, true); result.Add(d); @@ -330,7 +324,7 @@ public IEnumerable DeleteBatchDeals(IEnumerable opportunity { if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); - var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); + var opportunities = _daoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); return ToListOpportunityDto(opportunities); @@ -365,7 +359,7 @@ public IEnumerable DeleteBatchDeals( ApiDateTime fromDate, ApiDateTime toDate) { - var deals = DaoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, + var deals = _daoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, responsibleid, opportunityStagesid, tags, @@ -376,7 +370,7 @@ public IEnumerable DeleteBatchDeals( if (!deals.Any()) return Enumerable.Empty(); - deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals); + deals = _daoFactory.GetDealDao().DeleteBatchDeals(deals); MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); return ToListOpportunityDto(deals); @@ -435,7 +429,7 @@ public IEnumerable GetDeals( if (dealsOrderBy != null) { - result = ToListOpportunityDto(DaoFactory.GetDealDao().GetDeals( + result = ToListOpportunityDto(_daoFactory.GetDealDao().GetDeals( searchString, responsibleid, opportunityStagesid, @@ -455,7 +449,7 @@ public IEnumerable GetDeals( } else { - result = ToListOpportunityDto(DaoFactory.GetDealDao().GetDeals( + result = ToListOpportunityDto(_daoFactory.GetDealDao().GetDeals( searchString, responsibleid, opportunityStagesid, @@ -477,7 +471,7 @@ public IEnumerable GetDeals( } else { - totalCount = DaoFactory + totalCount = _daoFactory .GetDealDao() .GetDealsCount(searchString, responsibleid, @@ -511,12 +505,12 @@ public OpportunityDto DeleteDeal(int opportunityid) { if (opportunityid <= 0) throw new ArgumentException(); - var deal = DaoFactory.GetDealDao().DeleteDeal(opportunityid); + var deal = _daoFactory.GetDealDao().DeleteDeal(opportunityid); if (deal == null) throw new ItemNotFoundException(); MessageService.Send(MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); - return OpportunityDtoHelper.Get(deal); + return _mapper.Map(deal); } /// @@ -583,9 +577,9 @@ public OpportunityDto CreateDeal(CreateOrUpdateDealRequestDto inDto) BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null, }; - CRMSecurity.DemandCreateOrUpdate(deal); + _crmSecurity.DemandCreateOrUpdate(deal); - deal.ID = DaoFactory.GetDealDao().CreateNewDeal(deal); + deal.ID = _daoFactory.GetDealDao().CreateNewDeal(deal); deal.CreateBy = SecurityContext.CurrentAccount.ID; deal.CreateOn = DateTime.UtcNow; @@ -599,22 +593,22 @@ public OpportunityDto CreateDeal(CreateOrUpdateDealRequestDto inDto) if (membersList.Any()) { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + var contacts = _daoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(_crmSecurity.CanAccessTo).ToList(); membersList = contacts.Select(m => m.ID).ToList(); - DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); + _daoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); } if (customFieldList != null) { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); + var existingCustomFieldList = _daoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); } } - return OpportunityDtoHelper.Get(deal); + return _mapper.Map(deal); } /// @@ -667,7 +661,7 @@ public OpportunityDto UpdateDeal( var customFieldList = inDto.CustomFieldList; var members = inDto.Members; - var deal = DaoFactory.GetDealDao().GetByID(opportunityid); + var deal = _daoFactory.GetDealDao().GetByID(opportunityid); if (deal == null) throw new ItemNotFoundException(); deal.Title = title; @@ -683,38 +677,38 @@ public OpportunityDto UpdateDeal( deal.ExpectedCloseDate = expectedCloseDate; deal.BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null; - CRMSecurity.DemandCreateOrUpdate(deal); + _crmSecurity.DemandCreateOrUpdate(deal); - DaoFactory.GetDealDao().EditDeal(deal); + _daoFactory.GetDealDao().EditDeal(deal); - deal = DaoFactory.GetDealDao().GetByID(opportunityid); + deal = _daoFactory.GetDealDao().GetByID(opportunityid); var membersList = members != null ? members.ToList() : new List(); if (membersList.Any()) { - var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList(); + var contacts = _daoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(_crmSecurity.CanAccessTo).ToList(); membersList = contacts.Select(m => m.ID).ToList(); - DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); + _daoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray()); } - if (CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) + if (_crmSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) { SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); } if (customFieldList != null) { - var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); + var existingCustomFieldList = _daoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList(); foreach (var field in customFieldList) { if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue; - DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); + _daoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value); } } - return OpportunityDtoHelper.Get(deal); + return _mapper.Map(deal); } /// @@ -729,15 +723,17 @@ public OpportunityDto UpdateDeal( [Read(@"opportunity/{opportunityid:int}/contact")] public IEnumerable GetDealMembers(int opportunityid) { - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); + var opportunity = _daoFactory.GetDealDao().GetByID(opportunityid); + + if (opportunity == null || !_crmSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + var contactIDs = _daoFactory.GetDealDao().GetMembers(opportunityid); - var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid); - if (contactIDs == null) return new List(); + + var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs); - var result = ContactDtoHelper.ToListContactDto(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList(); + var result = _mapper.Map, List>(contacts); result.ForEach(item => { if (item.Id == opportunity.ContactID) item.CanEdit = false; }); @@ -760,15 +756,15 @@ public ContactDto AddMemberToDeal(int opportunityid, int contactid) { if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + var opportunity = _daoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !_crmSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ContactDtoHelper.ToContactDto(contact); + var result = _mapper.Map(contact); - DaoFactory.GetDealDao().AddMember(opportunityid, contactid); + _daoFactory.GetDealDao().AddMember(opportunityid, contactid); var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; MessageService.Send(messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); @@ -793,15 +789,15 @@ public ContactDto DeleteMemberFromDeal(int opportunityid, int contactid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); - var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + var opportunity = _daoFactory.GetDealDao().GetByID(opportunityid); + if (opportunity == null || !_crmSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - var result = ContactDtoHelper.ToContactDto(contact); + var result = _mapper.Map(contact); - DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid); + _daoFactory.GetDealDao().RemoveMember(opportunityid, contactid); var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson; MessageService.Send(messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); @@ -827,12 +823,12 @@ public IEnumerable GetDealsByPrefix(string prefix, int contactID if (contactID > 0 && internalSearch) { - var findedDeals = DaoFactory.GetDealDao().GetDealsByContactID(contactID); + var findedDeals = _daoFactory.GetDealDao().GetDealsByContactID(contactID); foreach (var item in findedDeals) { if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1) { - result.Add(OpportunityDtoHelper.Get(item)); + result.Add(_mapper.Map(item)); } } @@ -841,10 +837,10 @@ public IEnumerable GetDealsByPrefix(string prefix, int contactID else { const int maxItemCount = 30; - var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); + var findedDeals = _daoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch); foreach (var item in findedDeals) { - result.Add(OpportunityDtoHelper.Get(item)); + result.Add(_mapper.Map(item)); } } @@ -863,7 +859,7 @@ public IEnumerable GetDealsByPrefix(string prefix, int contactID [Read(@"opportunity/bycontact/{contactid:int}")] public IEnumerable GetDeals(int contactid) { - var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid); + var deals = _daoFactory.GetDealDao().GetDealsByContactID(contactid); return ToListOpportunityDto(deals); } @@ -871,10 +867,10 @@ public IEnumerable GetDeals(int contactid) [Update(@"opportunity/{opportunityid:int}/creationdate")] public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate) { - var dao = DaoFactory.GetDealDao(); + var dao = _daoFactory.GetDealDao(); var opportunity = dao.GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) + if (opportunity == null || !_crmSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); dao.SetDealCreationDate(opportunityid, creationDate); @@ -884,10 +880,10 @@ public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate) [Update(@"opportunity/{opportunityid:int}/lastmodifeddate")] public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDate) { - var dao = DaoFactory.GetDealDao(); + var dao = _daoFactory.GetDealDao(); var opportunity = dao.GetByID(opportunityid); - if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) + if (opportunity == null || !_crmSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); dao.SetDealLastModifedDate(opportunityid, lastModifedDate); @@ -915,15 +911,15 @@ private IEnumerable ToListOpportunityDto(ICollection deals var contacts = new Dictionary(); - var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) + var customFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(x=> new CustomFieldBaseDto(x))); + .ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); - var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) + var dealMilestones = _daoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) .ToDictionary(item => item.ID, item => new DealMilestoneBaseDto(item)); - var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); + var dealMembers = _daoFactory.GetDealDao().GetMembers(dealIDs.ToArray()); foreach (var value in dealMembers.Values) { @@ -934,16 +930,16 @@ private IEnumerable ToListOpportunityDto(ICollection deals if (contactIDs.Count > 0) { - DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item => + _daoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item => { if (item == null) return; - contacts.Add(item.ID, ContactDtoHelper.GetContactBaseDto(item)); + contacts.Add(item.ID, _mapper.Map(item)); }); } foreach (var deal in deals) { - var dealDto = OpportunityDtoHelper.Get(deal); + var dealDto = _mapper.Map(deal); if (contacts.ContainsKey(deal.ContactID)) { @@ -963,16 +959,16 @@ private IEnumerable ToListOpportunityDto(ICollection deals dealDto.Stage = dealMilestones[deal.DealMilestoneID]; } - dealDto.IsPrivate = CRMSecurity.IsPrivate(deal); + dealDto.IsPrivate = _crmSecurity.IsPrivate(deal); if (dealDto.IsPrivate) { - dealDto.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); + dealDto.AccessList = _crmSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); } if (!string.IsNullOrEmpty(deal.BidCurrency)) { - dealDto.BidCurrency = CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); + dealDto.BidCurrency = _mapper.Map(CurrencyProvider.Get(deal.BidCurrency)); } result.Add(dealDto); diff --git a/products/ASC.CRM/Server/Api/InvoicesController.cs b/products/ASC.CRM/Server/Api/InvoicesController.cs index 1e60741bafc..f34cf931cf9 100644 --- a/products/ASC.CRM/Server/Api/InvoicesController.cs +++ b/products/ASC.CRM/Server/Api/InvoicesController.cs @@ -52,58 +52,44 @@ namespace ASC.CRM.Api { public class InvoicesController : BaseApiController { - private readonly IMapper _mapper; - public InvoicesController(CRMSecurity cRMSecurity, + + private readonly PdfQueueWorker _pdfQueueWorker; + private readonly Global _global; + private readonly FileWrapperHelper _fileWrapperHelper; + private readonly PdfCreator _pdfCreator; + private readonly SettingsManager _settingsManager; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly ApiContext _apiContext; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + + public InvoicesController(CRMSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, - ContactDtoHelper contactBaseDtoHelper, - InvoiceDtoHelper invoiceDtoHelper, ApiDateTimeHelper apiDateTimeHelper, SettingsManager settingsManager, FileWrapperHelper fileWrapperHelper, PdfCreator pdfCreator, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - InvoiceBaseDtoHelper invoiceBaseDtoHelper, Global global, - InvoiceLineDtoHelper invoiceLineDtoHelper, PdfQueueWorker pdfQueueWorker, IMapper mapper) - : base(daoFactory, cRMSecurity) + : base(daoFactory, crmSecurity, mapper) { - ApiContext = apiContext; - MessageTarget = messageTarget; - MessageService = messageService; - ContactDtoHelper = contactBaseDtoHelper; - InvoiceDtoHelper = invoiceDtoHelper; - ApiDateTimeHelper = apiDateTimeHelper; - SettingsManager = settingsManager; - PdfCreator = pdfCreator; - FileWrapperHelper = fileWrapperHelper; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - InvoiceBaseDtoHelper = invoiceBaseDtoHelper; - Global = global; - InvoiceLineDtoHelper = invoiceLineDtoHelper; - PdfQueueWorker = pdfQueueWorker; + _apiContext = apiContext; + _messageTarget = messageTarget; + _messageService = messageService; + _apiDateTimeHelper = apiDateTimeHelper; + _settingsManager = settingsManager; + _pdfCreator = pdfCreator; + _fileWrapperHelper = fileWrapperHelper; + _global = global; + _pdfQueueWorker = pdfQueueWorker; _mapper = mapper; } - public PdfQueueWorker PdfQueueWorker { get; } - public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } - public Global Global { get; } - public InvoiceBaseDtoHelper InvoiceBaseDtoHelper { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public FileWrapperHelper FileWrapperHelper { get; } - public PdfCreator PdfCreator { get; } - public SettingsManager SettingsManager { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public InvoiceDtoHelper InvoiceDtoHelper { get; } - public ContactDtoHelper ContactDtoHelper { get; } - private ApiContext ApiContext { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } - + /// /// Returns the detailed information about the invoice with the ID specified in the request /// @@ -116,15 +102,15 @@ public InvoiceDto GetInvoiceByID(int invoiceid) { if (invoiceid <= 0) throw new ArgumentException(); - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceid); if (invoice == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(invoice)) + if (!_crmSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } - return InvoiceDtoHelper.Get(invoice); + return _mapper.Map(invoice); } /// @@ -136,15 +122,17 @@ public InvoiceDto GetInvoiceByID(int invoiceid) [Read(@"invoice/sample")] public InvoiceDto GetInvoiceSample() { + var defaultCurrency = _settingsManager.Load().DefaultCurrency; + var sample = InvoiceDto.GetSample(); - sample.Number = DaoFactory.GetInvoiceDao().GetNewInvoicesNumber(); - sample.Terms = DaoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; - sample.IssueDate = ApiDateTimeHelper.Get(DateTime.UtcNow); - sample.DueDate = ApiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); - sample.CreateOn = ApiDateTimeHelper.Get(DateTime.UtcNow); + sample.Number = _daoFactory.GetInvoiceDao().GetNewInvoicesNumber(); + sample.Terms = _daoFactory.GetInvoiceDao().GetSettings().Terms ?? string.Empty; + sample.IssueDate = _apiDateTimeHelper.Get(DateTime.UtcNow); + sample.DueDate = _apiDateTimeHelper.Get(DateTime.UtcNow.AddDays(30)); + sample.CreateOn = _apiDateTimeHelper.Get(DateTime.UtcNow); - sample.Currency = CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency); + sample.Currency = _mapper.Map(defaultCurrency); sample.InvoiceLines.First().Quantity = 1; @@ -161,12 +149,12 @@ public InvoiceDto GetInvoiceSample() [Read(@"invoice/jsondata/{invoiceid:int}")] public string GetInvoiceJsonData(int invoiceid) { - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceid); if (invoice == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(invoice)) + if (!_crmSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } return invoice.JsonData; @@ -210,13 +198,13 @@ String currency OrderBy invoiceOrderBy; - var searchString = ApiContext.FilterValue; + var searchString = _apiContext.FilterValue; - if (InvoiceSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) + if (InvoiceSortedByType.TryParse(_apiContext.SortBy, true, out sortBy)) { - invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + invoiceOrderBy = new OrderBy(sortBy, !_apiContext.SortDescending); } - else if (String.IsNullOrEmpty(ApiContext.SortBy)) + else if (String.IsNullOrEmpty(_apiContext.SortBy)) { invoiceOrderBy = new OrderBy(InvoiceSortedByType.Number, true); } @@ -225,13 +213,13 @@ String currency invoiceOrderBy = null; } - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; + var fromIndex = (int)_apiContext.StartIndex; + var count = (int)_apiContext.Count; if (invoiceOrderBy != null) { result = ToListInvoiceBaseDtos( - DaoFactory.GetInvoiceDao().GetInvoices( + _daoFactory.GetInvoiceDao().GetInvoices( searchString, status, issueDateFrom, issueDateTo, @@ -241,14 +229,14 @@ String currency fromIndex, count, invoiceOrderBy)); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else { result = ToListInvoiceBaseDtos( - DaoFactory.GetInvoiceDao().GetInvoices( + _daoFactory.GetInvoiceDao().GetInvoices( searchString, status, issueDateFrom, issueDateTo, @@ -268,7 +256,7 @@ String currency } else { - totalCount = DaoFactory.GetInvoiceDao().GetInvoicesCount( + totalCount = _daoFactory.GetInvoiceDao().GetInvoicesCount( searchString, status, issueDateFrom, issueDateTo, @@ -277,7 +265,7 @@ String currency currency); } - ApiContext.SetTotalCount(totalCount); + _apiContext.SetTotalCount(totalCount); return result; } @@ -295,7 +283,7 @@ public IEnumerable GetEntityInvoices(String entityType, int enti { if (String.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException(); - return ToListInvoiceBaseDtos(DaoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); + return ToListInvoiceBaseDtos(_daoFactory.GetInvoiceDao().GetEntityInvoices(ToEntityType(entityType), entityid)); } /// @@ -314,9 +302,9 @@ InvoiceStatus status { if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); - var oldInvoices = DaoFactory.GetInvoiceDao().GetByID(invoiceids).Where(CRMSecurity.CanAccessTo).ToList(); + var oldInvoices = _daoFactory.GetInvoiceDao().GetByID(invoiceids).Where(_crmSecurity.CanAccessTo).ToList(); - var updatedInvoices = DaoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status); + var updatedInvoices = _daoFactory.GetInvoiceDao().UpdateInvoiceBatchStatus(oldInvoices.ToList().Select(i => i.ID).ToArray(), status); // detect what really changed var realUpdatedInvoices = updatedInvoices @@ -326,14 +314,14 @@ InvoiceStatus status if (realUpdatedInvoices.Any()) { - MessageService.Send(MessageAction.InvoicesUpdatedStatus, MessageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString()); + _messageService.Send(MessageAction.InvoicesUpdatedStatus, _messageTarget.Create(realUpdatedInvoices.Select(x => x.ID)), realUpdatedInvoices.Select(x => x.Number), status.ToLocalizedString()); } var invoiceItemsUpdated = new List(); if (status == InvoiceStatus.Sent || status == InvoiceStatus.Rejected) { - var invoiceItemsAll = DaoFactory.GetInvoiceItemDao().GetAll(); + var invoiceItemsAll = _daoFactory.GetInvoiceItemDao().GetAll(); var invoiceItemsWithTrackInventory = invoiceItemsAll.Where(item => item.TrackInventory).ToList(); if (status == InvoiceStatus.Sent && invoiceItemsWithTrackInventory != null && invoiceItemsWithTrackInventory.Count != 0) @@ -347,7 +335,7 @@ InvoiceStatus status if (oldInv != null && oldInv.Status == InvoiceStatus.Draft) { //was changed to Sent - var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + var invoiceLines = _daoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); foreach (var line in invoiceLines) { @@ -355,7 +343,7 @@ InvoiceStatus status if (item != null) { item.StockQuantity -= line.Quantity; - DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); + _daoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); if (oldItem != null) { @@ -380,7 +368,7 @@ InvoiceStatus status if (oldInv != null && oldInv.Status == InvoiceStatus.Sent) { //was changed from Sent to Rejectes - var invoiceLines = DaoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); + var invoiceLines = _daoFactory.GetInvoiceLineDao().GetInvoiceLines(inv.ID); foreach (var line in invoiceLines) { @@ -388,16 +376,16 @@ InvoiceStatus status if (item != null) { item.StockQuantity += line.Quantity; - - DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); - + + _daoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(item); + var oldItem = invoiceItemsUpdated.Find(i => i.ID == item.ID); - + if (oldItem != null) { invoiceItemsUpdated.Remove(oldItem); } - + invoiceItemsUpdated.Add(item); } } @@ -426,14 +414,13 @@ public InvoiceBaseDto DeleteInvoice(int invoiceid) { if (invoiceid <= 0) throw new ArgumentException(); - var invoice = DaoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); + var invoice = _daoFactory.GetInvoiceDao().DeleteInvoice(invoiceid); if (invoice == null) throw new ItemNotFoundException(); - MessageService.Send(MessageAction.InvoiceDeleted, MessageTarget.Create(invoice.ID), invoice.Number); - - return InvoiceBaseDtoHelper.Get(invoice); + _messageService.Send(MessageAction.InvoiceDeleted, _messageTarget.Create(invoice.ID), invoice.Number); + return _mapper.Map(invoice); } /// @@ -448,8 +435,8 @@ public IEnumerable DeleteBatchInvoices(IEnumerable invoicei { if (invoiceids == null || !invoiceids.Any()) throw new ArgumentException(); - var invoices = DaoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); - MessageService.Send(MessageAction.InvoicesDeleted, MessageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); + var invoices = _daoFactory.GetInvoiceDao().DeleteBatchInvoices(invoiceids.ToArray()); + _messageService.Send(MessageAction.InvoicesDeleted, _messageTarget.Create(invoices.Select(x => x.ID)), invoices.Select(x => x.Number)); return ToListInvoiceBaseDtos(invoices); } @@ -552,30 +539,30 @@ CreateOrUpdateInvoiceRequestDto inDto Description = description }; - CRMSecurity.DemandCreateOrUpdate(invoice); + _crmSecurity.DemandCreateOrUpdate(invoice); if (billingAddressID > 0) { - var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); + var address = _daoFactory.GetContactInfoDao().GetByID(billingAddressID); if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) throw new ArgumentException(); } if (deliveryAddressID > 0) { - var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); + var address = _daoFactory.GetContactInfoDao().GetByID(deliveryAddressID); if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) throw new ArgumentException(); } - invoice.ID = DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + invoice.ID = _daoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); CreateInvoiceLines(invoiceLinesList, invoice); - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + _daoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - return InvoiceDtoHelper.Get(invoice); + return _mapper.Map(invoice); } @@ -588,13 +575,13 @@ private bool IsLinesForInvoiceCorrect(List invoiceLines) line.Discount < 0 || line.Discount > 100 || line.InvoiceTax1ID < 0 || line.InvoiceTax2ID < 0) return false; - if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) + if (!_daoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) return false; - if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) + if (line.InvoiceTax1ID > 0 && !_daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) return false; - if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) + if (line.InvoiceTax2ID > 0 && !_daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) return false; } return true; @@ -619,7 +606,7 @@ private List CreateInvoiceLines(List invoiceLines, Inv Discount = Convert.ToInt32(invoiceLines[i].Discount) }; - line.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line); + line.ID = _daoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(line); result.Add(line); } return result; @@ -682,7 +669,7 @@ private List CreateInvoiceLines(List invoiceLines, Inv public InvoiceDto UpdateInvoice( int id, CreateOrUpdateInvoiceRequestDto inDto) - + { ApiDateTime issueDate = inDto.IssueDate; int templateType = inDto.TemplateType; @@ -703,8 +690,8 @@ public InvoiceDto UpdateInvoice( var invoiceLinesList = invoiceLines != null ? invoiceLines.ToList() : new List(); if (!invoiceLinesList.Any() || !IsLinesForInvoiceCorrect(invoiceLinesList)) throw new ArgumentException(); - var invoice = DaoFactory.GetInvoiceDao().GetByID(id); - if (invoice == null || !CRMSecurity.CanEdit(invoice)) throw new ItemNotFoundException(); + var invoice = _daoFactory.GetInvoiceDao().GetByID(id); + if (invoice == null || !_crmSecurity.CanEdit(invoice)) throw new ItemNotFoundException(); invoice.IssueDate = issueDate; invoice.TemplateType = (InvoiceTemplateType)templateType; @@ -721,36 +708,36 @@ public InvoiceDto UpdateInvoice( invoice.Description = description; invoice.JsonData = null; - CRMSecurity.DemandCreateOrUpdate(invoice); + _crmSecurity.DemandCreateOrUpdate(invoice); if (billingAddressID > 0) { - var address = DaoFactory.GetContactInfoDao().GetByID(billingAddressID); + var address = _daoFactory.GetContactInfoDao().GetByID(billingAddressID); if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Billing || address.ContactID != contactId) throw new ArgumentException(); } if (deliveryAddressID > 0) { - var address = DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID); + var address = _daoFactory.GetContactInfoDao().GetByID(deliveryAddressID); if (address == null || address.InfoType != ContactInfoType.Address || address.Category != (int)AddressCategory.Postal || address.ContactID != consigneeId) throw new ArgumentException(); } - DaoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); + _daoFactory.GetInvoiceDao().SaveOrUpdateInvoice(invoice); - DaoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID); + _daoFactory.GetInvoiceLineDao().DeleteInvoiceLines(invoice.ID); CreateInvoiceLines(invoiceLinesList, invoice); - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); + _daoFactory.GetInvoiceDao().UpdateInvoiceJsonData(invoice, billingAddressID, deliveryAddressID); - if (Global.CanDownloadInvoices) + if (_global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(invoice.ID); + _pdfQueueWorker.StartTask(invoice.ID); } - return InvoiceDtoHelper.Get(invoice); + return _mapper.Map(invoice); } /// @@ -765,20 +752,20 @@ public FileWrapper GetInvoicePdfExistOrCreate(int invoiceid) { if (invoiceid <= 0) throw new ArgumentException(); - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceid); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceid); if (invoice == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(invoice)) + if (!_crmSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } - return FileWrapperHelper.Get(GetInvoicePdfExistingOrCreate(invoice)); + return _fileWrapperHelper.Get(GetInvoicePdfExistingOrCreate(invoice)); } private ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice) { - var existingFile = invoice.GetInvoiceFile(DaoFactory); + var existingFile = invoice.GetInvoiceFile(_daoFactory); if (existingFile != null) { @@ -786,13 +773,13 @@ private ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Enti } else { - var newFile = PdfCreator.CreateFile(invoice, DaoFactory); + var newFile = _pdfCreator.CreateFile(invoice, _daoFactory); invoice.FileID = Int32.Parse(newFile.ID.ToString()); - DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + _daoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + _daoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); return newFile; } @@ -813,12 +800,12 @@ public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, s { if (invoiceId <= 0) throw new ArgumentException(); - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceId); if (invoice == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(invoice)) + if (!_crmSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } var converterData = new ConverterData @@ -828,7 +815,7 @@ public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, s InvoiceId = invoiceId }; - var existingFile = invoice.GetInvoiceFile(DaoFactory); + var existingFile = invoice.GetInvoiceFile(_daoFactory); if (existingFile != null) { converterData.FileId = invoice.FileID; @@ -837,16 +824,16 @@ public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, s if (string.IsNullOrEmpty(storageUrl) || string.IsNullOrEmpty(revisionId)) { - return PdfCreator.StartCreationFileAsync(invoice); + return _pdfCreator.StartCreationFileAsync(invoice); } else { - var convertedFile = PdfCreator.GetConvertedFile(converterData, DaoFactory); + var convertedFile = _pdfCreator.GetConvertedFile(converterData, _daoFactory); if (convertedFile != null) { invoice.FileID = Int32.Parse(convertedFile.ID.ToString()); - DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + _daoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + _daoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); converterData.FileId = invoice.FileID; return converterData; @@ -870,7 +857,7 @@ public Boolean GetInvoiceByNumberExistence(string number) { if (String.IsNullOrEmpty(number)) throw new ArgumentException(); - return DaoFactory.GetInvoiceDao().IsExist(number); + return _daoFactory.GetInvoiceDao().IsExist(number); } @@ -886,15 +873,15 @@ public InvoiceDto GetInvoiceByNumber(string number) { if (String.IsNullOrEmpty(number)) throw new ArgumentException(); - var invoice = DaoFactory.GetInvoiceDao().GetByNumber(number); + var invoice = _daoFactory.GetInvoiceDao().GetByNumber(number); if (invoice == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(invoice)) + if (!_crmSecurity.CanAccessTo(invoice)) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } - return InvoiceDtoHelper.Get(invoice); + return _mapper.Map(invoice); } /// @@ -914,13 +901,13 @@ public IEnumerable GetInvoiceItems(int status, bool? inventorySt OrderBy invoiceOrderBy; - var searchString = ApiContext.FilterValue; + var searchString = _apiContext.FilterValue; - if (InvoiceItemSortedByType.TryParse(ApiContext.SortBy, true, out sortBy)) + if (InvoiceItemSortedByType.TryParse(_apiContext.SortBy, true, out sortBy)) { - invoiceOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + invoiceOrderBy = new OrderBy(sortBy, !_apiContext.SortDescending); } - else if (String.IsNullOrEmpty(ApiContext.SortBy)) + else if (String.IsNullOrEmpty(_apiContext.SortBy)) { invoiceOrderBy = new OrderBy(InvoiceItemSortedByType.Name, true); } @@ -929,32 +916,32 @@ public IEnumerable GetInvoiceItems(int status, bool? inventorySt invoiceOrderBy = null; } - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; + var fromIndex = (int)_apiContext.StartIndex; + var count = (int)_apiContext.Count; if (invoiceOrderBy != null) { - var resultFromDao = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( + var resultFromDao = _daoFactory.GetInvoiceItemDao().GetInvoiceItems( searchString, status, inventoryStock, fromIndex, count, invoiceOrderBy); - result = _mapper.Map, List>(resultFromDao); - - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + result = _mapper.Map, List>(resultFromDao); + + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else { - var resultFromDao = DaoFactory.GetInvoiceItemDao().GetInvoiceItems( - searchString, - status, - inventoryStock, - 0, 0, - null); + var resultFromDao = _daoFactory.GetInvoiceItemDao().GetInvoiceItems( + searchString, + status, + inventoryStock, + 0, 0, + null); result = _mapper.Map, List>(resultFromDao); @@ -968,13 +955,13 @@ public IEnumerable GetInvoiceItems(int status, bool? inventorySt } else { - totalCount = DaoFactory.GetInvoiceItemDao().GetInvoiceItemsCount( + totalCount = _daoFactory.GetInvoiceItemDao().GetInvoiceItemsCount( searchString, status, inventoryStock); } - ApiContext.SetTotalCount(totalCount); + _apiContext.SetTotalCount(totalCount); return result; } @@ -991,7 +978,7 @@ public InvoiceItemDto GetInvoiceItemByID(int invoiceitemid) { if (invoiceitemid <= 0) throw new ArgumentException(); - var invoiceItem = DaoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); + var invoiceItem = _daoFactory.GetInvoiceItemDao().GetByID(invoiceitemid); if (invoiceItem == null) throw new ItemNotFoundException(); return _mapper.Map(invoiceItem); @@ -1043,20 +1030,20 @@ CreateOrUpdateInvoiceLineRequestDto inDto if (invoiceId <= 0) throw new ArgumentException(); - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceId); + + _crmSecurity.DemandCreateOrUpdate(invoiceLine, invoice); - CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + invoiceLine.ID = _daoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); - invoiceLine.ID = DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + _daoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - - if (Global.CanDownloadInvoices) + if (_global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(invoice.ID); + _pdfQueueWorker.StartTask(invoice.ID); } - return InvoiceLineDtoHelper.Get(invoiceLine); + return _mapper.Map(invoiceLine); } /// @@ -1076,10 +1063,7 @@ CreateOrUpdateInvoiceLineRequestDto inDto /// Invoices /// InvoiceLine [Update(@"invoiceline/{id:int}")] - public InvoiceLineDto UpdateInvoiceLine( - int id, - CreateOrUpdateInvoiceLineRequestDto inDto - ) + public InvoiceLineDto UpdateInvoiceLine(int id, CreateOrUpdateInvoiceLineRequestDto inDto) { int invoiceId = inDto.InvoiceId; int invoiceItemId = inDto.InvoiceItemId; @@ -1094,7 +1078,8 @@ CreateOrUpdateInvoiceLineRequestDto inDto if (invoiceId <= 0) throw new ArgumentException(); - var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); + var invoiceLine = _daoFactory.GetInvoiceLineDao().GetByID(id); + if (invoiceLine == null || invoiceLine.InvoiceID != invoiceId) throw new ItemNotFoundException(); @@ -1108,19 +1093,19 @@ CreateOrUpdateInvoiceLineRequestDto inDto invoiceLine.Price = price; invoiceLine.Discount = discount; - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); - CRMSecurity.DemandCreateOrUpdate(invoiceLine, invoice); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceId); + _crmSecurity.DemandCreateOrUpdate(invoiceLine, invoice); - DaoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); + _daoFactory.GetInvoiceLineDao().SaveOrUpdateInvoiceLine(invoiceLine); - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + _daoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - if (Global.CanDownloadInvoices) + if (_global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(invoice.ID); + _pdfQueueWorker.StartTask(invoice.ID); } - return InvoiceLineDtoHelper.Get(invoiceLine); + return _mapper.Map(invoiceLine); } /// @@ -1133,21 +1118,21 @@ CreateOrUpdateInvoiceLineRequestDto inDto [Delete(@"invoiceline/{id:int}")] public int DeleteInvoiceLine(int id) { - var invoiceLine = DaoFactory.GetInvoiceLineDao().GetByID(id); + var invoiceLine = _daoFactory.GetInvoiceLineDao().GetByID(id); if (invoiceLine == null) throw new ItemNotFoundException(); - if (!DaoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line"); + if (!_daoFactory.GetInvoiceLineDao().CanDelete(invoiceLine.ID)) throw new Exception("Can't delete invoice line"); - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceLine.InvoiceID); if (invoice == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanEdit(invoice)) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.CanEdit(invoice)) throw _crmSecurity.CreateSecurityException(); - DaoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); + _daoFactory.GetInvoiceLineDao().DeleteInvoiceLine(id); - DaoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); + _daoFactory.GetInvoiceDao().UpdateInvoiceJsonDataAfterLinesUpdated(invoice); - if (Global.CanDownloadInvoices) + if (_global.CanDownloadInvoices) { - PdfQueueWorker.StartTask(invoice.ID); + _pdfQueueWorker.StartTask(invoice.ID); } return id; @@ -1183,9 +1168,9 @@ CreateOrUpdateInvoiceItemRequestDto inDto int invoiceTax1id = inDto.InvoiceTax1id; int invoiceTax2id = inDto.InvoiceTax2id; - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } if (String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); @@ -1202,9 +1187,9 @@ CreateOrUpdateInvoiceItemRequestDto inDto InvoiceTax2ID = invoiceTax2id }; - invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + invoiceItem = _daoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); - MessageService.Send(MessageAction.InvoiceItemCreated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + _messageService.Send(MessageAction.InvoiceItemCreated, _messageTarget.Create(invoiceItem.ID), invoiceItem.Title); return _mapper.Map(invoiceItem); } @@ -1240,14 +1225,14 @@ CreateOrUpdateInvoiceItemRequestDto inDto int invoiceTax1id = inDto.InvoiceTax1id; int invoiceTax2id = inDto.InvoiceTax2id; - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } if (id <= 0 || String.IsNullOrEmpty(title) || price <= 0) throw new ArgumentException(); - if (!DaoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException(); + if (!_daoFactory.GetInvoiceItemDao().IsExist(id)) throw new ItemNotFoundException(); var invoiceItem = new InvoiceItem { @@ -1262,8 +1247,8 @@ CreateOrUpdateInvoiceItemRequestDto inDto InvoiceTax2ID = invoiceTax2id }; - invoiceItem = DaoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); - MessageService.Send(MessageAction.InvoiceItemUpdated, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + invoiceItem = _daoFactory.GetInvoiceItemDao().SaveOrUpdateInvoiceItem(invoiceItem); + _messageService.Send(MessageAction.InvoiceItemUpdated, _messageTarget.Create(invoiceItem.ID), invoiceItem.Title); return _mapper.Map(invoiceItem); } @@ -1278,17 +1263,17 @@ CreateOrUpdateInvoiceItemRequestDto inDto [Delete(@"invoiceitem/{id:int}")] public InvoiceItemDto DeleteInvoiceItem(int id) { - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } if (id <= 0) throw new ArgumentException(); - var invoiceItem = DaoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id); + var invoiceItem = _daoFactory.GetInvoiceItemDao().DeleteInvoiceItem(id); if (invoiceItem == null) throw new ItemNotFoundException(); - MessageService.Send(MessageAction.InvoiceItemDeleted, MessageTarget.Create(invoiceItem.ID), invoiceItem.Title); + _messageService.Send(MessageAction.InvoiceItemDeleted, _messageTarget.Create(invoiceItem.ID), invoiceItem.Title); return _mapper.Map(invoiceItem); @@ -1304,17 +1289,17 @@ public InvoiceItemDto DeleteInvoiceItem(int id) [Delete(@"invoiceitem")] public IEnumerable DeleteBatchItems(IEnumerable ids) { - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } if (ids == null) throw new ArgumentException(); ids = ids.Distinct(); - var items = DaoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); - - MessageService.Send(MessageAction.InvoiceItemsDeleted, MessageTarget.Create(ids), items.Select(x => x.Title)); + var items = _daoFactory.GetInvoiceItemDao().DeleteBatchInvoiceItems(ids.ToArray()); + + _messageService.Send(MessageAction.InvoiceItemsDeleted, _messageTarget.Create(ids), items.Select(x => x.Title)); return _mapper.Map, List>(items); } @@ -1328,7 +1313,7 @@ public IEnumerable DeleteBatchItems(IEnumerable ids) [Read(@"invoice/tax")] public IEnumerable GetInvoiceTaxes() { - var responceFromDao = DaoFactory.GetInvoiceTaxDao().GetAll(); + var responceFromDao = _daoFactory.GetInvoiceTaxDao().GetAll(); return _mapper.Map, List>(responceFromDao); } @@ -1350,13 +1335,13 @@ public InvoiceTaxDto CreateInvoiceTax( string description = inDto.Description; decimal rate = inDto.Rate; - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } if (String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); - if (DaoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError); + if (_daoFactory.GetInvoiceTaxDao().IsExist(name)) throw new ArgumentException(CRMInvoiceResource.ExistTaxNameError); var invoiceTax = new InvoiceTax { @@ -1365,8 +1350,8 @@ public InvoiceTaxDto CreateInvoiceTax( Rate = rate }; - invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); - MessageService.Send(MessageAction.InvoiceTaxCreated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + invoiceTax = _daoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); + _messageService.Send(MessageAction.InvoiceTaxCreated, _messageTarget.Create(invoiceTax.ID), invoiceTax.Name); return _mapper.Map(invoiceTax); } @@ -1390,14 +1375,14 @@ public InvoiceTaxDto UpdateInvoiceTax( string description = inDto.Description; decimal rate = inDto.Rate; - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } if (id <= 0 || String.IsNullOrEmpty(name)) throw new ArgumentException(CRMInvoiceResource.EmptyTaxNameError); - if (!DaoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException(); + if (!_daoFactory.GetInvoiceTaxDao().IsExist(id)) throw new ItemNotFoundException(); var invoiceTax = new InvoiceTax { @@ -1407,8 +1392,8 @@ public InvoiceTaxDto UpdateInvoiceTax( Rate = rate }; - invoiceTax = DaoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); - MessageService.Send(MessageAction.InvoiceTaxUpdated, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + invoiceTax = _daoFactory.GetInvoiceTaxDao().SaveOrUpdateInvoiceTax(invoiceTax); + _messageService.Send(MessageAction.InvoiceTaxUpdated, _messageTarget.Create(invoiceTax.ID), invoiceTax.Name); return _mapper.Map(invoiceTax); } @@ -1423,17 +1408,17 @@ public InvoiceTaxDto UpdateInvoiceTax( [Delete(@"invoice/tax/{id:int}")] public InvoiceTaxDto DeleteInvoiceTax(int id) { - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } if (id <= 0) throw new ArgumentException(); - var invoiceTax = DaoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id); + var invoiceTax = _daoFactory.GetInvoiceTaxDao().DeleteInvoiceTax(id); if (invoiceTax == null) throw new ItemNotFoundException(); - MessageService.Send(MessageAction.InvoiceTaxDeleted, MessageTarget.Create(invoiceTax.ID), invoiceTax.Name); + _messageService.Send(MessageAction.InvoiceTaxDeleted, _messageTarget.Create(invoiceTax.ID), invoiceTax.Name); return _mapper.Map(invoiceTax); } @@ -1447,7 +1432,7 @@ public InvoiceTaxDto DeleteInvoiceTax(int id) [Read(@"invoice/settings")] public InvoiceSetting GetSettings() { - return DaoFactory.GetInvoiceDao().GetSettings(); + return _daoFactory.GetInvoiceDao().GetSettings(); } /// @@ -1468,12 +1453,12 @@ SaveNumberSettingsRequestDto inDto var number = inDto.Number; var prefix = inDto.Prefix; - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); if (autogenerated && string.IsNullOrEmpty(number)) throw new ArgumentException(); - if (autogenerated && DaoFactory.GetInvoiceDao().IsExist(prefix + number)) + if (autogenerated && _daoFactory.GetInvoiceDao().IsExist(prefix + number)) throw new ArgumentException(); var invoiceSetting = GetSettings(); @@ -1482,8 +1467,8 @@ SaveNumberSettingsRequestDto inDto invoiceSetting.Prefix = prefix; invoiceSetting.Number = number; - var settings = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); - MessageService.Send(MessageAction.InvoiceNumberFormatUpdated); + var settings = _daoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); + _messageService.Send(MessageAction.InvoiceNumberFormatUpdated); return settings; } @@ -1498,14 +1483,14 @@ SaveNumberSettingsRequestDto inDto [Update(@"invoice/settings/terms")] public InvoiceSetting SaveTermsSettings(string terms) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var invoiceSetting = GetSettings(); invoiceSetting.Terms = terms; - var result = DaoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); - MessageService.Send(MessageAction.InvoiceDefaultTermsUpdated); + var result = _daoFactory.GetInvoiceDao().SaveInvoiceSettings(invoiceSetting); + _messageService.Send(MessageAction.InvoiceDefaultTermsUpdated); return result; } @@ -1514,10 +1499,10 @@ public InvoiceSetting SaveTermsSettings(string terms) [Update(@"invoice/{invoiceid:int}/creationdate")] public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate) { - var dao = DaoFactory.GetInvoiceDao(); + var dao = _daoFactory.GetInvoiceDao(); var invoice = dao.GetByID(invoiceid); - if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) + if (invoice == null || !_crmSecurity.CanAccessTo(invoice)) throw new ItemNotFoundException(); dao.SetInvoiceCreationDate(invoiceid, creationDate); @@ -1527,11 +1512,13 @@ public void SetInvoiceCreationDate(int invoiceid, ApiDateTime creationDate) [Update(@"invoice/{invoiceid:int}/lastmodifeddate")] public void SetInvoiceLastModifedDate(int invoiceid, ApiDateTime lastModifedDate) { - var dao = DaoFactory.GetInvoiceDao(); + var dao = _daoFactory.GetInvoiceDao(); var invoice = dao.GetByID(invoiceid); - if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) + if (invoice == null || !_crmSecurity.CanAccessTo(invoice)) + { throw new ItemNotFoundException(); + } dao.SetInvoiceLastModifedDate(invoiceid, lastModifedDate); } @@ -1542,17 +1529,17 @@ private IEnumerable ToListInvoiceBaseDtos(ICollection i var result = new List(); - var contactIDs = items.Select(item => item.ContactID); + contactIDs.ToList().AddRange(items.Select(item => item.ConsigneeID)); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) - .ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseWithEmailDto(x)); + var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) + .ToDictionary(item => item.ID, x => _mapper.Map(x)); foreach (var invoice in items) { - var invoiceDto = InvoiceBaseDtoHelper.Get(invoice); + var invoiceDto = _mapper.Map(invoice); if (contacts.ContainsKey(invoice.ContactID)) { @@ -1569,7 +1556,7 @@ private IEnumerable ToListInvoiceBaseDtos(ICollection i invoiceDto.Entity = ToEntityDto(invoice.EntityType, invoice.EntityID); //Need to optimize } - invoiceDto.Cost = invoice.GetInvoiceCost(DaoFactory); + invoiceDto.Cost = invoice.GetInvoiceCost(_daoFactory); result.Add(invoiceDto); } @@ -1589,7 +1576,7 @@ private EntityDto ToEntityDto(EntityType entityType, int entityID) switch (entityType) { case EntityType.Case: - var caseObj = DaoFactory.GetCasesDao().GetByID(entityID); + var caseObj = _daoFactory.GetCasesDao().GetByID(entityID); if (caseObj == null) return null; @@ -1598,7 +1585,7 @@ private EntityDto ToEntityDto(EntityType entityType, int entityID) break; case EntityType.Opportunity: - var dealObj = DaoFactory.GetDealDao().GetByID(entityID); + var dealObj = _daoFactory.GetDealDao().GetByID(entityID); if (dealObj == null) return null; diff --git a/products/ASC.CRM/Server/Api/ListItemsController.cs b/products/ASC.CRM/Server/Api/ListItemsController.cs index 667d2c68fb0..e2bb3254e16 100644 --- a/products/ASC.CRM/Server/Api/ListItemsController.cs +++ b/products/ASC.CRM/Server/Api/ListItemsController.cs @@ -38,6 +38,8 @@ using ASC.MessagingSystem; using ASC.Web.Api.Routing; +using AutoMapper; + namespace ASC.CRM.Api { public class ListItemsController : BaseApiController @@ -45,20 +47,18 @@ public class ListItemsController : BaseApiController public ListItemsController(CRMSecurity cRMSecurity, DaoFactory daoFactory, MessageTarget messageTarget, - MessageService messageService, - TaskCategoryDtoHelper taskCategoryDtoHelper, - HistoryCategoryDtoHelper historyCategoryDtoHelper) - : base(daoFactory, cRMSecurity) + MessageService messageService, + HistoryCategoryDtoHelper historyCategoryDtoHelper, + IMapper mapper) + : base(daoFactory, cRMSecurity, mapper) { MessageTarget = messageTarget; MessageService = messageService; - TaskCategoryDtoHelper = taskCategoryDtoHelper; HistoryCategoryDtoHelper = historyCategoryDtoHelper; } public MessageService MessageService { get; } public MessageTarget MessageTarget { get; } - public TaskCategoryDtoHelper TaskCategoryDtoHelper { get; } public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } /// @@ -83,7 +83,7 @@ public DealMilestoneDto CreateDealMilestone( int successProbability, DealMilestoneStatus stageType) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (string.IsNullOrEmpty(title)) throw new ArgumentException(); @@ -98,7 +98,7 @@ public DealMilestoneDto CreateDealMilestone( Status = stageType }; - dealMilestone.ID = DaoFactory.GetDealMilestoneDao().Create(dealMilestone); + dealMilestone.ID = _daoFactory.GetDealMilestoneDao().Create(dealMilestone); MessageService.Send(MessageAction.OpportunityStageCreated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneDto(dealMilestone); @@ -129,13 +129,13 @@ public DealMilestoneDto UpdateDealMilestone( int successProbability, DealMilestoneStatus stageType) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); if (successProbability < 0) successProbability = 0; - var curDealMilestoneExist = DaoFactory.GetDealMilestoneDao().IsExist(id); + var curDealMilestoneExist = _daoFactory.GetDealMilestoneDao().IsExist(id); if (!curDealMilestoneExist) throw new ItemNotFoundException(); var dealMilestone = new DealMilestone @@ -148,7 +148,7 @@ public DealMilestoneDto UpdateDealMilestone( ID = id }; - DaoFactory.GetDealMilestoneDao().Edit(dealMilestone); + _daoFactory.GetDealMilestoneDao().Edit(dealMilestone); MessageService.Send(MessageAction.OpportunityStageUpdated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneDto(dealMilestone); @@ -169,16 +169,16 @@ public DealMilestoneDto UpdateDealMilestone( [Update(@"opportunity/stage/{id:int}/color")] public DealMilestoneDto UpdateDealMilestoneColor(int id, string color) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0) throw new ArgumentException(); - var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(id); + var dealMilestone = _daoFactory.GetDealMilestoneDao().GetByID(id); if (dealMilestone == null) throw new ItemNotFoundException(); dealMilestone.Color = color; - DaoFactory.GetDealMilestoneDao().ChangeColor(id, color); + _daoFactory.GetDealMilestoneDao().ChangeColor(id, color); MessageService.Send(MessageAction.OpportunityStageUpdatedColor, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneDto(dealMilestone); @@ -201,15 +201,15 @@ public DealMilestoneDto UpdateDealMilestoneColor(int id, string color) [Update(@"opportunity/stage/reorder")] public IEnumerable UpdateDealMilestonesOrder(IEnumerable ids) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (ids == null) throw new ArgumentException(); var idsList = ids.ToList(); - var result = idsList.Select(id => DaoFactory.GetDealMilestoneDao().GetByID(id)).ToList(); + var result = idsList.Select(id => _daoFactory.GetDealMilestoneDao().GetByID(id)).ToList(); - DaoFactory.GetDealMilestoneDao().Reorder(idsList.ToArray()); + _daoFactory.GetDealMilestoneDao().Reorder(idsList.ToArray()); MessageService.Send(MessageAction.OpportunityStagesUpdatedOrder, MessageTarget.Create(idsList), result.Select(x => x.Title)); return result.Select(ToDealMilestoneDto); @@ -229,16 +229,16 @@ public IEnumerable UpdateDealMilestonesOrder(IEnumerable [Delete(@"opportunity/stage/{id:int}")] public DealMilestoneDto DeleteDealMilestone(int id) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0) throw new ArgumentException(); - var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(id); + var dealMilestone = _daoFactory.GetDealMilestoneDao().GetByID(id); if (dealMilestone == null) throw new ItemNotFoundException(); var result = ToDealMilestoneDto(dealMilestone); - DaoFactory.GetDealMilestoneDao().Delete(id); + _daoFactory.GetDealMilestoneDao().Delete(id); MessageService.Send(MessageAction.OpportunityStageDeleted, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); return result; @@ -258,7 +258,7 @@ public DealMilestoneDto DeleteDealMilestone(int id) [Create(@"history/category")] public HistoryCategoryDto CreateHistoryCategory(string title, string description, string imageName, int sortOrder) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (string.IsNullOrEmpty(title)) throw new ArgumentException(); @@ -270,7 +270,7 @@ public HistoryCategoryDto CreateHistoryCategory(string title, string description AdditionalParams = imageName }; - listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.HistoryCategory, listItem); + listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.HistoryCategory, listItem); MessageService.Send(MessageAction.HistoryEventCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); return ToHistoryCategoryDto(listItem); @@ -292,11 +292,11 @@ public HistoryCategoryDto CreateHistoryCategory(string title, string description [Update(@"history/category/{id:int}")] public HistoryCategoryDto UpdateHistoryCategory(int id, string title, string description, string imageName, int sortOrder) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); - var curHistoryCategoryExist = DaoFactory.GetListItemDao().IsExist(id); + var curHistoryCategoryExist = _daoFactory.GetListItemDao().IsExist(id); if (!curHistoryCategoryExist) throw new ItemNotFoundException(); var listItem = new ListItem @@ -308,7 +308,7 @@ public HistoryCategoryDto UpdateHistoryCategory(int id, string title, string des ID = id }; - DaoFactory.GetListItemDao().EditItem(ListType.HistoryCategory, listItem); + _daoFactory.GetListItemDao().EditItem(ListType.HistoryCategory, listItem); MessageService.Send(MessageAction.HistoryEventCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); return ToHistoryCategoryDto(listItem); @@ -329,16 +329,16 @@ public HistoryCategoryDto UpdateHistoryCategory(int id, string title, string des [Update(@"history/category/{id:int}/icon")] public HistoryCategoryDto UpdateHistoryCategoryIcon(int id, string imageName) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0) throw new ArgumentException(); - var historyCategory = DaoFactory.GetListItemDao().GetByID(id); + var historyCategory = _daoFactory.GetListItemDao().GetByID(id); if (historyCategory == null) throw new ItemNotFoundException(); historyCategory.AdditionalParams = imageName; - DaoFactory.GetListItemDao().ChangePicture(id, imageName); + _daoFactory.GetListItemDao().ChangePicture(id, imageName); MessageService.Send(MessageAction.HistoryEventCategoryUpdatedIcon, MessageTarget.Create(historyCategory.ID), historyCategory.Title); return ToHistoryCategoryDto(historyCategory); @@ -361,13 +361,13 @@ public HistoryCategoryDto UpdateHistoryCategoryIcon(int id, string imageName) [Update(@"history/category/reorder")] public IEnumerable UpdateHistoryCategoriesOrder(IEnumerable titles) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (titles == null) throw new ArgumentException(); - var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.HistoryCategory, title)).ToList(); + var result = titles.Select(title => _daoFactory.GetListItemDao().GetByTitle(ListType.HistoryCategory, title)).ToList(); - DaoFactory.GetListItemDao().ReorderItems(ListType.HistoryCategory, titles.ToArray()); + _daoFactory.GetListItemDao().ReorderItems(ListType.HistoryCategory, titles.ToArray()); MessageService.Send(MessageAction.HistoryEventCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToHistoryCategoryDto); @@ -386,11 +386,11 @@ public IEnumerable UpdateHistoryCategoriesOrder(IEnumerable< [Delete(@"history/category/{id:int}")] public HistoryCategoryDto DeleteHistoryCategory(int id) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0) throw new ArgumentException(); - var dao = DaoFactory.GetListItemDao(); + var dao = _daoFactory.GetListItemDao(); var listItem = dao.GetByID(id); if (listItem == null) throw new ItemNotFoundException(); @@ -424,7 +424,7 @@ public HistoryCategoryDto DeleteHistoryCategory(int id) [Create(@"task/category")] public TaskCategoryDto CreateTaskCategory(string title, string description, string imageName, int sortOrder) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); var listItem = new ListItem { @@ -434,7 +434,7 @@ public TaskCategoryDto CreateTaskCategory(string title, string description, stri AdditionalParams = imageName }; - listItem.ID = DaoFactory.GetListItemDao().CreateItem(ListType.TaskCategory, listItem); + listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.TaskCategory, listItem); MessageService.Send(MessageAction.CrmTaskCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryDto(listItem); @@ -460,11 +460,11 @@ public TaskCategoryDto CreateTaskCategory(string title, string description, stri [Update(@"task/category/{id:int}")] public TaskCategoryDto UpdateTaskCategory(int id, string title, string description, string imageName, int sortOrder) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); - var curTaskCategoryExist = DaoFactory.GetListItemDao().IsExist(id); + var curTaskCategoryExist = _daoFactory.GetListItemDao().IsExist(id); if (!curTaskCategoryExist) throw new ItemNotFoundException(); var listItem = new ListItem @@ -476,7 +476,7 @@ public TaskCategoryDto UpdateTaskCategory(int id, string title, string descripti ID = id }; - DaoFactory.GetListItemDao().EditItem(ListType.TaskCategory, listItem); + _daoFactory.GetListItemDao().EditItem(ListType.TaskCategory, listItem); MessageService.Send(MessageAction.CrmTaskCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryDto(listItem); @@ -497,16 +497,16 @@ public TaskCategoryDto UpdateTaskCategory(int id, string title, string descripti [Update(@"task/category/{id:int}/icon")] public TaskCategoryDto UpdateTaskCategoryIcon(int id, string imageName) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (id <= 0) throw new ArgumentException(); - var taskCategory = DaoFactory.GetListItemDao().GetByID(id); + var taskCategory = _daoFactory.GetListItemDao().GetByID(id); if (taskCategory == null) throw new ItemNotFoundException(); taskCategory.AdditionalParams = imageName; - DaoFactory.GetListItemDao().ChangePicture(id, imageName); + _daoFactory.GetListItemDao().ChangePicture(id, imageName); MessageService.Send(MessageAction.CrmTaskCategoryUpdatedIcon, MessageTarget.Create(taskCategory.ID), taskCategory.Title); return ToTaskCategoryDto(taskCategory); @@ -529,13 +529,13 @@ public TaskCategoryDto UpdateTaskCategoryIcon(int id, string imageName) [Update(@"task/category/reorder")] public IEnumerable UpdateTaskCategoriesOrder(IEnumerable titles) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (titles == null) throw new ArgumentException(); - var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.TaskCategory, title)).ToList(); + var result = titles.Select(title => _daoFactory.GetListItemDao().GetByTitle(ListType.TaskCategory, title)).ToList(); - DaoFactory.GetListItemDao().ReorderItems(ListType.TaskCategory, titles.ToArray()); + _daoFactory.GetListItemDao().ReorderItems(ListType.TaskCategory, titles.ToArray()); MessageService.Send(MessageAction.CrmTaskCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToTaskCategoryDto); @@ -554,11 +554,11 @@ public IEnumerable UpdateTaskCategoriesOrder(IEnumerable UpdateContactStatusesOrder(IEnumerable titles) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (titles == null) throw new ArgumentException(); - var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.ContactStatus, title)).ToList(); + var result = titles.Select(title => _daoFactory.GetListItemDao().GetByTitle(ListType.ContactStatus, title)).ToList(); - DaoFactory.GetListItemDao().ReorderItems(ListType.ContactStatus, titles.ToArray()); + _daoFactory.GetListItemDao().ReorderItems(ListType.ContactStatus, titles.ToArray()); MessageService.Send(MessageAction.ContactTemperatureLevelsUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToContactStatusDto); @@ -722,11 +722,11 @@ public IEnumerable UpdateContactStatusesOrder(IEnumerable UpdateContactTypesOrder(IEnumerable titles) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (titles == null) throw new ArgumentException(); - var result = titles.Select(title => DaoFactory.GetListItemDao().GetByTitle(ListType.ContactType, title)).ToList(); + var result = titles.Select(title => _daoFactory.GetListItemDao().GetByTitle(ListType.ContactType, title)).ToList(); - DaoFactory.GetListItemDao().ReorderItems(ListType.ContactType, titles.ToArray()); + _daoFactory.GetListItemDao().ReorderItems(ListType.ContactType, titles.ToArray()); MessageService.Send(MessageAction.ContactTypesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToContactTypeDto); @@ -875,10 +875,10 @@ public IEnumerable UpdateContactTypesOrder(IEnumerable t [Delete(@"contact/type/{contactTypeid:int}")] public ContactTypeDto DeleteContactType(int contactTypeid) { - if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); if (contactTypeid <= 0) throw new ArgumentException(); - var dao = DaoFactory.GetListItemDao(); + var dao = _daoFactory.GetListItemDao(); var listItem = dao.GetByID(contactTypeid); if (listItem == null) throw new ItemNotFoundException(); @@ -910,7 +910,7 @@ public ContactTypeDto GetContactTypeByID(int contactTypeid) { if (contactTypeid <= 0) throw new ArgumentException(); - var listItem = DaoFactory.GetListItemDao().GetByID(contactTypeid); + var listItem = _daoFactory.GetListItemDao().GetByID(contactTypeid); if (listItem == null) throw new ItemNotFoundException(); return ToContactTypeDto(listItem); @@ -930,7 +930,7 @@ public DealMilestoneDto GetDealMilestoneByID(int stageid) { if (stageid <= 0) throw new ArgumentException(); - var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(stageid); + var dealMilestone = _daoFactory.GetDealMilestoneDao().GetByID(stageid); if (dealMilestone == null) throw new ItemNotFoundException(); return ToDealMilestoneDto(dealMilestone); @@ -950,7 +950,7 @@ public TaskCategoryDto GetTaskCategoryByID(int categoryid) { if (categoryid <= 0) throw new ArgumentException(); - var listItem = DaoFactory.GetListItemDao().GetByID(categoryid); + var listItem = _daoFactory.GetListItemDao().GetByID(categoryid); if (listItem == null) throw new ItemNotFoundException(); return ToTaskCategoryDto(listItem); @@ -967,9 +967,9 @@ public TaskCategoryDto GetTaskCategoryByID(int categoryid) [Read(@"history/category")] public IEnumerable GetHistoryCategoryDto() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.HistoryCategory).ConvertAll(item => new HistoryCategoryDto(item)); + var result = _daoFactory.GetListItemDao().GetItems(ListType.HistoryCategory).ConvertAll(item => new HistoryCategoryDto(item)); - var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory); + var relativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory); result.ForEach(x => { @@ -990,9 +990,9 @@ public IEnumerable GetHistoryCategoryDto() [Read(@"task/category")] public IEnumerable GetTaskCategories() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => (TaskCategoryDto)TaskCategoryDtoHelper.Get(item)); + var result = _daoFactory.GetListItemDao().GetItems(ListType.TaskCategory).ConvertAll(item => (TaskCategoryDto)_mapper.Map(item)); - var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory); + var relativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory); result.ForEach(x => { @@ -1013,9 +1013,9 @@ public IEnumerable GetTaskCategories() [Read(@"contact/status")] public IEnumerable GetContactStatuses() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactStatus).ConvertAll(item => new ContactStatusDto(item)); + var result = _daoFactory.GetListItemDao().GetItems(ListType.ContactStatus).ConvertAll(item => new ContactStatusDto(item)); - var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus); + var relativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus); result.ForEach(x => { @@ -1036,9 +1036,9 @@ public IEnumerable GetContactStatuses() [Read(@"contact/type")] public IEnumerable GetContactTypes() { - var result = DaoFactory.GetListItemDao().GetItems(ListType.ContactType).ConvertAll(item => new ContactTypeDto(item)); + var result = _daoFactory.GetListItemDao().GetItems(ListType.ContactType).ConvertAll(item => new ContactTypeDto(item)); - var relativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType); + var relativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType); result.ForEach(x => { @@ -1060,9 +1060,9 @@ public IEnumerable GetContactTypes() [Read(@"opportunity/stage")] public IEnumerable GetDealMilestones() { - var result = DaoFactory.GetDealMilestoneDao().GetAll().ConvertAll(item => new DealMilestoneDto(item)); + var result = _daoFactory.GetDealMilestoneDao().GetAll().ConvertAll(item => new DealMilestoneDto(item)); - var relativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(); + var relativeItemsCount = _daoFactory.GetDealMilestoneDao().GetRelativeItemsCount(); result.ForEach(x => { @@ -1077,7 +1077,7 @@ public ContactStatusDto ToContactStatusDto(ListItem listItem) { var result = new ContactStatusDto(listItem) { - RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, listItem.ID) + RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, listItem.ID) }; return result; @@ -1087,7 +1087,7 @@ public ContactTypeDto ToContactTypeDto(ListItem listItem) { var result = new ContactTypeDto(listItem) { - RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, listItem.ID) + RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, listItem.ID) }; return result; @@ -1097,16 +1097,16 @@ public HistoryCategoryDto ToHistoryCategoryDto(ListItem listItem) { var result = (HistoryCategoryDto)HistoryCategoryDtoHelper.Get(listItem); - result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID); + result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID); return result; } public TaskCategoryDto ToTaskCategoryDto(ListItem listItem) { - var result = (TaskCategoryDto)TaskCategoryDtoHelper.Get(listItem); + var result = (TaskCategoryDto)_mapper.Map(listItem); - result.RelativeItemsCount = DaoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID); + result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID); return result; } @@ -1115,7 +1115,7 @@ private DealMilestoneDto ToDealMilestoneDto(DealMilestone dealMilestone) { var result = new DealMilestoneDto(dealMilestone) { - RelativeItemsCount = DaoFactory.GetDealMilestoneDao().GetRelativeItemsCount(dealMilestone.ID) + RelativeItemsCount = _daoFactory.GetDealMilestoneDao().GetRelativeItemsCount(dealMilestone.ID) }; return result; } diff --git a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs index f86567dfccd..07879c859d5 100644 --- a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs +++ b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs @@ -24,30 +24,29 @@ */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + using ASC.Api.Core; -using ASC.CRM.ApiModels; +using ASC.Api.CRM; using ASC.Api.Documents; using ASC.Common.Web; +using ASC.CRM.ApiModels; using ASC.CRM.Core; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.Files.Utils; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; +using AutoMapper; using OrderBy = ASC.CRM.Core.Entities.OrderBy; -using ASC.Api.CRM; -using ASC.CRM.Core.Dao; -using ASC.Web.CRM.Services.NotifyService; -using ASC.Core; -using ASC.Web.Core.Users; namespace ASC.CRM.Api { @@ -58,19 +57,16 @@ public RelationshipEventsController(CRMSecurity cRMSecurity, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, - ContactDtoHelper contactBaseDtoHelper, - RelationshipEventDtoHelper relationshipEventDtoHelper, FileWrapperHelper fileWrapperHelper, ASC.Files.Core.Data.DaoFactory filesDaoFactory, FileUploader fileUploader, - HistoryCategoryDtoHelper historyCategoryDtoHelper) - : base(daoFactory, cRMSecurity) + HistoryCategoryDtoHelper historyCategoryDtoHelper, + IMapper mapper) + : base(daoFactory, cRMSecurity, mapper) { ApiContext = apiContext; MessageTarget = messageTarget; MessageService = messageService; - ContactDtoHelper = contactBaseDtoHelper; - RelationshipEventDtoHelper = relationshipEventDtoHelper; FileWrapperHelper = fileWrapperHelper; FilesDaoFactory = filesDaoFactory; FileUploader = fileUploader; @@ -81,12 +77,10 @@ public RelationshipEventsController(CRMSecurity cRMSecurity, public FileUploader FileUploader { get; } public ASC.Files.Core.Data.DaoFactory FilesDaoFactory { get; set; } public FileWrapperHelper FileWrapperHelper { get; } - public RelationshipEventDtoHelper RelationshipEventDtoHelper { get; } - public ContactDtoHelper ContactDtoHelper { get; } private ApiContext ApiContext { get; } public MessageService MessageService { get; } public MessageTarget MessageTarget { get; } - + /// /// Returns the list of all events matching the parameters specified in the request /// @@ -117,18 +111,18 @@ public IEnumerable GetHistory( switch (entityTypeObj) { case EntityType.Contact: - var contact = DaoFactory.GetContactDao().GetByID(entityId); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) + var contact = _daoFactory.GetContactDao().GetByID(entityId); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); break; case EntityType.Case: - var cases = DaoFactory.GetCasesDao().GetByID(entityId); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) + var cases = _daoFactory.GetCasesDao().GetByID(entityId); + if (cases == null || !_crmSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); break; case EntityType.Opportunity: - var deal = DaoFactory.GetDealDao().GetByID(entityId); - if (deal == null || !CRMSecurity.CanAccessTo(deal)) + var deal = _daoFactory.GetDealDao().GetByID(entityId); + if (deal == null || !_crmSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); break; default: @@ -160,7 +154,7 @@ public IEnumerable GetHistory( if (eventOrderBy != null) { - result = ToListRelationshipEventDto(DaoFactory.GetRelationshipEventDao().GetItems( + result = ToListRelationshipEventDto(_daoFactory.GetRelationshipEventDao().GetItems( ApiContext.FilterValue, entityTypeObj, entityId, @@ -178,7 +172,7 @@ public IEnumerable GetHistory( } else { - result = ToListRelationshipEventDto(DaoFactory.GetRelationshipEventDao().GetItems( + result = ToListRelationshipEventDto(_daoFactory.GetRelationshipEventDao().GetItems( ApiContext.FilterValue, entityTypeObj, entityId, @@ -212,11 +206,11 @@ public RelationshipEventDto DeleteHistory(int id) { if (id <= 0) throw new ArgumentException(); - var item = DaoFactory.GetRelationshipEventDao().GetByID(id); + var item = _daoFactory.GetRelationshipEventDao().GetByID(id); if (item == null) throw new ItemNotFoundException(); - var wrapper = RelationshipEventDtoHelper.Get(item); + var wrapper = _mapper.Map(item); - DaoFactory.GetRelationshipEventDao().DeleteItem(id); + _daoFactory.GetRelationshipEventDao().DeleteItem(id); var messageAction = GetHistoryDeletedAction(item.EntityType, item.ContactID); var entityTitle = wrapper.Contact == null ? wrapper.Entity.EntityTitle : wrapper.Contact.DisplayName; @@ -506,18 +500,18 @@ public RelationshipEventDto AttachFiles(string entityType, int entityid, IEnumer switch (entityTypeObj) { case EntityType.Contact: - var relationshipEvent1 = DaoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray()); + var relationshipEvent1 = _daoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray()); var messageAction = entityObj is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return RelationshipEventDtoHelper.Get(relationshipEvent1); + return _mapper.Map(relationshipEvent1); case EntityType.Opportunity: - var relationshipEvent2 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); + var relationshipEvent2 = _daoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); MessageService.Send(MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return RelationshipEventDtoHelper.Get(relationshipEvent2); + return _mapper.Map(relationshipEvent2); case EntityType.Case: - var relationshipEvent3 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); + var relationshipEvent3 = _daoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); MessageService.Send(MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); - return RelationshipEventDtoHelper.Get(relationshipEvent3); + return _mapper.Map(relationshipEvent3); default: throw new ArgumentException(); } @@ -534,7 +528,7 @@ public RelationshipEventDto AttachFiles(string entityType, int entityid, IEnumer [Read(@"files/root")] public int GetRootFolderID() { - return DaoFactory.GetFileDao().GetRoot(); + return _daoFactory.GetFileDao().GetRoot(); } /// @@ -557,10 +551,10 @@ public IEnumerable> GetFiles(string entityType, int entityid) switch (entityTypeObj) { case EntityType.Contact: - return DaoFactory.GetRelationshipEventDao().GetAllFiles(new[] { entityid }, EntityType.Any, 0).ConvertAll(file => FileWrapperHelper.Get(file)); + return _daoFactory.GetRelationshipEventDao().GetAllFiles(new[] { entityid }, EntityType.Any, 0).ConvertAll(file => FileWrapperHelper.Get(file)); case EntityType.Opportunity: case EntityType.Case: - return DaoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => FileWrapperHelper.Get(file)); + return _daoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => FileWrapperHelper.Get(file)); default: throw new ArgumentException(); } @@ -586,7 +580,7 @@ public FileWrapper DeleteCRMFile(int fileid) if (file == null) throw new ItemNotFoundException(); var result = FileWrapperHelper.Get(file); - var _eventsDao = DaoFactory.GetRelationshipEventDao(); + var _eventsDao = _daoFactory.GetRelationshipEventDao(); var eventIDs = _eventsDao.RemoveFile(file); var events = new List(); @@ -654,7 +648,7 @@ private IEnumerable ToListRelationshipEventDto(List { if (item == null) return; @@ -670,7 +664,7 @@ private IEnumerable ToListRelationshipEventDto(List { if (item == null) return; @@ -690,15 +684,15 @@ private IEnumerable ToListRelationshipEventDto(List x.ID, x => HistoryCategoryDtoHelper.Get(x)); + var categories = _daoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => HistoryCategoryDtoHelper.Get(x)); - var files = DaoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray()); + var files = _daoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray()); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => ContactDtoHelper.GetContactBaseDto(x)); + var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => _mapper.Map(x)); foreach (var item in itemList) { - var eventObjWrap = RelationshipEventDtoHelper.Get(item); + var eventObjWrap = _mapper.Map(item); if (contacts.ContainsKey(item.ContactID)) { @@ -729,13 +723,13 @@ private IEnumerable ToListRelationshipEventDto(List 0) { - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyCreatedHistoryEvent : MessageAction.PersonCreatedHistoryEvent; } @@ -746,7 +740,7 @@ private MessageAction GetHistoryCreatedAction(EntityType entityType, int contact case EntityType.Case: return MessageAction.CaseCreatedHistoryEvent; case EntityType.Any: - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyCreatedHistoryEvent : MessageAction.PersonCreatedHistoryEvent; default: throw new ArgumentException("Invalid entityType: " + entityType); @@ -757,7 +751,7 @@ private MessageAction GetHistoryDeletedAction(EntityType entityType, int contact { if (contactId > 0) { - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyDeletedHistoryEvent : MessageAction.PersonDeletedHistoryEvent; } @@ -768,7 +762,7 @@ private MessageAction GetHistoryDeletedAction(EntityType entityType, int contact case EntityType.Case: return MessageAction.CaseDeletedHistoryEvent; case EntityType.Any: - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyDeletedHistoryEvent : MessageAction.PersonDeletedHistoryEvent; default: throw new ArgumentException("Invalid entityType: " + entityType); @@ -779,7 +773,7 @@ private MessageAction GetFilesAttachAction(EntityType entityType, int contactId) { if (contactId > 0) { - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; } @@ -790,7 +784,7 @@ private MessageAction GetFilesAttachAction(EntityType entityType, int contactId) case EntityType.Case: return MessageAction.CaseAttachedFiles; case EntityType.Any: - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; default: throw new ArgumentException("Invalid entityType: " + entityType); @@ -801,7 +795,7 @@ private MessageAction GetFilesDetachAction(EntityType entityType, int contactId) { if (contactId > 0) { - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyDetachedFile : MessageAction.PersonDetachedFile; } @@ -812,7 +806,7 @@ private MessageAction GetFilesDetachAction(EntityType entityType, int contactId) case EntityType.Case: return MessageAction.CaseDetachedFile; case EntityType.Any: - var contact = DaoFactory.GetContactDao().GetByID(contactId); + var contact = _daoFactory.GetContactDao().GetByID(contactId); return contact is Company ? MessageAction.CompanyDetachedFile : MessageAction.PersonAttachedFiles; default: throw new ArgumentException("Invalid entityType: " + entityType); diff --git a/products/ASC.CRM/Server/Api/ReportsController.cs b/products/ASC.CRM/Server/Api/ReportsController.cs index ea73d1e080e..cc3295ac1be 100644 --- a/products/ASC.CRM/Server/Api/ReportsController.cs +++ b/products/ASC.CRM/Server/Api/ReportsController.cs @@ -24,39 +24,37 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Api.CRM; using ASC.Api.Documents; using ASC.Common.Web; -using ASC.Core; using ASC.Core.Common.Settings; -using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; -using ASC.MessagingSystem; using ASC.Web.Api.Routing; using ASC.Web.CRM.Classes; using ASC.Web.Files.Services.DocumentService; -using Microsoft.AspNetCore.Http; - -using System; -using System.Collections.Generic; -using System.Linq; +using AutoMapper; namespace ASC.CRM.Api { public class ReportsController : BaseApiController { - public ReportsController(CRMSecurity cRMSecurity, + public ReportsController(CRMSecurity crmSecurity, DaoFactory daoFactory, SettingsManager settingsManager, Global global, ReportHelper reportHelper, FileWrapperHelper fileWrapperHelper, - DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper + DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper, + IMapper mapper ) - : base(daoFactory, cRMSecurity) + : base(daoFactory, crmSecurity, mapper) { SettingsManager = settingsManager; Global = global; @@ -66,7 +64,7 @@ DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper } public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } - + public FileWrapperHelper FileWrapperHelper { get; } public ReportHelper ReportHelper { get; } public Global Global { get; } @@ -81,9 +79,9 @@ DocbuilderReportsUtilityHelper docbuilderReportsUtilityHelper public IEnumerable> GetFiles() { if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); - var reportDao = DaoFactory.GetReportDao(); + var reportDao = _daoFactory.GetReportDao(); var files = reportDao.GetFiles(); @@ -115,15 +113,15 @@ public IEnumerable> GetFiles() public void DeleteFile(int fileid) { if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); if (fileid < 0) throw new ArgumentException(); - var file = DaoFactory.GetReportDao().GetFile(fileid); + var file = _daoFactory.GetReportDao().GetFile(fileid); if (file == null) throw new ItemNotFoundException("File not found"); - DaoFactory.GetReportDao().DeleteFile(fileid); + _daoFactory.GetReportDao().DeleteFile(fileid); } /// Get the state of the report generation task @@ -135,7 +133,7 @@ public void DeleteFile(int fileid) public ReportState GetStatus() { if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); return DocbuilderReportsUtilityHelper.Status(ReportOrigin.CRM); @@ -149,7 +147,7 @@ public ReportState GetStatus() public void Terminate() { if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); DocbuilderReportsUtilityHelper.Terminate(ReportOrigin.CRM); } @@ -166,7 +164,7 @@ public void Terminate() public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) { if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); return new { @@ -187,7 +185,7 @@ public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) { if (!Global.CanCreateReports) - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); return ReportHelper.RunGenareteReport(type, timePeriod, managers); } diff --git a/products/ASC.CRM/Server/Api/TagsController.cs b/products/ASC.CRM/Server/Api/TagsController.cs index 462631a17f8..731c426301b 100644 --- a/products/ASC.CRM/Server/Api/TagsController.cs +++ b/products/ASC.CRM/Server/Api/TagsController.cs @@ -39,7 +39,8 @@ using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; -using ASC.Web.CRM.Services.NotifyService; + +using AutoMapper; namespace ASC.CRM.Api { @@ -49,8 +50,9 @@ public TagsController(CRMSecurity cRMSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, - MessageService messageService) - : base(daoFactory, cRMSecurity) + MessageService messageService, + IMapper mapper) + : base(daoFactory, cRMSecurity, mapper) { ApiContext = apiContext; MessageTarget = messageTarget; @@ -84,23 +86,23 @@ public IEnumerable GetEntityTags(string entityType, int entityid) case EntityType.Contact: case EntityType.Person: case EntityType.Company: - var contact = DaoFactory.GetContactDao().GetByID(entityid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) + var contact = _daoFactory.GetContactDao().GetByID(entityid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); break; case EntityType.Case: - var cases = DaoFactory.GetCasesDao().GetByID(entityid); - if (cases == null || !CRMSecurity.CanAccessTo(cases)) + var cases = _daoFactory.GetCasesDao().GetByID(entityid); + if (cases == null || !_crmSecurity.CanAccessTo(cases)) throw new ItemNotFoundException(); break; case EntityType.Opportunity: - var deal = DaoFactory.GetDealDao().GetByID(entityid); - if (deal == null || !CRMSecurity.CanAccessTo(deal)) + var deal = _daoFactory.GetDealDao().GetByID(entityid); + if (deal == null || !_crmSecurity.CanAccessTo(deal)) throw new ItemNotFoundException(); break; } - return DaoFactory.GetTagDao().GetEntityTags(entityTypeObj, entityid); + return _daoFactory.GetTagDao().GetEntityTags(entityTypeObj, entityid); } /// @@ -117,10 +119,10 @@ public IEnumerable GetEntityTags(string entityType, int entityid) public IEnumerable GetContactTags(int contactid) { if (contactid <= 0) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(contactid); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) + var contact = _daoFactory.GetContactDao().GetByID(contactid); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - return DaoFactory.GetTagDao().GetEntityTags(EntityType.Contact, contactid); + return _daoFactory.GetTagDao().GetEntityTags(EntityType.Contact, contactid); } /// @@ -142,7 +144,7 @@ public string CreateTag(string entityType, string tagName) var entityTypeObj = ToEntityType(entityType); var messageAction = GetEntityTagCreatedAction(entityTypeObj); - DaoFactory.GetTagDao().AddTag(entityTypeObj, tagName); + _daoFactory.GetTagDao().AddTag(entityTypeObj, tagName); MessageService.Send(messageAction, tagName); @@ -165,8 +167,8 @@ public IEnumerable GetAllTags(string entityType) if (string.IsNullOrEmpty(entityType)) throw new ArgumentException(); var entType = ToEntityType(entityType); - var tagTitles = DaoFactory.GetTagDao().GetAllTags(entType).ToList(); - var relativeItemsCountArrayJSON = DaoFactory.GetTagDao().GetTagsLinkCount(entType).ToList(); + var tagTitles = _daoFactory.GetTagDao().GetAllTags(entType).ToList(); + var relativeItemsCountArrayJSON = _daoFactory.GetTagDao().GetTagsLinkCount(entType).ToList(); if (tagTitles.Count != relativeItemsCountArrayJSON.Count) throw new ArgumentException(); var result = new List(); @@ -228,7 +230,7 @@ public string AddTagToBatchContacts( ApiDateTime toDate, string tagName) { - var contacts = DaoFactory + var contacts = _daoFactory .GetContactDao() .GetContacts(ApiContext.FilterValue, tags, @@ -239,7 +241,7 @@ public string AddTagToBatchContacts( toDate, 0, 0, - null).Where(CRMSecurity.CanEdit).ToList(); + null).Where(_crmSecurity.CanEdit).ToList(); foreach (var contact in contacts) { @@ -279,7 +281,7 @@ public string AddTagToBatchDeals( ApiDateTime toDate, string tagName) { - var deals = DaoFactory + var deals = _daoFactory .GetDealDao() .GetDeals( ApiContext.FilterValue, @@ -289,7 +291,7 @@ public string AddTagToBatchDeals( contactid, stageType, contactAlsoIsParticipant, - fromDate, toDate, 0, 0, null).Where(CRMSecurity.CanAccessTo).ToList(); + fromDate, toDate, 0, 0, null).Where(_crmSecurity.CanAccessTo).ToList(); foreach (var deal in deals) { @@ -314,8 +316,8 @@ public string AddTagToBatchDeals( [Create(@"case/filter/taglist")] public string AddTagToBatchCases(int contactid, bool? isClosed, IEnumerable tags, string tagName) { - var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null) - .Where(CRMSecurity.CanAccessTo).ToList(); + var caseses = _daoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null) + .Where(_crmSecurity.CanAccessTo).ToList(); if (!caseses.Any()) return tagName; @@ -337,13 +339,13 @@ public string AddTagToBatchCases(int contactid, bool? isClosed, IEnumerable DeleteUnusedTag(string entityType) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var entityTypeObj = ToEntityType(entityType); - var result = DaoFactory.GetTagDao().GetUnusedTags(entityTypeObj); + var result = _daoFactory.GetTagDao().GetUnusedTags(entityTypeObj); - DaoFactory.GetTagDao().DeleteUnusedTags(entityTypeObj); + _daoFactory.GetTagDao().DeleteUnusedTags(entityTypeObj); return new List(result); } @@ -369,9 +371,9 @@ public string AddTagTo(string entityType, int entityid, string tagName) DomainObject entityObj; var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj); - if (entityTypeObj == EntityType.Contact && !CRMSecurity.CanEdit(entityObj as Contact)) throw CRMSecurity.CreateSecurityException(); + if (entityTypeObj == EntityType.Contact && !_crmSecurity.CanEdit(entityObj as Contact)) throw _crmSecurity.CreateSecurityException(); - DaoFactory.GetTagDao().AddTagToEntity(entityTypeObj, entityid, tagName); + _daoFactory.GetTagDao().AddTagToEntity(entityTypeObj, entityid, tagName); var messageAction = GetTagCreatedAction(entityTypeObj, entityid); MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, tagName); @@ -401,8 +403,8 @@ public string AddContactTagToGroup(string entityType, int entityid, string tagNa var entityTypeObj = ToEntityType(entityType); if (entityTypeObj != EntityType.Company && entityTypeObj != EntityType.Person) throw new ArgumentException(); - var contactInst = DaoFactory.GetContactDao().GetByID(entityid); - if (contactInst == null || !CRMSecurity.CanAccessTo(contactInst)) throw new ItemNotFoundException(); + var contactInst = _daoFactory.GetContactDao().GetByID(entityid); + if (contactInst == null || !_crmSecurity.CanAccessTo(contactInst)) throw new ItemNotFoundException(); if (contactInst is Person && entityTypeObj == EntityType.Company) throw new Exception(CRMErrorsResource.ContactIsNotCompany); if (contactInst is Company && entityTypeObj == EntityType.Person) throw new Exception(CRMErrorsResource.ContactIsNotPerson); @@ -415,11 +417,11 @@ public string AddContactTagToGroup(string entityType, int entityid, string tagNa { contactIDsToAddTag.Add(contactInst.ID); - var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID); + var members = _daoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID); foreach (var m in members) { - if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + if (_crmSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) { contactIDsToAddTag.Add(m.Key); } @@ -430,16 +432,16 @@ public string AddContactTagToGroup(string entityType, int entityid, string tagNa var CompanyID = ((Person)contactInst).CompanyID; if (CompanyID != 0) { - var cnt = DaoFactory.GetContactDao().GetByID(CompanyID); - if (cnt != null && cnt is Company && CRMSecurity.CanAccessTo(cnt)) + var cnt = _daoFactory.GetContactDao().GetByID(CompanyID); + if (cnt != null && cnt is Company && _crmSecurity.CanAccessTo(cnt)) { contactIDsToAddTag.Add(CompanyID); - var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID); + var members = _daoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID); foreach (var m in members) { - if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + if (_crmSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) { contactIDsToAddTag.Add(m.Key); } @@ -456,7 +458,7 @@ public string AddContactTagToGroup(string entityType, int entityid, string tagNa } } - DaoFactory.GetTagDao().AddTagToContacts(contactIDsToAddTag.ToArray(), tagName); + _daoFactory.GetTagDao().AddTagToContacts(contactIDsToAddTag.ToArray(), tagName); var entityTitle = contactInst.GetTitle(); @@ -489,9 +491,9 @@ public string DeleteTag(string entityType, string tagName) var entityTypeObj = ToEntityType(entityType); - if (!DaoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException(); + if (!_daoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException(); - DaoFactory.GetTagDao().DeleteTag(entityTypeObj, tagName); + _daoFactory.GetTagDao().DeleteTag(entityTypeObj, tagName); var messageAction = GetEntityTagDeletedAction(entityTypeObj); MessageService.Send(messageAction, tagName); @@ -520,11 +522,11 @@ public string DeleteTagFrom(string entityType, int entityid, string tagName) DomainObject entityObj; var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj); - if (entityTypeObj == EntityType.Contact && !CRMSecurity.CanEdit(entityObj as Contact)) throw CRMSecurity.CreateSecurityException(); + if (entityTypeObj == EntityType.Contact && !_crmSecurity.CanEdit(entityObj as Contact)) throw _crmSecurity.CreateSecurityException(); - if (!DaoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException(); + if (!_daoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException(); - DaoFactory.GetTagDao().DeleteTagFromEntity(entityTypeObj, entityid, tagName); + _daoFactory.GetTagDao().DeleteTagFromEntity(entityTypeObj, entityid, tagName); var messageAction = GetTagDeletedAction(entityTypeObj, entityid); @@ -555,7 +557,7 @@ public string DeleteContactTagFromGroup(string entityType, int entityid, string var entityTypeObj = ToEntityType(entityType); if (entityTypeObj != EntityType.Company && entityTypeObj != EntityType.Person) throw new ArgumentException(); - var contactInst = DaoFactory.GetContactDao().GetByID(entityid); + var contactInst = _daoFactory.GetContactDao().GetByID(entityid); if (contactInst == null) throw new ItemNotFoundException(); if (contactInst is Person && entityTypeObj == EntityType.Company) throw new Exception(CRMErrorsResource.ContactIsNotCompany); @@ -567,11 +569,11 @@ public string DeleteContactTagFromGroup(string entityType, int entityid, string { contactIDsForDeleteTag.Add(contactInst.ID); - var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID); + var members = _daoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID); foreach (var m in members) { - if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + if (_crmSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) { contactIDsForDeleteTag.Add(m.Key); } @@ -582,16 +584,16 @@ public string DeleteContactTagFromGroup(string entityType, int entityid, string var CompanyID = ((Person)contactInst).CompanyID; if (CompanyID != 0) { - var cnt = DaoFactory.GetContactDao().GetByID(CompanyID); - if (cnt != null && cnt is Company && CRMSecurity.CanAccessTo(cnt)) + var cnt = _daoFactory.GetContactDao().GetByID(CompanyID); + if (cnt != null && cnt is Company && _crmSecurity.CanAccessTo(cnt)) { contactIDsForDeleteTag.Add(CompanyID); - var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID); + var members = _daoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID); foreach (var m in members) { - if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) + if (_crmSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0)) { contactIDsForDeleteTag.Add(m.Key); } @@ -608,7 +610,7 @@ public string DeleteContactTagFromGroup(string entityType, int entityid, string } } - DaoFactory.GetTagDao().DeleteTagFromContacts(contactIDsForDeleteTag.ToArray(), tagName); + _daoFactory.GetTagDao().DeleteTagFromContacts(contactIDsForDeleteTag.ToArray(), tagName); return tagName; } @@ -649,7 +651,7 @@ private MessageAction GetTagCreatedAction(EntityType entityType, int entityId) switch (entityType) { case EntityType.Contact: - var entity = DaoFactory.GetContactDao().GetByID(entityId); + var entity = _daoFactory.GetContactDao().GetByID(entityId); return entity is Company ? MessageAction.CompanyCreatedTag : MessageAction.PersonCreatedTag; case EntityType.Company: return MessageAction.CompanyCreatedTag; @@ -682,7 +684,7 @@ private MessageAction GetTagDeletedAction(EntityType entityType, int entityId) switch (entityType) { case EntityType.Contact: - var entity = DaoFactory.GetContactDao().GetByID(entityId); + var entity = _daoFactory.GetContactDao().GetByID(entityId); return entity is Company ? MessageAction.CompanyDeletedTag : MessageAction.PersonDeletedTag; case EntityType.Company: return MessageAction.CompanyDeletedTag; diff --git a/products/ASC.CRM/Server/Api/TaskTemplateController.cs b/products/ASC.CRM/Server/Api/TaskTemplateController.cs index 832ecceb121..2978423e7ae 100644 --- a/products/ASC.CRM/Server/Api/TaskTemplateController.cs +++ b/products/ASC.CRM/Server/Api/TaskTemplateController.cs @@ -24,37 +24,37 @@ */ -using ASC.CRM.ApiModels; -using ASC.Common.Web; -using ASC.CRM.Core.Entities; -using ASC.Web.Api.Routing; - using System; using System.Collections.Generic; using System.Linq; + using ASC.Api.CRM; +using ASC.Common.Web; +using ASC.CRM.ApiModels; using ASC.CRM.Core; -using ASC.Api.Core; using ASC.CRM.Core.Dao; -using ASC.Web.CRM.Services.NotifyService; -using ASC.MessagingSystem; +using ASC.CRM.Core.Entities; using ASC.Web.Api.Models; +using ASC.Web.Api.Routing; + +using AutoMapper; namespace ASC.CRM.Api { public class TaskTemplateController : BaseApiController { - public TaskTemplateController(CRMSecurity cRMSecurity, - DaoFactory daoFactory, - EmployeeWraperHelper employeeWraperHelper) - : base(daoFactory, cRMSecurity) + public TaskTemplateController(CRMSecurity crmSecurity, + DaoFactory daoFactory, + EmployeeWraperHelper employeeWraperHelper, + IMapper mapper) + : base(daoFactory, crmSecurity, mapper) { EmployeeWraperHelper = employeeWraperHelper; } public EmployeeWraperHelper EmployeeWraperHelper { get; } - + /// /// Creates a new task template container with the type and title specified in the request @@ -79,7 +79,7 @@ public TaskTemplateContainerDto CreateTaskTemplateContainer(string entityType, s Title = title }; - taskTemplateContainer.ID = DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(taskTemplateContainer); + taskTemplateContainer.ID = _daoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(taskTemplateContainer); return ToTaskTemplateContainerDto(taskTemplateContainer); } @@ -96,7 +96,7 @@ public TaskTemplateContainerDto CreateTaskTemplateContainer(string entityType, s [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/tasktemplatecontainer")] public IEnumerable GetTaskTemplateContainers(string entityType) { - return ToTaskListTemplateContainerDto(DaoFactory.GetTaskTemplateContainerDao().GetItems(ToEntityType(entityType))); + return ToTaskListTemplateContainerDto(_daoFactory.GetTaskTemplateContainerDao().GetItems(ToEntityType(entityType))); } /// @@ -116,10 +116,10 @@ public TaskTemplateContainerDto DeleteTaskTemplateContainer(int containerid) { if (containerid <= 0) throw new ArgumentException(); - var result = ToTaskTemplateContainerDto(DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid)); + var result = ToTaskTemplateContainerDto(_daoFactory.GetTaskTemplateContainerDao().GetByID(containerid)); if (result == null) throw new ItemNotFoundException(); - DaoFactory.GetTaskTemplateContainerDao().Delete(containerid); + _daoFactory.GetTaskTemplateContainerDao().Delete(containerid); return result; } @@ -142,12 +142,12 @@ public TaskTemplateContainerDto UpdateTaskTemplateContainer(int containerid, str { if (containerid <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException(); - var result = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + var result = _daoFactory.GetTaskTemplateContainerDao().GetByID(containerid); if (result == null) throw new ItemNotFoundException(); result.Title = title; - DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(result); + _daoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(result); return ToTaskTemplateContainerDto(result); } @@ -169,7 +169,7 @@ public TaskTemplateContainerDto GetTaskTemplateContainerByID(int containerid) { if (containerid <= 0) throw new ArgumentException(); - var item = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + var item = _daoFactory.GetTaskTemplateContainerDao().GetByID(containerid); if (item == null) throw new ItemNotFoundException(); return ToTaskTemplateContainerDto(item); @@ -192,10 +192,10 @@ public IEnumerable GetTaskTemplates(int containerid) { if (containerid <= 0) throw new ArgumentException(); - var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + var container = _daoFactory.GetTaskTemplateContainerDao().GetByID(containerid); if (container == null) throw new ItemNotFoundException(); - return DaoFactory.GetTaskTemplateDao().GetList(containerid).ConvertAll(ToTaskTemplateDto); + return _daoFactory.GetTaskTemplateDao().GetList(containerid).ConvertAll(ToTaskTemplateDto); } /// @@ -229,7 +229,7 @@ bool deadLineIsFixed { if (containerid <= 0 || string.IsNullOrEmpty(title) || categoryid <= 0) throw new ArgumentException(); - var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + var container = _daoFactory.GetTaskTemplateContainerDao().GetByID(containerid); if (container == null) throw new ItemNotFoundException(); var item = new TaskTemplate @@ -244,7 +244,7 @@ bool deadLineIsFixed Offset = TimeSpan.FromTicks(offsetTicks) }; - item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); + item.ID = _daoFactory.GetTaskTemplateDao().SaveOrUpdate(item); return ToTaskTemplateDto(item); } @@ -282,10 +282,10 @@ bool deadLineIsFixed { if (containerid <= 0 || string.IsNullOrEmpty(title) || categoryid <= 0) throw new ArgumentException(); - var updatingItem = DaoFactory.GetTaskTemplateDao().GetByID(id); + var updatingItem = _daoFactory.GetTaskTemplateDao().GetByID(id); if (updatingItem == null) throw new ItemNotFoundException(); - var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid); + var container = _daoFactory.GetTaskTemplateContainerDao().GetByID(containerid); if (container == null) throw new ItemNotFoundException(); var item = new TaskTemplate @@ -301,7 +301,7 @@ bool deadLineIsFixed Offset = TimeSpan.FromTicks(offsetTicks) }; - item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item); + item.ID = _daoFactory.GetTaskTemplateDao().SaveOrUpdate(item); return ToTaskTemplateDto(item); } @@ -321,12 +321,12 @@ public TaskTemplateDto DeleteTaskTemplate(int id) { if (id <= 0) throw new ArgumentException(); - var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id); + var taskTemplate = _daoFactory.GetTaskTemplateDao().GetByID(id); if (taskTemplate == null) throw new ItemNotFoundException(); var result = ToTaskTemplateDto(taskTemplate); - DaoFactory.GetTaskTemplateDao().Delete(id); + _daoFactory.GetTaskTemplateDao().Delete(id); return result; } @@ -346,7 +346,7 @@ public TaskTemplateDto GetTaskTemplateByID(int id) { if (id <= 0) throw new ArgumentException(); - var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id); + var taskTemplate = _daoFactory.GetTaskTemplateDao().GetByID(id); if (taskTemplate == null) throw new ItemNotFoundException(); return ToTaskTemplateDto(taskTemplate); @@ -357,7 +357,7 @@ protected TaskTemplateDto ToTaskTemplateDto(TaskTemplate taskTemplate) // TODO: set task template category return new TaskTemplateDto { -// Category = GetTaskCategoryByID(taskTemplate.CategoryID), + // Category = GetTaskCategoryByID(taskTemplate.CategoryID), ContainerID = taskTemplate.ContainerID, DeadLineIsFixed = taskTemplate.DeadLineIsFixed, Description = taskTemplate.Description, @@ -373,7 +373,7 @@ protected IEnumerable ToTaskListTemplateContainerDto(I { var result = new List(); - var taskTemplateDictionary = DaoFactory.GetTaskTemplateDao().GetAll() + var taskTemplateDictionary = _daoFactory.GetTaskTemplateDao().GetAll() .GroupBy(item => item.ContainerID) .ToDictionary(x => x.Key, y => y.Select(ToTaskTemplateDto)); diff --git a/products/ASC.CRM/Server/Api/TasksController.cs b/products/ASC.CRM/Server/Api/TasksController.cs index 4a198ba31db..71fc09456c8 100644 --- a/products/ASC.CRM/Server/Api/TasksController.cs +++ b/products/ASC.CRM/Server/Api/TasksController.cs @@ -4,7 +4,6 @@ using ASC.Api.Core; using ASC.Api.CRM; -using ASC.Common; using ASC.Common.Web; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -20,11 +19,8 @@ namespace ASC.CRM.Api { - public class TasksController: BaseApiController + public class TasksController : BaseApiController { - private readonly IMapper _mapper; - private readonly TaskCategoryDtoHelper _taskCategoryDtoHelper; - private readonly ContactDtoHelper _contactDtoHelper; private readonly NotifyClient _notifyClient; private readonly ApiContext _apiContext; private readonly MessageService _messageService; @@ -36,20 +32,16 @@ public TasksController(CRMSecurity cRMSecurity, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - ContactDtoHelper contactBaseDtoHelper, - TaskCategoryDtoHelper taskCategoryDtoHelper, IMapper mapper) - : base(daoFactory, cRMSecurity) + : base(daoFactory, cRMSecurity, mapper) { _apiContext = apiContext; _messageTarget = messageTarget; _messageService = messageService; _notifyClient = notifyClient; - _contactDtoHelper = contactBaseDtoHelper; - _taskCategoryDtoHelper = taskCategoryDtoHelper; _mapper = mapper; } - + /// /// Returns the detailed information about the task with the ID specified in the request /// @@ -64,12 +56,12 @@ public TaskDto GetTaskByID(int taskid) { if (taskid <= 0) throw new ArgumentException(); - var task = DaoFactory.GetTaskDao().GetByID(taskid); + var task = _daoFactory.GetTaskDao().GetByID(taskid); if (task == null) throw new ItemNotFoundException(); - if (!CRMSecurity.CanAccessTo(task)) + if (!_crmSecurity.CanAccessTo(task)) { - throw CRMSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); } return _mapper.Map(task); @@ -136,7 +128,7 @@ public IEnumerable GetAllTasks( if (taskOrderBy != null) { result = ToTaskListDto( - DaoFactory.GetTaskDao() + _daoFactory.GetTaskDao() .GetTasks( searchText, responsibleid, @@ -156,7 +148,7 @@ public IEnumerable GetAllTasks( } else result = ToTaskListDto( - DaoFactory + _daoFactory .GetTaskDao() .GetTasks( searchText, @@ -179,7 +171,7 @@ public IEnumerable GetAllTasks( } else { - totalCount = DaoFactory + totalCount = _daoFactory .GetTaskDao() .GetTasksCount( searchText, @@ -212,9 +204,9 @@ public TaskDto ReOpenTask(int taskid) { if (taskid <= 0) throw new ArgumentException(); - DaoFactory.GetTaskDao().OpenTask(taskid); + _daoFactory.GetTaskDao().OpenTask(taskid); - var task = DaoFactory.GetTaskDao().GetByID(taskid); + var task = _daoFactory.GetTaskDao().GetByID(taskid); _messageService.Send(MessageAction.CrmTaskOpened, _messageTarget.Create(task.ID), task.Title); @@ -236,9 +228,9 @@ public TaskDto CloseTask(int taskid) { if (taskid <= 0) throw new ArgumentException(); - DaoFactory.GetTaskDao().CloseTask(taskid); + _daoFactory.GetTaskDao().CloseTask(taskid); - var task = DaoFactory.GetTaskDao().GetByID(taskid); + var task = _daoFactory.GetTaskDao().GetByID(taskid); _messageService.Send(MessageAction.CrmTaskClosed, _messageTarget.Create(task.ID), task.Title); return _mapper.Map(task); @@ -261,10 +253,10 @@ public TaskDto DeleteTask(int taskid) { if (taskid <= 0) throw new ArgumentException(); - var task = DaoFactory.GetTaskDao().GetByID(taskid); + var task = _daoFactory.GetTaskDao().GetByID(taskid); if (task == null) throw new ItemNotFoundException(); - DaoFactory.GetTaskDao().DeleteTask(taskid); + _daoFactory.GetTaskDao().DeleteTask(taskid); _messageService.Send(MessageAction.CrmTaskDeleted, _messageTarget.Create(task.ID), task.Title); return _mapper.Map(task); @@ -310,7 +302,7 @@ int alertValue || categoryId <= 0) throw new ArgumentException(); - var listItem = DaoFactory.GetListItemDao().GetByID(categoryId); + var listItem = _daoFactory.GetListItemDao().GetByID(categoryId); if (listItem == null) throw new ItemNotFoundException(CRMErrorsResource.TaskCategoryNotFound); var task = new Task @@ -327,7 +319,7 @@ int alertValue AlertValue = alertValue }; - task = DaoFactory.GetTaskDao().SaveOrUpdateTask(task); + task = _daoFactory.GetTaskDao().SaveOrUpdateTask(task); if (isNotify) { @@ -337,7 +329,7 @@ int alertValue if (task.ContactID > 0) { - taskContact = DaoFactory.GetContactDao().GetByID(task.ContactID); + taskContact = _daoFactory.GetContactDao().GetByID(task.ContactID); } if (task.EntityID > 0) @@ -345,10 +337,10 @@ int alertValue switch (task.EntityType) { case EntityType.Case: - taskCase = DaoFactory.GetCasesDao().GetByID(task.EntityID); + taskCase = _daoFactory.GetCasesDao().GetByID(task.EntityID); break; case EntityType.Opportunity: - taskDeal = DaoFactory.GetDealDao().GetByID(task.EntityID); + taskDeal = _daoFactory.GetDealDao().GetByID(task.EntityID); break; } } @@ -418,14 +410,14 @@ public IEnumerable CreateTaskGroup( }); } - tasks = DaoFactory.GetTaskDao().SaveOrUpdateTaskList(tasks).ToList(); + tasks = _daoFactory.GetTaskDao().SaveOrUpdateTaskList(tasks).ToList(); string taskCategory = null; if (isNotify) { if (categoryId > 0) { - var listItem = DaoFactory.GetListItemDao().GetByID(categoryId); + var listItem = _daoFactory.GetListItemDao().GetByID(categoryId); if (listItem == null) throw new ItemNotFoundException(); taskCategory = listItem.Title; @@ -442,7 +434,7 @@ public IEnumerable CreateTaskGroup( if (tasks[i].ContactID > 0) { - taskContact = DaoFactory.GetContactDao().GetByID(tasks[i].ContactID); + taskContact = _daoFactory.GetContactDao().GetByID(tasks[i].ContactID); } if (tasks[i].EntityID > 0) @@ -450,10 +442,10 @@ public IEnumerable CreateTaskGroup( switch (tasks[i].EntityType) { case EntityType.Case: - taskCase = DaoFactory.GetCasesDao().GetByID(tasks[i].EntityID); + taskCase = _daoFactory.GetCasesDao().GetByID(tasks[i].EntityID); break; case EntityType.Opportunity: - taskDeal = DaoFactory.GetDealDao().GetByID(tasks[i].EntityID); + taskDeal = _daoFactory.GetDealDao().GetByID(tasks[i].EntityID); break; } } @@ -463,7 +455,7 @@ public IEnumerable CreateTaskGroup( if (tasks.Any()) { - var contacts = DaoFactory.GetContactDao().GetContacts(contactId); + var contacts = _daoFactory.GetContactDao().GetContacts(contactId); var task = tasks.First(); _messageService.Send(MessageAction.ContactsCreatedCrmTasks, _messageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title); } @@ -509,7 +501,7 @@ public TaskDto UpdateTask( ) || categoryid <= 0) throw new ArgumentException(); - var listItem = DaoFactory.GetListItemDao().GetByID(categoryid); + var listItem = _daoFactory.GetListItemDao().GetByID(categoryid); if (listItem == null) throw new ItemNotFoundException(CRMErrorsResource.TaskCategoryNotFound); var task = new Task @@ -527,7 +519,7 @@ public TaskDto UpdateTask( }; - task = DaoFactory.GetTaskDao().SaveOrUpdateTask(task); + task = _daoFactory.GetTaskDao().SaveOrUpdateTask(task); if (isNotify) { @@ -537,7 +529,7 @@ public TaskDto UpdateTask( if (task.ContactID > 0) { - taskContact = DaoFactory.GetContactDao().GetByID(task.ContactID); + taskContact = _daoFactory.GetContactDao().GetByID(task.ContactID); } if (task.EntityID > 0) @@ -545,10 +537,10 @@ public TaskDto UpdateTask( switch (task.EntityType) { case EntityType.Case: - taskCase = DaoFactory.GetCasesDao().GetByID(task.EntityID); + taskCase = _daoFactory.GetCasesDao().GetByID(task.EntityID); break; case EntityType.Opportunity: - taskDeal = DaoFactory.GetDealDao().GetByID(task.EntityID); + taskDeal = _daoFactory.GetDealDao().GetByID(task.EntityID); break; } } @@ -565,10 +557,10 @@ public TaskDto UpdateTask( [Update(@"task/{taskid:int}/creationdate")] public void SetTaskCreationDate(int taskId, ApiDateTime creationDate) { - var dao = DaoFactory.GetTaskDao(); + var dao = _daoFactory.GetTaskDao(); var task = dao.GetByID(taskId); - if (task == null || !CRMSecurity.CanAccessTo(task)) + if (task == null || !_crmSecurity.CanAccessTo(task)) throw new ItemNotFoundException(); dao.SetTaskCreationDate(taskId, creationDate); @@ -578,10 +570,10 @@ public void SetTaskCreationDate(int taskId, ApiDateTime creationDate) [Update(@"task/{taskid:int}/lastmodifeddate")] public void SetTaskLastModifedDate(int taskId, ApiDateTime lastModifedDate) { - var dao = DaoFactory.GetTaskDao(); + var dao = _daoFactory.GetTaskDao(); var task = dao.GetByID(taskId); - if (task == null || !CRMSecurity.CanAccessTo(task)) + if (task == null || !_crmSecurity.CanAccessTo(task)) throw new ItemNotFoundException(); dao.SetTaskLastModifedDate(taskId, lastModifedDate); @@ -635,7 +627,7 @@ private IEnumerable ToTaskListDto(IEnumerable itemList) switch (entityType) { case EntityType.Opportunity: - DaoFactory.GetDealDao().GetDeals(entityDtosIDs[entityType].Distinct().ToArray()) + _daoFactory.GetDealDao().GetDeals(entityDtosIDs[entityType].Distinct().ToArray()) .ForEach(item => { if (item == null) return; @@ -651,7 +643,7 @@ private IEnumerable ToTaskListDto(IEnumerable itemList) }); break; case EntityType.Case: - DaoFactory.GetCasesDao().GetByID(entityDtosIDs[entityType].ToArray()) + _daoFactory.GetCasesDao().GetByID(entityDtosIDs[entityType].ToArray()) .ForEach(item => { if (item == null) return; @@ -669,15 +661,15 @@ private IEnumerable ToTaskListDto(IEnumerable itemList) } } - var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => _taskCategoryDtoHelper.Get(x)); - var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => _contactDtoHelper.GetContactBaseWithEmailDto(x)); - var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => _contactDtoHelper.GetContactBaseWithEmailDto(x)); + var categories = _daoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => _mapper.Map(x)); + var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => _mapper.Map(x)); + var restrictedContacts = _daoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, x => _mapper.Map(x)); foreach (var item in itemList) { - var taskDto = _mapper.Map(item); + var taskDto = _mapper.Map(item); - taskDto.CanEdit = CRMSecurity.CanEdit(item); + taskDto.CanEdit = _crmSecurity.CanEdit(item); if (contacts.ContainsKey(item.ContactID)) { diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index 906405ec42a..09350d1e370 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -24,7 +24,11 @@ */ -using ASC.Api.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; + using ASC.Api.CRM; using ASC.Common.Threading.Progress; using ASC.Core.Common.Settings; @@ -38,12 +42,8 @@ using ASC.Web.Api.Routing; using ASC.Web.Core.Utility; using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Services.NotifyService; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security; +using AutoMapper; namespace ASC.CRM.Api { @@ -54,18 +54,17 @@ public UtilsController(CRMSecurity cRMSecurity, MessageService messageService, SettingsManager settingsManager, CurrencyProvider currencyProvider, - CurrencyInfoDtoHelper currencyInfoDtoHelper, CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, InvoiceSetting invoiceSetting, ImportFromCSVManager importFromCSVManager, OrganisationLogoManager organisationLogoManager, Global global, ImportFromCSV importFromCSV, - ExportToCsv exportToCsv) - : base(daoFactory, cRMSecurity) + ExportToCsv exportToCsv, + IMapper mapper) + : base(daoFactory, cRMSecurity, mapper) { MessageService = messageService; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; CurrencyProvider = currencyProvider; SettingsManager = settingsManager; CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; @@ -86,9 +85,8 @@ public UtilsController(CRMSecurity cRMSecurity, public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } public SettingsManager SettingsManager { get; } public CurrencyProvider CurrencyProvider { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } public MessageService MessageService { get; } - + /// /// Returns the list of all currencies currently available on the portal /// @@ -100,7 +98,7 @@ public UtilsController(CRMSecurity cRMSecurity, [Read(@"settings/currency")] public IEnumerable GetAvaliableCurrency() { - return CurrencyProvider.GetAll().ConvertAll(item => CurrencyInfoDtoHelper.Get(item)); + return CurrencyProvider.GetAll().ConvertAll(item => _mapper.Map(item)); } /// @@ -141,10 +139,13 @@ public IEnumerable GetSummaryTable(String currency) } var cur = CurrencyProvider.Get(currency.ToUpper()); + if (cur == null) throw new ArgumentException(); var table = CurrencyProvider.MoneyConvert(cur); + table.ToList().ForEach(tableItem => result.Add(CurrencyRateInfoDtoHelper.Get(tableItem.Key, tableItem.Value))); + return result; } @@ -230,7 +231,7 @@ public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAut [Update(@"settings")] public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var tenantSettings = SettingsManager.Load(); @@ -253,7 +254,7 @@ public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey) [Update(@"settings/organisation/base")] public String UpdateOrganisationSettingsCompanyName(String companyName) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var tenantSettings = SettingsManager.Load(); @@ -285,7 +286,7 @@ public String UpdateOrganisationSettingsCompanyName(String companyName) [Update(@"settings/organisation/address")] public String UpdateOrganisationSettingsCompanyAddress(String street, String city, String state, String zip, String country) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var tenantSettings = SettingsManager.Load(); @@ -325,13 +326,13 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit [Update(@"settings/organisation/logo")] public Int32 UpdateOrganisationSettingsLogo(bool reset) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); int companyLogoID; if (!reset) { - companyLogoID = OrganisationLogoManager.TryUploadOrganisationLogoFromTmp(DaoFactory); + companyLogoID = OrganisationLogoManager.TryUploadOrganisationLogoFromTmp(_daoFactory); if (companyLogoID == 0) { throw new Exception("Downloaded image not found"); @@ -395,7 +396,7 @@ public String GetOrganisationSettingsLogo(int id) [Update(@"settings/webformkey/change")] public string ChangeWebToLeadFormKey() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var tenantSettings = SettingsManager.Load(); @@ -420,7 +421,7 @@ public string ChangeWebToLeadFormKey() [Update(@"settings/currency")] public CurrencyInfoDto UpdateCRMCurrency(String currency) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); if (string.IsNullOrEmpty(currency)) { @@ -433,7 +434,7 @@ public CurrencyInfoDto UpdateCRMCurrency(String currency) Global.SaveDefaultCurrencySettings(cur); MessageService.Send(MessageAction.CrmDefaultCurrencyUpdated); - return CurrencyInfoDtoHelper.Get(cur); + return _mapper.Map(cur); } /// false @@ -519,7 +520,7 @@ public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings [Read(@"export/status")] public IProgressItem GetExportStatus() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); return ExportToCsv.GetStatus(false); @@ -529,7 +530,7 @@ public IProgressItem GetExportStatus() [Update(@"export/cancel")] public IProgressItem CancelExport() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); ExportToCsv.Cancel(false); @@ -541,7 +542,7 @@ public IProgressItem CancelExport() [Create(@"export/start")] public IProgressItem StartExport() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); MessageService.Send(MessageAction.CrmAllDataExported); diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index 3a8390f82b4..a1e8120c3ff 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -51,6 +51,8 @@ using ASC.Web.CRM.Classes; using ASC.Web.Studio.Utility; +using AutoMapper; + using SecurityContext = ASC.Core.SecurityContext; namespace ASC.CRM.Api @@ -68,9 +70,9 @@ public VoIPController(CRMSecurity cRMSecurity, TenantUtil tenantUtil, VoipEngine voipEngine, ApiContext apiContext, - ContactDtoHelper contactDtoHelper, - SignalrServiceClient signalrServiceClient) - : base(daoFactory, cRMSecurity) + SignalrServiceClient signalrServiceClient, + IMapper mapper) + : base(daoFactory, cRMSecurity, mapper) { Global = global; ContactPhotoManager = contactPhotoManager; @@ -81,7 +83,6 @@ public VoIPController(CRMSecurity cRMSecurity, TenantUtil = tenantUtil; VoipEngine = voipEngine; ApiContext = apiContext; - ContactDtoHelper = contactDtoHelper; SignalrServiceClient = signalrServiceClient; } @@ -89,7 +90,6 @@ public VoIPController(CRMSecurity cRMSecurity, public ApiContext ApiContext { get; } public VoipEngine VoipEngine { get; } public TenantUtil TenantUtil { get; } - public ContactDtoHelper ContactDtoHelper { get; } public VoipCallDtoHelper VoipCallDtoHelper { get; } public SecurityContext SecurityContext { get; } public CommonLinkUtility CommonLinkUtility { get; } @@ -108,11 +108,11 @@ public VoIPController(CRMSecurity cRMSecurity, [Read(@"voip/numbers/available")] public IEnumerable GetAvailablePhoneNumbers(PhoneNumberType numberType, string isoCountryCode) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException(); - return DaoFactory.GetVoipDao().GetProvider().GetAvailablePhoneNumbers(numberType, isoCountryCode); + return _daoFactory.GetVoipDao().GetProvider().GetAvailablePhoneNumbers(numberType, isoCountryCode); } @@ -126,10 +126,10 @@ public IEnumerable GetAvailablePhoneNumbers(PhoneNumberType numberTyp [Read(@"voip/numbers/unlinked")] public IEnumerable GetUnlinkedPhoneNumbers() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var listPhones = DaoFactory.GetVoipDao().GetProvider().GetExistingPhoneNumbers(); - var buyedPhones = DaoFactory.GetVoipDao().GetNumbers(); + var listPhones = _daoFactory.GetVoipDao().GetProvider().GetExistingPhoneNumbers(); + var buyedPhones = _daoFactory.GetVoipDao().GetNumbers(); return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList(); } @@ -144,9 +144,9 @@ public IEnumerable GetUnlinkedPhoneNumbers() [Read(@"voip/numbers/existing")] public IEnumerable GetExistingPhoneNumbers() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - return DaoFactory.GetVoipDao().GetNumbers(); + return _daoFactory.GetVoipDao().GetNumbers(); } /// /// @@ -158,15 +158,15 @@ public IEnumerable GetExistingPhoneNumbers() [Create(@"voip/numbers")] public VoipPhone BuyNumber(string number) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var newPhone = DaoFactory.GetVoipDao().GetProvider().BuyNumber(number); + var newPhone = _daoFactory.GetVoipDao().GetProvider().BuyNumber(number); - DaoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone); + _daoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone); SetDefaultAudio(newPhone); - DaoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone); - return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); + _daoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone); + return _daoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); } /// @@ -179,16 +179,16 @@ public VoipPhone BuyNumber(string number) [Create(@"voip/numbers/link")] public VoipPhone LinkNumber(string id) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var newPhone = DaoFactory.GetVoipDao().GetProvider().GetPhone(id); + var newPhone = _daoFactory.GetVoipDao().GetProvider().GetPhone(id); - DaoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone); + _daoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone); SetDefaultAudio(newPhone); - DaoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone); + _daoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone); - return DaoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); + return _daoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone); } public void SetDefaultAudio(VoipPhone newPhone) @@ -225,12 +225,12 @@ public void SetDefaultAudio(VoipPhone newPhone) [Delete(@"voip/numbers/{numberId:regex(\w+)}")] public VoipPhone DeleteNumber(string numberId) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var phone = dao.GetNumber(numberId).NotFoundIfNull(); - DaoFactory.GetVoipDao().GetProvider().DisablePhone(phone); + _daoFactory.GetVoipDao().GetProvider().DisablePhone(phone); dao.DeleteNumber(numberId); new SignalRHelper(phone.Number, SignalrServiceClient).Reload(); @@ -248,7 +248,7 @@ public VoipPhone DeleteNumber(string numberId) [Read(@"voip/numbers/{numberId:regex(\w+)}")] public VoipPhone GetNumber(string numberId) { - return DaoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull(); + return _daoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull(); } /// @@ -260,7 +260,7 @@ public VoipPhone GetNumber(string numberId) [Read(@"voip/numbers/current")] public VoipPhone GetCurrentNumber() { - return DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); + return _daoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); } /// @@ -272,7 +272,7 @@ public VoipPhone GetCurrentNumber() [Read(@"voip/token")] public string GetToken() { - return DaoFactory.GetVoipDao().GetProvider().GetToken(GetCurrentNumber().Caller); + return _daoFactory.GetVoipDao().GetProvider().GetToken(GetCurrentNumber().Caller); } /// @@ -285,9 +285,9 @@ public string GetToken() [Update(@"voip/numbers/{numberId:regex(\w+)}/settings")] public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var number = dao.GetNumber(numberId).NotFoundIfNull(); number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias); @@ -334,9 +334,9 @@ public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, [Update(@"voip/numbers/settings")] public object UpdateSettings(Queue queue, bool pause) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var numbers = dao.GetNumbers(); if (queue != null) @@ -382,9 +382,9 @@ public object UpdateSettings(Queue queue, bool pause) [Read(@"voip/numbers/settings")] public object GetVoipSettings() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null); if (number != null) { @@ -406,7 +406,7 @@ public object GetVoipSettings() [Read(@"voip/uploads")] public IEnumerable GetUploadedFilesUri() { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var result = new List(); @@ -454,7 +454,7 @@ private VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, [Delete(@"voip/uploads")] public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); var store = Global.GetStore(); var path = Path.Combine(audioType.ToString().ToLower(), fileName); @@ -468,7 +468,7 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); store.Delete("voip", path); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var numbers = dao.GetNumbers(); var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); @@ -521,7 +521,7 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) [Read(@"voip/numbers/{numberId:regex(\w+)}/oper")] public IEnumerable GetOperators(string numberId) { - return DaoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id); + return _daoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id); } /// @@ -535,14 +535,14 @@ public IEnumerable GetOperators(string numberId) [Update(@"voip/numbers/{numberId:regex(\w+)}/oper")] public IEnumerable AddOperators(string numberId, IEnumerable operators) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - if (DaoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) + if (_daoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id))) { throw new ArgumentException("Duplicate", "operators"); } - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var phone = dao.GetNumber(numberId); var lastOper = phone.Settings.Operators.LastOrDefault(); var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100; @@ -564,9 +564,9 @@ public IEnumerable AddOperators(string numberId, IEnumerable operat [Delete(@"voip/numbers/{numberId:regex(\w+)}/oper")] public Guid DeleteOperator(string numberId, Guid oper) { - if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var phone = dao.GetNumber(numberId); var startOperId = 100; @@ -593,9 +593,9 @@ public Guid DeleteOperator(string numberId, Guid oper) [Update(@"voip/opers/{operatorId}")] public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber) { - if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); var oper = phone.Settings.Operators.Find(r => r.Id == operatorId); @@ -646,7 +646,7 @@ public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOut [Create(@"voip/call")] public VoipCallDto MakeCall(string to, string contactId) { - var number = DaoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); + var number = _daoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied); @@ -656,19 +656,19 @@ public VoipCallDto MakeCall(string to, string contactId) if (String.IsNullOrEmpty(contactId)) { - var ids = DaoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone, null, null); + var ids = _daoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone, null, null); - contact = DaoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => ContactDtoHelper.GetContactDto(x)).FirstOrDefault(); + contact = _daoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => _mapper.Map(x)).FirstOrDefault(); } else { - contact = ContactDtoHelper.GetContactDto(DaoFactory.GetContactDao().GetByID(Convert.ToInt32(contactId))); + contact = _mapper.Map(_daoFactory.GetContactDao().GetByID(Convert.ToInt32(contactId))); } if (contact == null) { - contact = ContactDtoHelper.GetContactDto(VoipEngine.CreateContact(contactPhone)); + contact = _mapper.Map(VoipEngine.CreateContact(contactPhone)); } contact = GetContactWithFotos(contact); @@ -688,7 +688,7 @@ public VoipCallDto MakeCall(string to, string contactId) [Create(@"voip/call/{callId:regex(\w+)}/answer")] public VoipCallDto AnswerCall(string callId) { - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); @@ -707,7 +707,7 @@ public VoipCallDto AnswerCall(string callId) [Create(@"voip/call/{callId:regex(\w+)}/reject")] public VoipCallDto RejectCall(string callId) { - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); @@ -725,19 +725,19 @@ public VoipCallDto RejectCall(string callId) [Create(@"voip/call/{callId:regex(\w+)}/redirect")] public VoipCallDto ReditectCall(string callId, string to) { - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); var number = dao.GetCurrentNumber().NotFoundIfNull(); if (call.ContactId != 0) { - var contact = DaoFactory.GetContactDao().GetByID(call.ContactId); - var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact); + var contact = _daoFactory.GetContactDao().GetByID(call.ContactId); + var managers = _crmSecurity.GetAccessSubjectGuidsTo(contact); if (!managers.Contains(Guid.Parse(to))) { managers.Add(Guid.Parse(to)); - CRMSecurity.SetAccessTo(contact, managers); + _crmSecurity.SetAccessTo(contact, managers); } } @@ -754,7 +754,7 @@ public VoipCallDto ReditectCall(string callId, string to) [Create(@"voip/call/{callId:regex(\w+)}")] public VoipCallDto SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) { - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callId) ?? new VoipCall(); @@ -788,13 +788,13 @@ public VoipCallDto SaveCall(string callId, string from, string to, Guid answered ShareType = ShareType.None }; - peopleInst.ID = DaoFactory.GetContactDao().SaveContact(peopleInst); + peopleInst.ID = _daoFactory.GetContactDao().SaveContact(peopleInst); + + _crmSecurity.SetAccessTo(peopleInst, new List { SecurityContext.CurrentAccount.ID }); - CRMSecurity.SetAccessTo(peopleInst, new List { SecurityContext.CurrentAccount.ID }); + var person = (PersonDto)_mapper.Map(peopleInst); - var person = (PersonDto)ContactDtoHelper.GetContactDto(peopleInst); - - DaoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); + _daoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone }); call.ContactId = person.Id; } @@ -821,7 +821,7 @@ public VoipCallDto SaveCall(string callId, string from, string to, Guid answered try { - var contact = ContactDtoHelper.GetContactDto(DaoFactory.GetContactDao().GetByID(call.ContactId)); + var contact = _mapper.Map(_daoFactory.GetContactDao().GetByID(call.ContactId)); contact = GetContactWithFotos(contact); return VoipCallDtoHelper.Get(call, contact); @@ -854,7 +854,7 @@ public void SavePrice(string callId) [Read(@"voip/call")] public IEnumerable GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID) { - var voipDao = DaoFactory.GetVoipDao(); + var voipDao = _daoFactory.GetVoipDao(); var filter = new VoipCallFilter { @@ -916,7 +916,7 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, ApiD [Read(@"voip/call/missed")] public IEnumerable GetMissedCalls() { - var voipDao = DaoFactory.GetVoipDao(); + var voipDao = _daoFactory.GetVoipDao(); var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( @@ -959,13 +959,13 @@ public IEnumerable GetMissedCalls() [Read(@"voip/call/{callId:regex(\w+)}")] public VoipCallDto GetCall(string callId) { - var call = DaoFactory.GetVoipDao().GetCall(callId); + var call = _daoFactory.GetVoipDao().GetCall(callId); VoipEngine.GetContact(call); if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); - var contact = ContactDtoHelper.GetContactDto(DaoFactory.GetContactDao().GetByID(call.ContactId)); + var contact = _mapper.Map(_daoFactory.GetContactDao().GetByID(call.ContactId)); contact = GetContactWithFotos(contact); diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateCasesRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateCasesRequestDto.cs index 86d54590080..0741f74ed79 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateCasesRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateCasesRequestDto.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using ASC.Api.Collections; diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateDealRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateDealRequestDto.cs index 04851776b45..09e58547f62 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateDealRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateDealRequestDto.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using ASC.Api.Collections; using ASC.Api.Core; diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs index b3b21e8ffd0..19af5d62a8c 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceItemRequestDto.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace ASC.CRM.ApiModels +namespace ASC.CRM.ApiModels { public class CreateOrUpdateInvoiceItemRequestDto { diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs index 1bb449b5b19..24f8db3a82d 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceLineRequestDto.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace ASC.CRM.ApiModels +namespace ASC.CRM.ApiModels { public class CreateOrUpdateInvoiceLineRequestDto { diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceRequestDto.cs index 6ae9ed5b0bc..11d84ecc231 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceRequestDto.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; using ASC.Api.Core; using ASC.CRM.Core.Entities; diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs index df87334dc49..9b340d10fa5 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdateInvoiceTaxRequestDto.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace ASC.CRM.ApiModels +namespace ASC.CRM.ApiModels { public class CreateOrUpdateInvoiceTaxRequestDto { diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdatePersonRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdatePersonRequestDto.cs index 4b1e6d2eae6..7565b89a567 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdatePersonRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/CreateOrUpdatePersonRequestDto.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Threading.Tasks; using ASC.Api.Collections; using ASC.CRM.Core.Enums; @@ -10,7 +7,7 @@ using Microsoft.AspNetCore.Http; namespace ASC.CRM.ApiModels -{ +{ public class CreateOrUpdateContactRequestDto { public string About { get; set; } @@ -21,7 +18,7 @@ public class CreateOrUpdateContactRequestDto } public class CreateOrUpdateCompanyRequestDto : CreateOrUpdateContactRequestDto - { + { public String CompanyName { get; set; } public IEnumerable PersonList { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/SaveNumberSettingsRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SaveNumberSettingsRequestDto.cs index c0c0aaed49e..03fb76eff19 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/SaveNumberSettingsRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SaveNumberSettingsRequestDto.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace ASC.CRM.ApiModels +namespace ASC.CRM.ApiModels { public class SaveNumberSettingsRequestDto { diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/SendMailSMTPToContactsRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SendMailSMTPToContactsRequestDto.cs index 95c09cda49a..b77a3a2f406 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/SendMailSMTPToContactsRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SendMailSMTPToContactsRequestDto.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace ASC.CRM.ApiModels { diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchCasesRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchCasesRequestDto.cs index 3327804876c..f24a87f62a4 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchCasesRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchCasesRequestDto.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace ASC.CRM.ApiModels { diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchContactRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchContactRequestDto.cs index 50ac917a9c7..0874b950b86 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchContactRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchContactRequestDto.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Threading.Tasks; using ASC.Api.Core; using ASC.CRM.Core.Enums; @@ -14,9 +11,9 @@ public class SetAccessToBatchContactByFilterRequestDto public IEnumerable Tags { get; set; } public int? ContactStage { get; set; } public int? ContactType { get; set; } - public ContactListViewType ContactListView { get; set; } + public ContactListViewType ContactListView { get; set; } public ApiDateTime FromDate { get; set; } - public ApiDateTime ToDate { get; set; } + public ApiDateTime ToDate { get; set; } public bool isPrivate { get; set; } public IEnumerable ManagerList { get; set; } } diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs index dbd7d78998e..6d60c671807 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/SetAccessToBatchDealByFilterRequestDto.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Threading.Tasks; using ASC.Api.Core; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs index eb21b729b35..5d534564085 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs @@ -24,6 +24,10 @@ */ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; @@ -31,10 +35,6 @@ using AutoMapper; -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; - namespace ASC.CRM.ApiModels { [DataContract(Name = "case", Namespace = "")] @@ -46,15 +46,15 @@ public CasesDto() [DataMember(Name = "id")] - public int Id { get; set; } - public IEnumerable Members { get; set; } - public EmployeeWraper CreateBy { get; set; } - public ApiDateTime Created { get; set; } - public String Title { get; set; } - public bool IsClosed { get; set; } - public bool IsPrivate { get; set; } - public IEnumerable AccessList { get; set; } - public bool CanEdit { get; set; } + public int Id { get; set; } + public IEnumerable Members { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public String Title { get; set; } + public bool IsClosed { get; set; } + public bool IsPrivate { get; set; } + public IEnumerable AccessList { get; set; } + public bool CanEdit { get; set; } public IEnumerable CustomFields { get; set; } public static CasesDto GetSample() { diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs index 2c5c3ef8b1b..b305a29889a 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -24,17 +24,18 @@ */ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + using ASC.Api.Core; -using ASC.CRM.Api; using ASC.Common; -using ASC.CRM.Classes; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; using ASC.Web.Api.Models; -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using Contact = ASC.CRM.Core.Entities.Contact; + +using AutoMapper; namespace ASC.CRM.ApiModels { @@ -44,23 +45,10 @@ namespace ASC.CRM.ApiModels [DataContract(Name = "person", Namespace = "")] public class PersonDto : ContactDto { - public PersonDto() - { - - } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public String FirstName { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public String LastName { get; set; } - - public ContactBaseDto Company { get; set; } - - public String Title { get; set; } - public new static PersonDto GetSample() { return new PersonDto @@ -82,11 +70,7 @@ public PersonDto() [Scope] public class PersonDtoHelper - { - public PersonDtoHelper() - { - } - + { public PersonDto Get(Person person) { return new PersonDto @@ -113,30 +97,10 @@ public PersonDto GetQuick(Person person) /// [DataContract(Name = "company", Namespace = "")] public class CompanyDto : ContactDto - { - public CompanyDto() - { - } - - //public CompanyDto(Company company) - // : base(company) - //{ - // CompanyName = company.CompanyName; - // // PersonsCount = Global.DaoFactory.ContactDao.GetMembersCount(company.ID); - //} - - - - - [DataMember(IsRequired = true, EmitDefaultValue = false)] + { public String CompanyName { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public IEnumerable Persons { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public int PersonsCount { get; set; } - public new static CompanyDto GetSample() { return new CompanyDto @@ -154,7 +118,7 @@ public CompanyDto() [DataContract(Name = "contact", Namespace = "")] [KnownType(typeof(PersonDto))] [KnownType(typeof(CompanyDto))] - public abstract class ContactDto : ContactBaseDto + public class ContactDto : ContactBaseDto, IMapFrom { public ContactDto() { @@ -182,8 +146,6 @@ public ContactDto() public IEnumerable CustomFields { get; set; } public IEnumerable Tags { get; set; } public int TaskCount { get; set; } - - public bool HaveLateTasks { get; set; } public new static ContactDto GetSample() { @@ -208,6 +170,18 @@ public ContactDto() HaveLateTasks = false }; } + + public void Mapping(Profile profile) { + + profile.CreateMap().ConvertUsing(); + profile.CreateMap, List>().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + + } } [DataContract(Name = "contactBase", Namespace = "")] @@ -275,15 +249,15 @@ public ContactBaseDto() [DataMember(Name = "id")] public int Id { get; set; } public String SmallFotoUrl { get; set; } - public String MediumFotoUrl { get; set; } - public String DisplayName { get; set; } + public String MediumFotoUrl { get; set; } + public String DisplayName { get; set; } public bool IsCompany { get; set; } - public IEnumerable AccessList { get; set; } - public bool IsPrivate { get; set; } - public bool IsShared { get; set; } - public ShareType ShareType { get; set; } - public CurrencyInfoDto Currency { get; set; } - public bool CanEdit { get; set; } + public IEnumerable AccessList { get; set; } + public bool IsPrivate { get; set; } + public bool IsShared { get; set; } + public ShareType ShareType { get; set; } + public CurrencyInfoDto Currency { get; set; } + public bool CanEdit { get; set; } public bool CanDelete { get; set; } public static ContactBaseDto GetSample() { diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs index eab908b59c2..f9806955c85 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs @@ -24,16 +24,17 @@ */ -using ASC.Api.Core; -using ASC.CRM.ApiModels; -using ASC.Common; +using System; +using System.Runtime.Serialization; + using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Enums; -using ASC.Web.Api.Models; +using ASC.CRM.Mapping; + +using AutoMapper; + using Newtonsoft.Json.Linq; -using System; -using System.Runtime.Serialization; namespace ASC.CRM.ApiModels { @@ -128,7 +129,7 @@ public static Address GetSample() /// Contact information /// [DataContract(Name = "commonDataItem", Namespace = "")] - public class ContactInfoDto + public class ContactInfoDto : IMapFrom { public ContactInfoDto() { @@ -163,5 +164,10 @@ public static ContactInfoDto GetSample() InfoType = ContactInfoType.Email }; } + + public void Mapping(Profile profile) + { + profile.CreateMap(); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs index a4f6bc85e77..7bfe844d966 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs @@ -27,7 +27,10 @@ using System; using System.Runtime.Serialization; -using ASC.Common; +using ASC.CRM.Core; +using ASC.CRM.Mapping; + +using AutoMapper; namespace ASC.CRM.ApiModels { @@ -35,18 +38,18 @@ namespace ASC.CRM.ApiModels /// Currency information /// [DataContract(Name = "currencyInfo", Namespace = "")] - public class CurrencyInfoDto + public class CurrencyInfoDto : IMapFrom { public CurrencyInfoDto() { - } - public String Title { get; set; } - public String Symbol { get; set; } - public String Abbreviation { get; set; } - public String CultureName { get; set; } - public bool IsConvertable { get; set; } + } + public String Title { get; set; } + public String Symbol { get; set; } + public String Abbreviation { get; set; } + public String CultureName { get; set; } + public bool IsConvertable { get; set; } public bool IsBasic { get; set; } public static CurrencyInfoDto GetSample() { @@ -60,13 +63,18 @@ public static CurrencyInfoDto GetSample() IsBasic = false }; } + + public void Mapping(Profile profile) + { + profile.CreateMap(); + } } - + /// /// Currency rate information /// [DataContract(Name = "currencyRateInfo", Namespace = "")] - public class CurrencyRateInfoDto : CurrencyInfoDto + public class CurrencyRateInfoDto : CurrencyInfoDto, IMapFrom { public CurrencyRateInfoDto() { @@ -78,7 +86,6 @@ public CurrencyRateInfoDto() // Rate = rate; //} - public decimal Rate { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs index b9ac941bf2c..2e50bf4435c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs @@ -27,7 +27,10 @@ using System; using System.Runtime.Serialization; -using ASC.Common; +using ASC.CRM.Core; +using ASC.CRM.Mapping; + +using AutoMapper; namespace ASC.CRM.ApiModels { @@ -35,7 +38,7 @@ namespace ASC.CRM.ApiModels /// Currency rate /// [DataContract(Name = "currencyRate", Namespace = "")] - public class CurrencyRateDto + public class CurrencyRateDto : IMapFrom { public CurrencyRateDto() { @@ -43,9 +46,9 @@ public CurrencyRateDto() [DataMember(Name = "id")] - public int Id { get; set; } - public String FromCurrency { get; set; } - public String ToCurrency { get; set; } + public int Id { get; set; } + public String FromCurrency { get; set; } + public String ToCurrency { get; set; } public decimal Rate { get; set; } public static CurrencyRateDto GetSample() { @@ -57,5 +60,11 @@ public static CurrencyRateDto GetSample() Rate = (decimal)1.1 }; } + + public void Mapping(Profile profile) + { + profile.CreateMap(); + } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index e8ba12b4244..914e6c91c2d 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -24,11 +24,12 @@ */ +using System; +using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using System; -using System.Runtime.Serialization; namespace ASC.CRM.ApiModels { @@ -43,21 +44,21 @@ public CustomFieldDto(int id) public CustomFieldDto(CustomField customField) : base(customField) { - } + } public int RelativeItemsCount { get; set; } public new static CustomFieldDto GetSample() { return new CustomFieldDto(0) - { - Position = 10, - EntityId = 14523423, - FieldType = CustomFieldType.Date, - FieldValue = ApiDateTime.GetSample().ToString(), - Label = "Birthdate", - Mask = "", - RelativeItemsCount = 0 - }; + { + Position = 10, + EntityId = 14523423, + FieldType = CustomFieldType.Date, + FieldValue = ApiDateTime.GetSample().ToString(), + Label = "Birthdate", + Mask = "", + RelativeItemsCount = 0 + }; } } @@ -65,7 +66,7 @@ public CustomFieldDto(CustomField customField) /// User custom fields /// [DataContract(Name = "customField", Namespace = "")] - public class CustomFieldBaseDto + public class CustomFieldBaseDto { public CustomFieldBaseDto(int id) { @@ -82,24 +83,24 @@ public CustomFieldBaseDto(CustomField customField) } [DataMember(Name = "id")] - public int Id { get; set; } - public int EntityId { get; set; } - public String Label { get; set; } - public String FieldValue { get; set; } - public CustomFieldType FieldType { get; set; } - public int Position { get; set; } + public int Id { get; set; } + public int EntityId { get; set; } + public String Label { get; set; } + public String FieldValue { get; set; } + public CustomFieldType FieldType { get; set; } + public int Position { get; set; } public String Mask { get; set; } public static CustomFieldBaseDto GetSample() { return new CustomFieldBaseDto(0) - { - Position = 10, - EntityId = 14523423, - FieldType = CustomFieldType.Date, - FieldValue = ApiDateTime.GetSample().ToString(), - Label = "Birthdate", - Mask = "" - }; + { + Position = 10, + EntityId = 14523423, + FieldType = CustomFieldType.Date, + FieldValue = ApiDateTime.GetSample().ToString(), + Label = "Birthdate", + Mask = "" + }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs index adbb0886f8f..68ddc523b3c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs @@ -23,14 +23,16 @@ * */ +using System.Collections.Generic; +using System.Runtime.Serialization; + using ASC.Api.Core; -using ASC.Common; -using ASC.CRM.Classes; +using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; using ASC.Web.Api.Models; -using System.Collections.Generic; -using System.Runtime.Serialization; +using AutoMapper; namespace ASC.CRM.ApiModels { @@ -38,29 +40,34 @@ namespace ASC.CRM.ApiModels /// Invoice /// [DataContract(Name = "invoiceBase", Namespace = "")] - public class InvoiceBaseDto + public class InvoiceBaseDto : IMapFrom { - public int Id { get; set; } - public InvoiceStatusDto Status { get; set; } - public string Number { get; set; } - public ApiDateTime IssueDate { get; set; } - public InvoiceTemplateType TemplateType { get; set; } - public ContactBaseWithEmailDto Contact { get; set; } - public ContactBaseWithEmailDto Consignee { get; set; } - public EntityDto Entity { get; set; } - public ApiDateTime DueDate { get; set; } - public string Language { get; set; } - public CurrencyInfoDto Currency { get; set; } - public decimal ExchangeRate { get; set; } - public string PurchaseOrderNumber { get; set; } - public string Terms { get; set; } - public string Description { get; set; } - public int FileID { get; set; } - public ApiDateTime CreateOn { get; set; } - public EmployeeWraper CreateBy { get; set; } - public decimal Cost { get; set; } - public bool CanEdit { get; set; } + public int Id { get; set; } + public InvoiceStatusDto Status { get; set; } + public string Number { get; set; } + public ApiDateTime IssueDate { get; set; } + public InvoiceTemplateType TemplateType { get; set; } + public ContactBaseWithEmailDto Contact { get; set; } + public ContactBaseWithEmailDto Consignee { get; set; } + public EntityDto Entity { get; set; } + public ApiDateTime DueDate { get; set; } + public string Language { get; set; } + public CurrencyInfoDto Currency { get; set; } + public decimal ExchangeRate { get; set; } + public string PurchaseOrderNumber { get; set; } + public string Terms { get; set; } + public string Description { get; set; } + public int FileID { get; set; } + public ApiDateTime CreateOn { get; set; } + public EmployeeWraper CreateBy { get; set; } + public decimal Cost { get; set; } + public bool CanEdit { get; set; } public bool CanDelete { get; set; } + + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } } /// @@ -68,7 +75,7 @@ public class InvoiceBaseDto /// [DataContract(Name = "invoice", Namespace = "")] public class InvoiceDto : InvoiceBaseDto - { + { public List InvoiceLines { get; set; } public static InvoiceDto GetSample() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs deleted file mode 100644 index 36e08ec0d16..00000000000 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDtoHelper.cs +++ /dev/null @@ -1,130 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - -using ASC.Api.Core; -using ASC.Common; -using ASC.Core.Common.Settings; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.Web.Api.Models; -using ASC.Web.CRM.Classes; - -using System; -using System.Linq; - -namespace ASC.CRM.ApiModels -{ - [Scope] - public class InvoiceDtoHelper - { - public InvoiceDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - SettingsManager settingsManager, - CurrencyProvider currencyProvider, - InvoiceStatusDtoHelper invoiceStatusDtoHelper, - InvoiceLineDtoHelper invoiceLineDtoHelper, - DaoFactory daoFactory, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, - ContactDtoHelper contactDtoHelper, - EntityDtoHelper entityDtoHelper) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - SettingsManager = settingsManager; - CurrencyProvider = currencyProvider; - InvoiceStatusDtoHelper = invoiceStatusDtoHelper; - DaoFactory = daoFactory; - InvoiceLineDtoHelper = invoiceLineDtoHelper; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; - ContactDtoHelper = contactDtoHelper; - EntityDtoHelper = entityDtoHelper; - } - - public ContactDtoHelper ContactDtoHelper { get; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper { get; } - public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } - public DaoFactory DaoFactory { get; } - public InvoiceLineDtoHelper InvoiceLineDtoHelper { get; } - public InvoiceStatusDtoHelper InvoiceStatusDtoHelper { get; } - public CurrencyProvider CurrencyProvider { get; } - public SettingsManager SettingsManager { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public CRMSecurity CRMSecurity { get; } - public EntityDtoHelper EntityDtoHelper { get; } - public InvoiceDto Get(Invoice invoice) - { - var result = new InvoiceDto - { - Id = invoice.ID, - Status = InvoiceStatusDtoHelper.Get(invoice.Status), - Number = invoice.Number, - IssueDate = ApiDateTimeHelper.Get(invoice.IssueDate), - TemplateType = invoice.TemplateType, - DueDate = ApiDateTimeHelper.Get(invoice.DueDate), - Currency = !String.IsNullOrEmpty(invoice.Currency) ? - CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(invoice.Currency)) : - CurrencyInfoDtoHelper.Get(SettingsManager.Load().DefaultCurrency), - ExchangeRate = invoice.ExchangeRate, - Language = invoice.Language, - PurchaseOrderNumber = invoice.PurchaseOrderNumber, - Terms = invoice.Terms, - Description = invoice.Description, - FileID = invoice.FileID, - CreateOn = ApiDateTimeHelper.Get(invoice.CreateOn), - CreateBy = EmployeeWraperHelper.Get(invoice.CreateBy), - CanEdit = CRMSecurity.CanEdit(invoice), - CanDelete = CRMSecurity.CanDelete(invoice), - }; - - if (invoice.ContactID > 0) - { - result.Contact = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ContactID)); - } - - if (invoice.ConsigneeID > 0) - { - result.Consignee = ContactDtoHelper.GetContactBaseWithEmailDto(DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); - } - - if (invoice.EntityID > 0) - { - result.Entity = EntityDtoHelper.Get(invoice.EntityType, invoice.EntityID); - } - - result.Cost = invoice.GetInvoiceCost(DaoFactory); - - result.InvoiceLines = invoice.GetInvoiceLines(DaoFactory).Select(x => InvoiceLineDtoHelper.Get(x)).ToList(); - - return result; - - } - } -} diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs index 562c0536470..997d96ff0d2 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs @@ -23,6 +23,8 @@ * */ +using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; @@ -30,8 +32,6 @@ using AutoMapper; -using System.Runtime.Serialization; - namespace ASC.CRM.ApiModels { /// @@ -39,19 +39,19 @@ namespace ASC.CRM.ApiModels /// [DataContract(Name = "invoiceItem", Namespace = "")] public class InvoiceItemDto : IMapFrom - { - public string Title { get; set; } - public string StockKeepingUnit { get; set; } - public string Description { get; set; } - public decimal Price { get; set; } - public CurrencyInfoDto Currency { get; set; } - public decimal StockQuantity { get; set; } - public bool TrackInvenory { get; set; } - public InvoiceTaxDto InvoiceTax1 { get; set; } - public InvoiceTaxDto InvoiceTax2 { get; set; } - public ApiDateTime CreateOn { get; set; } - public EmployeeWraper CreateBy { get; set; } - public bool CanEdit { get; set; } + { + public string Title { get; set; } + public string StockKeepingUnit { get; set; } + public string Description { get; set; } + public decimal Price { get; set; } + public CurrencyInfoDto Currency { get; set; } + public decimal StockQuantity { get; set; } + public bool TrackInvenory { get; set; } + public InvoiceTaxDto InvoiceTax1 { get; set; } + public InvoiceTaxDto InvoiceTax2 { get; set; } + public ApiDateTime CreateOn { get; set; } + public EmployeeWraper CreateBy { get; set; } + public bool CanEdit { get; set; } public bool CanDelete { get; set; } public void Mapping(Profile profile) diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs index 722832987f6..bfefa0a354c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs @@ -25,23 +25,26 @@ using System.Runtime.Serialization; +using ASC.CRM.Core.Entities; +using ASC.CRM.Mapping; + namespace ASC.CRM.ApiModels { /// /// Invoice Line /// [DataContract(Name = "invoiceLine", Namespace = "")] - public class InvoiceLineDto + public class InvoiceLineDto : IMapFrom { - public int Id { get; set; } - public int InvoiceID { get; set; } - public int InvoiceItemID { get; set; } - public int InvoiceTax1ID { get; set; } - public int InvoiceTax2ID { get; set; } - public int SortOrder { get; set; } - public string Description { get; set; } - public decimal Quantity { get; set; } - public decimal Price { get; set; } + public int Id { get; set; } + public int InvoiceID { get; set; } + public int InvoiceItemID { get; set; } + public int InvoiceTax1ID { get; set; } + public int InvoiceTax2ID { get; set; } + public int SortOrder { get; set; } + public string Description { get; set; } + public decimal Quantity { get; set; } + public decimal Price { get; set; } public decimal Discount { get; set; } public static InvoiceLineDto GetSample() { diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs index d09e770fcd3..cd4f33ccc26 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs @@ -23,10 +23,13 @@ * */ +using System.Runtime.Serialization; + using ASC.CRM.Classes; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; -using System.Runtime.Serialization; +using AutoMapper; namespace ASC.CRM.ApiModels { @@ -34,9 +37,9 @@ namespace ASC.CRM.ApiModels /// Invoice Status /// [DataContract(Name = "invoiceStatus", Namespace = "")] - public class InvoiceStatusDto + public class InvoiceStatusDto : IMapFrom { - public int Id { get; set; } + public int Id { get; set; } public string Title { get; set; } public static InvoiceStatusDto GetSample() { @@ -47,5 +50,11 @@ public static InvoiceStatusDto GetSample() }; } + public void Mapping(Profile profile) + { + profile.CreateMap() + .ForMember(x => x.Title, x => x.MapFrom(y => y.ToLocalizedString())); + + } } } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs index 5eea296d1ba..eaf72299c1c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs @@ -23,6 +23,8 @@ * */ +using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; @@ -30,8 +32,6 @@ using AutoMapper; -using System.Runtime.Serialization; - namespace ASC.CRM.ApiModels { //public static class InvoiceItemDtoHelperExtension @@ -51,15 +51,15 @@ namespace ASC.CRM.ApiModels /// Invoice Tax /// [DataContract(Name = "invoiceTax", Namespace = "")] - public class InvoiceTaxDto: IMapFrom + public class InvoiceTaxDto : IMapFrom { - public int Id { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public decimal Rate { get; set; } - public ApiDateTime CreateOn { get; set; } - public EmployeeWraper CreateBy { get; set; } - public bool CanEdit { get; set; } + public int Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public decimal Rate { get; set; } + public ApiDateTime CreateOn { get; set; } + public EmployeeWraper CreateBy { get; set; } + public bool CanEdit { get; set; } public bool CanDelete { get; set; } public void Mapping(Profile profile) diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index 119544fe7b3..ef5ff6dfd4d 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -24,11 +24,14 @@ */ +using System; +using System.Runtime.Serialization; + using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; -using System; -using System.Runtime.Serialization; +using AutoMapper; namespace ASC.CRM.ApiModels { @@ -51,19 +54,19 @@ public HistoryCategoryBaseDto(ListItem listItem) [DataMember(Name = "id")] public int Id { get; set; } - + public String ImagePath { get; set; } public static HistoryCategoryBaseDto GetSample() { return new HistoryCategoryBaseDto - { - Title = "Lunch", - SortOrder = 10, - Color = String.Empty, - Description = "", - ImagePath = "path to image" - }; + { + Title = "Lunch", + SortOrder = 10, + Color = String.Empty, + Description = "", + ImagePath = "path to image" + }; } } @@ -79,20 +82,20 @@ public HistoryCategoryDto(ListItem listItem) { } - + public int RelativeItemsCount { get; set; } public new static HistoryCategoryDto GetSample() { return new HistoryCategoryDto - { - Title = "Lunch", - SortOrder = 10, - Color = String.Empty, - Description = "", - ImagePath = "path to image", - RelativeItemsCount = 1 - }; + { + Title = "Lunch", + SortOrder = 10, + Color = String.Empty, + Description = "", + ImagePath = "path to image", + RelativeItemsCount = 1 + }; } } @@ -116,23 +119,23 @@ public DealMilestoneBaseDto(DealMilestone dealMilestone) Title = dealMilestone.Title; } - + public int SuccessProbability { get; set; } - + public DealMilestoneStatus StageType { get; set; } public static DealMilestoneBaseDto GetSample() { return new DealMilestoneBaseDto - { - Title = "Discussion", - SortOrder = 2, - Color = "#B9AFD3", - Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal", - StageType = DealMilestoneStatus.Open, - SuccessProbability = 20 - }; + { + Title = "Discussion", + SortOrder = 2, + Color = "#B9AFD3", + Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal", + StageType = DealMilestoneStatus.Open, + SuccessProbability = 20 + }; } } @@ -148,21 +151,21 @@ public DealMilestoneDto(DealMilestone dealMilestone) { } - + public int RelativeItemsCount { get; set; } public new static DealMilestoneDto GetSample() { return new DealMilestoneDto - { - Title = "Discussion", - SortOrder = 2, - Color = "#B9AFD3", - Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal", - StageType = DealMilestoneStatus.Open, - SuccessProbability = 20, - RelativeItemsCount = 1 - }; + { + Title = "Discussion", + SortOrder = 2, + Color = "#B9AFD3", + Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal", + StageType = DealMilestoneStatus.Open, + SuccessProbability = 20, + RelativeItemsCount = 1 + }; } } @@ -171,7 +174,7 @@ public DealMilestoneDto(DealMilestone dealMilestone) #region Task Category [DataContract(Name = "taskCategoryBase", Namespace = "")] - public class TaskCategoryBaseDto : ListItemDto + public class TaskCategoryBaseDto : ListItemDto, IMapFrom { public TaskCategoryBaseDto() { @@ -182,19 +185,26 @@ public TaskCategoryBaseDto(ListItem listItem) : base(listItem) } - + public String ImagePath { get; set; } public static TaskCategoryBaseDto GetSample() { return new TaskCategoryBaseDto - { - Title = "Appointment", - SortOrder = 2, - Description = "", - ImagePath = "path to image" - }; + { + Title = "Appointment", + SortOrder = 2, + Description = "", + ImagePath = "path to image" + }; } + + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } + + } [DataContract(Name = "taskCategory", Namespace = "")] @@ -204,25 +214,25 @@ public TaskCategoryDto() { } - public TaskCategoryDto(ListItem listItem): base(listItem) + public TaskCategoryDto(ListItem listItem) : base(listItem) { } - + public int RelativeItemsCount { get; set; } public new static TaskCategoryDto GetSample() { return new TaskCategoryDto - { - Id = 30, - Title = "Appointment", - SortOrder = 2, - Description = "", - ImagePath = "path to image", - RelativeItemsCount = 1 - }; + { + Id = 30, + Title = "Appointment", + SortOrder = 2, + Description = "", + ImagePath = "path to image", + RelativeItemsCount = 1 + }; } } @@ -239,7 +249,7 @@ public TaskCategoryDto(ListItem listItem): base(listItem) [DataContract(Name = "contactStatusBase", Namespace = "")] public class ContactStatusBaseDto : ListItemDto { - public ContactStatusBaseDto() + public ContactStatusBaseDto() { } @@ -251,11 +261,11 @@ public ContactStatusBaseDto(ListItem listItem) public static ContactStatusBaseDto GetSample() { return new ContactStatusBaseDto - { - Title = "Cold", - SortOrder = 2, - Description = "" - }; + { + Title = "Cold", + SortOrder = 2, + Description = "" + }; } } @@ -271,18 +281,18 @@ public ContactStatusDto(ListItem listItem) { } - + public int RelativeItemsCount { get; set; } public new static ContactStatusDto GetSample() { return new ContactStatusDto - { - Title = "Cold", - SortOrder = 2, - Description = "", - RelativeItemsCount = 1 - }; + { + Title = "Cold", + SortOrder = 2, + Description = "", + RelativeItemsCount = 1 + }; } } @@ -306,12 +316,12 @@ public ContactTypeBaseDto(ListItem listItem) public static ContactTypeBaseDto GetSample() { return new ContactTypeBaseDto - { - Id = 30, - Title = "Client", - SortOrder = 2, - Description = "" - }; + { + Id = 30, + Title = "Client", + SortOrder = 2, + Description = "" + }; } } @@ -327,19 +337,19 @@ public ContactTypeDto(ListItem listItem) { } - + public int RelativeItemsCount { get; set; } public new static ContactTypeDto GetSample() { return new ContactTypeDto - { - Id= 30, - Title = "Client", - SortOrder = 2, - Description = "", - RelativeItemsCount = 1 - }; + { + Id = 30, + Title = "Client", + SortOrder = 2, + Description = "", + RelativeItemsCount = 1 + }; } } @@ -365,23 +375,23 @@ public TagDto(String tag, int relativeItemsCount = 0) [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } - + public int RelativeItemsCount { get; set; } public static TagDto GetSample() { return new TagDto - { - Title = "Tag", - RelativeItemsCount = 1 - }; + { + Title = "Tag", + RelativeItemsCount = 1 + }; } } #endregion [DataContract(Name = "listItem", Namespace = "")] - public abstract class ListItemDto + public class ListItemDto { protected ListItemDto() { @@ -397,10 +407,10 @@ protected ListItemDto(ListItem listItem) } [DataMember(Name = "id")] - public int Id { get; set; } - public String Title { get; set; } - public String Description { get; set; } - public String Color { get; set; } + public int Id { get; set; } + public String Title { get; set; } + public String Description { get; set; } + public String Color { get; set; } public int SortOrder { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs index 7005491841a..875aefa9469 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs @@ -24,14 +24,14 @@ */ -using ASC.Api.Core; -using ASC.CRM.Core.Enums; -using ASC.Web.Api.Models; - using System; using System.Collections.Generic; using System.Runtime.Serialization; +using ASC.Api.Core; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; + namespace ASC.CRM.ApiModels { /// @@ -40,37 +40,37 @@ namespace ASC.CRM.ApiModels [DataContract(Name = "opportunity", Namespace = "")] public class OpportunityDto { - + public OpportunityDto() { } [DataMember(Name = "id")] - public int Id { get; set; } - public EmployeeWraper CreateBy { get; set; } - public ApiDateTime Created { get; set; } - public IEnumerable Members { get; set; } + public int Id { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public IEnumerable Members { get; set; } public ContactBaseDto Contact { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] - public String Title { get; set; } - public String Description { get; set; } - public EmployeeWraper Responsible { get; set; } - public BidType BidType { get; set; } - public decimal BidValue { get; set; } - public CurrencyInfoDto BidCurrency { get; set; } - public int PerPeriodValue { get; set; } - public DealMilestoneBaseDto Stage { get; set; } - public int SuccessProbability { get; set; } - public ApiDateTime ActualCloseDate { get; set; } + public String Title { get; set; } + public String Description { get; set; } + public EmployeeWraper Responsible { get; set; } + public BidType BidType { get; set; } + public decimal BidValue { get; set; } + public CurrencyInfoDto BidCurrency { get; set; } + public int PerPeriodValue { get; set; } + public DealMilestoneBaseDto Stage { get; set; } + public int SuccessProbability { get; set; } + public ApiDateTime ActualCloseDate { get; set; } public ApiDateTime ExpectedCloseDate { get; set; } - - public bool IsPrivate { get; set; } + + public bool IsPrivate { get; set; } public IEnumerable AccessList { get; set; } - - public bool CanEdit { get; set; } + + public bool CanEdit { get; set; } public IEnumerable CustomFields { get; set; } public static OpportunityDto GetSample() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs index 51f02183615..c8b6ae99a0a 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs @@ -24,25 +24,28 @@ */ +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Api.Documents; using ASC.Common; -using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; using ASC.Web.Api.Models; -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; + +using AutoMapper; namespace ASC.CRM.ApiModels { [DataContract(Name = "entity", Namespace = "")] public class EntityDto - { - public String EntityType { get; set; } - public int EntityId { get; set; } + { + public String EntityType { get; set; } + public int EntityId { get; set; } public String EntityTitle { get; set; } public static EntityDto GetSample() { @@ -64,7 +67,7 @@ public EntityDtoHelper(DaoFactory daoFactory) } public DaoFactory DaoFactory { get; } - + public EntityDto Get(EntityType entityType, int entityID) { if (entityID == 0) return null; @@ -103,17 +106,17 @@ public EntityDto Get(EntityType entityType, int entityID) } [DataContract(Name = "historyEvent", Namespace = "")] - public class RelationshipEventDto + public class RelationshipEventDto : IMapFrom { public RelationshipEventDto() { } - + [DataMember(Name = "id")] public int Id { get; set; } - + public EmployeeWraper CreateBy { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] @@ -124,17 +127,9 @@ public RelationshipEventDto() [DataMember(IsRequired = true, EmitDefaultValue = false)] public HistoryCategoryBaseDto Category { get; set; } - - public ContactBaseDto Contact { get; set; } - - public EntityDto Entity { get; set; } - - public bool CanEdit { get; set; } - - public IEnumerable> Files { get; set; } public static RelationshipEventDto GetSample() @@ -151,80 +146,12 @@ public static RelationshipEventDto GetSample() Content = @"Agreed to meet at lunch and discuss the client commercial offer" }; } - } - [Scope] - public class RelationshipEventDtoHelper - { - public RelationshipEventDtoHelper( - ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - ContactDtoHelper contactBaseDtoHelper, - FileWrapperHelper fileWrapperHelper, - CRMSecurity cRMSecurity, - DaoFactory daoFactory, - EntityDtoHelper entityDtoHelper, - HistoryCategoryDtoHelper historyCategoryDtoHelper) + public void Mapping(Profile profile) { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - DaoFactory = daoFactory; - ContactBaseDtoHelper = contactBaseDtoHelper; - FileWrapperHelper = fileWrapperHelper; - EntityDtoHelper = entityDtoHelper; - HistoryCategoryDtoHelper = historyCategoryDtoHelper; + profile.CreateMap() + .ConvertUsing(); } - - public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } - public FileWrapperHelper FileWrapperHelper { get; } - public ContactDtoHelper ContactBaseDtoHelper { get; } - public DaoFactory DaoFactory { get; } - public CRMSecurity CRMSecurity { get; } - public ApiDateTimeHelper ApiDateTimeHelper { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } - public EntityDtoHelper EntityDtoHelper { get; } - public RelationshipEventDto Get(RelationshipEvent relationshipEvent) - { - var result = new RelationshipEventDto - { - Id = relationshipEvent.ID, - CreateBy = EmployeeWraperHelper.Get(relationshipEvent.CreateBy), - Created = ApiDateTimeHelper.Get(relationshipEvent.CreateOn), - Content = relationshipEvent.Content, - Files = new List>(), - CanEdit = CRMSecurity.CanEdit(relationshipEvent) - }; - - - var historyCategory = DaoFactory.GetListItemDao().GetByID(relationshipEvent.CategoryID); - - if (historyCategory != null) - { - result.Category = HistoryCategoryDtoHelper.Get(historyCategory); - } - - if (relationshipEvent.EntityID > 0) - { - result.Entity = EntityDtoHelper.Get(relationshipEvent.EntityType, relationshipEvent.EntityID); - } - - result.Files = DaoFactory.GetRelationshipEventDao().GetFiles(relationshipEvent.ID).ConvertAll(file => FileWrapperHelper.Get(file)); - - if (relationshipEvent.ContactID > 0) - { - var relativeContact = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); - if (relativeContact != null) - { - result.Contact = ContactBaseDtoHelper.GetContactBaseDto(relativeContact); - } - } - - result.CanEdit = CRMSecurity.CanAccessTo(relationshipEvent); - - return result; - - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs index a6ed356f0e5..4ff6bb84378 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs @@ -32,10 +32,10 @@ namespace ASC.CRM.ApiModels { [DataContract] public class ReportDto - { - public String ReportTitle { get; set; } - public String ReportDescription { get; set; } - public IEnumerable Lables { get; set; } + { + public String ReportTitle { get; set; } + public String ReportDescription { get; set; } + public IEnumerable Lables { get; set; } public Object Data { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs index b3ffe0cc949..8cfb0401a1b 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs @@ -24,20 +24,16 @@ */ +using System; +using System.Runtime.Serialization; + using ASC.Api.Core; -using ASC.Common; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; using ASC.Web.Api.Models; using AutoMapper; -using System; -using System.Runtime.Serialization; - namespace ASC.CRM.ApiModels { /// @@ -46,18 +42,18 @@ namespace ASC.CRM.ApiModels [DataContract(Name = "task", Namespace = "")] public class TaskDto : IMapFrom { - public int Id { get; set; } - public EmployeeWraper CreateBy { get; set; } - public ApiDateTime Created { get; set; } - public ContactBaseWithEmailDto Contact { get; set; } - public string Title { get; set; } - public string Description { get; set; } - public ApiDateTime DeadLine { get; set; } - public int AlertValue { get; set; } - public EmployeeWraper Responsible { get; set; } - public bool IsClosed { get; set; } - public TaskCategoryBaseDto Category { get; set; } - public EntityDto Entity { get; set; } + public int Id { get; set; } + public EmployeeWraper CreateBy { get; set; } + public ApiDateTime Created { get; set; } + public ContactBaseWithEmailDto Contact { get; set; } + public string Title { get; set; } + public string Description { get; set; } + public ApiDateTime DeadLine { get; set; } + public int AlertValue { get; set; } + public EmployeeWraper Responsible { get; set; } + public bool IsClosed { get; set; } + public TaskCategoryBaseDto Category { get; set; } + public EntityDto Entity { get; set; } public bool CanEdit { get; set; } public static TaskDto GetSample() { @@ -84,14 +80,14 @@ public void Mapping(Profile profile) public class TaskBaseDto { public int Id { get; set; } - public String Title { get; set; } - public String Description { get; set; } - public ApiDateTime DeadLine { get; set; } - public int AlertValue { get; set; } - public EmployeeWraper Responsible { get; set; } - public bool IsClosed { get; set; } - public TaskCategoryBaseDto Category { get; set; } - public EntityDto Entity { get; set; } + public String Title { get; set; } + public String Description { get; set; } + public ApiDateTime DeadLine { get; set; } + public int AlertValue { get; set; } + public EmployeeWraper Responsible { get; set; } + public bool IsClosed { get; set; } + public TaskCategoryBaseDto Category { get; set; } + public EntityDto Entity { get; set; } public bool CanEdit { get; set; } public static TaskBaseDto GetSample() { diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs index 4d36f711b47..4d947c9defc 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs @@ -24,11 +24,12 @@ */ -using ASC.Web.Api.Models; using System; using System.Collections.Generic; using System.Runtime.Serialization; +using ASC.Web.Api.Models; + namespace ASC.CRM.ApiModels { [DataContract(Namespace = "taskTemplateContainer")] @@ -48,27 +49,27 @@ public TaskTemplateContainerDto() [DataMember(IsRequired = true, EmitDefaultValue = true)] public String EntityType { get; set; } - + public IEnumerable Items { get; set; } public static TaskTemplateContainerDto GetSample() { return new TaskTemplateContainerDto - { - EntityType = "contact", - Title = "Birthday greetings", - Items = new List + { + EntityType = "contact", + Title = "Birthday greetings", + Items = new List { TaskTemplateDto.GetSample() } - }; + }; } } [DataContract(Namespace = "taskTemplate")] - public class TaskTemplateDto + public class TaskTemplateDto { - public TaskTemplateDto() + public TaskTemplateDto() { } @@ -82,7 +83,7 @@ public TaskTemplateDto() [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } - + public String Description { get; set; } [DataMember(IsRequired = true, EmitDefaultValue = false)] @@ -91,28 +92,28 @@ public TaskTemplateDto() [DataMember(IsRequired = true, EmitDefaultValue = false)] public TaskCategoryDto Category { get; set; } - + public bool isNotify { get; set; } - + public long OffsetTicks { get; set; } - + public bool DeadLineIsFixed { get; set; } public static TaskTemplateDto GetSample() { return new TaskTemplateDto - { - Title = "Send an Email", - Category = TaskCategoryDto.GetSample(), - isNotify = true, - Responsible = EmployeeWraper.GetSample(), - ContainerID = 12, - DeadLineIsFixed = false, - OffsetTicks = TimeSpan.FromDays(10).Ticks, - Description = "" - }; + { + Title = "Send an Email", + Category = TaskCategoryDto.GetSample(), + isNotify = true, + Responsible = EmployeeWraper.GetSample(), + ContainerID = 12, + DeadLineIsFixed = false, + OffsetTicks = TimeSpan.FromDays(10).Ticks, + Description = "" + }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs index 38a0f483e2e..287acd47059 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs @@ -24,14 +24,13 @@ */ +using System.Collections.Generic; +using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.VoipService; using ASC.Web.Api.Models; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; - namespace ASC.CRM.ApiModels { [DataContract(Name = "voipCall", Namespace = "")] diff --git a/products/ASC.CRM/Server/ApiModels/Subject.cs b/products/ASC.CRM/Server/ApiModels/Subject.cs index 2a99be247ca..ac1740654d8 100644 --- a/products/ASC.CRM/Server/ApiModels/Subject.cs +++ b/products/ASC.CRM/Server/ApiModels/Subject.cs @@ -34,4 +34,4 @@ public enum SubjectEnum Case, Opportunity } - } \ No newline at end of file +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/CRMCalendar.cs b/products/ASC.CRM/Server/Classes/CRMCalendar.cs index 85c0285324a..46bb16b53f4 100644 --- a/products/ASC.CRM/Server/Classes/CRMCalendar.cs +++ b/products/ASC.CRM/Server/Classes/CRMCalendar.cs @@ -24,6 +24,10 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; + using ASC.Common; using ASC.Common.Utils; using ASC.Core; @@ -34,10 +38,6 @@ using ASC.Web.Core; using ASC.Web.Core.Calendars; -using System; -using System.Collections.Generic; -using System.Globalization; - namespace ASC.CRM.Api { [Scope] diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index f4473d06fd4..6a71262d657 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -24,15 +24,16 @@ */ +using System; +using System.Runtime.Serialization; + +using ASC.Common; using ASC.Core; using ASC.Core.Common.Settings; using ASC.CRM.Core; -using Microsoft.Extensions.Configuration; -using System; -using System.Runtime.Serialization; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using ASC.Common; namespace ASC.Web.CRM.Classes { @@ -64,28 +65,14 @@ public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) SenderEmailAddress = smtpSettings.SenderAddress; } - - public String Host { get; set; } - + public String Host { get; set; } public int Port { get; set; } - - public bool EnableSSL { get; set; } - - public bool RequiredHostAuthentication { get; set; } - - public String HostLogin { get; set; } - - public String HostPassword { get; set; } - - public String SenderDisplayName { get; set; } - - public String SenderEmailAddress { get; set; } } @@ -111,37 +98,25 @@ public InvoiceSetting DefaultSettings get { return new InvoiceSetting(Configuration) - { - Autogenerated = true, - Prefix = Configuration["crm:invoice:prefix"] ?? "INV-", - Number = "0000001", - Terms = String.Empty, - CompanyName = String.Empty, - CompanyLogoID = 0, - CompanyAddress = String.Empty - }; + { + Autogenerated = true, + Prefix = Configuration["crm:invoice:prefix"] ?? "INV-", + Number = "0000001", + Terms = String.Empty, + CompanyName = String.Empty, + CompanyLogoID = 0, + CompanyAddress = String.Empty + }; } } - - public bool Autogenerated { get; set; } - + public bool Autogenerated { get; set; } public String Prefix { get; set; } - - public String Number { get; set; } - - public String Terms { get; set; } - - public String CompanyName { get; set; } - - public Int32 CompanyLogoID { get; set; } - - public String CompanyAddress { get; set; } } @@ -174,11 +149,7 @@ public SMTPServerSetting SMTPServerSetting [DataMember(Name = "SMTPServerSetting")] public SMTPServerSetting SMTPServerSettingOld { get; set; } - - public InvoiceSetting InvoiceSetting { get; set; } - - public Guid WebFormKey { get; set; } public Guid ID @@ -226,18 +197,18 @@ public ISettings GetDefault(IServiceProvider serviceProvider) var languageName = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; var findedCurrency = CurrencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); - + return new CRMSettings(serviceProvider.GetService(), serviceProvider.GetService()) - { - defaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", - IsConfiguredPortal = false, - ChangeContactStatusGroupAuto = null, - AddTagToContactGroupAuto = null, - WriteMailToHistoryAuto = false, - WebFormKey = Guid.Empty, - InvoiceSetting = InvoiceSetting.DefaultSettings - }; + { + defaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", + IsConfiguredPortal = false, + ChangeContactStatusGroupAuto = null, + AddTagToContactGroupAuto = null, + WriteMailToHistoryAuto = false, + WebFormKey = Guid.Empty//, +// InvoiceSetting = InvoiceSetting.DefaultSettings + }; } } @@ -259,6 +230,6 @@ public ISettings GetDefault(IServiceProvider serviceProvider) return new CRMReportSampleSettings { NeedToGenerate = true }; } } - + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/CSVReader.cs b/products/ASC.CRM/Server/Classes/CSVReader.cs index f658216e9af..739d2a14f5e 100644 --- a/products/ASC.CRM/Server/Classes/CSVReader.cs +++ b/products/ASC.CRM/Server/Classes/CSVReader.cs @@ -60,8 +60,8 @@ using System; using System.Collections.Generic; -using System.IO; using System.Data; +using System.IO; using System.Text; namespace ASC.Web.CRM.Classes @@ -81,7 +81,7 @@ public class CSVReader : IDisposable /// /// This reader will read all of the CSV data /// - private BinaryReader reader; + private readonly BinaryReader reader; /// /// The number of rows to scan for types when building a DataTable (0 to scan the whole file) diff --git a/products/ASC.CRM/Server/Classes/CSVReaderExtension.cs b/products/ASC.CRM/Server/Classes/CSVReaderExtension.cs index 9dadc7b0247..515cee5f632 100644 --- a/products/ASC.CRM/Server/Classes/CSVReaderExtension.cs +++ b/products/ASC.CRM/Server/Classes/CSVReaderExtension.cs @@ -58,7 +58,6 @@ * */ -using System; using System.Collections.Generic; using System.Data; diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs index 960e8b41450..a0e807edaec 100644 --- a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -24,6 +24,14 @@ */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Net; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -36,14 +44,6 @@ using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; -using System.Linq; -using System.Net; - namespace ASC.Web.CRM.Classes { public class ResizeWorkerItem @@ -83,7 +83,7 @@ public ContactPhotoManager(Global global, IOptionsMonitor logger, ICache cache, ICacheNotify cacheNotify, - WorkerQueueOptionsManager workerQueueOptionsManager ) + WorkerQueueOptionsManager workerQueueOptionsManager) { Global = global; WebImageSupplier = webImageSupplier; diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 7526a4161cc..7db2d894162 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -24,27 +24,26 @@ */ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Globalization; +using System.IO; + using ASC.Common; using ASC.Core; using ASC.Core.Common.Settings; using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.Web.Core; using ASC.Web.Core.Files; using ASC.Web.Studio.Core; + using Microsoft.Extensions.Configuration; + using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.Globalization; -using System.IO; -using System.Text; namespace ASC.Web.CRM.Classes { @@ -87,7 +86,7 @@ IConfiguration configuration public static readonly int DefaultCustomFieldCols = 40; public static readonly int MaxHistoryEventCharacters = 65000; - public static readonly decimal MaxInvoiceItemPrice = (decimal) 99999999.99; + public static readonly decimal MaxInvoiceItemPrice = (decimal)99999999.99; protected int TenantID { get; private set; } @@ -99,7 +98,7 @@ IConfiguration configuration public StorageFactory StorageFactory { get; } public CRMSecurity CRMSecurity { get; } - + public IDataStore GetStore() { return StorageFactory.GetStorage(TenantID.ToString(), "crm"); @@ -140,7 +139,7 @@ public bool CanCreateProjects() return canCreateProject; } - catch + catch { return false; } @@ -176,11 +175,11 @@ public bool CanCreateReports public void SaveDefaultCurrencySettings(CurrencyInfo currency) { var tenantSettings = SettingsManager.Load(); - tenantSettings.DefaultCurrency = currency; + tenantSettings.DefaultCurrency = currency; SettingsManager.Save(tenantSettings); } - + /// /// The method to Decode your Base64 strings. /// @@ -217,7 +216,7 @@ public static byte[] ToByteArray(Stream inputStream) br.Close(); return br.ToArray(); } - + public static string GetImgFormatName(ImageFormat format) { if (format.Equals(ImageFormat.Bmp)) return "bmp"; @@ -238,7 +237,7 @@ public static byte[] SaveToBytes(Image img) { return CommonPhotoManager.SaveToBytes(img, GetImgFormatName(img.RawFormat)); } - + private static readonly string[] Formats = new[] { "o", @@ -268,6 +267,6 @@ public static JObject JObjectParseWithDateAsString(string data) ); reader.DateParseHandling = DateParseHandling.None; return JObject.Load(reader); - } + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs index 5e27aeaba0d..41d93cc8893 100644 --- a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs +++ b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs @@ -27,16 +27,14 @@ #region Import using System; -using System.Collections.Generic; -using System.Web; -using System.Linq; -using ASC.CRM.Core; +using System.IO; + +using ASC.Common; +using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Core.Utility; -using System.IO; + using Newtonsoft.Json.Linq; -using ASC.CRM.Core.Enums; -using ASC.Common; #endregion @@ -61,7 +59,7 @@ public ImportFromCSVManager(Global global, public void StartImport(EntityType entityType, String CSVFileURI, String importSettingsJSON) { ImportFromCSV.Start(entityType, CSVFileURI, importSettingsJSON); - + MessageService.Send(GetMessageAction(entityType)); } diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index e846bd64f37..9306996769c 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -24,16 +24,18 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + using ASC.Common; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; + using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Text; namespace ASC.Web.CRM.Classes { @@ -681,5 +683,5 @@ private InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, return data; } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs b/products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs index 6ce73b107b8..24875c55e58 100644 --- a/products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs +++ b/products/ASC.CRM/Server/Classes/LocalizedEnumConverter.cs @@ -26,13 +26,13 @@ #region Import -using ASC.CRM.Resources; using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; -using System.Reflection; + +using ASC.CRM.Resources; #endregion @@ -52,7 +52,7 @@ public static bool TryParse(string value, out T result) return TryParse(value, false, out result); } - public static bool TryParse(string value, bool ignoreCase, out T result) + public static bool TryParse(string value, bool ignoreCase, out T result) where T : struct // error CS0702: Constraint cannot be special class 'System.Enum' { if (value == null) @@ -69,16 +69,16 @@ public static bool TryParse(string value, bool ignoreCase, out T result) return false; } - + } public class LocalizedEnumConverter : EnumConverter { private class LookupTable : Dictionary { } - private Dictionary _lookupTables = new Dictionary(); - private System.Resources.ResourceManager _resourceManager; - private bool _isFlagEnum = false; - private Array _flagValues; + private readonly Dictionary _lookupTables = new Dictionary(); + private readonly System.Resources.ResourceManager _resourceManager; + private readonly bool _isFlagEnum = false; + private readonly Array _flagValues; /// /// GetList the lookup table for the given culture (creating if necessary) @@ -195,7 +195,7 @@ private object GetValue(CultureInfo culture, string text) lookupTable.TryGetValue(text, out result); return result; } - + private object GetFlagValue(CultureInfo culture, string text) { LookupTable lookupTable = GetLookupTable(culture); @@ -238,7 +238,7 @@ public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext } return result; } - + return base.ConvertFrom(context, culture, value); } @@ -284,7 +284,7 @@ public static List GetLocalizedValues(Type enumType) { var converter = TypeDescriptor.GetConverter(enumType); - return (from Enum value in Enum.GetValues(enumType) + return (from Enum value in Enum.GetValues(enumType) select converter.ConvertToString(null, CultureInfo.CurrentUICulture, value)).ToList(); } diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs index f058600a8f5..b7287b6ae36 100644 --- a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -28,6 +28,7 @@ using System.Drawing; using System.Drawing.Imaging; using System.IO; + using ASC.Common; using ASC.Common.Logging; using ASC.CRM.Core.Dao; @@ -35,8 +36,7 @@ using ASC.Web.Core; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM.Configuration; -using ASC.Web.CRM.Core; -using Autofac; + using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Classes @@ -131,7 +131,7 @@ public String GetOrganisationLogoBase64(int logoID) } - + public String GetOrganisationLogoSrc(int logoID) { var bytestring = GetOrganisationLogoBase64(logoID); @@ -195,5 +195,5 @@ public String UploadLogo(byte[] imageData, ImageFormat imageFormat) return ExecResizeImage(imageData, OrganisationLogoSize, Global.GetStore(), photoPath); } - } + } } diff --git a/products/ASC.CRM/Server/Classes/PathProvider.cs b/products/ASC.CRM/Server/Classes/PathProvider.cs index 9a4dc49290c..66b9a3b953a 100644 --- a/products/ASC.CRM/Server/Classes/PathProvider.cs +++ b/products/ASC.CRM/Server/Classes/PathProvider.cs @@ -27,11 +27,11 @@ #region Import using System; -using System.Web; + using ASC.Common; -using ASC.Common.Web; using ASC.Data.Storage; using ASC.Web.Studio.Utility; + using Microsoft.AspNetCore.Http; #endregion @@ -41,9 +41,9 @@ namespace ASC.Web.CRM [Scope] public class PathProvider { - public PathProvider(IHttpContextAccessor httpContextAccessor, + public PathProvider(IHttpContextAccessor httpContextAccessor, CommonLinkUtility commonLinkUtility) - { + { CommonLinkUtility = commonLinkUtility; HttpContext = httpContextAccessor.HttpContext; @@ -106,6 +106,6 @@ public String StartURL() // return fileName; //} - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/SignalRHelper.cs b/products/ASC.CRM/Server/Classes/SignalRHelper.cs index c4ed1408bda..92a5663d5d5 100644 --- a/products/ASC.CRM/Server/Classes/SignalRHelper.cs +++ b/products/ASC.CRM/Server/Classes/SignalRHelper.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; + using ASC.Core.Notify.Signalr; using ASC.VoipService; @@ -41,9 +42,9 @@ public SignalRHelper(string numberId, SignalrServiceClient signalrServiceClient) { SignalrServiceClient = signalrServiceClient; - this.numberId = numberId.TrimStart('+'); + this.numberId = numberId.TrimStart('+'); } - + public void Enqueue(string call, string agent) { SignalrServiceClient.EnqueueCall(numberId, call, agent); diff --git a/products/ASC.CRM/Server/Classes/StringConverter.cs b/products/ASC.CRM/Server/Classes/StringConverter.cs index b1204c73971..d9542add5d6 100644 --- a/products/ASC.CRM/Server/Classes/StringConverter.cs +++ b/products/ASC.CRM/Server/Classes/StringConverter.cs @@ -179,7 +179,7 @@ public static Type FindCommonType(Type typeA, Type typeB) private static Dictionary> typeMap = null; // Locker object to build the singleton typeMap in a typesafe manner - private static object locker = new object(); + private static readonly object locker = new object(); /// /// Build the singleton type map in a typesafe manner. diff --git a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs index 1b95f54f55a..1052e86ba44 100644 --- a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs +++ b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs @@ -26,14 +26,14 @@ #region Import +using System; +using System.Collections.Generic; + using ASC.Core; using ASC.CRM.Resources; using ASC.Notify.Model; using ASC.Web.Core.Subscriptions; using ASC.Web.CRM.Services.NotifyService; -using Microsoft.Extensions.Configuration; -using System; -using System.Collections.Generic; #endregion @@ -58,7 +58,7 @@ public ProductSubscriptionManager(CoreBaseSettings coreBaseSettings, NotifySourc public CoreBaseSettings CoreBaseSettings { get; } public List GetSubscriptionObjects(Guid subItem) - { + { return new List(); } @@ -137,7 +137,7 @@ public GroupByType GroupByType public List GetSubscriptionGroups() { - return new List(); + return new List(); } } diff --git a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs index 11cd58ddf1e..be6cfb37f97 100644 --- a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs +++ b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs @@ -24,18 +24,19 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Common; using ASC.Common.Web; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Resources; -using ASC.Files.Core; using ASC.Files.Core.EF; using ASC.Web.Core; + using Microsoft.EntityFrameworkCore; -using System; -using System.Collections.Generic; -using System.Linq; namespace ASC.Web.CRM.Configuration { diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index 01b51d2f6e1..36d4250bd7f 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -23,6 +23,9 @@ * */ +using System; +using System.Linq; + using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.Settings; @@ -34,13 +37,9 @@ using ASC.CRM.Resources; using ASC.Web.Core; using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Core; -using ASC.Web.CRM.Services.NotifyService; using ASC.Web.Files.Api; -using Autofac; + using Microsoft.Extensions.Options; -using System; -using System.Linq; namespace ASC.Web.CRM.Configuration @@ -67,22 +66,22 @@ public ProductEntryPoint(SecurityContext securityContext, CoreConfiguration = coreConfiguration; FileSecurityProvider = fileSecurityProvider; } - + public static readonly Guid ID = WebItemManager.CRMProductID; - + private ProductContext context; private static readonly object Locker = new object(); - private static bool registered; - + private static readonly bool registered; + public FileSecurityProvider FileSecurityProvider { get; } public CoreConfiguration CoreConfiguration { get; } public ILog Logger { get; } - public SettingsManager SettingsManager { get; } - public FilesIntegration FilesIntegration { get; } + public SettingsManager SettingsManager { get; } + public FilesIntegration FilesIntegration { get; } public DaoFactory DaoFactory { get; } public PathProvider PathProvider { get; } - public SecurityContext SecurityContext { get; } + public SecurityContext SecurityContext { get; } public UserManager UserManager { get; } // TODO: CRM: Реализовать проперти ApiURL @@ -117,8 +116,8 @@ public override void Init() IconFileName = "product_logo.png", LargeIconFileName = "product_logolarge.svg", DefaultSortOrder = 30, - // SubscriptionManager = new ProductSubscriptionManager(), - // SpaceUsageStatManager = new CRMSpaceUsageStatManager(), + // SubscriptionManager = new ProductSubscriptionManager(), + // SpaceUsageStatManager = new CRMSpaceUsageStatManager(), AdminOpportunities = () => CRMCommonResource.ProductAdminOpportunities.Split('|').ToList(), UserOpportunities = () => CRMCommonResource.ProductUserOpportunities.Split('|').ToList(), }; @@ -132,155 +131,155 @@ public override void Init() FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", FileSecurityProvider); } -// SearchHandlerManager.Registry(new SearchHandler()); + // SearchHandlerManager.Registry(new SearchHandler()); //GlobalConfiguration.Configuration.Routes.MapHttpRoute( // name: "Twilio", // routeTemplate: "twilio/{action}", // defaults: new {controller = "Twilio", action = "index" }); -// ClientScriptLocalization = new ClientLocalizationResources(); + // ClientScriptLocalization = new ClientLocalizationResources(); } public void ConfigurePortal() { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = SettingsManager.Load(); if (!tenantSettings.IsConfiguredPortal) { - // Task Category - var listItemDao = DaoFactory.GetListItemDao(); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Call, "task_category_call.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Deal, "task_category_deal.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Demo, "task_category_demo.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Email, "task_category_email.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Fax, "task_category_fax.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_FollowUP, "task_category_follow_up.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Lunch, "task_category_lunch.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Meeting, "task_category_meeting.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Note, "task_category_note.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Ship, "task_category_ship.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_SocialNetworks, "task_category_social_networks.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_ThankYou, "task_category_thank_you.png")); - - // Deal Milestone New - var milestoneDao = DaoFactory.GetDealMilestoneDao(); - - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_InitialContact_Title, - Description = CRMDealResource.DealMilestone_InitialContact_Description, - Probability = 1, - Color = "#e795c1", - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Preapproach_Title, - Description = CRMDealResource.DealMilestone_Preapproach_Description, - Probability = 2, - Color = "#df7895", - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Suspect_Title, - Description = CRMDealResource.DealMilestone_Suspect_Description, - Probability = 3, - Color = "#f48454", - SortOrder = 1, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Champion_Title, - Description = CRMDealResource.DealMilestone_Champion_Description, - Probability = 20, - Color = "#b58fd6", - SortOrder = 2, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Opportunity_Title, - Description = CRMDealResource.DealMilestone_Opportunity_Description, - Probability = 50, - Color = "#d28cc8", - SortOrder = 3, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Prospect_Title, - Description = CRMDealResource.DealMilestone_Prospect_Description, - Probability = 75, - Color = "#ffb45e", - SortOrder = 4, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Verbal_Title, - Description = CRMDealResource.DealMilestone_Verbal_Description, - Probability = 90, - Color = "#ffd267", - SortOrder = 5, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Won_Title, - Description = CRMDealResource.DealMilestone_Won_Description, - Probability = 100, - Color = "#6bbd72", - SortOrder = 6, - Status = DealMilestoneStatus.ClosedAndWon - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Lost_Title, - Description = CRMDealResource.DealMilestone_Lost_Description, - Probability = 0, - Color = "#f2a9be", - SortOrder = 7, - Status = DealMilestoneStatus.ClosedAndLost - }); - - // Contact Status - listItemDao.CreateItem(ListType.ContactStatus, new ListItem {Title = CRMContactResource.ContactStatus_Cold, Color = "#8a98d8", SortOrder = 1}); - listItemDao.CreateItem(ListType.ContactStatus, new ListItem {Title = CRMContactResource.ContactStatus_Warm, Color = "#ffd267", SortOrder = 2}); - listItemDao.CreateItem(ListType.ContactStatus, new ListItem {Title = CRMContactResource.ContactStatus_Hot, Color = "#df7895", SortOrder = 3}); - // Contact Type - listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Client, SortOrder = 1}); - listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Supplier, SortOrder = 2}); - listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Partner, SortOrder = 3}); - listItemDao.CreateItem(ListType.ContactType, new ListItem {Title = CRMContactResource.ContactType_Competitor, SortOrder = 4}); - - // History Category - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Note, "event_category_note.png")); - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Email, "event_category_email.png")); - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png")); - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Meeting, "event_category_meeting.png")); - // Tags - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Lead, true); - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Customer, true); - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Supplier, true); - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Staff, true); - - tenantSettings.WebFormKey = Guid.NewGuid(); - tenantSettings.IsConfiguredPortal = true; - - if (!SettingsManager.Save(tenantSettings)) - { - throw new Exception("not save CRMSettings"); - } + // Task Category + var listItemDao = DaoFactory.GetListItemDao(); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Call, "task_category_call.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Deal, "task_category_deal.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Demo, "task_category_demo.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Email, "task_category_email.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Fax, "task_category_fax.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_FollowUP, "task_category_follow_up.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Lunch, "task_category_lunch.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Meeting, "task_category_meeting.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Note, "task_category_note.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Ship, "task_category_ship.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_SocialNetworks, "task_category_social_networks.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_ThankYou, "task_category_thank_you.png")); + + // Deal Milestone New + var milestoneDao = DaoFactory.GetDealMilestoneDao(); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_InitialContact_Title, + Description = CRMDealResource.DealMilestone_InitialContact_Description, + Probability = 1, + Color = "#e795c1", + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Preapproach_Title, + Description = CRMDealResource.DealMilestone_Preapproach_Description, + Probability = 2, + Color = "#df7895", + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Suspect_Title, + Description = CRMDealResource.DealMilestone_Suspect_Description, + Probability = 3, + Color = "#f48454", + SortOrder = 1, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Champion_Title, + Description = CRMDealResource.DealMilestone_Champion_Description, + Probability = 20, + Color = "#b58fd6", + SortOrder = 2, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Opportunity_Title, + Description = CRMDealResource.DealMilestone_Opportunity_Description, + Probability = 50, + Color = "#d28cc8", + SortOrder = 3, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Prospect_Title, + Description = CRMDealResource.DealMilestone_Prospect_Description, + Probability = 75, + Color = "#ffb45e", + SortOrder = 4, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Verbal_Title, + Description = CRMDealResource.DealMilestone_Verbal_Description, + Probability = 90, + Color = "#ffd267", + SortOrder = 5, + Status = DealMilestoneStatus.Open + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Won_Title, + Description = CRMDealResource.DealMilestone_Won_Description, + Probability = 100, + Color = "#6bbd72", + SortOrder = 6, + Status = DealMilestoneStatus.ClosedAndWon + }); + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Lost_Title, + Description = CRMDealResource.DealMilestone_Lost_Description, + Probability = 0, + Color = "#f2a9be", + SortOrder = 7, + Status = DealMilestoneStatus.ClosedAndLost + }); + + // Contact Status + listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Cold, Color = "#8a98d8", SortOrder = 1 }); + listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Warm, Color = "#ffd267", SortOrder = 2 }); + listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Hot, Color = "#df7895", SortOrder = 3 }); + // Contact Type + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Client, SortOrder = 1 }); + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Supplier, SortOrder = 2 }); + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Partner, SortOrder = 3 }); + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Competitor, SortOrder = 4 }); + + // History Category + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Note, "event_category_note.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Email, "event_category_email.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Meeting, "event_category_meeting.png")); + // Tags + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Lead, true); + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Customer, true); + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Supplier, true); + DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Staff, true); + + tenantSettings.WebFormKey = Guid.NewGuid(); + tenantSettings.IsConfiguredPortal = true; + + if (!SettingsManager.Save(tenantSettings)) + { + throw new Exception("not save CRMSettings"); + } } if (!tenantSettings.IsConfiguredSmtp) { var smtp = SettingsManager.Load().SMTPServerSettingOld; - + if (smtp != null && CoreConfiguration.SmtpSettings.IsDefaultSettings) { try @@ -298,7 +297,7 @@ public void ConfigurePortal() } CoreConfiguration.SmtpSettings = newSettings; - + } catch (Exception e) { @@ -306,7 +305,7 @@ public void ConfigurePortal() } } - + tenantSettings.IsConfiguredSmtp = true; if (!SettingsManager.Save(tenantSettings)) @@ -322,7 +321,7 @@ public void ConfigurePortal() // if (registered) // { // NotifyClient.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask); - + // } //} diff --git a/products/ASC.CRM/Server/Configuration/VoipModule.cs b/products/ASC.CRM/Server/Configuration/VoipModule.cs index f8388010e6a..22102a7cfc3 100644 --- a/products/ASC.CRM/Server/Configuration/VoipModule.cs +++ b/products/ASC.CRM/Server/Configuration/VoipModule.cs @@ -24,12 +24,12 @@ */ +using System; + using ASC.CRM.Resources; -using ASC.Data.Storage; using ASC.Web.Core; using ASC.Web.Core.WebZones; using ASC.Web.Studio.Core; -using System; namespace ASC.Web.CRM.Configuration { @@ -80,11 +80,11 @@ public string HelpURL public void Init() { Context = new AddonContext - { - DefaultSortOrder = 90, - IconFileName = "voip_logo.png", - CanNotBeDisabled = true - }; + { + DefaultSortOrder = 90, + IconFileName = "voip_logo.png", + CanNotBeDisabled = true + }; } public void Shutdown() diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index c167f4e0684..c6429c3c216 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -28,12 +28,14 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; + using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; + using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -42,12 +44,10 @@ namespace ASC.CRM.Core.Dao public class AbstractDao { protected readonly List _supportedEntityType = new List(); - public CRMDbContext CRMDbContext { get; } - public SecurityContext SecurityContext { get; } - + protected SecurityContext _securityContext; protected readonly ICache _cache; - public ILog Logger { get; } + protected ILog _logger; public AbstractDao( DbContextManager dbContextManager, @@ -58,12 +58,12 @@ ICache ascCache ) { - Logger = logger.Get("ASC.CRM"); + _logger = logger.Get("ASC.CRM"); _cache = ascCache; CRMDbContext = dbContextManager.Get(CRMConstants.DatabaseId); TenantID = tenantManager.GetCurrentTenant().TenantId; - SecurityContext = securityContext; + _securityContext = securityContext; _supportedEntityType.Add(EntityType.Company); _supportedEntityType.Add(EntityType.Person); @@ -108,18 +108,19 @@ protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumer var tagIDs = new List(); - foreach (var tag in tags) { + foreach (var tag in tags) + { tagIDs.Add(CRMDbContext .Tags .Where(x => x.EntityType == entityType && String.Compare(x.Title, tag.Trim(), true) == 0) .Select(x => x.Id).Single()); } - + var sqlQuery = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && tagIDs.Contains(x.TagId)); if (exceptIDs != null && exceptIDs.Length > 0) sqlQuery = sqlQuery.Where(x => exceptIDs.Contains(x.EntityId)); - + return sqlQuery.GroupBy(x => x.EntityId) .Where(x => x.Count() == tags.Count()) .Select(x => x.Key) @@ -134,10 +135,10 @@ protected Dictionary GetRelativeToEntity(int[] contactID, EntityType exp = x => x.EntityType == entityType && contactID.Contains(x.ContactId); else if (entityID != null && entityID.Length > 0 && (contactID == null || contactID.Length == 0)) exp = x => x.EntityType == entityType && entityID.Contains(x.EntityId); - + return CRMDbContext.EntityContact.Where(exp).GroupBy(x => x.EntityId).ToDictionary( x => x.Key, - x => x.Select(x => Convert.ToInt32(x.ContactId)).ToArray()); + x => x.Select(x => Convert.ToInt32(x.ContactId)).ToArray()); } protected int[] GetRelativeToEntity(int? contactID, EntityType entityType, int? entityID) @@ -239,12 +240,12 @@ protected void RemoveRelative(int contactID, EntityType entityType, int entityID public int SaveOrganisationLogo(byte[] bytes) - { + { var entity = new DbOrganisationLogo { Content = Convert.ToBase64String(bytes), CreateOn = DateTime.UtcNow, - CreateBy = SecurityContext.CurrentAccount.ID.ToString() + CreateBy = _securityContext.CurrentAccount.ID.ToString() }; CRMDbContext.OrganisationLogo.Add(entity); @@ -255,9 +256,9 @@ public int SaveOrganisationLogo(byte[] bytes) } public string GetOrganisationLogoBase64(int logo_id) - { + { if (logo_id <= 0) throw new ArgumentException(); - + return Query(CRMDbContext.OrganisationLogo) .Where(x => x.Id == logo_id) .Select(x => x.Content) @@ -276,21 +277,21 @@ protected IQueryable Query(DbSet set) where T : class, IDbCrm { return set.Where(r => r.TenantId == TenantID); } - + protected string GetTenantColumnName(string table) { var tenant = "tenant_id"; - + if (!table.Contains(" ")) return tenant; - - return table.Substring(table.IndexOf(" ")).Trim() + "." + tenant; + + return table.Substring(table.IndexOf(" ")).Trim() + "." + tenant; } protected static Guid ToGuid(object guid) { var str = guid as string; - - return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty; + + return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty; } } } diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index cde80ce9a29..83f8edd9b84 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -24,7 +24,16 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + using ASC.Collections; +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Tenants; @@ -34,19 +43,13 @@ using ASC.Files.Core; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; + using Microsoft.AspNetCore.Http; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; -using OrderBy = ASC.CRM.Core.Entities.OrderBy; using Microsoft.EntityFrameworkCore; -using SortedByType = ASC.CRM.Core.Enums.SortedByType; using Microsoft.Extensions.Options; -using ASC.Common.Logging; -using ASC.Common; -using ASC.Common.Caching; + +using OrderBy = ASC.CRM.Core.Entities.OrderBy; +using SortedByType = ASC.CRM.Core.Enums.SortedByType; namespace ASC.CRM.Core.Dao { @@ -265,9 +268,9 @@ private int CreateCasesInDb(String title) Title = title, IsClosed = false, CreateOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -292,7 +295,7 @@ public virtual void UpdateCases(Cases cases) Title = cases.Title, IsClosed = cases.IsClosed, LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID, CreateBy = cases.CreateBy, CreateOn = cases.CreateOn @@ -416,7 +419,7 @@ public int GetCasesCount( var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + "cases" + - SecurityContext.CurrentAccount.ID.ToString() + + _securityContext.CurrentAccount.ID.ToString() + searchText + contactID; @@ -457,9 +460,9 @@ public int GetCasesCount( if (privateCount > countWithoutPrivate) { - Logger.ErrorFormat(@"Private cases count more than all cases. Tenant: {0}. CurrentAccount: {1}", + _logger.ErrorFormat(@"Private cases count more than all cases. Tenant: {0}. CurrentAccount: {1}", TenantID, - SecurityContext.CurrentAccount.ID); + _securityContext.CurrentAccount.ID); privateCount = 0; } diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index d675afedf1e..886cd890672 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -24,6 +24,12 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -38,16 +44,12 @@ using ASC.Files.Core; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; -using OrderBy = ASC.CRM.Core.Entities.OrderBy; +using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Core.Dao { public class CachedContactDao : ContactDao @@ -66,7 +68,7 @@ public CachedContactDao( FactoryIndexerContact factoryIndexerContact, FactoryIndexerContactInfo factoryIndexerContactInfo, IOptionsMonitor logger, - ICache ascCache, + ICache ascCache, DbContextManager coreDbContext, BundleSearch bundleSearch) : base(dbContextManager, @@ -212,7 +214,7 @@ public List GetContactsByPrefix(String prefix, int searchType, int from { var idsFromAcl = CoreDbContext.Acl.Where(x => x.Tenant == TenantID && x.Action == CRMSecurity._actionRead.ID && - x.Subject == SecurityContext.CurrentAccount.ID && + x.Subject == _securityContext.CurrentAccount.ID && (Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName + "%") || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Person).FullName + "%"))) .Select(x => Convert.ToInt32(x.Object.Split('|', StringSplitOptions.None)[1])) @@ -253,7 +255,7 @@ public int GetContactsCount(String searchText, var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + "contacts" + - SecurityContext.CurrentAccount.ID + + _securityContext.CurrentAccount.ID + searchText + contactStage + contactType + @@ -294,38 +296,38 @@ public int GetContactsCount(String searchText, switch (contactListView) { case ContactListViewType.Person: - { + { - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) - .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? - sharedTypes.Contains(x.IsShared.Value) : - true && !x.IsCompany).Select(x => x.Id)) - .ToList(); + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) + .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + sharedTypes.Contains(x.IsShared.Value) : + true && !x.IsCompany).Select(x => x.Id)) + .ToList(); - break; + break; - } + } case ContactListViewType.Company: - { - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) - .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? - sharedTypes.Contains(x.IsShared.Value) : - true && x.IsCompany).Select(x => x.Id)) - .ToList(); + { + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) + .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + sharedTypes.Contains(x.IsShared.Value) : + true && x.IsCompany).Select(x => x.Id)) + .ToList(); - break; - } + break; + } default: - { - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)) - .Union(CRMSecurity.GetPrivateItems(typeof(Person))) - .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? - sharedTypes.Contains(x.IsShared.Value) : - true && x.IsCompany).Select(x => x.Id)) - .ToList(); + { + excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)) + .Union(CRMSecurity.GetPrivateItems(typeof(Person))) + .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + sharedTypes.Contains(x.IsShared.Value) : + true && x.IsCompany).Select(x => x.Id)) + .ToList(); - break; - } + break; + } } var dbContactsByFilters = GetDbContactsByFilters(excludedContactIDs, @@ -393,7 +395,7 @@ public int GetContactsCount(String searchText, if (privateCount > countWithoutPrivate) { - Logger.Error("Private contacts count more than all contacts"); + _logger.Error("Private contacts count more than all contacts"); privateCount = 0; } @@ -708,7 +710,7 @@ private IQueryable GetDbContactsByFilters( List contactsIds; if (!BundleSearch.TrySelectContact(searchText, out contactsIds)) { - Logger.Debug("FullTextSearch.SupportModule('CRM.Contacts') = false"); + _logger.Debug("FullTextSearch.SupportModule('CRM.Contacts') = false"); foreach (var k in keywords) { @@ -717,8 +719,8 @@ private IQueryable GetDbContactsByFilters( } else { - Logger.Debug("FullTextSearch.SupportModule('CRM.Contacts') = true"); - Logger.DebugFormat("FullTextSearch.Search: searchText = {0}", searchText); + _logger.Debug("FullTextSearch.SupportModule('CRM.Contacts') = true"); + _logger.DebugFormat("FullTextSearch.Search: searchText = {0}", searchText); var full_text_ids = contactsIds; @@ -752,17 +754,17 @@ private IQueryable GetDbContactsByFilters( switch (contactListView) { case ContactListViewType.Company: - { - sqlQuery = sqlQuery.Where(x => x.IsCompany); + { + sqlQuery = sqlQuery.Where(x => x.IsCompany); - break; - } + break; + } case ContactListViewType.Person: - { - sqlQuery = sqlQuery.Where(x => !x.IsCompany); + { + sqlQuery = sqlQuery.Where(x => !x.IsCompany); - break; - } + break; + } case ContactListViewType.WithOpportunity: if (ids.Count > 0) { @@ -913,38 +915,38 @@ private List GetCrudeContacts( break; case ContactSortedByType.FirstName: - { - dbContactsQuery = dbContactsQuery.OrderBy("FirstName", orderBy.IsAsc); - dbContactsQuery = dbContactsQuery.OrderBy("LastName", orderBy.IsAsc); - } + { + dbContactsQuery = dbContactsQuery.OrderBy("FirstName", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy("LastName", orderBy.IsAsc); + } - break; + break; case ContactSortedByType.LastName: - { - dbContactsQuery = dbContactsQuery.OrderBy("LastName", orderBy.IsAsc); - dbContactsQuery = dbContactsQuery.OrderBy("FirstName", orderBy.IsAsc); - } - break; + { + dbContactsQuery = dbContactsQuery.OrderBy("LastName", orderBy.IsAsc); + dbContactsQuery = dbContactsQuery.OrderBy("FirstName", orderBy.IsAsc); + } + break; case ContactSortedByType.History: - { - dbContactsQuery = dbContactsQuery.GroupJoin(Query(CRMDbContext.RelationshipEvent), - x => x.Id, - y => y.ContactId, - (x, y) => new { x, y }) - .OrderBy(x => x.y.Max(x => x.LastModifedOn)) - .ThenBy(x => x.x.CreateOn) - .Select(x => x.x); + { + dbContactsQuery = dbContactsQuery.GroupJoin(Query(CRMDbContext.RelationshipEvent), + x => x.Id, + y => y.ContactId, + (x, y) => new { x, y }) + .OrderBy(x => x.y.Max(x => x.LastModifedOn)) + .ThenBy(x => x.x.CreateOn) + .Select(x => x.x); - } + } - break; + break; default: - { - dbContactsQuery = dbContactsQuery.OrderBy("DisplayName", orderBy.IsAsc); - } + { + dbContactsQuery = dbContactsQuery.OrderBy("DisplayName", orderBy.IsAsc); + } - break; + break; } } @@ -1271,7 +1273,7 @@ private void UpdateContactFromDb(Contact contact) itemToUpdate.StatusId = contact.StatusID; itemToUpdate.CompanyId = companyID; itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); - itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; itemToUpdate.DisplayName = displayName; itemToUpdate.IsShared = contact.ShareType; itemToUpdate.ContactTypeId = contact.ContactTypeID; @@ -1481,10 +1483,10 @@ private int SaveContactToDb(Contact contact) Industry = contact.Industry, StatusId = contact.StatusID, CompanyId = companyID, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, CreateOn = TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn), LastModifedOn = TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn), - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, DisplayName = displayName, IsShared = contact.ShareType, ContactTypeId = contact.ContactTypeID, @@ -2085,5 +2087,5 @@ public void SetContactLastModifedDate(int contactId, DateTime lastModifedDate) // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index d1aad3ad4f4..33d934ac90d 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -23,6 +23,10 @@ * */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -33,14 +37,10 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; using ASC.Web.CRM.Core.Search; + using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -62,7 +62,7 @@ IServiceProvider serviceProvider : base( dbContextManager, tenantManager, - securityContext, + securityContext, tenantUtil, logger, ascCache, @@ -113,7 +113,7 @@ public override int Update(ContactInfo contactInfo) [Scope] public class ContactInfoDao : AbstractDao - { + { public ContactInfoDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -154,22 +154,22 @@ public virtual void Delete(int id) CRMDbContext.ContactsInfo.Remove(itemToDelete); CRMDbContext.SaveChanges(); - FactoryIndexerContactInfo.Delete(r => r.Where(a => a.Id, id)); + FactoryIndexerContactInfo.Delete(r => r.Where(a => a.Id, id)); } public virtual void DeleteByContact(int contactID) { if (contactID <= 0) return; - + CRMDbContext.RemoveRange(Query(CRMDbContext.ContactsInfo) .Where(x => x.ContactId == contactID)); CRMDbContext.SaveChanges(); - FactoryIndexerContactInfo.Delete(r => r.Where(a => a.ContactId, contactID)); + FactoryIndexerContactInfo.Delete(r => r.Where(a => a.ContactId, contactID)); } - public virtual int Update(ContactInfo contactInfo) + public virtual int Update(ContactInfo contactInfo) { var result = UpdateInDb(contactInfo); @@ -193,14 +193,14 @@ private int UpdateInDb(ContactInfo contactInfo) ContactId = contactInfo.ContactID, Type = contactInfo.InfoType, LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), - LastModifedBy = SecurityContext.CurrentAccount.ID, - TenantId = TenantID + LastModifedBy = _securityContext.CurrentAccount.ID, + TenantId = TenantID }; CRMDbContext.ContactsInfo.Update(itemToUpdate); CRMDbContext.SaveChanges(); - + return contactInfo.ID; } @@ -224,19 +224,19 @@ private int SaveInDb(ContactInfo contactInfo) { var itemToInsert = new DbContactInfo { - Data = contactInfo.Data, - Category = contactInfo.Category, - IsPrimary = contactInfo.IsPrimary, - ContactId = contactInfo.ContactID, - Type = contactInfo.InfoType, - LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), - LastModifedBy = SecurityContext.CurrentAccount.ID, - TenantId = TenantID + Data = contactInfo.Data, + Category = contactInfo.Category, + IsPrimary = contactInfo.IsPrimary, + ContactId = contactInfo.ContactID, + Type = contactInfo.InfoType, + LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedBy = _securityContext.CurrentAccount.ID, + TenantId = TenantID }; CRMDbContext.Add(itemToInsert); - + CRMDbContext.SaveChanges(); return itemToInsert.Id; @@ -259,7 +259,7 @@ public List GetAll(int[] contactID) return Query(CRMDbContext.ContactsInfo) .Where(x => contactID.Contains(x.ContactId)) - .ToList().ConvertAll(ToContactInfo); + .ToList().ConvertAll(ToContactInfo); } public virtual List GetList(int contactID, ContactInfoType? infoType, int? categoryID, bool? isPrimary) @@ -270,10 +270,10 @@ public virtual List GetList(int contactID, ContactInfoType? infoTyp items = items.Where(x => x.ContactId == contactID); if (infoType.HasValue) - items = items.Where(x => x.Type == infoType.Value); + items = items.Where(x => x.Type == infoType.Value); if (categoryID.HasValue) - items = items.Where(x => x.Category == categoryID.Value); + items = items.Where(x => x.Category == categoryID.Value); if (isPrimary.HasValue) items = items.Where(x => x.IsPrimary == isPrimary.Value); @@ -291,16 +291,16 @@ public int[] UpdateList(List items, Contact contact = null) var result = new List(); var tx = CRMDbContext.Database.BeginTransaction(); - + foreach (var contactInfo in items) result.Add(UpdateInDb(contactInfo)); - + tx.Commit(); - + if (contact != null) { var itemIDs = items.Select(y => y.ID); - + var dbContactInfos = Query(CRMDbContext.ContactsInfo) .Where(x => itemIDs.Contains(x.Id)); @@ -318,7 +318,7 @@ public int[] SaveList(List items, Contact contact = null) if (items == null || items.Count == 0) return null; var result = new List(); - + var tx = CRMDbContext.Database.BeginTransaction(); foreach (var contactInfo in items) @@ -329,7 +329,7 @@ public int[] SaveList(List items, Contact contact = null) } tx.Commit(); - + if (contact != null) { var itemIDs = items.Select(y => y.ID); @@ -351,14 +351,14 @@ protected static ContactInfo ToContactInfo(DbContactInfo dbContactInfo) if (dbContactInfo == null) return null; return new ContactInfo - { - ID = dbContactInfo.Id, - Category = dbContactInfo.Category, - ContactID = dbContactInfo.ContactId, - Data = dbContactInfo.Data, - InfoType = dbContactInfo.Type, - IsPrimary = dbContactInfo.IsPrimary - }; + { + ID = dbContactInfo.Id, + Category = dbContactInfo.Category, + ContactID = dbContactInfo.ContactId, + Data = dbContactInfo.Data, + InfoType = dbContactInfo.Type, + IsPrimary = dbContactInfo.IsPrimary + }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 77ea1222794..0f7009fb418 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -27,19 +27,21 @@ using System; using System.Collections.Generic; using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; + using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao { [Scope] public class CurrencyInfoDao : AbstractDao - { + { public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -51,15 +53,15 @@ public CurrencyInfoDao(DbContextManager dbContextManager, logger, ascCache) { - - + + } public virtual List GetAll() { return CRMDbContext.CurrencyInfo.ToList().ConvertAll(ToCurrencyInfo); } - + public virtual CurrencyInfo GetByAbbreviation(string abbreviation) { return ToCurrencyInfo(CRMDbContext.CurrencyInfo @@ -81,7 +83,7 @@ public List GetOther() .ToList() .ConvertAll(ToCurrencyInfo); } - + private static CurrencyInfo ToCurrencyInfo(DbCurrencyInfo dbCurrencyInfo) { return new CurrencyInfo( @@ -90,7 +92,7 @@ private static CurrencyInfo ToCurrencyInfo(DbCurrencyInfo dbCurrencyInfo) dbCurrencyInfo.Abbreviation, dbCurrencyInfo.CultureName, dbCurrencyInfo.IsConvertable, - dbCurrencyInfo.IsBasic + dbCurrencyInfo.IsBasic ); } } diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index ee89cae7742..4fdc933c519 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -26,12 +26,14 @@ using System; using System.Collections.Generic; using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.CRM.Core.EF; + using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -48,7 +50,7 @@ public CurrencyRateDao( base(dbContextManager, tenantManager, securityContext, - logger, + logger, ascCache) { @@ -66,8 +68,8 @@ public virtual CurrencyRate GetByID(int id) public CurrencyRate GetByCurrencies(string fromCurrency, string toCurrency) { - return ToCurrencyRate(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && - String.Compare(x.ToCurrency, toCurrency, true) == 0)); + return ToCurrencyRate(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && + String.Compare(x.ToCurrency, toCurrency, true) == 0)); } public int SaveOrUpdate(CurrencyRate currencyRate) @@ -77,7 +79,7 @@ public int SaveOrUpdate(CurrencyRate currencyRate) if (currencyRate.ID > 0 && currencyRate.Rate == 0) return Delete(currencyRate.ID); - + if (CRMDbContext.CurrencyRate.Where(x => x.Id == currencyRate.ID).Any()) { var itemToInsert = new DbCurrencyRate @@ -85,9 +87,9 @@ public int SaveOrUpdate(CurrencyRate currencyRate) FromCurrency = currencyRate.FromCurrency.ToUpper(), ToCurrency = currencyRate.ToCurrency.ToUpper(), Rate = currencyRate.Rate, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, CreateOn = DateTime.UtcNow, - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, LastModifedOn = DateTime.UtcNow, TenantId = TenantID }; @@ -104,12 +106,12 @@ public int SaveOrUpdate(CurrencyRate currencyRate) itemToUpdate.FromCurrency = currencyRate.FromCurrency.ToUpper(); itemToUpdate.ToCurrency = currencyRate.ToCurrency.ToUpper(); itemToUpdate.Rate = currencyRate.Rate; - itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; itemToUpdate.LastModifedOn = DateTime.UtcNow; itemToUpdate.TenantId = TenantID; - + CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CRMDbContext.SaveChanges(); } return currencyRate.ID; @@ -135,16 +137,17 @@ public List SetCurrencyRates(List rates) var items = CRMDbContext.CurrencyRate.Where(x => x.TenantId == TenantID); CRMDbContext.RemoveRange(items); - + foreach (var rate in rates) { - var itemToInsert = new DbCurrencyRate { + var itemToInsert = new DbCurrencyRate + { FromCurrency = rate.FromCurrency.ToUpper(), ToCurrency = rate.ToCurrency.ToUpper(), Rate = rate.Rate, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, CreateOn = DateTime.UtcNow, - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, LastModifedOn = DateTime.UtcNow, TenantId = TenantID }; @@ -160,7 +163,7 @@ public List SetCurrencyRates(List rates) return rates; } - + private static CurrencyRate ToCurrencyRate(DbCurrencyRate dbCurrencyRate) { if (dbCurrencyRate == null) return null; diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 67e41b60fc1..26e563c3166 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -23,6 +23,10 @@ * */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -36,12 +40,11 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; + using Microsoft.Extensions.Options; + using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -117,7 +120,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, FieldId = fieldID, EntityType = entityType, LastModifedOn = lastModifiedOn, - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -215,7 +218,7 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) } if (customFieldType == CustomFieldType.SelectBox) { - Logger.Error(ex); + _logger.Error(ex); throw ex; } @@ -358,7 +361,7 @@ public void EditItem(CustomField customField) } catch (Exception ex) { - Logger.Error(ex); + _logger.Error(ex); throw ex; } @@ -501,8 +504,9 @@ private List GetEnityFields(EntityType entityType, int[] entityID, } if (!includeEmptyFields) - sqlQuery = sqlQuery.Where(x => x.y != null && x.x.Type == CustomFieldType.Heading); + sqlQuery = sqlQuery.Where(x => x.y != null || x.x.Type == CustomFieldType.Heading); + return sqlQuery.ToList().ConvertAll(x => ToCustomField(x.x, x.y)); } @@ -569,10 +573,10 @@ public CustomField ToCustomField(DbFieldDescription dbFieldDescription, }; - if (dbFieldValue != null) + if (customField != null) { - dbFieldValue.Value = dbFieldValue.Value; - dbFieldValue.EntityId = dbFieldValue.EntityId; + customField.Value = dbFieldValue.Value; + customField.EntityID = dbFieldValue.EntityId; } return customField; diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 9f91abb2d02..3b75b62c758 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -23,10 +23,12 @@ * */ -using Microsoft.Extensions.DependencyInjection; -using ASC.VoipService.Dao; using System; + using ASC.Common; +using ASC.VoipService.Dao; + +using Microsoft.Extensions.DependencyInjection; namespace ASC.CRM.Core.Dao { diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 8719ce3af50..4df93cc7890 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -24,6 +24,12 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -44,11 +50,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; + using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Core.Dao @@ -205,7 +207,7 @@ public virtual int CreateNewDeal(Deal deal) var result = CreateNewDealInDb(deal); deal.ID = result; - + FactoryIndexer.Index(Query(CRMDbContext.Deals).Where(x => x.Id == deal.ID).FirstOrDefault()); return result; @@ -234,9 +236,9 @@ private int CreateNewDealInDb(Deal deal) ActualCloseDate = deal.ActualCloseDate, PerPeriodValue = deal.PerPeriodValue, CreateOn = TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn), - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, LastModifedOn = TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn), - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -258,7 +260,7 @@ public virtual int[] SaveDealList(List items) var result = items.Select(item => CreateNewDealInDb(item)).ToArray(); tx.Commit(); - + foreach (var deal in Query(CRMDbContext.Deals).Where(x => result.Contains(x.Id))) { FactoryIndexer.Index(deal); @@ -294,7 +296,7 @@ public virtual void EditDeal(Deal deal) itemToUpdate.ActualCloseDate = TenantUtil.DateTimeToUtc(deal.ActualCloseDate); itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); - itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; CRMDbContext.Update(itemToUpdate); CRMDbContext.SaveChanges(); @@ -444,71 +446,71 @@ private IQueryable GetDbDealByFilters( switch ((DealSortedByType)orderBy.SortedBy) { case DealSortedByType.Title: - { - sqlQuery = sqlQuery.OrderBy("x.x.Title", orderBy.IsAsc); + { + sqlQuery = sqlQuery.OrderBy("x.x.Title", orderBy.IsAsc); - break; - } + break; + } case DealSortedByType.BidValue: - { - sqlQuery = sqlQuery.OrderBy("x.x.BidValue", orderBy.IsAsc); + { + sqlQuery = sqlQuery.OrderBy("x.x.BidValue", orderBy.IsAsc); - break; - } + break; + } case DealSortedByType.Responsible: + { + if (orderBy.IsAsc) + { + sqlQuery = sqlQuery.OrderBy(x => x.x.ResponsibleId) + .ThenBy(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); + } + else { - if (orderBy.IsAsc) - { - sqlQuery = sqlQuery.OrderBy(x => x.x.ResponsibleId) - .ThenBy(x => x.y.SortOrder) - .ThenBy(x => x.x.ContactId) - .ThenByDescending(x => x.x.ActualCloseDate) - .ThenBy(x => x.x.ExpectedCloseDate) - .ThenBy(x => x.x.Title); - } - else - { - sqlQuery = sqlQuery.OrderByDescending(x => x.x.ResponsibleId) - .OrderByDescending(x => x.y.SortOrder) - .ThenBy(x => x.x.ContactId) - .ThenByDescending(x => x.x.ActualCloseDate) - .ThenBy(x => x.x.ExpectedCloseDate) - .ThenBy(x => x.x.Title); - - } - - break; + sqlQuery = sqlQuery.OrderByDescending(x => x.x.ResponsibleId) + .OrderByDescending(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); + } + + break; + } case DealSortedByType.Stage: + { + if (orderBy.IsAsc) + { + sqlQuery = sqlQuery.OrderBy(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); + } + else { - if (orderBy.IsAsc) - { - sqlQuery = sqlQuery.OrderBy(x => x.y.SortOrder) - .ThenBy(x => x.x.ContactId) - .ThenByDescending(x => x.x.ActualCloseDate) - .ThenBy(x => x.x.ExpectedCloseDate) - .ThenBy(x => x.x.Title); - } - else - { - sqlQuery = sqlQuery.OrderByDescending(x => x.y.SortOrder) - .ThenBy(x => x.x.ContactId) - .ThenByDescending(x => x.x.ActualCloseDate) - .ThenBy(x => x.x.ExpectedCloseDate) - .ThenBy(x => x.x.Title); - - } - - break; + sqlQuery = sqlQuery.OrderByDescending(x => x.y.SortOrder) + .ThenBy(x => x.x.ContactId) + .ThenByDescending(x => x.x.ActualCloseDate) + .ThenBy(x => x.x.ExpectedCloseDate) + .ThenBy(x => x.x.Title); } + + break; + + } case DealSortedByType.DateAndTime: - { - sqlQuery.OrderBy("x.x.close_date", orderBy.IsAsc); + { + sqlQuery.OrderBy("x.x.close_date", orderBy.IsAsc); - break; + break; - } + } default: throw new ArgumentException(); } @@ -534,7 +536,7 @@ public int GetDealsCount(String searchText, { var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + "deals" + - SecurityContext.CurrentAccount.ID.ToString() + + _securityContext.CurrentAccount.ID.ToString() + searchText + responsibleID + milestoneID + @@ -597,7 +599,7 @@ public int GetDealsCount(String searchText, if (privateCount > countWithoutPrivate) { - Logger.Error("Private deals count more than all deals"); + _logger.Error("Private deals count more than all deals"); privateCount = 0; } @@ -795,7 +797,7 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta sqlQuery = sqlQuery.OrderBy(x => x.Title); - return _mapper.ProjectTo(sqlQuery).ToList().FindAll(CRMSecurity.CanAccessTo); + return _mapper.ProjectTo(sqlQuery).ToList().FindAll(CRMSecurity.CanAccessTo); } public virtual Deal DeleteDeal(int dealID) @@ -963,5 +965,5 @@ public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index b77e83e12ce..4471b6bea44 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -26,6 +26,10 @@ #region Import +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -34,13 +38,10 @@ using ASC.Core.Common.EF; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; using ASC.CRM.Resources; + using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; #endregion diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index c31883c9623..a26d3b05162 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -35,6 +36,7 @@ using ASC.CRM.Core.EF; using ASC.Files.Core; using ASC.Web.Files.Api; + using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -82,7 +84,7 @@ public int GetRoot() public int GetMy() { - return FilesIntegration.RegisterBunch("files", "my", SecurityContext.CurrentAccount.ID.ToString()); + return FilesIntegration.RegisterBunch("files", "my", _securityContext.CurrentAccount.ID.ToString()); } public File SaveFile(File file, System.IO.Stream stream) @@ -97,7 +99,7 @@ public List GetEventsByFile(int id) var tagdao = FilesIntegration.DaoFactory.GetTagDao(); var tags = tagdao.GetTags(id, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); - + return tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index c7249f40b9d..e6ed3f82b62 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -24,6 +24,12 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -38,16 +44,13 @@ using ASC.ElasticSearch; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; + using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Linq.Expressions; -using System.Text.RegularExpressions; + using SecurityContext = ASC.Core.SecurityContext; namespace ASC.CRM.Core.Dao @@ -148,7 +151,7 @@ public InvoiceDao( public InvoiceSetting InvoiceSetting { get; } public InvoiceFormattedData InvoiceFormattedData { get; } - public SettingsManager SettingsManager { get; } + public SettingsManager SettingsManager { get; } public FactoryIndexerInvoice FactoryIndexer { get; } @@ -312,9 +315,9 @@ public List GetCrudeInvoices( int from, int count, OrderBy orderBy) - { + { var withParams = hasParams(searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); - + var sqlQuery = GetDbInvoceByFilters(new List(), searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); if (withParams && sqlQuery == null) @@ -400,7 +403,7 @@ public int GetInvoicesCount( { var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + "invoice" + - SecurityContext.CurrentAccount.ID.ToString() + + _securityContext.CurrentAccount.ID.ToString() + searchText; var fromCache = _cache.Get(cacheKey); @@ -416,7 +419,7 @@ public int GetInvoicesCount( if (withParams) { var sqlQuery = GetDbInvoceByFilters(exceptIDs, searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); - + result = sqlQuery != null ? sqlQuery.Count() : 0; } @@ -428,9 +431,9 @@ public int GetInvoicesCount( if (privateCount > countWithoutPrivate) { - Logger.ErrorFormat(@"Private invoice count more than all cases. Tenant: {0}. CurrentAccount: {1}", + _logger.ErrorFormat(@"Private invoice count more than all cases. Tenant: {0}. CurrentAccount: {1}", TenantID, - SecurityContext.CurrentAccount.ID); + _securityContext.CurrentAccount.ID); privateCount = 0; } @@ -576,9 +579,9 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) JsonData = invoice.JsonData, FileId = invoice.FileID, CreateOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, LastModifedOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -613,7 +616,7 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) itemToUpdate.JsonData = null; itemToUpdate.FileId = 0; itemToUpdate.LastModifedOn = DateTime.UtcNow; - itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; itemToUpdate.TenantId = TenantID; CRMDbContext.SaveChanges(); @@ -652,7 +655,7 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) var invoice = GetByIDFromDb(invoiceid); if (invoice == null) { - Logger.Error("Invoice not found"); + _logger.Error("Invoice not found"); return null; } @@ -660,8 +663,8 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) if (!invoiceStatusMap.Contains(new KeyValuePair(invoice.Status, status))) { - Logger.ErrorFormat("Status for invoice with ID={0} can't be changed. Return without changes", invoiceid); - + _logger.ErrorFormat("Status for invoice with ID={0} can't be changed. Return without changes", invoiceid); + return invoice; } @@ -669,7 +672,7 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) itemToUpdate.Status = status; itemToUpdate.LastModifedOn = DateTime.UtcNow; - itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; CRMDbContext.Update(itemToUpdate); @@ -692,7 +695,7 @@ private int UpdateInvoiceJsonDataInDb(int invoiceId, string jsonData) itemToUpdate.JsonData = jsonData; itemToUpdate.LastModifedOn = DateTime.UtcNow; - itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; CRMDbContext.Update(itemToUpdate); CRMDbContext.SaveChanges(); @@ -733,7 +736,7 @@ private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) sqlToUpdate.FileId = fileId; sqlToUpdate.LastModifedOn = DateTime.UtcNow; - sqlToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + sqlToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; CRMDbContext.Update(sqlToUpdate); CRMDbContext.SaveChanges(); @@ -743,9 +746,9 @@ private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) public InvoiceSetting SaveInvoiceSettings(InvoiceSetting invoiceSetting) { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = SettingsManager.Load(); tenantSettings.InvoiceSetting = invoiceSetting; - + SettingsManager.Save(tenantSettings); return tenantSettings.InvoiceSetting; diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 10a30ef0cbc..64338c977a6 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -24,6 +24,11 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -35,13 +40,10 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Web.CRM.Classes; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -206,11 +208,11 @@ public List GetInvoiceItems( sqlQuery = sqlQuery.OrderBy("Price", orderBy.IsAsc); break; case InvoiceItemSortedByType.Quantity: - { - sqlQuery = sqlQuery.OrderBy("StockQuantity", orderBy.IsAsc) - .OrderBy("Title", true); - break; - } + { + sqlQuery = sqlQuery.OrderBy("StockQuantity", orderBy.IsAsc) + .OrderBy("Title", true); + break; + } case InvoiceItemSortedByType.Created: sqlQuery = sqlQuery.OrderBy("CreateOn", orderBy.IsAsc); break; @@ -240,7 +242,7 @@ public int GetInvoiceItemsCount( { var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + "invoiceItem" + - SecurityContext.CurrentAccount.ID.ToString() + + _securityContext.CurrentAccount.ID.ToString() + searchText; var fromCache = _cache.Get(cacheKey); @@ -248,7 +250,7 @@ public int GetInvoiceItemsCount( if (fromCache != null) return Convert.ToInt32(fromCache); var exceptIDs = CRMSecurity.GetPrivateItems(typeof(InvoiceItem)).ToList(); - + int result; var withParams = !(String.IsNullOrEmpty(searchText) || status != 0 || inventoryStock.HasValue); @@ -265,9 +267,9 @@ public int GetInvoiceItemsCount( if (privateCount > countWithoutPrivate) { - Logger.ErrorFormat(@"Private invoice items count more than all cases. Tenant: {0}. CurrentAccount: {1}", + _logger.ErrorFormat(@"Private invoice items count more than all cases. Tenant: {0}. CurrentAccount: {1}", TenantID, - SecurityContext.CurrentAccount.ID); + _securityContext.CurrentAccount.ID); privateCount = 0; } @@ -323,9 +325,9 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) InvoiceTax2Id = invoiceItem.InvoiceTax2ID, Currency = String.Empty, CreateOn = DateTime.UtcNow, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, LastModifedOn = DateTime.Now, - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -356,7 +358,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) itemToUpdate.Currency = invoiceItem.Currency; itemToUpdate.LastModifedOn = invoiceItem.LastModifedOn; - itemToUpdate.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; CRMDbContext.Add(itemToUpdate); CRMDbContext.SaveChanges(); @@ -492,4 +494,4 @@ private IQueryable GetDbInvoiceItemByFilters( return sqlQuery; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 8b4c5b04557..71df6c6822a 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -24,6 +24,12 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -32,14 +38,11 @@ using ASC.Core.Common.EF; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; + using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; + using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; namespace ASC.CRM.Core.Dao { @@ -92,7 +95,7 @@ private void ResetCache(int invoiceLineID) _invoiceLineCache.Reset(invoiceLineID.ToString(CultureInfo.InvariantCulture)); } } - + [Scope] public class InvoiceLineDao : AbstractDao { @@ -111,7 +114,8 @@ public InvoiceLineDao(DbContextManager dbContextManager, } - public static string GetJson(InvoiceItem invoiceItem) { + public static string GetJson(InvoiceItem invoiceItem) + { return invoiceItem == null ? string.Empty : JsonConvert.SerializeObject(new @@ -121,7 +125,8 @@ public static string GetJson(InvoiceItem invoiceItem) { description = invoiceItem.Description }); } - public static string GetJson(InvoiceTax invoiceTax) { + public static string GetJson(InvoiceTax invoiceTax) + { return invoiceTax == null ? string.Empty : JsonConvert.SerializeObject(new @@ -132,7 +137,7 @@ public static string GetJson(InvoiceTax invoiceTax) { description = invoiceTax.Description }); } - + public virtual List GetAll() { return Query(CRMDbContext.InvoiceLine) @@ -150,7 +155,7 @@ public virtual InvoiceLine GetByID(int id) { return ToInvoiceLine(Query(CRMDbContext.InvoiceLine).FirstOrDefault(x => x.Id == id)); } - + public List GetInvoiceLines(int invoiceID) { return GetInvoiceLinesInDb(invoiceID); @@ -164,7 +169,7 @@ public List GetInvoiceLinesInDb(int invoiceID) .ToList() .ConvertAll(ToInvoiceLine); } - + public virtual int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -227,7 +232,7 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) return invoiceLine.ID; } - + public virtual void DeleteInvoiceLine(int invoiceLineID) { var invoiceLine = GetByID(invoiceLineID); @@ -239,7 +244,7 @@ public virtual void DeleteInvoiceLine(int invoiceLineID) CRMDbContext.Attach(itemToDelete); CRMDbContext.Remove(itemToDelete); CRMDbContext.SaveChanges(); - + /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ } @@ -250,7 +255,7 @@ public void DeleteInvoiceLines(int invoiceID) CRMDbContext.RemoveRange(itemToDelete); CRMDbContext.SaveChanges(); - + /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ } @@ -268,7 +273,7 @@ public Boolean CanDeleteInDb(int invoiceLineID) if (!invoiceID.Any()) return false; - return Query(CRMDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceLineID).Any(); + return Query(CRMDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceLineID).Any(); } private InvoiceLine ToInvoiceLine(DbInvoiceLine dbInvoiceLine) diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index ae6b77ec411..a1f47209634 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -24,6 +24,11 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -38,10 +43,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -148,7 +149,7 @@ public Boolean CanDelete(int invoiceTaxID) public virtual List GetAll() { - return _mapper.Map,List>(Query(CRMDbContext.InvoiceTax).ToList()); + return _mapper.Map, List>(Query(CRMDbContext.InvoiceTax).ToList()); } public DateTime GetMaxLastModified() @@ -189,13 +190,13 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) if (String.IsNullOrEmpty(invoiceTax.Name)) throw new ArgumentException(); - invoiceTax.LastModifedBy = SecurityContext.CurrentAccount.ID; + invoiceTax.LastModifedBy = _securityContext.CurrentAccount.ID; invoiceTax.LastModifedOn = DateTime.UtcNow; if (!Query(CRMDbContext.InvoiceTax).Where(x => x.Id == invoiceTax.ID).Any()) { invoiceTax.CreateOn = DateTime.UtcNow; - invoiceTax.CreateBy = SecurityContext.CurrentAccount.ID; + invoiceTax.CreateBy = _securityContext.CurrentAccount.ID; var itemToInsert = new DbInvoiceTax { @@ -203,7 +204,7 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) Description = invoiceTax.Description, Rate = invoiceTax.Rate, CreateOn = invoiceTax.CreateOn, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, LastModifedBy = invoiceTax.LastModifedBy, LastModifedOn = invoiceTax.LastModifedOn, TenantId = TenantID @@ -220,7 +221,7 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) var oldInvoiceTax = GetByID(invoiceTax.ID); CRMSecurity.DemandEdit(oldInvoiceTax); - + var itemToUpdate = Query(CRMDbContext.InvoiceTax) .FirstOrDefault(x => x.Id == invoiceTax.ID); @@ -260,7 +261,7 @@ public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) /* _cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ return invoiceTax; - } + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index ad68e724481..936c19e8536 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -23,6 +23,11 @@ * */ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -34,13 +39,10 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -319,47 +321,34 @@ public Dictionary GetRelativeItemsCount(ListType listType) switch (listType) { case ListType.ContactStatus: - { - result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.Contacts), - x => x.Id, - y => y.StatusId, - (x, y) => new { Column1 = x, Column2 = y.Count() }) - .Where(x => x.Column1.ListType == listType) - .OrderBy(x => x.Column1.SortOrder) - .ToDictionary(x => x.Column1.Id, x => x.Column2); + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.Contacts), + x => x.Id, + y => y.StatusId, + (x, y) => new { Column1 = x, Column2 = y.Count() }) + .Where(x => x.Column1.ListType == listType) + .OrderBy(x => x.Column1.SortOrder) + .ToDictionary(x => x.Column1.Id, x => x.Column2); - break; - } + break; + } case ListType.ContactType: - { - result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.Contacts), - x => x.Id, - y => y.ContactTypeId, - (x, y) => new { Column1 = x, Column2 = y.Count() }) - .Where(x => x.Column1.ListType == listType) - .OrderBy(x => x.Column1.SortOrder) - .ToDictionary(x => x.Column1.Id, x => x.Column2); - break; - } + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.Contacts), + x => x.Id, + y => y.ContactTypeId, + (x, y) => new { Column1 = x, Column2 = y.Count() }) + .Where(x => x.Column1.ListType == listType) + .OrderBy(x => x.Column1.SortOrder) + .ToDictionary(x => x.Column1.Id, x => x.Column2); + break; + } case ListType.TaskCategory: - { - result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.Tasks), - x => x.Id, - y => y.CategoryId, - (x, y) => new { Column1 = x, Column2 = y.Count() }) - .Where(x => x.Column1.ListType == listType) - .OrderBy(x => x.Column1.SortOrder) - .ToDictionary(x => x.Column1.Id, x => x.Column2); - - break; - } - case ListType.HistoryCategory: - { - result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.RelationshipEvent), + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.Tasks), x => x.Id, y => y.CategoryId, (x, y) => new { Column1 = x, Column2 = y.Count() }) @@ -367,8 +356,21 @@ public Dictionary GetRelativeItemsCount(ListType listType) .OrderBy(x => x.Column1.SortOrder) .ToDictionary(x => x.Column1.Id, x => x.Column2); - break; - } + break; + } + case ListType.HistoryCategory: + { + result = Query(CRMDbContext.ListItem) + .GroupJoin(Query(CRMDbContext.RelationshipEvent), + x => x.Id, + y => y.CategoryId, + (x, y) => new { Column1 = x, Column2 = y.Count() }) + .Where(x => x.Column1.ListType == listType) + .OrderBy(x => x.Column1.SortOrder) + .ToDictionary(x => x.Column1.Id, x => x.Column2); + + break; + } default: throw new ArgumentException(); } @@ -497,39 +499,39 @@ public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toIte switch (listType) { case ListType.ContactStatus: - { - var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.StatusId == fromItemID); + { + var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.StatusId == fromItemID); - itemToUpdate.StatusId = toItemID; + itemToUpdate.StatusId = toItemID; - CRMDbContext.Update(itemToUpdate); - } - break; + CRMDbContext.Update(itemToUpdate); + } + break; case ListType.ContactType: - { - var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.ContactTypeId == fromItemID); + { + var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.ContactTypeId == fromItemID); - itemToUpdate.ContactTypeId = toItemID; + itemToUpdate.ContactTypeId = toItemID; - CRMDbContext.Update(itemToUpdate); - } - break; + CRMDbContext.Update(itemToUpdate); + } + break; case ListType.TaskCategory: - { - var itemToUpdate = Query(CRMDbContext.Tasks).Single(x => x.CategoryId == fromItemID); - itemToUpdate.CategoryId = toItemID; + { + var itemToUpdate = Query(CRMDbContext.Tasks).Single(x => x.CategoryId == fromItemID); + itemToUpdate.CategoryId = toItemID; - CRMDbContext.Update(itemToUpdate); - } - break; + CRMDbContext.Update(itemToUpdate); + } + break; case ListType.HistoryCategory: - { - var itemToUpdate = Query(CRMDbContext.RelationshipEvent).Single(x => x.CategoryId == fromItemID); - itemToUpdate.CategoryId = toItemID; + { + var itemToUpdate = Query(CRMDbContext.RelationshipEvent).Single(x => x.CategoryId == fromItemID); + itemToUpdate.CategoryId = toItemID; - CRMDbContext.Update(itemToUpdate); - } - break; + CRMDbContext.Update(itemToUpdate); + } + break; default: throw new ArgumentException(); } diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 887e148440f..3ae2f1ec4b8 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -24,6 +24,13 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Json; +using System.Text; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -35,22 +42,18 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; using ASC.Files.Core; using ASC.Web.CRM; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; using ASC.Web.Studio.Core; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; + using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Json; -using System.Text; + using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Core.Dao @@ -214,7 +217,7 @@ private int[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID) return tagdao.GetTags(tagNames.ToArray(), TagType.System) .Where(t => t.EntryType == FileEntryType.File) .Select(t => Convert.ToInt32(t.EntryId)).ToArray(); - + } public List> GetAllFiles(int[] contactID, EntityType entityType, int entityID) @@ -309,7 +312,8 @@ public List RemoveFile(File file) { if (GetFiles(eventID).Count == 0) { - var dbRelationshipEvent = new DbRelationshipEvent { + var dbRelationshipEvent = new DbRelationshipEvent + { Id = eventID, HaveFiles = false, TenantId = TenantID @@ -359,8 +363,8 @@ public RelationshipEvent CreateItem(RelationshipEvent item) if (item.CreateOn == DateTime.MinValue) item.CreateOn = TenantUtil.DateTimeNow(); - item.CreateBy = SecurityContext.CurrentAccount.ID; - item.LastModifedBy = SecurityContext.CurrentAccount.ID; + item.CreateBy = _securityContext.CurrentAccount.ID; + item.LastModifedBy = _securityContext.CurrentAccount.ID; if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) { @@ -372,8 +376,8 @@ public RelationshipEvent CreateItem(RelationshipEvent item) // String.Format("{0}mail/messages/{1}.json?id={1}&loadImages=true&needSanitize=true", SetupInfo.WebApiBaseUrl, messageId), "GET"); String msg = null; -// if (msg == null) - throw new ArgumentException("Mail message cannot be found"); + // if (msg == null) + throw new ArgumentException("Mail message cannot be found"); //var msgResponseDto = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg))); //var msgRequestObj = msgResponseDto.Value("response"); @@ -649,7 +653,7 @@ public void DeleteItem(RelationshipEvent item) FactoryIndexer.DeleteAsync(itemToDelete); CRMDbContext.RelationshipEvent.Remove(itemToDelete); - + CRMDbContext.SaveChanges(); } @@ -657,37 +661,37 @@ public void DeleteItem(RelationshipEvent item) [DataContract] internal class CrmHistoryContent { - + public string to; - + public string from; - + public string cc; - + public string bcc; - + public string subject; - + public bool important; - + public string chain_id; - + public bool is_sended; - + public string date_created; - + public string introduction; - + public long message_id; } @@ -718,4 +722,4 @@ private static string GetHistoryContentJson(JObject apiResponse) } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index a145f4cc986..c3bcc180ef2 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -26,29 +26,27 @@ #region Import +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; + +using ASC.Common; +using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; using ASC.Core.Common.Settings; using ASC.Core.Tenants; -using ASC.CRM.Classes; using ASC.CRM.Core.EF; -using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; -using ASC.VoipService; using ASC.Web.CRM.Classes; using ASC.Web.Files.Api; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; + using Microsoft.Extensions.DependencyInjection; -using ASC.Common; -using ASC.Common.Caching; +using Microsoft.Extensions.Options; #endregion @@ -270,7 +268,7 @@ public List GetMissingRates(string defaultCurrency) if (storeTemplate == null) return result; - var culture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture() ?? + var culture = UserManager.GetUsers(_securityContext.CurrentAccount.ID).GetCulture() ?? TenantManager.GetCurrentTenant().GetCulture(); var path = culture + "/"; @@ -306,7 +304,7 @@ public List GetMissingRates(string defaultCurrency) public List> GetFiles() { - return GetFiles(SecurityContext.CurrentAccount.ID); + return GetFiles(_securityContext.CurrentAccount.ID); } public List> GetFiles(Guid userId) @@ -327,7 +325,7 @@ public List GetFileIds(Guid userId) public Files.Core.File GetFile(int fileid) { - return GetFile(fileid, SecurityContext.CurrentAccount.ID); + return GetFile(fileid, _securityContext.CurrentAccount.ID); } public Files.Core.File GetFile(int fileid, Guid userId) @@ -343,7 +341,7 @@ public Files.Core.File GetFile(int fileid, Guid userId) public void DeleteFile(int fileid) { - var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.FileId == fileid && x.CreateBy == SecurityContext.CurrentAccount.ID); + var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.FileId == fileid && x.CreateBy == _securityContext.CurrentAccount.ID); CRMDbContext.Remove(itemToDelete); CRMDbContext.SaveChanges(); @@ -357,7 +355,7 @@ public void DeleteFiles(Guid userId) { var fileIds = GetFileIds(userId); - var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.CreateBy == SecurityContext.CurrentAccount.ID); + var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.CreateBy == _securityContext.CurrentAccount.ID); CRMDbContext.Remove(itemToDelete); CRMDbContext.SaveChanges(); @@ -379,7 +377,7 @@ public void SaveFile(int fileId, int reportType) FileId = fileId, ReportType = (ReportType)reportType, CreateOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index c7297981ac2..92f735be791 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -24,6 +24,10 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -35,17 +39,14 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; using ASC.Web.Core.ModuleManagement.Common; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM; using ASC.Web.CRM.Configuration; using ASC.Web.CRM.Core.Search; + using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -55,7 +56,7 @@ public class SearchDao : AbstractDao private Dictionary> _findedIDs; //TODO: setting _fullTextSearchEnable field - private bool _fullTextSearchEnable; + private readonly bool _fullTextSearchEnable; private DaoFactory DaoFactory { get; set; } @@ -88,7 +89,7 @@ BundleSearch bundleSearch BundleSearch = bundleSearch; } - + public BundleSearch BundleSearch { get; } public WebImageSupplier WebImageSupplier { get; } @@ -105,7 +106,7 @@ public SearchResultItem[] Search(String searchText) .ToArray(); if (keywords.Length == 0) return new List().ToArray(); - + if (_fullTextSearchEnable) { _findedIDs = new Dictionary>(); @@ -200,7 +201,7 @@ private Dictionary> SearchByContactInfos(String[] k return new Dictionary> { { EntityType.Contact, sqlQuery.Select(x => x.ContactId).Distinct() } }; } - + private bool IncludeToSearch(EntityType entityType) { return _findedIDs.ContainsKey(entityType); diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index a1932d6e065..a771f4cf15e 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -24,6 +24,10 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -32,12 +36,11 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; + using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Options; + using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -93,7 +96,7 @@ public List> GetAllTags() { return Query(CRMDbContext.Tags) .OrderBy(x => x.Title) - .Select(x => new KeyValuePair (x.EntityType, x.Title)).ToList(); + .Select(x => new KeyValuePair(x.EntityType, x.Title)).ToList(); } public String GetTagsLinkCountJSON(EntityType entityType) @@ -117,13 +120,15 @@ public IEnumerable GetTagsLinkCount(EntityType entityType) public Dictionary> GetEntitiesTags(EntityType entityType) { - return CRMDbContext.EntityTags.Join(Query(CRMDbContext.Tags), - x => x.TagId, - y => y.Id, - (x, y) => new { x, y }) - .Where(x => x.x.EntityType == entityType) - .GroupBy(x => x.x.EntityId) - .ToDictionary(x => x.Key, x => x.ToList().ConvertAll(x => x.y.Title)); + return CRMDbContext.EntityTags.Join(Query(CRMDbContext.Tags), + x => x.TagId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => x.x.EntityType == entityType) + .Select(x => new { EntityId = x.x.EntityId, Title = x.y.Title }) + .ToList() + .GroupBy(x => x.EntityId) + .ToDictionary(x => x.Key, x => x.ToList().ConvertAll(t => t.Title)); } public String[] GetEntityTags(EntityType entityType, int entityID) @@ -134,13 +139,14 @@ public String[] GetEntityTags(EntityType entityType, int entityID) y => y.TagId, (x, y) => new { - x, y + x, + y }) .Where(x => x.y.EntityId == entityID && x.y.EntityType == entityType) .Select(x => x.x.Title).ToArray(); } - + public string[] GetUnusedTags(EntityType entityType) { return Query(CRMDbContext.Tags) @@ -171,7 +177,7 @@ public void DeleteTagFromEntity(EntityType entityType, int entityID, String tagN var tagID = Query(CRMDbContext.Tags) .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) .Select(x => x.Id).SingleOrDefault(); - + if (tagID == 0) return; var itemsToRemove = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && x.TagId == tagID); @@ -192,7 +198,7 @@ public void DeleteAllTagsFromEntity(EntityType entityType, int entityID) if (entityID <= 0) return; var itemsToRemove = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && x.EntityId == entityID); - + CRMDbContext.EntityTags.RemoveRange(itemsToRemove); CRMDbContext.SaveChanges(); @@ -202,15 +208,15 @@ public void DeleteUnusedTags(EntityType entityType) { if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - + var itemToDelete = Query(CRMDbContext.Tags).GroupJoin(CRMDbContext.EntityTags, x => x.Id, y => y.TagId, (x, y) => new { x, y } ).Where(x => x.x.EntityType == entityType && x.y == null).Select(x => x.x).ToList(); - + CRMDbContext.RemoveRange(itemToDelete); - + CRMDbContext.SaveChanges(); } @@ -252,14 +258,14 @@ private int AddTagInDb(EntityType entityType, String tagName) public Dictionary GetAndAddTags(EntityType entityType, String[] tags) { tags = tags.Select(CorrectTag).Where(t => !string.IsNullOrWhiteSpace(t)).ToArray(); - + using var tx = CRMDbContext.Database.BeginTransaction(); - var tagNamesAndIds = Query(CRMDbContext.Tags) + var tagNamesAndIds = Query(CRMDbContext.Tags) .Where(x => tags.Contains(x.Title) && x.EntityType == entityType) .Select(x => new { x.Id, x.Title }) .ToDictionary(x => x.Title, x => x.Id); - + var tagsForCreate = tags.Where(t => !tagNamesAndIds.ContainsKey(t)); foreach (var tagName in tagsForCreate) @@ -271,7 +277,7 @@ public Dictionary GetAndAddTags(EntityType entityType, String[] tag return tagNamesAndIds; } - + private int AddTagToEntityInDb(EntityType entityType, int entityID, String tagName) { tagName = CorrectTag(tagName); @@ -353,12 +359,12 @@ public int DeleteTagFromContacts(int[] contactID, String tagName) var itemsToRemove = CRMDbContext .EntityTags - .Where(x => x.EntityType == EntityType.Contact && - x.TagId == tagID && + .Where(x => x.EntityType == EntityType.Contact && + x.TagId == tagID && contactID.Contains(x.EntityId)); - + CRMDbContext.EntityTags.RemoveRange(itemsToRemove); - + CRMDbContext.SaveChanges(); tx.Commit(); @@ -369,7 +375,7 @@ public int DeleteTagFromContacts(int[] contactID, String tagName) public void SetTagToEntity(EntityType entityType, int entityID, String[] tags) { using var tx = CRMDbContext.Database.BeginTransaction(); - + var itemsToDelete = CRMDbContext.EntityTags.Where(x => x.EntityId == entityID && x.EntityType == entityType); CRMDbContext.EntityTags.RemoveRange(itemsToDelete); @@ -422,4 +428,4 @@ private static string CorrectTag(string tag) } -} \ No newline at end of file +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 88cee0af20d..34324514cfc 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -24,6 +24,12 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text.RegularExpressions; + using ASC.Collections; using ASC.Common; using ASC.Common.Caching; @@ -43,12 +49,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; - namespace ASC.CRM.Core.Dao { public class CachedTaskDao : TaskDao @@ -380,6 +380,7 @@ private List GetCrudeTasks( } } + return _mapper.ProjectTo(sqlQuery).ToList(); } @@ -396,11 +397,11 @@ public int GetTasksCount( int result = 0; - Logger.DebugFormat("Starting GetTasksCount: {0}", DateTime.Now.ToString()); + _logger.DebugFormat("Starting GetTasksCount: {0}", DateTime.Now.ToString()); var cacheKey = TenantID.ToString(CultureInfo.InvariantCulture) + "tasks" + - SecurityContext.CurrentAccount.ID.ToString() + + _securityContext.CurrentAccount.ID.ToString() + searchText + responsibleId + categoryId + @@ -411,7 +412,7 @@ public int GetTasksCount( if (!String.IsNullOrEmpty(_cache.Get(cacheKey))) { - Logger.DebugFormat("End GetTasksCount: {0}. From cache", DateTime.Now.ToString()); + _logger.DebugFormat("End GetTasksCount: {0}. From cache", DateTime.Now.ToString()); return Convert.ToInt32(_cache.Get(cacheKey)); } @@ -783,7 +784,8 @@ public Dictionary GetTasksCount(int[] contactID) return Query(CRMDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId)) .GroupBy(x => x.ContactId) - .ToDictionary(x => x.Key, x => x.Count()); + .Select(x => new { Key = x.Key, Value = x.Count() }) + .ToDictionary(x => x.Key, x => x.Value); } public int GetTasksCount(int contactID) @@ -800,7 +802,8 @@ public Dictionary HaveLateTask(int[] contactID) return Query(CRMDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed && x.Deadline <= DateTime.UtcNow) .GroupBy(x => x.ContactId) - .ToDictionary(x => x.Key, x => x.Any()); + .Select(x => new { Key = x.Key, Value = x.Count() }) + .ToDictionary(x => x.Key, x => x.Value > 0); } public bool HaveLateTask(int contactID) @@ -815,17 +818,21 @@ public bool HaveLateTask(int contactID) public virtual Task SaveOrUpdateTask(Task newTask) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + return SaveOrUpdateTaskInDb(newTask); } public virtual Task[] SaveOrUpdateTaskList(List newTasks) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + var result = new List(); + foreach (var newTask in newTasks) { result.Add(SaveOrUpdateTaskInDb(newTask)); } + return result.ToArray(); } @@ -838,10 +845,10 @@ private Task SaveOrUpdateTaskInDb(Task newTask) if (newTask.ID == 0 || Query(CRMDbContext.Tasks).Where(x => x.Id == newTask.ID).Count() == 0) { newTask.CreateOn = DateTime.UtcNow; - newTask.CreateBy = SecurityContext.CurrentAccount.ID; + newTask.CreateBy = _securityContext.CurrentAccount.ID; newTask.LastModifedOn = DateTime.UtcNow; - newTask.LastModifedBy = SecurityContext.CurrentAccount.ID; + newTask.LastModifedBy = _securityContext.CurrentAccount.ID; var itemToInsert = new DbTask { @@ -898,7 +905,7 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.CreateBy = oldTask.CreateBy; newTask.LastModifedOn = DateTime.UtcNow; - newTask.LastModifedBy = SecurityContext.CurrentAccount.ID; + newTask.LastModifedBy = _securityContext.CurrentAccount.ID; newTask.IsClosed = oldTask.IsClosed; } @@ -932,9 +939,9 @@ private int SaveTaskInDb(Task newTask) IsClosed = newTask.IsClosed, CategoryId = newTask.CategoryID, CreateOn = newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, LastModifedOn = newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn, - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, AlertValue = newTask.AlertValue, TenantId = TenantID }; diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index c67e9f9e410..8f11b07cce1 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -23,6 +23,10 @@ * */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -31,11 +35,9 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; + using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; namespace ASC.CRM.Core.Dao { @@ -66,16 +68,16 @@ public virtual int SaveOrUpdate(TaskTemplateContainer item) Title = item.Title, EntityType = item.EntityType, CreateOn = DateTime.UtcNow, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, LastModifedOn = DateTime.UtcNow, - LastModifedBy = SecurityContext.CurrentAccount.ID, + LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; if (item.ID == 0 && Query(CRMDbContext.TaskTemplateContainer).Where(x => x.Id == item.ID).Any()) { CRMDbContext.TaskTemplateContainer.Add(dbTaskTemplateContainer); - + CRMDbContext.SaveChanges(); item.ID = dbTaskTemplateContainer.Id; @@ -123,7 +125,7 @@ public virtual List GetItems(EntityType entityType) .ToList() .ConvertAll(ToObject); } - + protected TaskTemplateContainer ToObject(DbTaskTemplateContainer dbTaskTemplateContainer) { if (dbTaskTemplateContainer == null) return null; @@ -147,8 +149,8 @@ public TaskTemplateDao(DbContextManager dbContextManager, ICache cache) : base(dbContextManager, tenantManager, - securityContext, - logger, + securityContext, + logger, cache) { @@ -175,8 +177,8 @@ public int SaveOrUpdate(TaskTemplate item) if (item.ID == 0) { itemToInsert.CreateOn = DateTime.UtcNow; - itemToInsert.CreateBy = SecurityContext.CurrentAccount.ID; - + itemToInsert.CreateBy = _securityContext.CurrentAccount.ID; + CRMDbContext.TaskTemplates.Add(itemToInsert); CRMDbContext.SaveChanges(); } @@ -184,7 +186,7 @@ public int SaveOrUpdate(TaskTemplate item) { itemToInsert.LastModifedOn = DateTime.UtcNow; - itemToInsert.LastModifedBy = SecurityContext.CurrentAccount.ID; + itemToInsert.LastModifedBy = _securityContext.CurrentAccount.ID; CRMDbContext.TaskTemplates.Attach(itemToInsert); CRMDbContext.TaskTemplates.Update(itemToInsert); @@ -211,7 +213,7 @@ public TaskTemplate GetNext(int taskID) if (sqlResult == null) return null; var result = ToObject(Query(CRMDbContext.TaskTemplates) - .FirstOrDefault(x => x.ContainerId == sqlResult.ContainerId && + .FirstOrDefault(x => x.ContainerId == sqlResult.ContainerId && x.SortOrder > sqlResult.SortOrder && !x.DeadLineIsFixed)); CRMDbContext.Remove(new DbTaskTemplateTask @@ -222,7 +224,7 @@ public TaskTemplate GetNext(int taskID) tx.Commit(); - return result; + return result; } public List GetAll() @@ -240,7 +242,7 @@ public List GetList(int containerID) return Query(CRMDbContext.TaskTemplates) .Where(x => x.ContainerId == containerID) - .OrderBy(x=> x.SortOrder) + .OrderBy(x => x.SortOrder) .ToList() .ConvertAll(ToObject); } @@ -285,7 +287,7 @@ protected TaskTemplate ToObject(DbTaskTemplate dbTaskTemplate) CreateOn = dbTaskTemplate.CreateOn, CreateBy = dbTaskTemplate.CreateBy }; - } + } } - + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/DomainObject.cs b/products/ASC.CRM/Server/Core/DomainObject.cs index 84c04aa4d04..11f336f82b0 100644 --- a/products/ASC.CRM/Server/Core/DomainObject.cs +++ b/products/ASC.CRM/Server/Core/DomainObject.cs @@ -27,10 +27,7 @@ #region Import using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; -using System.Text; #endregion @@ -40,7 +37,7 @@ namespace ASC.CRM.Core [Serializable] public class DomainObject { - + [DataMember(Name = "id")] public virtual int ID { @@ -65,6 +62,6 @@ private bool IsTransient() { return ID.Equals(default(int)); } - + } } diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index 21ac37570a6..ad01e91f552 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -1,10 +1,8 @@ -using System; -using ASC.Common; +using ASC.Common; using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; namespace ASC.CRM.Core.EF { @@ -50,7 +48,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .AddDbTask(); - + modelBuilder.Entity(entity => @@ -100,7 +98,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); -; + ; modelBuilder.Entity(entity => { @@ -153,7 +151,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); }); - + modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) diff --git a/products/ASC.CRM/Server/Core/EF/DbCase.cs b/products/ASC.CRM/Server/Core/EF/DbCase.cs index 6febbab39be..745c85540a8 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCase.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCase.cs @@ -17,24 +17,24 @@ namespace ASC.CRM.Core.EF public class DbCase : IDbCrm, ISearchItem { public int Id { get; set; } - + [Required] [Text(Analyzer = "whitespacecustom")] public string Title { get; set; } - + [Column("is_closed")] public bool IsClosed { get; set; } [Required] [Column("create_by", TypeName = "char(38)")] public Guid CreateBy { get; set; } - + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } - + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } - + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbContact.cs b/products/ASC.CRM/Server/Core/EF/DbContact.cs index bbf72fb78db..8c2c81cd79e 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContact.cs @@ -1,4 +1,9 @@ -using ASC.Core.Common.EF; +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; + +using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; @@ -7,11 +12,6 @@ using Nest; -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq.Expressions; - namespace ASC.CRM.Core.EF { [ElasticsearchType(RelationName = "crm_contact")] @@ -19,49 +19,49 @@ namespace ASC.CRM.Core.EF public partial class DbContact : IDbCrm, ISearchItem { public int Id { get; set; } - + [Column("is_company")] public bool IsCompany { get; set; } - + public string Notes { get; set; } - + [Text(Analyzer = "whitespacecustom")] public string Title { get; set; } - + [Column("first_name", TypeName = "varchar(255)")] public string FirstName { get; set; } - + [Column("last_name", TypeName = "varchar(255)")] public string LastName { get; set; } - + [Column("company_name", TypeName = "varchar(255)")] public string CompanyName { get; set; } - + [Column("industry", TypeName = "varchar(255)")] public string Industry { get; set; } - + [Column("status_id", TypeName = "int(11)")] public int StatusId { get; set; } - + [Column("company_id", TypeName = "int(11)")] public int CompanyId { get; set; } - + [Column("contact_type_id", TypeName = "int(11)")] public int ContactTypeId { get; set; } - + [Required] [Column("create_by", TypeName = "char(38)")] public Guid CreateBy { get; set; } - + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } - + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } - + [Column("last_modifed_by", TypeName = "char(38)")] public Guid LastModifedBy { get; set; } - + [Column("display_name", TypeName = "varchar(255)")] public string DisplayName { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs index b66e90b3ce3..37008145775 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs @@ -1,4 +1,9 @@ -using ASC.Core.Common.EF; +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; + +using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; @@ -7,11 +12,6 @@ using Nest; -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq.Expressions; - namespace ASC.CRM.Core.EF { [ElasticsearchType(RelationName = "crm_contact_info")] @@ -23,25 +23,25 @@ public sealed class DbContactInfo : IDbCrm, ISearchItem [Required] [Text(Analyzer = "whitespacecustom")] public string Data { get; set; } - + [Column("category", TypeName = "int(255)")] public int Category { get; set; } - + [Column("tenant_id", TypeName = "int(255)")] public int TenantId { get; set; } - + [Column("is_primary", TypeName = "tinyint(4)")] public bool IsPrimary { get; set; } - + [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } - + [Column("type", TypeName = "int(255)")] public ContactInfoType Type { get; set; } - + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } - + [Column("last_modifed_by", TypeName = "char(38)")] public Guid LastModifedBy { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs index 6502389b0e9..b9eed31d757 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs @@ -14,11 +14,11 @@ public partial class DbCurrencyRate [Required] [Column("from_currency", TypeName = "varchar(255)")] public string FromCurrency { get; set; } - + [Required] [Column("to_currency", TypeName = "varchar(255)")] public string ToCurrency { get; set; } - + [Column("rate", TypeName = "decimal(10,2)")] public decimal Rate { get; set; } [Required] diff --git a/products/ASC.CRM/Server/Core/EF/DbDeal.cs b/products/ASC.CRM/Server/Core/EF/DbDeal.cs index 266a130e550..9161ab609d1 100644 --- a/products/ASC.CRM/Server/Core/EF/DbDeal.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDeal.cs @@ -23,20 +23,19 @@ * */ +using System; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; + using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nest; -using System; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq.Expressions; - namespace ASC.CRM.Core.EF { [ElasticsearchType(RelationName = "crm_deal")] diff --git a/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs b/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs index 15de02e3642..eeedd5ede5f 100644 --- a/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbEntityContact.cs @@ -1,8 +1,9 @@  -using ASC.CRM.Core.Enums; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using ASC.CRM.Core.Enums; + namespace ASC.CRM.Core.EF { [Table("crm_entity_contact")] @@ -11,14 +12,14 @@ public partial class DbEntityContact [Key] [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } - + [Key] [Column("entity_type", TypeName = "int(11)")] public EntityType EntityType { get; set; } - + [Key] [Column("contact_id", TypeName = "int(11)")] - public int ContactId { get; set; } + public int ContactId { get; set; } } - + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs index 53612816467..b45254a8f62 100644 --- a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs @@ -1,4 +1,8 @@ -using ASC.Core.Common.EF; +using System; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; + +using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; @@ -7,11 +11,6 @@ using Nest; -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq.Expressions; - namespace ASC.CRM.Core.EF { [ElasticsearchType(RelationName = "crm_field_value")] @@ -22,22 +21,22 @@ public partial class DbFieldValue : IDbCrm, ISearchItem [Text(Analyzer = "whitespacecustom")] public string Value { get; set; } - + [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } - + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } [Column("field_id", TypeName = "int(11)")] public int FieldId { get; set; } - + [Column("entity_type", TypeName = "int(10)")] public EntityType EntityType { get; set; } - + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } - + [Column("last_modifed_by", TypeName = "char(38)")] public Guid LastModifedBy { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs index cf9abc0174b..47288e573bd 100644 --- a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs @@ -1,13 +1,13 @@ -using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; - -using Nest; - -using System; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq.Expressions; +using ASC.CRM.Core.Enums; +using ASC.ElasticSearch; + +using Nest; + namespace ASC.CRM.Core.EF { [Table("crm_invoice")] @@ -19,72 +19,72 @@ public class DbInvoice : IDbCrm, ISearchItem [Column("status", TypeName = "int(11)")] public InvoiceStatus Status { get; set; } - + [Required] [Column("number", TypeName = "varchar(255)")] public string Number { get; set; } - + [Column("issue_date", TypeName = "datetime")] public DateTime IssueDate { get; set; } - + [Column("template_type", TypeName = "int(11)")] public InvoiceTemplateType TemplateType { get; set; } - + [Column("contact_id", TypeName = "int(11)")] public int ContactId { get; set; } - + [Column("consignee_id", TypeName = "int(11)")] public int ConsigneeId { get; set; } - + [Column("entity_type", TypeName = "int(11)")] public EntityType EntityType { get; set; } - + [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } - + [Column("due_date", TypeName = "datetime")] public DateTime DueDate { get; set; } - + [Required] [Column("language", TypeName = "varchar(255)")] public string Language { get; set; } - + [Required] [Column("currency", TypeName = "varchar(255)")] public string Currency { get; set; } - + [Column("exchange_rate", TypeName = "decimal(10,2)")] public decimal ExchangeRate { get; set; } - + [Required] [Column("purchase_order_number", TypeName = "varchar(255)")] public string PurchaseOrderNumber { get; set; } - + [Column("terms", TypeName = "text")] public string Terms { get; set; } - + [Column("description", TypeName = "text")] public string Description { get; set; } - + [Column("json_data", TypeName = "text")] public string JsonData { get; set; } - + [Column("file_id", TypeName = "int(11)")] public int FileId { get; set; } - + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } - + [Required] [Column("create_by", TypeName = "char(38)")] public Guid CreateBy { get; set; } - + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } - + [Column("last_modifed_by", TypeName = "char(38)")] public Guid LastModifedBy { get; set; } - + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbListItem.cs b/products/ASC.CRM/Server/Core/EF/DbListItem.cs index ad5f8155804..9b221f05a62 100644 --- a/products/ASC.CRM/Server/Core/EF/DbListItem.cs +++ b/products/ASC.CRM/Server/Core/EF/DbListItem.cs @@ -1,7 +1,8 @@ -using ASC.CRM.Core.Enums; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using ASC.CRM.Core.Enums; + namespace ASC.CRM.Core.EF { [Table("crm_list_item")] @@ -10,23 +11,23 @@ public partial class DbListItem : IDbCrm [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } - + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } - + [Column("sort_order", TypeName = "int(11)")] public int SortOrder { get; set; } - + [Column("color", TypeName = "varchar(255)")] public string Color { get; set; } - + [Column("additional_params", TypeName = "varchar(255)")] public string AdditionalParams { get; set; } - + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } - + [Column("list_type", TypeName = "int(255)")] public ListType ListType { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbProjects.cs b/products/ASC.CRM/Server/Core/EF/DbProjects.cs index d7e0e64f85e..bed9c2a6458 100644 --- a/products/ASC.CRM/Server/Core/EF/DbProjects.cs +++ b/products/ASC.CRM/Server/Core/EF/DbProjects.cs @@ -1,5 +1,4 @@ -using Microsoft.EntityFrameworkCore; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ASC.CRM.Core.EF @@ -14,7 +13,7 @@ public partial class DbProjects : IDbCrm [Key] [Column("contact_id", TypeName = "int(10)")] public int ContactId { get; set; } - + [Key] [Column("tenant_id", TypeName = "int(10)")] public int TenantId { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index 3c45a80f15a..e172cf810ae 100644 --- a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -1,4 +1,9 @@ -using ASC.Core.Common.EF; +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; + +using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; @@ -7,11 +12,6 @@ using Nest; -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq.Expressions; - namespace ASC.CRM.Core.EF { [ElasticsearchType(RelationName = "crm_relationship_event")] @@ -24,36 +24,36 @@ public class DbRelationshipEvent : IDbCrm, ISearchItem [Column("contact_id")] public int ContactId { get; set; } - + [Column("content")] [Text(Analyzer = "whitespacecustom")] public string Content { get; set; } - + [Required] [Column("create_by", TypeName = "char(38)")] public Guid CreateBy { get; set; } - + [Column("create_on", TypeName = "datetime")] public DateTime CreateOn { get; set; } - + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } - + [Column("entity_type", TypeName = "int(11)")] public EntityType EntityType { get; set; } - + [Column("entity_id", TypeName = "int(11)")] public int EntityId { get; set; } [Column("category_id", TypeName = "int(11)")] public int CategoryId { get; set; } - + [Column("last_modifed_by", TypeName = "char(38)")] public Guid? LastModifedBy { get; set; } - + [Column("last_modifed_on", TypeName = "datetime")] public DateTime? LastModifedOn { get; set; } - + [Column("have_files", TypeName = "int(11)")] public bool HaveFiles { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbTag.cs b/products/ASC.CRM/Server/Core/EF/DbTag.cs index b1abf57b411..36ae65b2bb8 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTag.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTag.cs @@ -1,7 +1,8 @@ -using ASC.CRM.Core.Enums; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using ASC.CRM.Core.Enums; + namespace ASC.CRM.Core.EF { [Table("crm_tag")] @@ -10,11 +11,11 @@ public partial class DbTag : IDbCrm [Key] [Column("id", TypeName = "int(11)")] public int Id { get; set; } - + [Required] [Column("title", TypeName = "varchar(255)")] public string Title { get; set; } - + [Column("tenant_id", TypeName = "int(11)")] public int TenantId { get; set; } diff --git a/products/ASC.CRM/Server/Core/EF/DbTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs index 7362d651de8..46dd2b21a83 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -1,4 +1,9 @@ -using ASC.Core.Common.EF; +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq.Expressions; + +using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; @@ -7,19 +12,14 @@ using Nest; -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq.Expressions; - namespace ASC.CRM.Core.EF { [ElasticsearchType(RelationName = "crm_task")] [Table("crm_task")] - public partial class DbTask: IDbCrm, ISearchItem + public partial class DbTask : IDbCrm, ISearchItem { public int Id { get; set; } - + [Required] [Text(Analyzer = "whitespacecustom")] public string Title { get; set; } @@ -87,7 +87,7 @@ public Expression> SearchContentFields } } } - + public static class DbTaskExtension { public static ModelBuilderWrapper AddDbTask(this ModelBuilderWrapper modelBuilder) diff --git a/products/ASC.CRM/Server/Core/EF/DbTaskTemplateTask.cs b/products/ASC.CRM/Server/Core/EF/DbTaskTemplateTask.cs index 310fe1b0ba9..9cf84ee691c 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTaskTemplateTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTaskTemplateTask.cs @@ -9,7 +9,7 @@ public partial class DbTaskTemplateTask : IDbCrm [Key] [Column("task_id", TypeName = "int(10)")] public int TaskId { get; set; } - + [Key] [Column("task_template_id", TypeName = "int(10)")] public int TaskTemplateId { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/Cases.cs b/products/ASC.CRM/Server/Core/Entities/Cases.cs index 9d5ed23945a..640ff44f133 100644 --- a/products/ASC.CRM/Server/Core/Entities/Cases.cs +++ b/products/ASC.CRM/Server/Core/Entities/Cases.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; + using ASC.Common.Security; namespace ASC.CRM.Core.Entities diff --git a/products/ASC.CRM/Server/Core/Entities/Contact.cs b/products/ASC.CRM/Server/Core/Entities/Contact.cs index ae02d7080f4..6bfbb970d12 100644 --- a/products/ASC.CRM/Server/Core/Entities/Contact.cs +++ b/products/ASC.CRM/Server/Core/Entities/Contact.cs @@ -24,10 +24,10 @@ */ +using System; + using ASC.Common.Security; -using ASC.CRM.Classes; using ASC.CRM.Core.Enums; -using System; namespace ASC.CRM.Core.Entities { diff --git a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs index 1790cda1988..73bc67f49b3 100644 --- a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs @@ -24,11 +24,12 @@ */ -using ASC.CRM.Classes; -using ASC.CRM.Core.Enums; using System; using System.Runtime.Serialization; +using ASC.CRM.Classes; +using ASC.CRM.Core.Enums; + namespace ASC.CRM.Core { [DataContract] diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index 97e85838977..6d7f9892c84 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -24,16 +24,17 @@ */ -using ASC.CRM.Resources; using System; using System.Runtime.Serialization; +using ASC.CRM.Resources; + namespace ASC.CRM.Core { [DataContract] public class CurrencyInfo { - private String _resourceKey; + private readonly String _resourceKey; [DataMember(Name = "title")] public String Title diff --git a/products/ASC.CRM/Server/Core/Entities/CustomField.cs b/products/ASC.CRM/Server/Core/Entities/CustomField.cs index e1b2619468b..d989d80e3c8 100644 --- a/products/ASC.CRM/Server/Core/Entities/CustomField.cs +++ b/products/ASC.CRM/Server/Core/Entities/CustomField.cs @@ -26,24 +26,22 @@ #region Import -using ASC.CRM.Core.Enums; using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.Serialization; -using System.Text; + +using ASC.CRM.Core.Enums; #endregion namespace ASC.CRM.Core.Entities { - + [DataContract] public class CustomField : DomainObject { [DataMember(Name = "entity_type")] public EntityType EntityType { get; set; } - + [DataMember(Name = "entity_id")] public int EntityID { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index 4a5d31859e8..9b53f1dd3d7 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -26,6 +26,7 @@ using System; using System.Runtime.Serialization; + using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; @@ -69,7 +70,7 @@ public class Deal : DomainObject, ISecurityObjectId, IMapFrom [DataMember(Name = "bid_currency")] public string BidCurrency { get; set; } - + [DataMember(Name = "per_period_value")] public int PerPeriodValue { get; set; } @@ -92,7 +93,7 @@ public class Deal : DomainObject, ISecurityObjectId, IMapFrom // set { ; } //} - + public DateTime ExpectedCloseDate { get; set; } [DataMember(Name = "expected_close_date")] @@ -105,7 +106,7 @@ public class Deal : DomainObject, ISecurityObjectId, IMapFrom // } // set { ; } //} - + public object SecurityId { get { return ID; } @@ -119,6 +120,6 @@ public Type ObjectType public void Mapping(Profile profile) { profile.CreateMap(); - } + } } } diff --git a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs index 47b7b588417..e1abb32de0d 100644 --- a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs +++ b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs @@ -27,13 +27,8 @@ #region Import using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; using System.Runtime.Serialization; -using System.Text; -using ASC.Common.Security; -using ASC.Common.Security.Authorizing; + using ASC.CRM.Core.Enums; #endregion diff --git a/products/ASC.CRM/Server/Core/Entities/Filter.cs b/products/ASC.CRM/Server/Core/Entities/Filter.cs index df8f5ce34a0..fa403126fdd 100644 --- a/products/ASC.CRM/Server/Core/Entities/Filter.cs +++ b/products/ASC.CRM/Server/Core/Entities/Filter.cs @@ -31,11 +31,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; + using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; using ASC.Web.CRM.Classes; + using Newtonsoft.Json; using Newtonsoft.Json.Linq; + using EnumExtension = ASC.CRM.Classes.EnumExtension; #endregion @@ -72,8 +75,8 @@ public CasesFilterObject() public CasesFilterObject(string base64String) { - if(string.IsNullOrEmpty(base64String)) return; - + if (string.IsNullOrEmpty(base64String)) return; + var json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); var jsonArray = json.Split(';'); @@ -387,7 +390,7 @@ public ContactFilterObject(string base64String) { ContactStage = -1; ContactType = -1; - + if (string.IsNullOrEmpty(base64String)) return; var json = Encoding.UTF8.GetString(Convert.FromBase64String(base64String)); @@ -515,7 +518,7 @@ public InvoiceItemFilterObject(string base64String) var paramString = filterObj.Value("params"); - if(string.IsNullOrEmpty(paramString)) continue; + if (string.IsNullOrEmpty(paramString)) continue; var filterParam = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs index 18388a4ebd3..8fc0c9ef523 100644 --- a/products/ASC.CRM/Server/Core/Entities/Invoice.cs +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -24,12 +24,13 @@ */ +using System; +using System.Collections.Generic; + using ASC.Common.Security; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; using ASC.Files.Core; -using System; -using System.Collections.Generic; namespace ASC.CRM.Core.Entities @@ -76,7 +77,7 @@ public class Invoice : DomainObject, ISecurityObjectId public Guid CreateBy { get; set; } public DateTime? LastModifedOn { get; set; } - + public Guid? LastModifedBy { get; set; } @@ -120,7 +121,7 @@ public decimal GetInvoiceCost(DaoFactory daoFactory) if (tax1 != null) { lineTax1 = Math.Round(linePrice * tax1.Rate / 100, 2); - } + } } decimal lineTax2 = 0; diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs index 922b46e7d18..9b487075c0a 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs @@ -26,6 +26,7 @@ using System; using System.Runtime.Serialization; + using ASC.Common.Security; diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs index 06b47c6372c..b8286344546 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs @@ -23,9 +23,6 @@ * */ - -using System; - namespace ASC.CRM.Core.Entities { public class InvoiceLine : DomainObject diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs index 0842696d9e0..cd76e7d12cd 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -26,6 +26,7 @@ using System; using System.Runtime.Serialization; + using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; @@ -45,8 +46,8 @@ public class InvoiceTax : DomainObject, ISecurityObjectId, IMapFrom(); -// .ForMember(x => x.CreateOn, x => x.ConvertUsing()) -// .ForMember(x => x.LastModifedOn, x => x.ConvertUsing()); + // .ForMember(x => x.CreateOn, x => x.ConvertUsing()) + // .ForMember(x => x.LastModifedOn, x => x.ConvertUsing()); } } } diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs index 4eb845e4f90..3b93c80871c 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs @@ -27,11 +27,7 @@ #region Import using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using ASC.Common.Security; + using ASC.CRM.Core.Enums; #endregion @@ -67,7 +63,7 @@ public class TaskTemplate : DomainObject public Guid CreateBy { get; set; } - public DateTime CreateOn { get; set; } + public DateTime CreateOn { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs b/products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs index c4ca6ed4669..4c811c94da4 100644 --- a/products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/ContactInfoCategoryEnum.cs @@ -25,11 +25,12 @@ using System.ComponentModel; + using ASC.CRM.Classes; namespace ASC.CRM.Core.Enums { - [TypeConverter(typeof (LocalizedEnumConverter))] + [TypeConverter(typeof(LocalizedEnumConverter))] public enum ContactInfoBaseCategory { Home, @@ -37,7 +38,7 @@ public enum ContactInfoBaseCategory Other } - [TypeConverter(typeof (LocalizedEnumConverter))] + [TypeConverter(typeof(LocalizedEnumConverter))] public enum PhoneCategory { Home, @@ -58,14 +59,14 @@ public enum AddressPart Country } - [TypeConverter(typeof (LocalizedEnumConverter))] + [TypeConverter(typeof(LocalizedEnumConverter))] public enum AddressCategory { Home, Postal, Office, Billing, - Other, + Other, Work } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs index 9209c132da5..c1acf721274 100644 --- a/products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/ContactInfoTypeEnum.cs @@ -25,6 +25,7 @@ using System.ComponentModel; + using ASC.CRM.Classes; diff --git a/products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs index 9f286de083d..48ac35b3491 100644 --- a/products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/ContactListViewTypeEnum.cs @@ -25,6 +25,7 @@ using System.ComponentModel; + using ASC.CRM.Classes; namespace ASC.CRM.Core.Enums diff --git a/products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs index d927471818c..67bc03245b3 100644 --- a/products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/CustomFieldTypeEnum.cs @@ -25,6 +25,7 @@ using System.ComponentModel; + using ASC.CRM.Classes; namespace ASC.CRM.Core.Enums diff --git a/products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs b/products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs index f1190315489..e7f505b1257 100644 --- a/products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs +++ b/products/ASC.CRM/Server/Core/Enums/DealMilestoneStatus.cs @@ -26,9 +26,10 @@ #region Import -using ASC.CRM.Classes; using System.ComponentModel; +using ASC.CRM.Classes; + #endregion namespace ASC.CRM.Core.Enums diff --git a/products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs index 5c5942e27e0..7fa846e55c5 100644 --- a/products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/EntityTypeEnum.cs @@ -24,15 +24,16 @@ */ -using ASC.CRM.Classes; using System.ComponentModel; +using ASC.CRM.Classes; + namespace ASC.CRM.Core.Enums { [TypeConverter(typeof(LocalizedEnumConverter))] public enum EntityType { - Any = -1, + Any = -1, Contact = 0, Opportunity = 1, RelationshipEvent = 2, diff --git a/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs b/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs index ce38dac7f79..7390696dbd3 100644 --- a/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs +++ b/products/ASC.CRM/Server/Core/Enums/InvoiceStatus.cs @@ -24,9 +24,10 @@ */ -using ASC.CRM.Classes; using System.ComponentModel; +using ASC.CRM.Classes; + namespace ASC.CRM.Core.Enums { [TypeConverter(typeof(LocalizedEnumConverter))] diff --git a/products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs index 70170ea78a0..c0da1517d76 100644 --- a/products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/InvoiceTemplateTypeEnum.cs @@ -25,6 +25,7 @@ using System.ComponentModel; + using ASC.CRM.Classes; namespace ASC.CRM.Core.Enums diff --git a/products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs index 3c6ee1b6748..7da612c994b 100644 --- a/products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/ListTypeEnum.cs @@ -26,9 +26,10 @@ #region Import -using ASC.CRM.Classes; using System.ComponentModel; +using ASC.CRM.Classes; + #endregion namespace ASC.CRM.Core.Enums diff --git a/products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs b/products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs index 578c59d0c1a..9080993068b 100644 --- a/products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs +++ b/products/ASC.CRM/Server/Core/Enums/SortedByTypeEnum.cs @@ -58,7 +58,7 @@ public enum ContactSortedByType DisplayName, ContactType, Created, - FirstName, + FirstName, LastName, History } diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index 1b4cb7ae0e1..8f2608dc7bc 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -84,7 +84,7 @@ public bool TrySelectCase(string text, out List result) } IReadOnlyCollection events; - + if (!FactoryIndexerEvents.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) { result.AddRange(events.Select(r => r.EntityId).ToList()); @@ -140,7 +140,7 @@ public bool TrySelectOpportunity(string text, out List result) result = new List(); List dealsId; - + if (FactoryIndexerDeal.TrySelectIds(s => s.MatchAll(text), out dealsId)) { result.AddRange(dealsId); @@ -148,7 +148,7 @@ public bool TrySelectOpportunity(string text, out List result) } IReadOnlyCollection casesCustom; - + if (FactoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 1), out casesCustom)) { result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs index 418eade63ce..de72fbb78f0 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs @@ -34,11 +34,9 @@ using ASC.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; -using ASC.CRM.Core.Entities; using ASC.ElasticSearch; using ASC.ElasticSearch.Core; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -46,7 +44,7 @@ namespace ASC.Web.CRM.Core.Search [Scope] public sealed class FactoryIndexerCase : FactoryIndexer { - public FactoryIndexerCase ( + public FactoryIndexerCase( IOptionsMonitor options, TenantManager tenantManager, SearchSettingsHelper searchSettingsHelper, diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs index 2ba40eac7f4..eb7922fcdef 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs @@ -34,11 +34,9 @@ using ASC.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; -using ASC.CRM.Core.Entities; using ASC.ElasticSearch; using ASC.ElasticSearch.Core; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs index b1337001d1e..433240e72a3 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs @@ -25,23 +25,19 @@ using System; -using System.Text; -using ASC.Common.Logging; -using ASC.Core; -using ASC.CRM.Core; -using ASC.CRM.Core.Enums; -using ASC.ElasticSearch; -using Microsoft.Extensions.Options; -using Newtonsoft.Json.Linq; +using System.Collections.Generic; +using System.Linq; -using Microsoft.Extensions.DependencyInjection; using ASC.Common; -using ASC.CRM.Core.EF; -using ASC.ElasticSearch.Core; using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Core; using ASC.CRM.Core.Dao; -using System.Collections.Generic; -using System.Linq; +using ASC.CRM.Core.EF; +using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; + +using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search { diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs index 5ce3f5e32fb..9639f5c2f49 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs @@ -34,11 +34,9 @@ using ASC.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; -using ASC.CRM.Core.Entities; using ASC.ElasticSearch; using ASC.ElasticSearch.Core; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -46,7 +44,7 @@ namespace ASC.Web.CRM.Core.Search [Scope] public sealed class FactoryIndexerFieldValue : FactoryIndexer { - public FactoryIndexerFieldValue ( + public FactoryIndexerFieldValue( IOptionsMonitor options, TenantManager tenantManager, SearchSettingsHelper searchSettingsHelper, diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs index 37b9091bb76..f7ee6cfd6ea 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs @@ -34,11 +34,9 @@ using ASC.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; -using ASC.CRM.Core.Entities; using ASC.ElasticSearch; using ASC.ElasticSearch.Core; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -53,7 +51,7 @@ public FactoryIndexerInvoice( FactoryIndexer factoryIndexer, BaseIndexer baseIndexer, IServiceProvider serviceProvider, - DaoFactory daoFactory, + DaoFactory daoFactory, ICache cache) : base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache) { diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs index 2ca345c8158..b1dd5e6169c 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs @@ -65,7 +65,7 @@ public override void IndexAll() var taskDao = DaoFactory.GetTaskDao(); (int, int, int) getCount(DateTime lastIndexed) - { + { var q = taskDao.CRMDbContext.Tasks .Where(r => r.LastModifedOn >= lastIndexed); @@ -82,7 +82,7 @@ List getData(long i, long step, DateTime lastIndexed) => .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) .ToList(); - + try { foreach (var data in Indexer.IndexAll(getCount, getData)) diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs index 6b1b3bc4b0c..d2db45fc9ae 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs @@ -28,12 +28,10 @@ using System; using System.Collections.Generic; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; + using ASC.Common.Security; using ASC.Common.Security.Authorizing; -using ASC.Core; -using Action = ASC.Common.Security.Authorizing.Action; +using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; #endregion @@ -62,7 +60,7 @@ public ISecurityObjectId InheritFrom(ISecurityObjectId objectId) contactId = eventObj.ContactID; entityId = eventObj.EntityID; entityType = eventObj.EntityType; - + } else { @@ -72,31 +70,31 @@ public ISecurityObjectId InheritFrom(ISecurityObjectId objectId) if (entityId == 0 && contactId == 0) return null; if (entityId == 0) - return new Company + return new Company { ID = contactId, CompanyName = "fakeCompany" }; - - // return _daoFactory.GetContactDao().GetByID(contactId); + + // return _daoFactory.GetContactDao().GetByID(contactId); switch (entityType) { case EntityType.Opportunity: return new Deal - { - ID = entityId, - Title = "fakeDeal" - }; - // return _daoFactory.GetDealDao().GetByID(entityId); + { + ID = entityId, + Title = "fakeDeal" + }; + // return _daoFactory.GetDealDao().GetByID(entityId); case EntityType.Case: return new Cases - { - ID = entityId, - Title = "fakeCases" - }; - // return _daoFactory.GetCasesDao().GetByID(entityId); + { + ID = entityId, + Title = "fakeCases" + }; + // return _daoFactory.GetCasesDao().GetByID(entityId); } return null; @@ -114,10 +112,10 @@ public bool ObjectRolesSupported public IEnumerable GetObjectRoles(ISubject account, ISecurityObjectId objectId, SecurityCallContext callContext) { - - // Constants.Everyone - // if (_daoFactory.GetManagerDao().GetAll(false).Contains(ASC.Core.CoreContext.UserManager.GetUsers(account.ID))) - // return new Action[] + + // Constants.Everyone + // if (_daoFactory.GetManagerDao().GetAll(false).Contains(ASC.Core.CoreContext.UserManager.GetUsers(account.ID))) + // return new Action[] throw new NotImplementedException(); } } diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 36402e6a45c..bdd9f23f580 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -24,13 +24,17 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security; + using ASC.Common; using ASC.Common.Security; using ASC.Common.Security.Authorizing; using ASC.Core; using ASC.Core.Users; using ASC.CRM.Core.Dao; -using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; @@ -40,12 +44,9 @@ using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; using ASC.Web.CRM.Configuration; -using ASC.Web.CRM.Core; + using Autofac; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security; + using Action = ASC.Common.Security.Authorizing.Action; using Constants = ASC.Core.Users.Constants; using SecurityContext = ASC.Core.SecurityContext; @@ -778,56 +779,56 @@ public IEnumerable FilterRead(IEnumerable tasks) .Distinct() .ToList(); - if (contactIDs.Any()) - { - contactIDs = DaoFactory.GetContactDao() - .GetContacts(contactIDs.ToArray()) - .Select(x => x.ID) - .ToList(); + if (contactIDs.Any()) + { + contactIDs = DaoFactory.GetContactDao() + .GetContacts(contactIDs.ToArray()) + .Select(x => x.ID) + .ToList(); - result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); + result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); - if (!result.Any()) return Enumerable.Empty(); - } + if (!result.Any()) return Enumerable.Empty(); + } - var casesIds = result.Where(x => x.EntityType == EntityType.Case && x.ResponsibleID != SecurityContext.CurrentAccount.ID) - .Select(x => x.EntityID) - .Distinct() - .ToList(); + var casesIds = result.Where(x => x.EntityType == EntityType.Case && x.ResponsibleID != SecurityContext.CurrentAccount.ID) + .Select(x => x.EntityID) + .Distinct() + .ToList(); - if (casesIds.Any()) - { - casesIds = DaoFactory.GetCasesDao() - .GetCases(casesIds.ToArray()) - .Select(x => x.ID) - .ToList(); + if (casesIds.Any()) + { + casesIds = DaoFactory.GetCasesDao() + .GetCases(casesIds.ToArray()) + .Select(x => x.ID) + .ToList(); - result = result.Where(x => x.EntityID == 0 || casesIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); + result = result.Where(x => x.EntityID == 0 || casesIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); - if (!result.Any()) return Enumerable.Empty(); - } + if (!result.Any()) return Enumerable.Empty(); + } + + var dealsIds = result.Where(x => x.EntityType == EntityType.Opportunity && x.ResponsibleID != SecurityContext.CurrentAccount.ID) + .Select(x => x.EntityID) + .Distinct() + .ToList(); - var dealsIds = result.Where(x => x.EntityType == EntityType.Opportunity && x.ResponsibleID != SecurityContext.CurrentAccount.ID) - .Select(x => x.EntityID) - .Distinct() - .ToList(); + if (dealsIds.Any()) + { + dealsIds = DaoFactory.GetDealDao() + .GetDeals(dealsIds.ToArray()) + .Select(x => x.ID) + .ToList(); - if (dealsIds.Any()) - { - dealsIds = DaoFactory.GetDealDao() - .GetDeals(dealsIds.ToArray()) - .Select(x => x.ID) - .ToList(); + result = result + .Where(x => x.EntityID == 0 || dealsIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID) + .ToList(); - result = result - .Where(x => x.EntityID == 0 || dealsIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID) - .ToList(); + if (!result.Any()) return Enumerable.Empty(); + } - if (!result.Any()) return Enumerable.Empty(); - } + return result; - return result; - } @@ -859,5 +860,5 @@ public bool CanGoToFeed(Task task) { return IsAdmin || task.ResponsibleID == SecurityContext.CurrentAccount.ID || task.CreateBy == SecurityContext.CurrentAccount.ID; } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index d3216be0f52..320a50552aa 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -27,11 +27,12 @@ using System; using System.Collections.Generic; using System.Linq; + using ASC.CRM.Core.Dao; using ASC.Files.Core; using ASC.Files.Core.Security; -using ASC.Web.CRM.Core; using ASC.Web.Files.Api; + using Autofac; namespace ASC.CRM.Core @@ -76,8 +77,8 @@ public bool CanReview(FileEntry entry, Guid userId) public bool CanDelete(FileEntry entry, Guid userId) { return CanEdit(entry, userId); - } - + } + public bool CanEdit(FileEntry entry, Guid userId) { return diff --git a/products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs deleted file mode 100644 index b92df989c21..00000000000 --- a/products/ASC.CRM/Server/Helpers/ContactInfoDtoHelper.cs +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common; -using ASC.CRM.Core; - -namespace ASC.CRM.ApiModels -{ - [Scope] - public class ContactInfoDtoHelper - { - public ContactInfoDtoHelper() - { - } - - public ContactInfoDto Get(ContactInfo contactInfo) - { - if (contactInfo == null) return null; - - return new ContactInfoDto - { - InfoType = contactInfo.InfoType, - Category = contactInfo.Category, - CategoryName = contactInfo.CategoryToString(), - Data = contactInfo.Data, - IsPrimary = contactInfo.IsPrimary, - Id = contactInfo.ID - }; - } - - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs deleted file mode 100644 index d712023a10a..00000000000 --- a/products/ASC.CRM/Server/Helpers/CurrencyInfoDtoHelper.cs +++ /dev/null @@ -1,54 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common; -using ASC.CRM.Core; - -namespace ASC.CRM.ApiModels -{ - [Singletone] - public class CurrencyInfoDtoHelper - { - public CurrencyInfoDtoHelper() - { - } - - public CurrencyInfoDto Get(CurrencyInfo currencyInfo) - { - if (currencyInfo == null) return null; - - return new CurrencyInfoDto - { - Abbreviation = currencyInfo.Abbreviation, - CultureName = currencyInfo.CultureName, - Symbol = currencyInfo.Symbol, - Title = currencyInfo.Title, - IsConvertable = currencyInfo.IsConvertable, - IsBasic = currencyInfo.IsBasic - }; - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs deleted file mode 100644 index 825db22db3d..00000000000 --- a/products/ASC.CRM/Server/Helpers/CurrencyRateDtoHelper.cs +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common; -using ASC.CRM.Core; - -namespace ASC.CRM.ApiModels -{ - [Scope] - public class CurrencyRateDtoHelper - { - public CurrencyRateDtoHelper() - { - } - - public CurrencyRateDto Get(CurrencyRate currencyRate) - { - return new CurrencyRateDto - { - FromCurrency = currencyRate.FromCurrency, - ToCurrency = currencyRate.ToCurrency, - Rate = currencyRate.Rate - }; - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs index bc52d3c97c3..26f2e75ef42 100644 --- a/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs +++ b/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs @@ -27,21 +27,23 @@ using ASC.Common; using ASC.CRM.Core; +using AutoMapper; + namespace ASC.CRM.ApiModels { [Scope] public class CurrencyRateInfoDtoHelper { - public CurrencyRateInfoDtoHelper(CurrencyInfoDtoHelper currencyInfoDtoHelper) + private IMapper _mapper; + + public CurrencyRateInfoDtoHelper(IMapper mapper) { - CurrencyInfoDtoHelper = currencyInfoDtoHelper; + _mapper = mapper; } - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper; - public CurrencyRateInfoDto Get(CurrencyInfo currencyInfo, decimal rate) { - var currencyInfoDto = CurrencyInfoDtoHelper.Get(currencyInfo); + var currencyInfoDto = _mapper.Map(currencyInfo); return new CurrencyRateInfoDto { diff --git a/products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs b/products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs deleted file mode 100644 index b2ff6f772e8..00000000000 --- a/products/ASC.CRM/Server/Helpers/InvoiceBaseDtoHelper.cs +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - -using ASC.Api.Core; -using ASC.Common; -using ASC.Core.Common.Settings; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.Web.Api.Models; -using ASC.Web.CRM.Classes; - -using System; - -namespace ASC.CRM.ApiModels -{ - [Scope] - public class InvoiceBaseDtoHelper - { - private EntityDtoHelper _entityDtoHelper; - private ContactDtoHelper _contactDtoHelper; - private CurrencyInfoDtoHelper _currencyInfoDtoHelper; - private InvoiceStatusDtoHelper _invoiceStatusDtoHelper; - private CurrencyProvider _currencyProvider; - private SettingsManager _settingsManager; - private CRMSecurity CRMSecurity; - private ApiDateTimeHelper _apiDateTimeHelper; - private EmployeeWraperHelper _employeeWraperHelper; - private DaoFactory _daoFactory; - - public InvoiceBaseDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - SettingsManager settingsManager, - CurrencyProvider currencyProvider, - InvoiceStatusDtoHelper invoiceStatusDtoHelper, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - DaoFactory daoFactory, - ContactDtoHelper contactDtoHelper, - EntityDtoHelper entityDtoHelper) - { - _apiDateTimeHelper = apiDateTimeHelper; - _employeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - _settingsManager = settingsManager; - _currencyProvider = currencyProvider; - _invoiceStatusDtoHelper = invoiceStatusDtoHelper; - _daoFactory = daoFactory; - _currencyInfoDtoHelper = currencyInfoDtoHelper; - _contactDtoHelper = contactDtoHelper; - _entityDtoHelper = entityDtoHelper; - } - - public InvoiceBaseDto Get(Invoice invoice) - { - - var result = new InvoiceBaseDto - { - Id = invoice.ID, - Status = _invoiceStatusDtoHelper.Get(invoice.Status), - Number = invoice.Number, - IssueDate = _apiDateTimeHelper.Get(invoice.IssueDate), - TemplateType = invoice.TemplateType, - DueDate = _apiDateTimeHelper.Get(invoice.DueDate), - Currency = !String.IsNullOrEmpty(invoice.Currency) ? - _currencyInfoDtoHelper.Get(_currencyProvider.Get(invoice.Currency)) : - _currencyInfoDtoHelper.Get(_settingsManager.Load().DefaultCurrency), - ExchangeRate = invoice.ExchangeRate, - Language = invoice.Language, - PurchaseOrderNumber = invoice.PurchaseOrderNumber, - Terms = invoice.Terms, - Description = invoice.Description, - FileID = invoice.FileID, - CreateOn = _apiDateTimeHelper.Get(invoice.CreateOn), - CreateBy = _employeeWraperHelper.Get(invoice.CreateBy), - CanEdit = CRMSecurity.CanEdit(invoice), - CanDelete = CRMSecurity.CanDelete(invoice) - }; - - if (invoice.ContactID > 0) - { - result.Contact = _contactDtoHelper.GetContactBaseWithEmailDto(_daoFactory.GetContactDao().GetByID(invoice.ContactID)); - } - - if (invoice.ConsigneeID > 0) - { - result.Consignee = _contactDtoHelper.GetContactBaseWithEmailDto(_daoFactory.GetContactDao().GetByID(invoice.ConsigneeID)); - } - - if (invoice.EntityID > 0) - { - result.Entity = _entityDtoHelper.Get(invoice.EntityType, invoice.EntityID); - } - - result.Cost = invoice.GetInvoiceCost(_daoFactory); - - return result; - - } - } -} diff --git a/products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs b/products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs deleted file mode 100644 index 73a865fd18c..00000000000 --- a/products/ASC.CRM/Server/Helpers/InvoiceLineDtoHelper.cs +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - -using ASC.Common; -using ASC.CRM.Core.Entities; - -namespace ASC.CRM.ApiModels -{ - [Singletone] - public class InvoiceLineDtoHelper - { - public InvoiceLineDtoHelper() - { - } - - public InvoiceLineDto Get(InvoiceLine invoiceLine) - { - return new InvoiceLineDto - { - Id = invoiceLine.ID, - InvoiceID = invoiceLine.InvoiceID, - InvoiceItemID = invoiceLine.InvoiceItemID, - InvoiceTax1ID = invoiceLine.InvoiceTax1ID, - InvoiceTax2ID = invoiceLine.InvoiceTax2ID, - SortOrder = invoiceLine.SortOrder, - Description = invoiceLine.Description, - Quantity = invoiceLine.Quantity, - Price = invoiceLine.Price, - Discount = invoiceLine.Discount - }; - } - } -} diff --git a/products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs b/products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs deleted file mode 100644 index 763a1ecf32e..00000000000 --- a/products/ASC.CRM/Server/Helpers/InvoiceStatusDtoHelper.cs +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - -using ASC.Common; -using ASC.CRM.Classes; -using ASC.CRM.Core.Enums; - -namespace ASC.CRM.ApiModels -{ - [Singletone] - public class InvoiceStatusDtoHelper - { - public InvoiceStatusDtoHelper() - { - } - - public InvoiceStatusDto Get(InvoiceStatus status) - { - return new InvoiceStatusDto - { - Id = (int)status, - Title = status.ToLocalizedString() - }; - } - } -} diff --git a/products/ASC.CRM/Server/Helpers/OpportunityDtoHelper.cs b/products/ASC.CRM/Server/Helpers/OpportunityDtoHelper.cs deleted file mode 100644 index 4a8cb7f956c..00000000000 --- a/products/ASC.CRM/Server/Helpers/OpportunityDtoHelper.cs +++ /dev/null @@ -1,130 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Api.Core; -using ASC.Common; -using ASC.Common.Web; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; -using ASC.Web.Api.Models; -using ASC.Web.CRM.Classes; - -using System.Collections.Generic; -using System.Linq; - -namespace ASC.CRM.ApiModels -{ - [Scope] - public class OpportunityDtoHelper - { - public OpportunityDtoHelper(ApiDateTimeHelper apiDateTimeHelper, - EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, - DaoFactory daoFactory, - CurrencyProvider currencyProvider, - ContactDtoHelper contactBaseDtoHelper, - CurrencyInfoDtoHelper currencyInfoDtoHelper - ) - { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeWraperHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - DaoFactory = daoFactory; - ContactBaseDtoHelper = contactBaseDtoHelper; - CurrencyProvider = currencyProvider; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - } - - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper; - public CurrencyProvider CurrencyProvider; - public ContactDtoHelper ContactBaseDtoHelper; - public DaoFactory DaoFactory; - public CRMSecurity CRMSecurity; - public ApiDateTimeHelper ApiDateTimeHelper; - public EmployeeWraperHelper EmployeeWraperHelper; - - public OpportunityDto Get(Deal deal) - { - var dealDto = new OpportunityDto - { - Id = deal.ID, - CreateBy = EmployeeWraperHelper.Get(deal.CreateBy), - Created = ApiDateTimeHelper.Get(deal.CreateOn), - Title = deal.Title, - Description = deal.Description, - Responsible = EmployeeWraperHelper.Get(deal.ResponsibleID), - BidType = deal.BidType, - BidValue = deal.BidValue, - PerPeriodValue = deal.PerPeriodValue, - SuccessProbability = deal.DealMilestoneProbability, - ActualCloseDate = ApiDateTimeHelper.Get(deal.ActualCloseDate), - ExpectedCloseDate = ApiDateTimeHelper.Get(deal.ExpectedCloseDate), - CanEdit = CRMSecurity.CanEdit(deal) - }; - - if (deal.ContactID > 0) - dealDto.Contact = ContactBaseDtoHelper.GetContactBaseDto(DaoFactory.GetContactDao().GetByID(deal.ContactID)); - - if (deal.DealMilestoneID > 0) - { - var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); - - if (dealMilestone == null) - throw new ItemNotFoundException(); - - dealDto.Stage = new DealMilestoneBaseDto(dealMilestone); - } - - dealDto.AccessList = CRMSecurity.GetAccessSubjectTo(deal) - .Select(item => EmployeeWraperHelper.Get(item.Key)); - - dealDto.IsPrivate = CRMSecurity.IsPrivate(deal); - - if (!string.IsNullOrEmpty(deal.BidCurrency)) - dealDto.BidCurrency = CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(deal.BidCurrency)); - - dealDto.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseDto(item)); - - dealDto.Members = new List(); - - var memberIDs = DaoFactory.GetDealDao().GetMembers(deal.ID); - var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs); - var membersDtoList = new List(); - - foreach (var member in membersList) - { - if (member == null) continue; - membersDtoList.Add(ContactBaseDtoHelper.GetContactBaseDto(member)); - } - - dealDto.Members = membersDtoList; - - return dealDto; - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs b/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs index 2e12ab2b8ff..76b397e2e4e 100644 --- a/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs +++ b/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs @@ -24,20 +24,20 @@ */ +using System.Linq; + using ASC.Api.Core; using ASC.Common; using ASC.VoipService; using ASC.Web.Api.Models; -using System.Linq; - namespace ASC.CRM.ApiModels { [Scope] public class VoipCallDtoHelper { - private ApiDateTimeHelper _apiDateTimeHelper; - private EmployeeWraperHelper _employeeWraperHelper; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; public VoipCallDtoHelper(EmployeeWraperHelper employeeWraper, ApiDateTimeHelper apiDateTimeHelper) diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs index 0c6401ddffb..86f99e2b2f8 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs @@ -37,7 +37,6 @@ using ASC.Web.Core.Files; using ASC.Web.Core.Utility; using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Configuration; using ASC.Web.Studio.Core; using Microsoft.AspNetCore.Builder; @@ -69,9 +68,9 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, // throw cRMSecurity.CreateSecurityException(); context.Request.EnableBuffering(); - + var contactId = Convert.ToInt32(context.Request.Form["contactID"]); - + Contact contact = null; if (contactId != 0) @@ -144,9 +143,9 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, if (contact != null) { var messageAction = contact is Company ? MessageAction.CompanyUpdatedPhoto : MessageAction.PersonUpdatedPhoto; - + messageService.Send(messageAction, messageTarget.Create(contact.ID), contact.GetTitle()); - + } await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs index abc7d10da57..23433df7bd0 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs @@ -24,17 +24,15 @@ */ -using ASC.Common; -using ASC.Common.Logging; +using System; +using System.IO; +using System.Threading.Tasks; + using ASC.CRM.Resources; using ASC.Web.CRM.Classes; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Options; -using System; -using System.IO; -using System.Threading.Tasks; namespace ASC.Web.CRM.HttpHandlers { @@ -46,11 +44,11 @@ public FileHandlerMiddleware(RequestDelegate next) { _next = next; } - + public async Task Invoke(HttpContext context, Global global, ContactPhotoManager contactPhotoManager) - { + { context.Request.EnableBuffering(); var action = context.Request.Query["action"]; @@ -58,51 +56,51 @@ public async Task Invoke(HttpContext context, switch (action) { case "contactphotoulr": - { - var contactId = Convert.ToInt32(context.Request.Query["cid"]); - var isCompany = Convert.ToBoolean(context.Request.Query["isc"]); - var photoSize = Convert.ToInt32(context.Request.Query["ps"]); + { + var contactId = Convert.ToInt32(context.Request.Query["cid"]); + var isCompany = Convert.ToBoolean(context.Request.Query["isc"]); + var photoSize = Convert.ToInt32(context.Request.Query["ps"]); string photoUrl; switch (photoSize) - { - case 1: - photoUrl = contactPhotoManager.GetSmallSizePhoto(contactId, isCompany); - break; - case 2: - photoUrl = contactPhotoManager.GetMediumSizePhoto(contactId, isCompany); - break; - case 3: - photoUrl = contactPhotoManager.GetBigSizePhoto(contactId, isCompany); - break; - default: - throw new Exception(CRMErrorsResource.ContactPhotoSizeUnknown); - } - - context.Response.Clear(); - - await context.Response.WriteAsync(photoUrl); - } - break; - case "mailmessage": { - var messageId = Convert.ToInt32(context.Request.Query["message_id"]); + case 1: + photoUrl = contactPhotoManager.GetSmallSizePhoto(contactId, isCompany); + break; + case 2: + photoUrl = contactPhotoManager.GetMediumSizePhoto(contactId, isCompany); + break; + case 3: + photoUrl = contactPhotoManager.GetBigSizePhoto(contactId, isCompany); + break; + default: + throw new Exception(CRMErrorsResource.ContactPhotoSizeUnknown); + } - var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); + context.Response.Clear(); - string messageContent = string.Empty; + await context.Response.WriteAsync(photoUrl); + } + break; + case "mailmessage": + { + var messageId = Convert.ToInt32(context.Request.Query["message_id"]); - using (var streamReader = new StreamReader(global.GetStore().GetReadStream("mail_messages", filePath))) - { - messageContent = streamReader.ReadToEnd(); - } + var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId); - context.Response.Clear(); + string messageContent = string.Empty; - await context.Response.WriteAsync(messageContent); + using (var streamReader = new StreamReader(global.GetStore().GetReadStream("mail_messages", filePath))) + { + messageContent = streamReader.ReadToEnd(); } - break; + + context.Response.Clear(); + + await context.Response.WriteAsync(messageContent); + } + break; default: throw new ArgumentException(String.Format("action='{0}' is not defined", action)); } diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs index 0e550a3abd1..551241a10b4 100644 --- a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs @@ -24,19 +24,21 @@ */ +using System; +using System.Text.Json; +using System.Threading.Tasks; + using ASC.CRM.Core.Dao; using ASC.CRM.Resources; using ASC.Files.Core; +using ASC.Web.Core.Utility; using ASC.Web.Studio.Core; using ASC.Web.Studio.UserControls.Statistics; using ASC.Web.Studio.Utility; + +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using System; using Microsoft.Extensions.DependencyInjection; -using ASC.Web.Core.Utility; -using Microsoft.AspNetCore.Builder; -using System.Threading.Tasks; -using System.Text.Json; namespace ASC.Web.CRM.HttpHandlers { @@ -67,16 +69,16 @@ public async Task InvokeAsync(HttpContext context, var fileName = context.Request.Form.Files[0].FileName; var contentLength = context.Request.Form.Files[0].Length; - + if (String.IsNullOrEmpty(fileName) || contentLength == 0) throw new InvalidOperationException(CRMErrorsResource.InvalidFile); if (0 < setupInfo.MaxUploadSize(tenantExtra, tenantStatisticsProvider) && setupInfo.MaxUploadSize(tenantExtra, tenantStatisticsProvider) < contentLength) throw fileSizeComment.FileSizeException; - fileName = fileName.LastIndexOf('\\') != -1 - ? fileName.Substring(fileName.LastIndexOf('\\') + 1) - : fileName; + fileName = fileName.LastIndexOf('\\') != -1 + ? fileName.Substring(fileName.LastIndexOf('\\') + 1) + : fileName; var document = serviceProvider.GetService>(); diff --git a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs index 3c1dea2871f..b54d196dec8 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs @@ -24,6 +24,10 @@ */ +using System; +using System.Text.Json; +using System.Threading.Tasks; + using ASC.CRM.Core; using ASC.Web.Core; using ASC.Web.Core.Utility; @@ -33,10 +37,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using System; -using System.Text.Json; -using System.Threading.Tasks; - namespace ASC.Web.CRM.HttpHandlers { public class ImportFileHandlerMiddleware @@ -49,7 +49,7 @@ public ImportFileHandlerMiddleware( _next = next; } - public async Task Invoke(HttpContext context, + public async Task Invoke(HttpContext context, WebItemSecurity webItemSecurity, CRMSecurity cRMSecurity, Global global, @@ -67,11 +67,11 @@ public async Task Invoke(HttpContext context, var fileName = context.Request.Form.Files[0].FileName; var contentLength = context.Request.Form.Files[0].Length; - + String assignedPath; global.GetStore().SaveTemp("temp", out assignedPath, context.Request.Form.Files[0].OpenReadStream()); - + var jObject = importFromCSV.GetInfo(context.Request.Form.Files[0].OpenReadStream(), context.Request.Form["importSettings"]); jObject.Add("assignedPath", assignedPath); diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs index 62c9824535d..3f5cb79c63e 100644 --- a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs @@ -24,7 +24,9 @@ */ -using ASC.Common.Web; +using System; +using System.Text.Json; + using ASC.CRM.Core; using ASC.CRM.Resources; using ASC.Web.Core.Files; @@ -35,10 +37,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -using System; -using System.IO; -using System.Text.Json; - namespace ASC.Web.CRM.HttpHandlers { public class OrganisationLogoHandlerMiddleware diff --git a/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs b/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs index 2caca450d47..3b3f07c7f2e 100644 --- a/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs +++ b/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs @@ -28,7 +28,7 @@ namespace ASC.CRM.Mapping { public interface IMapFrom - { + { void Mapping(Profile profile) => profile.CreateMap(typeof(T), GetType()); } } diff --git a/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs b/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs index 7847a48360f..f63b8d384ab 100644 --- a/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs +++ b/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs @@ -41,7 +41,7 @@ public MappingProfile() private void ApplyMappingsFromAssembly(Assembly assembly) { var types = assembly.GetExportedTypes() - .Where(t => t.GetInterfaces().Any(i => + .Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>))) .ToList(); @@ -49,9 +49,9 @@ private void ApplyMappingsFromAssembly(Assembly assembly) { var instance = Activator.CreateInstance(type); - var methodInfo = type.GetMethod("Mapping") + var methodInfo = type.GetMethod("Mapping") ?? type.GetInterface("IMapFrom`1").GetMethod("Mapping"); - + methodInfo?.Invoke(instance, new object[] { this }); } diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs index 7f11135c59c..04aefac9570 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs @@ -43,7 +43,6 @@ namespace ASC.CRM.Mapping { public class CasesDtoTypeConverter : ITypeConverter { - private readonly ContactDtoHelper _contactBaseDtoHelper; private readonly DaoFactory _daoFactory; private readonly CRMSecurity _CRMSecurity; private readonly ApiDateTimeHelper _apiDateTimeHelper; @@ -52,14 +51,12 @@ public class CasesDtoTypeConverter : ITypeConverter public CasesDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, CRMSecurity cRMSecurity, - DaoFactory daoFactory, - ContactDtoHelper contactBaseDtoHelper) + DaoFactory daoFactory) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; _CRMSecurity = cRMSecurity; _daoFactory = daoFactory; - _contactBaseDtoHelper = contactBaseDtoHelper; } public CasesDto Convert(Cases source, CasesDto destination, ResolutionContext context) @@ -99,7 +96,7 @@ public CasesDto Convert(Cases source, CasesDto destination, ResolutionContext co { if (member == null) continue; - membersDtoList.Add(_contactBaseDtoHelper.GetContactBaseDto(member)); + membersDtoList.Add(context.Mapper.Map(member)); } result.Members = membersDtoList; diff --git a/products/ASC.CRM/Server/Helpers/ContactDtoHelper.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs similarity index 56% rename from products/ASC.CRM/Server/Helpers/ContactDtoHelper.cs rename to products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs index c74961e8a37..33659d1591e 100644 --- a/products/ASC.CRM/Server/Helpers/ContactDtoHelper.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs @@ -24,9 +24,14 @@ */ +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Api.Core; using ASC.Common; using ASC.Common.Web; +using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -35,104 +40,225 @@ using ASC.Web.CRM; using ASC.Web.CRM.Classes; -using System; -using System.Collections.Generic; -using System.Linq; +using AutoMapper; using Contact = ASC.CRM.Core.Entities.Contact; -namespace ASC.CRM.ApiModels +namespace ASC.CRM.Mapping { - [Scope] - public class ContactDtoHelper + public class ContactDtoTypeConverter : ITypeConverter, + ITypeConverter, List>, + ITypeConverter, + ITypeConverter, + ITypeConverter, + ITypeConverter, + ITypeConverter + + { - public ContactDtoHelper(ApiDateTimeHelper apiDateTimeHelper, + private readonly DaoFactory _daoFactory; + private readonly CRMSecurity _crmSecurity; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeDtoHelper; + private readonly CurrencyProvider _currencyProvider; + private readonly PathProvider _pathProvider; + + public ContactDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, CurrencyProvider currencyProvider, PathProvider pathProvider, - CurrencyInfoDtoHelper currencyInfoDtoHelper, - DaoFactory daoFactory, - ContactInfoDtoHelper contactInfoDtoHelper) + DaoFactory daoFactory) { - ApiDateTimeHelper = apiDateTimeHelper; - EmployeeDtoHelper = employeeWraperHelper; - CRMSecurity = cRMSecurity; - CurrencyProvider = currencyProvider; - PathProvider = pathProvider; - CurrencyInfoDtoHelper = currencyInfoDtoHelper; - DaoFactory = daoFactory; - ContactInfoDtoHelper = contactInfoDtoHelper; + _apiDateTimeHelper = apiDateTimeHelper; + _employeeDtoHelper = employeeWraperHelper; + _crmSecurity = crmSecurity; + _currencyProvider = currencyProvider; + _pathProvider = pathProvider; + _daoFactory = daoFactory; } - public ContactInfoDtoHelper ContactInfoDtoHelper; - public DaoFactory DaoFactory; - public CurrencyInfoDtoHelper CurrencyInfoDtoHelper; - public CRMSecurity CRMSecurity; - public ApiDateTimeHelper ApiDateTimeHelper; - public EmployeeWraperHelper EmployeeDtoHelper; - public CurrencyProvider CurrencyProvider; - public PathProvider PathProvider; - public ContactBaseDto GetContactBaseDtoQuick(Contact contact) + + public ContactDto Convert(Contact source, ContactDto destination, ResolutionContext context) + { + ContactDto result; + + var person = source as Person; + + if (person != null) + { + var peopleDto = (PersonDto)context.Mapper.Map(source); + + peopleDto.FirstName = person.FirstName; + peopleDto.LastName = person.LastName; + peopleDto.Title = person.JobTitle; + + if (person.CompanyID > 0) + { + peopleDto.Company = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(person.CompanyID)); + } + + result = peopleDto; + } + else + { + var company = source as Company; + + if (company != null) + { + result = (CompanyDto)context.Mapper.Map(source); + ((CompanyDto)result).CompanyName = company.CompanyName; + ((CompanyDto)result).PersonsCount = _daoFactory.GetContactDao().GetMembersCount(result.Id); + } + else throw new ArgumentException(); + } + + if (source.StatusID > 0) + { + var listItem = _daoFactory.GetListItemDao().GetByID(source.StatusID); + if (listItem == null) throw new ItemNotFoundException(); + + result.ContactStatus = new ContactStatusBaseDto(listItem); + } + + result.TaskCount = _daoFactory.GetTaskDao().GetTasksCount(source.ID); + result.HaveLateTasks = _daoFactory.GetTaskDao().HaveLateTask(source.ID); + + var contactInfos = new List(); + var addresses = new List
    (); + + var data = _daoFactory.GetContactInfoDao().GetList(source.ID, null, null, null); + + foreach (var contactInfo in data) + { + if (contactInfo.InfoType == ContactInfoType.Address) + { + addresses.Add(new Address(contactInfo)); + } + else + { + contactInfos.Add(context.Mapper.Map(contactInfo)); + } + } + + result.Addresses = addresses; + result.CommonData = contactInfos; + + result.CustomFields = _daoFactory.GetCustomFieldDao() + .GetEnityFields(source is Person ? EntityType.Person : EntityType.Company, source.ID, false) + .ConvertAll(item => new CustomFieldBaseDto(item)); + return result; + } + + public ContactBaseDto Convert(Contact source, ContactBaseDto destination, ResolutionContext context) { ContactBaseDto result; - if (contact is Company) + if (source is Company) result = new CompanyDto(); else result = new PersonDto(); - result.Id = contact.ID; - result.DisplayName = contact.GetTitle(); - result.IsPrivate = CRMSecurity.IsPrivate(contact); - result.IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read; - result.ShareType = contact.ShareType; - result.Currency = !String.IsNullOrEmpty(contact.Currency) ? - CurrencyInfoDtoHelper.Get(CurrencyProvider.Get(contact.Currency)) : null; - result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); - result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower(); - result.IsCompany = contact is Company; - result.CanEdit = CRMSecurity.CanEdit(contact); - // CanDelete = CRMSecurity.CanDelete(contact), + result.Id = source.ID; + result.DisplayName = source.GetTitle(); + result.IsPrivate = _crmSecurity.IsPrivate(source); + result.IsShared = source.ShareType == ShareType.ReadWrite || source.ShareType == ShareType.Read; + result.ShareType = source.ShareType; + + result.Currency = !String.IsNullOrEmpty(source.Currency) ? + context.Mapper.Map(_currencyProvider.Get(source.Currency)) : null; + + + result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", _pathProvider.BaseAbsolutePath, source.ID, source is Company).ToLower(); + result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", _pathProvider.BaseAbsolutePath, source.ID, source is Company).ToLower(); + result.IsCompany = source is Company; + result.CanEdit = _crmSecurity.CanEdit(source); + result.CanDelete = _crmSecurity.CanDelete(source); if (result.IsPrivate) { - result.AccessList = CRMSecurity.GetAccessSubjectTo(contact) - .Select(item => EmployeeDtoHelper.Get(item.Key)); + result.AccessList = _crmSecurity.GetAccessSubjectTo(source) + .Select(item => _employeeDtoHelper.Get(item.Key)); } return result; } - public ContactDto ToContactDto(Contact contact) + public PersonDto Convert(Person source, PersonDto destination, ResolutionContext context) { - return ToListContactDto(new List - { - contact - }).Single(); + var result = (PersonDto)context.Mapper.Map(source); + + result.CreateBy = _employeeDtoHelper.Get(source.CreateBy); + result.Created = _apiDateTimeHelper.Get(source.CreateOn); + result.About = source.About; + result.Industry = source.Industry; + result.FirstName = source.FirstName; + result.LastName = source.LastName; + result.Title = source.JobTitle; + + return result; + } + + public CompanyDto Convert(Company source, CompanyDto destination, ResolutionContext context) + { + var result = (CompanyDto)context.Mapper.Map(source); + + result.CompanyName = source.CompanyName; + + result.CreateBy = _employeeDtoHelper.Get(source.CreateBy); + result.Created = _apiDateTimeHelper.Get(source.CreateOn); + result.About = source.About; + result.Industry = source.Industry; + + return result; + } + + public ContactBaseWithPhoneDto Convert(Contact source, ContactBaseWithPhoneDto destination, ResolutionContext context) + { + if (source == null) return null; + + var result = (ContactBaseWithPhoneDto)context.Mapper.Map(source); + + var phone = _daoFactory.GetContactInfoDao().GetList(source.ID, ContactInfoType.Phone, null, true).FirstOrDefault(); + + result.Phone = context.Mapper.Map(phone); + + return result; + } + + public ContactBaseWithEmailDto Convert(Contact source, ContactBaseWithEmailDto destination, ResolutionContext context) + { + if (source == null) return null; + + var result = (ContactBaseWithEmailDto)context.Mapper.Map(source); + var email = _daoFactory.GetContactInfoDao().GetList(source.ID, ContactInfoType.Email, null, true).FirstOrDefault(); + + result.Email = context.Mapper.Map(email); + + return result; } - public IEnumerable ToListContactDto(IReadOnlyList itemList) + public List Convert(List source, List destination, ResolutionContext context) { - if (itemList.Count == 0) return new List(); + if (source.Count == 0) return new List(); var result = new List(); var personsIDs = new List(); var companyIDs = new List(); - var contactIDs = new int[itemList.Count]; + var contactIDs = new int[source.Count]; var peopleCompanyIDs = new List(); var peopleCompanyList = new Dictionary(); - var contactDao = DaoFactory.GetContactDao(); + var contactDao = _daoFactory.GetContactDao(); - for (var index = 0; index < itemList.Count; index++) + for (var index = 0; index < source.Count; index++) { - var contact = itemList[index]; + var contact = source[index]; if (contact is Company) { @@ -152,12 +278,12 @@ public IEnumerable ToListContactDto(IReadOnlyList itemList) } } - contactIDs[index] = itemList[index].ID; + contactIDs[index] = source[index].ID; } if (peopleCompanyIDs.Count > 0) { - var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => GetContactBaseDtoQuick(item)); + var tmpList = contactDao.GetContacts(peopleCompanyIDs.ToArray()).ConvertAll(item => context.Mapper.Map(item)); var tmpListCanDelete = contactDao.CanDelete(tmpList.Select(item => item.Id).ToArray()); foreach (var contactBaseDtoQuick in tmpList) @@ -169,26 +295,26 @@ public IEnumerable ToListContactDto(IReadOnlyList itemList) var companiesMembersCount = contactDao.GetMembersCount(companyIDs.Distinct().ToArray()); - var contactStatusIDs = itemList.Select(item => item.StatusID).Distinct().ToArray(); + var contactStatusIDs = source.Select(item => item.StatusID).Distinct().ToArray(); var contactInfos = new Dictionary>(); - var haveLateTask = DaoFactory.GetTaskDao().HaveLateTask(contactIDs); - var contactStatus = DaoFactory.GetListItemDao() + var haveLateTask = _daoFactory.GetTaskDao().HaveLateTask(contactIDs); + var contactStatus = _daoFactory.GetListItemDao() .GetItems(contactStatusIDs) .ToDictionary(item => item.ID, item => new ContactStatusBaseDto(item)); - var personsCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Person, personsIDs.ToArray()); - var companyCustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Company, companyIDs.ToArray()); + var personsCustomFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Person, personsIDs.ToArray()); + var companyCustomFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Company, companyIDs.ToArray()); var customFields = personsCustomFields.Union(companyCustomFields) .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); var addresses = new Dictionary>(); - var taskCount = DaoFactory.GetTaskDao().GetTasksCount(contactIDs); + var taskCount = _daoFactory.GetTaskDao().GetTasksCount(contactIDs); - var contactTags = DaoFactory.GetTagDao().GetEntitiesTags(EntityType.Contact); + var contactTags = _daoFactory.GetTagDao().GetEntitiesTags(EntityType.Contact); - DaoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( + _daoFactory.GetContactInfoDao().GetAll(contactIDs).ForEach( item => { if (item.InfoType == ContactInfoType.Address) @@ -201,15 +327,15 @@ public IEnumerable ToListContactDto(IReadOnlyList itemList) else { if (!contactInfos.ContainsKey(item.ContactID)) - contactInfos.Add(item.ContactID, new List { ContactInfoDtoHelper.Get(item) }); + contactInfos.Add(item.ContactID, new List { context.Mapper.Map(item) }); else - contactInfos[item.ContactID].Add(ContactInfoDtoHelper.Get(item)); + contactInfos[item.ContactID].Add(context.Mapper.Map(item)); } } ); - foreach (var contact in itemList) + foreach (var contact in source) { ContactDto contactDto; @@ -218,7 +344,7 @@ public IEnumerable ToListContactDto(IReadOnlyList itemList) { var people = person; - var peopleDto = GetPersonDtoQuick(people); + var peopleDto = context.Mapper.Map(people); if (people.CompanyID > 0 && peopleCompanyList.ContainsKey(people.CompanyID)) { @@ -232,7 +358,7 @@ public IEnumerable ToListContactDto(IReadOnlyList itemList) var company = contact as Company; if (company != null) { - contactDto = GetCompanyDtoQuick(company); + contactDto = context.Mapper.Map(company); if (companiesMembersCount.ContainsKey(contactDto.Id)) { @@ -286,139 +412,6 @@ public IEnumerable ToListContactDto(IReadOnlyList itemList) return result; } - - public ContactBaseDto GetContactBaseDto(Contact contact) - { - var result = GetContactBaseDtoQuick(contact); - - result.CanDelete = CRMSecurity.CanDelete(contact); - - return result; - } - - public ContactBaseWithPhoneDto GetContactBaseWithPhoneDto(Contact contact) - { - if (contact == null) return null; - - var result = (ContactBaseWithPhoneDto)GetContactBaseDto(contact); - - result.Phone = ContactInfoDtoHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Phone, null, true).FirstOrDefault()); - - return result; - } - - public ContactBaseWithEmailDto GetContactBaseWithEmailDto(Contact contact) - { - if (contact == null) return null; - - var result = (ContactBaseWithEmailDto)GetContactBaseDto(contact); - - result.Email = ContactInfoDtoHelper.Get(DaoFactory.GetContactInfoDao().GetList(contact.ID, ContactInfoType.Email, null, true).FirstOrDefault()); - - return result; - } - - public ContactDto GetContactDto(Contact contact) - { - ContactDto result; - - var person = contact as Person; - - if (person != null) - { - var peopleDto = (PersonDto)GetContactBaseDto(contact); - - peopleDto.FirstName = person.FirstName; - peopleDto.LastName = person.LastName; - peopleDto.Title = person.JobTitle; - - if (person.CompanyID > 0) - { - peopleDto.Company = GetContactBaseDto(DaoFactory.GetContactDao().GetByID(person.CompanyID)); - } - - result = peopleDto; - } - else - { - var company = contact as Company; - - if (company != null) - { - result = (CompanyDto)GetContactBaseDto(company); - ((CompanyDto)result).CompanyName = company.CompanyName; - ((CompanyDto)result).PersonsCount = DaoFactory.GetContactDao().GetMembersCount(result.Id); - } - else throw new ArgumentException(); - } - - if (contact.StatusID > 0) - { - var listItem = DaoFactory.GetListItemDao().GetByID(contact.StatusID); - if (listItem == null) throw new ItemNotFoundException(); - - result.ContactStatus = new ContactStatusBaseDto(listItem); - } - - result.TaskCount = DaoFactory.GetTaskDao().GetTasksCount(contact.ID); - result.HaveLateTasks = DaoFactory.GetTaskDao().HaveLateTask(contact.ID); - - var contactInfos = new List(); - var addresses = new List
    (); - - var data = DaoFactory.GetContactInfoDao().GetList(contact.ID, null, null, null); - - foreach (var contactInfo in data) - { - if (contactInfo.InfoType == ContactInfoType.Address) - { - addresses.Add(new Address(contactInfo)); - } - else - { - contactInfos.Add(ContactInfoDtoHelper.Get(contactInfo)); - } - } - - result.Addresses = addresses; - result.CommonData = contactInfos; - - result.CustomFields = DaoFactory.GetCustomFieldDao() - .GetEnityFields(contact is Person ? EntityType.Person : EntityType.Company, contact.ID, false) - .ConvertAll(item => new CustomFieldBaseDto(item)); - return result; - } - - - public CompanyDto GetCompanyDtoQuick(Company company) - { - var result = (CompanyDto)GetContactBaseDtoQuick(company); - - result.CompanyName = company.CompanyName; - - result.CreateBy = EmployeeDtoHelper.Get(company.CreateBy); - result.Created = ApiDateTimeHelper.Get(company.CreateOn); - result.About = company.About; - result.Industry = company.Industry; - - return result; - } - - public PersonDto GetPersonDtoQuick(Person person) - { - var result = (PersonDto)GetContactBaseDtoQuick(person); - - result.CreateBy = EmployeeDtoHelper.Get(person.CreateBy); - result.Created = ApiDateTimeHelper.Get(person.CreateOn); - result.About = person.About; - result.Industry = person.Industry; - - result.FirstName = person.FirstName; - result.LastName = person.LastName; - result.Title = person.JobTitle; - - return result; - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs new file mode 100644 index 00000000000..7cfb6abd38d --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs @@ -0,0 +1,116 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System; + +using ASC.Api.Core; +using ASC.Common; +using ASC.Core.Common.Settings; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + [Scope] + public class InvoiceBaseDtoTypeConverter : ITypeConverter + { + private readonly EntityDtoHelper _entityDtoHelper; + private readonly CurrencyProvider _currencyProvider; + private readonly SettingsManager _settingsManager; + private readonly CRMSecurity _crmSecurity; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly DaoFactory _daoFactory; + + public InvoiceBaseDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + DaoFactory daoFactory, + EntityDtoHelper entityDtoHelper) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _crmSecurity = cRMSecurity; + _settingsManager = settingsManager; + _currencyProvider = currencyProvider; + _daoFactory = daoFactory; + _entityDtoHelper = entityDtoHelper; + } + + public InvoiceBaseDto Convert(Invoice source, InvoiceBaseDto destination, ResolutionContext context) + { + var result = new InvoiceBaseDto + { + Id = source.ID, + Status = context.Mapper.Map(source.Status), + Number = source.Number, + IssueDate = _apiDateTimeHelper.Get(source.IssueDate), + TemplateType = source.TemplateType, + DueDate = _apiDateTimeHelper.Get(source.DueDate), + Currency = !String.IsNullOrEmpty(source.Currency) ? + context.Mapper.Map(_currencyProvider.Get(source.Currency)) : + context.Mapper.Map(_settingsManager.Load().DefaultCurrency), + ExchangeRate = source.ExchangeRate, + Language = source.Language, + PurchaseOrderNumber = source.PurchaseOrderNumber, + Terms = source.Terms, + Description = source.Description, + FileID = source.FileID, + CreateOn = _apiDateTimeHelper.Get(source.CreateOn), + CreateBy = _employeeWraperHelper.Get(source.CreateBy), + CanEdit = _crmSecurity.CanEdit(source), + CanDelete = _crmSecurity.CanDelete(source) + }; + + if (source.ContactID > 0) + { + result.Contact = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(source.ContactID)); + } + + if (source.ConsigneeID > 0) + { + result.Consignee = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(source.ConsigneeID)); + } + + if (source.EntityID > 0) + { + result.Entity = _entityDtoHelper.Get(source.EntityType, source.EntityID); + } + + result.Cost = source.GetInvoiceCost(_daoFactory); + + return result; + + } + } +} diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs new file mode 100644 index 00000000000..c3ac77dadc5 --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs @@ -0,0 +1,117 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + +using System; +using System.Linq; + +using ASC.Api.Core; +using ASC.Core.Common.Settings; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public class InvoiceDtoTypeConverter : ITypeConverter + { + private readonly DaoFactory _daoFactory; + private readonly CurrencyProvider _currencyProvider; + private readonly SettingsManager _settingsManager; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly CRMSecurity _crmSecurity; + private readonly EntityDtoHelper _entityDtoHelper; + + public InvoiceDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity crmSecurity, + SettingsManager settingsManager, + CurrencyProvider currencyProvider, + DaoFactory daoFactory, + EntityDtoHelper entityDtoHelper) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _crmSecurity = crmSecurity; + _settingsManager = settingsManager; + _currencyProvider = currencyProvider; + _daoFactory = daoFactory; + _entityDtoHelper = entityDtoHelper; + } + + + public InvoiceDto Convert(Invoice source, InvoiceDto destination, ResolutionContext context) + { + var result = new InvoiceDto + { + Id = source.ID, + Status = context.Mapper.Map(source.Status), + Number = source.Number, + IssueDate = _apiDateTimeHelper.Get(source.IssueDate), + TemplateType = source.TemplateType, + DueDate = _apiDateTimeHelper.Get(source.DueDate), + Currency = !String.IsNullOrEmpty(source.Currency) ? + context.Mapper.Map(_currencyProvider.Get(source.Currency)) : + context.Mapper.Map(_settingsManager.Load().DefaultCurrency), + ExchangeRate = source.ExchangeRate, + Language = source.Language, + PurchaseOrderNumber = source.PurchaseOrderNumber, + Terms = source.Terms, + Description = source.Description, + FileID = source.FileID, + CreateOn = _apiDateTimeHelper.Get(source.CreateOn), + CreateBy = _employeeWraperHelper.Get(source.CreateBy), + CanEdit = _crmSecurity.CanEdit(source), + CanDelete = _crmSecurity.CanDelete(source), + }; + + if (source.ContactID > 0) + { + result.Contact = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(source.ContactID)); + } + + if (source.ConsigneeID > 0) + { + result.Consignee = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(source.ConsigneeID)); + } + + if (source.EntityID > 0) + { + result.Entity = _entityDtoHelper.Get(source.EntityType, source.EntityID); + } + + result.Cost = source.GetInvoiceCost(_daoFactory); + + result.InvoiceLines = source.GetInvoiceLines(_daoFactory).Select(x => context.Mapper.Map(x)).ToList(); + + return result; + } + } +} diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs index a4954ae8078..dcdf52c9d37 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs @@ -23,8 +23,9 @@ * */ +using System; + using ASC.Api.Core; -using ASC.Common; using ASC.Core.Common.Settings; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -35,35 +36,30 @@ using AutoMapper; -using System; - namespace ASC.CRM.Mapping { public class InvoiceItemDtoTypeConverter : ITypeConverter { - private CurrencyInfoDtoHelper _currencyInfoDtoHelper; - private DaoFactory _daoFactory; - private CurrencyProvider _currencyProvider; - private SettingsManager _settingsManager; - private ApiDateTimeHelper _apiDateTimeHelper; - private EmployeeWraperHelper _employeeWraperHelper; - private CRMSecurity _CRMSecurity; + private readonly DaoFactory _daoFactory; + private readonly CurrencyProvider _currencyProvider; + private readonly SettingsManager _settingsManager; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly CRMSecurity _crmSecurity; public InvoiceItemDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, SettingsManager settingsManager, CurrencyProvider currencyProvider, - DaoFactory daoFactory, - CurrencyInfoDtoHelper currencyInfoDtoHelper) + DaoFactory daoFactory) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _CRMSecurity = cRMSecurity; + _crmSecurity = crmSecurity; _settingsManager = settingsManager; _currencyProvider = currencyProvider; _daoFactory = daoFactory; - _currencyInfoDtoHelper = currencyInfoDtoHelper; } public InvoiceItemDto Convert(InvoiceItem source, InvoiceItemDto destination, ResolutionContext context) @@ -83,10 +79,10 @@ public InvoiceItemDto Convert(InvoiceItem source, InvoiceItemDto destination, Re CreateOn = _apiDateTimeHelper.Get(source.CreateOn), CreateBy = _employeeWraperHelper.Get(source.CreateBy), Currency = !String.IsNullOrEmpty(source.Currency) ? - _currencyInfoDtoHelper.Get(_currencyProvider.Get(source.Currency)) : - _currencyInfoDtoHelper.Get(_settingsManager.Load().DefaultCurrency), - CanEdit = _CRMSecurity.CanEdit(source), - CanDelete = _CRMSecurity.CanDelete(source) + context.Mapper.Map(_currencyProvider.Get(source.Currency)) : + context.Mapper.Map(_settingsManager.Load().DefaultCurrency), + CanEdit = _crmSecurity.CanEdit(source), + CanDelete = _crmSecurity.CanDelete(source) }; if (source.InvoiceTax1ID > 0) diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs index ec86eb42750..d048a71ed3b 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxTypeConverter.cs @@ -26,7 +26,6 @@ using System; using ASC.Api.Core; -using ASC.Common; using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Entities; @@ -38,9 +37,9 @@ namespace ASC.CRM.Mapping { public class InvoiceTaxTypeConverter : ITypeConverter { - private ApiDateTimeHelper _apiDateTimeHelper; - private EmployeeWraperHelper _employeeWraperHelper; - private CRMSecurity _CRMSecurity; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly CRMSecurity _CRMSecurity; public InvoiceTaxTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs new file mode 100644 index 00000000000..7fa7e7b175a --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs @@ -0,0 +1,124 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.Collections.Generic; +using System.Linq; + +using ASC.Api.Core; +using ASC.Common.Web; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.Web.Api.Models; +using ASC.Web.CRM.Classes; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public class OpportunityDtoTypeConverter : ITypeConverter + { + private readonly CurrencyProvider _currencyProvider; + private readonly DaoFactory _daoFactory; + private readonly CRMSecurity _cRMSecurity; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + + public OpportunityDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + CRMSecurity cRMSecurity, + DaoFactory daoFactory, + CurrencyProvider currencyProvider) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _cRMSecurity = cRMSecurity; + _daoFactory = daoFactory; + _currencyProvider = currencyProvider; + } + + public OpportunityDto Convert(Deal source, OpportunityDto destination, ResolutionContext context) + { + var dealDto = new OpportunityDto + { + Id = source.ID, + CreateBy = _employeeWraperHelper.Get(source.CreateBy), + Created = _apiDateTimeHelper.Get(source.CreateOn), + Title = source.Title, + Description = source.Description, + Responsible = _employeeWraperHelper.Get(source.ResponsibleID), + BidType = source.BidType, + BidValue = source.BidValue, + PerPeriodValue = source.PerPeriodValue, + SuccessProbability = source.DealMilestoneProbability, + ActualCloseDate = _apiDateTimeHelper.Get(source.ActualCloseDate), + ExpectedCloseDate = _apiDateTimeHelper.Get(source.ExpectedCloseDate), + CanEdit = _cRMSecurity.CanEdit(source) + }; + + if (source.ContactID > 0) + dealDto.Contact = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(source.ContactID)); + + if (source.DealMilestoneID > 0) + { + var dealMilestone = _daoFactory.GetDealMilestoneDao().GetByID(source.DealMilestoneID); + + if (dealMilestone == null) + throw new ItemNotFoundException(); + + dealDto.Stage = new DealMilestoneBaseDto(dealMilestone); + } + + dealDto.AccessList = _cRMSecurity.GetAccessSubjectTo(source) + .Select(item => _employeeWraperHelper.Get(item.Key)); + + dealDto.IsPrivate = _cRMSecurity.IsPrivate(source); + + if (!string.IsNullOrEmpty(source.BidCurrency)) + dealDto.BidCurrency = context.Mapper.Map(_currencyProvider.Get(source.BidCurrency)); + + dealDto.CustomFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, source.ID, false).ConvertAll(item => new CustomFieldBaseDto(item)); + + dealDto.Members = new List(); + + var memberIDs = _daoFactory.GetDealDao().GetMembers(source.ID); + var membersList = _daoFactory.GetContactDao().GetContacts(memberIDs); + var membersDtoList = new List(); + + foreach (var member in membersList) + { + if (member == null) continue; + membersDtoList.Add(context.Mapper.Map(member)); + } + + dealDto.Members = membersDtoList; + + return dealDto; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs new file mode 100644 index 00000000000..0b62c134e1f --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs @@ -0,0 +1,115 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System.Collections.Generic; + +using ASC.Api.Core; +using ASC.Api.Documents; +using ASC.Common; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.Web.Api.Models; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + [Scope] + public class RelationshipEventDtoTypeConverter : ITypeConverter + { + private HistoryCategoryDtoHelper _historyCategoryDtoHelper; + private FileWrapperHelper _fileWrapperHelper; + private DaoFactory _daoFactory; + private CRMSecurity _crmSecurity; + private ApiDateTimeHelper _apiDateTimeHelper; + private EmployeeWraperHelper _employeeWraperHelper; + private EntityDtoHelper _entityDtoHelper; + + public RelationshipEventDtoTypeConverter( + ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + FileWrapperHelper fileWrapperHelper, + CRMSecurity cRMSecurity, + DaoFactory daoFactory, + EntityDtoHelper entityDtoHelper, + HistoryCategoryDtoHelper historyCategoryDtoHelper) + { + _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; + _crmSecurity = cRMSecurity; + _daoFactory = daoFactory; + _fileWrapperHelper = fileWrapperHelper; + _entityDtoHelper = entityDtoHelper; + _historyCategoryDtoHelper = historyCategoryDtoHelper; + } + + public RelationshipEventDto Convert(RelationshipEvent source, RelationshipEventDto destination, ResolutionContext context) + { + var result = new RelationshipEventDto + { + Id = source.ID, + CreateBy = _employeeWraperHelper.Get(source.CreateBy), + Created = _apiDateTimeHelper.Get(source.CreateOn), + Content = source.Content, + Files = new List>(), + CanEdit = _crmSecurity.CanEdit(source) + }; + + + var historyCategory = _daoFactory.GetListItemDao().GetByID(source.CategoryID); + + if (historyCategory != null) + { + result.Category = _historyCategoryDtoHelper.Get(historyCategory); + } + + if (source.EntityID > 0) + { + result.Entity = _entityDtoHelper.Get(source.EntityType, source.EntityID); + } + + result.Files = _daoFactory.GetRelationshipEventDao().GetFiles(source.ID).ConvertAll(file => _fileWrapperHelper.Get(file)); + + if (source.ContactID > 0) + { + var relativeContact = _daoFactory.GetContactDao().GetByID(source.ContactID); + + if (relativeContact != null) + { + result.Contact = context.Mapper.Map(relativeContact); + } + } + + result.CanEdit = _crmSecurity.CanAccessTo(source); + + return result; + + } + } + +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/TaskCategoryDtoHelper.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs similarity index 72% rename from products/ASC.CRM/Server/Helpers/TaskCategoryDtoHelper.cs rename to products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs index 9b248fd91e4..2032c18bd22 100644 --- a/products/ASC.CRM/Server/Helpers/TaskCategoryDtoHelper.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs @@ -24,28 +24,29 @@ */ -using ASC.Common; +using ASC.CRM.ApiModels; using ASC.CRM.Core.Entities; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM.Configuration; -namespace ASC.CRM.ApiModels +using AutoMapper; + +namespace ASC.CRM.Mapping { - [Scope] - public sealed class TaskCategoryDtoHelper + public sealed class TaskCategoryDtoTypeConverter : ITypeConverter { - public TaskCategoryDtoHelper(WebImageSupplier webImageSupplier) + private readonly WebImageSupplier _webImageSupplier; + + public TaskCategoryDtoTypeConverter(WebImageSupplier webImageSupplier) { - WebImageSupplier = webImageSupplier; + _webImageSupplier = webImageSupplier; } - public WebImageSupplier WebImageSupplier; - - public TaskCategoryBaseDto Get(ListItem listItem) + public TaskCategoryBaseDto Convert(ListItem source, TaskCategoryBaseDto destination, ResolutionContext context) { - return new TaskCategoryBaseDto(listItem) + return new TaskCategoryBaseDto(source) { - ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) + ImagePath = _webImageSupplier.GetAbsoluteWebPath(source.AdditionalParams, ProductEntryPoint.ID) }; } } diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs index 634f7d0e2ef..b1c026207e0 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs @@ -38,10 +38,10 @@ namespace ASC.CRM.Mapping { + [Scope] public class TaskDtoTypeConverter : ITypeConverter, ITypeConverter { - private readonly ContactDtoHelper _contactBaseDtoHelper; private readonly CRMSecurity _CRMSecurity; private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; @@ -50,18 +50,15 @@ public class TaskDtoTypeConverter : ITypeConverter, public TaskDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, DaoFactory daoFactory, - ContactDtoHelper contactBaseDtoHelper, EntityDtoHelper entityDtoHelper) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _CRMSecurity = cRMSecurity; + _CRMSecurity = crmSecurity; _daoFactory = daoFactory; - _contactBaseDtoHelper = contactBaseDtoHelper; _entityDtoHelper = entityDtoHelper; - } public TaskDto Convert(Task source, TaskDto destination, ResolutionContext context) @@ -90,7 +87,7 @@ public TaskDto Convert(Task source, TaskDto destination, ResolutionContext conte if (source.ContactID > 0) { - result.Contact = _contactBaseDtoHelper.GetContactBaseWithEmailDto(_daoFactory.GetContactDao().GetByID(source.ContactID)); + result.Contact = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(source.ContactID)); } if (source.EntityID > 0) diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index ba846ec0548..5b270945bbc 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -23,11 +23,17 @@ * */ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Globalization; +using System.Linq; +using System.Web; + using ASC.Common; using ASC.Core; -using ASC.Core.Billing; using ASC.Core.Tenants; -using ASC.Core.Users; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -35,17 +41,8 @@ using ASC.Notify; using ASC.Notify.Patterns; using ASC.Notify.Recipients; -using ASC.Web.CRM.Core; -using Autofac; + using Microsoft.Extensions.DependencyInjection; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Web; namespace ASC.Web.CRM.Services.NotifyService { @@ -116,26 +113,26 @@ private NameValueCollection ExtractBaseDataFrom(EntityType entityType, int entit case EntityType.Person: case EntityType.Company: case EntityType.Contact: - { - var contact = daoFactory.GetContactDao().GetByID(entityID); - title = contact != null ? contact.GetTitle() : string.Empty; - relativeURL = "default.aspx?id=" + entityID; - break; - } + { + var contact = daoFactory.GetContactDao().GetByID(entityID); + title = contact != null ? contact.GetTitle() : string.Empty; + relativeURL = "default.aspx?id=" + entityID; + break; + } case EntityType.Opportunity: - { - var deal = daoFactory.GetDealDao().GetByID(entityID); - title = deal != null ? deal.Title : string.Empty; - relativeURL = "deals.aspx?id=" + entityID; - break; - } + { + var deal = daoFactory.GetDealDao().GetByID(entityID); + title = deal != null ? deal.Title : string.Empty; + relativeURL = "deals.aspx?id=" + entityID; + break; + } case EntityType.Case: - { - var cases = daoFactory.GetCasesDao().GetByID(entityID); - title = cases != null ? cases.Title : string.Empty; - relativeURL = "cases.aspx?id=" + entityID; - break; - } + { + var cases = daoFactory.GetCasesDao().GetByID(entityID); + title = cases != null ? cases.Title : string.Empty; + relativeURL = "cases.aspx?id=" + entityID; + break; + } default: throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs index a9243cc7208..e4f0d8e696f 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyConstants.cs @@ -42,7 +42,7 @@ public static class NotifyConstants public static readonly INotifyAction Event_TaskReminder = new NotifyAction("TaskReminder", "auto reminder about task"); public static readonly INotifyAction Event_ResponsibleForOpportunity = new NotifyAction("ResponsibleForOpportunity", "responsible for opportunity"); - + public static readonly INotifyAction Event_AddRelationshipEvent = new NotifyAction("AddRelationshipEvent", "add relationship event"); public static readonly INotifyAction Event_ExportCompleted = new NotifyAction("ExportCompleted", "export is completed"); diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs index 827e41c1787..74d42301789 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifySource.cs @@ -23,12 +23,14 @@ * */ +using System; + using ASC.Core; using ASC.CRM.Services.NotifyService; using ASC.Notify.Model; using ASC.Notify.Patterns; using ASC.Notify.Recipients; -using System; + using NotifySourceBase = ASC.Core.Notify.NotifySource; namespace ASC.Web.CRM.Services.NotifyService diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index a2c16992f0f..a1e81e488b7 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -4,7 +4,6 @@ using ASC.Api.Core; using ASC.Common; using ASC.CRM.Api; -using ASC.CRM.Core; using ASC.CRM.Mapping; using ASC.Web.CRM.HttpHandlers; @@ -48,6 +47,17 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + services.AddAutoMapper(Assembly.GetExecutingAssembly()); } diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index 61493bcd2ea..9f9ba0f9401 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -24,22 +24,24 @@ */ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Text.RegularExpressions; + using ASC.Common; using ASC.Common.Logging; using ASC.Core.Common.Settings; using ASC.CRM.Core; using ASC.CRM.Core.Dao; -using ASC.Web.CRM.Core; + using Autofac; + using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Text.RegularExpressions; namespace ASC.Web.CRM.Classes { @@ -178,7 +180,7 @@ private string GetExchangesTempPath() return Path.Combine(Path.GetTempPath(), Path.Combine("onlyoffice", "exchanges")); } - private Regex CurRateRegex = new Regex("[a-zA-Z]{3})\">(?[\\d\\.]+)"); + private readonly Regex CurRateRegex = new Regex("[a-zA-Z]{3})\">(?[\\d\\.]+)"); private Dictionary GetExchangeRates() { diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 2f83baaa750..d25f9f39623 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -24,6 +24,15 @@ */ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -45,7 +54,6 @@ using ASC.Web.Files.Classes; using ASC.Web.Files.Utils; using ASC.Web.Studio.Utility; -using ASC.Web.Core.Calendars; using ICSharpCode.SharpZipLib.Zip; @@ -53,15 +61,6 @@ using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Data; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text; - namespace ASC.Web.CRM.Classes { [Singletone] @@ -1437,7 +1436,7 @@ public IProgressItem Start(FilterObject filterObject, string fileName) if (operation == null) { - ExportDataOperation.Configure(key,filterObject, fileName); + ExportDataOperation.Configure(key, filterObject, fileName); Queue.Add(ExportDataOperation); } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs index fa6cec2bf00..6469ce2b4ac 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportBase.cs @@ -24,7 +24,6 @@ */ -using ASC.Web.CRM.Classes; using System; namespace LumenWorks.Framework.IO.Csv diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs index de8b6c6eb3a..c70f5061ebd 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs @@ -24,13 +24,15 @@ */ -using ASC.CRM.Core.Enums; -using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using ASC.CRM.Core.Enums; + +using Newtonsoft.Json.Linq; + namespace ASC.Web.CRM.Classes { public class ImportCSVSettings diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index 37ec5cb6087..87684503922 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -26,15 +26,18 @@ #region Import +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; + using LumenWorks.Framework.IO.Csv; + using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; #endregion @@ -159,7 +162,7 @@ private void ImportCaseData(DaoFactory _daoFactory) } ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); - + var newIDs = casesDao.SaveCasesList(findedCases); findedCases.ForEach(d => d.ID = newIDs[d.ID]); @@ -176,7 +179,7 @@ private void ImportCaseData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); foreach (var findedCasesMemberKey in findedCasesMembers.Keys) { @@ -192,7 +195,7 @@ private void ImportCaseData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); foreach (var findedTagKey in findedTags.Keys) @@ -213,7 +216,7 @@ private void ImportCaseData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Case,(ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index 196268c9794..4f229c027a8 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -26,15 +26,18 @@ #region Import +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; + using LumenWorks.Framework.IO.Csv; + using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; #endregion @@ -45,7 +48,7 @@ public partial class ImportDataOperation private Int32 DaoIterationStep = 200; - + private void ImportContactsData(DaoFactory _daoFactory) { @@ -619,80 +622,80 @@ private void _DuplicateRecordRuleProcess(DaoFactory _daoFactory, switch (_importSettings.DuplicateRecordRule) { case 1: // Skip + { + var emails = findedContactInfos.Where(item => item.InfoType == ContactInfoType.Email).ToList(); + + if (emails.Count == 0) break; + + var index = 0; + while (index < emails.Count) { - var emails = findedContactInfos.Where(item => item.InfoType == ContactInfoType.Email).ToList(); + var emailsIteration = emails.Skip(index).Take(DaoIterationStep).ToList();// Get next step - if (emails.Count == 0) break; + var duplicateContactsID = contactDao.FindDuplicateByEmail(emailsIteration, false) + .Distinct() + .ToList(); - var index = 0; - while (index < emails.Count) + if (duplicateContactsID.Count != 0) { - var emailsIteration = emails.Skip(index).Take(DaoIterationStep).ToList();// Get next step + findedContacts = findedContacts.Where(item => !duplicateContactsID.Contains(item.Key)).ToDictionary(x => x.Key, y => y.Value); - var duplicateContactsID = contactDao.FindDuplicateByEmail(emailsIteration, false) - .Distinct() - .ToList(); + personFakeIdCompanyNameHash = personFakeIdCompanyNameHash.Where(item => !duplicateContactsID.Contains(item.Key)).ToDictionary(x => x.Key, y => y.Value); - if (duplicateContactsID.Count != 0) + if (findedContacts.Count == 0) { - findedContacts = findedContacts.Where(item => !duplicateContactsID.Contains(item.Key)).ToDictionary(x => x.Key, y => y.Value); - - personFakeIdCompanyNameHash = personFakeIdCompanyNameHash.Where(item => !duplicateContactsID.Contains(item.Key)).ToDictionary(x => x.Key, y => y.Value); - - if (findedContacts.Count == 0) - { - Complete(); - return; - } - - findedContactInfos = findedContactInfos.Where(item => !duplicateContactsID.Contains(item.ContactID)).ToList(); - findedCustomField = findedCustomField.Where(item => !duplicateContactsID.Contains(item.EntityID)).ToList(); - - foreach (var exceptID in duplicateContactsID) - { - if (findedTags.ContainsKey(exceptID)) findedTags.Remove(exceptID); - } + Complete(); + return; } - index += DaoIterationStep; - if (index > emails.Count) + findedContactInfos = findedContactInfos.Where(item => !duplicateContactsID.Contains(item.ContactID)).ToList(); + findedCustomField = findedCustomField.Where(item => !duplicateContactsID.Contains(item.EntityID)).ToList(); + + foreach (var exceptID in duplicateContactsID) { - index = emails.Count; + if (findedTags.ContainsKey(exceptID)) findedTags.Remove(exceptID); } } + + index += DaoIterationStep; + if (index > emails.Count) + { + index = emails.Count; + } } - break; + } + break; case 2: // Overwrite - { - var emailContactInfos = findedContactInfos.Where(item => item.InfoType == ContactInfoType.Email).ToList(); - if (emailContactInfos.Count == 0) break; + { + var emailContactInfos = findedContactInfos.Where(item => item.InfoType == ContactInfoType.Email).ToList(); + if (emailContactInfos.Count == 0) break; - _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. Start. All emeails count = {0}", emailContactInfos.Count); + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. Start. All emeails count = {0}", emailContactInfos.Count); - var index = 0; - while (index < emailContactInfos.Count) - { - var emailsIteration = emailContactInfos.Skip(index).Take(DaoIterationStep).ToList();// Get next step + var index = 0; + while (index < emailContactInfos.Count) + { + var emailsIteration = emailContactInfos.Skip(index).Take(DaoIterationStep).ToList();// Get next step - _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. Portion from index = {0}. count = {1}", index, emailsIteration.Count); - var duplicateContactsID = contactDao.FindDuplicateByEmail(emailsIteration, true) - .Distinct() - .ToArray(); + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. Portion from index = {0}. count = {1}", index, emailsIteration.Count); + var duplicateContactsID = contactDao.FindDuplicateByEmail(emailsIteration, true) + .Distinct() + .ToArray(); - _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. FindDuplicateByEmail result count = {0}", duplicateContactsID.Length); - var deleted = contactDao.DeleteBatchContact(duplicateContactsID); + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. FindDuplicateByEmail result count = {0}", duplicateContactsID.Length); + var deleted = contactDao.DeleteBatchContact(duplicateContactsID); - _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. DeleteBatchContact. Was deleted {0} contacts", deleted != null ? deleted.Count : 0); + _log.InfoFormat("_DuplicateRecordRuleProcess. Overwrite. DeleteBatchContact. Was deleted {0} contacts", deleted != null ? deleted.Count : 0); - index += DaoIterationStep; - if (index > emailContactInfos.Count) - { - index = emailContactInfos.Count; - } + index += DaoIterationStep; + if (index > emailContactInfos.Count) + { + index = emailContactInfos.Count; } - - break; } + + break; + } case 3: // Clone break; default: diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 1a7491ccf41..00ce93c2ba1 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -24,6 +24,10 @@ */ +using System; +using System.Globalization; +using System.Linq; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -36,13 +40,9 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Data.Storage; -using ASC.Web.CRM.Core; using ASC.Web.CRM.Services.NotifyService; -using Autofac; + using Microsoft.Extensions.Options; -using System; -using System.Globalization; -using System.Linq; namespace ASC.Web.CRM.Classes { @@ -271,7 +271,7 @@ public void RunJob() TenantManager.SetCurrentTenant(_tenantID); SecurityContext.AuthenticateMe(_author); - + var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index 75ffe70cf4d..4ee0992ffca 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -26,17 +26,20 @@ #region Import +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Core.Users; using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; + using LumenWorks.Framework.IO.Csv; + using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Linq; #endregion @@ -109,7 +112,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) var bidValueStr = GetPropertyValue("bid_amount"); - if (Decimal.TryParse(bidValueStr, out bidValue)) + if (Decimal.TryParse(bidValueStr, out bidValue)) obj.BidValue = bidValue; else obj.BidValue = 0; @@ -265,7 +268,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); findedDeals.Add(obj); @@ -284,8 +287,8 @@ private void ImportOpportunityData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); - + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + var newDealIDs = dealDao.SaveDealList(findedDeals); findedDeals.ForEach(d => d.ID = newDealIDs[d.ID]); @@ -298,7 +301,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); findedCustomField.ForEach(item => item.EntityID = newDealIDs[item.EntityID]); @@ -313,7 +316,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); foreach (var findedDealMemberKey in findedDealMembers.Keys) { @@ -329,7 +332,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); foreach (var findedTagKey in findedTags.Keys) { @@ -348,8 +351,8 @@ private void ImportOpportunityData(DaoFactory _daoFactory) throw new OperationCanceledException(); } - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); - + ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + } Complete(); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index 4ed06d5d07d..3e00fe26a92 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -24,15 +24,18 @@ */ +using System; +using System.IO; +using System.Linq; + using ASC.Common; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.CRM.Core.Enums; + using LumenWorks.Framework.IO.Csv; + using Newtonsoft.Json.Linq; -using System; -using System.IO; -using System.Linq; namespace ASC.Web.CRM.Classes { @@ -59,7 +62,7 @@ public ImportFromCSV(TenantManager tenantProvider, private readonly object _syncObj = new object(); private readonly ProgressQueue _importQueue; - + public readonly int MaxRoxCount = 10000; public int GetQuotas() diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs index 4236f06fec6..7640c793465 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs @@ -26,6 +26,10 @@ #region Import +using System; +using System.Collections.Generic; +using System.Linq; + using ASC.Core; using ASC.Core.Tenants; using ASC.Core.Users; @@ -34,10 +38,8 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Web.Core.Users; + using LumenWorks.Framework.IO.Csv; -using System; -using System.Collections.Generic; -using System.Linq; #endregion @@ -45,8 +47,8 @@ namespace ASC.Web.CRM.Classes { public partial class ImportDataOperation { - public ImportDataOperation(TenantUtil tenantUtil, - ImportFromCSV importFromCSV, + public ImportDataOperation(TenantUtil tenantUtil, + ImportFromCSV importFromCSV, DisplayUserSettingsHelper displayUserSettingsHelper) { TenantUtil = tenantUtil; @@ -56,7 +58,7 @@ public ImportDataOperation(TenantUtil tenantUtil, public ImportFromCSV ImportFromCSV { get; } public TenantUtil TenantUtil { get; } - public DisplayUserSettingsHelper DisplayUserSettingsHelper { get;} + public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } private void ImportTaskData(DaoFactory _daoFactory) { diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index d9dc0344683..5b4f68c5978 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -26,6 +26,16 @@ #region Import +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; + using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -39,7 +49,6 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; -using ASC.Web.CRM.Core; using ASC.Web.Files.Api; using Autofac; @@ -55,16 +64,6 @@ using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.Sockets; -using System.Runtime.Serialization; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading; - using File = System.IO.File; using SmtpClient = MailKit.Net.Smtp.SmtpClient; @@ -121,12 +120,7 @@ DaoFactory daoFactory _smtpSetting = settingsManager.Load().SMTPServerSetting; _currUser = SecurityContext.CurrentAccount.ID; - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = 0, - DeliveryCount = 0 - }; + AuthManager = authManager; UserManager = userManager; @@ -154,6 +148,13 @@ public void Configure(List fileID, _subject = subject; _bodyTempate = bodyTempate; _storeInHistory = storeInHistory; + + Status = new + { + RecipientCount = _contactID.Count, + EstimatedTime = 0, + DeliveryCount = 0 + }; } private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) @@ -544,10 +545,11 @@ public void Dispose() } } + [Scope] public class MailSenderDataCache { public MailSenderDataCache(TenantManager tenantManager, - ICache cache ) + ICache cache) { TenantID = tenantManager.GetCurrentTenant().TenantId; Cache = cache; diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index 1485ea353a3..a9eef7152c3 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -24,30 +24,26 @@ */ -using ASC.Common.Logging; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Resources; -using ASC.Files.Core; -using ASC.Web.Core.Files; -using ASC.Web.CRM.Core; -using ASC.Web.Files.Services.DocumentService; -using ASC.Web.Files.Utils; -using Autofac; -using Microsoft.Extensions.Options; using System; using System.Globalization; using System.IO; -using System.Linq; using System.Net; using System.Text; using System.Xml; -using Microsoft.Extensions.DependencyInjection; using ASC.Common; -using ASC.Web.Files.Classes; +using ASC.Common.Logging; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Resources; +using ASC.Files.Core; +using ASC.Web.Files.Services.DocumentService; + using ICSharpCode.SharpZipLib.Zip; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + namespace ASC.Web.CRM.Classes { [Scope] @@ -295,8 +291,8 @@ private Stream GetStreamDocx(Invoice data) using (var zipInputStream = new ZipInputStream(Template)) { ZipEntry zipEntry; - - while((zipEntry = zipInputStream.GetNextEntry()) != null) + + while ((zipEntry = zipInputStream.GetNextEntry()) != null) { zipOutputStream.PutNextEntry(new ZipEntry(zipEntry.Name)); @@ -311,7 +307,7 @@ private Stream GetStreamDocx(Invoice data) var document = new XmlDocument(); document.Load(documentXmlStream); - + var documentStr = GenerateDocumentXml(document, invoiceData, logo); var documentStrAsStream = new MemoryStream(Encoding.UTF8.GetBytes(documentStr)); @@ -789,7 +785,7 @@ public class ConverterData public int FileId { get; set; } } - class CustomStaticDataSource: IStaticDataSource + class CustomStaticDataSource : IStaticDataSource { private Stream _stream; // Implement method from IStaticDataSource diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index 6085912bf3a..eae84882bb4 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -26,18 +26,18 @@ using System; using System.Web; -using ASC.Common.Logging; -using ASC.CRM.Core; + +using ASC.Common; using ASC.Common.Threading.Progress; -using ASC.Common.Web; using ASC.Core; -using Microsoft.AspNetCore.Http; using ASC.CRM.Core.Enums; + using log4net; -using ASC.Common; + +using Microsoft.AspNetCore.Http; namespace ASC.Web.CRM.Classes -{ +{ [Transient] public class PdfQueueWorker { @@ -96,7 +96,7 @@ public PdfProgressItem StartTask(int invoiceId) PdfProgressItem.Configure(GetTaskId(tenantId, invoiceId), tenantId, userId, invoiceId); Queue.Add(PdfProgressItem); - + } if (!Queue.IsStarted) @@ -125,9 +125,9 @@ public class PdfProgressItem : IProgressItem public TenantManager TenantManager { get; } public PdfProgressItem(IHttpContextAccessor httpContextAccessor) - { + { _contextUrl = httpContextAccessor.HttpContext != null ? httpContextAccessor.HttpContext.Request.GetUrlRewriter().ToString() : null; - + Status = ProgressStatus.Queued; Error = null; Percentage = 0; diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index dfa5fd783dc..35724ba3335 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -24,23 +24,24 @@ */ +using System; +using System.Collections.Generic; +using System.Net; + +using ASC.Common; +using ASC.Core; using ASC.Core.Common.Settings; using ASC.Core.Tenants; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Files.Core; -using ASC.Web.CRM.Core; using ASC.Web.Files.Services.DocumentService; -using Autofac; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Net; -using Microsoft.Extensions.DependencyInjection; -using ASC.Common; -using ASC.Core; + using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; + +using Newtonsoft.Json; namespace ASC.Web.CRM.Classes { From 9182d0aac230e111ec61626b2dbdb976e9517ba8 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 14:38:28 +0300 Subject: [PATCH 26/61] crm: bug fix --- .../ASC.CRM/Server/Api/DealsController.cs | 16 +-- .../ASC.CRM/Server/Api/InvoicesController.cs | 1 - .../ApiModels/ResponsesDto/ContactDto.cs | 4 +- .../ApiModels/ResponsesDto/CustomFieldDto.cs | 2 + .../ApiModels/ResponsesDto/OpportunityDto.cs | 15 ++- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 12 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 12 +- .../ASC.CRM/Server/Core/Dao/DaoFactory.cs | 3 + products/ASC.CRM/Server/Core/Dao/DealDao.cs | 14 +-- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 115 ++++++++++-------- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 50 ++++---- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 10 +- products/ASC.CRM/Server/Core/Entities/Deal.cs | 4 +- .../TypeConverter/ContactDtoTypeConverter.cs | 39 +++++- .../TaskCategoryDtoTypeConverter.cs | 2 +- 15 files changed, 180 insertions(+), 119 deletions(-) diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index 183f9a22e50..e8228ea0884 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -394,14 +394,14 @@ public IEnumerable DeleteBatchDeals( /// [Read(@"opportunity/filter")] public IEnumerable GetDeals( - Guid responsibleid, - int opportunityStagesid, - IEnumerable tags, - int contactid, - DealMilestoneStatus? stageType, - bool? contactAlsoIsParticipant, - ApiDateTime fromDate, - ApiDateTime toDate) + [FromQuery] Guid responsibleid, + [FromQuery] int opportunityStagesid, + [FromQuery] IEnumerable tags, + [FromQuery] int contactid, + [FromQuery] DealMilestoneStatus? stageType, + [FromQuery] bool? contactAlsoIsParticipant, + [FromQuery] ApiDateTime fromDate, + [FromQuery] ApiDateTime toDate) { DealSortedByType dealSortedByType; diff --git a/products/ASC.CRM/Server/Api/InvoicesController.cs b/products/ASC.CRM/Server/Api/InvoicesController.cs index f34cf931cf9..bdbd9d0420c 100644 --- a/products/ASC.CRM/Server/Api/InvoicesController.cs +++ b/products/ASC.CRM/Server/Api/InvoicesController.cs @@ -1536,7 +1536,6 @@ private IEnumerable ToListInvoiceBaseDtos(ICollection i var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs.Distinct().ToArray()) .ToDictionary(item => item.ID, x => _mapper.Map(x)); - foreach (var invoice in items) { var invoiceDto = _mapper.Map(invoice); diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs index b305a29889a..390cf17e0e0 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -178,9 +178,9 @@ public void Mapping(Profile profile) { profile.CreateMap().ConvertUsing(); profile.CreateMap().ConvertUsing(); profile.CreateMap().ConvertUsing(); - profile.CreateMap().ConvertUsing(); - profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); } } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index 914e6c91c2d..af5da4b9bb9 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -74,6 +74,8 @@ public CustomFieldBaseDto(int id) public CustomFieldBaseDto(CustomField customField) { + if (customField != null) + EntityId = customField.EntityID; Label = customField.Label; FieldValue = customField.Value; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs index 875aefa9469..3b5c83f550e 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs @@ -29,16 +29,20 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; using ASC.Web.Api.Models; +using AutoMapper; + namespace ASC.CRM.ApiModels { /// /// Opportunity /// [DataContract(Name = "opportunity", Namespace = "")] - public class OpportunityDto + public class OpportunityDto : IMapFrom { public OpportunityDto() @@ -65,11 +69,8 @@ public OpportunityDto() public ApiDateTime ActualCloseDate { get; set; } public ApiDateTime ExpectedCloseDate { get; set; } - public bool IsPrivate { get; set; } public IEnumerable AccessList { get; set; } - - public bool CanEdit { get; set; } public IEnumerable CustomFields { get; set; } @@ -90,5 +91,11 @@ public static OpportunityDto GetSample() Stage = DealMilestoneBaseDto.GetSample() }; } + + + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index c6429c3c216..b1e0a2a8f40 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -128,17 +128,19 @@ protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumer } protected Dictionary GetRelativeToEntity(int[] contactID, EntityType entityType, int[] entityID) - { - Expression> exp = null; + { Expression> exp = null; if (contactID != null && contactID.Length > 0 && (entityID == null || entityID.Length == 0)) exp = x => x.EntityType == entityType && contactID.Contains(x.ContactId); else if (entityID != null && entityID.Length > 0 && (contactID == null || contactID.Length == 0)) exp = x => x.EntityType == entityType && entityID.Contains(x.EntityId); - return CRMDbContext.EntityContact.Where(exp).GroupBy(x => x.EntityId).ToDictionary( - x => x.Key, - x => x.Select(x => Convert.ToInt32(x.ContactId)).ToArray()); + return CRMDbContext.EntityContact + .Where(exp) + .Select(x => new { EntityId = x.EntityId, ContactId = x.ContactId }) + .ToList() + .GroupBy(x=> x.EntityId) + .ToDictionary(x=>x.Key, y=> y.Select(c => c.ContactId).ToArray()); } protected int[] GetRelativeToEntity(int? contactID, EntityType entityType, int? entityID) diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 26e563c3166..158a8c47aaa 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -440,10 +440,10 @@ public int GetContactLinkCount(EntityType entityType, int entityID) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.FieldDescription).GroupJoin(Query(CRMDbContext.FieldValue), + var sqlQuery = Query(CRMDbContext.FieldDescription).Join(Query(CRMDbContext.FieldValue), x => x.Id, y => y.FieldId, - (x, y) => new { x = x, count = y.Count() } + (x, y) => new { x, y } ); if (entityType == EntityType.Company || entityType == EntityType.Person) @@ -456,9 +456,9 @@ public int GetContactLinkCount(EntityType entityType, int entityID) } sqlQuery = sqlQuery.Where(x => x.x.Id == entityID); - sqlQuery = sqlQuery.OrderBy(x => x.x.SortOrder); - return sqlQuery.Single().count; + return sqlQuery.GroupBy(x => x.x.Id) + .Select(x => x.Count()).SingleOrDefault(); } public List GetEnityFields(EntityType entityType, int entityID, bool includeEmptyFields) @@ -560,7 +560,7 @@ public void DeleteField(int fieldID) public CustomField ToCustomField(DbFieldDescription dbFieldDescription, DbFieldValue dbFieldValue = null) { - if (dbFieldDescription == null || dbFieldValue == null) return null; + if (dbFieldDescription == null) return null; var customField = new CustomField { @@ -573,7 +573,7 @@ public CustomField ToCustomField(DbFieldDescription dbFieldDescription, }; - if (customField != null) + if (dbFieldValue != null) { customField.Value = dbFieldValue.Value; customField.EntityID = dbFieldValue.EntityId; diff --git a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs index 3b75b62c758..33c6fb95d81 100644 --- a/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs +++ b/products/ASC.CRM/Server/Core/Dao/DaoFactory.cs @@ -167,6 +167,7 @@ public static void Register(DIHelper services) services.TryAdd(); services.TryAdd(); services.TryAdd(); + services.TryAdd(); services.TryAdd(); services.TryAdd(); services.TryAdd(); @@ -177,6 +178,8 @@ public static void Register(DIHelper services) services.TryAdd(); services.TryAdd(); + services.TryAdd(); + services.TryAdd(); services.TryAdd(); diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 4df93cc7890..43e78c7ab76 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -187,10 +187,9 @@ public virtual List GetDeals(int[] id) { if (id == null || !id.Any()) return new List(); - return _mapper.ProjectTo(Query(CRMDbContext.Deals) - .Where(x => id.Contains(x.Id))) - .ToList() - .FindAll(CRMSecurity.CanAccessTo); + var dbDeals = Query(CRMDbContext.Deals).Where(x => id.Contains(x.Id)).ToList(); + + return _mapper.Map, List>(dbDeals); } public virtual Deal GetByID(int dealID) @@ -747,8 +746,7 @@ private List GetCrudeDeals( sqlQuery = sqlQuery.Take(count); } - - return _mapper.ProjectTo(sqlQuery).ToList(); + return _mapper.Map, List>(sqlQuery.ToList()); } public List GetDealsByContactID(int contactID) @@ -797,7 +795,9 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta sqlQuery = sqlQuery.OrderBy(x => x.Title); - return _mapper.ProjectTo(sqlQuery).ToList().FindAll(CRMSecurity.CanAccessTo); + var dbDeals = sqlQuery.ToList(); + + return _mapper.Map, List>(dbDeals).FindAll(CRMSecurity.CanAccessTo); } public virtual Deal DeleteDeal(int dealID) diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index e6ed3f82b62..3f22b96274f 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -68,7 +68,9 @@ public CachedInvoiceDao(DbContextManager dbContextManager, ICache ascCache, SettingsManager settingsManager, InvoiceSetting invoiceSetting, - InvoiceFormattedData invoiceFormattedData) + InvoiceFormattedData invoiceFormattedData, + CRMSecurity crmSecurity, + TenantUtil tenantUtil) : base(dbContextManager, tenantManager, securityContext, @@ -77,7 +79,9 @@ public CachedInvoiceDao(DbContextManager dbContextManager, ascCache, settingsManager, invoiceSetting, - invoiceFormattedData + invoiceFormattedData, + crmSecurity, + tenantUtil ) { _invoiceCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice"); @@ -126,38 +130,41 @@ public class InvoiceDao : AbstractDao new KeyValuePair(InvoiceStatus.Paid, InvoiceStatus.Sent)//Bug 23450 }; + private InvoiceSetting _invoiceSetting; + private InvoiceFormattedData _invoiceFormattedData; + private SettingsManager _settingsManager; + private FactoryIndexerInvoice _factoryIndexer; + private TenantUtil _tenantUtil; + private CRMSecurity _crmSecurity; + public InvoiceDao( DbContextManager dbContextManager, TenantManager tenantManager, + SecurityContext securityContext, FactoryIndexerInvoice factoryIndexer, IOptionsMonitor logger, ICache ascCache, SettingsManager settingsManager, InvoiceSetting invoiceSetting, - InvoiceFormattedData invoiceFormattedData) + InvoiceFormattedData invoiceFormattedData, + CRMSecurity crmSecurity, + TenantUtil tenantUtil) : base(dbContextManager, tenantManager, securityContext, logger, ascCache) { - FactoryIndexer = factoryIndexer; - SettingsManager = settingsManager; - InvoiceSetting = invoiceSetting; - InvoiceFormattedData = invoiceFormattedData; + _factoryIndexer = factoryIndexer; + _settingsManager = settingsManager; + _invoiceSetting = invoiceSetting; + _invoiceFormattedData = invoiceFormattedData; + _crmSecurity = crmSecurity; + _tenantUtil = tenantUtil; } - public InvoiceSetting InvoiceSetting { get; } - - public InvoiceFormattedData InvoiceFormattedData { get; } - public SettingsManager SettingsManager { get; } - - public FactoryIndexerInvoice FactoryIndexer { get; } - - public TenantUtil TenantUtil { get; } - public CRMSecurity CRMSecurity { get; } - + public Boolean IsExist(int invoiceID) { return IsExistFromDb(invoiceID); @@ -231,7 +238,7 @@ public List GetInvoices( OrderBy orderBy) { - if (CRMSecurity.IsAdmin) + if (_crmSecurity.IsAdmin) return GetCrudeInvoices( searchText, status, @@ -263,9 +270,9 @@ public List GetInvoices( if (crudeInvoices.Count == 0) return crudeInvoices; - if (crudeInvoices.Count < from + count) return CRMSecurity.FilterRead(crudeInvoices).Skip(from).ToList(); + if (crudeInvoices.Count < from + count) return _crmSecurity.FilterRead(crudeInvoices).Skip(from).ToList(); - var result = CRMSecurity.FilterRead(crudeInvoices).ToList(); + var result = _crmSecurity.FilterRead(crudeInvoices).ToList(); if (result.Count == crudeInvoices.Count) return result.Skip(from).ToList(); @@ -290,7 +297,7 @@ public List GetInvoices( if (crudeInvoices.Count == 0) break; - result.AddRange(CRMSecurity.FilterRead(crudeInvoices)); + result.AddRange(_crmSecurity.FilterRead(crudeInvoices)); if ((result.Count >= count + from) || (crudeInvoices.Count < localCount)) break; @@ -412,7 +419,7 @@ public int GetInvoicesCount( var withParams = hasParams(searchText, status, issueDateFrom, issueDateTo, dueDateFrom, dueDateTo, entityType, entityID, currency); - var exceptIDs = CRMSecurity.GetPrivateItems(typeof(Invoice)).ToList(); + var exceptIDs = _crmSecurity.GetPrivateItems(typeof(Invoice)).ToList(); int result; @@ -456,7 +463,7 @@ public List GetInvoices(int[] ids) .Where(x => ids.Contains(x.Id)) .ToList() .ConvertAll(ToInvoice) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } public List GetEntityInvoices(EntityType entityType, int entityID) @@ -470,7 +477,7 @@ public List GetEntityInvoices(EntityType entityType, int entityID) return Query(CRMDbContext.Invoices).Where(x => x.EntityId == entityID && x.EntityType == entityType) .ToList() .ConvertAll(ToInvoice) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } if (entityType == EntityType.Contact || entityType == EntityType.Person || entityType == EntityType.Company) @@ -489,7 +496,7 @@ public List GetContactInvoices(int contactID) return Query(CRMDbContext.Invoices).Where(x => x.ContactId == contactID) .ToList() .ConvertAll(ToInvoice) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } public string GetNewInvoicesNumber() @@ -524,9 +531,9 @@ public string GetNewInvoicesNumber() public InvoiceSetting GetSettings() { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); - return tenantSettings.InvoiceSetting ?? InvoiceSetting.DefaultSettings; + return tenantSettings.InvoiceSetting ?? _invoiceSetting.DefaultSettings; } public virtual int SaveOrUpdateInvoice(Invoice invoice) @@ -535,7 +542,7 @@ public virtual int SaveOrUpdateInvoice(Invoice invoice) var result = SaveOrUpdateInvoiceInDb(invoice); - FactoryIndexer.Index(Query(CRMDbContext.Invoices).Where(x => x.Id == invoice.ID).Single()); + _factoryIndexer.Index(Query(CRMDbContext.Invoices).Where(x => x.Id == invoice.ID).Single()); return result; } @@ -563,13 +570,13 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) { Status = invoice.Status, Number = invoice.Number, - IssueDate = TenantUtil.DateTimeToUtc(invoice.IssueDate), + IssueDate = _tenantUtil.DateTimeToUtc(invoice.IssueDate), TemplateType = invoice.TemplateType, ContactId = invoice.ContactID, ConsigneeId = invoice.ConsigneeID, EntityType = invoice.EntityType, EntityId = invoice.EntityID, - DueDate = TenantUtil.DateTimeToUtc(invoice.DueDate), + DueDate = _tenantUtil.DateTimeToUtc(invoice.DueDate), Language = invoice.Language, Currency = invoice.Currency, ExchangeRate = invoice.ExchangeRate, @@ -598,16 +605,16 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) var oldInvoice = ToInvoice(itemToUpdate); - CRMSecurity.DemandEdit(oldInvoice); + _crmSecurity.DemandEdit(oldInvoice); itemToUpdate.Status = invoice.Status; - itemToUpdate.IssueDate = TenantUtil.DateTimeToUtc(invoice.IssueDate); + itemToUpdate.IssueDate = _tenantUtil.DateTimeToUtc(invoice.IssueDate); itemToUpdate.TemplateType = invoice.TemplateType; itemToUpdate.ContactId = invoice.ContactID; itemToUpdate.ConsigneeId = invoice.ConsigneeID; itemToUpdate.EntityType = invoice.EntityType; itemToUpdate.EntityId = invoice.EntityID; - itemToUpdate.DueDate = TenantUtil.DateTimeToUtc(invoice.DueDate); + itemToUpdate.DueDate = _tenantUtil.DateTimeToUtc(invoice.DueDate); itemToUpdate.Language = invoice.Language; itemToUpdate.Currency = invoice.Currency; itemToUpdate.ExchangeRate = invoice.ExchangeRate; @@ -659,7 +666,7 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) return null; } - CRMSecurity.DemandAccessTo(invoice); + _crmSecurity.DemandAccessTo(invoice); if (!invoiceStatusMap.Contains(new KeyValuePair(invoice.Status, status))) { @@ -705,7 +712,7 @@ private int UpdateInvoiceJsonDataInDb(int invoiceId, string jsonData) public void UpdateInvoiceJsonData(Invoice invoice, int billingAddressID, int deliveryAddressID) { - var jsonData = InvoiceFormattedData.GetData(invoice, billingAddressID, deliveryAddressID); + var jsonData = _invoiceFormattedData.GetData(invoice, billingAddressID, deliveryAddressID); if (jsonData.LogoBase64Id != 0) { jsonData.LogoBase64 = null; @@ -716,7 +723,7 @@ public void UpdateInvoiceJsonData(Invoice invoice, int billingAddressID, int del public void UpdateInvoiceJsonDataAfterLinesUpdated(Invoice invoice) { - var jsonData = InvoiceFormattedData.GetDataAfterLinesUpdated(invoice); + var jsonData = _invoiceFormattedData.GetDataAfterLinesUpdated(invoice); if (jsonData.LogoBase64Id != 0) { jsonData.LogoBase64 = null; @@ -746,10 +753,10 @@ private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) public InvoiceSetting SaveInvoiceSettings(InvoiceSetting invoiceSetting) { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.InvoiceSetting = invoiceSetting; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); return tenantSettings.InvoiceSetting; } @@ -761,7 +768,7 @@ public virtual Invoice DeleteInvoice(int invoiceID) var invoice = GetByID(invoiceID); if (invoice == null) return null; - CRMSecurity.DemandDelete(invoice); + _crmSecurity.DemandDelete(invoice); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -773,7 +780,7 @@ public virtual Invoice DeleteInvoice(int invoiceID) public List DeleteBatchInvoices(int[] invoiceID) { - var invoices = GetInvoices(invoiceID).Where(CRMSecurity.CanDelete).ToList(); + var invoices = GetInvoices(invoiceID).Where(_crmSecurity.CanDelete).ToList(); if (!invoices.Any()) return invoices; // Delete relative keys @@ -799,7 +806,7 @@ private void DeleteBatchInvoicesExecute(List invoices) tx.Commit(); - dbInvoicesQuery.ToList().ForEach(invoice => FactoryIndexer.Delete(invoice)); + dbInvoicesQuery.ToList().ForEach(invoice => _factoryIndexer.Delete(invoice)); } @@ -812,13 +819,13 @@ private Invoice ToInvoice(DbInvoice dbInvoice) ID = dbInvoice.Id, Status = dbInvoice.Status, Number = dbInvoice.Number, - IssueDate = TenantUtil.DateTimeFromUtc(dbInvoice.IssueDate), + IssueDate = _tenantUtil.DateTimeFromUtc(dbInvoice.IssueDate), TemplateType = dbInvoice.TemplateType, ContactID = dbInvoice.ContactId, ConsigneeID = dbInvoice.ConsigneeId, EntityType = dbInvoice.EntityType, EntityID = dbInvoice.EntityId, - DueDate = TenantUtil.DateTimeFromUtc(dbInvoice.DueDate), + DueDate = _tenantUtil.DateTimeFromUtc(dbInvoice.DueDate), Language = dbInvoice.Language, Currency = dbInvoice.Currency, ExchangeRate = dbInvoice.ExchangeRate, @@ -827,14 +834,14 @@ private Invoice ToInvoice(DbInvoice dbInvoice) Description = dbInvoice.Description, JsonData = dbInvoice.JsonData, FileID = dbInvoice.FileId, - CreateOn = TenantUtil.DateTimeFromUtc(dbInvoice.CreateOn), + CreateOn = _tenantUtil.DateTimeFromUtc(dbInvoice.CreateOn), CreateBy = dbInvoice.CreateBy, LastModifedBy = dbInvoice.LastModifedBy }; if (dbInvoice.LastModifedOn.HasValue) { - result.LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoice.LastModifedOn.Value); + result.LastModifedOn = _tenantUtil.DateTimeFromUtc(dbInvoice.LastModifedOn.Value); } return result; @@ -887,7 +894,7 @@ private IQueryable GetDbInvoceByFilters( if (keywords.Length > 0) { List invoicesIds; - if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out invoicesIds)) + if (!_factoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out invoicesIds)) { foreach (var k in keywords) { @@ -909,28 +916,28 @@ private IQueryable GetDbInvoceByFilters( if (issueDateFrom != DateTime.MinValue && issueDateTo != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.IssueDate >= TenantUtil.DateTimeToUtc(issueDateFrom) && x.DueDate <= TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1))); + sqlQuery = sqlQuery.Where(x => x.IssueDate >= _tenantUtil.DateTimeToUtc(issueDateFrom) && x.DueDate <= _tenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1))); } else if (issueDateFrom != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.IssueDate > TenantUtil.DateTimeToUtc(issueDateFrom)); + sqlQuery = sqlQuery.Where(x => x.IssueDate > _tenantUtil.DateTimeToUtc(issueDateFrom)); } else if (issueDateTo != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.IssueDate < TenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1))); + sqlQuery = sqlQuery.Where(x => x.IssueDate < _tenantUtil.DateTimeToUtc(issueDateTo.AddDays(1).AddMinutes(-1))); } if (dueDateFrom != DateTime.MinValue && dueDateTo != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.DueDate >= TenantUtil.DateTimeToUtc(dueDateFrom) && x.DueDate <= TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1))); + sqlQuery = sqlQuery.Where(x => x.DueDate >= _tenantUtil.DateTimeToUtc(dueDateFrom) && x.DueDate <= _tenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1))); } else if (dueDateFrom != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.DueDate > TenantUtil.DateTimeToUtc(dueDateFrom)); + sqlQuery = sqlQuery.Where(x => x.DueDate > _tenantUtil.DateTimeToUtc(dueDateFrom)); } else if (dueDateTo != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.DueDate < TenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1))); + sqlQuery = sqlQuery.Where(x => x.DueDate < _tenantUtil.DateTimeToUtc(dueDateTo.AddDays(1).AddMinutes(-1))); } if (!String.IsNullOrEmpty(currency)) @@ -967,7 +974,7 @@ public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) { var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); - itemToUpdate.CreateOn = TenantUtil.DateTimeToUtc(creationDate); + itemToUpdate.CreateOn = _tenantUtil.DateTimeToUtc(creationDate); CRMDbContext.Invoices.Update(itemToUpdate); CRMDbContext.SaveChanges(); @@ -985,7 +992,7 @@ public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) { var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); - itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate); + itemToUpdate.LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate); CRMDbContext.Invoices.Update(itemToUpdate); diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 936c19e8536..5bd8e1924a3 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -323,51 +323,57 @@ public Dictionary GetRelativeItemsCount(ListType listType) case ListType.ContactStatus: { result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.Contacts), + .Join(Query(CRMDbContext.Contacts), x => x.Id, y => y.StatusId, - (x, y) => new { Column1 = x, Column2 = y.Count() }) - .Where(x => x.Column1.ListType == listType) - .OrderBy(x => x.Column1.SortOrder) - .ToDictionary(x => x.Column1.Id, x => x.Column2); + (x, y) => new { x, y }) + .Where(x => x.x.ListType == listType) + .GroupBy(x => x.x.Id) + .Select(x => new { Id = x.Key, Count = x.Count() }) + .ToDictionary(x => x.Id, x => x.Count); break; } case ListType.ContactType: { result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.Contacts), + .Join(Query(CRMDbContext.Contacts), x => x.Id, y => y.ContactTypeId, - (x, y) => new { Column1 = x, Column2 = y.Count() }) - .Where(x => x.Column1.ListType == listType) - .OrderBy(x => x.Column1.SortOrder) - .ToDictionary(x => x.Column1.Id, x => x.Column2); + (x, y) => new { x, y }) + .Where(x => x.x.ListType == listType) + .GroupBy(x => x.x.Id) + .Select(x => new { Id = x.Key, Count = x.Count() }) + .ToDictionary(x => x.Id, x => x.Count); + break; } case ListType.TaskCategory: { result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.Tasks), + .Join(Query(CRMDbContext.Tasks), x => x.Id, y => y.CategoryId, - (x, y) => new { Column1 = x, Column2 = y.Count() }) - .Where(x => x.Column1.ListType == listType) - .OrderBy(x => x.Column1.SortOrder) - .ToDictionary(x => x.Column1.Id, x => x.Column2); + (x, y) => new { x, y }) + .Where(x => x.x.ListType == listType) + .GroupBy(x => x.x.Id) + .Select(x => new { Id = x.Key, Count = x.Count() }) + .ToDictionary(x => x.Id, x => x.Count); break; } case ListType.HistoryCategory: { + result = Query(CRMDbContext.ListItem) - .GroupJoin(Query(CRMDbContext.RelationshipEvent), - x => x.Id, - y => y.CategoryId, - (x, y) => new { Column1 = x, Column2 = y.Count() }) - .Where(x => x.Column1.ListType == listType) - .OrderBy(x => x.Column1.SortOrder) - .ToDictionary(x => x.Column1.Id, x => x.Column2); + .Join(Query(CRMDbContext.RelationshipEvent), + x => x.Id, + y => y.CategoryId, + (x, y) => new { x, y }) + .Where(x => x.x.ListType == listType) + .GroupBy(x => x.x.Id) + .Select(x => new { Id = x.Key, Count = x.Count() }) + .ToDictionary(x => x.Id, x => x.Count); break; } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 34324514cfc..a50c3e9eebe 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -222,10 +222,11 @@ public int GetAllTasksCount() public List GetAllTasks() { - return _mapper.ProjectTo(Query(CRMDbContext.Tasks) + var dbTasks = Query(CRMDbContext.Tasks) .OrderBy(x => x.Deadline) - .OrderBy(x => x.Title)) - .ToList() + .OrderBy(x => x.Title).ToList(); + + return _mapper.Map, List>(dbTasks) .FindAll(CRMSecurity.CanAccessTo); } @@ -380,8 +381,7 @@ private List GetCrudeTasks( } } - - return _mapper.ProjectTo(sqlQuery).ToList(); + return _mapper.Map, List>(sqlQuery.ToList()); } public int GetTasksCount( diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index 9b53f1dd3d7..8a5bb762ad6 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -80,6 +80,7 @@ public class Deal : DomainObject, ISecurityObjectId, IMapFrom [DataMember(Name = "deal_milestone_probability")] public int DealMilestoneProbability { get; set; } + [DataMember(Name = "actual_close_date")] public DateTime ActualCloseDate { get; set; } //[DataMember(Name = "actual_close_date")] @@ -93,10 +94,9 @@ public class Deal : DomainObject, ISecurityObjectId, IMapFrom // set { ; } //} - + [DataMember(Name = "expected_close_date")] public DateTime ExpectedCloseDate { get; set; } - [DataMember(Name = "expected_close_date")] //private String ExpectedCloseDateStr //{ // get diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs index 33659d1591e..459e4857f07 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs @@ -218,7 +218,25 @@ public ContactBaseWithPhoneDto Convert(Contact source, ContactBaseWithPhoneDto d { if (source == null) return null; - var result = (ContactBaseWithPhoneDto)context.Mapper.Map(source); + if (source == null) return null; + + var contactBaseDto = context.Mapper.Map(source); + + var result = new ContactBaseWithPhoneDto + { + AccessList = contactBaseDto.AccessList, + CanDelete = contactBaseDto.CanDelete, + CanEdit = contactBaseDto.CanEdit, + Currency = contactBaseDto.Currency, + DisplayName = contactBaseDto.DisplayName, + Id = contactBaseDto.Id, + IsCompany = contactBaseDto.IsCompany, + IsPrivate = contactBaseDto.IsPrivate, + IsShared = contactBaseDto.IsShared, + MediumFotoUrl = contactBaseDto.MediumFotoUrl, + ShareType = contactBaseDto.ShareType, + SmallFotoUrl = contactBaseDto.SmallFotoUrl + }; var phone = _daoFactory.GetContactInfoDao().GetList(source.ID, ContactInfoType.Phone, null, true).FirstOrDefault(); @@ -231,7 +249,24 @@ public ContactBaseWithEmailDto Convert(Contact source, ContactBaseWithEmailDto d { if (source == null) return null; - var result = (ContactBaseWithEmailDto)context.Mapper.Map(source); + var contactBaseDto = context.Mapper.Map(source); + + var result = new ContactBaseWithEmailDto + { + AccessList = contactBaseDto.AccessList, + CanDelete = contactBaseDto.CanDelete, + CanEdit = contactBaseDto.CanEdit, + Currency = contactBaseDto.Currency, + DisplayName = contactBaseDto.DisplayName, + Id = contactBaseDto.Id, + IsCompany = contactBaseDto.IsCompany, + IsPrivate = contactBaseDto.IsPrivate, + IsShared = contactBaseDto.IsShared, + MediumFotoUrl = contactBaseDto.MediumFotoUrl, + ShareType = contactBaseDto.ShareType, + SmallFotoUrl = contactBaseDto.SmallFotoUrl + }; + var email = _daoFactory.GetContactInfoDao().GetList(source.ID, ContactInfoType.Email, null, true).FirstOrDefault(); result.Email = context.Mapper.Map(email); diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs index 2032c18bd22..3395de5b858 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs @@ -44,7 +44,7 @@ public TaskCategoryDtoTypeConverter(WebImageSupplier webImageSupplier) public TaskCategoryBaseDto Convert(ListItem source, TaskCategoryBaseDto destination, ResolutionContext context) { - return new TaskCategoryBaseDto(source) + return new TaskCategoryDto(source) { ImagePath = _webImageSupplier.GetAbsoluteWebPath(source.AdditionalParams, ProductEntryPoint.ID) }; From c0d9a1572c8f2a3329782d609f92545ba1c659ba Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 14:56:42 +0300 Subject: [PATCH 27/61] crm: refactoring --- .../Server/Api/CustomFieldsController.cs | 30 ++++----------- .../ApiModels/ResponsesDto/CustomFieldDto.cs | 23 +++++++++++- .../CustomFieldDtoTypeConverter.cs | 37 +++++++++++++++++++ products/ASC.CRM/Server/Startup.cs | 3 +- 4 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs diff --git a/products/ASC.CRM/Server/Api/CustomFieldsController.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs index f286d006e78..4cfde7d674b 100644 --- a/products/ASC.CRM/Server/Api/CustomFieldsController.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -72,7 +72,7 @@ public CustomFieldsController(CRMSecurity crmSecurity, [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/definitions")] public IEnumerable GetCustomFieldDefinitions(string entityType) { - return _daoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldDto); + return _mapper.Map,List>(_daoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType))); } /// @@ -86,7 +86,7 @@ public IEnumerable GetCustomFieldDefinitions(string entityType) [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield")] public IEnumerable GetCustomFieldForSubject(string entityType, int entityid) { - return _daoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseDto); + return _mapper.Map, List>(_daoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false)); } /// @@ -113,7 +113,7 @@ public CustomFieldBaseDto SetEntityCustomFieldValue(string entityType, int entit _daoFactory.GetCustomFieldDao().SetFieldValue(entityTypeStr, entityid, fieldid, fieldValue); - return ToCustomFieldBaseDto(customField); + return _mapper.Map(customField); } /// @@ -219,7 +219,7 @@ public CustomFieldDto CreateCustomFieldValue(string entityType, string label, in var messageAction = GetCustomFieldCreatedAction(entityTypeObj); _messageService.Send(messageAction, _messageTarget.Create(wrapper.ID), wrapper.Label); - return ToCustomFieldDto(_daoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); + return _mapper.Map(_daoFactory.GetCustomFieldDao().GetFieldDescription(fieldID)); } /// @@ -271,7 +271,7 @@ public CustomFieldDto UpdateCustomFieldValue(int id, string entityType, string l var messageAction = GetCustomFieldUpdatedAction(entityTypeObj); _messageService.Send(messageAction, _messageTarget.Create(customField.ID), customField.Label); - return ToCustomFieldDto(customField); + return _mapper.Map(customField); } /// @@ -295,7 +295,7 @@ public CustomFieldDto DeleteCustomField(string entityType, int fieldid) var customField = _daoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); if (customField == null) throw new ItemNotFoundException(); - var result = ToCustomFieldDto(customField); + var result = _mapper.Map(customField); _daoFactory.GetCustomFieldDao().DeleteField(fieldid); @@ -335,23 +335,9 @@ public IEnumerable UpdateCustomFieldsOrder(IEnumerable var messageAction = GetCustomFieldsUpdatedOrderAction(ToEntityType(entityType)); _messageService.Send(messageAction, _messageTarget.Create(fieldids), customFields.Select(x => x.Label)); - return customFields.Select(ToCustomFieldBaseDto); + return _mapper.Map, List>(customFields); } - - private static CustomFieldBaseDto ToCustomFieldBaseDto(CustomField customField) - { - return new CustomFieldBaseDto(customField); - } - - private CustomFieldDto ToCustomFieldDto(CustomField customField) - { - var result = new CustomFieldDto(customField) - { - RelativeItemsCount = _daoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID) - }; - return result; - } - + private static MessageAction GetCustomFieldCreatedAction(EntityType entityType) { switch (entityType) diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index af5da4b9bb9..02f57bf0d09 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -30,12 +30,20 @@ using ASC.Api.Core; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; + +using AutoMapper; namespace ASC.CRM.ApiModels { [DataContract(Name = "customField", Namespace = "")] - public class CustomFieldDto : CustomFieldBaseDto + public class CustomFieldDto : CustomFieldBaseDto, IMapFrom { + public CustomFieldDto() + { + + } + public CustomFieldDto(int id) : base(id) { @@ -60,14 +68,25 @@ public CustomFieldDto(CustomField customField) RelativeItemsCount = 0 }; } + + public void Mapping(Profile profile) + { + profile.CreateMap() + .ConvertUsing(); + } } /// /// User custom fields /// [DataContract(Name = "customField", Namespace = "")] - public class CustomFieldBaseDto + public class CustomFieldBaseDto : IMapFrom { + public CustomFieldBaseDto() + { + + } + public CustomFieldBaseDto(int id) { } diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs new file mode 100644 index 00000000000..1a29583d92f --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using ASC.CRM.ApiModels; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public class CustomFieldDtoTypeConverter : ITypeConverter + { + private readonly DaoFactory _daoFactory; + + public CustomFieldDtoTypeConverter(DaoFactory daoFactory) + { + _daoFactory = daoFactory; + + } + + public CustomFieldDto Convert(CustomField source, CustomFieldDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new CustomFieldDto(source) + { + RelativeItemsCount = _daoFactory.GetCustomFieldDao().GetContactLinkCount(source.EntityType, source.ID) + }; + + return result; + } + } +} diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index a1e81e488b7..dc1ff2b601d 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -57,7 +57,8 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); - + DIHelper.TryAdd(); + services.AddAutoMapper(Assembly.GetExecutingAssembly()); } From 2b1b3e508fc9fc44399f5d5ff02ba84e68037999 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 15:42:03 +0300 Subject: [PATCH 28/61] crm: refactoring --- .../ASC.CRM/Server/Api/CasesController.cs | 2 +- .../ASC.CRM/Server/Api/DealsController.cs | 2 +- .../ApiModels/ResponsesDto/CustomFieldDto.cs | 31 ++----------------- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 17 +++++----- .../Server/Core/Dao/DealMilestoneDao.cs | 14 +++++---- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 21 +++++++------ .../TypeConverter/CasesDtoTypeConverter.cs | 2 +- .../TypeConverter/ContactDtoTypeConverter.cs | 4 +-- .../CustomFieldDtoTypeConverter.cs | 9 +++++- .../OpportunityDtoTypeConverter.cs | 2 +- 10 files changed, 44 insertions(+), 60 deletions(-) diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index 284aba48235..6533a989b16 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -741,7 +741,7 @@ private IEnumerable ToListCasesDtos(ICollection items) var customFields = _daoFactory.GetCustomFieldDao() .GetEnityFields(EntityType.Case, casesIDs) .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); + .ToDictionary(item => item.Key, item => item.Select(x => _mapper.Map(x))); var casesMembers = _daoFactory.GetCasesDao().GetMembers(casesIDs); diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index e8228ea0884..57d41899ac6 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -913,7 +913,7 @@ private IEnumerable ToListOpportunityDto(ICollection deals var customFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray()) .GroupBy(item => item.EntityID) - .ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); + .ToDictionary(item => item.Key, item => item.Select(x => _mapper.Map(x))); var dealMilestones = _daoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray()) .ToDictionary(item => item.ID, item => new DealMilestoneBaseDto(item)); diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index 02f57bf0d09..0319b75b2b2 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -44,20 +44,11 @@ public CustomFieldDto() } - public CustomFieldDto(int id) - : base(id) - { - } - - public CustomFieldDto(CustomField customField) - : base(customField) - { - } public int RelativeItemsCount { get; set; } public new static CustomFieldDto GetSample() { - return new CustomFieldDto(0) + return new CustomFieldDto { Position = 10, EntityId = 14523423, @@ -86,23 +77,7 @@ public CustomFieldBaseDto() { } - - public CustomFieldBaseDto(int id) - { - } - - public CustomFieldBaseDto(CustomField customField) - { - if (customField != null) - - EntityId = customField.EntityID; - Label = customField.Label; - FieldValue = customField.Value; - FieldType = customField.FieldType; - Position = customField.Position; - Mask = customField.Mask; - } - + [DataMember(Name = "id")] public int Id { get; set; } public int EntityId { get; set; } @@ -113,7 +88,7 @@ public CustomFieldBaseDto(CustomField customField) public String Mask { get; set; } public static CustomFieldBaseDto GetSample() { - return new CustomFieldBaseDto(0) + return new CustomFieldBaseDto { Position = 10, EntityId = 14523423, diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 158a8c47aaa..3b1b35bb132 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -415,11 +415,11 @@ public String GetContactLinkCountJSON(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.FieldDescription).GroupJoin(Query(CRMDbContext.FieldValue), - x => x.Id, - y => y.FieldId, - (x, y) => new { x = x, count = y.Count() } - ); + var sqlQuery = Query(CRMDbContext.FieldDescription).Join(Query(CRMDbContext.FieldValue), + x => x.Id, + y => y.FieldId, + (x, y) => new { x, y } + ); if (entityType == EntityType.Company || entityType == EntityType.Person) { @@ -429,10 +429,9 @@ public String GetContactLinkCountJSON(EntityType entityType) { sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType); } - - sqlQuery = sqlQuery.OrderBy(x => x.x.SortOrder); - - return JsonConvert.SerializeObject(sqlQuery.Select(x => x.count).ToList()); + + return JsonConvert.SerializeObject(sqlQuery.GroupBy(x => x.x.Id) + .Select(x => x.Count()).ToList()); } public int GetContactLinkCount(EntityType entityType, int entityID) diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 4471b6bea44..44cf6e5bf50 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -162,12 +162,14 @@ public int GetCount() public Dictionary GetRelativeItemsCount() { - return Query(CRMDbContext.DealMilestones).GroupJoin(CRMDbContext.Deals, - x => x.Id, - x => x.DealMilestoneId, - (x, y) => new { x = x, count = y.Count() }) - .OrderBy(x => x.x.SortOrder) - .ToDictionary(x => x.x.Id, y => y.count); + return Query(CRMDbContext.DealMilestones) + .Join(CRMDbContext.Deals, + x => x.Id, + x => x.DealMilestoneId, + (x, y) => new { x = x, y = y }) + .GroupBy(x => x.x.Id) + .Select(x => new { Id = x.Key, Count = x.Count() }) + .ToDictionary(x => x.Id, y => y.Count); } public int GetRelativeItemsCount(int id) diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index a771f4cf15e..031238dad3d 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -108,13 +108,13 @@ public String GetTagsLinkCountJSON(EntityType entityType) public IEnumerable GetTagsLinkCount(EntityType entityType) { return Query(CRMDbContext.Tags) - .GroupJoin(CRMDbContext.EntityTags, + .Join(CRMDbContext.EntityTags, x => x.Id, y => y.TagId, - (x, y) => new { x = x, count = y.Count() }) + (x, y) => new { x, y }) .Where(x => x.x.EntityType == entityType) - .OrderBy(x => x.x.Title) - .Select(x => x.count).ToList(); + .GroupBy(x => x.x.Id) + .Select(x => x.Count()); } @@ -150,7 +150,7 @@ public String[] GetEntityTags(EntityType entityType, int entityID) public string[] GetUnusedTags(EntityType entityType) { return Query(CRMDbContext.Tags) - .GroupJoin(CRMDbContext.EntityTags.DefaultIfEmpty(), + .Join(CRMDbContext.EntityTags.DefaultIfEmpty(), x => x.Id, y => y.TagId, (x, y) => new { x, y }) @@ -209,11 +209,12 @@ public void DeleteUnusedTags(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var itemToDelete = Query(CRMDbContext.Tags).GroupJoin(CRMDbContext.EntityTags, - x => x.Id, - y => y.TagId, - (x, y) => new { x, y } - ).Where(x => x.x.EntityType == entityType && x.y == null).Select(x => x.x).ToList(); + var itemToDelete = Query(CRMDbContext.Tags) + .Join(CRMDbContext.EntityTags.DefaultIfEmpty(), + x => x.Id, + y => y.TagId, + (x, y) => new { x, y }) + .Where(x => x.x.EntityType == entityType && x.y == null).Select(x => x.x).ToList(); CRMDbContext.RemoveRange(itemToDelete); diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs index 04aefac9570..0b584cbdbf6 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs @@ -83,7 +83,7 @@ public CasesDto Convert(Cases source, CasesDto destination, ResolutionContext co result.CustomFields = _daoFactory .GetCustomFieldDao() .GetEnityFields(EntityType.Case, source.ID, false) - .ConvertAll(item => new CustomFieldBaseDto(item)); + .ConvertAll(item => context.Mapper.Map(item)); result.Members = new List(); diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs index 459e4857f07..1ab879402c0 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs @@ -147,7 +147,7 @@ public ContactDto Convert(Contact source, ContactDto destination, ResolutionCont result.CustomFields = _daoFactory.GetCustomFieldDao() .GetEnityFields(source is Person ? EntityType.Person : EntityType.Company, source.ID, false) - .ConvertAll(item => new CustomFieldBaseDto(item)); + .ConvertAll(item => context.Mapper.Map(item)); return result; } @@ -342,7 +342,7 @@ public List Convert(List source, List destinati var companyCustomFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Company, companyIDs.ToArray()); var customFields = personsCustomFields.Union(companyCustomFields) - .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(x => new CustomFieldBaseDto(x))); + .GroupBy(item => item.EntityID).ToDictionary(item => item.Key, item => item.Select(x => context.Mapper.Map(x))); var addresses = new Dictionary>(); var taskCount = _daoFactory.GetTaskDao().GetTasksCount(contactIDs); diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs index 1a29583d92f..b970a8f655d 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs @@ -26,8 +26,15 @@ public CustomFieldDto Convert(CustomField source, CustomFieldDto destination, Re if (destination != null) throw new NotImplementedException(); - var result = new CustomFieldDto(source) + var result = new CustomFieldDto { + Id = source.ID, + EntityId = source.EntityID, + FieldType = source.FieldType, + FieldValue = source.Value, + Label = source.Label, + Mask = source.Mask, + Position = source.Position, RelativeItemsCount = _daoFactory.GetCustomFieldDao().GetContactLinkCount(source.EntityType, source.ID) }; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs index 7fa7e7b175a..9dadafea148 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs @@ -102,7 +102,7 @@ public OpportunityDto Convert(Deal source, OpportunityDto destination, Resolutio if (!string.IsNullOrEmpty(source.BidCurrency)) dealDto.BidCurrency = context.Mapper.Map(_currencyProvider.Get(source.BidCurrency)); - dealDto.CustomFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, source.ID, false).ConvertAll(item => new CustomFieldBaseDto(item)); + dealDto.CustomFields = _daoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, source.ID, false).ConvertAll(item => context.Mapper.Map(item)); dealDto.Members = new List(); From 1fac4bc1fe894606cda3a55414a3ac44e24fa2c4 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 18:48:08 +0300 Subject: [PATCH 29/61] crm: refactoring --- .../ASC.CRM/Server/Api/ContactsController.cs | 4 - .../ApiModels/ResponsesDto/ContactDto.cs | 76 +++++++------------ products/ASC.CRM/Server/Startup.cs | 25 +++++- 3 files changed, 53 insertions(+), 52 deletions(-) diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index e234e8dd362..c93e57b1cc1 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -348,12 +348,8 @@ public IEnumerable GetContacts( [FromQuery] ApiDateTime toDate) { IEnumerable result; - OrderBy contactsOrderBy; - ContactSortedByType sortBy; - - var searchString = _apiContext.FilterValue; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs index 390cf17e0e0..cda764133fc 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -26,7 +26,10 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; +using System.Text.Json; +using System.Text.Json.Serialization; using ASC.Api.Core; using ASC.Common; @@ -116,8 +119,6 @@ public class CompanyDto : ContactDto } [DataContract(Name = "contact", Namespace = "")] - [KnownType(typeof(PersonDto))] - [KnownType(typeof(CompanyDto))] public class ContactDto : ContactBaseDto, IMapFrom { public ContactDto() @@ -125,16 +126,6 @@ public ContactDto() } - //protected ContactDto(Contact contact) - // : base(contact) - //{ - // CreateBy = EmployeeWraper.Get(contact.CreateBy); - // Created = (ApiDateTime)contact.CreateOn; - // About = contact.About; - // Industry = contact.Industry; - //} - - public IEnumerable
    Addresses { get; set; } public EmployeeWraper CreateBy { get; set; } public ApiDateTime Created { get; set; } @@ -190,50 +181,45 @@ public class ContactBaseWithEmailDto : ContactBaseDto public ContactInfoDto Email { get; set; } } - [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithPhoneDto : ContactBaseDto { public ContactInfoDto Phone { get; set; } } + public class ContactDtoJsonConverter : JsonConverter + { + public override ContactDto Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + public override void Write(Utf8JsonWriter writer, ContactDto value, JsonSerializerOptions options) + { + if (value is PersonDto) + { + JsonSerializer.Serialize(writer, (PersonDto)value!, options); + return; + } + if (value is CompanyDto) + { + JsonSerializer.Serialize(writer, (CompanyDto)value!, options); + return; + } + if (value is ContactDto) + { + JsonSerializer.Serialize(writer, value!, options); + return; + } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + throw new NotImplementedException(); + } + } /// /// Contact base information @@ -275,11 +261,7 @@ public static ContactBaseDto GetSample() [DataContract(Name = "contact_task", Namespace = "")] public class ContactWithTaskDto { - public TaskBaseDto Task { get; set; } - - public ContactDto Contact { get; set; } } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index dc1ff2b601d..d79524b094c 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,9 +1,16 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using ASC.Api.Core; using ASC.Common; using ASC.CRM.Api; +using ASC.CRM.ApiModels; using ASC.CRM.Mapping; using ASC.Web.CRM.HttpHandlers; @@ -58,7 +65,7 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); - + services.AddAutoMapper(Assembly.GetExecutingAssembly()); } @@ -110,5 +117,21 @@ public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) }); } + + public override JsonConverter[] Converters + { + get + { + var jsonConverters = new List + { + new ContactDtoJsonConverter() + }; + + return jsonConverters.ToArray(); + } + } + } } + + From 7c96b2f6259a2ca7c60205a052c59468b291fd2a Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 19:04:37 +0300 Subject: [PATCH 30/61] core: migrate several interfaces --- web/ASC.Web.Core/Utility/IFileUploadHandler.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/ASC.Web.Core/Utility/IFileUploadHandler.cs b/web/ASC.Web.Core/Utility/IFileUploadHandler.cs index 0d4fae9fde1..959a48797e7 100644 --- a/web/ASC.Web.Core/Utility/IFileUploadHandler.cs +++ b/web/ASC.Web.Core/Utility/IFileUploadHandler.cs @@ -30,9 +30,12 @@ namespace ASC.Web.Core.Utility { public class FileUploadResult { + public bool Success { get; set; } public object Data { get; set; } public string Message { get; set; } + public string FileName { get; set; } + public string FileURL { get; set; } } public interface IFileUploadHandler From c750a55e36ba9664e182e9f286dcb9e0fbd2899d Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 19:07:34 +0300 Subject: [PATCH 31/61] core: added ControllerNameAttribute --- .../ControllerNameAttributeConvention.cs | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs diff --git a/common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs b/common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs new file mode 100644 index 00000000000..af35112c35c --- /dev/null +++ b/common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Mvc.ApplicationModels; + +namespace ASC.Api.Core.Convention +{ + [AttributeUsage(AttributeTargets.Class)] + public class ControllerNameAttribute : Attribute + { + public string Name { get; } + + public ControllerNameAttribute(string name) + { + Name = name; + } + } + + public class ControllerNameAttributeConvention : IControllerModelConvention + { + public void Apply(ControllerModel controller) + { + var controllerNameAttribute = controller.Attributes.OfType().SingleOrDefault(); + if (controllerNameAttribute != null) + { + controller.ControllerName = controllerNameAttribute.Name; + } + } + } +} From 11e37380903275adab8d4cb177ae3459fa19ee3c Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 19:10:14 +0300 Subject: [PATCH 32/61] files: added 'scope' attribute for several classes --- .../DocumentService/DocbuilderReportsUtility.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/products/ASC.Files/Core/Services/DocumentService/DocbuilderReportsUtility.cs b/products/ASC.Files/Core/Services/DocumentService/DocbuilderReportsUtility.cs index 021856f78e2..8361e83032c 100644 --- a/products/ASC.Files/Core/Services/DocumentService/DocbuilderReportsUtility.cs +++ b/products/ASC.Files/Core/Services/DocumentService/DocbuilderReportsUtility.cs @@ -28,8 +28,9 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using System.Web; - +using System.Web; + +using ASC.Common; using ASC.Common.Logging; using ASC.Common.Threading; using ASC.Core; @@ -250,7 +251,7 @@ protected void FillDistributedTask() TaskInfo.SetProperty("exception", Exception); } } - + [Scope] public class DocbuilderReportsUtility { private readonly DistributedTaskQueue tasks; @@ -321,7 +322,8 @@ internal static string GetCacheKey(ReportOrigin origin, int tenantId, Guid userI return $"{tenantId}_{userId}_{(int)origin}"; } } - + + [Scope] public class DocbuilderReportsUtilityHelper { public DocbuilderReportsUtility DocbuilderReportsUtility { get; } From 950506a59cdbfc651e7543b620a22138e9552ca0 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 22 Mar 2021 19:13:15 +0300 Subject: [PATCH 33/61] calendar: migrate extension for DateTime --- web/ASC.Web.Core/Calendars/RecurrenceRule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/ASC.Web.Core/Calendars/RecurrenceRule.cs b/web/ASC.Web.Core/Calendars/RecurrenceRule.cs index ca1139ffe79..94443eaaf37 100644 --- a/web/ASC.Web.Core/Calendars/RecurrenceRule.cs +++ b/web/ASC.Web.Core/Calendars/RecurrenceRule.cs @@ -73,6 +73,12 @@ public static int GetDayOfWeekInMonth(this DateTime date) } return count; } + + public static string ToShortString(this DateTime targetDateTime) + { + return String.Format("{0} {1}", targetDateTime.ToShortDateString(), targetDateTime.ToShortTimeString()); + } + } public enum Frequency From 11acb31f5479af0cdbb799939cd5f046726e74af Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 23 Mar 2021 18:41:56 +0300 Subject: [PATCH 34/61] crm: refactoring --- products/ASC.CRM/Server/ASC.CRM.csproj | 1 + .../ASC.CRM/Server/Api/CasesController.cs | 92 ++--- .../Server/Api/ContactInfosController.cs | 2 - .../ASC.CRM/Server/Api/ContactsController.cs | 2 +- .../Server/Api/CurrencyRatesController.cs | 40 ++- .../Server/Api/CustomFieldsController.cs | 8 +- .../ASC.CRM/Server/Api/DealsController.cs | 111 +++--- .../ASC.CRM/Server/Api/InvoicesController.cs | 6 +- .../ASC.CRM/Server/Api/ListItemsController.cs | 80 ++--- .../Api/RelationshipEventsController.cs | 79 ++--- .../ASC.CRM/Server/Api/ReportsController.cs | 50 +-- products/ASC.CRM/Server/Api/TagsController.cs | 30 +- .../Server/Api/TaskTemplateController.cs | 7 +- .../ASC.CRM/Server/Api/UtilsController.cs | 154 ++++----- products/ASC.CRM/Server/Api/VoipController.cs | 150 ++++---- .../ApiModels/ResponsesDto/ContactDto.cs | 12 +- .../ApiModels/ResponsesDto/CustomFieldDto.cs | 4 +- .../ApiModels/ResponsesDto/ListItemDto.cs | 27 +- .../ASC.CRM/Server/Classes/CRMSettings.cs | 72 ++-- products/ASC.CRM/Server/Classes/Global.cs | 3 +- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 7 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 16 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 324 +++++++++--------- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 8 +- .../Server/Core/Entities/RelationshipEvent.cs | 1 - .../Helpers/CurrencyRateInfoDtoHelper.cs | 2 +- .../Helpers/HistoryCategoryDtoHelper.cs | 52 --- .../TypeConverter/ContactDtoTypeConverter.cs | 1 - .../CustomFieldDtoTypeConverter.cs | 3 - .../InvoiceBaseDtoTypeConverter.cs | 5 +- .../TypeConverter/InvoiceDtoTypeConverter.cs | 5 +- .../InvoiceItemDtoTypeConverter.cs | 5 +- ...nverter.cs => ListItemDtoTypeConverter.cs} | 31 +- .../RelationshipEventDtoTypeConverter.cs | 24 +- .../Server/Properties/launchSettings.json | 13 +- products/ASC.CRM/Server/Startup.cs | 6 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 6 +- .../Server/Utils/Import/CSV/ImportContacts.cs | 2 +- .../Server/Utils/Import/CSV/ImportDeals.cs | 5 +- products/ASC.CRM/Server/Utils/MailSender.cs | 16 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 14 +- 42 files changed, 715 insertions(+), 765 deletions(-) delete mode 100644 products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs rename products/ASC.CRM/Server/Mapping/TypeConverter/{TaskCategoryDtoTypeConverter.cs => ListItemDtoTypeConverter.cs} (66%) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index cd10a82868b..6db6794da8d 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -2,6 +2,7 @@ netcoreapp3.1 + ac29beb8-6c38-4b45-9c56-6331e3c67472 diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index 6533a989b16..e743a67a4a0 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -53,6 +53,13 @@ namespace ASC.CRM.Api { public class CasesController : BaseApiController { + private readonly DisplayUserSettingsHelper _displayUserSettingsHelper; + private readonly SecurityContext _securityContext; + private readonly NotifyClient _notifyClient; + private readonly ApiContext _apiContext; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + private readonly UserManager _userManager; public CasesController(CRMSecurity crmSecurity, DaoFactory daoFactory, @@ -66,23 +73,16 @@ public CasesController(CRMSecurity crmSecurity, IMapper mapper) : base(daoFactory, crmSecurity, mapper) { - ApiContext = apiContext; - MessageTarget = messageTarget; - MessageService = messageService; - NotifyClient = notifyClient; - SecurityContext = securityContext; - DisplayUserSettingsHelper = displayUserSettingsHelper; - UserManager = userManager; + _apiContext = apiContext; + _messageTarget = messageTarget; + _messageService = messageService; + _notifyClient = notifyClient; + _securityContext = securityContext; + _displayUserSettingsHelper = displayUserSettingsHelper; + _userManager = userManager; _mapper = mapper; } - public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } - public SecurityContext SecurityContext { get; } - public NotifyClient NotifyClient { get; } - private ApiContext ApiContext { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } - public UserManager UserManager { get; } /// /// Close the case with the ID specified in the request @@ -103,7 +103,7 @@ public CasesDto CloseCases(int caseid) var cases = _daoFactory.GetCasesDao().CloseCases(caseid); if (cases == null) throw new ItemNotFoundException(); - MessageService.Send(MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title); + _messageService.Send(MessageAction.CaseClosed, _messageTarget.Create(cases.ID), cases.Title); return _mapper.Map(cases); @@ -128,7 +128,7 @@ public CasesDto ReOpenCases(int caseid) var cases = _daoFactory.GetCasesDao().ReOpenCases(caseid); if (cases == null) throw new ItemNotFoundException(); - MessageService.Send(MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title); + _messageService.Send(MessageAction.CaseOpened, _messageTarget.Create(cases.ID), cases.Title); return _mapper.Map(cases); } @@ -178,7 +178,7 @@ public CasesDto CreateCases([FromForm] CreateOrUpdateCasesRequestDto inDto) { ID = casesID, Title = title, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, CreateOn = DateTime.UtcNow }; @@ -255,7 +255,7 @@ public CasesDto UpdateCases(int caseid, [FromForm] CreateOrUpdateCasesRequestDto _daoFactory.GetCasesDao().UpdateCases(cases); - if (_crmSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) + if (_crmSecurity.IsAdmin || cases.CreateBy == _securityContext.CurrentAccount.ID) { SetAccessToCases(cases, isPrivate, accessList, isNotify, false); } @@ -302,7 +302,7 @@ public CasesDto SetAccessToCases(int caseid, bool isPrivate, IEnumerable a var cases = _daoFactory.GetCasesDao().GetByID(caseid); if (cases == null) throw new ItemNotFoundException(); - if (!(_crmSecurity.IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin || cases.CreateBy == _securityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); return SetAccessToCases(cases, isPrivate, accessList, false, true); } @@ -314,20 +314,20 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable { if (isNotify) { - accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList(); - NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, _daoFactory, accessListLocal.ToArray()); + accessListLocal = accessListLocal.Where(u => u != _securityContext.CurrentAccount.ID).ToList(); + _notifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, _daoFactory, accessListLocal.ToArray()); } - if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) + if (!accessListLocal.Contains(_securityContext.CurrentAccount.ID)) { - accessListLocal.Add(SecurityContext.CurrentAccount.ID); + accessListLocal.Add(_securityContext.CurrentAccount.ID); } _crmSecurity.SetAccessTo(cases, accessListLocal); if (isMessageServicSende) { var users = GetUsersByIdList(accessListLocal); - MessageService.Send(MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); + _messageService.Send(MessageAction.CaseRestrictedAccess, _messageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); } } else @@ -335,7 +335,7 @@ private CasesDto SetAccessToCases(Cases cases, bool isPrivate, IEnumerable _crmSecurity.MakePublic(cases); if (isMessageServicSende) { - MessageService.Send(MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title); + _messageService.Send(MessageAction.CaseOpenedAccess, _messageTarget.Create(cases.ID), cases.Title); } } @@ -372,7 +372,7 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa { if (c == null) throw new ItemNotFoundException(); - if (!(_crmSecurity.IsAdmin || c.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || c.CreateBy == _securityContext.CurrentAccount.ID)) continue; SetAccessToCases(c, isPrivate, accessList, false, true); result.Add(c); @@ -407,7 +407,7 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa var result = new List(); - var caseses = _daoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + var caseses = _daoFactory.GetCasesDao().GetCases(_apiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); if (!caseses.Any()) return new List(); @@ -415,7 +415,7 @@ public IEnumerable SetAccessToBatchCases([FromForm] SetAccessToBatchCa { if (casese == null) throw new ItemNotFoundException(); - if (!(_crmSecurity.IsAdmin || casese.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || casese.CreateBy == _securityContext.CurrentAccount.ID)) continue; SetAccessToCases(casese, isPrivate, accessList, false, true); result.Add(casese); @@ -461,13 +461,13 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable SortedByType sortBy; OrderBy casesOrderBy; - var searchString = ApiContext.FilterValue; + var searchString = _apiContext.FilterValue; - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy)) + if (ASC.CRM.Classes.EnumExtension.TryParse(_apiContext.SortBy, true, out sortBy)) { - casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending); + casesOrderBy = new OrderBy(sortBy, !_apiContext.SortDescending); } - else if (string.IsNullOrEmpty(ApiContext.SortBy)) + else if (string.IsNullOrEmpty(_apiContext.SortBy)) { casesOrderBy = new OrderBy(SortedByType.Title, true); } @@ -476,8 +476,8 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable casesOrderBy = null; } - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; + var fromIndex = (int)_apiContext.StartIndex; + var count = (int)_apiContext.Count; if (casesOrderBy != null) { @@ -493,9 +493,9 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable count, casesOrderBy)).ToList(); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else { @@ -521,7 +521,7 @@ public IEnumerable GetCases(int contactid, bool? isClosed, IEnumerable totalCount = _daoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags); } - ApiContext.SetTotalCount(totalCount); + _apiContext.SetTotalCount(totalCount); return result; } @@ -545,7 +545,7 @@ public CasesDto DeleteCase(int caseid) if (cases == null) throw new ItemNotFoundException(); - MessageService.Send(MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title); + _messageService.Send(MessageAction.CaseDeleted, _messageTarget.Create(cases.ID), cases.Title); return _mapper.Map(cases); } @@ -571,7 +571,7 @@ public IEnumerable DeleteBatchCases([FromForm] IEnumerable casesi if (caseses == null || !caseses.Any()) return new List(); - MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title)); + _messageService.Send(MessageAction.CasesDeleted, _messageTarget.Create(casesids), caseses.Select(c => c.Title)); return ToListCasesDtos(caseses); } @@ -592,12 +592,12 @@ public IEnumerable DeleteBatchCases([FromForm] IEnumerable casesi [Delete(@"case/filter")] public IEnumerable DeleteBatchCases(int contactid, bool? isClosed, IEnumerable tags) { - var caseses = _daoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); + var caseses = _daoFactory.GetCasesDao().GetCases(_apiContext.FilterValue, contactid, isClosed, tags, 0, 0, null); if (!caseses.Any()) return new List(); caseses = _daoFactory.GetCasesDao().DeleteBatchCases(caseses); - MessageService.Send(MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); + _messageService.Send(MessageAction.CasesDeleted, _messageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title)); return ToListCasesDtos(caseses); } @@ -647,7 +647,7 @@ public ContactDto AddMemberToCases(int caseid, int contactid) _daoFactory.GetCasesDao().AddMember(caseid, contactid); var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson; - MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); return _mapper.Map(contact); } @@ -681,7 +681,7 @@ public ContactDto DeleteMemberFromCases(int caseid, int contactid) var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson; - MessageService.Send(messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(cases.ID), cases.Title, contact.GetTitle()); return result; } @@ -713,7 +713,7 @@ public IEnumerable GetCasesByPrefix(string prefix, int contactID) } } - ApiContext.SetTotalCount(findedCases.Count); + _apiContext.SetTotalCount(findedCases.Count); } else { @@ -775,7 +775,7 @@ private IEnumerable ToListCasesDtos(ICollection items) private IEnumerable GetUsersByIdList(IEnumerable ids) { - return UserManager.GetUsers().Where(x => ids.Contains(x.ID)); + return _userManager.GetUsers().Where(x => ids.Contains(x.ID)); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index 292cea8b131..b888d0659aa 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -41,8 +41,6 @@ using AutoMapper; -using Microsoft.AspNetCore.Mvc; - using Newtonsoft.Json; using Newtonsoft.Json.Serialization; diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index c93e57b1cc1..56bbcba57f9 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -350,7 +350,7 @@ public IEnumerable GetContacts( IEnumerable result; OrderBy contactsOrderBy; ContactSortedByType sortBy; - + var searchString = _apiContext.FilterValue; if (ASC.CRM.Classes.EnumExtension.TryParse(_apiContext.SortBy, true, out sortBy)) diff --git a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs index a28b745390d..3d3ee6fe305 100644 --- a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs +++ b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs @@ -44,6 +44,11 @@ namespace ASC.CRM.Api { public class CurrencyRatesController : BaseApiController { + private readonly CurrencyProvider _currencyProvider; + private readonly SettingsManager _settingsManager; + private readonly Global _global; + private readonly MessageService _messageService; + public CurrencyRatesController(CRMSecurity crmSecurity, DaoFactory daoFactory, MessageService messageService, @@ -53,16 +58,12 @@ public CurrencyRatesController(CRMSecurity crmSecurity, IMapper mapper) : base(daoFactory, crmSecurity, mapper) { - MessageService = messageService; - SettingsManager = settingsManager; - Global = global; - CurrencyProvider = currencyProvider; + _messageService = messageService; + _settingsManager = settingsManager; + _global = global; + _currencyProvider = currencyProvider; } - public CurrencyProvider CurrencyProvider { get; } - public SettingsManager SettingsManager { get; } - public Global Global { get; } - public MessageService MessageService { get; } //TABLE `crm_currency_rate` column `rate` DECIMAL(10,2) NOT NULL public const decimal MaxRateValue = (decimal)99999999.99; @@ -141,7 +142,7 @@ public CurrencyRateDto CreateCurrencyRate(string fromCurrency, string toCurrency }; currencyRate.ID = _daoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); - MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); + _messageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); return _mapper.Map(currencyRate); } @@ -172,7 +173,7 @@ public CurrencyRateDto UpdateCurrencyRate(int id, string fromCurrency, string to currencyRate.Rate = rate; currencyRate.ID = _daoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate); - MessageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); + _messageService.Send(MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency); return _mapper.Map(currencyRate); } @@ -196,23 +197,26 @@ public List SetCurrencyRates(String currency, List().DefaultCurrency.Abbreviation != currency) + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(_settingsManager.Load().DefaultCurrency); + + if (defaultCurrency.Abbreviation != currency) { - var cur = CurrencyProvider.Get(currency); + var cur = _currencyProvider.Get(currency); if (cur == null) throw new ArgumentException(); - Global.SaveDefaultCurrencySettings(cur); + _global.SaveDefaultCurrencySettings(cur); - MessageService.Send(MessageAction.CrmDefaultCurrencyUpdated); + _messageService.Send(MessageAction.CrmDefaultCurrencyUpdated); } rates = _daoFactory.GetCurrencyRateDao().SetCurrencyRates(rates); foreach (var rate in rates) { - MessageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + _messageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); } return rates.Select(x => _mapper.Map(x)).ToList(); @@ -245,7 +249,7 @@ public List AddCurrencyRates(List rates) existingRate.Rate = rate.Rate; _daoFactory.GetCurrencyRateDao().SaveOrUpdate(existingRate); - MessageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + _messageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); exist = true; break; } @@ -253,7 +257,7 @@ public List AddCurrencyRates(List rates) if (exist) continue; rate.ID = _daoFactory.GetCurrencyRateDao().SaveOrUpdate(rate); - MessageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); + _messageService.Send(MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency); existingRates.Add(rate); } @@ -301,7 +305,7 @@ private void ValidateCurrencies(string[] currencies) if (currencies.Any(string.IsNullOrEmpty)) throw new ArgumentException(); - var available = CurrencyProvider.GetAll().Select(x => x.Abbreviation); + var available = _currencyProvider.GetAll().Select(x => x.Abbreviation); var unknown = currencies.Where(x => !available.Contains(x)).ToArray(); diff --git a/products/ASC.CRM/Server/Api/CustomFieldsController.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs index 4cfde7d674b..d194674dc0b 100644 --- a/products/ASC.CRM/Server/Api/CustomFieldsController.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -44,8 +44,8 @@ namespace ASC.CRM.Api { public class CustomFieldsController : BaseApiController { - private MessageService _messageService; - private MessageTarget _messageTarget; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; public CustomFieldsController(CRMSecurity crmSecurity, DaoFactory daoFactory, @@ -72,7 +72,7 @@ public CustomFieldsController(CRMSecurity crmSecurity, [Read(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield/definitions")] public IEnumerable GetCustomFieldDefinitions(string entityType) { - return _mapper.Map,List>(_daoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType))); + return _mapper.Map, List>(_daoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType))); } /// @@ -337,7 +337,7 @@ public IEnumerable UpdateCustomFieldsOrder(IEnumerable return _mapper.Map, List>(customFields); } - + private static MessageAction GetCustomFieldCreatedAction(EntityType entityType) { switch (entityType) diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index 57d41899ac6..f7d77ea7d1d 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -53,7 +53,17 @@ namespace ASC.CRM.Api { public class DealsController : BaseApiController { - public DealsController(CRMSecurity cRMSecurity, + private readonly DisplayUserSettingsHelper _displayUserSettingsHelper; + private readonly NotifyClient _notifyClient; + private readonly ApiContext _apiContext; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + private readonly SecurityContext _securityContext; + private readonly CurrencyProvider _currencyProvider; + private readonly UserManager _userManager; + private readonly EmployeeWraperHelper _employeeWraperHelper; + + public DealsController(CRMSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, @@ -63,28 +73,21 @@ public DealsController(CRMSecurity cRMSecurity, UserManager userManager, EmployeeWraperHelper employeeWraperHelper, DisplayUserSettingsHelper displayUserSettingsHelper, + SecurityContext securityContext, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { - ApiContext = apiContext; - MessageTarget = messageTarget; - MessageService = messageService; - NotifyClient = notifyClient; - CurrencyProvider = currencyProvider; - UserManager = userManager; - EmployeeWraperHelper = employeeWraperHelper; - DisplayUserSettingsHelper = displayUserSettingsHelper; + _apiContext = apiContext; + _messageTarget = messageTarget; + _messageService = messageService; + _notifyClient = notifyClient; + _currencyProvider = currencyProvider; + _userManager = userManager; + _employeeWraperHelper = employeeWraperHelper; + _displayUserSettingsHelper = displayUserSettingsHelper; + _securityContext = securityContext; } - public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } - public NotifyClient NotifyClient { get; } - private ApiContext ApiContext { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } - public SecurityContext SecurityContext { get; } - public CurrencyProvider CurrencyProvider { get; } - public UserManager UserManager { get; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } /// /// Returns the detailed information about the opportunity with the ID specified in the request @@ -136,7 +139,7 @@ public OpportunityDto UpdateToDealMilestone(int opportunityid, int stageid) deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue; _daoFactory.GetDealDao().EditDeal(deal); - MessageService.Send(MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title); + _messageService.Send(MessageAction.OpportunityUpdatedStage, _messageTarget.Create(deal.ID), deal.Title); return _mapper.Map(deal); } @@ -162,7 +165,7 @@ public OpportunityDto SetAccessToDeal(int opportunityid, bool isPrivate, IEnumer var deal = _daoFactory.GetDealDao().GetByID(opportunityid); if (deal == null) throw new ItemNotFoundException(); - if (!(_crmSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); + if (!(_crmSecurity.IsAdmin || deal.CreateBy == _securityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); return SetAccessToDeal(deal, isPrivate, accessList, false, true); } @@ -174,21 +177,21 @@ private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable u != SecurityContext.CurrentAccount.ID).ToList(); - NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, _daoFactory, accessListLocal.ToArray()); + accessListLocal = accessListLocal.Where(u => u != _securityContext.CurrentAccount.ID).ToList(); + _notifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, _daoFactory, accessListLocal.ToArray()); } - if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID)) + if (!accessListLocal.Contains(_securityContext.CurrentAccount.ID)) { - accessListLocal.Add(SecurityContext.CurrentAccount.ID); + accessListLocal.Add(_securityContext.CurrentAccount.ID); } _crmSecurity.SetAccessTo(deal, accessListLocal); if (isMessageServicSende) { - var users = UserManager.GetUsers().Where(x => accessListLocal.Contains(x.ID)); - MessageService.Send(MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, DisplayUserSettingsHelper))); + var users = _userManager.GetUsers().Where(x => accessListLocal.Contains(x.ID)); + _messageService.Send(MessageAction.OpportunityRestrictedAccess, _messageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false, _displayUserSettingsHelper))); } } else @@ -196,7 +199,7 @@ private OpportunityDto SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBa var result = new List(); var deals = _daoFactory.GetDealDao() - .GetDeals(ApiContext.FilterValue, + .GetDeals(_apiContext.FilterValue, responsibleid, opportunityStagesid, tags, @@ -255,7 +258,7 @@ public IEnumerable SetAccessToBatchDeal([FromForm] SetAccessToBa { if (deal == null) throw new ItemNotFoundException(); - if (!(_crmSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || deal.CreateBy == _securityContext.CurrentAccount.ID)) continue; SetAccessToDeal(deal.ID, isPrivate, accessList); @@ -298,7 +301,7 @@ public IEnumerable SetAccessToBatchDeal(SetAccessToBatchDealRequ { if (d == null) throw new ItemNotFoundException(); - if (!(_crmSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue; + if (!(_crmSecurity.IsAdmin || d.CreateBy == _securityContext.CurrentAccount.ID)) continue; SetAccessToDeal(d, isPrivate, accessList, false, true); result.Add(d); @@ -325,7 +328,7 @@ public IEnumerable DeleteBatchDeals(IEnumerable opportunity if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException(); var opportunities = _daoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray()); - MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); + _messageService.Send(MessageAction.OpportunitiesDeleted, _messageTarget.Create(opportunityids), opportunities.Select(o => o.Title)); return ToListOpportunityDto(opportunities); } @@ -359,7 +362,7 @@ public IEnumerable DeleteBatchDeals( ApiDateTime fromDate, ApiDateTime toDate) { - var deals = _daoFactory.GetDealDao().GetDeals(ApiContext.FilterValue, + var deals = _daoFactory.GetDealDao().GetDeals(_apiContext.FilterValue, responsibleid, opportunityStagesid, tags, @@ -371,7 +374,7 @@ public IEnumerable DeleteBatchDeals( if (!deals.Any()) return Enumerable.Empty(); deals = _daoFactory.GetDealDao().DeleteBatchDeals(deals); - MessageService.Send(MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); + _messageService.Send(MessageAction.OpportunitiesDeleted, _messageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title)); return ToListOpportunityDto(deals); } @@ -407,15 +410,15 @@ public IEnumerable GetDeals( IEnumerable result; - var searchString = ApiContext.FilterValue; + var searchString = _apiContext.FilterValue; OrderBy dealsOrderBy; - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType)) + if (ASC.CRM.Classes.EnumExtension.TryParse(_apiContext.SortBy, true, out dealSortedByType)) { - dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending); + dealsOrderBy = new OrderBy(dealSortedByType, !_apiContext.SortDescending); } - else if (string.IsNullOrEmpty(ApiContext.SortBy)) + else if (string.IsNullOrEmpty(_apiContext.SortBy)) { dealsOrderBy = new OrderBy(DealSortedByType.Stage, true); } @@ -424,8 +427,8 @@ public IEnumerable GetDeals( dealsOrderBy = null; } - var fromIndex = (int)ApiContext.StartIndex; - var count = (int)ApiContext.Count; + var fromIndex = (int)_apiContext.StartIndex; + var count = (int)_apiContext.Count; if (dealsOrderBy != null) { @@ -443,9 +446,9 @@ public IEnumerable GetDeals( count, dealsOrderBy)).ToList(); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else { @@ -484,7 +487,7 @@ public IEnumerable GetDeals( toDate); } - ApiContext.SetTotalCount(totalCount); + _apiContext.SetTotalCount(totalCount); return result; } @@ -508,7 +511,7 @@ public OpportunityDto DeleteDeal(int opportunityid) var deal = _daoFactory.GetDealDao().DeleteDeal(opportunityid); if (deal == null) throw new ItemNotFoundException(); - MessageService.Send(MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title); + _messageService.Send(MessageAction.OpportunityDeleted, _messageTarget.Create(deal.ID), deal.Title); return _mapper.Map(deal); } @@ -581,7 +584,7 @@ public OpportunityDto CreateDeal(CreateOrUpdateDealRequestDto inDto) deal.ID = _daoFactory.GetDealDao().CreateNewDeal(deal); - deal.CreateBy = SecurityContext.CurrentAccount.ID; + deal.CreateBy = _securityContext.CurrentAccount.ID; deal.CreateOn = DateTime.UtcNow; SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); @@ -693,7 +696,7 @@ public OpportunityDto UpdateDeal( } - if (_crmSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) + if (_crmSecurity.IsAdmin || deal.CreateBy == _securityContext.CurrentAccount.ID) { SetAccessToDeal(deal, isPrivate, accessList, isNotify, false); } @@ -730,8 +733,8 @@ public IEnumerable GetDealMembers(int opportunityid) var contactIDs = _daoFactory.GetDealDao().GetMembers(opportunityid); if (contactIDs == null) return new List(); - - var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs); + + var contacts = _daoFactory.GetContactDao().GetContacts(contactIDs); var result = _mapper.Map, List>(contacts); @@ -767,7 +770,7 @@ public ContactDto AddMemberToDeal(int opportunityid, int contactid) _daoFactory.GetDealDao().AddMember(opportunityid, contactid); var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson; - MessageService.Send(messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); return result; } @@ -800,7 +803,7 @@ public ContactDto DeleteMemberFromDeal(int opportunityid, int contactid) _daoFactory.GetDealDao().RemoveMember(opportunityid, contactid); var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson; - MessageService.Send(messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); + _messageService.Send(messageAction, _messageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle()); return result; } @@ -832,7 +835,7 @@ public IEnumerable GetDealsByPrefix(string prefix, int contactID } } - ApiContext.SetTotalCount(result.Count); + _apiContext.SetTotalCount(result.Count); } else { @@ -963,12 +966,12 @@ private IEnumerable ToListOpportunityDto(ICollection deals if (dealDto.IsPrivate) { - dealDto.AccessList = _crmSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraperHelper.Get(item.Key)); + dealDto.AccessList = _crmSecurity.GetAccessSubjectTo(deal).Select(item => _employeeWraperHelper.Get(item.Key)); } if (!string.IsNullOrEmpty(deal.BidCurrency)) { - dealDto.BidCurrency = _mapper.Map(CurrencyProvider.Get(deal.BidCurrency)); + dealDto.BidCurrency = _mapper.Map(_currencyProvider.Get(deal.BidCurrency)); } result.Add(dealDto); diff --git a/products/ASC.CRM/Server/Api/InvoicesController.cs b/products/ASC.CRM/Server/Api/InvoicesController.cs index bdbd9d0420c..ad280ae2671 100644 --- a/products/ASC.CRM/Server/Api/InvoicesController.cs +++ b/products/ASC.CRM/Server/Api/InvoicesController.cs @@ -62,6 +62,7 @@ public class InvoicesController : BaseApiController private readonly ApiContext _apiContext; private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; + private readonly CurrencyProvider _currencyProvider; public InvoicesController(CRMSecurity crmSecurity, DaoFactory daoFactory, @@ -74,6 +75,7 @@ public InvoicesController(CRMSecurity crmSecurity, PdfCreator pdfCreator, Global global, PdfQueueWorker pdfQueueWorker, + CurrencyProvider currencyProvider, IMapper mapper) : base(daoFactory, crmSecurity, mapper) { @@ -87,6 +89,7 @@ public InvoicesController(CRMSecurity crmSecurity, _global = global; _pdfQueueWorker = pdfQueueWorker; _mapper = mapper; + _currencyProvider = currencyProvider; } @@ -122,7 +125,8 @@ public InvoiceDto GetInvoiceByID(int invoiceid) [Read(@"invoice/sample")] public InvoiceDto GetInvoiceSample() { - var defaultCurrency = _settingsManager.Load().DefaultCurrency; + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); var sample = InvoiceDto.GetSample(); diff --git a/products/ASC.CRM/Server/Api/ListItemsController.cs b/products/ASC.CRM/Server/Api/ListItemsController.cs index e2bb3254e16..d847ae5afb8 100644 --- a/products/ASC.CRM/Server/Api/ListItemsController.cs +++ b/products/ASC.CRM/Server/Api/ListItemsController.cs @@ -44,22 +44,20 @@ namespace ASC.CRM.Api { public class ListItemsController : BaseApiController { + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + public ListItemsController(CRMSecurity cRMSecurity, DaoFactory daoFactory, MessageTarget messageTarget, MessageService messageService, - HistoryCategoryDtoHelper historyCategoryDtoHelper, IMapper mapper) : base(daoFactory, cRMSecurity, mapper) { - MessageTarget = messageTarget; - MessageService = messageService; - HistoryCategoryDtoHelper = historyCategoryDtoHelper; + _messageTarget = messageTarget; + _messageService = messageService; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } - public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } /// /// Creates an opportunity stage with the parameters (title, description, success probability, etc.) specified in the request @@ -99,7 +97,7 @@ public DealMilestoneDto CreateDealMilestone( }; dealMilestone.ID = _daoFactory.GetDealMilestoneDao().Create(dealMilestone); - MessageService.Send(MessageAction.OpportunityStageCreated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + _messageService.Send(MessageAction.OpportunityStageCreated, _messageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneDto(dealMilestone); } @@ -149,7 +147,7 @@ public DealMilestoneDto UpdateDealMilestone( }; _daoFactory.GetDealMilestoneDao().Edit(dealMilestone); - MessageService.Send(MessageAction.OpportunityStageUpdated, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + _messageService.Send(MessageAction.OpportunityStageUpdated, _messageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneDto(dealMilestone); } @@ -179,7 +177,7 @@ public DealMilestoneDto UpdateDealMilestoneColor(int id, string color) dealMilestone.Color = color; _daoFactory.GetDealMilestoneDao().ChangeColor(id, color); - MessageService.Send(MessageAction.OpportunityStageUpdatedColor, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + _messageService.Send(MessageAction.OpportunityStageUpdatedColor, _messageTarget.Create(dealMilestone.ID), dealMilestone.Title); return ToDealMilestoneDto(dealMilestone); } @@ -210,7 +208,7 @@ public IEnumerable UpdateDealMilestonesOrder(IEnumerable var result = idsList.Select(id => _daoFactory.GetDealMilestoneDao().GetByID(id)).ToList(); _daoFactory.GetDealMilestoneDao().Reorder(idsList.ToArray()); - MessageService.Send(MessageAction.OpportunityStagesUpdatedOrder, MessageTarget.Create(idsList), result.Select(x => x.Title)); + _messageService.Send(MessageAction.OpportunityStagesUpdatedOrder, _messageTarget.Create(idsList), result.Select(x => x.Title)); return result.Select(ToDealMilestoneDto); } @@ -239,7 +237,7 @@ public DealMilestoneDto DeleteDealMilestone(int id) var result = ToDealMilestoneDto(dealMilestone); _daoFactory.GetDealMilestoneDao().Delete(id); - MessageService.Send(MessageAction.OpportunityStageDeleted, MessageTarget.Create(dealMilestone.ID), dealMilestone.Title); + _messageService.Send(MessageAction.OpportunityStageDeleted, _messageTarget.Create(dealMilestone.ID), dealMilestone.Title); return result; } @@ -271,9 +269,9 @@ public HistoryCategoryDto CreateHistoryCategory(string title, string description }; listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.HistoryCategory, listItem); - MessageService.Send(MessageAction.HistoryEventCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.HistoryEventCategoryCreated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToHistoryCategoryDto(listItem); + return _mapper.Map(listItem); } /// @@ -309,9 +307,9 @@ public HistoryCategoryDto UpdateHistoryCategory(int id, string title, string des }; _daoFactory.GetListItemDao().EditItem(ListType.HistoryCategory, listItem); - MessageService.Send(MessageAction.HistoryEventCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.HistoryEventCategoryUpdated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToHistoryCategoryDto(listItem); + return _mapper.Map(listItem); } /// @@ -339,9 +337,9 @@ public HistoryCategoryDto UpdateHistoryCategoryIcon(int id, string imageName) historyCategory.AdditionalParams = imageName; _daoFactory.GetListItemDao().ChangePicture(id, imageName); - MessageService.Send(MessageAction.HistoryEventCategoryUpdatedIcon, MessageTarget.Create(historyCategory.ID), historyCategory.Title); + _messageService.Send(MessageAction.HistoryEventCategoryUpdatedIcon, _messageTarget.Create(historyCategory.ID), historyCategory.Title); - return ToHistoryCategoryDto(historyCategory); + return _mapper.Map(historyCategory); } /// @@ -368,9 +366,9 @@ public IEnumerable UpdateHistoryCategoriesOrder(IEnumerable< var result = titles.Select(title => _daoFactory.GetListItemDao().GetByTitle(ListType.HistoryCategory, title)).ToList(); _daoFactory.GetListItemDao().ReorderItems(ListType.HistoryCategory, titles.ToArray()); - MessageService.Send(MessageAction.HistoryEventCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + _messageService.Send(MessageAction.HistoryEventCategoriesUpdatedOrder, _messageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToHistoryCategoryDto); + return _mapper.Map, List>(result); } /// @@ -399,10 +397,11 @@ public HistoryCategoryDto DeleteHistoryCategory(int id) throw new ArgumentException("The last history category cannot be deleted"); } - var result = ToHistoryCategoryDto(listItem); + var result = _mapper.Map(listItem); dao.DeleteItem(ListType.HistoryCategory, id, 0); - MessageService.Send(MessageAction.HistoryEventCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + + _messageService.Send(MessageAction.HistoryEventCategoryDeleted, _messageTarget.Create(listItem.ID), listItem.Title); return result; } @@ -435,7 +434,7 @@ public TaskCategoryDto CreateTaskCategory(string title, string description, stri }; listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.TaskCategory, listItem); - MessageService.Send(MessageAction.CrmTaskCategoryCreated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.CrmTaskCategoryCreated, _messageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryDto(listItem); } @@ -477,7 +476,7 @@ public TaskCategoryDto UpdateTaskCategory(int id, string title, string descripti }; _daoFactory.GetListItemDao().EditItem(ListType.TaskCategory, listItem); - MessageService.Send(MessageAction.CrmTaskCategoryUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.CrmTaskCategoryUpdated, _messageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryDto(listItem); } @@ -507,7 +506,7 @@ public TaskCategoryDto UpdateTaskCategoryIcon(int id, string imageName) taskCategory.AdditionalParams = imageName; _daoFactory.GetListItemDao().ChangePicture(id, imageName); - MessageService.Send(MessageAction.CrmTaskCategoryUpdatedIcon, MessageTarget.Create(taskCategory.ID), taskCategory.Title); + _messageService.Send(MessageAction.CrmTaskCategoryUpdatedIcon, _messageTarget.Create(taskCategory.ID), taskCategory.Title); return ToTaskCategoryDto(taskCategory); } @@ -536,7 +535,7 @@ public IEnumerable UpdateTaskCategoriesOrder(IEnumerable _daoFactory.GetListItemDao().GetByTitle(ListType.TaskCategory, title)).ToList(); _daoFactory.GetListItemDao().ReorderItems(ListType.TaskCategory, titles.ToArray()); - MessageService.Send(MessageAction.CrmTaskCategoriesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + _messageService.Send(MessageAction.CrmTaskCategoriesUpdatedOrder, _messageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToTaskCategoryDto); } @@ -568,7 +567,7 @@ public TaskCategoryDto DeleteTaskCategory(int categoryid, int newcategoryid) } dao.DeleteItem(ListType.TaskCategory, categoryid, newcategoryid); - MessageService.Send(MessageAction.CrmTaskCategoryDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.CrmTaskCategoryDeleted, _messageTarget.Create(listItem.ID), listItem.Title); return ToTaskCategoryDto(listItem); } @@ -601,7 +600,7 @@ public ContactStatusDto CreateContactStatus(string title, string description, st }; listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.ContactStatus, listItem); - MessageService.Send(MessageAction.ContactTemperatureLevelCreated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.ContactTemperatureLevelCreated, _messageTarget.Create(listItem.ID), listItem.Title); return ToContactStatusDto(listItem); } @@ -643,7 +642,7 @@ public ContactStatusDto UpdateContactStatus(int id, string title, string descrip }; _daoFactory.GetListItemDao().EditItem(ListType.ContactStatus, listItem); - MessageService.Send(MessageAction.ContactTemperatureLevelUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.ContactTemperatureLevelUpdated, _messageTarget.Create(listItem.ID), listItem.Title); return ToContactStatusDto(listItem); } @@ -673,7 +672,7 @@ public ContactStatusDto UpdateContactStatusColor(int id, string color) contactStatus.Color = color; _daoFactory.GetListItemDao().ChangeColor(id, color); - MessageService.Send(MessageAction.ContactTemperatureLevelUpdatedColor, MessageTarget.Create(contactStatus.ID), contactStatus.Title); + _messageService.Send(MessageAction.ContactTemperatureLevelUpdatedColor, _messageTarget.Create(contactStatus.ID), contactStatus.Title); return ToContactStatusDto(contactStatus); } @@ -702,7 +701,7 @@ public IEnumerable UpdateContactStatusesOrder(IEnumerable _daoFactory.GetListItemDao().GetByTitle(ListType.ContactStatus, title)).ToList(); _daoFactory.GetListItemDao().ReorderItems(ListType.ContactStatus, titles.ToArray()); - MessageService.Send(MessageAction.ContactTemperatureLevelsUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + _messageService.Send(MessageAction.ContactTemperatureLevelsUpdatedOrder, _messageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToContactStatusDto); } @@ -738,7 +737,7 @@ public ContactStatusDto DeleteContactStatus(int contactStatusid) var contactStatus = ToContactStatusDto(listItem); dao.DeleteItem(ListType.ContactStatus, contactStatusid, 0); - MessageService.Send(MessageAction.ContactTemperatureLevelDeleted, MessageTarget.Create(contactStatus.Id), contactStatus.Title); + _messageService.Send(MessageAction.ContactTemperatureLevelDeleted, _messageTarget.Create(contactStatus.Id), contactStatus.Title); return contactStatus; } @@ -788,7 +787,7 @@ public ContactTypeDto CreateContactType(string title, int sortOrder) }; listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.ContactType, listItem); - MessageService.Send(MessageAction.ContactTypeCreated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.ContactTypeCreated, _messageTarget.Create(listItem.ID), listItem.Title); return ToContactTypeDto(listItem); } @@ -826,7 +825,7 @@ public ContactTypeDto UpdateContactType(int id, string title, int sortOrder) }; _daoFactory.GetListItemDao().EditItem(ListType.ContactType, listItem); - MessageService.Send(MessageAction.ContactTypeUpdated, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.ContactTypeUpdated, _messageTarget.Create(listItem.ID), listItem.Title); return ToContactTypeDto(listItem); } @@ -855,7 +854,7 @@ public IEnumerable UpdateContactTypesOrder(IEnumerable t var result = titles.Select(title => _daoFactory.GetListItemDao().GetByTitle(ListType.ContactType, title)).ToList(); _daoFactory.GetListItemDao().ReorderItems(ListType.ContactType, titles.ToArray()); - MessageService.Send(MessageAction.ContactTypesUpdatedOrder, MessageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); + _messageService.Send(MessageAction.ContactTypesUpdatedOrder, _messageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); return result.ConvertAll(ToContactTypeDto); } @@ -891,7 +890,7 @@ public ContactTypeDto DeleteContactType(int contactTypeid) var contactType = ToContactTypeDto(listItem); dao.DeleteItem(ListType.ContactType, contactTypeid, 0); - MessageService.Send(MessageAction.ContactTypeDeleted, MessageTarget.Create(listItem.ID), listItem.Title); + _messageService.Send(MessageAction.ContactTypeDeleted, _messageTarget.Create(listItem.ID), listItem.Title); return contactType; } @@ -1093,15 +1092,6 @@ public ContactTypeDto ToContactTypeDto(ListItem listItem) return result; } - public HistoryCategoryDto ToHistoryCategoryDto(ListItem listItem) - { - var result = (HistoryCategoryDto)HistoryCategoryDtoHelper.Get(listItem); - - result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, listItem.ID); - - return result; - } - public TaskCategoryDto ToTaskCategoryDto(ListItem listItem) { var result = (TaskCategoryDto)_mapper.Map(listItem); diff --git a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs index 07879c859d5..61a17445e0a 100644 --- a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs +++ b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs @@ -52,6 +52,14 @@ namespace ASC.CRM.Api { public class RelationshipEventsController : BaseApiController { + private readonly HistoryCategoryDto _historyCategoryDtoHelper; + private readonly FileUploader _fileUploader; + private readonly ASC.Files.Core.Data.DaoFactory _filesDaoFactory; + private readonly FileWrapperHelper _fileWrapperHelper; + private readonly ApiContext _apiContext; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + public RelationshipEventsController(CRMSecurity cRMSecurity, DaoFactory daoFactory, ApiContext apiContext, @@ -60,26 +68,19 @@ public RelationshipEventsController(CRMSecurity cRMSecurity, FileWrapperHelper fileWrapperHelper, ASC.Files.Core.Data.DaoFactory filesDaoFactory, FileUploader fileUploader, - HistoryCategoryDtoHelper historyCategoryDtoHelper, + HistoryCategoryDto historyCategoryDtoHelper, IMapper mapper) : base(daoFactory, cRMSecurity, mapper) { - ApiContext = apiContext; - MessageTarget = messageTarget; - MessageService = messageService; - FileWrapperHelper = fileWrapperHelper; - FilesDaoFactory = filesDaoFactory; - FileUploader = fileUploader; - HistoryCategoryDtoHelper = historyCategoryDtoHelper; + _apiContext = apiContext; + _messageTarget = messageTarget; + _messageService = messageService; + _fileWrapperHelper = fileWrapperHelper; + _filesDaoFactory = filesDaoFactory; + _fileUploader = fileUploader; + _historyCategoryDtoHelper = historyCategoryDtoHelper; } - public HistoryCategoryDtoHelper HistoryCategoryDtoHelper { get; } - public FileUploader FileUploader { get; } - public ASC.Files.Core.Data.DaoFactory FilesDaoFactory { get; set; } - public FileWrapperHelper FileWrapperHelper { get; } - private ApiContext ApiContext { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } /// /// Returns the list of all events matching the parameters specified in the request @@ -139,11 +140,11 @@ public IEnumerable GetHistory( OrderBy eventOrderBy; - if (ASC.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out eventByType)) + if (ASC.CRM.Classes.EnumExtension.TryParse(_apiContext.SortBy, true, out eventByType)) { - eventOrderBy = new OrderBy(eventByType, !ApiContext.SortDescending); + eventOrderBy = new OrderBy(eventByType, !_apiContext.SortDescending); } - else if (string.IsNullOrEmpty(ApiContext.SortBy)) + else if (string.IsNullOrEmpty(_apiContext.SortBy)) { eventOrderBy = new OrderBy(RelationshipEventByType.Created, false); } @@ -155,25 +156,25 @@ public IEnumerable GetHistory( if (eventOrderBy != null) { result = ToListRelationshipEventDto(_daoFactory.GetRelationshipEventDao().GetItems( - ApiContext.FilterValue, + _apiContext.FilterValue, entityTypeObj, entityId, createBy, categoryId, fromDate, toDate, - (int)ApiContext.StartIndex, - (int)ApiContext.Count, + (int)_apiContext.StartIndex, + (int)_apiContext.Count, eventOrderBy)); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); } else { result = ToListRelationshipEventDto(_daoFactory.GetRelationshipEventDao().GetItems( - ApiContext.FilterValue, + _apiContext.FilterValue, entityTypeObj, entityId, createBy, @@ -214,7 +215,7 @@ public RelationshipEventDto DeleteHistory(int id) var messageAction = GetHistoryDeletedAction(item.EntityType, item.ContactID); var entityTitle = wrapper.Contact == null ? wrapper.Entity.EntityTitle : wrapper.Contact.DisplayName; - MessageService.Send(messageAction, MessageTarget.Create(item.ID), entityTitle, wrapper.Category.Title); + _messageService.Send(messageAction, _messageTarget.Create(item.ID), entityTitle, wrapper.Category.Title); return wrapper; } @@ -323,9 +324,9 @@ public FileWrapper CreateTextFile(string entityType, int entityid, string t private FileWrapper SaveFile(int folderid, Stream file, string fileName) { - var resultFile = FileUploader.Exec(folderid, fileName, file.Length, file); + var resultFile = _fileUploader.Exec(folderid, fileName, file.Length, file); - return FileWrapperHelper.Get(resultFile); + return _fileWrapperHelper.Get(resultFile); } /// @@ -484,7 +485,7 @@ public RelationshipEventDto AttachFiles(string entityType, int entityid, IEnumer { if (entityid <= 0 || fileids == null) throw new ArgumentException(); - var files = FilesDaoFactory.GetFileDao().GetFiles(fileids.ToArray()); + var files = _filesDaoFactory.GetFileDao().GetFiles(fileids.ToArray()); var folderid = GetRootFolderID(); @@ -502,15 +503,15 @@ public RelationshipEventDto AttachFiles(string entityType, int entityid, IEnumer case EntityType.Contact: var relationshipEvent1 = _daoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray()); var messageAction = entityObj is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles; - MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + _messageService.Send(messageAction, _messageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); return _mapper.Map(relationshipEvent1); case EntityType.Opportunity: var relationshipEvent2 = _daoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); - MessageService.Send(MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + _messageService.Send(MessageAction.OpportunityAttachedFiles, _messageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); return _mapper.Map(relationshipEvent2); case EntityType.Case: var relationshipEvent3 = _daoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray()); - MessageService.Send(MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); + _messageService.Send(MessageAction.CaseAttachedFiles, _messageTarget.Create(entityid), entityTitle, files.Select(x => x.Title)); return _mapper.Map(relationshipEvent3); default: throw new ArgumentException(); @@ -551,10 +552,10 @@ public IEnumerable> GetFiles(string entityType, int entityid) switch (entityTypeObj) { case EntityType.Contact: - return _daoFactory.GetRelationshipEventDao().GetAllFiles(new[] { entityid }, EntityType.Any, 0).ConvertAll(file => FileWrapperHelper.Get(file)); + return _daoFactory.GetRelationshipEventDao().GetAllFiles(new[] { entityid }, EntityType.Any, 0).ConvertAll(file => _fileWrapperHelper.Get(file)); case EntityType.Opportunity: case EntityType.Case: - return _daoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => FileWrapperHelper.Get(file)); + return _daoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => _fileWrapperHelper.Get(file)); default: throw new ArgumentException(); } @@ -576,9 +577,9 @@ public FileWrapper DeleteCRMFile(int fileid) { if (fileid < 0) throw new ArgumentException(); - var file = FilesDaoFactory.GetFileDao().GetFile(fileid); + var file = _filesDaoFactory.GetFileDao().GetFile(fileid); if (file == null) throw new ItemNotFoundException(); - var result = FileWrapperHelper.Get(file); + var result = _fileWrapperHelper.Get(file); var _eventsDao = _daoFactory.GetRelationshipEventDao(); var eventIDs = _eventsDao.RemoveFile(file); @@ -594,7 +595,7 @@ public FileWrapper DeleteCRMFile(int fileid) : GetEntityTitle(evt.EntityType, evt.EntityID, false, out entityObj); var messageAction = GetFilesDetachAction(evt.EntityType, evt.ContactID); - MessageService.Send(messageAction, MessageTarget.Create(file.ID), entityTitle, file.Title); + _messageService.Send(messageAction, _messageTarget.Create(file.ID), entityTitle, file.Title); } return result; @@ -684,7 +685,7 @@ private IEnumerable ToListRelationshipEventDto(List x.ID, x => HistoryCategoryDtoHelper.Get(x)); + var categories = _daoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => _mapper.Map(x)); var files = _daoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray()); @@ -710,7 +711,7 @@ private IEnumerable ToListRelationshipEventDto(List - FileWrapperHelper.Get(file)) : new List>(); + _fileWrapperHelper.Get(file)) : new List>(); if (categories.ContainsKey(item.CategoryID)) { diff --git a/products/ASC.CRM/Server/Api/ReportsController.cs b/products/ASC.CRM/Server/Api/ReportsController.cs index cc3295ac1be..d49c163e54d 100644 --- a/products/ASC.CRM/Server/Api/ReportsController.cs +++ b/products/ASC.CRM/Server/Api/ReportsController.cs @@ -45,6 +45,12 @@ namespace ASC.CRM.Api { public class ReportsController : BaseApiController { + private readonly DocbuilderReportsUtilityHelper _docbuilderReportsUtilityHelper; + private readonly FileWrapperHelper _fileWrapperHelper; + private readonly ReportHelper _reportHelper; + private readonly Global _global; + private readonly SettingsManager _settingsManager; + public ReportsController(CRMSecurity crmSecurity, DaoFactory daoFactory, SettingsManager settingsManager, @@ -56,19 +62,13 @@ IMapper mapper ) : base(daoFactory, crmSecurity, mapper) { - SettingsManager = settingsManager; - Global = global; - ReportHelper = reportHelper; - FileWrapperHelper = fileWrapperHelper; - DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; + _settingsManager = settingsManager; + _global = global; + _reportHelper = reportHelper; + _fileWrapperHelper = fileWrapperHelper; + _docbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; } - public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } - - public FileWrapperHelper FileWrapperHelper { get; } - public ReportHelper ReportHelper { get; } - public Global Global { get; } - public SettingsManager SettingsManager { get; } /// Returns a list of all user report files /// Get report files @@ -78,7 +78,7 @@ IMapper mapper [Read(@"report/files")] public IEnumerable> GetFiles() { - if (!Global.CanCreateReports) + if (!_global.CanCreateReports) throw _crmSecurity.CreateSecurityException(); var reportDao = _daoFactory.GetReportDao(); @@ -87,7 +87,7 @@ public IEnumerable> GetFiles() if (!files.Any()) { - var settings = SettingsManager.Load(); + var settings = _settingsManager.Load(); if (settings.NeedToGenerate) { @@ -95,11 +95,11 @@ public IEnumerable> GetFiles() settings.NeedToGenerate = false; - SettingsManager.Save(settings); + _settingsManager.Save(settings); } } - return files.ConvertAll(file => FileWrapperHelper.Get(file)).OrderByDescending(file => file.Id); + return files.ConvertAll(file => _fileWrapperHelper.Get(file)).OrderByDescending(file => file.Id); } /// Delete the report file with the ID specified in the request @@ -112,7 +112,7 @@ public IEnumerable> GetFiles() [Delete(@"report/file/{fileid:int}")] public void DeleteFile(int fileid) { - if (!Global.CanCreateReports) + if (!_global.CanCreateReports) throw _crmSecurity.CreateSecurityException(); if (fileid < 0) throw new ArgumentException(); @@ -132,10 +132,10 @@ public void DeleteFile(int fileid) [Read(@"report/status")] public ReportState GetStatus() { - if (!Global.CanCreateReports) + if (!_global.CanCreateReports) throw _crmSecurity.CreateSecurityException(); - return DocbuilderReportsUtilityHelper.Status(ReportOrigin.CRM); + return _docbuilderReportsUtilityHelper.Status(ReportOrigin.CRM); } @@ -146,10 +146,10 @@ public ReportState GetStatus() [Read(@"report/terminate")] public void Terminate() { - if (!Global.CanCreateReports) + if (!_global.CanCreateReports) throw _crmSecurity.CreateSecurityException(); - DocbuilderReportsUtilityHelper.Terminate(ReportOrigin.CRM); + _docbuilderReportsUtilityHelper.Terminate(ReportOrigin.CRM); } /// Check data availability for a report @@ -163,13 +163,13 @@ public void Terminate() [Create(@"report/check")] public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) { - if (!Global.CanCreateReports) + if (!_global.CanCreateReports) throw _crmSecurity.CreateSecurityException(); return new { - hasData = ReportHelper.CheckReportData(type, timePeriod, managers), - missingRates = ReportHelper.GetMissingRates(type) + hasData = _reportHelper.CheckReportData(type, timePeriod, managers), + missingRates = _reportHelper.GetMissingRates(type) }; } @@ -184,10 +184,10 @@ public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid [Create(@"report/generate")] public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) { - if (!Global.CanCreateReports) + if (!_global.CanCreateReports) throw _crmSecurity.CreateSecurityException(); - return ReportHelper.RunGenareteReport(type, timePeriod, managers); + return _reportHelper.RunGenareteReport(type, timePeriod, managers); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Api/TagsController.cs b/products/ASC.CRM/Server/Api/TagsController.cs index 731c426301b..9f9ede5bc34 100644 --- a/products/ASC.CRM/Server/Api/TagsController.cs +++ b/products/ASC.CRM/Server/Api/TagsController.cs @@ -46,6 +46,10 @@ namespace ASC.CRM.Api { public class TagsController : BaseApiController { + private readonly ApiContext _apiContext; + private readonly MessageService _messageService; + private readonly MessageTarget _messageTarget; + public TagsController(CRMSecurity cRMSecurity, DaoFactory daoFactory, ApiContext apiContext, @@ -54,14 +58,12 @@ public TagsController(CRMSecurity cRMSecurity, IMapper mapper) : base(daoFactory, cRMSecurity, mapper) { - ApiContext = apiContext; - MessageTarget = messageTarget; - MessageService = messageService; + _apiContext = apiContext; + _messageTarget = messageTarget; + _messageService = messageService; } - private ApiContext ApiContext { get; } - public MessageService MessageService { get; } - public MessageTarget MessageTarget { get; } + /// /// Returns the list of all tags associated with the entity with the ID and type specified in the request @@ -146,7 +148,7 @@ public string CreateTag(string entityType, string tagName) var messageAction = GetEntityTagCreatedAction(entityTypeObj); _daoFactory.GetTagDao().AddTag(entityTypeObj, tagName); - MessageService.Send(messageAction, tagName); + _messageService.Send(messageAction, tagName); return tagName; } @@ -232,7 +234,7 @@ public string AddTagToBatchContacts( { var contacts = _daoFactory .GetContactDao() - .GetContacts(ApiContext.FilterValue, + .GetContacts(_apiContext.FilterValue, tags, contactStage, contactType, @@ -284,7 +286,7 @@ public string AddTagToBatchDeals( var deals = _daoFactory .GetDealDao() .GetDeals( - ApiContext.FilterValue, + _apiContext.FilterValue, responsibleid, opportunityStagesid, tags, @@ -316,7 +318,7 @@ public string AddTagToBatchDeals( [Create(@"case/filter/taglist")] public string AddTagToBatchCases(int contactid, bool? isClosed, IEnumerable tags, string tagName) { - var caseses = _daoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null) + var caseses = _daoFactory.GetCasesDao().GetCases(_apiContext.FilterValue, contactid, isClosed, tags, 0, 0, null) .Where(_crmSecurity.CanAccessTo).ToList(); if (!caseses.Any()) return tagName; @@ -376,7 +378,7 @@ public string AddTagTo(string entityType, int entityid, string tagName) _daoFactory.GetTagDao().AddTagToEntity(entityTypeObj, entityid, tagName); var messageAction = GetTagCreatedAction(entityTypeObj, entityid); - MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, tagName); + _messageService.Send(messageAction, _messageTarget.Create(entityid), entityTitle, tagName); return tagName; } @@ -465,7 +467,7 @@ public string AddContactTagToGroup(string entityType, int entityid, string tagNa var messageActions = GetTagCreatedGroupAction(entityTypeObj); foreach (var messageAction in messageActions) { - MessageService.Send(messageAction, MessageTarget.Create(contactInst.ID), entityTitle, tagName); + _messageService.Send(messageAction, _messageTarget.Create(contactInst.ID), entityTitle, tagName); } return tagName; @@ -496,7 +498,7 @@ public string DeleteTag(string entityType, string tagName) _daoFactory.GetTagDao().DeleteTag(entityTypeObj, tagName); var messageAction = GetEntityTagDeletedAction(entityTypeObj); - MessageService.Send(messageAction, tagName); + _messageService.Send(messageAction, tagName); return tagName; } @@ -530,7 +532,7 @@ public string DeleteTagFrom(string entityType, int entityid, string tagName) var messageAction = GetTagDeletedAction(entityTypeObj, entityid); - MessageService.Send(messageAction, MessageTarget.Create(entityid), entityTitle, tagName); + _messageService.Send(messageAction, _messageTarget.Create(entityid), entityTitle, tagName); return tagName; } diff --git a/products/ASC.CRM/Server/Api/TaskTemplateController.cs b/products/ASC.CRM/Server/Api/TaskTemplateController.cs index 2978423e7ae..5e595ae2377 100644 --- a/products/ASC.CRM/Server/Api/TaskTemplateController.cs +++ b/products/ASC.CRM/Server/Api/TaskTemplateController.cs @@ -43,6 +43,8 @@ namespace ASC.CRM.Api { public class TaskTemplateController : BaseApiController { + private readonly EmployeeWraperHelper _employeeWraperHelper; + public TaskTemplateController(CRMSecurity crmSecurity, DaoFactory daoFactory, EmployeeWraperHelper employeeWraperHelper, @@ -50,10 +52,9 @@ public TaskTemplateController(CRMSecurity crmSecurity, : base(daoFactory, crmSecurity, mapper) { - EmployeeWraperHelper = employeeWraperHelper; + _employeeWraperHelper = employeeWraperHelper; } - public EmployeeWraperHelper EmployeeWraperHelper { get; } /// @@ -365,7 +366,7 @@ protected TaskTemplateDto ToTaskTemplateDto(TaskTemplate taskTemplate) isNotify = taskTemplate.isNotify, Title = taskTemplate.Title, OffsetTicks = taskTemplate.Offset.Ticks, - Responsible = EmployeeWraperHelper.Get(taskTemplate.ResponsibleID) + Responsible = _employeeWraperHelper.Get(taskTemplate.ResponsibleID) }; } diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index 09350d1e370..acffe047a92 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -49,6 +49,17 @@ namespace ASC.CRM.Api { public class UtilsController : BaseApiController { + private readonly ExportToCsv _exportToCsv; + private readonly ImportFromCSV _importFromCSV; + private readonly Global _global; + private readonly OrganisationLogoManager _organisationLogoManager; + private readonly ImportFromCSVManager _importFromCSVManager; + private readonly InvoiceSetting _invoiceSetting; + private readonly CurrencyRateInfoDtoHelper _currencyRateInfoDtoHelper; + private readonly SettingsManager _settingsManager; + private readonly CurrencyProvider _currencyProvider; + private readonly MessageService _messageService; + public UtilsController(CRMSecurity cRMSecurity, DaoFactory daoFactory, MessageService messageService, @@ -64,29 +75,18 @@ public UtilsController(CRMSecurity cRMSecurity, IMapper mapper) : base(daoFactory, cRMSecurity, mapper) { - MessageService = messageService; - CurrencyProvider = currencyProvider; - SettingsManager = settingsManager; - CurrencyRateInfoDtoHelper = currencyRateInfoDtoHelper; - InvoiceSetting = invoiceSetting; - ImportFromCSVManager = importFromCSVManager; - OrganisationLogoManager = organisationLogoManager; - Global = global; - ImportFromCSV = importFromCSV; - ExportToCsv = exportToCsv; + _messageService = messageService; + _currencyProvider = currencyProvider; + _settingsManager = settingsManager; + _currencyRateInfoDtoHelper = currencyRateInfoDtoHelper; + _invoiceSetting = invoiceSetting; + _importFromCSVManager = importFromCSVManager; + _organisationLogoManager = organisationLogoManager; + _global = global; + _importFromCSV = importFromCSV; + _exportToCsv = exportToCsv; } - public ExportToCsv ExportToCsv { get; } - public ImportFromCSV ImportFromCSV { get; } - public Global Global { get; } - public OrganisationLogoManager OrganisationLogoManager { get; } - public ImportFromCSVManager ImportFromCSVManager { get; } - public InvoiceSetting InvoiceSetting { get; } - public CurrencyRateInfoDtoHelper CurrencyRateInfoDtoHelper { get; } - public SettingsManager SettingsManager { get; } - public CurrencyProvider CurrencyProvider { get; } - public MessageService MessageService { get; } - /// /// Returns the list of all currencies currently available on the portal /// @@ -98,7 +98,7 @@ public UtilsController(CRMSecurity cRMSecurity, [Read(@"settings/currency")] public IEnumerable GetAvaliableCurrency() { - return CurrencyProvider.GetAll().ConvertAll(item => _mapper.Map(item)); + return _currencyProvider.GetAll().ConvertAll(item => _mapper.Map(item)); } /// @@ -115,7 +115,7 @@ public IEnumerable GetAvaliableCurrency() [Read(@"settings/currency/convert")] public Decimal ConvertAmount(Decimal amount, String fromcurrency, String tocurrency) { - return CurrencyProvider.MoneyConvert(amount, fromcurrency, tocurrency); + return _currencyProvider.MoneyConvert(amount, fromcurrency, tocurrency); } /// @@ -138,13 +138,13 @@ public IEnumerable GetSummaryTable(String currency) throw new ArgumentException(); } - var cur = CurrencyProvider.Get(currency.ToUpper()); + var cur = _currencyProvider.Get(currency.ToUpper()); if (cur == null) throw new ArgumentException(); - var table = CurrencyProvider.MoneyConvert(cur); + var table = _currencyProvider.MoneyConvert(cur); - table.ToList().ForEach(tableItem => result.Add(CurrencyRateInfoDtoHelper.Get(tableItem.Key, tableItem.Value))); + table.ToList().ForEach(tableItem => result.Add(_currencyRateInfoDtoHelper.Get(tableItem.Key, tableItem.Value))); return result; } @@ -162,13 +162,13 @@ public IEnumerable GetSummaryTable(String currency) [Update(@"contact/status/settings")] public Boolean? UpdateCRMContactStatusSettings(Boolean? changeContactStatusGroupAuto) { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.ChangeContactStatusGroupAuto = changeContactStatusGroupAuto; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); - MessageService.Send(MessageAction.ContactTemperatureLevelSettingsUpdated); + _messageService.Send(MessageAction.ContactTemperatureLevelSettingsUpdated); return changeContactStatusGroupAuto; } @@ -186,11 +186,11 @@ public IEnumerable GetSummaryTable(String currency) [Update(@"contact/mailtohistory/settings")] public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAuto) { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.WriteMailToHistoryAuto = writeMailToHistoryAuto; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); //MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated); return writeMailToHistoryAuto; @@ -209,12 +209,12 @@ public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAut [Update(@"contact/tag/settings")] public Boolean? UpdateCRMContactTagSettings(Boolean? addTagToContactGroupAuto) { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.AddTagToContactGroupAuto = addTagToContactGroupAuto; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); - MessageService.Send(MessageAction.ContactsTagSettingsUpdated); + _messageService.Send(MessageAction.ContactsTagSettingsUpdated); return addTagToContactGroupAuto; } @@ -233,12 +233,12 @@ public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.IsConfiguredPortal = configured ?? true; tenantSettings.WebFormKey = webFormKey ?? Guid.NewGuid(); - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); return tenantSettings.IsConfiguredPortal; } @@ -256,17 +256,17 @@ public String UpdateOrganisationSettingsCompanyName(String companyName) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { - tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; + tenantSettings.InvoiceSetting = _invoiceSetting.DefaultSettings; } tenantSettings.InvoiceSetting.CompanyName = companyName; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); - MessageService.Send(MessageAction.OrganizationProfileUpdatedCompanyName, companyName); + _messageService.Send(MessageAction.OrganizationProfileUpdatedCompanyName, companyName); return companyName; } @@ -288,11 +288,11 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { - tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; + tenantSettings.InvoiceSetting = _invoiceSetting.DefaultSettings; } var companyAddress = Newtonsoft.Json.JsonConvert.SerializeObject(new @@ -307,9 +307,9 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit tenantSettings.InvoiceSetting.CompanyAddress = companyAddress; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); - MessageService.Send(MessageAction.OrganizationProfileUpdatedAddress); + _messageService.Send(MessageAction.OrganizationProfileUpdatedAddress); return companyAddress; } @@ -332,7 +332,7 @@ public Int32 UpdateOrganisationSettingsLogo(bool reset) if (!reset) { - companyLogoID = OrganisationLogoManager.TryUploadOrganisationLogoFromTmp(_daoFactory); + companyLogoID = _organisationLogoManager.TryUploadOrganisationLogoFromTmp(_daoFactory); if (companyLogoID == 0) { throw new Exception("Downloaded image not found"); @@ -343,17 +343,17 @@ public Int32 UpdateOrganisationSettingsLogo(bool reset) companyLogoID = 0; } - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { - tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings; + tenantSettings.InvoiceSetting = _invoiceSetting.DefaultSettings; } tenantSettings.InvoiceSetting.CompanyLogoID = companyLogoID; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); - MessageService.Send(MessageAction.OrganizationProfileUpdatedInvoiceLogo); + _messageService.Send(MessageAction.OrganizationProfileUpdatedInvoiceLogo); return companyLogoID; } @@ -371,18 +371,18 @@ public String GetOrganisationSettingsLogo(int id) { if (id != 0) { - return OrganisationLogoManager.GetOrganisationLogoBase64(id); + return _organisationLogoManager.GetOrganisationLogoBase64(id); } else { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { return string.Empty; } - return OrganisationLogoManager.GetOrganisationLogoBase64(tenantSettings.InvoiceSetting.CompanyLogoID); + return _organisationLogoManager.GetOrganisationLogoBase64(tenantSettings.InvoiceSetting.CompanyLogoID); } } @@ -398,13 +398,13 @@ public string ChangeWebToLeadFormKey() { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.WebFormKey = Guid.NewGuid(); - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); - MessageService.Send(MessageAction.WebsiteContactFormUpdatedKey); + _messageService.Send(MessageAction.WebsiteContactFormUpdatedKey); return tenantSettings.WebFormKey.ToString(); } @@ -428,11 +428,11 @@ public CurrencyInfoDto UpdateCRMCurrency(String currency) throw new ArgumentException(); } currency = currency.ToUpper(); - var cur = CurrencyProvider.Get(currency); + var cur = _currencyProvider.Get(currency); if (cur == null) throw new ArgumentException(); - Global.SaveDefaultCurrencySettings(cur); - MessageService.Send(MessageAction.CrmDefaultCurrencyUpdated); + _global.SaveDefaultCurrencySettings(cur); + _messageService.Send(MessageAction.CrmDefaultCurrencyUpdated); return _mapper.Map(cur); } @@ -462,7 +462,7 @@ public string StartImportFromCSV(string entityType, string csvFileURI, string js throw new ArgumentException(); } - ImportFromCSVManager.StartImport(entityTypeObj, csvFileURI, jsonSettings); + _importFromCSVManager.StartImport(entityTypeObj, csvFileURI, jsonSettings); return ""; @@ -493,7 +493,7 @@ public IProgressItem GetImportFromCSVStatus(string entityType) throw new ArgumentException(); } - return ImportFromCSV.GetStatus(entityTypeObj); + return _importFromCSV.GetStatus(entityTypeObj); } /// false @@ -502,18 +502,18 @@ public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string { if (String.IsNullOrEmpty(csvFileURI) || indexRow < 0) throw new ArgumentException(); - if (!Global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException(); + if (!_global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException(); - var CSVFileStream = Global.GetStore().GetReadStream("temp", csvFileURI); + var CSVFileStream = _global.GetStore().GetReadStream("temp", csvFileURI); - return ImportFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings); + return _importFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings); } /// false [Create(@"import/uploadfake")] public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings) { - return ImportFromCSVManager.ProcessUploadFake(csvFileURI, jsonSettings); + return _importFromCSVManager.ProcessUploadFake(csvFileURI, jsonSettings); } /// false @@ -522,7 +522,7 @@ public IProgressItem GetExportStatus() { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - return ExportToCsv.GetStatus(false); + return _exportToCsv.GetStatus(false); } @@ -532,9 +532,9 @@ public IProgressItem CancelExport() { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - ExportToCsv.Cancel(false); + _exportToCsv.Cancel(false); - return ExportToCsv.GetStatus(false); + return _exportToCsv.GetStatus(false); } @@ -544,16 +544,16 @@ public IProgressItem StartExport() { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - MessageService.Send(MessageAction.CrmAllDataExported); + _messageService.Send(MessageAction.CrmAllDataExported); - return ExportToCsv.Start(null, CRMSettingResource.Export + ".zip"); + return _exportToCsv.Start(null, CRMSettingResource.Export + ".zip"); } /// false [Read(@"export/partial/status")] public IProgressItem GetPartialExportStatus() { - return ExportToCsv.GetStatus(true); + return _exportToCsv.GetStatus(true); } /// false @@ -561,9 +561,9 @@ public IProgressItem GetPartialExportStatus() public IProgressItem CancelPartialExport() { - ExportToCsv.Cancel(true); + _exportToCsv.Cancel(true); - return ExportToCsv.GetStatus(true); + return _exportToCsv.GetStatus(true); } @@ -581,22 +581,22 @@ public IProgressItem StartPartialExport(string entityType, string base64FilterSt case "contact": filterObject = new ContactFilterObject(base64FilterString); fileName = CRMContactResource.Contacts + ".csv"; - MessageService.Send(MessageAction.ContactsExportedToCsv); + _messageService.Send(MessageAction.ContactsExportedToCsv); break; case "opportunity": filterObject = new DealFilterObject(base64FilterString); fileName = CRMCommonResource.DealModuleName + ".csv"; - MessageService.Send(MessageAction.OpportunitiesExportedToCsv); + _messageService.Send(MessageAction.OpportunitiesExportedToCsv); break; case "case": filterObject = new CasesFilterObject(base64FilterString); fileName = CRMCommonResource.CasesModuleName + ".csv"; - MessageService.Send(MessageAction.CasesExportedToCsv); + _messageService.Send(MessageAction.CasesExportedToCsv); break; case "task": filterObject = new TaskFilterObject(base64FilterString); fileName = CRMCommonResource.TaskModuleName + ".csv"; - MessageService.Send(MessageAction.CrmTasksExportedToCsv); + _messageService.Send(MessageAction.CrmTasksExportedToCsv); break; case "invoiceitem": fileName = CRMCommonResource.ProductsAndServices + ".csv"; @@ -606,7 +606,7 @@ public IProgressItem StartPartialExport(string entityType, string base64FilterSt throw new ArgumentException(); } - return ExportToCsv.Start(filterObject, fileName); + return _exportToCsv.Start(filterObject, fileName); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index a1e8120c3ff..fc2bc7a2813 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -59,6 +59,17 @@ namespace ASC.CRM.Api { public class VoIPController : BaseApiController { + private readonly SignalrServiceClient _signalrServiceClient; + private readonly ApiContext _apiContext; + private readonly VoipEngine _voipEngine; + private readonly TenantUtil _tenantUtil; + private readonly VoipCallDtoHelper _voipCallDtoHelper; + private readonly SecurityContext _securityContext; + private readonly CommonLinkUtility _commonLinkUtility; + private readonly StorageFactory _storageFactory; + private readonly ContactPhotoManager _contactPhotoManager; + private readonly Global _global; + public VoIPController(CRMSecurity cRMSecurity, DaoFactory daoFactory, Global global, @@ -74,29 +85,18 @@ public VoIPController(CRMSecurity cRMSecurity, IMapper mapper) : base(daoFactory, cRMSecurity, mapper) { - Global = global; - ContactPhotoManager = contactPhotoManager; - StorageFactory = storageFactory; - CommonLinkUtility = commonLinkUtility; - SecurityContext = securityContext; - VoipCallDtoHelper = voipCallDtoHelper; - TenantUtil = tenantUtil; - VoipEngine = voipEngine; - ApiContext = apiContext; - SignalrServiceClient = signalrServiceClient; + _global = global; + _contactPhotoManager = contactPhotoManager; + _storageFactory = storageFactory; + _commonLinkUtility = commonLinkUtility; + _securityContext = securityContext; + _voipCallDtoHelper = voipCallDtoHelper; + _tenantUtil = tenantUtil; + _voipEngine = voipEngine; + _apiContext = apiContext; + _signalrServiceClient = signalrServiceClient; } - public SignalrServiceClient SignalrServiceClient { get; } - public ApiContext ApiContext { get; } - public VoipEngine VoipEngine { get; } - public TenantUtil TenantUtil { get; } - public VoipCallDtoHelper VoipCallDtoHelper { get; } - public SecurityContext SecurityContext { get; } - public CommonLinkUtility CommonLinkUtility { get; } - public StorageFactory StorageFactory { get; } - public ContactPhotoManager ContactPhotoManager { get; } - public Global Global { get; } - /// /// /// @@ -193,12 +193,12 @@ public VoipPhone LinkNumber(string id) public void SetDefaultAudio(VoipPhone newPhone) { - var storage = StorageFactory.GetStorage("", "crm"); + var storage = _storageFactory.GetStorage("", "crm"); const string path = "default/"; var files = storage.ListFilesRelative("voip", path, "*.*", true) .Select(filePath => new { - path = CommonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()), + path = _commonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()), audioType = (AudioType)Enum.Parse(typeof(AudioType), Directory.GetParent(filePath).Name, true) }).ToList(); @@ -233,7 +233,7 @@ public VoipPhone DeleteNumber(string numberId) _daoFactory.GetVoipDao().GetProvider().DisablePhone(phone); dao.DeleteNumber(numberId); - new SignalRHelper(phone.Number, SignalrServiceClient).Reload(); + new SignalRHelper(phone.Number, _signalrServiceClient).Reload(); return phone; } @@ -391,9 +391,9 @@ public object GetVoipSettings() return new { queue = number.Settings.Queue, pause = number.Settings.Pause }; } - var files = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true); + var files = _storageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true); var file = files.FirstOrDefault(); - return new { queue = new Queue(null, "Default", 5, file != null ? CommonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false }; + return new { queue = new Queue(null, "Default", 5, file != null ? _commonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false }; } /// @@ -415,14 +415,14 @@ public IEnumerable GetUploadedFilesUri() var type = (AudioType)Enum.Parse(typeof(AudioType), audioType); var path = audioType.ToLower(); - var store = Global.GetStore(); + var store = _global.GetStore(); var filePaths = store.ListFilesRelative("voip", path, "*", true); result.AddRange( filePaths.Select(filePath => GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type))); path = "default/" + audioType.ToLower(); - store = StorageFactory.GetStorage("", "crm"); + store = _storageFactory.GetStorage("", "crm"); filePaths = store.ListFilesRelative("voip", path, "*.*", true); result.AddRange( filePaths.Select(filePath => @@ -436,7 +436,7 @@ private VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, { return new VoipUpload { - Path = CommonLinkUtility.GetFullAbsolutePath(link.ToString()), + Path = _commonLinkUtility.GetFullAbsolutePath(link.ToString()), Name = fileName, AudioType = audioType, IsDefault = isDefault @@ -456,13 +456,13 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var store = Global.GetStore(); + var store = _global.GetStore(); var path = Path.Combine(audioType.ToString().ToLower(), fileName); var result = new VoipUpload { AudioType = audioType, Name = fileName, - Path = CommonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString()) + Path = _commonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString()) }; if (!store.IsFile("voip", path)) throw new ItemNotFoundException(); @@ -471,7 +471,7 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) var dao = _daoFactory.GetVoipDao(); var numbers = dao.GetNumbers(); - var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); + var defAudio = _storageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault(); if (defAudio == null) return result; foreach (var number in numbers) @@ -481,26 +481,26 @@ public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName) case AudioType.Greeting: if (number.Settings.GreetingAudio == result.Path) { - number.Settings.GreetingAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + number.Settings.GreetingAudio = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); } break; case AudioType.HoldUp: if (number.Settings.HoldAudio == result.Path) { - number.Settings.HoldAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + number.Settings.HoldAudio = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); } break; case AudioType.Queue: var queue = number.Settings.Queue; if (queue != null && queue.WaitUrl == result.Path) { - queue.WaitUrl = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + queue.WaitUrl = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); } break; case AudioType.VoiceMail: if (number.Settings.VoiceMail == result.Path) { - number.Settings.VoiceMail = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); + number.Settings.VoiceMail = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString()); } break; } @@ -593,7 +593,7 @@ public Guid DeleteOperator(string numberId, Guid oper) [Update(@"voip/opers/{operatorId}")] public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber) { - if (!_crmSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin && !operatorId.Equals(_securityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException(); var dao = _daoFactory.GetVoipDao(); var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull(); @@ -629,7 +629,7 @@ public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOut if (allowOutgoingCalls.HasValue) { - new SignalRHelper(phone.Number, SignalrServiceClient).Reload(operatorId.ToString()); + new SignalRHelper(phone.Number, _signalrServiceClient).Reload(operatorId.ToString()); } return oper; @@ -668,14 +668,14 @@ public VoipCallDto MakeCall(string to, string contactId) if (contact == null) { - contact = _mapper.Map(VoipEngine.CreateContact(contactPhone)); + contact = _mapper.Map(_voipEngine.CreateContact(contactPhone)); } contact = GetContactWithFotos(contact); var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); - return VoipCallDtoHelper.Get(call, contact); + return _voipCallDtoHelper.Get(call, contact); } @@ -694,7 +694,7 @@ public VoipCallDto AnswerCall(string callId) number.AnswerQueueCall(call.Id); - return VoipCallDtoHelper.Get(call); + return _voipCallDtoHelper.Get(call); } @@ -713,7 +713,7 @@ public VoipCallDto RejectCall(string callId) number.RejectQueueCall(call.Id); - return VoipCallDtoHelper.Get(call); + return _voipCallDtoHelper.Get(call); } /// @@ -742,7 +742,7 @@ public VoipCallDto ReditectCall(string callId, string to) } number.RedirectCall(call.Id, to); - return VoipCallDtoHelper.Get(call); + return _voipCallDtoHelper.Get(call); } /// @@ -774,7 +774,7 @@ public VoipCallDto SaveCall(string callId, string from, string to, Guid answered } else { - VoipEngine.GetContact(call); + _voipEngine.GetContact(call); } if (call.ContactId == 0) @@ -784,13 +784,13 @@ public VoipCallDto SaveCall(string callId, string from, string to, Guid answered var peopleInst = new Person { FirstName = contactPhone, - LastName = TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), + LastName = _tenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), ShareType = ShareType.None }; peopleInst.ID = _daoFactory.GetContactDao().SaveContact(peopleInst); - _crmSecurity.SetAccessTo(peopleInst, new List { SecurityContext.CurrentAccount.ID }); + _crmSecurity.SetAccessTo(peopleInst, new List { _securityContext.CurrentAccount.ID }); var person = (PersonDto)_mapper.Map(peopleInst); @@ -817,18 +817,18 @@ public VoipCallDto SaveCall(string callId, string from, string to, Guid answered call = dao.SaveOrUpdateCall(call); - if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); + if (call.ContactId == 0) return _voipCallDtoHelper.Get(call); try { var contact = _mapper.Map(_daoFactory.GetContactDao().GetByID(call.ContactId)); contact = GetContactWithFotos(contact); - return VoipCallDtoHelper.Get(call, contact); + return _voipCallDtoHelper.Get(call, contact); } catch (Exception) { - return VoipCallDtoHelper.Get(call); + return _voipCallDtoHelper.Get(call); } } @@ -842,7 +842,7 @@ public VoipCallDto SaveCall(string callId, string from, string to, Guid answered [Create(@"voip/price/{callId:regex(\w+)}")] public void SavePrice(string callId) { - VoipEngine.SaveAdditionalInfo(callId); + _voipEngine.SaveAdditionalInfo(callId); } /// @@ -864,19 +864,19 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, ApiD Agent = agent, Client = client, ContactID = contactID, - SortBy = ApiContext.SortBy, - SortOrder = !ApiContext.SortDescending, - SearchText = ApiContext.FilterValue, - Offset = ApiContext.StartIndex, - Max = ApiContext.Count, + SortBy = _apiContext.SortBy, + SortOrder = !_apiContext.SortDescending, + SearchText = _apiContext.FilterValue, + Offset = _apiContext.StartIndex, + Max = _apiContext.Count, }; - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - ApiContext.TotalCount = voipDao.GetCallsCount(filter); + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); + _apiContext.TotalCount = voipDao.GetCallsCount(filter); - var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); + var defaultSmallPhoto = _contactPhotoManager.GetSmallSizePhoto(-1, false); var calls = voipDao.GetCalls(filter).Select( r => { @@ -892,7 +892,7 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, ApiD Id = r.ContactId }; - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + contact.SmallFotoUrl = _contactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); } else @@ -900,7 +900,7 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, ApiD contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } - return VoipCallDtoHelper.Get(r, contact); + return _voipCallDtoHelper.Get(r, contact); }).ToList(); @@ -917,9 +917,9 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, ApiD public IEnumerable GetMissedCalls() { var voipDao = _daoFactory.GetVoipDao(); - var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false); + var defaultSmallPhoto = _contactPhotoManager.GetSmallSizePhoto(-1, false); - var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( + var calls = voipDao.GetMissedCalls(_securityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select( r => { ContactDto contact; @@ -930,7 +930,7 @@ public IEnumerable GetMissedCalls() ? (ContactDto)new CompanyDto() { DisplayName = r.ContactTitle, Id = r.ContactId } : new PersonDto() { DisplayName = r.ContactTitle, Id = r.ContactId }; - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + contact.SmallFotoUrl = _contactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); } else @@ -938,14 +938,14 @@ public IEnumerable GetMissedCalls() contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } - return VoipCallDtoHelper.Get(r, contact); + return _voipCallDtoHelper.Get(r, contact); }).ToList(); - ApiContext.SetDataPaginated(); - ApiContext.SetDataFiltered(); - ApiContext.SetDataSorted(); - ApiContext.TotalCount = calls.Count; + _apiContext.SetDataPaginated(); + _apiContext.SetDataFiltered(); + _apiContext.SetDataSorted(); + _apiContext.TotalCount = calls.Count; return calls; } @@ -961,21 +961,21 @@ public VoipCallDto GetCall(string callId) { var call = _daoFactory.GetVoipDao().GetCall(callId); - VoipEngine.GetContact(call); + _voipEngine.GetContact(call); - if (call.ContactId == 0) return VoipCallDtoHelper.Get(call); + if (call.ContactId == 0) return _voipCallDtoHelper.Get(call); var contact = _mapper.Map(_daoFactory.GetContactDao().GetByID(call.ContactId)); contact = GetContactWithFotos(contact); - return VoipCallDtoHelper.Get(call, contact); + return _voipCallDtoHelper.Get(call, contact); } private ContactDto GetContactWithFotos(ContactDto contact) { - contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); - contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); + contact.SmallFotoUrl = _contactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany); + contact.MediumFotoUrl = _contactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany); return contact; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs index cda764133fc..618f986678d 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -26,7 +26,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Runtime.Serialization; using System.Text.Json; using System.Text.Json.Serialization; @@ -73,7 +72,7 @@ public class PersonDto : ContactDto [Scope] public class PersonDtoHelper - { + { public PersonDto Get(Person person) { return new PersonDto @@ -100,7 +99,7 @@ public PersonDto GetQuick(Person person) /// [DataContract(Name = "company", Namespace = "")] public class CompanyDto : ContactDto - { + { public String CompanyName { get; set; } public IEnumerable Persons { get; set; } public int PersonsCount { get; set; } @@ -162,7 +161,8 @@ public ContactDto() }; } - public void Mapping(Profile profile) { + public void Mapping(Profile profile) + { profile.CreateMap().ConvertUsing(); profile.CreateMap, List>().ConvertUsing(); @@ -171,7 +171,7 @@ public void Mapping(Profile profile) { profile.CreateMap().ConvertUsing(); profile.CreateMap().ConvertUsing(); - profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); } } @@ -195,7 +195,7 @@ public override ContactDto Read(ref Utf8JsonReader reader, Type typeToConvert, J } public override void Write(Utf8JsonWriter writer, ContactDto value, JsonSerializerOptions options) - { + { if (value is PersonDto) { JsonSerializer.Serialize(writer, (PersonDto)value!, options); diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index 0319b75b2b2..994c0dfc1f3 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -75,9 +75,9 @@ public class CustomFieldBaseDto : IMapFrom { public CustomFieldBaseDto() { - + } - + [DataMember(Name = "id")] public int Id { get; set; } public int EntityId { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index ef5ff6dfd4d..d306d8cd712 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -51,10 +51,6 @@ public HistoryCategoryBaseDto(ListItem listItem) { } - [DataMember(Name = "id")] - public int Id { get; set; } - - public String ImagePath { get; set; } public static HistoryCategoryBaseDto GetSample() @@ -119,12 +115,8 @@ public DealMilestoneBaseDto(DealMilestone dealMilestone) Title = dealMilestone.Title; } - public int SuccessProbability { get; set; } - - public DealMilestoneStatus StageType { get; set; } - public static DealMilestoneBaseDto GetSample() { return new DealMilestoneBaseDto @@ -150,8 +142,6 @@ public DealMilestoneDto(DealMilestone dealMilestone) : base(dealMilestone) { } - - public int RelativeItemsCount { get; set; } public new static DealMilestoneDto GetSample() @@ -174,7 +164,7 @@ public DealMilestoneDto(DealMilestone dealMilestone) #region Task Category [DataContract(Name = "taskCategoryBase", Namespace = "")] - public class TaskCategoryBaseDto : ListItemDto, IMapFrom + public class TaskCategoryBaseDto : ListItemDto { public TaskCategoryBaseDto() { @@ -185,7 +175,6 @@ public TaskCategoryBaseDto(ListItem listItem) : base(listItem) } - public String ImagePath { get; set; } public static TaskCategoryBaseDto GetSample() @@ -199,10 +188,6 @@ public static TaskCategoryBaseDto GetSample() }; } - public void Mapping(Profile profile) - { - profile.CreateMap().ConvertUsing(); - } } @@ -391,9 +376,9 @@ public static TagDto GetSample() #endregion [DataContract(Name = "listItem", Namespace = "")] - public class ListItemDto + public class ListItemDto : IMapFrom { - protected ListItemDto() + public ListItemDto() { } @@ -412,5 +397,11 @@ protected ListItemDto(ListItem listItem) public String Description { get; set; } public String Color { get; set; } public int SortOrder { get; set; } + + public void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index 6a71262d657..0fb534467a2 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -26,6 +26,7 @@ using System; using System.Runtime.Serialization; +using System.Text.Json.Serialization; using ASC.Common; using ASC.Core; @@ -43,14 +44,6 @@ public class SMTPServerSetting { public SMTPServerSetting() { - Host = String.Empty; - Port = 0; - EnableSSL = false; - RequiredHostAuthentication = false; - HostLogin = String.Empty; - HostPassword = String.Empty; - SenderDisplayName = String.Empty; - SenderEmailAddress = String.Empty; } public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) @@ -82,12 +75,13 @@ public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) [Scope] public class InvoiceSetting { + public InvoiceSetting() + { + + } + public InvoiceSetting(IConfiguration configuration) { - Autogenerated = false; - Prefix = String.Empty; - Number = String.Empty; - Terms = String.Empty; Configuration = configuration; } @@ -120,31 +114,18 @@ public InvoiceSetting DefaultSettings public String CompanyAddress { get; set; } } - [Serializable] [DataContract] public class CRMSettings : ISettings { - public CRMSettings(CoreConfiguration coreConfiguration, - CurrencyProvider currencyProvider) + public CRMSettings() { - CurrencyProvider = currencyProvider; - CoreConfiguration = coreConfiguration; + } - public CurrencyProvider CurrencyProvider { get; } - public CoreConfiguration CoreConfiguration { get; } - - [DataMember(Name = "DefaultCurrency")] - private string defaultCurrency; - - // - public SMTPServerSetting SMTPServerSetting + public Guid ID { - get - { - return new SMTPServerSetting(CoreConfiguration.SmtpSettings); - } + get { return new Guid("fdf39b9a-ec96-4eb7-aeab-63f2c608eada"); } } [DataMember(Name = "SMTPServerSetting")] @@ -152,17 +133,9 @@ public SMTPServerSetting SMTPServerSetting public InvoiceSetting InvoiceSetting { get; set; } public Guid WebFormKey { get; set; } - public Guid ID - { - get { return new Guid("fdf39b9a-ec96-4eb7-aeab-63f2c608eada"); } - } - - public CurrencyInfo DefaultCurrency - { - get { return CurrencyProvider.Get(defaultCurrency); } - set { defaultCurrency = value.Abbreviation; } - } - + [DataMember(Name = "DefaultCurrency")] + public String DefaultCurrency { get; set; } + [DataMember(Name = "ChangeContactStatusGroupAuto")] public string ChangeContactStatusGroupAutoDto { get; set; } @@ -176,7 +149,7 @@ public Boolean? ChangeContactStatusGroupAuto [DataMember(Name = "AddTagToContactGroupAuto")] public string AddTagToContactGroupAutoDto { get; set; } - [IgnoreDataMember] + [JsonIgnore] public Boolean? AddTagToContactGroupAuto { get { return string.IsNullOrEmpty(AddTagToContactGroupAutoDto) ? null : (bool?)bool.Parse(AddTagToContactGroupAutoDto); } @@ -191,23 +164,24 @@ public Boolean? AddTagToContactGroupAuto [DataMember(Name = "IsConfiguredSmtp")] public bool IsConfiguredSmtp { get; set; } - public ISettings GetDefault(IServiceProvider serviceProvider) { + var currencyProvider = serviceProvider.GetService(); + var configuration = serviceProvider.GetService(); + var languageName = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; - var findedCurrency = CurrencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); + var findedCurrency = currencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); - return new CRMSettings(serviceProvider.GetService(), - serviceProvider.GetService()) + return new CRMSettings() { - defaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", + DefaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", IsConfiguredPortal = false, ChangeContactStatusGroupAuto = null, AddTagToContactGroupAuto = null, WriteMailToHistoryAuto = false, - WebFormKey = Guid.Empty//, -// InvoiceSetting = InvoiceSetting.DefaultSettings + WebFormKey = Guid.Empty, + InvoiceSetting = new InvoiceSetting(configuration).DefaultSettings }; } } @@ -230,6 +204,4 @@ public ISettings GetDefault(IServiceProvider serviceProvider) return new CRMReportSampleSettings { NeedToGenerate = true }; } } - - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 7db2d894162..7366ca9ae2a 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -175,7 +175,8 @@ public bool CanCreateReports public void SaveDefaultCurrencySettings(CurrencyInfo currency) { var tenantSettings = SettingsManager.Load(); - tenantSettings.DefaultCurrency = currency; + + tenantSettings.DefaultCurrency = currency.Abbreviation; SettingsManager.Save(tenantSettings); } diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index b1e0a2a8f40..f05111dfb96 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -128,7 +128,8 @@ protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumer } protected Dictionary GetRelativeToEntity(int[] contactID, EntityType entityType, int[] entityID) - { Expression> exp = null; + { + Expression> exp = null; if (contactID != null && contactID.Length > 0 && (entityID == null || entityID.Length == 0)) exp = x => x.EntityType == entityType && contactID.Contains(x.ContactId); @@ -139,8 +140,8 @@ protected Dictionary GetRelativeToEntity(int[] contactID, EntityType .Where(exp) .Select(x => new { EntityId = x.EntityId, ContactId = x.ContactId }) .ToList() - .GroupBy(x=> x.EntityId) - .ToDictionary(x=>x.Key, y=> y.Select(c => c.ContactId).ToArray()); + .GroupBy(x => x.EntityId) + .ToDictionary(x => x.Key, y => y.Select(c => c.ContactId).ToArray()); } protected int[] GetRelativeToEntity(int? contactID, EntityType entityType, int? entityID) diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 3b1b35bb132..601626c06bc 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -429,7 +429,7 @@ public String GetContactLinkCountJSON(EntityType entityType) { sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType); } - + return JsonConvert.SerializeObject(sqlQuery.GroupBy(x => x.x.Id) .Select(x => x.Count()).ToList()); } @@ -505,7 +505,7 @@ private List GetEnityFields(EntityType entityType, int[] entityID, if (!includeEmptyFields) sqlQuery = sqlQuery.Where(x => x.y != null || x.x.Type == CustomFieldType.Heading); - + return sqlQuery.ToList().ConvertAll(x => ToCustomField(x.x, x.y)); } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 3f22b96274f..a07c3cc1231 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -130,17 +130,17 @@ public class InvoiceDao : AbstractDao new KeyValuePair(InvoiceStatus.Paid, InvoiceStatus.Sent)//Bug 23450 }; - private InvoiceSetting _invoiceSetting; - private InvoiceFormattedData _invoiceFormattedData; - private SettingsManager _settingsManager; - private FactoryIndexerInvoice _factoryIndexer; - private TenantUtil _tenantUtil; - private CRMSecurity _crmSecurity; + private readonly InvoiceSetting _invoiceSetting; + private readonly InvoiceFormattedData _invoiceFormattedData; + private readonly SettingsManager _settingsManager; + private readonly FactoryIndexerInvoice _factoryIndexer; + private readonly TenantUtil _tenantUtil; + private readonly CRMSecurity _crmSecurity; public InvoiceDao( DbContextManager dbContextManager, TenantManager tenantManager, - + SecurityContext securityContext, FactoryIndexerInvoice factoryIndexer, IOptionsMonitor logger, @@ -164,7 +164,7 @@ public InvoiceDao( _tenantUtil = tenantUtil; } - + public Boolean IsExist(int invoiceID) { return IsExistFromDb(invoiceID); diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index c3bcc180ef2..3ee81b4a7a4 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -40,6 +40,7 @@ using ASC.Core.Common.Settings; using ASC.Core.Tenants; using ASC.CRM.Core.EF; +using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Web.CRM.Classes; @@ -59,7 +60,14 @@ public class ReportDao : AbstractDao const string TimeFormat = "[h]:mm:ss;@"; const string ShortDateFormat = "M/d/yyyy"; - private DaoFactory DaoFactory { get; set; } + private IServiceProvider _serviceProvider; + private TenantManager _tenantManager; + private UserManager _userManager; + private Global _global; + private FilesIntegration _filesIntegration; + private CRMSettings _crmSettings; + private TenantUtil _tenantUtil; + private DaoFactory _daoFactory; #region Constructor @@ -80,35 +88,26 @@ public ReportDao(DbContextManager dbContextManager, logger, ascCache) { - TenantUtil = tenantUtil; - - FilesIntegration = filesIntegration; - CRMSettings = settingsManager.Load(); - Global = global; - UserManager = userManager; - TenantManager = tenantManager; - ServiceProvider = serviceProvider; + _tenantUtil = tenantUtil; + + _filesIntegration = filesIntegration; + _crmSettings = settingsManager.Load(); + _global = global; + _userManager = userManager; + _tenantManager = tenantManager; + _serviceProvider = serviceProvider; } #endregion - public IServiceProvider ServiceProvider { get; } - public TenantManager TenantManager { get; } - - public UserManager UserManager { get; } - public Global Global { get; } - public FilesIntegration FilesIntegration { get; } - - public CRMSettings CRMSettings { get; } - - public TenantUtil TenantUtil { get; } + #region Common Methods private void GetTimePeriod(ReportTimePeriod timePeriod, out DateTime fromDate, out DateTime toDate) { - var now = TenantUtil.DateTimeNow().Date; + var now = _tenantUtil.DateTimeNow().Date; var diff = (int)now.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; if (diff < 0) @@ -257,19 +256,18 @@ public List GetMissingRates(string defaultCurrency) #endregion - #region Report Files public List> SaveSampleReportFiles() { var result = new List>(); - var storeTemplate = Global.GetStoreTemplate(); + var storeTemplate = _global.GetStoreTemplate(); if (storeTemplate == null) return result; - var culture = UserManager.GetUsers(_securityContext.CurrentAccount.ID).GetCulture() ?? - TenantManager.GetCurrentTenant().GetCulture(); + var culture = _userManager.GetUsers(_securityContext.CurrentAccount.ID).GetCulture() ?? + _tenantManager.GetCurrentTenant().GetCulture(); var path = culture + "/"; @@ -284,14 +282,14 @@ public List GetMissingRates(string defaultCurrency) using (var stream = storeTemplate.GetReadStream("", filePath)) { - var document = ServiceProvider.GetService>(); + var document = _serviceProvider.GetService>(); document.Title = Path.GetFileName(filePath); - document.FolderID = DaoFactory.GetFileDao().GetRoot(); + document.FolderID = _daoFactory.GetFileDao().GetRoot(); document.ContentLength = stream.Length; - var file = DaoFactory.GetFileDao().SaveFile(document, stream); + var file = _daoFactory.GetFileDao().SaveFile(document, stream); SaveFile((int)file.ID, -1); @@ -309,7 +307,7 @@ public List GetMissingRates(string defaultCurrency) public List> GetFiles(Guid userId) { - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); var fileIds = Query(CRMDbContext.ReportFile).Where(x => x.CreateBy == userId).Select(x => x.FileId).ToArray(); @@ -333,7 +331,7 @@ public Files.Core.File GetFile(int fileid, Guid userId) var exist = Query(CRMDbContext.ReportFile) .Any(x => x.CreateBy == userId && x.FileId == fileid); - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); return exist ? filedao.GetFile(fileid) : null; @@ -346,7 +344,7 @@ public void DeleteFile(int fileid) CRMDbContext.Remove(itemToDelete); CRMDbContext.SaveChanges(); - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); filedao.DeleteFile(fileid); } @@ -360,7 +358,7 @@ public void DeleteFiles(Guid userId) CRMDbContext.Remove(itemToDelete); CRMDbContext.SaveChanges(); - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); foreach (var fileId in fileIds) { @@ -376,7 +374,7 @@ public void SaveFile(int fileId, int reportType) { FileId = fileId, ReportType = (ReportType)reportType, - CreateOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + CreateOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), CreateBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -1239,152 +1237,154 @@ public void SaveFile(int fileId, int reportType) //#endregion - //#region WorkloadByTasksReport - - //public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => x.IsClosed) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - - - // var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => x.IsClosed) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Where(x => (!x.IsClosed && x.Deadline < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || - // (x.IsClosed && x.LastModifedOn > x.Deadline)) - // .Any(); - - // return sqlNewTasksQuery || - // sqlClosedTasksQuery || - // sqlOverdueTasksQuery; - //} + #region WorkloadByTasksReport - //public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // var reportData = BuildWorkloadByTasksReport(timePeriod, managers); - - // if (reportData == null || !reportData.Any()) return null; - - // var hasData = reportData.Any(item => item.Value.Count > 0); + public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; - // return hasData ? GenerateReportData(timePeriod, reportData) : null; - //} + GetTimePeriod(timePeriod, out fromDate, out toDate); - //private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; + var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); - // GetTimePeriod(timePeriod, out fromDate, out toDate); + var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.IsClosed) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); - // var sqlNewTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); - // var sqlClosedTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Eq("t.is_closed", 1)) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); - // var sqlOverdueTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); + var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.IsClosed) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => (!x.IsClosed && x.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + (x.IsClosed && x.LastModifedOn > x.Deadline)) + .Any(); - // Dictionary> res; + return sqlNewTasksQuery || + sqlClosedTasksQuery || + sqlOverdueTasksQuery; + } - // using (var tx = Db.BeginTransaction()) - // { - // res = new Dictionary> - // { - // {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, - // {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, - // {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} - // }; + public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByTasksReport(timePeriod, managers); - // tx.Commit(); - // } + if (reportData == null || !reportData.Any()) return null; - // return res; - //} + var hasData = reportData.Any(item => item.Value.Count > 0); - //private WorkloadByTasks ToWorkloadByTasks(object[] row) - //{ - // return new WorkloadByTasks - // { - // CategoryId = Convert.ToInt32(row[0]), - // CategoryName = Convert.ToString(row[1]), - // UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), - // UserName = Convert.ToString(row[3]), - // Count = Convert.ToInt32(row[4]) - // }; - //} + return hasData ? GenerateReportData(timePeriod, reportData) : null; + } - //private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) - //{ - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByTasksReport, - // sheetName = CRMReportResource.WorkloadByTasksReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), + private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) + { + throw new NotImplementedException(); + + //DateTime fromDate; + //DateTime toDate; + + //GetTimePeriod(timePeriod, out fromDate, out toDate); + + //var sqlNewTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + //var sqlClosedTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Eq("t.is_closed", 1)) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + //var sqlOverdueTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + //Dictionary> res; + + //using (var tx = Db.BeginTransaction()) + //{ + // res = new Dictionary> + // { + // {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, + // {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, + // {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} + // }; + + // tx.Commit(); + //} + + //return res; + } - // header1 = CRMReportResource.ClosedTasks, - // header2 = CRMReportResource.NewTasks, - // header3 = CRMReportResource.OverdueTasks, + private WorkloadByTasks ToWorkloadByTasks(object[] row) + { + return new WorkloadByTasks + { + CategoryId = Convert.ToInt32(row[0]), + CategoryName = Convert.ToString(row[1]), + UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), + UserName = Convert.ToString(row[3]), + Count = Convert.ToInt32(row[4]) + }; + } - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total - // }, - // data = reportData - // }; - //} + private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) + { + return new + { + resource = new + { + header = CRMReportResource.WorkloadByTasksReport, + sheetName = CRMReportResource.WorkloadByTasksReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + header1 = CRMReportResource.ClosedTasks, + header2 = CRMReportResource.NewTasks, + header3 = CRMReportResource.OverdueTasks, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total + }, + data = reportData + }; + } - //#endregion + #endregion //#region WorkloadByDealsReport diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index a50c3e9eebe..f8db8d9c63f 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -818,21 +818,21 @@ public bool HaveLateTask(int contactID) public virtual Task SaveOrUpdateTask(Task newTask) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); - + return SaveOrUpdateTaskInDb(newTask); } public virtual Task[] SaveOrUpdateTaskList(List newTasks) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); - + var result = new List(); - + foreach (var newTask in newTasks) { result.Add(SaveOrUpdateTaskInDb(newTask)); } - + return result.ToArray(); } diff --git a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs index c79e906e1be..344127989b8 100644 --- a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs @@ -27,7 +27,6 @@ #region Import using System; -using System.Runtime.Serialization; using ASC.Common.Security; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs index 26f2e75ef42..26e19cfa90a 100644 --- a/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs +++ b/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs @@ -34,7 +34,7 @@ namespace ASC.CRM.ApiModels [Scope] public class CurrencyRateInfoDtoHelper { - private IMapper _mapper; + private readonly IMapper _mapper; public CurrencyRateInfoDtoHelper(IMapper mapper) { diff --git a/products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs b/products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs deleted file mode 100644 index d8fa4c8231f..00000000000 --- a/products/ASC.CRM/Server/Helpers/HistoryCategoryDtoHelper.cs +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common; -using ASC.CRM.Core.Entities; -using ASC.Web.Core.Utility.Skins; -using ASC.Web.CRM.Configuration; - -namespace ASC.CRM.ApiModels -{ - [Scope] - public sealed class HistoryCategoryDtoHelper - { - public HistoryCategoryDtoHelper(WebImageSupplier webImageSupplier) - { - WebImageSupplier = webImageSupplier; - } - - public WebImageSupplier WebImageSupplier; - - public HistoryCategoryBaseDto Get(ListItem listItem) - { - return new HistoryCategoryBaseDto(listItem) - { - ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID) - }; - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs index 1ab879402c0..ffb0579211c 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs @@ -29,7 +29,6 @@ using System.Linq; using ASC.Api.Core; -using ASC.Common; using ASC.Common.Web; using ASC.CRM.ApiModels; using ASC.CRM.Core; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs index b970a8f655d..bc41767b6d9 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using ASC.CRM.ApiModels; using ASC.CRM.Core.Dao; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs index 7cfb6abd38d..273385be083 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs @@ -69,6 +69,9 @@ public InvoiceBaseDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, public InvoiceBaseDto Convert(Invoice source, InvoiceBaseDto destination, ResolutionContext context) { + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); + var result = new InvoiceBaseDto { Id = source.ID, @@ -79,7 +82,7 @@ public InvoiceBaseDto Convert(Invoice source, InvoiceBaseDto destination, Resolu DueDate = _apiDateTimeHelper.Get(source.DueDate), Currency = !String.IsNullOrEmpty(source.Currency) ? context.Mapper.Map(_currencyProvider.Get(source.Currency)) : - context.Mapper.Map(_settingsManager.Load().DefaultCurrency), + context.Mapper.Map(defaultCurrency), ExchangeRate = source.ExchangeRate, Language = source.Language, PurchaseOrderNumber = source.PurchaseOrderNumber, diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs index c3ac77dadc5..2bf89600325 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs @@ -69,6 +69,9 @@ public InvoiceDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, public InvoiceDto Convert(Invoice source, InvoiceDto destination, ResolutionContext context) { + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); + var result = new InvoiceDto { Id = source.ID, @@ -79,7 +82,7 @@ public InvoiceDto Convert(Invoice source, InvoiceDto destination, ResolutionCont DueDate = _apiDateTimeHelper.Get(source.DueDate), Currency = !String.IsNullOrEmpty(source.Currency) ? context.Mapper.Map(_currencyProvider.Get(source.Currency)) : - context.Mapper.Map(_settingsManager.Load().DefaultCurrency), + context.Mapper.Map(defaultCurrency), ExchangeRate = source.ExchangeRate, Language = source.Language, PurchaseOrderNumber = source.PurchaseOrderNumber, diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs index dcdf52c9d37..8c50b3cb480 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs @@ -67,6 +67,9 @@ public InvoiceItemDto Convert(InvoiceItem source, InvoiceItemDto destination, Re if (destination != null) throw new NotImplementedException(); + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); + var result = new InvoiceItemDto { @@ -80,7 +83,7 @@ public InvoiceItemDto Convert(InvoiceItem source, InvoiceItemDto destination, Re CreateBy = _employeeWraperHelper.Get(source.CreateBy), Currency = !String.IsNullOrEmpty(source.Currency) ? context.Mapper.Map(_currencyProvider.Get(source.Currency)) : - context.Mapper.Map(_settingsManager.Load().DefaultCurrency), + context.Mapper.Map(defaultCurrency), CanEdit = _crmSecurity.CanEdit(source), CanDelete = _crmSecurity.CanDelete(source) }; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs similarity index 66% rename from products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs rename to products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs index 3395de5b858..f2bdd1e8926 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskCategoryDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs @@ -24,8 +24,12 @@ */ +using System; + using ASC.CRM.ApiModels; +using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.Web.Core.Utility.Skins; using ASC.Web.CRM.Configuration; @@ -33,21 +37,42 @@ namespace ASC.CRM.Mapping { - public sealed class TaskCategoryDtoTypeConverter : ITypeConverter + public sealed class ListItemDtoTypeConverter : ITypeConverter, + ITypeConverter { private readonly WebImageSupplier _webImageSupplier; + private readonly DaoFactory _daoFactory; - public TaskCategoryDtoTypeConverter(WebImageSupplier webImageSupplier) + public ListItemDtoTypeConverter(WebImageSupplier webImageSupplier, + DaoFactory daoFactory) { _webImageSupplier = webImageSupplier; + _daoFactory = daoFactory; } public TaskCategoryBaseDto Convert(ListItem source, TaskCategoryBaseDto destination, ResolutionContext context) { + if (destination != null) + throw new NotImplementedException(); + return new TaskCategoryDto(source) { ImagePath = _webImageSupplier.GetAbsoluteWebPath(source.AdditionalParams, ProductEntryPoint.ID) }; } + + public HistoryCategoryDto Convert(ListItem source, HistoryCategoryDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new HistoryCategoryDto(source); + + result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, source.ID); + + + throw new System.NotImplementedException(); + } } -} \ No newline at end of file +} + diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs index 0b62c134e1f..849ea02ed9e 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs @@ -42,13 +42,13 @@ namespace ASC.CRM.Mapping [Scope] public class RelationshipEventDtoTypeConverter : ITypeConverter { - private HistoryCategoryDtoHelper _historyCategoryDtoHelper; - private FileWrapperHelper _fileWrapperHelper; - private DaoFactory _daoFactory; - private CRMSecurity _crmSecurity; - private ApiDateTimeHelper _apiDateTimeHelper; - private EmployeeWraperHelper _employeeWraperHelper; - private EntityDtoHelper _entityDtoHelper; + private readonly HistoryCategoryDto _historyCategoryDtoHelper; + private readonly FileWrapperHelper _fileWrapperHelper; + private readonly DaoFactory _daoFactory; + private readonly CRMSecurity _crmSecurity; + private readonly ApiDateTimeHelper _apiDateTimeHelper; + private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly EntityDtoHelper _entityDtoHelper; public RelationshipEventDtoTypeConverter( ApiDateTimeHelper apiDateTimeHelper, @@ -56,8 +56,7 @@ public RelationshipEventDtoTypeConverter( FileWrapperHelper fileWrapperHelper, CRMSecurity cRMSecurity, DaoFactory daoFactory, - EntityDtoHelper entityDtoHelper, - HistoryCategoryDtoHelper historyCategoryDtoHelper) + EntityDtoHelper entityDtoHelper) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; @@ -65,7 +64,6 @@ public RelationshipEventDtoTypeConverter( _daoFactory = daoFactory; _fileWrapperHelper = fileWrapperHelper; _entityDtoHelper = entityDtoHelper; - _historyCategoryDtoHelper = historyCategoryDtoHelper; } public RelationshipEventDto Convert(RelationshipEvent source, RelationshipEventDto destination, ResolutionContext context) @@ -85,7 +83,7 @@ public RelationshipEventDto Convert(RelationshipEvent source, RelationshipEventD if (historyCategory != null) { - result.Category = _historyCategoryDtoHelper.Get(historyCategory); + result.Category = (HistoryCategoryBaseDto)context.Mapper.Map(historyCategory); } if (source.EntityID > 0) @@ -98,10 +96,10 @@ public RelationshipEventDto Convert(RelationshipEvent source, RelationshipEventD if (source.ContactID > 0) { var relativeContact = _daoFactory.GetContactDao().GetByID(source.ContactID); - + if (relativeContact != null) { - result.Contact = context.Mapper.Map(relativeContact); + result.Contact = context.Mapper.Map(relativeContact); } } diff --git a/products/ASC.CRM/Server/Properties/launchSettings.json b/products/ASC.CRM/Server/Properties/launchSettings.json index 7a3e9309af3..12700d139f0 100644 --- a/products/ASC.CRM/Server/Properties/launchSettings.json +++ b/products/ASC.CRM/Server/Properties/launchSettings.json @@ -9,21 +9,10 @@ }, "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "weatherforecast", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "$STORAGE_ROOT": "../../../Data", - "log__name": "crm", - "log__dir": "../../../Logs" - } - }, "Kestrel WebServer": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "api/2.0/crm/task/10", + "launchUrl": "api/2.0/crm/contact/filter", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "$STORAGE_ROOT": "../../../Data", diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index d79524b094c..0a37d757df1 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text; -using System.Text.Json; using System.Text.Json.Serialization; using ASC.Api.Core; @@ -62,7 +58,7 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); - DIHelper.TryAdd(); + DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index 9f9ba0f9401..1fa4639d583 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -167,7 +167,11 @@ public Decimal MoneyConvert(decimal amount, string from, string to) public decimal MoneyConvertToDefaultCurrency(decimal amount, string from) { - return MoneyConvert(amount, from, SettingsManager.Load().DefaultCurrency.Abbreviation); + + var crmSettings = SettingsManager.Load(); + var defaultCurrency = Get(crmSettings.DefaultCurrency); + + return MoneyConvert(amount, from, defaultCurrency.Abbreviation); } private bool ObsoleteData() diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index 4f229c027a8..ee3b53fe13c 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -45,7 +45,7 @@ namespace ASC.Web.CRM.Classes { public partial class ImportDataOperation { - private Int32 DaoIterationStep = 200; + private readonly Int32 DaoIterationStep = 200; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index 4ee0992ffca..da09967df26 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -103,10 +103,13 @@ private void ImportOpportunityData(DaoFactory _daoFactory) var currency = CurrencyProvider.Get(GetPropertyValue("bid_currency")); + var crmSettings = SettingsManager.Load(); + var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); + if (currency != null) obj.BidCurrency = currency.Abbreviation; else - obj.BidCurrency = SettingsManager.Load().DefaultCurrency.Abbreviation; + obj.BidCurrency = defaultCurrency.Abbreviation; decimal bidValue; diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index 5b4f68c5978..a463c919057 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -106,7 +106,8 @@ public SendBatchEmailsOperation( AuthManager authManager, SettingsManager settingsManager, MailSenderDataCache mailSenderDataCache, - DaoFactory daoFactory + DaoFactory daoFactory, + CoreConfiguration coreConfiguration ) { TenantUtil = tenantUtil; @@ -117,7 +118,10 @@ DaoFactory daoFactory _log = logger.Get("ASC.CRM.MailSender"); _tenantID = tenantManager.GetCurrentTenant().TenantId; - _smtpSetting = settingsManager.Load().SMTPServerSetting; + + var _crmSettings = settingsManager.Load(); + + _smtpSetting = new SMTPServerSetting(coreConfiguration.SmtpSettings); _currUser = SecurityContext.CurrentAccount.ID; @@ -615,13 +619,15 @@ public MailSender( SettingsManager settingsManager, MailSenderDataCache mailSenderDataCache, ProgressQueueOptionsManager progressQueueOptionsManager, - SendBatchEmailsOperation sendBatchEmailsOperation + SendBatchEmailsOperation sendBatchEmailsOperation, + CoreConfiguration coreConfiguration ) { SendBatchEmailsOperation = sendBatchEmailsOperation; TenantID = tenantManager.GetCurrentTenant().TenantId; MailSenderDataCache = mailSenderDataCache; _mailQueue = progressQueueOptionsManager.Value; + CoreConfiguration = coreConfiguration; int parsed; @@ -641,7 +647,7 @@ SendBatchEmailsOperation sendBatchEmailsOperation public SendBatchEmailsOperation SendBatchEmailsOperation { get; } public MailSenderDataCache MailSenderDataCache { get; } public int TenantID { get; } - + public CoreConfiguration CoreConfiguration { get; } public IOptionsMonitor LogManager { get; } public int GetQuotas() @@ -722,7 +728,7 @@ public void StartSendTestMail(string recipientEmail, string mailSubj, string mai } TenantManager.SetCurrentTenant(TenantID); - var smtpSetting = SettingsManager.Load().SMTPServerSetting; + var smtpSetting = new SMTPServerSetting(CoreConfiguration.SmtpSettings); ThreadPool.QueueUserWorkItem(_ => { diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index 35724ba3335..82f305e6093 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -56,7 +56,8 @@ public ReportHelper(TenantManager tenantManager, DaoFactory daoFactory, SecurityContext securityContext, IServiceProvider serviceProvider, - IHttpContextAccessor httpContextAccessor + IHttpContextAccessor httpContextAccessor, + CurrencyProvider currencyProvider ) { TenantManager = tenantManager; @@ -68,8 +69,10 @@ IHttpContextAccessor httpContextAccessor DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; SecurityContext = securityContext; HttpContext = httpContextAccessor; + CurrencyProvider = currencyProvider; } + private CurrencyProvider CurrencyProvider { get; } public IHttpContextAccessor HttpContext { get; } public SecurityContext SecurityContext { get; } public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } @@ -167,13 +170,18 @@ public List GetMissingRates(ReportType reportType) if (reportType == ReportType.WorkloadByTasks || reportType == ReportType.WorkloadByInvoices || reportType == ReportType.WorkloadByContacts || reportType == ReportType.WorkloadByVoip) return null; - return reportDao.GetMissingRates(SettingsManager.Load().DefaultCurrency.Abbreviation); + var crmSettings = SettingsManager.Load(); + var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); + + return reportDao.GetMissingRates(defaultCurrency.Abbreviation); } private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { + var crmSettings = SettingsManager.Load(); + var reportDao = DaoFactory.GetReportDao(); - var defaultCurrency = SettingsManager.Load().DefaultCurrency.Abbreviation; + var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); throw new NotImplementedException(); From ec05e8dc9a2914652808fcdd6f77cd7c4c552813 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 24 Mar 2021 18:55:47 +0300 Subject: [PATCH 35/61] crm: refactoring & bugfix --- .../ASC.CRM/Server/Api/CasesController.cs | 2 +- .../Server/Api/ContactInfosController.cs | 13 +- .../ASC.CRM/Server/Api/ContactsController.cs | 10 +- .../Server/Api/CurrencyRatesController.cs | 13 +- .../Server/Api/CustomFieldsController.cs | 15 +- .../ASC.CRM/Server/Api/DealsController.cs | 2 +- .../ASC.CRM/Server/Api/InvoicesController.cs | 5 +- .../ASC.CRM/Server/Api/ListItemsController.cs | 32 +- .../Api/RelationshipEventsController.cs | 13 +- .../ASC.CRM/Server/Api/ReportsController.cs | 13 +- products/ASC.CRM/Server/Api/TagsController.cs | 48 +- .../Server/Api/TaskTemplateController.cs | 20 +- .../ASC.CRM/Server/Api/TasksController.cs | 42 +- .../ASC.CRM/Server/Api/UtilsController.cs | 8 +- products/ASC.CRM/Server/Api/VoipController.cs | 25 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 3447 +++++++++-------- .../ASC.CRM/Server/Core/EF/DbCurrencyRate.cs | 2 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 55 +- 18 files changed, 1962 insertions(+), 1803 deletions(-) diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index e743a67a4a0..acbd69e6cf2 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -634,7 +634,7 @@ public IEnumerable GetCasesMembers(int caseid) /// Participant /// [Create(@"case/{caseid:int}/contact")] - public ContactDto AddMemberToCases(int caseid, int contactid) + public ContactDto AddMemberToCases([FromRoute] int caseid,[FromForm] int contactid) { if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index b888d0659aa..27c713e7376 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -41,6 +41,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + using Newtonsoft.Json; using Newtonsoft.Json.Serialization; @@ -158,7 +160,12 @@ public ContactInfoDto GetContactInfoByID(int contactid, int id) /// /// [Create(@"contact/{contactid:int}/data")] - public ContactInfoDto CreateContactInfo(int contactid, ContactInfoType infoType, string data, bool isPrimary, string category) + public ContactInfoDto CreateContactInfo( + [FromRoute] int contactid, + [FromForm] ContactInfoType infoType, + [FromForm] string data, + [FromForm] bool isPrimary, + [FromForm] string category) { if (string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); var contact = _daoFactory.GetContactDao().GetByID(contactid); @@ -220,7 +227,7 @@ public ContactInfoDto CreateContactInfo(int contactid, ContactInfoType infoType, /// /// [Create(@"contact/{contactid:int}/addressdata")] - public ContactInfoDto CreateContactInfoAddress(int contactid, Address address) + public ContactInfoDto CreateContactInfoAddress([FromRoute] int contactid, Address address) { if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid"); @@ -279,7 +286,7 @@ public ContactInfoDto CreateContactInfoAddress(int contactid, Address address) /// /// false [Create(@"contact/{contactid:int}/batch")] - public IEnumerable CreateBatchContactInfo(int contactid, IEnumerable items) + public IEnumerable CreateBatchContactInfo([FromRoute] int contactid, [FromForm] IEnumerable items) { if (contactid <= 0) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index 56bbcba57f9..b86925b43eb 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -274,7 +274,7 @@ public IEnumerable GetContactsByProjectID(int projectid) /// Opportunity /// [Create(@"contact/{contactid:int}/opportunity/{opportunityid:int}")] - public OpportunityDto AddDealToContact(int contactid, [FromQuery] int opportunityid) + public OpportunityDto AddDealToContact([FromRoute] int contactid, [FromRoute] int opportunityid) { if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException(); @@ -676,7 +676,7 @@ public IEnumerable GetPeopleFromCompany(int companyid) /// Person /// [Create(@"contact/company/{companyid:int}/person")] - public PersonDto AddPeopleToCompany(int companyid, int personid) + public PersonDto AddPeopleToCompany([FromRoute] int companyid, [FromForm] int personid) { if ((companyid <= 0) || (personid <= 0)) throw new ArgumentException(); @@ -1060,7 +1060,7 @@ public CompanyDto CreateCompany([FromForm] CreateOrUpdateCompanyRequestDto inDto /// Contact list /// [Create(@"contact/company/quick")] - public IEnumerable CreateCompany(IEnumerable companyName) + public IEnumerable CreateCompany([FromForm] IEnumerable companyName) { if (companyName == null) throw new ArgumentException(); @@ -1110,7 +1110,7 @@ public IEnumerable CreateCompany(IEnumerable companyName /// Contact list /// [Create(@"contact/person/quick")] - public IEnumerable CreatePerson(IEnumerable> data) + public IEnumerable CreatePerson([FromForm] IEnumerable> data) { if (data == null) return null; @@ -1906,7 +1906,7 @@ public IProgressItem SendMailSMTPToContacts( /// false [Create(@"contact/mailsmtp/preview")] - public string GetMailSMTPToContactsPreview(string template, int contactId) + public string GetMailSMTPToContactsPreview([FromForm] string template, [FromForm] int contactId) { if (contactId == 0 || String.IsNullOrEmpty(template)) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs index 3d3ee6fe305..896ab957efd 100644 --- a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs +++ b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs @@ -40,6 +40,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class CurrencyRatesController : BaseApiController @@ -128,7 +130,10 @@ public CurrencyRateDto GetCurrencyRate(string fromCurrency, string toCurrency) /// Common /// [Create(@"currency/rates")] - public CurrencyRateDto CreateCurrencyRate(string fromCurrency, string toCurrency, decimal rate) + public CurrencyRateDto CreateCurrencyRate( + [FromForm] string fromCurrency, + [FromForm] string toCurrency, + [FromForm] decimal rate) { ValidateRate(rate); @@ -185,7 +190,9 @@ public CurrencyRateDto UpdateCurrencyRate(int id, string fromCurrency, string to /// Common /// [Create(@"currency/setrates")] - public List SetCurrencyRates(String currency, List rates) + public List SetCurrencyRates( + [FromForm] String currency, + [FromForm] List rates) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); @@ -229,7 +236,7 @@ public List SetCurrencyRates(String currency, ListCommon /// [Create(@"currency/addrates")] - public List AddCurrencyRates(List rates) + public List AddCurrencyRates([FromForm] List rates) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); diff --git a/products/ASC.CRM/Server/Api/CustomFieldsController.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs index d194674dc0b..4da9d644382 100644 --- a/products/ASC.CRM/Server/Api/CustomFieldsController.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -40,6 +40,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class CustomFieldsController : BaseApiController @@ -102,7 +104,11 @@ public IEnumerable GetCustomFieldForSubject(string entityTyp /// User field /// [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")] - public CustomFieldBaseDto SetEntityCustomFieldValue(string entityType, int entityid, int fieldid, string fieldValue) + public CustomFieldBaseDto SetEntityCustomFieldValue( + [FromRoute] string entityType, + [FromRoute] int entityid, + [FromRoute] int fieldid, + [FromForm] string fieldValue) { var customField = _daoFactory.GetCustomFieldDao().GetFieldDescription(fieldid); @@ -209,7 +215,12 @@ public CustomFieldBaseDto SetEntityCustomFieldValue(string entityType, int entit /// ]]> /// [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield")] - public CustomFieldDto CreateCustomFieldValue(string entityType, string label, int fieldType, int position, string mask) + public CustomFieldDto CreateCustomFieldValue( + [FromRoute] string entityType, + [FromForm] string label, + [FromForm] int fieldType, + [FromForm] int position, + [FromForm] string mask) { if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); var entityTypeObj = ToEntityType(entityType); diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index f7d77ea7d1d..6f573fae14d 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -755,7 +755,7 @@ public IEnumerable GetDealMembers(int opportunityid) /// Participant /// [Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")] - public ContactDto AddMemberToDeal(int opportunityid, int contactid) + public ContactDto AddMemberToDeal([FromRoute] int opportunityid, [FromRoute] int contactid) { if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/InvoicesController.cs b/products/ASC.CRM/Server/Api/InvoicesController.cs index ad280ae2671..d79c4c9b3fa 100644 --- a/products/ASC.CRM/Server/Api/InvoicesController.cs +++ b/products/ASC.CRM/Server/Api/InvoicesController.cs @@ -800,7 +800,10 @@ private ASC.Files.Core.File GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Enti /// Invoices /// ConverterData [Create(@"invoice/converter/data")] - public ConverterData GetInvoiceConverterData(int invoiceId, string storageUrl, string revisionId) + public ConverterData GetInvoiceConverterData( + [FromForm] int invoiceId, + [FromForm] string storageUrl, + [FromForm] string revisionId) { if (invoiceId <= 0) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/ListItemsController.cs b/products/ASC.CRM/Server/Api/ListItemsController.cs index d847ae5afb8..d19d7e8e5ce 100644 --- a/products/ASC.CRM/Server/Api/ListItemsController.cs +++ b/products/ASC.CRM/Server/Api/ListItemsController.cs @@ -40,6 +40,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class ListItemsController : BaseApiController @@ -75,11 +77,11 @@ public ListItemsController(CRMSecurity cRMSecurity, /// [Create(@"opportunity/stage")] public DealMilestoneDto CreateDealMilestone( - string title, - string description, - string color, - int successProbability, - DealMilestoneStatus stageType) + [FromForm] string title, + [FromForm] string description, + [FromForm] string color, + [FromForm] int successProbability, + [FromForm] DealMilestoneStatus stageType) { if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); @@ -254,7 +256,11 @@ public DealMilestoneDto DeleteDealMilestone(int id) ///History category /// [Create(@"history/category")] - public HistoryCategoryDto CreateHistoryCategory(string title, string description, string imageName, int sortOrder) + public HistoryCategoryDto CreateHistoryCategory( + [FromForm] string title, + [FromForm] string description, + [FromForm] string imageName, + [FromForm] int sortOrder) { if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); @@ -421,7 +427,11 @@ public HistoryCategoryDto DeleteHistoryCategory(int id) /// Task category /// [Create(@"task/category")] - public TaskCategoryDto CreateTaskCategory(string title, string description, string imageName, int sortOrder) + public TaskCategoryDto CreateTaskCategory( + [FromForm] string title, + [FromForm] string description, + [FromForm] string imageName, + [FromForm] int sortOrder) { if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); @@ -587,7 +597,11 @@ public TaskCategoryDto DeleteTaskCategory(int categoryid, int newcategoryid) /// Contact status /// [Create(@"contact/status")] - public ContactStatusDto CreateContactStatus(string title, string description, string color, int sortOrder) + public ContactStatusDto CreateContactStatus( + [FromForm] string title, + [FromForm] string description, + [FromForm] string color, + [FromForm] int sortOrder) { if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); @@ -775,7 +789,7 @@ public ContactStatusDto GetContactStatusByID(int contactStatusid) /// Contact type /// [Create(@"contact/type")] - public ContactTypeDto CreateContactType(string title, int sortOrder) + public ContactTypeDto CreateContactType([FromForm] string title, [FromForm] int sortOrder) { if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); diff --git a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs index 61a17445e0a..60063c5d6cf 100644 --- a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs +++ b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs @@ -46,6 +46,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Api @@ -233,7 +235,11 @@ public RelationshipEventDto DeleteHistory(int id) /// File info /// [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files/text")] - public FileWrapper CreateTextFile(string entityType, int entityid, string title, string content) + public FileWrapper CreateTextFile( + [FromRoute] string entityType, + [FromRoute] int entityid, + [FromForm] string title, + [FromForm] string content) { if (title == null) throw new ArgumentNullException("title"); if (content == null) throw new ArgumentNullException("content"); @@ -481,7 +487,10 @@ private FileWrapper SaveFile(int folderid, Stream file, string fileName) /// Files /// Entity with the file attached [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files")] - public RelationshipEventDto AttachFiles(string entityType, int entityid, IEnumerable fileids) + public RelationshipEventDto AttachFiles( + [FromRoute] string entityType, + [FromRoute] int entityid, + [FromForm] IEnumerable fileids) { if (entityid <= 0 || fileids == null) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/ReportsController.cs b/products/ASC.CRM/Server/Api/ReportsController.cs index d49c163e54d..ef3372c09a3 100644 --- a/products/ASC.CRM/Server/Api/ReportsController.cs +++ b/products/ASC.CRM/Server/Api/ReportsController.cs @@ -41,6 +41,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class ReportsController : BaseApiController @@ -161,7 +163,10 @@ public void Terminate() /// Object /// if user can't create reports [Create(@"report/check")] - public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) + public object CheckReportData( + [FromForm] ReportType type, + [FromForm] ReportTimePeriod timePeriod, + [FromForm] Guid[] managers) { if (!_global.CanCreateReports) throw _crmSecurity.CreateSecurityException(); @@ -182,10 +187,10 @@ public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid /// Report state /// if user can't create reports [Create(@"report/generate")] - public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers) + public ReportState GenerateReport([FromForm] ReportType type, [FromForm] ReportTimePeriod timePeriod, [FromForm] Guid[] managers) { - if (!_global.CanCreateReports) - throw _crmSecurity.CreateSecurityException(); +// if (!_global.CanCreateReports) + // throw _crmSecurity.CreateSecurityException(); return _reportHelper.RunGenareteReport(type, timePeriod, managers); } diff --git a/products/ASC.CRM/Server/Api/TagsController.cs b/products/ASC.CRM/Server/Api/TagsController.cs index 9f9ede5bc34..217bacd6f7c 100644 --- a/products/ASC.CRM/Server/Api/TagsController.cs +++ b/products/ASC.CRM/Server/Api/TagsController.cs @@ -42,6 +42,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class TagsController : BaseApiController @@ -139,7 +141,7 @@ public IEnumerable GetContactTags(int contactid) /// /// [Create(@"{entityType:regex(contact|opportunity|case)}/tag")] - public string CreateTag(string entityType, string tagName) + public string CreateTag([FromRoute] string entityType, [FromForm] string tagName) { if (string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -194,7 +196,7 @@ public IEnumerable GetAllTags(string entityType) /// Tag /// [Create(@"{entityType:regex(contact|opportunity|case)}/taglist")] - public string AddTagToBatch(string entityType, IEnumerable entityid, string tagName) + public string AddTagToBatch([FromRoute] string entityType, [FromForm] IEnumerable entityid, [FromForm] string tagName) { var ids = entityid.ToList(); if (entityid == null || !ids.Any()) throw new ArgumentException(); @@ -224,13 +226,13 @@ public string AddTagToBatch(string entityType, IEnumerable entityid, string /// [Create(@"contact/filter/taglist")] public string AddTagToBatchContacts( - IEnumerable tags, - int contactStage, - int contactType, - ContactListViewType contactListView, - ApiDateTime fromDate, - ApiDateTime toDate, - string tagName) + [FromForm] IEnumerable tags, + [FromForm] int contactStage, + [FromForm] int contactType, + [FromForm] ContactListViewType contactListView, + [FromForm] ApiDateTime fromDate, + [FromForm] ApiDateTime toDate, + [FromForm] string tagName) { var contacts = _daoFactory .GetContactDao() @@ -273,15 +275,15 @@ public string AddTagToBatchContacts( /// [Create(@"opportunity/filter/taglist")] public string AddTagToBatchDeals( - Guid responsibleid, - int opportunityStagesid, - IEnumerable tags, - int contactid, - DealMilestoneStatus? stageType, - bool? contactAlsoIsParticipant, - ApiDateTime fromDate, - ApiDateTime toDate, - string tagName) + [FromForm] Guid responsibleid, + [FromForm] int opportunityStagesid, + [FromForm] IEnumerable tags, + [FromForm] int contactid, + [FromForm] DealMilestoneStatus? stageType, + [FromForm] bool? contactAlsoIsParticipant, + [FromForm] ApiDateTime fromDate, + [FromForm] ApiDateTime toDate, + [FromForm] string tagName) { var deals = _daoFactory .GetDealDao() @@ -316,7 +318,11 @@ public string AddTagToBatchDeals( /// Tag /// [Create(@"case/filter/taglist")] - public string AddTagToBatchCases(int contactid, bool? isClosed, IEnumerable tags, string tagName) + public string AddTagToBatchCases( + [FromForm] int contactid, + [FromForm] bool? isClosed, + [FromForm] IEnumerable tags, + [FromForm] string tagName) { var caseses = _daoFactory.GetCasesDao().GetCases(_apiContext.FilterValue, contactid, isClosed, tags, 0, 0, null) .Where(_crmSecurity.CanAccessTo).ToList(); @@ -365,7 +371,7 @@ public IEnumerable DeleteUnusedTag(string entityType) /// Tag /// [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/tag")] - public string AddTagTo(string entityType, int entityid, string tagName) + public string AddTagTo([FromRoute] string entityType, [FromRoute] int entityid, [FromForm] string tagName) { if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); @@ -398,7 +404,7 @@ public string AddTagTo(string entityType, int entityid, string tagName) /// Tag /// [Create(@"{entityType:regex(company|person)}/{entityid:int}/tag/group")] - public string AddContactTagToGroup(string entityType, int entityid, string tagName) + public string AddContactTagToGroup([FromRoute] string entityType, [FromRoute] int entityid, [FromForm] string tagName) { if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/TaskTemplateController.cs b/products/ASC.CRM/Server/Api/TaskTemplateController.cs index 5e595ae2377..5802bb4515e 100644 --- a/products/ASC.CRM/Server/Api/TaskTemplateController.cs +++ b/products/ASC.CRM/Server/Api/TaskTemplateController.cs @@ -39,6 +39,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class TaskTemplateController : BaseApiController @@ -70,7 +72,7 @@ public TaskTemplateController(CRMSecurity crmSecurity, /// /// false [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/tasktemplatecontainer")] - public TaskTemplateContainerDto CreateTaskTemplateContainer(string entityType, string title) + public TaskTemplateContainerDto CreateTaskTemplateContainer([FromRoute] string entityType, [FromForm] string title) { if (string.IsNullOrEmpty(title)) throw new ArgumentException(); @@ -218,14 +220,14 @@ public IEnumerable GetTaskTemplates(int containerid) /// false [Create(@"tasktemplatecontainer/{containerid:int}/tasktemplate")] public TaskTemplateDto CreateTaskTemplate( - int containerid, - string title, - string description, - Guid responsibleid, - int categoryid, - bool isNotify, - long offsetTicks, - bool deadLineIsFixed + [FromRoute] int containerid, + [FromForm] string title, + [FromForm] string description, + [FromForm] Guid responsibleid, + [FromForm] int categoryid, + [FromForm] bool isNotify, + [FromForm] long offsetTicks, + [FromForm] bool deadLineIsFixed ) { if (containerid <= 0 || string.IsNullOrEmpty(title) || categoryid <= 0) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/TasksController.cs b/products/ASC.CRM/Server/Api/TasksController.cs index 71fc09456c8..7c49c7daea9 100644 --- a/products/ASC.CRM/Server/Api/TasksController.cs +++ b/products/ASC.CRM/Server/Api/TasksController.cs @@ -17,6 +17,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class TasksController : BaseApiController @@ -282,16 +284,16 @@ public TaskDto DeleteTask(int taskid) /// Task [Create(@"task")] public TaskDto CreateTask( - string title, - string description, - ApiDateTime deadline, - Guid responsibleId, - int categoryId, - int contactId, - string entityType, - int entityId, - bool isNotify, - int alertValue + [FromForm] string title, + [FromForm] string description, + [FromForm] ApiDateTime deadline, + [FromForm] Guid responsibleId, + [FromForm] int categoryId, + [FromForm] int contactId, + [FromForm] string entityType, + [FromForm] int entityId, + [FromForm] bool isNotify, + [FromForm] int alertValue ) { if (!string.IsNullOrEmpty(entityType) && @@ -373,16 +375,16 @@ int alertValue /// false [Create(@"contact/task/group")] public IEnumerable CreateTaskGroup( - string title, - string description, - ApiDateTime deadline, - Guid responsibleId, - int categoryId, - int[] contactId, - string entityType, - int entityId, - bool isNotify, - int alertValue) + [FromForm] string title, + [FromForm] string description, + [FromForm] ApiDateTime deadline, + [FromForm] Guid responsibleId, + [FromForm] int categoryId, + [FromForm] int[] contactId, + [FromForm] string entityType, + [FromForm] int entityId, + [FromForm] bool isNotify, + [FromForm] int alertValue) { var tasks = new List(); diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index acffe047a92..e2382e36cb4 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -45,6 +45,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + namespace ASC.CRM.Api { public class UtilsController : BaseApiController @@ -439,7 +441,7 @@ public CurrencyInfoDto UpdateCRMCurrency(String currency) /// false [Create(@"{entityType:regex(contact|opportunity|case|task)}/import/start")] - public string StartImportFromCSV(string entityType, string csvFileURI, string jsonSettings) + public string StartImportFromCSV([FromRoute] string entityType, [FromForm] string csvFileURI, [FromForm] string jsonSettings) { EntityType entityTypeObj; @@ -511,7 +513,7 @@ public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string /// false [Create(@"import/uploadfake")] - public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings) + public FileUploadResult ProcessUploadFake( [FromForm] string csvFileURI, [FromForm] string jsonSettings) { return _importFromCSVManager.ProcessUploadFake(csvFileURI, jsonSettings); } @@ -569,7 +571,7 @@ public IProgressItem CancelPartialExport() /// false [Create(@"export/partial/{entityType:regex(contact|opportunity|case|task|invoiceitem)}/start")] - public IProgressItem StartPartialExport(string entityType, string base64FilterString) + public IProgressItem StartPartialExport([FromRoute] string entityType, [FromForm] string base64FilterString) { if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index fc2bc7a2813..4e073527495 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -53,6 +53,8 @@ using AutoMapper; +using Microsoft.AspNetCore.Mvc; + using SecurityContext = ASC.Core.SecurityContext; namespace ASC.CRM.Api @@ -156,7 +158,7 @@ public IEnumerable GetExistingPhoneNumbers() /// /// [Create(@"voip/numbers")] - public VoipPhone BuyNumber(string number) + public VoipPhone BuyNumber([FromForm] string number) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); @@ -177,7 +179,7 @@ public VoipPhone BuyNumber(string number) /// /// [Create(@"voip/numbers/link")] - public VoipPhone LinkNumber(string id) + public VoipPhone LinkNumber([FromForm] string id) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); @@ -644,7 +646,7 @@ public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOut /// /// [Create(@"voip/call")] - public VoipCallDto MakeCall(string to, string contactId) + public VoipCallDto MakeCall([FromForm] string to, [FromForm] string contactId) { var number = _daoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull(); @@ -686,7 +688,7 @@ public VoipCallDto MakeCall(string to, string contactId) /// Voip /// [Create(@"voip/call/{callId:regex(\w+)}/answer")] - public VoipCallDto AnswerCall(string callId) + public VoipCallDto AnswerCall([FromRoute] string callId) { var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); @@ -705,7 +707,7 @@ public VoipCallDto AnswerCall(string callId) /// Voip /// [Create(@"voip/call/{callId:regex(\w+)}/reject")] - public VoipCallDto RejectCall(string callId) + public VoipCallDto RejectCall([FromRoute] string callId) { var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); @@ -723,7 +725,7 @@ public VoipCallDto RejectCall(string callId) /// Voip /// [Create(@"voip/call/{callId:regex(\w+)}/redirect")] - public VoipCallDto ReditectCall(string callId, string to) + public VoipCallDto ReditectCall([FromRoute] string callId, [FromForm] string to) { var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callId).NotFoundIfNull(); @@ -752,7 +754,14 @@ public VoipCallDto ReditectCall(string callId, string to) /// Voip /// [Create(@"voip/call/{callId:regex(\w+)}")] - public VoipCallDto SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price) + public VoipCallDto SaveCall( + [FromRoute] string callId, + [FromForm] string from, + [FromForm] string to, + [FromForm] Guid answeredBy, + [FromForm] VoipCallStatus? status, + [FromForm] string contactId, + [FromForm] decimal? price) { var dao = _daoFactory.GetVoipDao(); @@ -840,7 +849,7 @@ public VoipCallDto SaveCall(string callId, string from, string to, Guid answered /// Voip /// [Create(@"voip/price/{callId:regex(\w+)}")] - public void SavePrice(string callId) + public void SavePrice([FromRoute] string callId) { _voipEngine.SaveAdditionalInfo(callId); } diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 3ee81b4a7a4..80cce0da58e 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -65,7 +65,7 @@ public class ReportDao : AbstractDao private UserManager _userManager; private Global _global; private FilesIntegration _filesIntegration; - private CRMSettings _crmSettings; + private CurrencyInfo _defaultCurrency; private TenantUtil _tenantUtil; private DaoFactory _daoFactory; @@ -81,7 +81,9 @@ public ReportDao(DbContextManager dbContextManager, SettingsManager settingsManager, Global global, UserManager userManager, - IServiceProvider serviceProvider) : + IServiceProvider serviceProvider, + CurrencyProvider currencyProvider, + DaoFactory daoFactory) : base(dbContextManager, tenantManager, securityContext, @@ -91,17 +93,20 @@ public ReportDao(DbContextManager dbContextManager, _tenantUtil = tenantUtil; _filesIntegration = filesIntegration; - _crmSettings = settingsManager.Load(); _global = global; _userManager = userManager; _tenantManager = tenantManager; _serviceProvider = serviceProvider; + _daoFactory = daoFactory; + var crmSettings = settingsManager.Load(); + + _defaultCurrency = currencyProvider.Get(crmSettings.DefaultCurrency); } #endregion - + #region Common Methods @@ -386,1841 +391,1919 @@ public void SaveFile(int fileId, int reportType) #endregion - //#region SalesByManagersReport + #region SalesByManagersReport - //public bool CheckSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; + public bool CheckSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; - // GetTimePeriod(timePeriod, out fromDate, out toDate); + GetTimePeriod(timePeriod, out fromDate, out toDate); - // return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), - // x => x.DealMilestoneId, - // y => y.Id, - // (x, y) => new { x, y }) - // .Where(x => x.y.Status == DealMilestoneStatus.ClosedAndWon) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - // .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - //} + return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => x.y.Status == DealMilestoneStatus.ClosedAndWon) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + } - //public object GetSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // var reportData = BuildSalesByManagersReport(timePeriod, managers, defaultCurrency); + public object GetSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSalesByManagersReport(timePeriod, managers, defaultCurrency); - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - //} + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } - //private List BuildSalesByManagersReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // string dateSelector; - - // switch (timePeriod) - // { - // case ReportTimePeriod.Today: - // case ReportTimePeriod.Yesterday: - // dateSelector = "date_add(date(d.actual_close_date), interval extract(hour from d.actual_close_date) hour) as close_date"; - // break; - // case ReportTimePeriod.CurrentWeek: - // case ReportTimePeriod.PreviousWeek: - // case ReportTimePeriod.CurrentMonth: - // case ReportTimePeriod.PreviousMonth: - // dateSelector = "date(d.actual_close_date) as close_date"; - // break; - // case ReportTimePeriod.CurrentQuarter: - // case ReportTimePeriod.PreviousQuarter: - // case ReportTimePeriod.CurrentYear: - // case ReportTimePeriod.PreviousYear: - // dateSelector = "date_sub(date(d.actual_close_date), interval (extract(day from d.actual_close_date) - 1) day) as close_date"; - // break; - // default: - // return null; - // } - - // var sqlQuery = Query("crm_deal d") - // .Select("d.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // string.Format(@"sum((case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end)) as bid_value", defaultCurrency), - // dateSelector) - // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) - // .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("responsible_id", "close_date"); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesByManagers); - //} + private List BuildSalesByManagersReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; - //private SalesByManager ToSalesByManagers(object[] row) - //{ - // return new SalesByManager - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1]), - // Value = Convert.ToDecimal(row[2]), - // Date = Convert.ToDateTime(row[3]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[3])) - // }; - //} + GetTimePeriod(timePeriod, out fromDate, out toDate); - //private object GenerateReportData(ReportTimePeriod timePeriod, List data) - //{ - // switch (timePeriod) - // { - // case ReportTimePeriod.Today: - // case ReportTimePeriod.Yesterday: - // return GenerateReportDataByHours(timePeriod, data); - // case ReportTimePeriod.CurrentWeek: - // case ReportTimePeriod.PreviousWeek: - // case ReportTimePeriod.CurrentMonth: - // case ReportTimePeriod.PreviousMonth: - // return GenerateReportDataByDays(timePeriod, data); - // case ReportTimePeriod.CurrentQuarter: - // case ReportTimePeriod.PreviousQuarter: - // case ReportTimePeriod.CurrentYear: - // case ReportTimePeriod.PreviousYear: - // return GenerateReportByMonths(timePeriod, data); - // default: - // return null; - // } - //} + throw new NotImplementedException(); - //private object GenerateReportDataByHours(ReportTimePeriod timePeriod, List data) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var res = new Dictionary>(); - - // var users = data.Select(x => x.UserId).Distinct().ToList(); - - // foreach (var userId in users) - // { - // var date = fromDate; - - // while (date < toDate) - // { - // if (res.ContainsKey(userId)) - // { - // res[userId].Add(date, 0); - // } - // else - // { - // res.Add(userId, new Dictionary { { date, 0 } }); - // } - - // date = date.AddHours(1); - // } - // } - - // foreach (var item in data) - // { - // var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day, item.Date.Hour, 0, 0); - - // if (itemDate < res[item.UserId].First().Key) - // itemDate = res[item.UserId].First().Key; - - // if (itemDate > res[item.UserId].Last().Key) - // itemDate = res[item.UserId].Last().Key; - - // res[item.UserId][itemDate] += item.Value; - // } - - // var body = new List>(); - - // foreach (var resItem in res) - // { - // var bodyItem = new List - // { - // data.First(x => x.UserId == resItem.Key).UserName - // }; - - // bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); - - // body.Add(bodyItem); - // } - - // var head = new List(); - - // foreach (var key in res.First().Value.Keys) - // { - // head.Add(new { format = "H:mm", value = key.ToShortTimeString() }); - // } - - // return new - // { - // resource = new - // { - // manager = CRMReportResource.Manager, - // summary = CRMReportResource.Sum, - // total = CRMReportResource.Total, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - // sheetName = CRMReportResource.SalesByManagersReport, - // header = CRMReportResource.SalesByManagersReport, - // header1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, - // header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName1 = CRMReportResource.SalesByHour + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol - // }, - // thead = head, - // tbody = body - // }; - //} + //string dateSelector; - //private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var res = new Dictionary>(); - - // var users = data.Select(x => x.UserId).Distinct().ToList(); - - // foreach (var userId in users) - // { - // var date = fromDate; - - // while (date < toDate) - // { - // if (res.ContainsKey(userId)) - // { - // res[userId].Add(date, 0); - // } - // else - // { - // res.Add(userId, new Dictionary { { date, 0 } }); - // } - - // date = date.AddDays(1); - // } - // } - - // foreach (var item in data) - // { - // var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); - - // if (itemDate < res[item.UserId].First().Key) - // itemDate = res[item.UserId].First().Key; - - // if (itemDate > res[item.UserId].Last().Key) - // itemDate = res[item.UserId].Last().Key; - - // res[item.UserId][itemDate] += item.Value; - // } - - // var body = new List>(); - - // foreach (var resItem in res) - // { - // var bodyItem = new List - // { - // data.First(x => x.UserId == resItem.Key).UserName - // }; - - // bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); - - // body.Add(bodyItem); - // } - - // var head = new List(); - // var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); - // var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); - - // foreach (var key in res.First().Value.Keys) - // { - // head.Add(new { format = pattern, value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); - // } - - // return new - // { - // resource = new - // { - // manager = CRMReportResource.Manager, - // summary = CRMReportResource.Sum, - // total = CRMReportResource.Total, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - // sheetName = CRMReportResource.SalesByManagersReport, - // header = CRMReportResource.SalesByManagersReport, - // header1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, - // header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName1 = CRMReportResource.SalesByDay + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol - // }, - // thead = head, - // tbody = body - // }; - //} + //switch (timePeriod) + //{ + // case ReportTimePeriod.Today: + // case ReportTimePeriod.Yesterday: + // dateSelector = "date_add(date(d.actual_close_date), interval extract(hour from d.actual_close_date) hour) as close_date"; + // break; + // case ReportTimePeriod.CurrentWeek: + // case ReportTimePeriod.PreviousWeek: + // case ReportTimePeriod.CurrentMonth: + // case ReportTimePeriod.PreviousMonth: + // dateSelector = "date(d.actual_close_date) as close_date"; + // break; + // case ReportTimePeriod.CurrentQuarter: + // case ReportTimePeriod.PreviousQuarter: + // case ReportTimePeriod.CurrentYear: + // case ReportTimePeriod.PreviousYear: + // dateSelector = "date_sub(date(d.actual_close_date), interval (extract(day from d.actual_close_date) - 1) day) as close_date"; + // break; + // default: + // return null; + //} - //private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var res = new Dictionary>(); - - // var users = data.Select(x => x.UserId).Distinct().ToList(); - - // foreach (var userId in users) - // { - // var date = fromDate; - - // while (date < toDate) - // { - // if (res.ContainsKey(userId)) - // { - // res[userId].Add(date, 0); - // } - // else - // { - // res.Add(userId, new Dictionary { { date, 0 } }); - // } - - // date = date.AddMonths(1); - // } - // } - - // foreach (var item in data) - // { - // var itemDate = new DateTime(item.Date.Year, item.Date.Month, 1); - - // if (itemDate < res[item.UserId].First().Key) - // itemDate = res[item.UserId].First().Key; - - // if (itemDate > res[item.UserId].Last().Key) - // itemDate = res[item.UserId].Last().Key; - - // res[item.UserId][itemDate] += item.Value; - // } - - // var body = new List>(); - - // foreach (var resItem in res) - // { - // var bodyItem = new List - // { - // data.First(x => x.UserId == resItem.Key).UserName - // }; - - // bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); - - // body.Add(bodyItem); - // } - - // var head = new List(); - - // foreach (var key in res.First().Value.Keys) - // { - // head.Add(new { format = "MMM-yy", value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); - // } - - // return new - // { - // resource = new - // { - // manager = CRMReportResource.Manager, - // summary = CRMReportResource.Sum, - // total = CRMReportResource.Total, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - // sheetName = CRMReportResource.SalesByManagersReport, - // header = CRMReportResource.SalesByManagersReport, - // header1 = CRMReportResource.SalesByMonth + ", " + CRMSettings.DefaultCurrency.Symbol, - // header2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName1 = CRMReportResource.SalesByMonth + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName2 = CRMReportResource.TotalSalesByManagers + ", " + CRMSettings.DefaultCurrency.Symbol - // }, - // thead = head, - // tbody = body - // }; - //} + //var sqlQuery = Query("crm_deal d") + // .Select("d.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // string.Format(@"sum((case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end)) as bid_value", defaultCurrency), + // dateSelector) + // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) + // .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("d.actual_close_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("responsible_id", "close_date"); + + + //return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesByManagers); + } - //#endregion + private SalesByManager ToSalesByManagers(object[] row) + { + return new SalesByManager + { + UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + UserName = Convert.ToString(row[1]), + Value = Convert.ToDecimal(row[2]), + Date = Convert.ToDateTime(row[3]) == DateTime.MinValue ? DateTime.MinValue : _tenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[3])) + }; + } + private object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + switch (timePeriod) + { + case ReportTimePeriod.Today: + case ReportTimePeriod.Yesterday: + return GenerateReportDataByHours(timePeriod, data); + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.PreviousWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.PreviousMonth: + return GenerateReportDataByDays(timePeriod, data); + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.PreviousQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.PreviousYear: + return GenerateReportByMonths(timePeriod, data); + default: + return null; + } + } - //#region SalesForecastReport + private object GenerateReportDataByHours(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; - //public bool CheckSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), - // x => x.DealMilestoneId, - // y => y.Id, - // (x, y) => new { x, y }) - // .Where(x => x.y.Status == DealMilestoneStatus.Open) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - // .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - //} + GetTimePeriod(timePeriod, out fromDate, out toDate); - //public object GetSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // var reportData = BuildSalesForecastReport(timePeriod, managers, defaultCurrency); + var res = new Dictionary>(); - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - //} + var users = data.Select(x => x.UserId).Distinct().ToList(); - //private List BuildSalesForecastReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // string dateSelector; - - // switch (timePeriod) - // { - // case ReportTimePeriod.CurrentWeek: - // case ReportTimePeriod.NextWeek: - // case ReportTimePeriod.CurrentMonth: - // case ReportTimePeriod.NextMonth: - // dateSelector = "d.expected_close_date as close_date"; - // break; - // case ReportTimePeriod.CurrentQuarter: - // case ReportTimePeriod.NextQuarter: - // case ReportTimePeriod.CurrentYear: - // case ReportTimePeriod.NextYear: - // dateSelector = "date_sub(date(d.expected_close_date), interval (extract(day from d.expected_close_date) - 1) day) as close_date"; - // break; - // default: - // return null; - // } - - // var sqlQuery = Query("crm_deal d") - // .Select(string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as value", defaultCurrency), - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 - // end) as value_with_probability", defaultCurrency), - // dateSelector) - // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("close_date"); - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesForecast); - //} + foreach (var userId in users) + { + var date = fromDate; - //private SalesForecast ToSalesForecast(object[] row) - //{ - // return new SalesForecast - // { - // Value = Convert.ToDecimal(row[0]), - // ValueWithProbability = Convert.ToDecimal(row[1]), - // Date = Convert.ToDateTime(row[2]) == DateTime.MinValue ? DateTime.MinValue : TenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[2])) - // }; - //} + while (date < toDate) + { + if (res.ContainsKey(userId)) + { + res[userId].Add(date, 0); + } + else + { + res.Add(userId, new Dictionary { { date, 0 } }); + } - //private object GenerateReportData(ReportTimePeriod timePeriod, List data) - //{ - // switch (timePeriod) - // { - // case ReportTimePeriod.CurrentWeek: - // case ReportTimePeriod.NextWeek: - // case ReportTimePeriod.CurrentMonth: - // case ReportTimePeriod.NextMonth: - // return GenerateReportDataByDays(timePeriod, data); - // case ReportTimePeriod.CurrentQuarter: - // case ReportTimePeriod.NextQuarter: - // case ReportTimePeriod.CurrentYear: - // case ReportTimePeriod.NextYear: - // return GenerateReportByMonths(timePeriod, data); - // default: - // return null; - // } - //} + date = date.AddHours(1); + } + } - //private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var res = new Dictionary>(); - - // var date = fromDate; - - // while (date < toDate) - // { - // res.Add(date, new Tuple(0, 0)); - // date = date.AddDays(1); - // } - - // foreach (var item in data) - // { - // var key = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); - - // if (key < res.First().Key) - // key = res.First().Key; - - // if (key > res.Last().Key) - // key = res.Last().Key; - - // res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, - // res[key].Item2 + item.Value); - // } - - // var body = new List>(); - // var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); - // var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); - - // foreach (var resItem in res) - // { - // var bodyItem = new List - // { - // new {format = pattern, value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, - // new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, - // new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} - // }; - - // body.Add(bodyItem); - // } - - // var head = new List - // { - // CRMReportResource.Day, - // CRMReportResource.WithRespectToProbability, - // CRMReportResource.IfAllOpportunitiesWon - // }; - - // return new - // { - // resource = new - // { - // total = CRMReportResource.Total, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - // sheetName = CRMReportResource.SalesForecastReport, - // header = CRMReportResource.SalesForecastReport, - // header1 = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol - // }, - // thead = head, - // tbody = body - // }; - //} + foreach (var item in data) + { + var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day, item.Date.Hour, 0, 0); - //private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var res = new Dictionary>(); - - // var date = fromDate; - - // while (date < toDate) - // { - // res.Add(date, new Tuple(0, 0)); - // date = date.AddMonths(1); - // } - - // foreach (var item in data) - // { - // var key = new DateTime(item.Date.Year, item.Date.Month, 1); - - // if (key < res.First().Key) - // key = res.First().Key; - - // if (key > res.Last().Key) - // key = res.Last().Key; - - // res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, - // res[key].Item2 + item.Value); - // } - - // var body = new List>(); - - // foreach (var resItem in res) - // { - // var bodyItem = new List - // { - // new {format = "MMM-yy", value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, - // new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, - // new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} - // }; - - // body.Add(bodyItem); - // } - - // var head = new List - // { - // CRMReportResource.Month, - // CRMReportResource.WithRespectToProbability, - // CRMReportResource.IfAllOpportunitiesWon - // }; - - // return new - // { - // resource = new - // { - // total = CRMReportResource.Total, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - // sheetName = CRMReportResource.SalesForecastReport, - // header = CRMReportResource.SalesForecastReport, - // header1 = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName = CRMReportResource.SalesForecastReport + ", " + CRMSettings.DefaultCurrency.Symbol - // }, - // thead = head, - // tbody = body - // }; - //} + if (itemDate < res[item.UserId].First().Key) + itemDate = res[item.UserId].First().Key; - //#endregion + if (itemDate > res[item.UserId].Last().Key) + itemDate = res[item.UserId].Last().Key; + res[item.UserId][itemDate] += item.Value; + } - //#region SalesFunnelReport + var body = new List>(); - //public bool CheckSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; + foreach (var resItem in res) + { + var bodyItem = new List + { + data.First(x => x.UserId == resItem.Key).UserName + }; - // GetTimePeriod(timePeriod, out fromDate, out toDate); + bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); - // return Query(CRMDbContext.Deals) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - //} + body.Add(bodyItem); + } - //public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // var reportData = BuildSalesFunnelReport(timePeriod, managers, defaultCurrency); + var head = new List(); - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - //} + foreach (var key in res.First().Value.Keys) + { + head.Add(new { format = "H:mm", value = key.ToShortTimeString() }); + } - //private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query("crm_deal_milestone m") - // .Select("m.status", "m.title", - // "count(d.id) as deals_count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency), - // "avg(if(m.status = 1, datediff(d.actual_close_date, d.create_on), 0)) as deals_duration") - // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & - // Exp.EqColumns("d.deal_milestone_id", "m.id") & - // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & - // Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "m.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .GroupBy("m.id") - // .OrderBy("m.sort_order", true); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesFunnel); - //} + return new + { + resource = new + { + manager = CRMReportResource.Manager, + summary = CRMReportResource.Sum, + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesByManagersReport, + header = CRMReportResource.SalesByManagersReport, + header1 = CRMReportResource.SalesByHour + ", " + _defaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + _defaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByHour + ", " + _defaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + _defaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } - //private SalesFunnel ToSalesFunnel(object[] row) - //{ - // return new SalesFunnel - // { - // Status = (DealMilestoneStatus)Convert.ToInt32(row[0]), - // Title = Convert.ToString(row[1]), - // Count = Convert.ToInt32(row[2]), - // Value = Convert.ToDecimal(row[3]), - // Duration = Convert.ToInt32(row[4]) - // }; - //} + private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; - //private object GenerateReportData(ReportTimePeriod timePeriod, List data) - //{ - // var totalCount = data.Sum(x => x.Count); - - // if (totalCount == 0) return null; - - // var totalBudget = data.Sum(x => x.Value); - - // var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); - - // var reportData = data.Select(item => new List - // { - // item.Title, - // item.Status, - // item.Count, - // item.Value - // }).ToList(); - - // return new - // { - // resource = new - // { - // header = CRMReportResource.SalesFunnelReport, - // sheetName = CRMReportResource.SalesFunnelReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // chartName = CRMReportResource.SalesFunnelByCount, - // chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName2 = CRMReportResource.DealsCount, - // chartName3 = CRMReportResource.DealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - // totalCountLabel = CRMReportResource.TotalDealsCount, - // totalCountValue = totalCount, - - // totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - // totalBudgetValue = totalBudget, - - // averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - // averageBidValue = totalBudget / totalCount, - - // averageDurationLabel = CRMReportResource.AverageDealsDuration, - // averageDurationValue = closed.Sum(x => x.Duration) / closed.Count, - - // header1 = CRMReportResource.ByCount, - // header2 = CRMReportResource.ByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - // stage = CRMReportResource.Stage, - // count = CRMReportResource.Count, - // budget = CRMReportResource.Budget, - // conversion = CRMReportResource.Conversion, - - // deals = CRMDealResource.Deals, - // status0 = DealMilestoneStatus.Open.ToLocalizedString(), - // status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), - // status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() - // }, - // data = reportData - // }; - //} + GetTimePeriod(timePeriod, out fromDate, out toDate); - //#endregion + var res = new Dictionary>(); + var users = data.Select(x => x.UserId).Distinct().ToList(); - //#region WorkloadByContactsReport + foreach (var userId in users) + { + var date = fromDate; - //public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; + while (date < toDate) + { + if (res.ContainsKey(userId)) + { + res[userId].Add(date, 0); + } + else + { + res.Add(userId, new Dictionary { { date, 0 } }); + } - // GetTimePeriod(timePeriod, out fromDate, out toDate); + date = date.AddDays(1); + } + } - // return Query(CRMDbContext.Contacts) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - //} + foreach (var item in data) + { + var itemDate = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); - //public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // var reportData = BuildWorkloadByContactsReport(timePeriod, managers); + if (itemDate < res[item.UserId].First().Key) + itemDate = res[item.UserId].First().Key; - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - //} + if (itemDate > res[item.UserId].Last().Key) + itemDate = res[item.UserId].Last().Key; - //private List BuildWorkloadByContactsReport(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query(CRMDbContext.Contacts) - // .GroupJoin(Query(CRMDbContext.ListItem), - // x => x.ContactTypeId, - // y => y.Id, - // (x, y) => new { x, y }) - // .GroupJoin(Query(CRMDbContext.Deals), - // x => x.x.Id, - // y=> y.Id, - // (x,y) => new { x, y }) - - - - // var sqlQuery = Query("crm_contact c") - // .Select("c.create_by", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "i.id", - // "i.title", - // "count(c.id) as total", - // "count(d.id) as `with deals`") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & Exp.Eq("i.list_type", (int)ListType.ContactType)) - // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "c.tenant_id") & Exp.EqColumns("d.contact_id", "c.id")) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.create_by")) - // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("c.create_by", "i.id") - // .OrderBy("i.sort_order, i.title", true); - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByContacts); - //} + res[item.UserId][itemDate] += item.Value; + } - //private WorkloadByContacts ToWorkloadByContacts(object[] row) - //{ - // return new WorkloadByContacts - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1]), - // CategoryId = Convert.ToInt32(row[2]), - // CategoryName = Convert.ToString(row[3]), - // Count = Convert.ToInt32(row[4]), - // WithDeals = Convert.ToInt32(row[5]) - // }; - //} + var body = new List>(); - //private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) - //{ - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByContactsReport, - // sheetName = CRMReportResource.WorkloadByContactsReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // header1 = CRMReportResource.NewContacts, - // header2 = CRMReportResource.NewContactsWithAndWithoutDeals, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total, - - // noSet = CRMCommonResource.NoSet, - // withDeals = CRMReportResource.ContactsWithDeals, - // withouthDeals = CRMReportResource.ContactsWithoutDeals, - // }, - // data = reportData - // }; - //} + foreach (var resItem in res) + { + var bodyItem = new List + { + data.First(x => x.UserId == resItem.Key).UserName + }; - //#endregion + bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + body.Add(bodyItem); + } - #region WorkloadByTasksReport + var head = new List(); + var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); + var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); - public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + foreach (var key in res.First().Value.Keys) + { + head.Add(new { format = pattern, value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); + } + + return new + { + resource = new + { + manager = CRMReportResource.Manager, + summary = CRMReportResource.Sum, + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesByManagersReport, + header = CRMReportResource.SalesByManagersReport, + header1 = CRMReportResource.SalesByDay + ", " + _defaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + _defaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByDay + ", " + _defaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + _defaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } + + private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) { DateTime fromDate; DateTime toDate; GetTimePeriod(timePeriod, out fromDate, out toDate); - var sqlNewTasksQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) - .Any(); + var res = new Dictionary>(); - var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => x.IsClosed) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) - .Any(); + var users = data.Select(x => x.UserId).Distinct().ToList(); + foreach (var userId in users) + { + var date = fromDate; + while (date < toDate) + { + if (res.ContainsKey(userId)) + { + res[userId].Add(date, 0); + } + else + { + res.Add(userId, new Dictionary { { date, 0 } }); + } - var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - .Where(x => x.IsClosed) - .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) - .Where(x => (!x.IsClosed && x.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || - (x.IsClosed && x.LastModifedOn > x.Deadline)) - .Any(); + date = date.AddMonths(1); + } + } + + foreach (var item in data) + { + var itemDate = new DateTime(item.Date.Year, item.Date.Month, 1); + + if (itemDate < res[item.UserId].First().Key) + itemDate = res[item.UserId].First().Key; + + if (itemDate > res[item.UserId].Last().Key) + itemDate = res[item.UserId].Last().Key; + + res[item.UserId][itemDate] += item.Value; + } + + var body = new List>(); + + foreach (var resItem in res) + { + var bodyItem = new List + { + data.First(x => x.UserId == resItem.Key).UserName + }; - return sqlNewTasksQuery || - sqlClosedTasksQuery || - sqlOverdueTasksQuery; + bodyItem.AddRange(resItem.Value.Select(x => new { format = "0.00", value = x.Value.ToString(CultureInfo.InvariantCulture) })); + + body.Add(bodyItem); + } + + var head = new List(); + + foreach (var key in res.First().Value.Keys) + { + head.Add(new { format = "MMM-yy", value = key.ToString(ShortDateFormat, CultureInfo.InvariantCulture) }); + } + + return new + { + resource = new + { + manager = CRMReportResource.Manager, + summary = CRMReportResource.Sum, + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesByManagersReport, + header = CRMReportResource.SalesByManagersReport, + header1 = CRMReportResource.SalesByMonth + ", " + _defaultCurrency.Symbol, + header2 = CRMReportResource.TotalSalesByManagers + ", " + _defaultCurrency.Symbol, + chartName1 = CRMReportResource.SalesByMonth + ", " + _defaultCurrency.Symbol, + chartName2 = CRMReportResource.TotalSalesByManagers + ", " + _defaultCurrency.Symbol + }, + thead = head, + tbody = body + }; } - public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) - { - var reportData = BuildWorkloadByTasksReport(timePeriod, managers); + #endregion + + + #region SalesForecastReport - if (reportData == null || !reportData.Any()) return null; + public bool CheckSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; - var hasData = reportData.Any(item => item.Value.Count > 0); + GetTimePeriod(timePeriod, out fromDate, out toDate); - return hasData ? GenerateReportData(timePeriod, reportData) : null; + return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => x.y.Status == DealMilestoneStatus.Open) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); } - private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) + public object GetSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) { - throw new NotImplementedException(); + var reportData = BuildSalesForecastReport(timePeriod, managers, defaultCurrency); - //DateTime fromDate; - //DateTime toDate; + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } - //GetTimePeriod(timePeriod, out fromDate, out toDate); + private List BuildSalesForecastReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; - //var sqlNewTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); + GetTimePeriod(timePeriod, out fromDate, out toDate); - //var sqlClosedTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Eq("t.is_closed", 1)) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); - - //var sqlOverdueTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); + throw new NotImplementedException(); - //Dictionary> res; + //string dateSelector; - //using (var tx = Db.BeginTransaction()) + //switch (timePeriod) //{ - // res = new Dictionary> - // { - // {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, - // {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, - // {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} - // }; - - // tx.Commit(); + // case ReportTimePeriod.CurrentWeek: + // case ReportTimePeriod.NextWeek: + // case ReportTimePeriod.CurrentMonth: + // case ReportTimePeriod.NextMonth: + // dateSelector = "d.expected_close_date as close_date"; + // break; + // case ReportTimePeriod.CurrentQuarter: + // case ReportTimePeriod.NextQuarter: + // case ReportTimePeriod.CurrentYear: + // case ReportTimePeriod.NextYear: + // dateSelector = "date_sub(date(d.expected_close_date), interval (extract(day from d.expected_close_date) - 1) day) as close_date"; + // break; + // default: + // return null; //} - //return res; + //var sqlQuery = Query("crm_deal d") + // .Select(string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as value", defaultCurrency), + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 + // end) as value_with_probability", defaultCurrency), + // dateSelector) + // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Between("d.expected_close_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("close_date"); + + //return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesForecast); } - private WorkloadByTasks ToWorkloadByTasks(object[] row) + private SalesForecast ToSalesForecast(object[] row) { - return new WorkloadByTasks + return new SalesForecast { - CategoryId = Convert.ToInt32(row[0]), - CategoryName = Convert.ToString(row[1]), - UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), - UserName = Convert.ToString(row[3]), - Count = Convert.ToInt32(row[4]) + Value = Convert.ToDecimal(row[0]), + ValueWithProbability = Convert.ToDecimal(row[1]), + Date = Convert.ToDateTime(row[2]) == DateTime.MinValue ? DateTime.MinValue : _tenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[2])) }; } - private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) + private object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + switch (timePeriod) + { + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.NextWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.NextMonth: + return GenerateReportDataByDays(timePeriod, data); + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.NextQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.NextYear: + return GenerateReportByMonths(timePeriod, data); + default: + return null; + } + } + + private object GenerateReportDataByDays(ReportTimePeriod timePeriod, List data) { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var res = new Dictionary>(); + + var date = fromDate; + + while (date < toDate) + { + res.Add(date, new Tuple(0, 0)); + date = date.AddDays(1); + } + + foreach (var item in data) + { + var key = new DateTime(item.Date.Year, item.Date.Month, item.Date.Day); + + if (key < res.First().Key) + key = res.First().Key; + + if (key > res.Last().Key) + key = res.Last().Key; + + res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, + res[key].Item2 + item.Value); + } + + var body = new List>(); + var separator = CultureInfo.CurrentCulture.DateTimeFormat.DateSeparator.ToCharArray(); + var pattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern.Replace("yyyy", string.Empty).Trim(separator); + + foreach (var resItem in res) + { + var bodyItem = new List + { + new {format = pattern, value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} + }; + + body.Add(bodyItem); + } + + var head = new List + { + CRMReportResource.Day, + CRMReportResource.WithRespectToProbability, + CRMReportResource.IfAllOpportunitiesWon + }; + return new { resource = new { - header = CRMReportResource.WorkloadByTasksReport, - sheetName = CRMReportResource.WorkloadByTasksReport, + total = CRMReportResource.Total, dateRangeLabel = CRMReportResource.TimePeriod + ":", dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesForecastReport, + header = CRMReportResource.SalesForecastReport, + header1 = CRMReportResource.SalesForecastReport + ", " + _defaultCurrency.Symbol, + chartName = CRMReportResource.SalesForecastReport + ", " + _defaultCurrency.Symbol + }, + thead = head, + tbody = body + }; + } - header1 = CRMReportResource.ClosedTasks, - header2 = CRMReportResource.NewTasks, - header3 = CRMReportResource.OverdueTasks, + private object GenerateReportByMonths(ReportTimePeriod timePeriod, List data) + { + DateTime fromDate; + DateTime toDate; - manager = CRMReportResource.Manager, - total = CRMReportResource.Total + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var res = new Dictionary>(); + + var date = fromDate; + + while (date < toDate) + { + res.Add(date, new Tuple(0, 0)); + date = date.AddMonths(1); + } + + foreach (var item in data) + { + var key = new DateTime(item.Date.Year, item.Date.Month, 1); + + if (key < res.First().Key) + key = res.First().Key; + + if (key > res.Last().Key) + key = res.Last().Key; + + res[key] = new Tuple(res[key].Item1 + item.ValueWithProbability, + res[key].Item2 + item.Value); + } + + var body = new List>(); + + foreach (var resItem in res) + { + var bodyItem = new List + { + new {format = "MMM-yy", value = resItem.Key.ToString(ShortDateFormat, CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item1.ToString(CultureInfo.InvariantCulture)}, + new {format = "0.00", value = resItem.Value.Item2.ToString(CultureInfo.InvariantCulture)} + }; + + body.Add(bodyItem); + } + + var head = new List + { + CRMReportResource.Month, + CRMReportResource.WithRespectToProbability, + CRMReportResource.IfAllOpportunitiesWon + }; + + return new + { + resource = new + { + total = CRMReportResource.Total, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + sheetName = CRMReportResource.SalesForecastReport, + header = CRMReportResource.SalesForecastReport, + header1 = CRMReportResource.SalesForecastReport + ", " + _defaultCurrency.Symbol, + chartName = CRMReportResource.SalesForecastReport + ", " + _defaultCurrency.Symbol }, - data = reportData + thead = head, + tbody = body }; } #endregion - //#region WorkloadByDealsReport + #region SalesFunnelReport - //public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; + public bool CheckSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; - // GetTimePeriod(timePeriod, out fromDate, out toDate); + GetTimePeriod(timePeriod, out fromDate, out toDate); - // return Query(CRMDbContext.Deals) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) || - // (x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate))) - // .Any(); - //} + return Query(CRMDbContext.Deals) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + } - //public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + //public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) //{ - // var reportData = BuildWorkloadByDealsReport(timePeriod, managers, defaultCurrency); + // var reportData = BuildSalesFunnelReport(timePeriod, managers, defaultCurrency); // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); //} - //private List BuildWorkloadByDealsReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query("crm_deal d") - // .Select("d.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "m.status", - // "count(d.id) as deals_count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - // Exp.Empty : - // Exp.Or(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), - // Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) - // .GroupBy("d.responsible_id", "m.status"); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByDeals); - //} + // private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query("crm_deal_milestone m") + // .Select("m.status", "m.title", + // "count(d.id) as deals_count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency), + // "avg(if(m.status = 1, datediff(d.actual_close_date, d.create_on), 0)) as deals_duration") + // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & + // Exp.EqColumns("d.deal_milestone_id", "m.id") & + // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & + // Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "m.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .GroupBy("m.id") + // .OrderBy("m.sort_order", true); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesFunnel); + // } + + // private SalesFunnel ToSalesFunnel(object[] row) + // { + // return new SalesFunnel + // { + // Status = (DealMilestoneStatus)Convert.ToInt32(row[0]), + // Title = Convert.ToString(row[1]), + // Count = Convert.ToInt32(row[2]), + // Value = Convert.ToDecimal(row[3]), + // Duration = Convert.ToInt32(row[4]) + // }; + // } + + // private object GenerateReportData(ReportTimePeriod timePeriod, List data) + // { + // var totalCount = data.Sum(x => x.Count); + + // if (totalCount == 0) return null; + + // var totalBudget = data.Sum(x => x.Value); + + // var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); + + // var reportData = data.Select(item => new List + // { + // item.Title, + // item.Status, + // item.Count, + // item.Value + // }).ToList(); + + // return new + // { + // resource = new + // { + // header = CRMReportResource.SalesFunnelReport, + // sheetName = CRMReportResource.SalesFunnelReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // chartName = CRMReportResource.SalesFunnelByCount, + // chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + _defaultCurrency.Symbol, + // chartName2 = CRMReportResource.DealsCount, + // chartName3 = CRMReportResource.DealsBudget + ", " + _defaultCurrency.Symbol, + + // totalCountLabel = CRMReportResource.TotalDealsCount, + // totalCountValue = totalCount, + + // totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + _defaultCurrency.Symbol, + // totalBudgetValue = totalBudget, + + // averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + _defaultCurrency.Symbol, + // averageBidValue = totalBudget / totalCount, + + // averageDurationLabel = CRMReportResource.AverageDealsDuration, + // averageDurationValue = closed.Sum(x => x.Duration) / closed.Count, + + // header1 = CRMReportResource.ByCount, + // header2 = CRMReportResource.ByBudget + ", " + _defaultCurrency.Symbol, + + // stage = CRMReportResource.Stage, + // count = CRMReportResource.Count, + // budget = CRMReportResource.Budget, + // conversion = CRMReportResource.Conversion, + + // deals = CRMDealResource.Deals, + // status0 = DealMilestoneStatus.Open.ToLocalizedString(), + // status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), + // status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() + // }, + // data = reportData + // }; + // } + + // #endregion + + + // #region WorkloadByContactsReport + + // public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Contacts) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + // .Any(); + // } + + // public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // var reportData = BuildWorkloadByContactsReport(timePeriod, managers); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + // } + + // private List BuildWorkloadByContactsReport(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query(CRMDbContext.Contacts) + // .GroupJoin(Query(CRMDbContext.ListItem), + // x => x.ContactTypeId, + // y => y.Id, + // (x, y) => new { x, y }) + // .GroupJoin(Query(CRMDbContext.Deals), + // x => x.x.Id, + // y => y.Id, + // (x, y) => new { x, y }) + + + + // var sqlQuery = Query("crm_contact c") + // .Select("c.create_by", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "i.id", + // "i.title", + // "count(c.id) as total", + // "count(d.id) as `with deals`") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & Exp.Eq("i.list_type", (int)ListType.ContactType)) + // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "c.tenant_id") & Exp.EqColumns("d.contact_id", "c.id")) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.create_by")) + // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("c.create_by", "i.id") + // .OrderBy("i.sort_order, i.title", true); + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByContacts); + // } + + // private WorkloadByContacts ToWorkloadByContacts(object[] row) + // { + // return new WorkloadByContacts + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1]), + // CategoryId = Convert.ToInt32(row[2]), + // CategoryName = Convert.ToString(row[3]), + // Count = Convert.ToInt32(row[4]), + // WithDeals = Convert.ToInt32(row[5]) + // }; + // } + + // private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + // { + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByContactsReport, + // sheetName = CRMReportResource.WorkloadByContactsReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // header1 = CRMReportResource.NewContacts, + // header2 = CRMReportResource.NewContactsWithAndWithoutDeals, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total, + + // noSet = CRMCommonResource.NoSet, + // withDeals = CRMReportResource.ContactsWithDeals, + // withouthDeals = CRMReportResource.ContactsWithoutDeals, + // }, + // data = reportData + // }; + // } + + // #endregion + + + // #region WorkloadByTasksReport + + // public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + // var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => x.IsClosed) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) + // .Any(); + + + + // var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => x.IsClosed) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) + // .Where(x => (!x.IsClosed && x.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + // (x.IsClosed && x.LastModifedOn > x.Deadline)) + // .Any(); + + // return sqlNewTasksQuery || + // sqlClosedTasksQuery || + // sqlOverdueTasksQuery; + // } + + // public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // var reportData = BuildWorkloadByTasksReport(timePeriod, managers); + + // if (reportData == null || !reportData.Any()) return null; + + // var hasData = reportData.Any(item => item.Value.Count > 0); + + // return hasData ? GenerateReportData(timePeriod, reportData) : null; + // } + + // private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + // .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), + // x => x.CategoryId, + // y => y.Id, + // (x, y) => new { Task = x, ListItem = y }) + // .Join(_userDbContext.Users.DefaultIfEmpty(), + // x => x.Task.ResponsibleId, + // y => y.Id, + // (x, y) => new { Task = x.Task, ListItem = x.ListItem, User = y } + // ) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + // .OrderBy(x => x.ListItem.SortOrder) + // .Select(x => new + // { + // x.ListItem.Id, + // x.ListItem.Title, + // x.Task.ResponsibleId, + // x.User + // }); + + // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + // .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), + // x => x.CategoryId, + // y => y.Id, + // (x, y) => new { Task = x, ListItem = y }) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + // .OrderBy(x => x.ListItem.SortOrder) + // .GroupBy(x => new { x.ListItem.Id, x.ListItem.Title, x.Task.ResponsibleId }) + // .Select(x => new + // { + // Id = x.Key.Id, + // Title = x.Key.Title, + // ResponsibleId = x.Key.ResponsibleId, + // Count = x.Count() + // }); + + // throw new NotImplementedException(); + + + // var sqlNewTasksQuery = Query("crm_task t") + //.Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + //.LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + //.LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + //.Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + //.Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + //.GroupBy("i.id", "t.responsible_id") + //.OrderBy("i.sort_order", true); + + // var sqlClosedTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(Exp.Eq("t.is_closed", 1)) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + // var sqlOverdueTasksQuery = Query("crm_task t") + // .Select("i.id", + // "i.title", + // "t.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "count(t.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) + // .GroupBy("i.id", "t.responsible_id") + // .OrderBy("i.sort_order", true); + + // Dictionary> res; + + // using (var tx = Db.BeginTransaction()) + // { + // res = new Dictionary> + // { + // {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, + // {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, + // {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} + // }; + + // tx.Commit(); + // } + + // return res; + // } + + // private WorkloadByTasks ToWorkloadByTasks(object[] row) + // { + // return new WorkloadByTasks + // { + // CategoryId = Convert.ToInt32(row[0]), + // CategoryName = Convert.ToString(row[1]), + // UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), + // UserName = Convert.ToString(row[3]), + // Count = Convert.ToInt32(row[4]) + // }; + // } + + // private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) + // { + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByTasksReport, + // sheetName = CRMReportResource.WorkloadByTasksReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // header1 = CRMReportResource.ClosedTasks, + // header2 = CRMReportResource.NewTasks, + // header3 = CRMReportResource.OverdueTasks, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total + // }, + // data = reportData + // }; + // } + + // #endregion + + + // #region WorkloadByDealsReport + + // public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Deals) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) || + // (x.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate))) + // .Any(); + // } + + // public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + // { + // var reportData = BuildWorkloadByDealsReport(timePeriod, managers, defaultCurrency); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + // } + + // private List BuildWorkloadByDealsReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query("crm_deal d") + // .Select("d.responsible_id", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "m.status", + // "count(d.id) as deals_count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + // Exp.Empty : + // Exp.Or(Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate)), + // Exp.Between("d.actual_close_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate)))) + // .GroupBy("d.responsible_id", "m.status"); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByDeals); + // } + + // private WorkloadByDeals ToWorkloadByDeals(object[] row) + // { + // return new WorkloadByDeals + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1]), + // Status = (DealMilestoneStatus)Convert.ToInt32(row[2]), + // Count = Convert.ToInt32(row[3]), + // Value = Convert.ToDecimal(row[4]) + // }; + // } + + // private object GenerateReportData(ReportTimePeriod timePeriod, List data) + // { + // var reportData = data.Select(item => new List + // { + // item.UserId, + // item.UserName, + // (int)item.Status, + // item.Count, + // item.Value + // }).ToList(); + + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByDealsReport, + // sheetName = CRMReportResource.WorkloadByDealsReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // chartName = CRMReportResource.DealsCount, + // chartName1 = CRMReportResource.DealsBudget + ", " + _defaultCurrency.Symbol, + + // header1 = CRMReportResource.ByCount, + // header2 = CRMReportResource.ByBudget + ", " + _defaultCurrency.Symbol, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total, + + // status0 = CRMReportResource.New, + // status1 = CRMReportResource.Won, + // status2 = CRMReportResource.Lost + // }, + // data = reportData + // }; + // } + + // #endregion + + + // #region WorkloadByInvoicesReport + + // public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.Invoices) + // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + // .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= _tenantUtil.DateTimeToUtc(toDate))) || + // (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate))) || + // (x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate))) || + // ((timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= _tenantUtil.DateTimeToUtc(toDate))) && + // (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()) || x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) + // .Any(); + // } + + // public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // var reportData = BuildWorkloadByInvoicesReport(timePeriod, managers); + + // if (reportData == null || !reportData.Any()) return null; + + // var hasData = reportData.Any(item => item.SentCount > 0 || item.PaidCount > 0 || item.RejectedCount > 0 || item.OverdueCount > 0); + + // return hasData ? GenerateReportData(timePeriod, reportData) : null; + // } + + // private List BuildWorkloadByInvoicesReport(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // throw new NotImplementedException(); + + // var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.issue_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))), 1, 0)); + // var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))), 1, 0)); + // var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))), 1, 0)); + // var overdue = Exp.Sum(Exp.If((timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.due_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) & Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); + + // var sqlQuery = Query("crm_invoice i") + // .Select("i.create_by", "concat(u.firstname, ' ', u.lastname) as full_name") + // .Select(sent) + // .Select(paid) + // .Select(rejected) + // .Select(overdue) + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "i.tenant_id") & Exp.EqColumns("u.id", "i.create_by")) + // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + // .GroupBy("i.create_by"); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByInvoices); + // } + + // private WorkloadByInvoices ToWorkloadByInvoices(object[] row) + // { + // return new WorkloadByInvoices + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1]), + // SentCount = Convert.ToInt32(row[2]), + // PaidCount = Convert.ToInt32(row[3]), + // RejectedCount = Convert.ToInt32(row[4]), + // OverdueCount = Convert.ToInt32(row[5]) + // }; + // } + + // private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + // { + // return new + // { + // resource = new + // { + // header = CRMReportResource.WorkloadByInvoicesReport, + // sheetName = CRMReportResource.WorkloadByInvoicesReport, + // dateRangeLabel = CRMReportResource.TimePeriod + ":", + // dateRangeValue = GetTimePeriodText(timePeriod), + + // chartName = CRMReportResource.BilledInvoices, + // chartName1 = CRMInvoiceResource.Invoices, + + // header1 = CRMInvoiceResource.Invoices, + + // manager = CRMReportResource.Manager, + // total = CRMReportResource.Total, + + // billed = CRMReportResource.Billed, + // paid = CRMReportResource.Paid, + // rejected = CRMReportResource.Rejected, + // overdue = CRMReportResource.Overdue + // }, + // data = reportData + // }; + // } + + // #endregion + + + // #region GetWorkloadByViopReport + + // public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // return Query(CRMDbContext.VoipCalls) + // .Where(x => x.ParentCallId == "") + // .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) + // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? + // true : + // x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) + // .Any(); + // } + + // public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + // { + // var reportData = BuildWorkloadByViopReport(timePeriod, managers); + + // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + // } + + // private List BuildWorkloadByViopReport(ReportTimePeriod timePeriod, Guid[] managers) + // { + // DateTime fromDate; + // DateTime toDate; + + // GetTimePeriod(timePeriod, out fromDate, out toDate); + + // var sqlQuery = Query("crm_voip_calls c") + // .Select("c.answered_by", + // "concat(u.firstname, ' ', u.lastname) as full_name", + // "c.status", + // "count(c.id) as calls_count", + // "sum(c.dial_duration) as duration") + // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.answered_by")) + // .Where(Exp.EqColumns("c.parent_call_id", "''")) + // .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? + // Exp.Empty : + // Exp.Between("c.dial_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("c.answered_by", "c.status"); + + + // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByViop); + // } + + // private WorkloadByViop ToWorkloadByViop(object[] row) + // { + // return new WorkloadByViop + // { + // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + // UserName = Convert.ToString(row[1] ?? string.Empty), + // Status = (VoipCallStatus)Convert.ToInt32(row[2] ?? 0), + // Count = Convert.ToInt32(row[3]), + // Duration = Convert.ToInt32(row[4]) + // }; + // } + + private object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + var reportData = data.Select(item => new List + { + item.UserId, + item.UserName, + (int) item.Status, + item.Count, + new {format = TimeFormat, value = SecondsToTimeFormat(item.Duration)} + }).ToList(); - //private WorkloadByDeals ToWorkloadByDeals(object[] row) - //{ - // return new WorkloadByDeals - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1]), - // Status = (DealMilestoneStatus)Convert.ToInt32(row[2]), - // Count = Convert.ToInt32(row[3]), - // Value = Convert.ToDecimal(row[4]) - // }; - //} + return new + { + resource = new + { + header = CRMReportResource.WorkloadByVoipReport, + sheetName = CRMReportResource.WorkloadByVoipReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), - //private object GenerateReportData(ReportTimePeriod timePeriod, List data) - //{ - // var reportData = data.Select(item => new List - // { - // item.UserId, - // item.UserName, - // (int)item.Status, - // item.Count, - // item.Value - // }).ToList(); - - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByDealsReport, - // sheetName = CRMReportResource.WorkloadByDealsReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // chartName = CRMReportResource.DealsCount, - // chartName1 = CRMReportResource.DealsBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - // header1 = CRMReportResource.ByCount, - // header2 = CRMReportResource.ByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total, - - // status0 = CRMReportResource.New, - // status1 = CRMReportResource.Won, - // status2 = CRMReportResource.Lost - // }, - // data = reportData - // }; - //} + chartName = CRMReportResource.CallsCount, + chartName1 = CRMReportResource.CallsDuration, - //#endregion + header1 = CRMReportResource.CallsCount, + header2 = CRMReportResource.CallsDuration, + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, - //#region WorkloadByInvoicesReport + incoming = CRMReportResource.Incoming, + outcoming = CRMReportResource.Outcoming, - //public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // return Query(CRMDbContext.Invoices) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= TenantUtil.DateTimeToUtc(toDate))) || - // (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || - // (x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= TenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= TenantUtil.DateTimeToUtc(toDate))) || - // ((timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= TenantUtil.DateTimeToUtc(toDate))) && - // (x.Status == InvoiceStatus.Sent && x.DueDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()) || x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) - // .Any(); - //} + timeFormat = TimeFormat + }, + data = reportData + }; + } - //public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // var reportData = BuildWorkloadByInvoicesReport(timePeriod, managers); + private string SecondsToTimeFormat(int duration) + { + var timeSpan = TimeSpan.FromSeconds(duration); - // if (reportData == null || !reportData.Any()) return null; + return string.Format("{0}:{1}:{2}", + ((timeSpan.TotalHours < 10 ? "0" : "") + (int)timeSpan.TotalHours), + ((timeSpan.Minutes < 10 ? "0" : "") + timeSpan.Minutes), + ((timeSpan.Seconds < 10 ? "0" : "") + timeSpan.Seconds)); + } - // var hasData = reportData.Any(item => item.SentCount > 0 || item.PaidCount > 0 || item.RejectedCount > 0 || item.OverdueCount > 0); + #endregion - // return hasData ? GenerateReportData(timePeriod, reportData) : null; - //} - //private List BuildWorkloadByInvoicesReport(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; + #region SummaryForThePeriodReport - // GetTimePeriod(timePeriod, out fromDate, out toDate); + public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; - // var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.issue_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); - // var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); - // var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))), 1, 0)); - // var overdue = Exp.Sum(Exp.If((timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.due_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) & Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); + GetTimePeriod(timePeriod, out fromDate, out toDate); - // var sqlQuery = Query("crm_invoice i") - // .Select("i.create_by", "concat(u.firstname, ' ', u.lastname) as full_name") - // .Select(sent) - // .Select(paid) - // .Select(rejected) - // .Select(overdue) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "i.tenant_id") & Exp.EqColumns("u.id", "i.create_by")) - // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - // .GroupBy("i.create_by"); + var newDealsSqlQuery = Query(CRMDbContext.Deals) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + var closedDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.DealMilestones), + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.y.Status != DealMilestoneStatus.Open) + .Any(); + + var overdueDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.DealMilestones), + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => x.x.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => (x.y.Status == DealMilestoneStatus.Open && x.x.ExpectedCloseDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + (x.y.Status == DealMilestoneStatus.ClosedAndWon && x.x.ActualCloseDate > x.x.ExpectedCloseDate)) + .Any(); + + var invoicesSqlQuery = Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + + var contactsSqlQuery = Query(CRMDbContext.Contacts) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + + + var tasksSqlQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + + + var voipSqlQuery = Query(CRMDbContext.VoipCalls) + .Where(x => x.ParentCallId == "") + .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) + .Where(x => x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + + return newDealsSqlQuery || + closedDealsSqlQuery || + overdueDealsSqlQuery || + invoicesSqlQuery || + contactsSqlQuery || + tasksSqlQuery || + voipSqlQuery; + } - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByInvoices); - //} + public object GetSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSummaryForThePeriodReport(timePeriod, managers, defaultCurrency); - //private WorkloadByInvoices ToWorkloadByInvoices(object[] row) - //{ - // return new WorkloadByInvoices - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1]), - // SentCount = Convert.ToInt32(row[2]), - // PaidCount = Convert.ToInt32(row[3]), - // RejectedCount = Convert.ToInt32(row[4]), - // OverdueCount = Convert.ToInt32(row[5]) - // }; - //} + if (reportData == null) return null; - //private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) - //{ - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByInvoicesReport, - // sheetName = CRMReportResource.WorkloadByInvoicesReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // chartName = CRMReportResource.BilledInvoices, - // chartName1 = CRMInvoiceResource.Invoices, - - // header1 = CRMInvoiceResource.Invoices, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total, - - // billed = CRMReportResource.Billed, - // paid = CRMReportResource.Paid, - // rejected = CRMReportResource.Rejected, - // overdue = CRMReportResource.Overdue - // }, - // data = reportData - // }; - //} + return GenerateSummaryForThePeriodReportData(timePeriod, reportData); + } - //#endregion + private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + GetTimePeriod(timePeriod, out fromDate, out toDate); - //#region GetWorkloadByViopReport + var newDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { Deal = x, CurrencyRate = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); + + var wonDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { Deal = x, CurrencyRate = y }) + .Join(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { Deal = x.Deal, CurrencyRate = x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); + + var lostDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { Deal = x, CurrencyRate = y }) + .Join(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { Deal = x.Deal, CurrencyRate = x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndLost) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); + + + var overdueDealsSqlQuery = Query(CRMDbContext.Deals) + .Join(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { Deal = x, CurrencyRate = y }) + .Join(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { Deal = x.Deal, CurrencyRate = x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ExpectedCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + + .Where(x => (x.DealMilestone.Status == DealMilestoneStatus.Open && x.Deal.ExpectedCloseDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + (x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon && x.Deal.ActualCloseDate > x.Deal.ExpectedCloseDate)) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); + + var invoicesSqlQuery = Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => x.Status) + .Select(x => new { + sent = x.Sum(x => x.Status != InvoiceStatus.Draft ? 1 :0), + paid = x.Sum(x => x.Status == InvoiceStatus.Paid ? 1 : 0), + rejected = x.Sum(x => x.Status == InvoiceStatus.Rejected ? 1 : 0), + overdue = x.Sum(x => (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + (x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate) + ? 1 : 0) + }).ToList(); + + var contactsSqlQuery = Query(CRMDbContext.Contacts) + .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), + x => x.ContactTypeId, + y => y.Id, + (x, y) => new { Contact = x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.ContactType) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Contact.CreateBy) : true) + .Where(x => x.Contact.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Contact.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => new { x.ListItem.Title }) + .Select(x => new + { + title = x.Key.Title, + count = x.Count() + }) + .OrderBy(x => x.title) + .ToList(); + + + + + + var tasksSqlQuery = Query(CRMDbContext.Tasks) + .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), + x => x.CategoryId, + y => y.Id, + (x,y) => new { Task = x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.TaskCategory) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) + .Where(x => x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => new { x.ListItem.Title }) + .Select(x => new + { + + title = x.Key.Title, + sum1 = x.Sum(x => x.Task.IsClosed && x.Task.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate) ? 1 : 0), + sum2 = x.Sum(x => (!x.Task.IsClosed && x.Task.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || (x.Task.IsClosed && x.Task.LastModifedOn > x.Task.Deadline) ? 1 :0), + count = x.Count() + }) + .OrderBy(x => x.title) + .ToList(); +// .OrderBy("i.sort_order, i.title", true); + + + + + var voipSqlQuery = Query(CRMDbContext.VoipCalls) + .Where(x => String.IsNullOrEmpty(x.ParentCallId)) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) + .Where(x => x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => x.Status) + .Select(x => new { + status = x.Key, + calls_count = x.Count(), + duration = x.Sum(x => x.DialDuration) + }) + .ToList(); + + object res; + + using (var tx = CRMDbContext.Database.BeginTransaction()) + { + res = new + { + DealsInfo = new + { + Created = newDealsSqlQuery, + Won = wonDealsSqlQuery, + Lost = lostDealsSqlQuery, + Overdue = overdueDealsSqlQuery + }, + InvoicesInfo = invoicesSqlQuery, + ContactsInfo = contactsSqlQuery, + TasksInfo = tasksSqlQuery, + VoipInfo = voipSqlQuery + }; + + tx.Commit(); + } - //public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // return Query(CRMDbContext.VoipCalls) - // .Where(x => x.ParentCallId == "") - // .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? - // true : - // x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - //} + return res; + } - //public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // var reportData = BuildWorkloadByViopReport(timePeriod, managers); + private object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) + { + return new + { + resource = new + { + header = CRMReportResource.SummaryForThePeriodReport, + sheetName = CRMReportResource.SummaryForThePeriodReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + chartName = CRMReportResource.DealsByBudget + ", " + _defaultCurrency.Symbol, + chartName1 = CRMReportResource.DealsByCount, + chartName2 = CRMReportResource.ContactsByType, + chartName3 = CRMReportResource.TasksForThePeriod, + chartName4 = CRMReportResource.InvoicesForThePeriod, + chartName5 = CRMReportResource.CallsForThePeriod, + header1 = CRMDealResource.Deals, + header2 = CRMContactResource.Contacts, + header3 = CRMTaskResource.Tasks, + header4 = CRMInvoiceResource.Invoices, + header5 = CRMReportResource.Calls, + byBudget = CRMReportResource.ByBudget, + currency = _defaultCurrency.Symbol, + byCount = CRMReportResource.ByCount, + item = CRMReportResource.Item, + type = CRMReportResource.Type, + won = CRMReportResource.Won, + lost = CRMReportResource.Lost, + created = CRMReportResource.Created, + closed = CRMReportResource.Closed, + overdue = CRMReportResource.Overdue, + notSpecified = CRMCommonResource.NoSet, + total = CRMReportResource.Total, + status = CRMReportResource.Status, + billed = CRMReportResource.Billed, + paid = CRMReportResource.Paid, + rejected = CRMReportResource.Rejected, + count = CRMReportResource.Count, + duration = CRMReportResource.Duration, + incoming = CRMReportResource.Incoming, + outcoming = CRMReportResource.Outcoming, + missed = CRMReportResource.MissedCount, + timeFormat = TimeFormat + }, + data = reportData + }; + } - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - //} + #endregion - //private List BuildWorkloadByViopReport(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query("crm_voip_calls c") - // .Select("c.answered_by", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "c.status", - // "count(c.id) as calls_count", - // "sum(c.dial_duration) as duration") - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.answered_by")) - // .Where(Exp.EqColumns("c.parent_call_id", "''")) - // .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - // Exp.Empty : - // Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("c.answered_by", "c.status"); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByViop); - //} - //private WorkloadByViop ToWorkloadByViop(object[] row) - //{ - // return new WorkloadByViop - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1] ?? string.Empty), - // Status = (VoipCallStatus)Convert.ToInt32(row[2] ?? 0), - // Count = Convert.ToInt32(row[3]), - // Duration = Convert.ToInt32(row[4]) - // }; - //} + #region SummaryAtThisMomentReport - //private object GenerateReportData(ReportTimePeriod timePeriod, List data) - //{ - // var reportData = data.Select(item => new List - // { - // item.UserId, - // item.UserName, - // (int) item.Status, - // item.Count, - // new {format = TimeFormat, value = SecondsToTimeFormat(item.Duration)} - // }).ToList(); - - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByVoipReport, - // sheetName = CRMReportResource.WorkloadByVoipReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // chartName = CRMReportResource.CallsCount, - // chartName1 = CRMReportResource.CallsDuration, - - // header1 = CRMReportResource.CallsCount, - // header2 = CRMReportResource.CallsDuration, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total, - - // incoming = CRMReportResource.Incoming, - // outcoming = CRMReportResource.Outcoming, - - // timeFormat = TimeFormat - // }, - // data = reportData - // }; - //} + public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; - //private string SecondsToTimeFormat(int duration) - //{ - // var timeSpan = TimeSpan.FromSeconds(duration); + GetTimePeriod(timePeriod, out fromDate, out toDate); - // return string.Format("{0}:{1}:{2}", - // ((timeSpan.TotalHours < 10 ? "0" : "") + (int)timeSpan.TotalHours), - // ((timeSpan.Minutes < 10 ? "0" : "") + timeSpan.Minutes), - // ((timeSpan.Seconds < 10 ? "0" : "") + timeSpan.Seconds)); - //} + var dealsSqlQuery = Query(CRMDbContext.Deals) + .Join(CRMDbContext.DealMilestones, + x => x.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.y.Status == DealMilestoneStatus.Open) + .Any(); - //#endregion + var contactsSqlQuery = Query(CRMDbContext.Contacts) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); - //#region SummaryForThePeriodReport + var tasksSqlQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); - //public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var newDealsSqlQuery = Query(CRMDbContext.Deals) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // var closedDealsSqlQuery = Query(CRMDbContext.Deals) - // .Join(Query(CRMDbContext.DealMilestones), - // x => x.DealMilestoneId, - // y => y.Id, - // (x, y) => new { x, y }) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - // .Where(x => x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - // .Where(x => x.y.Status != DealMilestoneStatus.Open) - // .Any(); - - // var overdueDealsSqlQuery = Query(CRMDbContext.Deals) - // .Join(Query(CRMDbContext.DealMilestones), - // x => x.DealMilestoneId, - // y => y.Id, - // (x, y) => new { x, y }) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - // .Where(x => x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= TenantUtil.DateTimeToUtc(toDate)) - // .Where(x => (x.y.Status == DealMilestoneStatus.Open && x.x.ExpectedCloseDate < TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())) || - // (x.y.Status == DealMilestoneStatus.ClosedAndWon && x.x.ActualCloseDate > x.x.ExpectedCloseDate)) - // .Any(); - - // var invoicesSqlQuery = Query(CRMDbContext.Invoices) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // var contactsSqlQuery = Query(CRMDbContext.Contacts) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - - // var tasksSqlQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - - // var voipSqlQuery = Query(CRMDbContext.VoipCalls) - // .Where(x => x.ParentCallId == "") - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) - // .Where(x => x.DialDate >= TenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // return newDealsSqlQuery || - // closedDealsSqlQuery || - // overdueDealsSqlQuery || - // invoicesSqlQuery || - // contactsSqlQuery || - // tasksSqlQuery || - // voipSqlQuery; - //} + var invoicesSqlQuery = Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); - //public object GetSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // var reportData = BuildSummaryForThePeriodReport(timePeriod, managers, defaultCurrency); + return dealsSqlQuery || + contactsSqlQuery || + tasksSqlQuery || + invoicesSqlQuery; - // if (reportData == null) return null; + } - // return GenerateSummaryForThePeriodReportData(timePeriod, reportData); - //} + public object GetSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSummaryAtThisMomentReport(timePeriod, managers, defaultCurrency); - //private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var newDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - - // var wonDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon); - - // var lostDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("d.actual_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.ClosedAndLost); - - // var overdueDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where( - // Exp.And( - // Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), - // Exp.Or(Exp.Eq("m.status", (int)DealMilestoneStatus.Open) & Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), - // Exp.Eq("m.status", (int)DealMilestoneStatus.ClosedAndWon) & Exp.Sql("d.actual_close_date > d.expected_close_date")))); - - // var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft), 1, 0)); - // var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid), 1, 0)); - // var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected), 1, 0)); - // var overdue = Exp.Sum(Exp.If(Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), - // Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); - - // var invoicesSqlQuery = Query("crm_invoice i") - // .Select(sent) - // .Select(paid) - // .Select(rejected) - // .Select(overdue) - // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - // .Where(Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - - - // var contactsSqlQuery = Query("crm_contact c") - // .Select("i.title", - // "count(c.id)") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - // Exp.EqColumns("i.id", "c.contact_type_id") & - // Exp.Eq("i.list_type", (int)ListType.ContactType)) - // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - // .Where(Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - // var tasksSqlQuery = Query("crm_task t") - // .Select("i.title") - // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 1) & Exp.Between("t.last_modifed_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)), 1, 0))) - // .Select(Exp.Sum(Exp.If(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")), 1, 0))) - // .Select("count(t.id)") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - // var voipSqlQuery = Query("crm_voip_calls c") - // .Select("c.status", - // "count(c.id) as calls_count", - // "sum(c.dial_duration) as duration") - // .Where(Exp.EqColumns("c.parent_call_id", "''")) - // .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) - // .Where(Exp.Between("c.dial_date", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("c.status"); - - // object res; - - // using (var tx = Db.BeginTransaction()) - // { - // res = new - // { - // DealsInfo = new - // { - // Created = Db.ExecuteList(newDealsSqlQuery), - // Won = Db.ExecuteList(wonDealsSqlQuery), - // Lost = Db.ExecuteList(lostDealsSqlQuery), - // Overdue = Db.ExecuteList(overdueDealsSqlQuery), - // }, - // InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), - // ContactsInfo = Db.ExecuteList(contactsSqlQuery), - // TasksInfo = Db.ExecuteList(tasksSqlQuery), - // VoipInfo = Db.ExecuteList(voipSqlQuery) - // }; - - // tx.Commit(); - // } - - // return res; - //} + if (reportData == null) return null; - //private object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) - //{ - // return new - // { - // resource = new - // { - // header = CRMReportResource.SummaryForThePeriodReport, - // sheetName = CRMReportResource.SummaryForThePeriodReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - // chartName = CRMReportResource.DealsByBudget + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName1 = CRMReportResource.DealsByCount, - // chartName2 = CRMReportResource.ContactsByType, - // chartName3 = CRMReportResource.TasksForThePeriod, - // chartName4 = CRMReportResource.InvoicesForThePeriod, - // chartName5 = CRMReportResource.CallsForThePeriod, - // header1 = CRMDealResource.Deals, - // header2 = CRMContactResource.Contacts, - // header3 = CRMTaskResource.Tasks, - // header4 = CRMInvoiceResource.Invoices, - // header5 = CRMReportResource.Calls, - // byBudget = CRMReportResource.ByBudget, - // currency = CRMSettings.DefaultCurrency.Symbol, - // byCount = CRMReportResource.ByCount, - // item = CRMReportResource.Item, - // type = CRMReportResource.Type, - // won = CRMReportResource.Won, - // lost = CRMReportResource.Lost, - // created = CRMReportResource.Created, - // closed = CRMReportResource.Closed, - // overdue = CRMReportResource.Overdue, - // notSpecified = CRMCommonResource.NoSet, - // total = CRMReportResource.Total, - // status = CRMReportResource.Status, - // billed = CRMReportResource.Billed, - // paid = CRMReportResource.Paid, - // rejected = CRMReportResource.Rejected, - // count = CRMReportResource.Count, - // duration = CRMReportResource.Duration, - // incoming = CRMReportResource.Incoming, - // outcoming = CRMReportResource.Outcoming, - // missed = CRMReportResource.MissedCount, - // timeFormat = TimeFormat - // }, - // data = reportData - // }; - //} + return GenerateSummaryAtThisMomentReportData(timePeriod, reportData); + } - //#endregion + private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + GetTimePeriod(timePeriod, out fromDate, out toDate); - //#region SummaryAtThisMomentReport + throw new NotImplementedException(); - //public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var dealsSqlQuery = Query(CRMDbContext.Deals) - // .Join(CRMDbContext.DealMilestones, - // x => x.DealMilestoneId, - // y => y.Id, - // (x, y) => new { x, y }) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.x.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Where(x => x.y.Status == DealMilestoneStatus.Open) - // .Any(); - - - // var contactsSqlQuery = Query(CRMDbContext.Contacts) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // var tasksSqlQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // var invoicesSqlQuery = Query(CRMDbContext.Invoices) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // return dealsSqlQuery || - // contactsSqlQuery || - // tasksSqlQuery || - // invoicesSqlQuery; + //var openDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.Open); + + //var overdueDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .Where(Exp.Lt("d.expected_close_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()))); + + //var nearDealsSqlQuery = Query("crm_deal d") + // .Select("count(d.id) as count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_currency_rate r", + // Exp.EqColumns("r.tenant_id", "d.tenant_id") & + // Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .LeftOuterJoin("crm_deal_milestone m", + // Exp.EqColumns("m.tenant_id", "d.tenant_id") & + // Exp.EqColumns("m.id", "d.deal_milestone_id")) + // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .Where(Exp.Between("d.expected_close_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow().AddDays(30)))); + + //var dealsByStageSqlQuery = Query("crm_deal_milestone m") + // .Select("m.title", + // "count(d.id) as deals_count", + // string.Format(@"sum(case d.bid_type + // when 0 then + // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) + // else + // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) + // end) as deals_value", defaultCurrency)) + // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & + // Exp.EqColumns("d.deal_milestone_id", "m.id") & + // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & + // (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate)))) + // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "m.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) + // .Where("m.status", (int)DealMilestoneStatus.Open) + // .GroupBy("m.id") + // .OrderBy("m.sort_order, m.title", true); + + //var contactsByTypeSqlQuery = Query("crm_contact c") + // .Select("i.title", + // "count(c.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + // Exp.EqColumns("i.id", "c.contact_type_id") & + // Exp.Eq("i.list_type", (int)ListType.ContactType)) + // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); + + //var contactsByStageSqlQuery = Query("crm_contact c") + // .Select("i.title", + // "count(c.id) as count") + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & + // Exp.EqColumns("i.id", "c.status_id") & + // Exp.Eq("i.list_type", (int)ListType.ContactStatus)) + // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); + + //var tasksSqlQuery = Query("crm_task t") + // .Select("i.title") + // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0), 1, 0))) + // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), 1, 0))) + // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) + // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) + // .GroupBy("i.id") + // .OrderBy("i.sort_order, i.title", true); - //} + //var sent = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent), 1, 0)); + //var overdue = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), 1, 0)); - //public object GetSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // var reportData = BuildSummaryAtThisMomentReport(timePeriod, managers, defaultCurrency); + //var invoicesSqlQuery = Query("crm_invoice i") + // .Select(sent) + // .Select(overdue) + // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) + // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))); - // if (reportData == null) return null; + //object res; - // return GenerateSummaryAtThisMomentReportData(timePeriod, reportData); - //} + //using (var tx = Db.BeginTransaction()) + //{ + // res = new + // { + // DealsInfo = new + // { + // Open = Db.ExecuteList(openDealsSqlQuery), + // Overdue = Db.ExecuteList(overdueDealsSqlQuery), + // Near = Db.ExecuteList(nearDealsSqlQuery), + // ByStage = Db.ExecuteList(dealsByStageSqlQuery) + // }, + // ContactsInfo = new + // { + // ByType = Db.ExecuteList(contactsByTypeSqlQuery), + // ByStage = Db.ExecuteList(contactsByStageSqlQuery) + // }, + // TasksInfo = Db.ExecuteList(tasksSqlQuery), + // InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), + // }; - //private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var openDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.Open); - - // var overdueDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .Where(Exp.Lt("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()))); - - // var nearDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .Where(Exp.Between("d.expected_close_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow().AddDays(30)))); - - // var dealsByStageSqlQuery = Query("crm_deal_milestone m") - // .Select("m.title", - // "count(d.id) as deals_count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & - // Exp.EqColumns("d.deal_milestone_id", "m.id") & - // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & - // (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate)))) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "m.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .GroupBy("m.id") - // .OrderBy("m.sort_order, m.title", true); - - // var contactsByTypeSqlQuery = Query("crm_contact c") - // .Select("i.title", - // "count(c.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - // Exp.EqColumns("i.id", "c.contact_type_id") & - // Exp.Eq("i.list_type", (int)ListType.ContactType)) - // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - // var contactsByStageSqlQuery = Query("crm_contact c") - // .Select("i.title", - // "count(c.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - // Exp.EqColumns("i.id", "c.status_id") & - // Exp.Eq("i.list_type", (int)ListType.ContactStatus)) - // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - // var tasksSqlQuery = Query("crm_task t") - // .Select("i.title") - // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0), 1, 0))) - // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0))) - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - // var sent = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent), 1, 0)); - // var overdue = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow())), 1, 0)); - - // var invoicesSqlQuery = Query("crm_invoice i") - // .Select(sent) - // .Select(overdue) - // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", TenantUtil.DateTimeToUtc(fromDate), TenantUtil.DateTimeToUtc(toDate))); - - // object res; - - // using (var tx = Db.BeginTransaction()) - // { - // res = new - // { - // DealsInfo = new - // { - // Open = Db.ExecuteList(openDealsSqlQuery), - // Overdue = Db.ExecuteList(overdueDealsSqlQuery), - // Near = Db.ExecuteList(nearDealsSqlQuery), - // ByStage = Db.ExecuteList(dealsByStageSqlQuery) - // }, - // ContactsInfo = new - // { - // ByType = Db.ExecuteList(contactsByTypeSqlQuery), - // ByStage = Db.ExecuteList(contactsByStageSqlQuery) - // }, - // TasksInfo = Db.ExecuteList(tasksSqlQuery), - // InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), - // }; - - // tx.Commit(); - // } - - // return res; - //} + // tx.Commit(); + //} - //private object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) - //{ - // return new - // { - // resource = new - // { - // header = CRMReportResource.SummaryAtThisMomentReport, - // sheetName = CRMReportResource.SummaryAtThisMomentReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - // chartName = CRMReportResource.DealsByStatus + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName1 = CRMReportResource.DealsByStage + ", " + CRMSettings.DefaultCurrency.Symbol, - // chartName2 = CRMReportResource.ContactsByType, - // chartName3 = CRMReportResource.ContactsByStage, - // chartName4 = CRMReportResource.TasksByStatus, - // chartName5 = CRMReportResource.InvoicesByStatus, - // header1 = CRMDealResource.Deals, - // header2 = CRMContactResource.Contacts, - // header3 = CRMTaskResource.Tasks, - // header4 = CRMInvoiceResource.Invoices, - // budget = CRMReportResource.Budget + ", " + CRMSettings.DefaultCurrency.Symbol, - // count = CRMReportResource.Count, - // open = CRMReportResource.Opened, - // overdue = CRMReportResource.Overdue, - // near = CRMReportResource.Near, - // stage = CRMReportResource.Stage, - // temperature = CRMContactResource.ContactStage, - // type = CRMReportResource.Type, - // total = CRMReportResource.Total, - // billed = CRMReportResource.Billed, - // notSpecified = CRMCommonResource.NoSet, - // status = CRMReportResource.Status, - // }, - // data = reportData - // }; - //} + //return res; + } - //#endregion + private object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) + { + return new + { + resource = new + { + header = CRMReportResource.SummaryAtThisMomentReport, + sheetName = CRMReportResource.SummaryAtThisMomentReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + chartName = CRMReportResource.DealsByStatus + ", " + _defaultCurrency.Symbol, + chartName1 = CRMReportResource.DealsByStage + ", " + _defaultCurrency.Symbol, + chartName2 = CRMReportResource.ContactsByType, + chartName3 = CRMReportResource.ContactsByStage, + chartName4 = CRMReportResource.TasksByStatus, + chartName5 = CRMReportResource.InvoicesByStatus, + header1 = CRMDealResource.Deals, + header2 = CRMContactResource.Contacts, + header3 = CRMTaskResource.Tasks, + header4 = CRMInvoiceResource.Invoices, + budget = CRMReportResource.Budget + ", " + _defaultCurrency.Symbol, + count = CRMReportResource.Count, + open = CRMReportResource.Opened, + overdue = CRMReportResource.Overdue, + near = CRMReportResource.Near, + stage = CRMReportResource.Stage, + temperature = CRMContactResource.ContactStage, + type = CRMReportResource.Type, + total = CRMReportResource.Total, + billed = CRMReportResource.Billed, + notSpecified = CRMCommonResource.NoSet, + status = CRMReportResource.Status, + }, + data = reportData + }; + } + + #endregion } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs index b9eed31d757..6fae35bc348 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCurrencyRate.cs @@ -5,7 +5,7 @@ namespace ASC.CRM.Core.EF { [Table("crm_currency_rate")] - public partial class DbCurrencyRate + public partial class DbCurrencyRate : IDbCrm { [Key] [Column("id", TypeName = "int(11)")] diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index 82f305e6093..7181d54795e 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -181,35 +181,33 @@ private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, var crmSettings = SettingsManager.Load(); var reportDao = DaoFactory.GetReportDao(); - var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); - - throw new NotImplementedException(); + var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency).Abbreviation; - //switch (reportType) - //{ - // case ReportType.SalesByManagers: - // return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); - // case ReportType.SalesForecast: - // return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); - // case ReportType.SalesFunnel: - // return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); - // case ReportType.WorkloadByContacts: - // return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); - // case ReportType.WorkloadByTasks: - // return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); - // case ReportType.WorkloadByDeals: - // return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); - // case ReportType.WorkloadByInvoices: - // return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); - // case ReportType.WorkloadByVoip: - // return reportDao.GetWorkloadByViopReportData(timePeriod, managers); - // case ReportType.SummaryForThePeriod: - // return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); - // case ReportType.SummaryAtThisMoment: - // return reportDao.GetSummaryAtThisMomentReportData(timePeriod, managers, defaultCurrency); - // default: - // return null; - //} + switch (reportType) + { + case ReportType.SalesByManagers: + return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); + case ReportType.SalesForecast: + return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); + //case ReportType.SalesFunnel: + // return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); + //case ReportType.WorkloadByContacts: + // return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); + //case ReportType.WorkloadByTasks: + // return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); + //case ReportType.WorkloadByDeals: + // return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); + //case ReportType.WorkloadByInvoices: + // return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); + //case ReportType.WorkloadByVoip: + // return reportDao.GetWorkloadByViopReportData(timePeriod, managers); + case ReportType.SummaryForThePeriod: + return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); + case ReportType.SummaryAtThisMoment: + return reportDao.GetSummaryAtThisMomentReportData(timePeriod, managers, defaultCurrency); + default: + return null; + } } private string GetReportScript(object data, ReportType type, string fileName) @@ -248,6 +246,7 @@ private void SaveReportFile(ReportState state, string url) public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { var reportData = GetReportData(reportType, timePeriod, managers); + if (reportData == null) throw new Exception(CRMReportResource.ErrorNullReportData); From 22293af8d04ed0c4e261631946376f9df62e52da Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Thu, 25 Mar 2021 19:36:41 +0300 Subject: [PATCH 36/61] crm: bugfix --- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 463 +++++++++--------- 1 file changed, 244 insertions(+), 219 deletions(-) diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 80cce0da58e..51a318088f2 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -1841,10 +1841,11 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ GetTimePeriod(timePeriod, out fromDate, out toDate); var newDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.CurrencyRate), + .GroupJoin(Query(CRMDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, - (x, y) => new { Deal = x, CurrencyRate = y }) + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) .Where(x => x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .GroupBy(x => x.Deal.Id) @@ -1852,18 +1853,20 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ { count = x.Count(), deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : - x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); var wonDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.CurrencyRate), - x => x.BidCurrency, - y => y.FromCurrency, - (x, y) => new { Deal = x, CurrencyRate = y }) - .Join(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, - (x, y) => new { Deal = x.Deal, CurrencyRate = x.CurrencyRate, DealMilestone = y }) + (x, y) => new { x,y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon) @@ -1872,51 +1875,54 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ { count = x.Count(), deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : - x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); var lostDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.CurrencyRate), - x => x.BidCurrency, - y => y.FromCurrency, - (x, y) => new { Deal = x, CurrencyRate = y }) - .Join(Query(CRMDbContext.DealMilestones), - x => x.Deal.DealMilestoneId, - y => y.Id, - (x, y) => new { Deal = x.Deal, CurrencyRate = x.CurrencyRate, DealMilestone = y }) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) - .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) - .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndLost) - .GroupBy(x => x.Deal.Id) - .Select(x => new - { - count = x.Count(), - deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : - x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) - }).ToList(); + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndLost) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); var overdueDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.CurrencyRate), - x => x.BidCurrency, - y => y.FromCurrency, - (x, y) => new { Deal = x, CurrencyRate = y }) - .Join(Query(CRMDbContext.DealMilestones), - x => x.Deal.DealMilestoneId, - y => y.Id, - (x, y) => new { Deal = x.Deal, CurrencyRate = x.CurrencyRate, DealMilestone = y }) - .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) - .Where(x => x.Deal.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ExpectedCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) - - .Where(x => (x.DealMilestone.Status == DealMilestoneStatus.Open && x.Deal.ExpectedCloseDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || - (x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon && x.Deal.ActualCloseDate > x.Deal.ExpectedCloseDate)) - .GroupBy(x => x.Deal.Id) - .Select(x => new - { - count = x.Count(), - deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : - x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) - }).ToList(); + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ExpectedCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => (x.DealMilestone.Status == DealMilestoneStatus.Open && x.Deal.ExpectedCloseDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + (x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon && x.Deal.ActualCloseDate > x.Deal.ExpectedCloseDate)) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); var invoicesSqlQuery = Query(CRMDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) @@ -1932,10 +1938,11 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ }).ToList(); var contactsSqlQuery = Query(CRMDbContext.Contacts) - .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), + .GroupJoin(Query(CRMDbContext.ListItem), x => x.ContactTypeId, y => y.Id, - (x, y) => new { Contact = x, ListItem = y }) + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x,y) => new { Contact = x.x, ListItem = y }) .Where(x => x.ListItem.ListType == ListType.ContactType) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Contact.CreateBy) : true) .Where(x => x.Contact.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Contact.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) @@ -1948,15 +1955,12 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ .OrderBy(x => x.title) .ToList(); - - - - var tasksSqlQuery = Query(CRMDbContext.Tasks) - .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), + .GroupJoin(Query(CRMDbContext.ListItem), x => x.CategoryId, y => y.Id, - (x,y) => new { Task = x, ListItem = y }) + (x,y) => new { x,y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Task = x.x, ListItem = y }) .Where(x => x.ListItem.ListType == ListType.TaskCategory) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) .Where(x => x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) @@ -1973,9 +1977,6 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ .ToList(); // .OrderBy("i.sort_order, i.title", true); - - - var voipSqlQuery = Query(CRMDbContext.VoipCalls) .Where(x => String.IsNullOrEmpty(x.ParentCallId)) .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) @@ -1987,30 +1988,20 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ duration = x.Sum(x => x.DialDuration) }) .ToList(); - - object res; - - using (var tx = CRMDbContext.Database.BeginTransaction()) + return new { - res = new + DealsInfo = new { - DealsInfo = new - { - Created = newDealsSqlQuery, - Won = wonDealsSqlQuery, - Lost = lostDealsSqlQuery, - Overdue = overdueDealsSqlQuery - }, - InvoicesInfo = invoicesSqlQuery, - ContactsInfo = contactsSqlQuery, - TasksInfo = tasksSqlQuery, - VoipInfo = voipSqlQuery - }; - - tx.Commit(); - } - - return res; + Created = newDealsSqlQuery, + Won = wonDealsSqlQuery, + Lost = lostDealsSqlQuery, + Overdue = overdueDealsSqlQuery + }, + InvoicesInfo = invoicesSqlQuery, + ContactsInfo = contactsSqlQuery, + TasksInfo = tasksSqlQuery, + VoipInfo = voipSqlQuery + }; } private object GenerateSummaryForThePeriodReportData(ReportTimePeriod timePeriod, object reportData) @@ -2122,149 +2113,183 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ GetTimePeriod(timePeriod, out fromDate, out toDate); - throw new NotImplementedException(); + var openDealsSqlQuery = Query(CRMDbContext.Deals) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.Open) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); - //var openDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.Open); + var overdueDealsSqlQuery = Query(CRMDbContext.Deals) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.Open) + .Where(x => x.Deal.ExpectedCloseDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); - //var overdueDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .Where(Exp.Lt("d.expected_close_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()))); - //var nearDealsSqlQuery = Query("crm_deal d") - // .Select("count(d.id) as count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "d.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("crm_deal_milestone m", - // Exp.EqColumns("m.tenant_id", "d.tenant_id") & - // Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .Where(Exp.Between("d.expected_close_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow().AddDays(30)))); + var nearDealsSqlQuery = Query(CRMDbContext.Deals) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.Open) + .Where(x => x.Deal.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()) && x.Deal.ExpectedCloseDate <= _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow().AddDays(30))) + .GroupBy(x => x.Deal.Id) + .Select(x => new + { + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); + + var dealsByStageSqlQuery = Query(CRMDbContext.DealMilestones) + .GroupJoin(Query(CRMDbContext.Deals), + x => x.Id, + y => y.DealMilestoneId, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = y, DealMilestone = x.x }) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.Deal.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, DealMilestone = x.x.DealMilestone, CurrencyRate = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.Open) + .GroupBy(x => new { x.DealMilestone.Id, x.DealMilestone.Title }) + .Select(x => new + { + title = x.Key.Title, + deals_count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList(); + + var contactsByTypeSqlQuery = Query(CRMDbContext.Contacts) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.ContactTypeId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Contact = x.x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.ContactType) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Contact.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Contact.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Contact.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => new { x.ListItem.Title }) + .Select(x => new + { + title = x.Key.Title, + count = x.Count() + }) + .OrderBy(x => x.title) + .ToList(); + + var contactsByStageSqlQuery = Query(CRMDbContext.Contacts) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.StatusId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Contact = x.x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.ContactStatus) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Contact.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Contact.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Contact.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => new { x.ListItem.Title }) + .Select(x => new + { + title = x.Key.Title, + count = x.Count() + }) + .OrderBy(x => x.title) + .ToList(); + + var tasksSqlQuery = Query(CRMDbContext.Tasks) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.CategoryId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Task = x.x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.TaskCategory) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => new { x.ListItem.Title }) + .Select(x => new + { + + title = x.Key.Title, + sum1 = x.Sum(x => !x.Task.IsClosed ? 1 : 0), + sum2 = x.Sum(x => (!x.Task.IsClosed && x.Task.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) ? 1 : 0), + count = x.Count() + }) + .OrderBy(x => x.title) + .ToList(); + + + var invoicesSqlQuery = Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => x.Status) + .Select(x => new { + sent = x.Sum(x => x.Status == InvoiceStatus.Sent ? 1 : 0), + overdue = x.Sum(x => (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) ? 1 : 0) + }).ToList(); - //var dealsByStageSqlQuery = Query("crm_deal_milestone m") - // .Select("m.title", - // "count(d.id) as deals_count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & - // Exp.EqColumns("d.deal_milestone_id", "m.id") & - // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & - // (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate)))) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "m.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .GroupBy("m.id") - // .OrderBy("m.sort_order, m.title", true); - - //var contactsByTypeSqlQuery = Query("crm_contact c") - // .Select("i.title", - // "count(c.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - // Exp.EqColumns("i.id", "c.contact_type_id") & - // Exp.Eq("i.list_type", (int)ListType.ContactType)) - // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - //var contactsByStageSqlQuery = Query("crm_contact c") - // .Select("i.title", - // "count(c.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & - // Exp.EqColumns("i.id", "c.status_id") & - // Exp.Eq("i.list_type", (int)ListType.ContactStatus)) - // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - //var tasksSqlQuery = Query("crm_task t") - // .Select("i.title") - // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0), 1, 0))) - // .Select(Exp.Sum(Exp.If(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), 1, 0))) - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id") - // .OrderBy("i.sort_order, i.title", true); - - //var sent = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent), 1, 0)); - //var overdue = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), 1, 0)); - - //var invoicesSqlQuery = Query("crm_invoice i") - // .Select(sent) - // .Select(overdue) - // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))); - - //object res; - - //using (var tx = Db.BeginTransaction()) - //{ - // res = new - // { - // DealsInfo = new - // { - // Open = Db.ExecuteList(openDealsSqlQuery), - // Overdue = Db.ExecuteList(overdueDealsSqlQuery), - // Near = Db.ExecuteList(nearDealsSqlQuery), - // ByStage = Db.ExecuteList(dealsByStageSqlQuery) - // }, - // ContactsInfo = new - // { - // ByType = Db.ExecuteList(contactsByTypeSqlQuery), - // ByStage = Db.ExecuteList(contactsByStageSqlQuery) - // }, - // TasksInfo = Db.ExecuteList(tasksSqlQuery), - // InvoicesInfo = Db.ExecuteList(invoicesSqlQuery), - // }; - - // tx.Commit(); - //} - //return res; + return new + { + DealsInfo = new + { + Open = openDealsSqlQuery, + Overdue = overdueDealsSqlQuery, + Near = nearDealsSqlQuery, + ByStage = dealsByStageSqlQuery + }, + ContactsInfo = new + { + ByType = contactsByTypeSqlQuery, + ByStage = contactsByStageSqlQuery + }, + TasksInfo = tasksSqlQuery, + InvoicesInfo = invoicesSqlQuery + }; } private object GenerateSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, object reportData) From 4ee1cf80b507bce1cde88ac6355cd07ad74f8146 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 26 Mar 2021 19:42:46 +0300 Subject: [PATCH 37/61] crm: fixed reports query --- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 1588 +++++++++-------- .../ASC.CRM/Server/Core/EF/DbVoipCalls.cs | 4 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 24 +- 3 files changed, 813 insertions(+), 803 deletions(-) diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 51a318088f2..22938f9fbc3 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -31,6 +31,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Linq.Expressions; using ASC.Common; using ASC.Common.Caching; @@ -39,10 +40,13 @@ using ASC.Core.Common.EF; using ASC.Core.Common.Settings; using ASC.Core.Tenants; +using ASC.CRM.Classes; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using ASC.VoipService; +using ASC.Web.Core.Users; using ASC.Web.CRM.Classes; using ASC.Web.Files.Api; @@ -68,10 +72,13 @@ public class ReportDao : AbstractDao private CurrencyInfo _defaultCurrency; private TenantUtil _tenantUtil; private DaoFactory _daoFactory; + private UserDbContext _userDbContext; + private DisplayUserSettingsHelper _displayUserSettings; #region Constructor public ReportDao(DbContextManager dbContextManager, + DbContextManager dbUserContextManager, TenantManager tenantManager, SecurityContext securityContext, FilesIntegration filesIntegration, @@ -83,7 +90,8 @@ public ReportDao(DbContextManager dbContextManager, UserManager userManager, IServiceProvider serviceProvider, CurrencyProvider currencyProvider, - DaoFactory daoFactory) : + DaoFactory daoFactory, + DisplayUserSettingsHelper displayUserSettingsHelper) : base(dbContextManager, tenantManager, securityContext, @@ -98,9 +106,15 @@ public ReportDao(DbContextManager dbContextManager, _tenantManager = tenantManager; _serviceProvider = serviceProvider; _daoFactory = daoFactory; + var crmSettings = settingsManager.Load(); - _defaultCurrency = currencyProvider.Get(crmSettings.DefaultCurrency); + _userDbContext = dbUserContextManager.Get(CRMConstants.DatabaseId); + + _defaultCurrency = currencyProvider.Get(crmSettings.DefaultCurrency); + + _displayUserSettings = displayUserSettingsHelper; + } @@ -425,63 +439,66 @@ private List BuildSalesByManagersReport(ReportTimePeriod timePer GetTimePeriod(timePeriod, out fromDate, out toDate); - throw new NotImplementedException(); - - //string dateSelector; - - //switch (timePeriod) - //{ - // case ReportTimePeriod.Today: - // case ReportTimePeriod.Yesterday: - // dateSelector = "date_add(date(d.actual_close_date), interval extract(hour from d.actual_close_date) hour) as close_date"; - // break; - // case ReportTimePeriod.CurrentWeek: - // case ReportTimePeriod.PreviousWeek: - // case ReportTimePeriod.CurrentMonth: - // case ReportTimePeriod.PreviousMonth: - // dateSelector = "date(d.actual_close_date) as close_date"; - // break; - // case ReportTimePeriod.CurrentQuarter: - // case ReportTimePeriod.PreviousQuarter: - // case ReportTimePeriod.CurrentYear: - // case ReportTimePeriod.PreviousYear: - // dateSelector = "date_sub(date(d.actual_close_date), interval (extract(day from d.actual_close_date) - 1) day) as close_date"; - // break; - // default: - // return null; - //} - - //var sqlQuery = Query("crm_deal d") - // .Select("d.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // string.Format(@"sum((case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end)) as bid_value", defaultCurrency), - // dateSelector) - // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.id", "d.deal_milestone_id") & Exp.EqColumns("m.tenant_id", "d.tenant_id")) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) - // .Where("m.status", (int)DealMilestoneStatus.ClosedAndWon) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("d.actual_close_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("responsible_id", "close_date"); - - - //return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesByManagers); - } + Func exp; - private SalesByManager ToSalesByManagers(object[] row) - { - return new SalesByManager + switch (timePeriod) { - UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - UserName = Convert.ToString(row[1]), - Value = Convert.ToDecimal(row[2]), - Date = Convert.ToDateTime(row[3]) == DateTime.MinValue ? DateTime.MinValue : _tenantUtil.DateTimeFromUtc(Convert.ToDateTime(row[3])) - }; + case ReportTimePeriod.Today: + case ReportTimePeriod.Yesterday: + exp = x => x ?? x.Value.Date.AddHours(x.Value.Hour); + + break; + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.PreviousWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.PreviousMonth: + exp = x => x??x.Value.Date; + + break; + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.PreviousQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.PreviousYear: + exp = x => x??x.Value.Date.AddDays(-(x.Value.Day - 1)); + + break; + default: + return null; + } + + var result = Query(CRMDbContext.Deals) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon) + .GroupBy(x => new { x.Deal.ResponsibleId, x.Deal.ActualCloseDate, x.DealMilestone.Status }) + .Select(x => new + { + responsible_id = x.Key.ResponsibleId, + status = x.Key.Status, + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)), + close_date = exp.Invoke(x.Key.ActualCloseDate) + }).ToList() + .ConvertAll(x => new SalesByManager + { + UserId = x.responsible_id, + UserName = _displayUserSettings.GetFullUserName(x.responsible_id), + Value = x.deals_value, + Date = x.close_date == DateTime.MinValue ? DateTime.MinValue : _tenantUtil.DateTimeFromUtc(x.close_date) + }); + + return result; } private object GenerateReportData(ReportTimePeriod timePeriod, List data) @@ -799,50 +816,59 @@ private List BuildSalesForecastReport(ReportTimePeriod timePeriod GetTimePeriod(timePeriod, out fromDate, out toDate); - throw new NotImplementedException(); - - //string dateSelector; - - //switch (timePeriod) - //{ - // case ReportTimePeriod.CurrentWeek: - // case ReportTimePeriod.NextWeek: - // case ReportTimePeriod.CurrentMonth: - // case ReportTimePeriod.NextMonth: - // dateSelector = "d.expected_close_date as close_date"; - // break; - // case ReportTimePeriod.CurrentQuarter: - // case ReportTimePeriod.NextQuarter: - // case ReportTimePeriod.CurrentYear: - // case ReportTimePeriod.NextYear: - // dateSelector = "date_sub(date(d.expected_close_date), interval (extract(day from d.expected_close_date) - 1) day) as close_date"; - // break; - // default: - // return null; - //} - - //var sqlQuery = Query("crm_deal d") - // .Select(string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as value", defaultCurrency), - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) * d.deal_milestone_probability / 100 - // end) as value_with_probability", defaultCurrency), - // dateSelector) - // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .Where("m.status", (int)DealMilestoneStatus.Open) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Between("d.expected_close_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("close_date"); - - //return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesForecast); + Func exp; + + switch (timePeriod) + { + case ReportTimePeriod.CurrentWeek: + case ReportTimePeriod.NextWeek: + case ReportTimePeriod.CurrentMonth: + case ReportTimePeriod.NextMonth: + exp = x => x.Date; + break; + case ReportTimePeriod.CurrentQuarter: + case ReportTimePeriod.NextQuarter: + case ReportTimePeriod.CurrentYear: + case ReportTimePeriod.NextYear: + exp = x => x.Date.AddDays(-(x.Day - 1)); + break; + default: + return null; + } + + var result = Query(CRMDbContext.Deals) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ExpectedCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon) + .GroupBy(x => new { x.Deal.ExpectedCloseDate }) + .Select(x => new + { + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)), + + value_with_probability = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) * x.Deal.DealMilestoneProbability/100.0m : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) * x.Deal.DealMilestoneProbability / 100.0m), + close_date = exp.Invoke(x.Key.ExpectedCloseDate) + }).ToList() + .ConvertAll(x => new SalesForecast + { + Value = x.deals_value, + ValueWithProbability = x.value_with_probability, + Date = x.close_date == DateTime.MinValue ? DateTime.MinValue : _tenantUtil.DateTimeFromUtc(x.close_date) + }); + + + return result; } private SalesForecast ToSalesForecast(object[] row) @@ -1032,679 +1058,658 @@ public bool CheckSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] manag .Any(); } - //public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - //{ - // var reportData = BuildSalesFunnelReport(timePeriod, managers, defaultCurrency); - - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - //} - - // private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query("crm_deal_milestone m") - // .Select("m.status", "m.title", - // "count(d.id) as deals_count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency), - // "avg(if(m.status = 1, datediff(d.actual_close_date, d.create_on), 0)) as deals_duration") - // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "m.tenant_id") & - // Exp.EqColumns("d.deal_milestone_id", "m.id") & - // (managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) & - // Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .LeftOuterJoin("crm_currency_rate r", - // Exp.EqColumns("r.tenant_id", "m.tenant_id") & - // Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .GroupBy("m.id") - // .OrderBy("m.sort_order", true); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToSalesFunnel); - // } - - // private SalesFunnel ToSalesFunnel(object[] row) - // { - // return new SalesFunnel - // { - // Status = (DealMilestoneStatus)Convert.ToInt32(row[0]), - // Title = Convert.ToString(row[1]), - // Count = Convert.ToInt32(row[2]), - // Value = Convert.ToDecimal(row[3]), - // Duration = Convert.ToInt32(row[4]) - // }; - // } - - // private object GenerateReportData(ReportTimePeriod timePeriod, List data) - // { - // var totalCount = data.Sum(x => x.Count); - - // if (totalCount == 0) return null; - - // var totalBudget = data.Sum(x => x.Value); - - // var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); - - // var reportData = data.Select(item => new List - // { - // item.Title, - // item.Status, - // item.Count, - // item.Value - // }).ToList(); - - // return new - // { - // resource = new - // { - // header = CRMReportResource.SalesFunnelReport, - // sheetName = CRMReportResource.SalesFunnelReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // chartName = CRMReportResource.SalesFunnelByCount, - // chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + _defaultCurrency.Symbol, - // chartName2 = CRMReportResource.DealsCount, - // chartName3 = CRMReportResource.DealsBudget + ", " + _defaultCurrency.Symbol, - - // totalCountLabel = CRMReportResource.TotalDealsCount, - // totalCountValue = totalCount, - - // totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + _defaultCurrency.Symbol, - // totalBudgetValue = totalBudget, - - // averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + _defaultCurrency.Symbol, - // averageBidValue = totalBudget / totalCount, - - // averageDurationLabel = CRMReportResource.AverageDealsDuration, - // averageDurationValue = closed.Sum(x => x.Duration) / closed.Count, - - // header1 = CRMReportResource.ByCount, - // header2 = CRMReportResource.ByBudget + ", " + _defaultCurrency.Symbol, - - // stage = CRMReportResource.Stage, - // count = CRMReportResource.Count, - // budget = CRMReportResource.Budget, - // conversion = CRMReportResource.Conversion, - - // deals = CRMDealResource.Deals, - // status0 = DealMilestoneStatus.Open.ToLocalizedString(), - // status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), - // status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() - // }, - // data = reportData - // }; - // } - - // #endregion - - - // #region WorkloadByContactsReport - - // public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // return Query(CRMDbContext.Contacts) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) - // .Any(); - // } - - // public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // var reportData = BuildWorkloadByContactsReport(timePeriod, managers); - - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - // } - - // private List BuildWorkloadByContactsReport(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query(CRMDbContext.Contacts) - // .GroupJoin(Query(CRMDbContext.ListItem), - // x => x.ContactTypeId, - // y => y.Id, - // (x, y) => new { x, y }) - // .GroupJoin(Query(CRMDbContext.Deals), - // x => x.x.Id, - // y => y.Id, - // (x, y) => new { x, y }) - - - - // var sqlQuery = Query("crm_contact c") - // .Select("c.create_by", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "i.id", - // "i.title", - // "count(c.id) as total", - // "count(d.id) as `with deals`") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "c.tenant_id") & Exp.EqColumns("i.id", "c.contact_type_id") & Exp.Eq("i.list_type", (int)ListType.ContactType)) - // .LeftOuterJoin("crm_deal d", Exp.EqColumns("d.tenant_id", "c.tenant_id") & Exp.EqColumns("d.contact_id", "c.id")) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.create_by")) - // .Where(managers != null && managers.Any() ? Exp.In("c.create_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("c.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("c.create_by", "i.id") - // .OrderBy("i.sort_order, i.title", true); - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByContacts); - // } - - // private WorkloadByContacts ToWorkloadByContacts(object[] row) - // { - // return new WorkloadByContacts - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1]), - // CategoryId = Convert.ToInt32(row[2]), - // CategoryName = Convert.ToString(row[3]), - // Count = Convert.ToInt32(row[4]), - // WithDeals = Convert.ToInt32(row[5]) - // }; - // } - - // private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) - // { - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByContactsReport, - // sheetName = CRMReportResource.WorkloadByContactsReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // header1 = CRMReportResource.NewContacts, - // header2 = CRMReportResource.NewContactsWithAndWithoutDeals, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total, - - // noSet = CRMCommonResource.NoSet, - // withDeals = CRMReportResource.ContactsWithDeals, - // withouthDeals = CRMReportResource.ContactsWithoutDeals, - // }, - // data = reportData - // }; - // } - - // #endregion - - - // #region WorkloadByTasksReport - - // public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - // var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => x.IsClosed) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) - // .Any(); - - - - // var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => x.IsClosed) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) - // .Where(x => (!x.IsClosed && x.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || - // (x.IsClosed && x.LastModifedOn > x.Deadline)) - // .Any(); - - // return sqlNewTasksQuery || - // sqlClosedTasksQuery || - // sqlOverdueTasksQuery; - // } - - // public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // var reportData = BuildWorkloadByTasksReport(timePeriod, managers); - - // if (reportData == null || !reportData.Any()) return null; - - // var hasData = reportData.Any(item => item.Value.Count > 0); - - // return hasData ? GenerateReportData(timePeriod, reportData) : null; - // } - - // private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) - // .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), - // x => x.CategoryId, - // y => y.Id, - // (x, y) => new { Task = x, ListItem = y }) - // .Join(_userDbContext.Users.DefaultIfEmpty(), - // x => x.Task.ResponsibleId, - // y => y.Id, - // (x, y) => new { Task = x.Task, ListItem = x.ListItem, User = y } - // ) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) - // .OrderBy(x => x.ListItem.SortOrder) - // .Select(x => new - // { - // x.ListItem.Id, - // x.ListItem.Title, - // x.Task.ResponsibleId, - // x.User - // }); - - // var sqlNewTasksQuery = Query(CRMDbContext.Tasks) - // .Join(Query(CRMDbContext.ListItem).DefaultIfEmpty(), - // x => x.CategoryId, - // y => y.Id, - // (x, y) => new { Task = x, ListItem = y }) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) - // .OrderBy(x => x.ListItem.SortOrder) - // .GroupBy(x => new { x.ListItem.Id, x.ListItem.Title, x.Task.ResponsibleId }) - // .Select(x => new - // { - // Id = x.Key.Id, - // Title = x.Key.Title, - // ResponsibleId = x.Key.ResponsibleId, - // Count = x.Count() - // }); - - // throw new NotImplementedException(); - - - // var sqlNewTasksQuery = Query("crm_task t") - //.Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - //.LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - //.LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - //.Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - //.Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - //.GroupBy("i.id", "t.responsible_id") - //.OrderBy("i.sort_order", true); - - // var sqlClosedTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(Exp.Eq("t.is_closed", 1)) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); - - // var sqlOverdueTasksQuery = Query("crm_task t") - // .Select("i.id", - // "i.title", - // "t.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "count(t.id) as count") - // .LeftOuterJoin("crm_list_item i", Exp.EqColumns("i.tenant_id", "t.tenant_id") & Exp.EqColumns("i.id", "t.category_id") & Exp.Eq("i.list_type", (int)ListType.TaskCategory)) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "t.tenant_id") & Exp.EqColumns("u.id", "t.responsible_id")) - // .Where(managers != null && managers.Any() ? Exp.In("t.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("t.deadline", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .Where(Exp.Or(Exp.Eq("t.is_closed", 0) & Exp.Lt("t.deadline", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), (Exp.Eq("t.is_closed", 1) & Exp.Sql("t.last_modifed_on > t.deadline")))) - // .GroupBy("i.id", "t.responsible_id") - // .OrderBy("i.sort_order", true); - - // Dictionary> res; - - // using (var tx = Db.BeginTransaction()) - // { - // res = new Dictionary> - // { - // {"Created", Db.ExecuteList(sqlNewTasksQuery).ConvertAll(ToWorkloadByTasks)}, - // {"Closed", Db.ExecuteList(sqlClosedTasksQuery).ConvertAll(ToWorkloadByTasks)}, - // {"Overdue", Db.ExecuteList(sqlOverdueTasksQuery).ConvertAll(ToWorkloadByTasks)} - // }; - - // tx.Commit(); - // } - - // return res; - // } - - // private WorkloadByTasks ToWorkloadByTasks(object[] row) - // { - // return new WorkloadByTasks - // { - // CategoryId = Convert.ToInt32(row[0]), - // CategoryName = Convert.ToString(row[1]), - // UserId = string.IsNullOrEmpty(Convert.ToString(row[2])) ? Guid.Empty : new Guid(Convert.ToString(row[2])), - // UserName = Convert.ToString(row[3]), - // Count = Convert.ToInt32(row[4]) - // }; - // } - - // private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) - // { - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByTasksReport, - // sheetName = CRMReportResource.WorkloadByTasksReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // header1 = CRMReportResource.ClosedTasks, - // header2 = CRMReportResource.NewTasks, - // header3 = CRMReportResource.OverdueTasks, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total - // }, - // data = reportData - // }; - // } - - // #endregion - - - // #region WorkloadByDealsReport - - // public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // return Query(CRMDbContext.Deals) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) || - // (x.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate))) - // .Any(); - // } - - // public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - // { - // var reportData = BuildWorkloadByDealsReport(timePeriod, managers, defaultCurrency); - - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - // } - - // private List BuildWorkloadByDealsReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query("crm_deal d") - // .Select("d.responsible_id", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "m.status", - // "count(d.id) as deals_count", - // string.Format(@"sum(case d.bid_type - // when 0 then - // d.bid_value * (if(d.bid_currency = '{0}', 1, r.rate)) - // else - // d.bid_value * (if(d.per_period_value = 0, 1, d.per_period_value)) * (if(d.bid_currency = '{0}', 1, r.rate)) - // end) as deals_value", defaultCurrency)) - // .LeftOuterJoin("crm_deal_milestone m", Exp.EqColumns("m.tenant_id", "d.tenant_id") & Exp.EqColumns("m.id", "d.deal_milestone_id")) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "d.tenant_id") & Exp.EqColumns("u.id", "d.responsible_id")) - // .LeftOuterJoin("crm_currency_rate r", Exp.EqColumns("r.tenant_id", "d.tenant_id") & Exp.EqColumns("r.from_currency", "d.bid_currency")) - // .Where(managers != null && managers.Any() ? Exp.In("d.responsible_id", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - // Exp.Empty : - // Exp.Or(Exp.Between("d.create_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate)), - // Exp.Between("d.actual_close_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate)))) - // .GroupBy("d.responsible_id", "m.status"); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByDeals); - // } - - // private WorkloadByDeals ToWorkloadByDeals(object[] row) - // { - // return new WorkloadByDeals - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1]), - // Status = (DealMilestoneStatus)Convert.ToInt32(row[2]), - // Count = Convert.ToInt32(row[3]), - // Value = Convert.ToDecimal(row[4]) - // }; - // } - - // private object GenerateReportData(ReportTimePeriod timePeriod, List data) - // { - // var reportData = data.Select(item => new List - // { - // item.UserId, - // item.UserName, - // (int)item.Status, - // item.Count, - // item.Value - // }).ToList(); - - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByDealsReport, - // sheetName = CRMReportResource.WorkloadByDealsReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // chartName = CRMReportResource.DealsCount, - // chartName1 = CRMReportResource.DealsBudget + ", " + _defaultCurrency.Symbol, - - // header1 = CRMReportResource.ByCount, - // header2 = CRMReportResource.ByBudget + ", " + _defaultCurrency.Symbol, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total, - - // status0 = CRMReportResource.New, - // status1 = CRMReportResource.Won, - // status2 = CRMReportResource.Lost - // }, - // data = reportData - // }; - // } - - // #endregion - - - // #region WorkloadByInvoicesReport - - // public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // return Query(CRMDbContext.Invoices) - // .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) - // .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= _tenantUtil.DateTimeToUtc(toDate))) || - // (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate))) || - // (x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate))) || - // ((timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= _tenantUtil.DateTimeToUtc(toDate))) && - // (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()) || x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) - // .Any(); - // } - - // public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // var reportData = BuildWorkloadByInvoicesReport(timePeriod, managers); - - // if (reportData == null || !reportData.Any()) return null; - - // var hasData = reportData.Any(item => item.SentCount > 0 || item.PaidCount > 0 || item.RejectedCount > 0 || item.OverdueCount > 0); - - // return hasData ? GenerateReportData(timePeriod, reportData) : null; - // } - - // private List BuildWorkloadByInvoicesReport(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // throw new NotImplementedException(); - - // var sent = Exp.Sum(Exp.If(!Exp.Eq("i.status", (int)InvoiceStatus.Draft) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.issue_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))), 1, 0)); - // var paid = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Paid) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))), 1, 0)); - // var rejected = Exp.Sum(Exp.If(Exp.Eq("i.status", (int)InvoiceStatus.Rejected) & (timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.last_modifed_on", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))), 1, 0)); - // var overdue = Exp.Sum(Exp.If((timePeriod == ReportTimePeriod.DuringAllTime ? Exp.Empty : Exp.Between("i.due_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) & Exp.Or(Exp.Eq("i.status", (int)InvoiceStatus.Sent) & Exp.Lt("i.due_date", _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())), Exp.Eq("i.status", (int)InvoiceStatus.Paid) & Exp.Sql("i.last_modifed_on > i.due_date")), 1, 0)); - - // var sqlQuery = Query("crm_invoice i") - // .Select("i.create_by", "concat(u.firstname, ' ', u.lastname) as full_name") - // .Select(sent) - // .Select(paid) - // .Select(rejected) - // .Select(overdue) - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "i.tenant_id") & Exp.EqColumns("u.id", "i.create_by")) - // .Where(managers != null && managers.Any() ? Exp.In("i.create_by", managers) : Exp.Empty) - // .GroupBy("i.create_by"); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByInvoices); - // } - - // private WorkloadByInvoices ToWorkloadByInvoices(object[] row) - // { - // return new WorkloadByInvoices - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1]), - // SentCount = Convert.ToInt32(row[2]), - // PaidCount = Convert.ToInt32(row[3]), - // RejectedCount = Convert.ToInt32(row[4]), - // OverdueCount = Convert.ToInt32(row[5]) - // }; - // } - - // private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) - // { - // return new - // { - // resource = new - // { - // header = CRMReportResource.WorkloadByInvoicesReport, - // sheetName = CRMReportResource.WorkloadByInvoicesReport, - // dateRangeLabel = CRMReportResource.TimePeriod + ":", - // dateRangeValue = GetTimePeriodText(timePeriod), - - // chartName = CRMReportResource.BilledInvoices, - // chartName1 = CRMInvoiceResource.Invoices, - - // header1 = CRMInvoiceResource.Invoices, - - // manager = CRMReportResource.Manager, - // total = CRMReportResource.Total, - - // billed = CRMReportResource.Billed, - // paid = CRMReportResource.Paid, - // rejected = CRMReportResource.Rejected, - // overdue = CRMReportResource.Overdue - // }, - // data = reportData - // }; - // } - - // #endregion - - - // #region GetWorkloadByViopReport - - // public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // return Query(CRMDbContext.VoipCalls) - // .Where(x => x.ParentCallId == "") - // .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) - // .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? - // true : - // x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) - // .Any(); - // } - - // public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) - // { - // var reportData = BuildWorkloadByViopReport(timePeriod, managers); - - // return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); - // } - - // private List BuildWorkloadByViopReport(ReportTimePeriod timePeriod, Guid[] managers) - // { - // DateTime fromDate; - // DateTime toDate; - - // GetTimePeriod(timePeriod, out fromDate, out toDate); - - // var sqlQuery = Query("crm_voip_calls c") - // .Select("c.answered_by", - // "concat(u.firstname, ' ', u.lastname) as full_name", - // "c.status", - // "count(c.id) as calls_count", - // "sum(c.dial_duration) as duration") - // .LeftOuterJoin("core_user u", Exp.EqColumns("u.tenant", "c.tenant_id") & Exp.EqColumns("u.id", "c.answered_by")) - // .Where(Exp.EqColumns("c.parent_call_id", "''")) - // .Where(managers != null && managers.Any() ? Exp.In("c.answered_by", managers) : Exp.Empty) - // .Where(timePeriod == ReportTimePeriod.DuringAllTime ? - // Exp.Empty : - // Exp.Between("c.dial_date", _tenantUtil.DateTimeToUtc(fromDate), _tenantUtil.DateTimeToUtc(toDate))) - // .GroupBy("c.answered_by", "c.status"); - - - // return Db.ExecuteList(sqlQuery).ConvertAll(ToWorkloadByViop); - // } - - // private WorkloadByViop ToWorkloadByViop(object[] row) - // { - // return new WorkloadByViop - // { - // UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), - // UserName = Convert.ToString(row[1] ?? string.Empty), - // Status = (VoipCallStatus)Convert.ToInt32(row[2] ?? 0), - // Count = Convert.ToInt32(row[3]), - // Duration = Convert.ToInt32(row[4]) - // }; - // } + public object GetSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildSalesFunnelReport(timePeriod, managers, defaultCurrency); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var result = Query(CRMDbContext.DealMilestones) + .GroupJoin(Query(CRMDbContext.Deals), + x => x.Id, + y => y.DealMilestoneId, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = y, DealMilestone = x.x }) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.Deal.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, DealMilestone = x.x.DealMilestone, CurrencyRate = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.Open) + .GroupBy(x => new { x.DealMilestone.Id, x.DealMilestone.Title, x.DealMilestone.Status }) + .Select(x => new + { + status = x.Key.Status, + title = x.Key.Title, + deals_count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)), + deals_duration = x.Average(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon ? (x.Deal.ActualCloseDate - x.Deal.CreateOn).Value.Days : 0) + }) + .ToList() + .ConvertAll(x => + new SalesFunnel + { + Status = x.status, + Title = x.title, + Count = x.deals_count, + Value = x.deals_value, + Duration = Convert.ToInt32(x.deals_duration) + }); + + return result; + } + + private object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + var totalCount = data.Sum(x => x.Count); + + if (totalCount == 0) return null; + + var totalBudget = data.Sum(x => x.Value); + + var closed = data.Where(x => x.Status == DealMilestoneStatus.ClosedAndWon).ToList(); + + var reportData = data.Select(item => new List + { + item.Title, + item.Status, + item.Count, + item.Value + }).ToList(); + + return new + { + resource = new + { + header = CRMReportResource.SalesFunnelReport, + sheetName = CRMReportResource.SalesFunnelReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.SalesFunnelByCount, + chartName1 = CRMReportResource.SalesFunnelByBudget + ", " + _defaultCurrency.Symbol, + chartName2 = CRMReportResource.DealsCount, + chartName3 = CRMReportResource.DealsBudget + ", " + _defaultCurrency.Symbol, + + totalCountLabel = CRMReportResource.TotalDealsCount, + totalCountValue = totalCount, + + totalBudgetLabel = CRMReportResource.TotalDealsBudget + ", " + _defaultCurrency.Symbol, + totalBudgetValue = totalBudget, + + averageBidLabel = CRMReportResource.AverageDealsBudget + ", " + _defaultCurrency.Symbol, + averageBidValue = totalBudget / totalCount, + + averageDurationLabel = CRMReportResource.AverageDealsDuration, + averageDurationValue = closed.Sum(x => x.Duration) / closed.Count, + + header1 = CRMReportResource.ByCount, + header2 = CRMReportResource.ByBudget + ", " + _defaultCurrency.Symbol, + + stage = CRMReportResource.Stage, + count = CRMReportResource.Count, + budget = CRMReportResource.Budget, + conversion = CRMReportResource.Conversion, + + deals = CRMDealResource.Deals, + status0 = DealMilestoneStatus.Open.ToLocalizedString(), + status1 = DealMilestoneStatus.ClosedAndWon.ToLocalizedString(), + status2 = DealMilestoneStatus.ClosedAndLost.ToLocalizedString() + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByContactsReport + + public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + return Query(CRMDbContext.Contacts) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + } + + public object GetWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByContactsReport(timePeriod, managers); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildWorkloadByContactsReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var result = Query(CRMDbContext.Contacts) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.ContactTypeId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Contact = x.x, ListItem = y }) + .GroupJoin(Query(CRMDbContext.Deals), + x => x.Contact.Id, + y => y.ContactId, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Contact = x.x.Contact, ListItem = x.x.ListItem, Deal = y }) + .Where(x => x.ListItem.ListType == ListType.ContactType) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Contact.CreateBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Contact.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Contact.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => new { x.Contact.CreateBy, x.ListItem.Id, x.ListItem.Title }) + .Select(x => new + { + create_by = x.Key.CreateBy, + id = x.Key.Id, + title = x.Key.Title, + total = x.Count(x => x.Contact.Id > 0), + with_deals = x.Count(x => x.Deal.Id > 0) + }) + .OrderBy(x => x.title) + .ToList() + .ConvertAll(x => new WorkloadByContacts + { + UserId = x.create_by, + UserName = _displayUserSettings.GetFullUserName(x.create_by), + CategoryId = x.id, + CategoryName = x.title, + Count = x.total, + WithDeals = x.with_deals + }); + + // .OrderBy("i.sort_order, i.title", true); + + return result; + } + + private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + { + return new + { + resource = new + { + header = CRMReportResource.WorkloadByContactsReport, + sheetName = CRMReportResource.WorkloadByContactsReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + header1 = CRMReportResource.NewContacts, + header2 = CRMReportResource.NewContactsWithAndWithoutDeals, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, + + noSet = CRMCommonResource.NoSet, + withDeals = CRMReportResource.ContactsWithDeals, + withouthDeals = CRMReportResource.ContactsWithoutDeals, + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByTasksReport + + public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + + var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.IsClosed) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + + + + var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => x.IsClosed) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => (!x.IsClosed && x.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + (x.IsClosed && x.LastModifedOn > x.Deadline)) + .Any(); + + return sqlNewTasksQuery || + sqlClosedTasksQuery || + sqlOverdueTasksQuery; + } + + public object GetWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByTasksReport(timePeriod, managers); + + if (reportData == null || !reportData.Any()) return null; + + var hasData = reportData.Any(item => item.Value.Count > 0); + + return hasData ? GenerateReportData(timePeriod, reportData) : null; + } + + private Dictionary> BuildWorkloadByTasksReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.CategoryId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Task = x.x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.TaskCategory) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) + .OrderBy(x => x.ListItem.SortOrder) + .GroupBy(x => new { x.ListItem.Id, x.ListItem.Title, x.Task.ResponsibleId }) + .Select(x => new + { + id = x.Key.Id, + title = x.Key.Title, + responsibleId = x.Key.ResponsibleId, + count = x.Count() + }) + .ToList() + .ConvertAll(x => new WorkloadByTasks + { + CategoryId = x.id, + CategoryName = x.title, + UserId = x.responsibleId, + UserName = _displayUserSettings.GetFullUserName(x.responsibleId), + Count = x.count + }); + + var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.CategoryId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Task = x.x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.TaskCategory) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => x.Task.IsClosed) + .OrderBy(x => x.ListItem.SortOrder) + .GroupBy(x => new { x.ListItem.Id, x.ListItem.Title, x.Task.ResponsibleId }) + .Select(x => new + { + id = x.Key.Id, + title = x.Key.Title, + responsibleId = x.Key.ResponsibleId, + count = x.Count() + }) + .ToList() + .ConvertAll(x => new WorkloadByTasks + { + CategoryId = x.id, + CategoryName = x.title, + UserId = x.responsibleId, + UserName = _displayUserSettings.GetFullUserName(x.responsibleId), + Count = x.count + }); + + var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) + .GroupJoin(Query(CRMDbContext.ListItem), + x => x.CategoryId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Task = x.x, ListItem = y }) + .Where(x => x.ListItem.ListType == ListType.TaskCategory) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Task.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.Deadline <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => (!x.Task.IsClosed && x.Task.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || (x.Task.IsClosed && x.Task.LastModifedOn > x.Task.Deadline)) + .OrderBy(x => x.ListItem.SortOrder) + .GroupBy(x => new { x.ListItem.Id, x.ListItem.Title, x.Task.ResponsibleId }) + .Select(x => new + { + id = x.Key.Id, + title = x.Key.Title, + responsibleId = x.Key.ResponsibleId, + count = x.Count() + }) + .ToList() + .ConvertAll(x => new WorkloadByTasks + { + CategoryId = x.id, + CategoryName = x.title, + UserId = x.responsibleId, + UserName = _displayUserSettings.GetFullUserName(x.responsibleId), + Count = x.count + }); + + return new Dictionary> { + {"Created", sqlNewTasksQuery}, + {"Closed", sqlClosedTasksQuery}, + {"Overdue", sqlOverdueTasksQuery} + }; + } + + private object GenerateReportData(ReportTimePeriod timePeriod, Dictionary> reportData) + { + return new + { + resource = new + { + header = CRMReportResource.WorkloadByTasksReport, + sheetName = CRMReportResource.WorkloadByTasksReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + header1 = CRMReportResource.ClosedTasks, + header2 = CRMReportResource.NewTasks, + header3 = CRMReportResource.OverdueTasks, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByDealsReport + + public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + return Query(CRMDbContext.Deals) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) || + (x.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate))) + .Any(); + } + + public object GetWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + var reportData = BuildWorkloadByDealsReport(timePeriod, managers, defaultCurrency); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildWorkloadByDealsReport(ReportTimePeriod timePeriod, Guid[] managers, string defaultCurrency) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var result = Query(CRMDbContext.Deals) + .GroupJoin(Query(CRMDbContext.CurrencyRate), + x => x.BidCurrency, + y => y.FromCurrency, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) + .GroupJoin(Query(CRMDbContext.DealMilestones), + x => x.Deal.DealMilestoneId, + y => y.Id, + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) + .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.Deal.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.CreateOn <= _tenantUtil.DateTimeToUtc(toDate) || + x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate))) + .GroupBy(x => new { x.Deal.ResponsibleId, x.DealMilestone.Status }) + .Select(x => new + { + responsible_id = x.Key.ResponsibleId, + status = x.Key.Status, + count = x.Count(), + deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : + x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) + }).ToList() + .ConvertAll(x => new WorkloadByDeals + { + UserId = x.responsible_id, + UserName = _displayUserSettings.GetFullUserName(x.responsible_id), + Status = x.status, + Count = x.count, + Value = x.deals_value + }); + + return result; + } + + private object GenerateReportData(ReportTimePeriod timePeriod, List data) + { + var reportData = data.Select(item => new List + { + item.UserId, + item.UserName, + (int)item.Status, + item.Count, + item.Value + }).ToList(); + + return new + { + resource = new + { + header = CRMReportResource.WorkloadByDealsReport, + sheetName = CRMReportResource.WorkloadByDealsReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.DealsCount, + chartName1 = CRMReportResource.DealsBudget + ", " + _defaultCurrency.Symbol, + + header1 = CRMReportResource.ByCount, + header2 = CRMReportResource.ByBudget + ", " + _defaultCurrency.Symbol, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, + + status0 = CRMReportResource.New, + status1 = CRMReportResource.Won, + status2 = CRMReportResource.Lost + }, + data = reportData + }; + } + + #endregion + + + #region WorkloadByInvoicesReport + + public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + return Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= _tenantUtil.DateTimeToUtc(toDate))) || + (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate))) || + (x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate))) || + ((timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= _tenantUtil.DateTimeToUtc(toDate))) && + (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()) || x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) + .Any(); + } + + public object GetWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByInvoicesReport(timePeriod, managers); + + if (reportData == null || !reportData.Any()) return null; + + var hasData = reportData.Any(item => item.SentCount > 0 || item.PaidCount > 0 || item.RejectedCount > 0 || item.OverdueCount > 0); + + return hasData ? GenerateReportData(timePeriod, reportData) : null; + } + + private List BuildWorkloadByInvoicesReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var result = Query(CRMDbContext.Invoices) + .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) + .GroupBy(x => x.CreateBy) + .Select(x => new + { + createBy = x.Key, + sent = x.Sum(x => x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= _tenantUtil.DateTimeToUtc(toDate)) ? 1 : 0), + paid = x.Sum(x => x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) ? 1 : 0), + rejected = x.Sum(x => x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) ? 1 : 0), + overdue = x.Sum(x => (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DueDate <= _tenantUtil.DateTimeToUtc(toDate)) && ((x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || (x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate)) ? 1 : 0) + }) + .ToList() + .ConvertAll(x => new WorkloadByInvoices + { + UserId = x.createBy, + UserName = _displayUserSettings.GetFullUserName(x.createBy), + SentCount = x.sent, + PaidCount = x.paid, + RejectedCount = x.rejected, + OverdueCount = x.overdue + }); + + return result; + } + + + private object GenerateReportData(ReportTimePeriod timePeriod, List reportData) + { + return new + { + resource = new + { + header = CRMReportResource.WorkloadByInvoicesReport, + sheetName = CRMReportResource.WorkloadByInvoicesReport, + dateRangeLabel = CRMReportResource.TimePeriod + ":", + dateRangeValue = GetTimePeriodText(timePeriod), + + chartName = CRMReportResource.BilledInvoices, + chartName1 = CRMInvoiceResource.Invoices, + + header1 = CRMInvoiceResource.Invoices, + + manager = CRMReportResource.Manager, + total = CRMReportResource.Total, + + billed = CRMReportResource.Billed, + paid = CRMReportResource.Paid, + rejected = CRMReportResource.Rejected, + overdue = CRMReportResource.Overdue + }, + data = reportData + }; + } + + #endregion + + + #region GetWorkloadByViopReport + + public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + return Query(CRMDbContext.VoipCalls) + .Where(x => x.ParentCallId == "") + .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? + true : + x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) + .Any(); + } + + public object GetWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] managers) + { + var reportData = BuildWorkloadByViopReport(timePeriod, managers); + + return reportData == null || !reportData.Any() ? null : GenerateReportData(timePeriod, reportData); + } + + private List BuildWorkloadByViopReport(ReportTimePeriod timePeriod, Guid[] managers) + { + DateTime fromDate; + DateTime toDate; + + GetTimePeriod(timePeriod, out fromDate, out toDate); + + var result = Query(CRMDbContext.VoipCalls) + .Where(x => x.ParentCallId == "") + .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) + .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) + .GroupBy(x => new { x.AnsweredBy, x.Status }) + .Select(x => new + { + answered_by = x.Key.AnsweredBy, + status = x.Key.Status, + calls_count = x.Count(), + duration = x.Sum(x => x.DialDuration) + }) + .ToList() + .ConvertAll(x => new WorkloadByViop + { + UserId = x.answered_by, + UserName = _displayUserSettings.GetFullUserName(x.answered_by), + Status = x.status, + Count = x.calls_count, + Duration = x.duration ?? x.duration.Value + }); + + return result; + } + + private WorkloadByViop ToWorkloadByViop(object[] row) + { + return new WorkloadByViop + { + UserId = string.IsNullOrEmpty(Convert.ToString(row[0])) ? Guid.Empty : new Guid(Convert.ToString(row[0])), + UserName = Convert.ToString(row[1] ?? string.Empty), + Status = (VoipCallStatus)Convert.ToInt32(row[2] ?? 0), + Count = Convert.ToInt32(row[3]), + Duration = Convert.ToInt32(row[4]) + }; + } private object GenerateReportData(ReportTimePeriod timePeriod, List data) { @@ -1865,8 +1870,8 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ .GroupJoin(Query(CRMDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, - (x, y) => new { x,y }) - .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) + (x, y) => new { x, y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon) @@ -1928,13 +1933,14 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .GroupBy(x => x.Status) - .Select(x => new { - sent = x.Sum(x => x.Status != InvoiceStatus.Draft ? 1 :0), - paid = x.Sum(x => x.Status == InvoiceStatus.Paid ? 1 : 0), - rejected = x.Sum(x => x.Status == InvoiceStatus.Rejected ? 1 : 0), - overdue = x.Sum(x => (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || - (x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate) - ? 1 : 0) + .Select(x => new + { + sent = x.Sum(x => x.Status != InvoiceStatus.Draft ? 1 : 0), + paid = x.Sum(x => x.Status == InvoiceStatus.Paid ? 1 : 0), + rejected = x.Sum(x => x.Status == InvoiceStatus.Rejected ? 1 : 0), + overdue = x.Sum(x => (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || + (x.Status == InvoiceStatus.Paid && x.LastModifedOn > x.DueDate) + ? 1 : 0) }).ToList(); var contactsSqlQuery = Query(CRMDbContext.Contacts) @@ -1942,7 +1948,7 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ x => x.ContactTypeId, y => y.Id, (x, y) => new { x, y }) - .SelectMany(x => x.y.DefaultIfEmpty(), (x,y) => new { Contact = x.x, ListItem = y }) + .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Contact = x.x, ListItem = y }) .Where(x => x.ListItem.ListType == ListType.ContactType) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Contact.CreateBy) : true) .Where(x => x.Contact.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Contact.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) @@ -1956,10 +1962,10 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ .ToList(); var tasksSqlQuery = Query(CRMDbContext.Tasks) - .GroupJoin(Query(CRMDbContext.ListItem), + .GroupJoin(Query(CRMDbContext.ListItem), x => x.CategoryId, y => y.Id, - (x,y) => new { x,y }) + (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Task = x.x, ListItem = y }) .Where(x => x.ListItem.ListType == ListType.TaskCategory) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Task.ResponsibleId) : true) @@ -1970,19 +1976,20 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ title = x.Key.Title, sum1 = x.Sum(x => x.Task.IsClosed && x.Task.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.Task.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate) ? 1 : 0), - sum2 = x.Sum(x => (!x.Task.IsClosed && x.Task.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || (x.Task.IsClosed && x.Task.LastModifedOn > x.Task.Deadline) ? 1 :0), + sum2 = x.Sum(x => (!x.Task.IsClosed && x.Task.Deadline < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) || (x.Task.IsClosed && x.Task.LastModifedOn > x.Task.Deadline) ? 1 : 0), count = x.Count() }) .OrderBy(x => x.title) .ToList(); -// .OrderBy("i.sort_order, i.title", true); + // .OrderBy("i.sort_order, i.title", true); var voipSqlQuery = Query(CRMDbContext.VoipCalls) .Where(x => String.IsNullOrEmpty(x.ParentCallId)) .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) .Where(x => x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) .GroupBy(x => x.Status) - .Select(x => new { + .Select(x => new + { status = x.Key, calls_count = x.Count(), duration = x.Sum(x => x.DialDuration) @@ -2267,7 +2274,8 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .GroupBy(x => x.Status) - .Select(x => new { + .Select(x => new + { sent = x.Sum(x => x.Status == InvoiceStatus.Sent ? 1 : 0), overdue = x.Sum(x => (x.Status == InvoiceStatus.Sent && x.DueDate < _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow())) ? 1 : 0) }).ToList(); diff --git a/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs b/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs index aaaafb3d389..70764feb123 100644 --- a/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs +++ b/products/ASC.CRM/Server/Core/EF/DbVoipCalls.cs @@ -4,6 +4,8 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using ASC.VoipService; + namespace ASC.CRM.Core.EF { [Table("crm_voip_calls")] @@ -22,7 +24,7 @@ public partial class DbVoipCalls : IDbCrm [Column("number_to", TypeName = "varchar(50)")] public string NumberTo { get; set; } [Column("status", TypeName = "int(10)")] - public int? Status { get; set; } + public VoipCallStatus Status { get; set; } [Required] [Column("answered_by", TypeName = "varchar(50)")] public Guid AnsweredBy { get; set; } diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index 7181d54795e..d808893baf9 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -189,18 +189,18 @@ private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, return reportDao.GetSalesByManagersReportData(timePeriod, managers, defaultCurrency); case ReportType.SalesForecast: return reportDao.GetSalesForecastReportData(timePeriod, managers, defaultCurrency); - //case ReportType.SalesFunnel: - // return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); - //case ReportType.WorkloadByContacts: - // return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); - //case ReportType.WorkloadByTasks: - // return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); - //case ReportType.WorkloadByDeals: - // return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); - //case ReportType.WorkloadByInvoices: - // return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); - //case ReportType.WorkloadByVoip: - // return reportDao.GetWorkloadByViopReportData(timePeriod, managers); + case ReportType.SalesFunnel: + return reportDao.GetSalesFunnelReportData(timePeriod, managers, defaultCurrency); + case ReportType.WorkloadByContacts: + return reportDao.GetWorkloadByContactsReportData(timePeriod, managers); + case ReportType.WorkloadByTasks: + return reportDao.GetWorkloadByTasksReportData(timePeriod, managers); + case ReportType.WorkloadByDeals: + return reportDao.GetWorkloadByDealsReportData(timePeriod, managers, defaultCurrency); + case ReportType.WorkloadByInvoices: + return reportDao.GetWorkloadByInvoicesReportData(timePeriod, managers); + case ReportType.WorkloadByVoip: + return reportDao.GetWorkloadByViopReportData(timePeriod, managers); case ReportType.SummaryForThePeriod: return reportDao.GetSummaryForThePeriodReportData(timePeriod, managers, defaultCurrency); case ReportType.SummaryAtThisMoment: From 393ada80fc66bb97972c7745e5e70e5799f1a09c Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 31 Mar 2021 19:21:54 +0300 Subject: [PATCH 38/61] crm: bugfix --- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 48 ++++---------------- 1 file changed, 10 insertions(+), 38 deletions(-) diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index d25f9f39623..0ac69874969 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -594,26 +594,11 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String ); }); - var customFieldEntity = new Dictionary>(); + var customFieldEntity = (contacts.Where(x => x is Company).Any() ? customFieldDao.GetEnityFields(EntityType.Company, contacts.Where(x => x is Company).Select(x => x.ID).ToArray()) : new List()) + .Union(contacts.Where(x => x is Person).Any() ? customFieldDao.GetEnityFields(EntityType.Person, contacts.Where(x => x is Person).Select(x => x.ID).ToArray()) : new List()) + .GroupBy(x => x.EntityID) + .ToDictionary(x => x.Key, x => x.ToList()); - var entityFields = customFieldDao.GetEnityFields(EntityType.Company, 0, false); - - customFieldDao.GetEnityFields(EntityType.Person, 0, false).ForEach(item => - { - var alreadyContains = entityFields.Any(field => field.ID == item.ID && field.EntityID == item.EntityID); - - if (!alreadyContains) - entityFields.Add(item); - }); - - entityFields.ForEach( - item => - { - if (!customFieldEntity.ContainsKey(item.EntityID)) - customFieldEntity.Add(item.EntityID, new List { item }); - else - customFieldEntity[item.EntityID].Add(item); - }); var tags = tagDao.GetEntitiesTags(EntityType.Contact); @@ -844,16 +829,10 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) }); }); - var customFieldEntity = new Dictionary>(); + var customFieldEntity = customFieldDao.GetEnityFields(EntityType.Opportunity, deals.Select(x => x.ID).ToArray()) + .GroupBy(x => x.EntityID) + .ToDictionary(x => x.Key, x => x.ToList()); - customFieldDao.GetEnityFields(EntityType.Opportunity, 0, false).ForEach( - item => - { - if (!customFieldEntity.ContainsKey(item.EntityID)) - customFieldEntity.Add(item.EntityID, new List { item }); - else - customFieldEntity[item.EntityID].Add(item); - }); var tags = tagDao.GetEntitiesTags(EntityType.Opportunity); @@ -969,16 +948,9 @@ private String ExportCasesToCsv(IEnumerable cases, }); }); - var customFieldEntity = new Dictionary>(); - - customFieldDao.GetEnityFields(EntityType.Case, 0, false).ForEach( - item => - { - if (!customFieldEntity.ContainsKey(item.EntityID)) - customFieldEntity.Add(item.EntityID, new List { item }); - else - customFieldEntity[item.EntityID].Add(item); - }); + var customFieldEntity = customFieldDao.GetEnityFields(EntityType.Case, cases.Select(x => x.ID).ToArray()) + .GroupBy(x => x.EntityID) + .ToDictionary(x => x.Key, x => x.ToList()); var tags = tagDao.GetEntitiesTags(EntityType.Case); From 8ff27ff1be36c89692276d06ec61fd4939d13da7 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 2 Apr 2021 18:46:00 +0300 Subject: [PATCH 39/61] added ControllerNameAttributeConvention --- .../ControllerNameAttributeConvention.cs | 2 -- common/ASC.Api.Core/Core/BaseStartup.cs | 18 +++++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs b/common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs index af35112c35c..65af908c8b7 100644 --- a/common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs +++ b/common/ASC.Api.Core/Convention/ControllerNameAttributeConvention.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ApplicationModels; diff --git a/common/ASC.Api.Core/Core/BaseStartup.cs b/common/ASC.Api.Core/Core/BaseStartup.cs index 1146255bfa9..7e257b224ca 100644 --- a/common/ASC.Api.Core/Core/BaseStartup.cs +++ b/common/ASC.Api.Core/Core/BaseStartup.cs @@ -1,6 +1,7 @@ using System.Text.Json.Serialization; using ASC.Api.Core.Auth; +using ASC.Api.Core.Convention; using ASC.Api.Core.Core; using ASC.Api.Core.Middleware; using ASC.Common; @@ -81,13 +82,16 @@ public virtual void ConfigureServices(IServiceCollection services) DIHelper.RegisterProducts(Configuration, HostEnvironment.ContentRootPath); var builder = services.AddMvcCore(config => - { - var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); - config.Filters.Add(new AuthorizeFilter(policy)); - config.Filters.Add(new TypeFilterAttribute(typeof(TenantStatusFilter))); - config.Filters.Add(new TypeFilterAttribute(typeof(PaymentFilter))); - config.Filters.Add(new TypeFilterAttribute(typeof(IpSecurityFilter))); - config.Filters.Add(new TypeFilterAttribute(typeof(ProductSecurityFilter))); + { + config.Conventions.Add(new ControllerNameAttributeConvention()); + + var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build(); + + config.Filters.Add(new AuthorizeFilter(policy)); + config.Filters.Add(new TypeFilterAttribute(typeof(TenantStatusFilter))); + config.Filters.Add(new TypeFilterAttribute(typeof(PaymentFilter))); + config.Filters.Add(new TypeFilterAttribute(typeof(IpSecurityFilter))); + config.Filters.Add(new TypeFilterAttribute(typeof(ProductSecurityFilter))); config.Filters.Add(new CustomResponseFilterAttribute()); config.Filters.Add(new CustomExceptionFilterAttribute()); config.Filters.Add(new TypeFilterAttribute(typeof(FormatFilter))); From 748ae7e343233c4c5e50da455e5268d5954ffcb5 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 2 Apr 2021 18:53:49 +0300 Subject: [PATCH 40/61] crm: bugfix --- products/ASC.CRM/Server/Core/Entities/CustomField.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/ASC.CRM/Server/Core/Entities/CustomField.cs b/products/ASC.CRM/Server/Core/Entities/CustomField.cs index d989d80e3c8..1f3b1a1fc81 100644 --- a/products/ASC.CRM/Server/Core/Entities/CustomField.cs +++ b/products/ASC.CRM/Server/Core/Entities/CustomField.cs @@ -62,7 +62,7 @@ public class CustomField : DomainObject public override int GetHashCode() { - return string.Format("{0}|{1}|{2}", GetType().FullName, Label, (int)FieldType).GetHashCode(); + return string.Format("{0}|{1}|{2}|{3}|{4}", GetType().FullName, ID, EntityID, Label, (int)FieldType).GetHashCode(); } } } From 635d20580f55a720694d4c1ce141822e5991330b Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 6 Apr 2021 20:33:28 +0300 Subject: [PATCH 41/61] crm: refactoring --- .../ASC.CRM/Server/Api/BaseApiController.cs | 4 +- .../Server/Api/ContactInfosController.cs | 4 +- .../ASC.CRM/Server/Api/ListItemsController.cs | 70 ++-- .../Api/RelationshipEventsController.cs | 330 +++++++++--------- .../ASC.CRM/Server/Api/ReportsController.cs | 4 +- products/ASC.CRM/Server/Api/TagsController.cs | 4 +- .../ASC.CRM/Server/Api/TasksController.cs | 4 +- .../ASC.CRM/Server/Api/UtilsController.cs | 4 +- products/ASC.CRM/Server/Api/VoipController.cs | 4 +- .../RequestsDto/AddHistoryToRequestDto.cs | 21 ++ .../RequestsDto/UploadFileInCRMRequestDto.cs | 22 ++ .../ApiModels/ResponsesDto/InvoiceTaxDto.cs | 2 +- .../ApiModels/ResponsesDto/ListItemDto.cs | 14 +- products/ASC.CRM/Server/Classes/Global.cs | 4 +- .../Server/Classes/TwilioController.cs | 4 +- products/ASC.CRM/Server/Classes/VoipEngine.cs | 4 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 8 +- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 8 +- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 8 +- .../Server/Core/Dao/RelationshipEventDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 4 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 8 +- .../Core/Security/FileSecurityProvider.cs | 8 +- .../HttpHandlers/ContactPhotoHandler.cs | 8 +- .../Server/HttpHandlers/ImportFileHandler.cs | 4 +- .../HttpHandlers/OrganisationLogoHandler.cs | 6 +- .../HttpHandlers/WebToLeadFromHandler.cs | 4 +- .../TypeConverter/CasesDtoTypeConverter.cs | 4 +- .../DealMilestoneDtoTypeConverter.cs | 57 +++ .../InvoiceBaseDtoTypeConverter.cs | 4 +- ...erter.cs => InvoiceTaxDtoTypeConverter.cs} | 14 +- .../TypeConverter/ListItemDtoTypeConverter.cs | 49 ++- .../OpportunityDtoTypeConverter.cs | 4 +- .../RelationshipEventDtoTypeConverter.cs | 5 +- .../TypeConverter/TaskDtoTypeConverter.cs | 2 +- .../Services/NotifyService/NotifyClient.cs | 194 +++++----- products/ASC.CRM/Server/Startup.cs | 2 +- .../Utils/Import/CSV/ImportDataOperation.cs | 4 +- 39 files changed, 532 insertions(+), 388 deletions(-) create mode 100644 products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs create mode 100644 products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs create mode 100644 products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs rename products/ASC.CRM/Server/Mapping/TypeConverter/{InvoiceTaxTypeConverter.cs => InvoiceTaxDtoTypeConverter.cs} (85%) diff --git a/products/ASC.CRM/Server/Api/BaseApiController.cs b/products/ASC.CRM/Server/Api/BaseApiController.cs index 7eb43680df8..38a9d8a9263 100644 --- a/products/ASC.CRM/Server/Api/BaseApiController.cs +++ b/products/ASC.CRM/Server/Api/BaseApiController.cs @@ -51,11 +51,11 @@ public abstract class BaseApiController : ControllerBase protected CRMSecurity _crmSecurity; public BaseApiController(DaoFactory daoFactory, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, IMapper mapper) { _daoFactory = daoFactory; - _crmSecurity = cRMSecurity; + _crmSecurity = crmSecurity; _mapper = mapper; } diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index 27c713e7376..12b8a364353 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -53,12 +53,12 @@ public class ContactInfosController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public ContactInfosController(CRMSecurity cRMSecurity, + public ContactInfosController(CRMSecurity crmSecurity, DaoFactory daoFactory, MessageTarget messageTarget, MessageService messageService, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { _messageTarget = messageTarget; _messageService = messageService; diff --git a/products/ASC.CRM/Server/Api/ListItemsController.cs b/products/ASC.CRM/Server/Api/ListItemsController.cs index d19d7e8e5ce..812cc428e1a 100644 --- a/products/ASC.CRM/Server/Api/ListItemsController.cs +++ b/products/ASC.CRM/Server/Api/ListItemsController.cs @@ -49,12 +49,12 @@ public class ListItemsController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public ListItemsController(CRMSecurity cRMSecurity, + public ListItemsController(CRMSecurity crmSecurity, DaoFactory daoFactory, MessageTarget messageTarget, MessageService messageService, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { _messageTarget = messageTarget; _messageService = messageService; @@ -446,7 +446,7 @@ public TaskCategoryDto CreateTaskCategory( listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.TaskCategory, listItem); _messageService.Send(MessageAction.CrmTaskCategoryCreated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToTaskCategoryDto(listItem); + return _mapper.Map(listItem); } /// @@ -488,7 +488,7 @@ public TaskCategoryDto UpdateTaskCategory(int id, string title, string descripti _daoFactory.GetListItemDao().EditItem(ListType.TaskCategory, listItem); _messageService.Send(MessageAction.CrmTaskCategoryUpdated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToTaskCategoryDto(listItem); + return _mapper.Map(listItem); } /// @@ -518,7 +518,7 @@ public TaskCategoryDto UpdateTaskCategoryIcon(int id, string imageName) _daoFactory.GetListItemDao().ChangePicture(id, imageName); _messageService.Send(MessageAction.CrmTaskCategoryUpdatedIcon, _messageTarget.Create(taskCategory.ID), taskCategory.Title); - return ToTaskCategoryDto(taskCategory); + return _mapper.Map(taskCategory); } /// @@ -545,9 +545,10 @@ public IEnumerable UpdateTaskCategoriesOrder(IEnumerable _daoFactory.GetListItemDao().GetByTitle(ListType.TaskCategory, title)).ToList(); _daoFactory.GetListItemDao().ReorderItems(ListType.TaskCategory, titles.ToArray()); + _messageService.Send(MessageAction.CrmTaskCategoriesUpdatedOrder, _messageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToTaskCategoryDto); + return _mapper.Map, List>(result); } /// @@ -579,7 +580,7 @@ public TaskCategoryDto DeleteTaskCategory(int categoryid, int newcategoryid) dao.DeleteItem(ListType.TaskCategory, categoryid, newcategoryid); _messageService.Send(MessageAction.CrmTaskCategoryDeleted, _messageTarget.Create(listItem.ID), listItem.Title); - return ToTaskCategoryDto(listItem); + return _mapper.Map(listItem); } /// @@ -616,7 +617,7 @@ public ContactStatusDto CreateContactStatus( listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.ContactStatus, listItem); _messageService.Send(MessageAction.ContactTemperatureLevelCreated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToContactStatusDto(listItem); + return _mapper.Map(listItem); } /// @@ -658,7 +659,7 @@ public ContactStatusDto UpdateContactStatus(int id, string title, string descrip _daoFactory.GetListItemDao().EditItem(ListType.ContactStatus, listItem); _messageService.Send(MessageAction.ContactTemperatureLevelUpdated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToContactStatusDto(listItem); + return _mapper.Map(listItem); } /// @@ -688,7 +689,7 @@ public ContactStatusDto UpdateContactStatusColor(int id, string color) _daoFactory.GetListItemDao().ChangeColor(id, color); _messageService.Send(MessageAction.ContactTemperatureLevelUpdatedColor, _messageTarget.Create(contactStatus.ID), contactStatus.Title); - return ToContactStatusDto(contactStatus); + return _mapper.Map(contactStatus); } /// @@ -717,7 +718,7 @@ public IEnumerable UpdateContactStatusesOrder(IEnumerable x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToContactStatusDto); + return _mapper.Map,List>(result); } /// @@ -748,7 +749,7 @@ public ContactStatusDto DeleteContactStatus(int contactStatusid) throw new ArgumentException("The last contact status cannot be deleted"); } - var contactStatus = ToContactStatusDto(listItem); + var contactStatus = _mapper.Map(listItem); dao.DeleteItem(ListType.ContactStatus, contactStatusid, 0); _messageService.Send(MessageAction.ContactTemperatureLevelDeleted, _messageTarget.Create(contactStatus.Id), contactStatus.Title); @@ -773,7 +774,7 @@ public ContactStatusDto GetContactStatusByID(int contactStatusid) var listItem = _daoFactory.GetListItemDao().GetByID(contactStatusid); if (listItem == null) throw new ItemNotFoundException(); - return ToContactStatusDto(listItem); + return _mapper.Map(listItem); } /// @@ -803,7 +804,7 @@ public ContactTypeDto CreateContactType([FromForm] string title, [FromForm] int listItem.ID = _daoFactory.GetListItemDao().CreateItem(ListType.ContactType, listItem); _messageService.Send(MessageAction.ContactTypeCreated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToContactTypeDto(listItem); + return _mapper.Map(listItem); } /// @@ -841,7 +842,7 @@ public ContactTypeDto UpdateContactType(int id, string title, int sortOrder) _daoFactory.GetListItemDao().EditItem(ListType.ContactType, listItem); _messageService.Send(MessageAction.ContactTypeUpdated, _messageTarget.Create(listItem.ID), listItem.Title); - return ToContactTypeDto(listItem); + return _mapper.Map(listItem); } /// @@ -870,7 +871,7 @@ public IEnumerable UpdateContactTypesOrder(IEnumerable t _daoFactory.GetListItemDao().ReorderItems(ListType.ContactType, titles.ToArray()); _messageService.Send(MessageAction.ContactTypesUpdatedOrder, _messageTarget.Create(result.Select(x => x.ID)), result.Select(x => x.Title)); - return result.ConvertAll(ToContactTypeDto); + return _mapper.Map, List>(result); } /// @@ -901,7 +902,7 @@ public ContactTypeDto DeleteContactType(int contactTypeid) throw new ArgumentException("The last contact type cannot be deleted"); } - var contactType = ToContactTypeDto(listItem); + var contactType = _mapper.Map(listItem); dao.DeleteItem(ListType.ContactType, contactTypeid, 0); _messageService.Send(MessageAction.ContactTypeDeleted, _messageTarget.Create(listItem.ID), listItem.Title); @@ -926,7 +927,7 @@ public ContactTypeDto GetContactTypeByID(int contactTypeid) var listItem = _daoFactory.GetListItemDao().GetByID(contactTypeid); if (listItem == null) throw new ItemNotFoundException(); - return ToContactTypeDto(listItem); + return _mapper.Map(listItem); } /// @@ -966,7 +967,7 @@ public TaskCategoryDto GetTaskCategoryByID(int categoryid) var listItem = _daoFactory.GetListItemDao().GetByID(categoryid); if (listItem == null) throw new ItemNotFoundException(); - return ToTaskCategoryDto(listItem); + return _mapper.Map(listItem); } /// @@ -1085,36 +1086,7 @@ public IEnumerable GetDealMilestones() return result; } - - public ContactStatusDto ToContactStatusDto(ListItem listItem) - { - var result = new ContactStatusDto(listItem) - { - RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, listItem.ID) - }; - - return result; - } - - public ContactTypeDto ToContactTypeDto(ListItem listItem) - { - var result = new ContactTypeDto(listItem) - { - RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, listItem.ID) - }; - - return result; - } - - public TaskCategoryDto ToTaskCategoryDto(ListItem listItem) - { - var result = (TaskCategoryDto)_mapper.Map(listItem); - - result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, listItem.ID); - - return result; - } - + private DealMilestoneDto ToDealMilestoneDto(DealMilestone dealMilestone) { var result = new DealMilestoneDto(dealMilestone) diff --git a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs index 60063c5d6cf..be56f8b4fe3 100644 --- a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs +++ b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs @@ -25,9 +25,11 @@ using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Mime; using System.Text; using System.Text.RegularExpressions; @@ -35,6 +37,7 @@ using ASC.Api.CRM; using ASC.Api.Documents; using ASC.Common.Web; +using ASC.Core; using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Dao; @@ -42,10 +45,13 @@ using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Api.Routing; +using ASC.Web.CRM.Services.NotifyService; +using ASC.Web.Files.Classes; using ASC.Web.Files.Utils; using AutoMapper; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using OrderBy = ASC.CRM.Core.Entities.OrderBy; @@ -54,15 +60,18 @@ namespace ASC.CRM.Api { public class RelationshipEventsController : BaseApiController { - private readonly HistoryCategoryDto _historyCategoryDtoHelper; private readonly FileUploader _fileUploader; private readonly ASC.Files.Core.Data.DaoFactory _filesDaoFactory; private readonly FileWrapperHelper _fileWrapperHelper; + private readonly FilesSettingsHelper _filesSettingsHelper; private readonly ApiContext _apiContext; private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; + private readonly SecurityContext _securityContext; + private readonly NotifyClient _notifyClient; - public RelationshipEventsController(CRMSecurity cRMSecurity, + public RelationshipEventsController( + CRMSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, @@ -70,9 +79,11 @@ public RelationshipEventsController(CRMSecurity cRMSecurity, FileWrapperHelper fileWrapperHelper, ASC.Files.Core.Data.DaoFactory filesDaoFactory, FileUploader fileUploader, - HistoryCategoryDto historyCategoryDtoHelper, + SecurityContext securityContext, + NotifyClient notifyClient, + FilesSettingsHelper filesSettingsHelper, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { _apiContext = apiContext; _messageTarget = messageTarget; @@ -80,7 +91,9 @@ public RelationshipEventsController(CRMSecurity cRMSecurity, _fileWrapperHelper = fileWrapperHelper; _filesDaoFactory = filesDaoFactory; _fileUploader = fileUploader; - _historyCategoryDtoHelper = historyCategoryDtoHelper; + _securityContext = securityContext; + _notifyClient = notifyClient; + _filesSettingsHelper = filesSettingsHelper; } @@ -291,42 +304,42 @@ public FileWrapper CreateTextFile( /// /// File info /// - //[Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files/upload")] - //public FileWrapper UploadFileInCRM( - // string entityType, - // int entityid, - // Stream file, - // ContentType contentType, - // ContentDisposition contentDisposition, - // IEnumerable files, - // bool storeOriginalFileFlag - // ) - //{ - // FilesSettings.StoreOriginalFilesSetting = storeOriginalFileFlag; - - // var folderid = GetRootFolderID(); - - // var fileNames = new List(); - - // FileWrapper uploadedFile = null; - // if (files != null && files.Any()) - // { - // //For case with multiple files - // foreach (var postedFile in files) - // { - // using var fileStream = postedFile.OpenReadStream(); - // uploadedFile = SaveFile(folderid, fileStream, postedFile.FileName); - // fileNames.Add(uploadedFile.Title); - // } - // } - // else if (file != null) - // { - // uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); - // fileNames.Add(uploadedFile.Title); - // } - - // return uploadedFile; - //} + [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files/upload")] + public FileWrapper UploadFileInCRM([FromForm] UploadFileInCRMRequestDto inDto) + { + string entityType = inDto.EntityType; + int entityid = inDto.Entityid; + Stream file = inDto.File; + ContentType contentType = inDto.ContentType; + ContentDisposition contentDisposition = inDto.ContentDisposition; + IEnumerable files = inDto.Files; + bool storeOriginalFileFlag = inDto.StoreOriginalFileFlag; + + _filesSettingsHelper.StoreOriginalFiles = storeOriginalFileFlag; + + var folderid = GetRootFolderID(); + + var fileNames = new List(); + + FileWrapper uploadedFile = null; + if (files != null && files.Any()) + { + //For case with multiple files + foreach (var postedFile in files) + { + using var fileStream = postedFile.OpenReadStream(); + uploadedFile = SaveFile(folderid, fileStream, postedFile.FileName); + fileNames.Add(uploadedFile.Title); + } + } + else if (file != null) + { + uploadedFile = SaveFile(folderid, file, contentDisposition.FileName); + fileNames.Add(uploadedFile.Title); + } + + return uploadedFile; + } private FileWrapper SaveFile(int folderid, Stream file, string fileName) { @@ -358,122 +371,125 @@ private FileWrapper SaveFile(int folderid, Stream file, string fileName) /// /// Created event /// - //[Create(@"history")] - //public RelationshipEventDto AddHistoryTo( - // string entityType, - // int entityId, - // int contactId, - // string content, - // int categoryId, - // ApiDateTime created, - // IEnumerable fileId, - // IEnumerable notifyUserList) - //{ - // if (!string.IsNullOrEmpty(entityType) && - // !( - // string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || - // string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0) - // ) - // throw new ArgumentException(); - - // var entityTypeObj = ToEntityType(entityType); - - // var entityTitle = ""; - // if (contactId > 0) { - // var contact = DaoFactory.GetContactDao().GetByID(contactId); - // if (contact == null || !CRMSecurity.CanAccessTo(contact)) - // throw new ArgumentException(); - // entityTitle = contact.GetTitle(); - // } - - // if (entityTypeObj == EntityType.Case) { - // var cases = DaoFactory.GetCasesDao().GetByID(entityId); - // if (cases == null || !CRMSecurity.CanAccessTo(cases)) - // throw new ArgumentException(); - // if (contactId <= 0) - // { - // entityTitle = cases.Title; - // } - // } - // if (entityTypeObj == EntityType.Opportunity) - // { - // var deal = DaoFactory.GetDealDao().GetByID(entityId); - // if (deal == null || !CRMSecurity.CanAccessTo(deal)) - // throw new ArgumentException(); - // if (contactId <= 0) - // { - // entityTitle = deal.Title; - // } - // } - - // var relationshipEvent = new RelationshipEvent - // { - // CategoryID = categoryId, - // EntityType = entityTypeObj, - // EntityID = entityId, - // Content = content, - // ContactID = contactId, - // CreateOn = created, - // CreateBy = SecurityContext.CurrentAccount.ID - // }; - - // var category = DaoFactory.GetListItemDao().GetByID(categoryId); - // if (category == null) throw new ArgumentException(); - - // var item = DaoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent); - - - // notifyUserList = notifyUserList != null ? notifyUserList.ToList() : new List(); - // var needNotify = notifyUserList.Any(); - - // var fileListInfoHashtable = new Hashtable(); - - // if (fileId != null) - // { - // var fileIds = fileId.ToList(); - // var files = FilesDaoFactory.GetFileDao().GetFiles(fileIds.ToArray()); - - // if (needNotify) - // { - // foreach (var file in files) - // { - // var extension = Path.GetExtension(file.Title); - // if (extension == null) continue; - - // var fileInfo = string.Format("{0} ({1})", file.Title, extension.ToUpper()); - // if (!fileListInfoHashtable.ContainsKey(fileInfo)) - // { - // fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); - // } - // else - // { - // fileInfo = string.Format("{0} ({1}, {2})", file.Title, extension.ToUpper(), file.UniqID); - // fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); - // } - // } - // } - - // DaoFactory.GetRelationshipEventDao().AttachFiles(item.ID, fileIds.ToArray()); - - // if (files.Any()) - // { - // var fileAttachAction = GetFilesAttachAction(entityTypeObj, contactId); - // MessageService.Send( fileAttachAction, MessageTarget.Create(item.ID), entityTitle, files.Select(x => x.Title)); - // } - // } - - // if (needNotify) - // { - // NotifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, DaoFactory, notifyUserList.ToArray()); - // } - - // var wrapper = RelationshipEventDtoHelper.Get(item); - - // var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); - // MessageService.Send( historyCreatedAction, MessageTarget.Create(item.ID), entityTitle, category.Title); - - // return wrapper; - //} + [Create(@"history")] + public RelationshipEventDto AddHistoryTo([FromForm] AddHistoryToRequestDto inDto) + { + string entityType = inDto.EntityType; + int entityId = inDto.EntityId; + int contactId = inDto.ContactId; + string content = inDto.Content; + int categoryId = inDto.CategoryId; + ApiDateTime created = inDto.Created; + IEnumerable fileId = inDto.FileId; + IEnumerable notifyUserList = inDto.NotifyUserList; + + if (!string.IsNullOrEmpty(entityType) && + !( + string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 || + string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0) + ) + throw new ArgumentException(); + + var entityTypeObj = ToEntityType(entityType); + + var entityTitle = ""; + if (contactId > 0) + { + var contact = _daoFactory.GetContactDao().GetByID(contactId); + if (contact == null || !_crmSecurity.CanAccessTo(contact)) + throw new ArgumentException(); + entityTitle = contact.GetTitle(); + } + + if (entityTypeObj == EntityType.Case) + { + var cases = _daoFactory.GetCasesDao().GetByID(entityId); + if (cases == null || !_crmSecurity.CanAccessTo(cases)) + throw new ArgumentException(); + if (contactId <= 0) + { + entityTitle = cases.Title; + } + } + if (entityTypeObj == EntityType.Opportunity) + { + var deal = _daoFactory.GetDealDao().GetByID(entityId); + if (deal == null || !_crmSecurity.CanAccessTo(deal)) + throw new ArgumentException(); + if (contactId <= 0) + { + entityTitle = deal.Title; + } + } + + var relationshipEvent = new RelationshipEvent + { + CategoryID = categoryId, + EntityType = entityTypeObj, + EntityID = entityId, + Content = content, + ContactID = contactId, + CreateOn = created, + CreateBy = _securityContext.CurrentAccount.ID + }; + + var category = _daoFactory.GetListItemDao().GetByID(categoryId); + if (category == null) throw new ArgumentException(); + + var item = _daoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent); + + + notifyUserList = notifyUserList != null ? notifyUserList.ToList() : new List(); + var needNotify = notifyUserList.Any(); + + var fileListInfoHashtable = new Hashtable(); + + if (fileId != null) + { + var fileIds = fileId.ToList(); + var files = _filesDaoFactory.GetFileDao().GetFiles(fileIds.ToArray()); + + if (needNotify) + { + foreach (var file in files) + { + var extension = Path.GetExtension(file.Title); + if (extension == null) continue; + + var fileInfo = string.Format("{0} ({1})", file.Title, extension.ToUpper()); + if (!fileListInfoHashtable.ContainsKey(fileInfo)) + { + fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); + } + else + { + fileInfo = string.Format("{0} ({1}, {2})", file.Title, extension.ToUpper(), file.UniqID); + fileListInfoHashtable.Add(fileInfo, file.DownloadUrl); + } + } + } + + _daoFactory.GetRelationshipEventDao().AttachFiles(item.ID, fileIds.ToArray()); + + if (files.Any()) + { + var fileAttachAction = GetFilesAttachAction(entityTypeObj, contactId); + + _messageService.Send(fileAttachAction, _messageTarget.Create(item.ID), entityTitle, files.Select(x => x.Title)); + } + } + + if (needNotify) + { + _notifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, _daoFactory, notifyUserList.ToArray()); + } + + var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); + + _messageService.Send(historyCreatedAction, _messageTarget.Create(item.ID), entityTitle, category.Title); + + return _mapper.Map(item); + } /// /// Associates the selected file(s) with the entity with the ID or type specified in the request diff --git a/products/ASC.CRM/Server/Api/ReportsController.cs b/products/ASC.CRM/Server/Api/ReportsController.cs index ef3372c09a3..17da3265c4b 100644 --- a/products/ASC.CRM/Server/Api/ReportsController.cs +++ b/products/ASC.CRM/Server/Api/ReportsController.cs @@ -189,8 +189,8 @@ public object CheckReportData( [Create(@"report/generate")] public ReportState GenerateReport([FromForm] ReportType type, [FromForm] ReportTimePeriod timePeriod, [FromForm] Guid[] managers) { -// if (!_global.CanCreateReports) - // throw _crmSecurity.CreateSecurityException(); + if (!_global.CanCreateReports) + throw _crmSecurity.CreateSecurityException(); return _reportHelper.RunGenareteReport(type, timePeriod, managers); } diff --git a/products/ASC.CRM/Server/Api/TagsController.cs b/products/ASC.CRM/Server/Api/TagsController.cs index 217bacd6f7c..3b914e87943 100644 --- a/products/ASC.CRM/Server/Api/TagsController.cs +++ b/products/ASC.CRM/Server/Api/TagsController.cs @@ -52,13 +52,13 @@ public class TagsController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public TagsController(CRMSecurity cRMSecurity, + public TagsController(CRMSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { _apiContext = apiContext; _messageTarget = messageTarget; diff --git a/products/ASC.CRM/Server/Api/TasksController.cs b/products/ASC.CRM/Server/Api/TasksController.cs index 7c49c7daea9..8ce9c5cc333 100644 --- a/products/ASC.CRM/Server/Api/TasksController.cs +++ b/products/ASC.CRM/Server/Api/TasksController.cs @@ -28,14 +28,14 @@ public class TasksController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public TasksController(CRMSecurity cRMSecurity, + public TasksController(CRMSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { _apiContext = apiContext; _messageTarget = messageTarget; diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index e2382e36cb4..e5998c080d5 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -62,7 +62,7 @@ public class UtilsController : BaseApiController private readonly CurrencyProvider _currencyProvider; private readonly MessageService _messageService; - public UtilsController(CRMSecurity cRMSecurity, + public UtilsController(CRMSecurity crmSecurity, DaoFactory daoFactory, MessageService messageService, SettingsManager settingsManager, @@ -75,7 +75,7 @@ public UtilsController(CRMSecurity cRMSecurity, ImportFromCSV importFromCSV, ExportToCsv exportToCsv, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { _messageService = messageService; _currencyProvider = currencyProvider; diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index 4e073527495..186f67ab54e 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -72,7 +72,7 @@ public class VoIPController : BaseApiController private readonly ContactPhotoManager _contactPhotoManager; private readonly Global _global; - public VoIPController(CRMSecurity cRMSecurity, + public VoIPController(CRMSecurity crmSecurity, DaoFactory daoFactory, Global global, ContactPhotoManager contactPhotoManager, @@ -85,7 +85,7 @@ public VoIPController(CRMSecurity cRMSecurity, ApiContext apiContext, SignalrServiceClient signalrServiceClient, IMapper mapper) - : base(daoFactory, cRMSecurity, mapper) + : base(daoFactory, crmSecurity, mapper) { _global = global; _contactPhotoManager = contactPhotoManager; diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs new file mode 100644 index 00000000000..c58a3be22c6 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using ASC.Api.Core; + +namespace ASC.CRM.ApiModels +{ + public class AddHistoryToRequestDto + { + public String EntityType { get; set; } + public int EntityId { get; set; } + public int ContactId { get; set; } + public string Content { get; set; } + public int CategoryId { get; set; } + public ApiDateTime Created { get; set; } + public IEnumerable FileId { get; set; } + public IEnumerable NotifyUserList { get; set; } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs new file mode 100644 index 00000000000..230831fa189 --- /dev/null +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Mime; +using System.Threading.Tasks; + +using Microsoft.AspNetCore.Http; + +namespace ASC.CRM.ApiModels +{ + public class UploadFileInCRMRequestDto + { + public string EntityType { get; set; } + public int Entityid { get; set; } + public Stream File { get; set; } + public ContentType ContentType { get; set; } + public ContentDisposition ContentDisposition { get; set; } + public IEnumerable Files { get; set; } + public bool StoreOriginalFileFlag { get; set; } + } +} diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs index eaf72299c1c..cb7b225c390 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs @@ -64,7 +64,7 @@ public class InvoiceTaxDto : IMapFrom public void Mapping(Profile profile) { - profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index d306d8cd712..0ae032b75d2 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -132,7 +132,7 @@ public static DealMilestoneBaseDto GetSample() } [DataContract(Name = "opportunityStages", Namespace = "")] - public class DealMilestoneDto : DealMilestoneBaseDto + public class DealMilestoneDto : DealMilestoneBaseDto, IMapFrom { public DealMilestoneDto() { @@ -157,6 +157,11 @@ public DealMilestoneDto(DealMilestone dealMilestone) RelativeItemsCount = 1 }; } + + public override void Mapping(Profile profile) + { + profile.CreateMap().ConvertUsing(); + } } #endregion @@ -398,10 +403,13 @@ protected ListItemDto(ListItem listItem) public String Color { get; set; } public int SortOrder { get; set; } - public void Mapping(Profile profile) + public virtual void Mapping(Profile profile) { profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); + profile.CreateMap().ConvertUsing(); } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 7366ca9ae2a..f3c4294e493 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -54,7 +54,7 @@ public Global(StorageFactory storageFactory, SecurityContext securityContext, SetupInfo setupInfo, FilesLinkUtility filesLinkUtility, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantManager tenantManager, SettingsManager settingsManager, IConfiguration configuration @@ -64,7 +64,7 @@ IConfiguration configuration FilesLinkUtility = filesLinkUtility; SetupInfo = setupInfo; SecurityContext = securityContext; - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; TenantID = tenantManager.GetCurrentTenant().TenantId; SettingsManager = settingsManager; Configuration = configuration; diff --git a/products/ASC.CRM/Server/Classes/TwilioController.cs b/products/ASC.CRM/Server/Classes/TwilioController.cs index b3fe4aea856..c26cfcd94cc 100644 --- a/products/ASC.CRM/Server/Classes/TwilioController.cs +++ b/products/ASC.CRM/Server/Classes/TwilioController.cs @@ -387,7 +387,7 @@ // CommonLinkUtility commonLinkUtility, // DaoFactory daoFactory, // SecurityContext securityContext, -// CRMSecurity cRMSecurity, +// CRMSecurity crmSecurity, // VoipEngine voipEngine, // SignalrServiceClient signalrServiceClient) // { @@ -396,7 +396,7 @@ // CommonLinkUtility = commonLinkUtility; // TwilioResponseHelper = twilioResponseHelper; // SecurityContext = securityContext; -// CRMSecurity = cRMSecurity; +// CRMSecurity = crmSecurity; // VoipEngine = voipEngine; // SignalrServiceClient = signalrServiceClient; diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index 8cafa9e5f7e..a7abf947e7a 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -53,14 +53,14 @@ public class VoipEngine private readonly object Locker = new object(); public VoipEngine(DaoFactory daoFactory, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, SecurityContext securityContext, IOptionsMonitor logger, TenantManager tenantManager, VoipDao voipDao) { - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; TenantUtil = tenantUtil; SecurityContext = securityContext; Logger = logger.Get("ASC.CRM"); diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 83f8edd9b84..336bedc7f9b 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -60,7 +60,7 @@ public class CachedCasesDao : CasesDao public CachedCasesDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, @@ -72,7 +72,7 @@ public CachedCasesDao(DbContextManager dbContextManager, base(dbContextManager, tenantManager, securityContext, - cRMSecurity, + crmSecurity, tenantUtil, filesIntegration, authorizationManager, @@ -122,7 +122,7 @@ public CasesDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, @@ -136,7 +136,7 @@ BundleSearch bundleSearch logger, ascCache) { - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; TenantUtil = tenantUtil; FilesIntegration = filesIntegration; AuthorizationManager = authorizationManager; diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 886cd890672..22c189d7a51 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -60,7 +60,7 @@ public CachedContactDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, IHttpContextAccessor httpContextAccessor, TenantUtil tenantUtil, AuthorizationManager authorizationManager, @@ -74,7 +74,7 @@ public CachedContactDao( base(dbContextManager, tenantManager, securityContext, - cRMSecurity, + crmSecurity, tenantUtil, authorizationManager, filesIntegration, @@ -138,7 +138,7 @@ public ContactDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, AuthorizationManager authorizationManager, FilesIntegration filesIntegration, @@ -155,7 +155,7 @@ BundleSearch bundleSearch logger, ascCache) { - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; TenantUtil = tenantUtil; AuthorizationManager = authorizationManager; FilesIntegration = filesIntegration; diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 43e78c7ab76..c3d8ea35c21 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -62,7 +62,7 @@ public class CachedDealDao : DealDao public CachedDealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, IHttpContextAccessor httpContextAccessor, @@ -73,7 +73,7 @@ public CachedDealDao(DbContextManager dbContextManager, : base(dbContextManager, tenantManager, securityContext, - cRMSecurity, + crmSecurity, factoryIndexer, filesIntegration, logger, @@ -127,7 +127,7 @@ public class DealDao : AbstractDao public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, IOptionsMonitor logger, @@ -140,7 +140,7 @@ public DealDao(DbContextManager dbContextManager, logger, ascCache) { - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; FactoryIndexer = factoryIndexer; FilesIntegration = filesIntegration; BundleSearch = bundleSearch; diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 64338c977a6..2c99145971e 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -55,7 +55,7 @@ public CachedInvoiceItemDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, ICache ascCache @@ -63,7 +63,7 @@ ICache ascCache tenantManager, securityContext, tenantUtil, - cRMSecurity, + crmSecurity, logger, ascCache) @@ -110,7 +110,7 @@ public InvoiceItemDao( TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, IOptionsMonitor logger, ICache ascCache ) : base(dbContextManager, @@ -120,7 +120,7 @@ ICache ascCache ascCache) { TenantUtil = tenantUtil; - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; } diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 3ae2f1ec4b8..34e2490f80a 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -66,7 +66,7 @@ public CachedRelationshipEventDao(DbContextManager dbContextManage TenantManager tenantManager, SecurityContext securityContext, FilesIntegration filesIntegration, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, SetupInfo setupInfo, PathProvider pathProvider, @@ -78,7 +78,7 @@ ICache ascCache tenantManager, securityContext, filesIntegration, - cRMSecurity, + crmSecurity, tenantUtil, setupInfo, pathProvider, @@ -112,7 +112,7 @@ public RelationshipEventDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, FilesIntegration filesIntegration, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, SetupInfo setupInfo, PathProvider pathProvider, @@ -127,7 +127,7 @@ ICache ascCache { FilesIntegration = filesIntegration; TenantUtil = tenantUtil; - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; SetupInfo = setupInfo; PathProvider = pathProvider; } diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index 92f735be791..56e10b336cf 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -64,7 +64,7 @@ public class SearchDao : AbstractDao public SearchDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, PathProvider pathProvider, FactoryIndexerTask tasksDtoIndexer, @@ -82,7 +82,7 @@ BundleSearch bundleSearch { FactoryIndexerTask = tasksDtoIndexer; FactoryIndexerInvoice = invoicesDtoIndexer; - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; TenantUtil = tenantUtil; PathProvider = pathProvider; WebImageSupplier = webImageSupplier; diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index f8db8d9c63f..cded672486d 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -59,7 +59,7 @@ public class CachedTaskDao : TaskDao public CachedTaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, @@ -72,7 +72,7 @@ IMapper mapper base(dbContextManager, tenantManager, securityContext, - cRMSecurity, + crmSecurity, tenantUtil, factoryIndexer, logger, @@ -129,7 +129,7 @@ public class TaskDao : AbstractDao public TaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, TenantUtil tenantUtil, FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, @@ -143,7 +143,7 @@ public TaskDao(DbContextManager dbContextManager, logger, ascCache) { - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; TenantUtil = tenantUtil; FactoryIndexer = factoryIndexer; UserDbContext = userDbContext.Value; diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index 320a50552aa..16619e92f42 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -40,11 +40,11 @@ namespace ASC.CRM.Core public class FileSecurity : IFileSecurity { public FileSecurity(FilesIntegration filesIntegration, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, DaoFactory daoFactory) { FilesIntegration = filesIntegration; - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; DaoFactory = daoFactory; } @@ -128,11 +128,11 @@ public bool CanCustomFilterEdit(FileEntry entry, Guid userId) public class FileSecurityProvider : IFileSecurityProvider { public FileSecurityProvider(FilesIntegration filesIntegration, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, DaoFactory daoFactory) { FilesIntegration = filesIntegration; - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; DaoFactory = daoFactory; } diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs index 86f99e2b2f8..a5dcfdaa5a2 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs @@ -55,7 +55,7 @@ public ContactPhotoHandlerMiddleware(RequestDelegate next) public async System.Threading.Tasks.Task Invoke(HttpContext context, SetupInfo setupInfo, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, FileSizeComment fileSizeComment, WebItemSecurity webItemSecurity, MessageTarget messageTarget, @@ -65,7 +65,7 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, { //if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) - // throw cRMSecurity.CreateSecurityException(); + // throw crmSecurity.CreateSecurityException(); context.Request.EnableBuffering(); @@ -77,8 +77,8 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, { contact = daoFactory.GetContactDao().GetByID(contactId); - //if (!cRMSecurity.CanEdit(contact)) - // throw cRMSecurity.CreateSecurityException(); + //if (!crmSecurity.CanEdit(contact)) + // throw crmSecurity.CreateSecurityException(); } var fileUploadResult = new FileUploadResult(); diff --git a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs index b54d196dec8..af1d0a2240b 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs @@ -51,12 +51,12 @@ public ImportFileHandlerMiddleware( public async Task Invoke(HttpContext context, WebItemSecurity webItemSecurity, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, Global global, ImportFromCSV importFromCSV) { if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) - throw cRMSecurity.CreateSecurityException(); + throw crmSecurity.CreateSecurityException(); var fileUploadResult = new FileUploadResult(); diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs index 3f5cb79c63e..b30e7c8686d 100644 --- a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs @@ -51,7 +51,7 @@ RequestDelegate next } public async System.Threading.Tasks.Task Invoke(HttpContext context, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, SetupInfo setupInfo, FileSizeComment fileSizeComment, ContactPhotoManager contactPhotoManager, @@ -59,8 +59,8 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, { context.Request.EnableBuffering(); - if (!cRMSecurity.IsAdmin) - throw cRMSecurity.CreateSecurityException(); + if (!crmSecurity.IsAdmin) + throw crmSecurity.CreateSecurityException(); var fileUploadResult = new FileUploadResult(); diff --git a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs index 9e345d2da36..69e5b6378ec 100644 --- a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs +++ b/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs @@ -106,7 +106,7 @@ private bool CheckPermission() public async System.Threading.Tasks.Task Invoke(HttpContext context, WebItemSecurity webItemSecurity, SecurityContext securityContext, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, MessageTarget messageTarget, MessageService messageService, Global global, @@ -119,7 +119,7 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, { WebItemSecurity = webItemSecurity; SecurityContext = securityContext; - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; MessageTarget = messageTarget; MessageService = messageService; Global = global; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs index 0b584cbdbf6..e95c13056f8 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs @@ -50,12 +50,12 @@ public class CasesDtoTypeConverter : ITypeConverter public CasesDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, DaoFactory daoFactory) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _CRMSecurity = cRMSecurity; + _CRMSecurity = crmSecurity; _daoFactory = daoFactory; } diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs new file mode 100644 index 00000000000..71b359289b6 --- /dev/null +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs @@ -0,0 +1,57 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +using System; + +using ASC.CRM.ApiModels; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; + +using AutoMapper; + +namespace ASC.CRM.Mapping +{ + public sealed class DealMilestoneDtoTypeConverter : ITypeConverter + { + private readonly DaoFactory _daoFactory; + + public DealMilestoneDtoTypeConverter(DaoFactory daoFactory) + { + _daoFactory = daoFactory; + } + + public DealMilestoneDto Convert(DealMilestone source, DealMilestoneDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + return new DealMilestoneDto(source) + { + RelativeItemsCount = _daoFactory.GetDealMilestoneDao().GetRelativeItemsCount(source.ID) + }; + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs index 273385be083..d729311497e 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs @@ -52,7 +52,7 @@ public class InvoiceBaseDtoTypeConverter : ITypeConverter + public class InvoiceTaxDtoTypeConverter : ITypeConverter { private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; - private readonly CRMSecurity _CRMSecurity; + private readonly CRMSecurity _crmSecurity; - public InvoiceTaxTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + public InvoiceTaxDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity) + CRMSecurity crmSecurity) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _CRMSecurity = cRMSecurity; + _crmSecurity = crmSecurity; } public InvoiceTaxDto Convert(InvoiceTax source, InvoiceTaxDto destination, ResolutionContext context) @@ -63,8 +63,8 @@ public InvoiceTaxDto Convert(InvoiceTax source, InvoiceTaxDto destination, Resol result.Rate = source.Rate; result.CreateOn = _apiDateTimeHelper.Get(source.CreateOn); result.CreateBy = _employeeWraperHelper.Get(source.CreateBy); - result.CanEdit = _CRMSecurity.CanEdit(source); - result.CanDelete = _CRMSecurity.CanDelete(source); + result.CanEdit = _crmSecurity.CanEdit(source); + result.CanDelete = _crmSecurity.CanDelete(source); return result; } diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs index f2bdd1e8926..bb7abb3092d 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs @@ -37,8 +37,13 @@ namespace ASC.CRM.Mapping { + public sealed class ListItemDtoTypeConverter : ITypeConverter, - ITypeConverter + ITypeConverter, + ITypeConverter, + ITypeConverter, + ITypeConverter + { private readonly WebImageSupplier _webImageSupplier; private readonly DaoFactory _daoFactory; @@ -70,9 +75,45 @@ public HistoryCategoryDto Convert(ListItem source, HistoryCategoryDto destinatio result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.HistoryCategory, source.ID); + return result; + } + + public TaskCategoryDto Convert(ListItem source, TaskCategoryDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new TaskCategoryDto(source); + + result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.TaskCategory, source.ID); - throw new System.NotImplementedException(); + return result; } - } -} + public ContactStatusDto Convert(ListItem source, ContactStatusDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new ContactStatusDto(source); + + result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactStatus, source.ID); + + return result; + + } + + public ContactTypeDto Convert(ListItem source, ContactTypeDto destination, ResolutionContext context) + { + if (destination != null) + throw new NotImplementedException(); + + var result = new ContactTypeDto(source); + + result.RelativeItemsCount = _daoFactory.GetListItemDao().GetRelativeItemsCount(ListType.ContactType, source.ID); + + return result; + + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs index 9dadafea148..bec288d855e 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs @@ -51,13 +51,13 @@ public class OpportunityDtoTypeConverter : ITypeConverter public OpportunityDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, DaoFactory daoFactory, CurrencyProvider currencyProvider) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _cRMSecurity = cRMSecurity; + _cRMSecurity = crmSecurity; _daoFactory = daoFactory; _currencyProvider = currencyProvider; } diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs index 849ea02ed9e..7d44a9cedfb 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs @@ -42,7 +42,6 @@ namespace ASC.CRM.Mapping [Scope] public class RelationshipEventDtoTypeConverter : ITypeConverter { - private readonly HistoryCategoryDto _historyCategoryDtoHelper; private readonly FileWrapperHelper _fileWrapperHelper; private readonly DaoFactory _daoFactory; private readonly CRMSecurity _crmSecurity; @@ -54,13 +53,13 @@ public RelationshipEventDtoTypeConverter( ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, FileWrapperHelper fileWrapperHelper, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, DaoFactory daoFactory, EntityDtoHelper entityDtoHelper) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _crmSecurity = cRMSecurity; + _crmSecurity = crmSecurity; _daoFactory = daoFactory; _fileWrapperHelper = fileWrapperHelper; _entityDtoHelper = entityDtoHelper; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs index b1c026207e0..15eb4053a92 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/TaskDtoTypeConverter.cs @@ -40,7 +40,7 @@ namespace ASC.CRM.Mapping { [Scope] public class TaskDtoTypeConverter : ITypeConverter, - ITypeConverter + ITypeConverter { private readonly CRMSecurity _CRMSecurity; private readonly ApiDateTimeHelper _apiDateTimeHelper; diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index 5b270945bbc..fc74f298be5 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -29,11 +29,15 @@ using System.Collections.Specialized; using System.Globalization; using System.Linq; +using System.Threading; using System.Web; using ASC.Common; +using ASC.Common.Logging; using ASC.Core; +using ASC.Core.Billing; using ASC.Core.Tenants; +using ASC.Core.Users; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -43,6 +47,7 @@ using ASC.Notify.Recipients; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Services.NotifyService { @@ -275,99 +280,102 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) new TagValue(NotifyConstants.Tag_EntityListTitle, entitiyListTitle)); } - //public void SendAutoReminderAboutTask(DateTime scheduleDate) - //{ - // using (var scope = DIHelper.Resolve(-1)) - // { - // var defaultDao = scope.Resolve(); - - // var execAlert = new List(); - - // foreach (var row in defaultDao.GetTaskDao() - // .GetInfoForReminder(scheduleDate)) - // { - - // var tenantId = Convert.ToInt32(row[0]); - // var taskId = Convert.ToInt32(row[1]); - // var deadline = Convert.ToDateTime(row[2]); - // var alertValue = Convert.ToInt32(row[3]); - // var responsibleID = !string.IsNullOrEmpty(Convert.ToString(row[4])) - // ? new Guid(Convert.ToString(row[4])) - // : Guid.Empty; - - // var deadlineReminderDate = deadline.AddMinutes(-alertValue); - - // if (deadlineReminderDate.Subtract(scheduleDate).Minutes > 1) continue; - - // execAlert.Add(taskId); - - // var tenant = TenantManager.GetTenant(tenantId); - // if (tenant == null || - // tenant.Status != TenantStatus.Active || - // TariffState.NotPaid <= PaymentManager.GetTariff(tenant.TenantId).State) - // { - // continue; - // } - - // try - // { - // TenantManager.SetCurrentTenant(tenant); - // SecurityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); - - // var user = UserManager.GetUsers(responsibleID); - - // if (!(!Constants.LostUser.Equals(user) && user.Status == EmployeeStatus.Active)) continue; - - // SecurityContext.AuthenticateMe(user.ID); - - // Thread.CurrentThread.CurrentCulture = user.GetCulture(); - // Thread.CurrentThread.CurrentUICulture = user.GetCulture(); - - // using (var innerScope = DIHelper.Resolve(tenantId)) - // { - // var dao = innerScope.Resolve(); - // var task = dao.GetTaskDao().GetByID(taskId); - - // if (task == null) continue; - - // ASC.CRM.Core.Entities.Contact taskContact = null; - // ASC.CRM.Core.Entities.Cases taskCase = null; - // ASC.CRM.Core.Entities.Deal taskDeal = null; - - // if (task.ContactID > 0) - // { - // taskContact = dao.GetContactDao().GetByID(task.ContactID); - // } - - // if (task.EntityID > 0) - // { - // switch (task.EntityType) - // { - // case EntityType.Case: - // taskCase = dao.GetCasesDao().GetByID(task.EntityID); - // break; - // case EntityType.Opportunity: - // taskDeal = dao.GetDealDao().GetByID(task.EntityID); - // break; - // } - // } - - // var listItem = dao.GetListItemDao().GetByID(task.CategoryID); - - // NotifyClient.SendTaskReminder(task, - // listItem != null ? listItem.Title : string.Empty, - // taskContact, taskCase, taskDeal); - // } - // } - // catch (Exception ex) - // { - // Logger.Error("SendAutoReminderAboutTask, tenant: " + tenant.TenantDomain, ex); - // } - // } - - // defaultDao.GetTaskDao().ExecAlert(execAlert); - // } - //} + public void SendAutoReminderAboutTask(DateTime scheduleDate) + { + using var scope = ServiceProvider.CreateScope(); + + var defaultDao = scope.ServiceProvider.GetService(); + var tenantManager = scope.ServiceProvider.GetService(); + var userManager = scope.ServiceProvider.GetService(); + var securityContext = scope.ServiceProvider.GetService(); + var paymentManager = scope.ServiceProvider.GetService(); + var logger = scope.ServiceProvider.GetService>().Get("ASC.CRM"); + var coreSettings = scope.ServiceProvider.GetService(); + + var execAlert = new List(); + + foreach (var row in defaultDao.GetTaskDao() + .GetInfoForReminder(scheduleDate)) + { + + var tenantId = Convert.ToInt32(row[0]); + var taskId = Convert.ToInt32(row[1]); + var deadline = Convert.ToDateTime(row[2]); + var alertValue = Convert.ToInt32(row[3]); + var responsibleID = !string.IsNullOrEmpty(Convert.ToString(row[4])) + ? new Guid(Convert.ToString(row[4])) + : Guid.Empty; + + var deadlineReminderDate = deadline.AddMinutes(-alertValue); + + if (deadlineReminderDate.Subtract(scheduleDate).Minutes > 1) continue; + + execAlert.Add(taskId); + + var tenant = tenantManager.GetTenant(tenantId); + if (tenant == null || + tenant.Status != TenantStatus.Active || + TariffState.NotPaid <= paymentManager.GetTariff(tenant.TenantId).State) + { + continue; + } + + try + { + tenantManager.SetCurrentTenant(tenant); + securityContext.AuthenticateMe(ASC.Core.Configuration.Constants.CoreSystem); + + var user = userManager.GetUsers(responsibleID); + + if (!(!Constants.LostUser.Equals(user) && user.Status == EmployeeStatus.Active)) continue; + + securityContext.AuthenticateMe(user.ID); + + Thread.CurrentThread.CurrentCulture = user.GetCulture(); + Thread.CurrentThread.CurrentUICulture = user.GetCulture(); + + var dao = defaultDao; + var task = dao.GetTaskDao().GetByID(taskId); + + if (task == null) continue; + + ASC.CRM.Core.Entities.Contact taskContact = null; + ASC.CRM.Core.Entities.Cases taskCase = null; + ASC.CRM.Core.Entities.Deal taskDeal = null; + + if (task.ContactID > 0) + { + taskContact = dao.GetContactDao().GetByID(task.ContactID); + } + + if (task.EntityID > 0) + { + switch (task.EntityType) + { + case EntityType.Case: + taskCase = dao.GetCasesDao().GetByID(task.EntityID); + break; + case EntityType.Opportunity: + taskDeal = dao.GetDealDao().GetByID(task.EntityID); + break; + } + } + + var listItem = dao.GetListItemDao().GetByID(task.CategoryID); + + SendTaskReminder(task, + listItem != null ? listItem.Title : string.Empty, + taskContact, taskCase, taskDeal); + } + catch (Exception ex) + { + logger.Error("SendAutoReminderAboutTask, tenant: " + tenant.GetTenantDomain(coreSettings), ex); + } + } + + defaultDao.GetTaskDao().ExecAlert(execAlert); + + } public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal) { diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 0a37d757df1..e376e0f7385 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -55,7 +55,7 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); - DIHelper.TryAdd(); + DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 00ce93c2ba1..910a37f2668 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -139,7 +139,7 @@ public ImportDataOperation(Global global, IOptionsMonitor logger, UserManager userManager, ImportDataCache importDataCache, - CRMSecurity cRMSecurity, + CRMSecurity crmSecurity, NotifyClient notifyClient, SettingsManager settingsManager, CurrencyProvider currencyProvider, @@ -164,7 +164,7 @@ SecurityContext securityContext _log = logger.Get("ASC.CRM"); - CRMSecurity = cRMSecurity; + CRMSecurity = crmSecurity; SettingsManager = settingsManager; CurrencyProvider = currencyProvider; DaoFactory = daoFactory; From b54e3d3b4ce16a2715b39a8dc978516a10bcb06e Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Thu, 15 Apr 2021 18:20:43 +0300 Subject: [PATCH 42/61] added support AutoMapper for Db Entity --- .../EntryPointApiController.cs} | 62 +++++------ .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 55 +++++----- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 14 ++- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 41 ++++--- .../Server/Core/Dao/CurrencyInfoDao.cs | 8 +- .../Server/Core/Dao/CurrencyRateDao.cs | 33 ++---- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 5 +- .../Server/Core/Dao/DealMilestoneDao.cs | 47 ++++---- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 8 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 101 +++++++----------- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 75 ++++++------- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 54 ++++------ .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 3 +- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 61 +++++------ .../Server/Core/Dao/RelationshipEventDao.cs | 22 ++-- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 8 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 4 +- .../Core/Dao/TaskTemplateContainerDao.cs | 14 ++- .../ASC.CRM/Server/Core/Entities/Cases.cs | 11 +- .../ASC.CRM/Server/Core/Entities/Comment.cs | 8 +- .../ASC.CRM/Server/Core/Entities/Contact.cs | 12 +-- .../Server/Core/Entities/ContactInfo.cs | 16 +-- .../Server/Core/Entities/CurrencyInfo.cs | 13 ++- .../Server/Core/Entities/CurrencyRate.cs | 15 +-- .../Server/Core/Entities/CustomField.cs | 12 +-- products/ASC.CRM/Server/Core/Entities/Deal.cs | 9 -- .../Server/Core/Entities/DealMilestone.cs | 16 +-- .../ASC.CRM/Server/Core/Entities/Invoice.cs | 29 +---- .../Server/Core/Entities/InvoiceItem.cs | 34 +----- .../Server/Core/Entities/InvoiceLine.cs | 13 +-- .../Server/Core/Entities/InvoiceTax.cs | 14 --- .../ASC.CRM/Server/Core/Entities/ListItem.cs | 32 +++--- .../Server/Core/Entities/ListItemHistory.cs | 4 - .../Server/Core/Entities/RelationshipEvent.cs | 4 +- products/ASC.CRM/Server/Core/Entities/Task.cs | 2 - .../Server/Core/Entities/TaskTemplate.cs | 52 +++++++++ .../Core/Entities/TaskTemplateContainer.cs | 30 +----- .../Core/Security/FileSecurityProvider.cs | 2 + products/ASC.CRM/Server/Startup.cs | 2 + 43 files changed, 419 insertions(+), 558 deletions(-) rename products/ASC.CRM/Server/{Controllers/CRMController.cs => Api/EntryPointApiController.cs} (70%) create mode 100644 products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs diff --git a/products/ASC.CRM/Server/Controllers/CRMController.cs b/products/ASC.CRM/Server/Api/EntryPointApiController.cs similarity index 70% rename from products/ASC.CRM/Server/Controllers/CRMController.cs rename to products/ASC.CRM/Server/Api/EntryPointApiController.cs index ee6c6e717db..364185e6a81 100644 --- a/products/ASC.CRM/Server/Controllers/CRMController.cs +++ b/products/ASC.CRM/Server/Api/EntryPointApiController.cs @@ -1,30 +1,32 @@ - -using ASC.Api.Core; -using ASC.Common; -using ASC.Web.Api.Routing; -using ASC.Web.CRM.Configuration; - -using Microsoft.AspNetCore.Mvc; - -namespace ASC.CRM.Controllers -{ - [Scope] - [DefaultRoute] - [ApiController] - public class CRMController : ControllerBase - { - private ProductEntryPoint ProductEntryPoint { get; } - - public CRMController(ProductEntryPoint productEntryPoint) - { - ProductEntryPoint = productEntryPoint; - } - - [Read("info")] - public Module GetModule() - { - ProductEntryPoint.Init(); - return new Module(ProductEntryPoint); - } - } -} + +using ASC.Api.Core; +using ASC.Api.Core.Convention; +using ASC.Common; +using ASC.Web.Api.Routing; +using ASC.Web.CRM.Configuration; + +using Microsoft.AspNetCore.Mvc; + +namespace ASC.CRM.Api +{ + [Scope] + [DefaultRoute] + [ApiController] + [ControllerName("crm")] + public class EntryPointApiController : ControllerBase + { + private ProductEntryPoint ProductEntryPoint { get; } + + public EntryPointApiController(ProductEntryPoint productEntryPoint) + { + ProductEntryPoint = productEntryPoint; + } + + [Read("info")] + public Module GetModule() + { + ProductEntryPoint.Init(); + return new Module(ProductEntryPoint); + } + } +} diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index f05111dfb96..2b5245f1cb6 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -36,6 +36,8 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using AutoMapper; + using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -48,16 +50,18 @@ public class AbstractDao protected SecurityContext _securityContext; protected readonly ICache _cache; protected ILog _logger; + protected IMapper _mapper; public AbstractDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) { - + _mapper = mapper; _logger = logger.Get("ASC.CRM"); _cache = ascCache; diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 336bedc7f9b..e5bbc97b43f 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -44,6 +44,8 @@ using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -67,7 +69,8 @@ public CachedCasesDao(DbContextManager dbContextManager, IOptionsMonitor logger, ICache ascCache, IHttpContextAccessor httpContextAccessor, - BundleSearch bundleSearch) + BundleSearch bundleSearch, + IMapper mapper) : base(dbContextManager, tenantManager, @@ -78,7 +81,8 @@ public CachedCasesDao(DbContextManager dbContextManager, authorizationManager, logger, ascCache, - bundleSearch) + bundleSearch, + mapper) { _casesCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_cases"); @@ -128,13 +132,15 @@ public CasesDao( AuthorizationManager authorizationManager, IOptionsMonitor logger, ICache ascCache, - BundleSearch bundleSearch + BundleSearch bundleSearch, + IMapper mapper ) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { CRMSecurity = crmSecurity; TenantUtil = tenantUtil; @@ -564,11 +570,12 @@ public List GetCases(IEnumerable casesID) { if (casesID == null || !casesID.Any()) return new List(); - return Query(CRMDbContext.Cases) + var result = Query(CRMDbContext.Cases) .Where(x => casesID.Contains(x.Id)) - .ToList() - .ConvertAll(ToCases) - .FindAll(CRMSecurity.CanAccessTo); + .ToList(); + + return _mapper.Map, List>(result) + .FindAll(CRMSecurity.CanAccessTo); } public List GetCases( @@ -607,8 +614,7 @@ public List GetCases( } } - - return dbCasesQuery.ToList().ConvertAll(ToCases); + return _mapper.Map, List>(dbCasesQuery.ToList()); } public List GetCasesByPrefix(String prefix, int from, int count) @@ -638,17 +644,20 @@ public List GetCasesByPrefix(String prefix, int from, int count) if (0 < count && count < int.MaxValue) q = q.Take(count); q = q.OrderBy(x => x.Title); - - return q.ToList().ConvertAll(ToCases).FindAll(CRMSecurity.CanAccessTo); + + return _mapper.Map, List>(q.ToList()) + .FindAll(CRMSecurity.CanAccessTo); } public virtual List GetByID(int[] ids) { - return CRMDbContext.Cases + var result = CRMDbContext.Cases .Where(x => ids.Contains(x.Id)) - .ToList() - .ConvertAll(ToCases); + .ToList(); + + + return _mapper.Map, List>(result); } public virtual Cases GetByID(int id) @@ -660,22 +669,6 @@ public virtual Cases GetByID(int id) return cases.Count == 0 ? null : cases[0]; } - private Cases ToCases(DbCase dbCase) - { - if (dbCase == null) return null; - - return new Cases - { - ID = dbCase.Id, - Title = dbCase.Title, - CreateBy = dbCase.CreateBy, - CreateOn = TenantUtil.DateTimeFromUtc(dbCase.CreateOn), - IsClosed = dbCase.IsClosed, - LastModifedBy = dbCase.LastModifedBy, - LastModifedOn = dbCase.LastModifedOn - }; - } - public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) { var cases = GetAllCases(); diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 22c189d7a51..bd4745020d6 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -45,6 +45,8 @@ using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -70,7 +72,8 @@ public CachedContactDao( IOptionsMonitor logger, ICache ascCache, DbContextManager coreDbContext, - BundleSearch bundleSearch) : + BundleSearch bundleSearch, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, @@ -83,7 +86,8 @@ public CachedContactDao( logger, ascCache, coreDbContext, - bundleSearch) + bundleSearch, + mapper) { _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact"); } @@ -147,13 +151,15 @@ public ContactDao( IOptionsMonitor logger, ICache ascCache, DbContextManager coreDbContext, - BundleSearch bundleSearch + BundleSearch bundleSearch, + IMapper mapper ) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { CRMSecurity = crmSecurity; TenantUtil = tenantUtil; diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 33d934ac90d..d545d108990 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -39,6 +39,8 @@ using ASC.CRM.Core.Enums; using ASC.Web.CRM.Core.Search; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; @@ -57,7 +59,8 @@ public CachedContactInfo( ICache ascCache, FactoryIndexerContactInfo factoryIndexerContactInfo, IHttpContextAccessor httpContextAccessor, - IServiceProvider serviceProvider + IServiceProvider serviceProvider, + IMapper mapper ) : base( dbContextManager, @@ -67,7 +70,8 @@ IServiceProvider serviceProvider logger, ascCache, factoryIndexerContactInfo, - serviceProvider) + serviceProvider, + mapper) { _contactInfoCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact_info"); } @@ -122,12 +126,14 @@ public ContactInfoDao( IOptionsMonitor logger, ICache ascCache, FactoryIndexerContactInfo factoryIndexerContactInfo, - IServiceProvider serviceProvider) + IServiceProvider serviceProvider, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { TenantUtil = tenantUtil; ServiceProvider = serviceProvider; @@ -141,7 +147,9 @@ public ContactInfoDao( public virtual ContactInfo GetByID(int id) { - return ToContactInfo(CRMDbContext.ContactsInfo.SingleOrDefault(x => x.Id == id)); + var dbContactInfo = CRMDbContext.ContactsInfo.SingleOrDefault(x => x.Id == id); + + return _mapper.Map(dbContactInfo); } public virtual void Delete(int id) @@ -257,9 +265,11 @@ public List GetAll(int[] contactID) { if (contactID == null || contactID.Length == 0) return null; - return Query(CRMDbContext.ContactsInfo) + var result = Query(CRMDbContext.ContactsInfo) .Where(x => contactID.Contains(x.ContactId)) - .ToList().ConvertAll(ToContactInfo); + .ToList(); + + return _mapper.Map, List>(result); } public virtual List GetList(int contactID, ContactInfoType? infoType, int? categoryID, bool? isPrimary) @@ -280,7 +290,7 @@ public virtual List GetList(int contactID, ContactInfoType? infoTyp items = items.OrderBy(x => x.Type); - return items.ToList().ConvertAll(row => ToContactInfo(row)); + return _mapper.Map, List>(items.ToList()); } @@ -345,20 +355,5 @@ public int[] SaveList(List items, Contact contact = null) return result.ToArray(); } - - protected static ContactInfo ToContactInfo(DbContactInfo dbContactInfo) - { - if (dbContactInfo == null) return null; - - return new ContactInfo - { - ID = dbContactInfo.Id, - Category = dbContactInfo.Category, - ContactID = dbContactInfo.ContactId, - Data = dbContactInfo.Data, - InfoType = dbContactInfo.Type, - IsPrimary = dbContactInfo.IsPrimary - }; - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 0f7009fb418..5f445cfc405 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -35,6 +35,8 @@ using ASC.Core.Common.EF; using ASC.CRM.Core.EF; +using AutoMapper; + using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -46,12 +48,14 @@ public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache) : + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index 4fdc933c519..d1ee1e54ce8 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -34,6 +34,8 @@ using ASC.Core.Common.EF; using ASC.CRM.Core.EF; +using AutoMapper; + using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -46,29 +48,33 @@ public CurrencyRateDao( TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache) : + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { } public virtual List GetAll() { - return CRMDbContext.CurrencyRate.Where(x => x.TenantId == TenantID).ToList().ConvertAll(ToCurrencyRate); + var rates = CRMDbContext.CurrencyRate.Where(x => x.TenantId == TenantID).ToList(); + + return _mapper.Map, List>(rates); } public virtual CurrencyRate GetByID(int id) { - return ToCurrencyRate(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.Id == id)); + return _mapper.Map(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.Id == id)); } public CurrencyRate GetByCurrencies(string fromCurrency, string toCurrency) { - return ToCurrencyRate(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && + return _mapper.Map(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && String.Compare(x.ToCurrency, toCurrency, true) == 0)); } @@ -163,22 +169,5 @@ public List SetCurrencyRates(List rates) return rates; } - - private static CurrencyRate ToCurrencyRate(DbCurrencyRate dbCurrencyRate) - { - if (dbCurrencyRate == null) return null; - - return new CurrencyRate - { - ID = dbCurrencyRate.Id, - FromCurrency = dbCurrencyRate.FromCurrency, - ToCurrency = dbCurrencyRate.ToCurrency, - Rate = dbCurrencyRate.Rate, - CreateBy = dbCurrencyRate.CreateBy, - CreateOn = dbCurrencyRate.CreateOn, - LastModifedBy = dbCurrencyRate.LastModifedBy, - LastModifedOn = dbCurrencyRate.LastModifedOn - }; - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 601626c06bc..6e8336b759f 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -41,6 +41,8 @@ using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; +using AutoMapper; + using Microsoft.Extensions.Options; using Newtonsoft.Json; @@ -57,13 +59,15 @@ public CustomFieldDao( SecurityContext securityContext, TenantUtil tenantUtil, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { TenantUtil = tenantUtil; } diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index c3d8ea35c21..71f3165e65e 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -122,8 +122,6 @@ private void ResetCache(int dealID) [Scope] public class DealDao : AbstractDao { - private readonly IMapper _mapper; - public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -138,7 +136,8 @@ public DealDao(DbContextManager dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { CRMSecurity = crmSecurity; FactoryIndexer = factoryIndexer; diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 44cf6e5bf50..6853fb6d043 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -40,6 +40,8 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Resources; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; @@ -56,13 +58,14 @@ public CachedDealMilestoneDao(DbContextManager dbContextManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - ICache ascCache) + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache - ) + ascCache, + mapper) { _dealMilestoneCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal_milestone"); @@ -123,12 +126,14 @@ public DealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache) : + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { @@ -270,7 +275,9 @@ public virtual void Delete(int id) public virtual DealMilestone GetByID(int id) { - return ToDealMilestone(Query(CRMDbContext.DealMilestones).FirstOrDefault(x => x.Id == id)); + var dbDealMilestone = Query(CRMDbContext.DealMilestones).FirstOrDefault(x => x.Id == id); + + return _mapper.Map(dbDealMilestone); } public Boolean IsExist(int id) @@ -280,31 +287,21 @@ public Boolean IsExist(int id) public List GetAll(int[] id) { - return Query(CRMDbContext.DealMilestones) - .OrderBy(x => x.SortOrder) - .Where(x => id.Contains(x.Id)).ToList().ConvertAll(ToDealMilestone); + var result = Query(CRMDbContext.DealMilestones) + .OrderBy(x => x.SortOrder) + .Where(x => id.Contains(x.Id)).ToList(); + + return _mapper.Map, List>(result); } public List GetAll() { - return Query(CRMDbContext.DealMilestones) + var result = Query(CRMDbContext.DealMilestones) .OrderBy(x => x.SortOrder) - .ToList() - .ConvertAll(ToDealMilestone); - } + .ToList(); + + return _mapper.Map, List>(result); - private static DealMilestone ToDealMilestone(DbDealMilestone dbDealMilestone) - { - return new DealMilestone - { - ID = dbDealMilestone.Id, - Title = dbDealMilestone.Title, - Color = dbDealMilestone.Color, - Status = dbDealMilestone.Status, - Description = dbDealMilestone.Description, - Probability = dbDealMilestone.Probability, - SortOrder = dbDealMilestone.SortOrder - }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index a26d3b05162..5acff4fec12 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -37,6 +37,8 @@ using ASC.Files.Core; using ASC.Web.Files.Api; +using AutoMapper; + using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -49,12 +51,14 @@ public FileDao(FilesIntegration filesIntegration, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache) : + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { FilesIntegration = filesIntegration; } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index a07c3cc1231..eefe5a2bd55 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -45,6 +45,8 @@ using ASC.Web.CRM.Classes; using ASC.Web.CRM.Core.Search; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -70,7 +72,8 @@ public CachedInvoiceDao(DbContextManager dbContextManager, InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData, CRMSecurity crmSecurity, - TenantUtil tenantUtil) + TenantUtil tenantUtil, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, @@ -81,7 +84,8 @@ public CachedInvoiceDao(DbContextManager dbContextManager, invoiceSetting, invoiceFormattedData, crmSecurity, - tenantUtil + tenantUtil, + mapper ) { _invoiceCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice"); @@ -149,12 +153,14 @@ public InvoiceDao( InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData, CRMSecurity crmSecurity, - TenantUtil tenantUtil) + TenantUtil tenantUtil, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { _factoryIndexer = factoryIndexer; _settingsManager = settingsManager; @@ -189,17 +195,19 @@ public Boolean IsExistFromDb(string number) public virtual List GetAll() { - return Query(CRMDbContext.Invoices) - .ToList() - .ConvertAll(ToInvoice); + var dbInvoices = Query(CRMDbContext.Invoices) + .ToList(); + + return _mapper.Map, List>(dbInvoices); } public virtual List GetByID(int[] ids) { - return Query(CRMDbContext.Invoices) + var dbInvoices = Query(CRMDbContext.Invoices) .Where(x => ids.Contains(x.Id)) - .ToList() - .ConvertAll(ToInvoice); + .ToList(); + + return _mapper.Map, List>(dbInvoices); } public virtual Invoice GetByID(int id) @@ -209,17 +217,17 @@ public virtual Invoice GetByID(int id) public virtual Invoice GetByIDFromDb(int id) { - return ToInvoice(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == id)); + return _mapper.Map(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == id)); } public Invoice GetByNumber(string number) { - return ToInvoice(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Number == number)); + return _mapper.Map(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Number == number)); } public Invoice GetByFileId(Int32 fileID) { - return ToInvoice(Query(CRMDbContext.Invoices) + return _mapper.Map(Query(CRMDbContext.Invoices) .FirstOrDefault(x => x.FileId == fileID)); } @@ -383,7 +391,7 @@ public List GetCrudeInvoices( sqlQuery = sqlQuery.OrderBy("Number", orderBy.IsAsc); } - return sqlQuery.ToList().ConvertAll(ToInvoice); + return _mapper.Map, List>(sqlQuery.ToList()); } public int GetAllInvoicesCount() @@ -459,25 +467,30 @@ public List GetInvoices(int[] ids) { if (ids == null || !ids.Any()) return new List(); - return Query(CRMDbContext.Invoices) + var dbInvoices = Query(CRMDbContext.Invoices) .Where(x => ids.Contains(x.Id)) - .ToList() - .ConvertAll(ToInvoice) + .ToList(); + + return _mapper.Map, List>(dbInvoices) .FindAll(_crmSecurity.CanAccessTo); } public List GetEntityInvoices(EntityType entityType, int entityID) { var result = new List(); + if (entityID <= 0) return result; if (entityType == EntityType.Opportunity) { - return Query(CRMDbContext.Invoices).Where(x => x.EntityId == entityID && x.EntityType == entityType) - .ToList() - .ConvertAll(ToInvoice) + + var sqlQuery = Query(CRMDbContext.Invoices).Where(x => x.EntityId == entityID && x.EntityType == entityType) + .ToList(); + + return _mapper.Map, List>(sqlQuery) .FindAll(_crmSecurity.CanAccessTo); + } if (entityType == EntityType.Contact || entityType == EntityType.Person || entityType == EntityType.Company) @@ -493,9 +506,10 @@ public List GetContactInvoices(int contactID) if (contactID <= 0) return result; - return Query(CRMDbContext.Invoices).Where(x => x.ContactId == contactID) - .ToList() - .ConvertAll(ToInvoice) + var dbInvoices = Query(CRMDbContext.Invoices).Where(x => x.ContactId == contactID) + .ToList(); + + return _mapper.Map, List>(dbInvoices) .FindAll(_crmSecurity.CanAccessTo); } @@ -603,8 +617,8 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) { var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoice.ID); - var oldInvoice = ToInvoice(itemToUpdate); - + var oldInvoice = _mapper.Map(itemToUpdate); + _crmSecurity.DemandEdit(oldInvoice); itemToUpdate.Status = invoice.Status; @@ -810,43 +824,6 @@ private void DeleteBatchInvoicesExecute(List invoices) } - private Invoice ToInvoice(DbInvoice dbInvoice) - { - if (dbInvoice == null) return null; - - var result = new Invoice - { - ID = dbInvoice.Id, - Status = dbInvoice.Status, - Number = dbInvoice.Number, - IssueDate = _tenantUtil.DateTimeFromUtc(dbInvoice.IssueDate), - TemplateType = dbInvoice.TemplateType, - ContactID = dbInvoice.ContactId, - ConsigneeID = dbInvoice.ConsigneeId, - EntityType = dbInvoice.EntityType, - EntityID = dbInvoice.EntityId, - DueDate = _tenantUtil.DateTimeFromUtc(dbInvoice.DueDate), - Language = dbInvoice.Language, - Currency = dbInvoice.Currency, - ExchangeRate = dbInvoice.ExchangeRate, - PurchaseOrderNumber = dbInvoice.PurchaseOrderNumber, - Terms = dbInvoice.Terms, - Description = dbInvoice.Description, - JsonData = dbInvoice.JsonData, - FileID = dbInvoice.FileId, - CreateOn = _tenantUtil.DateTimeFromUtc(dbInvoice.CreateOn), - CreateBy = dbInvoice.CreateBy, - LastModifedBy = dbInvoice.LastModifedBy - }; - - if (dbInvoice.LastModifedOn.HasValue) - { - result.LastModifedOn = _tenantUtil.DateTimeFromUtc(dbInvoice.LastModifedOn.Value); - } - - return result; - } - private IQueryable GetDbInvoceByFilters( ICollection exceptIDs, String searchText, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 2c99145971e..3b72ebef33b 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -41,6 +41,8 @@ using ASC.CRM.Core.Enums; using ASC.Web.CRM.Classes; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -58,14 +60,16 @@ public CachedInvoiceItemDao(DbContextManager dbContextManager, CRMSecurity crmSecurity, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) : base(dbContextManager, tenantManager, securityContext, tenantUtil, crmSecurity, logger, - ascCache) + ascCache, + mapper) { _invoiceItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_item"); @@ -112,12 +116,14 @@ public InvoiceItemDao( TenantUtil tenantUtil, CRMSecurity crmSecurity, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { TenantUtil = tenantUtil; CRMSecurity = crmSecurity; @@ -149,30 +155,37 @@ public virtual List GetAll() } public virtual List GetAllInDb() { - return Query(CRMDbContext.InvoiceItem).ToList().ConvertAll(ToInvoiceItem); + var dbInvoiceItems = Query(CRMDbContext.InvoiceItem).ToList(); + + return _mapper.Map, List>(dbInvoiceItems); } public virtual List GetByID(int[] ids) { - return Query(CRMDbContext.InvoiceItem) - .Where(x => ids.Contains(x.Id)) - .ToList() - .ConvertAll(ToInvoiceItem); + var dbInvoiceItems = Query(CRMDbContext.InvoiceItem) + .Where(x => ids.Contains(x.Id)) + .ToList(); + + return _mapper.Map, List>(dbInvoiceItems); } public virtual InvoiceItem GetByID(int id) { - return ToInvoiceItem(Query(CRMDbContext.InvoiceItem).FirstOrDefault(x => x.Id == id)); + var dbInvoiceItems = Query(CRMDbContext.InvoiceItem).FirstOrDefault(x => x.Id == id); + + return _mapper.Map(dbInvoiceItems); } public List GetInvoiceItems(IEnumerable ids) { if (ids == null || !ids.Any()) return new List(); - return Query(CRMDbContext.InvoiceItem) + var dbInvoiceItems = Query(CRMDbContext.InvoiceItem) .Where(x => ids.Contains(x.Id)) - .ToList() - .ConvertAll(ToInvoiceItem); + .ToList(); + + return _mapper.Map, List>(dbInvoiceItems); + } public List GetInvoiceItems( @@ -226,7 +239,9 @@ public List GetInvoiceItems( sqlQuery = sqlQuery.OrderBy("Title", true); } - return sqlQuery.ToList().ConvertAll(ToInvoiceItem); + var dbInvoiceItems = sqlQuery.ToList(); + + return _mapper.Map, List>(dbInvoiceItems); } @@ -343,7 +358,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) { var itemToUpdate = Query(CRMDbContext.InvoiceItem).Single(x => x.Id == invoiceItem.ID); - var oldInvoiceItem = ToInvoiceItem(itemToUpdate); + var oldInvoiceItem = _mapper.Map(itemToUpdate); CRMSecurity.DemandEdit(oldInvoiceItem); @@ -417,35 +432,7 @@ private void DeleteBatchItemsExecute(List items) CRMDbContext.SaveChanges(); } - - private InvoiceItem ToInvoiceItem(DbInvoiceItem dbInvoiceItem) - { - if (dbInvoiceItem == null) return null; - - var result = new InvoiceItem - { - ID = dbInvoiceItem.Id, - Title = dbInvoiceItem.Title, - Description = dbInvoiceItem.Description, - StockKeepingUnit = dbInvoiceItem.StockKeepingUnit, - Price = dbInvoiceItem.Price, - StockQuantity = dbInvoiceItem.StockQuantity, - TrackInventory = dbInvoiceItem.TrackInventory, - InvoiceTax1ID = dbInvoiceItem.InvoiceTax1Id, - InvoiceTax2ID = dbInvoiceItem.InvoiceTax2Id, - Currency = dbInvoiceItem.Currency, - CreateOn = TenantUtil.DateTimeFromUtc(dbInvoiceItem.CreateOn), - CreateBy = dbInvoiceItem.CreateBy, - LastModifedBy = dbInvoiceItem.LastModifedBy - }; - - if (result.LastModifedOn.HasValue) - result.LastModifedOn = TenantUtil.DateTimeFromUtc(dbInvoiceItem.LastModifedOn.Value); - - return result; - - } - + private IQueryable GetDbInvoiceItemByFilters( ICollection exceptIDs, String searchText, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 71df6c6822a..3012f0516aa 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -39,6 +39,8 @@ using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; @@ -55,12 +57,14 @@ public CachedInvoiceLineDao(DbContextManager dbContextManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - ICache ascCache) + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { _invoiceLineCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_line"); } @@ -103,12 +107,14 @@ public InvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache) + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { } @@ -140,20 +146,22 @@ public static string GetJson(InvoiceTax invoiceTax) public virtual List GetAll() { - return Query(CRMDbContext.InvoiceLine) - .ToList() - .ConvertAll(ToInvoiceLine); + var dbInvoiceLines = Query(CRMDbContext.InvoiceLine) + .ToList(); + + return _mapper.Map, List>(dbInvoiceLines); } public virtual List GetByID(int[] ids) { - return Query(CRMDbContext.InvoiceLine).Where(x => ids.Contains(x.Id)).ToList() - .ConvertAll(ToInvoiceLine); + var dbInvoiceLines = Query(CRMDbContext.InvoiceLine).Where(x => ids.Contains(x.Id)).ToList(); + + return _mapper.Map, List>(dbInvoiceLines); } public virtual InvoiceLine GetByID(int id) { - return ToInvoiceLine(Query(CRMDbContext.InvoiceLine).FirstOrDefault(x => x.Id == id)); + return _mapper.Map(Query(CRMDbContext.InvoiceLine).FirstOrDefault(x => x.Id == id)); } public List GetInvoiceLines(int invoiceID) @@ -163,11 +171,12 @@ public List GetInvoiceLines(int invoiceID) public List GetInvoiceLinesInDb(int invoiceID) { - return Query(CRMDbContext.InvoiceLine) + var dbInvoiceLines = Query(CRMDbContext.InvoiceLine) .Where(x => x.InvoiceId == invoiceID) .OrderBy(x => x.SortOrder) - .ToList() - .ConvertAll(ToInvoiceLine); + .ToList(); + + return _mapper.Map, List>(dbInvoiceLines); } public virtual int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) @@ -275,24 +284,5 @@ public Boolean CanDeleteInDb(int invoiceLineID) return Query(CRMDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceLineID).Any(); } - - private InvoiceLine ToInvoiceLine(DbInvoiceLine dbInvoiceLine) - { - if (dbInvoiceLine == null) return null; - - return new InvoiceLine - { - ID = dbInvoiceLine.Id, - InvoiceID = dbInvoiceLine.InvoiceId, - InvoiceItemID = dbInvoiceLine.InvoiceItemId, - InvoiceTax1ID = dbInvoiceLine.InvoiceTax1Id, - InvoiceTax2ID = dbInvoiceLine.InvoiceTax2Id, - SortOrder = dbInvoiceLine.SortOrder, - Description = dbInvoiceLine.Description, - Quantity = dbInvoiceLine.Quantity, - Price = dbInvoiceLine.Price, - Discount = dbInvoiceLine.Discount - }; - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index a1f47209634..030c3f772a2 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -120,7 +120,8 @@ IMapper mapper tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { TenantUtil = tenantUtil; _mapper = mapper; diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 5bd8e1924a3..d1c0273e3aa 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -40,6 +40,8 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -57,12 +59,14 @@ public CachedListItem( SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - ICache ascCache) + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { _listItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_list_item"); } @@ -126,12 +130,14 @@ public ListItemDao( TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache) + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { @@ -151,19 +157,21 @@ public bool IsExist(int id) public List GetItems() { - return Query(CRMDbContext.ListItem) + var dbListItems = Query(CRMDbContext.ListItem) .OrderBy(x => x.SortOrder) - .ToList() - .ConvertAll(ToListItem); + .ToList(); + + return _mapper.Map, List>(dbListItems); } public List GetItems(ListType listType) { - return Query(CRMDbContext.ListItem) + var dbListItems = Query(CRMDbContext.ListItem) .Where(x => x.ListType == listType) .OrderBy(x => x.SortOrder) - .ToList() - .ConvertAll(ToListItem); + .ToList(); + + return _mapper.Map, List>(dbListItems); } public int GetItemsCount(ListType listType) @@ -233,12 +241,12 @@ public virtual ListItem GetByID(int id) { if (id < 0) return GetSystemListItem(id); - return ToListItem(Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == id)); + return _mapper.Map(Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == id)); } public virtual List GetItems(int[] id) { - var sqlResult = CRMDbContext.ListItem.Where(x => id.Contains(x.Id)).ToList().ConvertAll(ToListItem); + var sqlResult = _mapper.Map, List>(CRMDbContext.ListItem.Where(x => id.Contains(x.Id)).ToList()); var systemItem = id.Where(item => item < 0).Select(GetSystemListItem); @@ -247,10 +255,12 @@ public virtual List GetItems(int[] id) public virtual List GetAll() { - return CRMDbContext + var dbListItems = CRMDbContext .ListItem - .ToList() - .ConvertAll(ToListItem); + .ToList(); + + return _mapper.Map, List>(dbListItems); + } public virtual void ChangeColor(int id, string newColor) @@ -283,7 +293,7 @@ public NameValueCollection GetColors(ListType listType) public ListItem GetByTitle(ListType listType, string title) { - return ToListItem(Query(CRMDbContext.ListItem) + return _mapper.Map(Query(CRMDbContext.ListItem) .FirstOrDefault(x => String.Compare(x.Title, title, true) == 0 && x.ListType == listType)); } @@ -593,24 +603,5 @@ public virtual void ReorderItems(ListType listType, String[] titles) tx.Commit(); } - - public static ListItem ToListItem(DbListItem dbListItem) - { - if (dbListItem == null) return null; - - var result = new ListItem - { - ID = dbListItem.Id, - Title = dbListItem.Title, - Description = dbListItem.Description, - Color = dbListItem.Color, - SortOrder = dbListItem.SortOrder, - AdditionalParams = dbListItem.AdditionalParams, - ListType = dbListItem.ListType - }; - - return result; - } } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 34e2490f80a..73dda7ff000 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -48,6 +48,8 @@ using ASC.Web.Files.Api; using ASC.Web.Studio.Core; +using AutoMapper; + using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -72,7 +74,8 @@ public CachedRelationshipEventDao(DbContextManager dbContextManage PathProvider pathProvider, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) : base(dbContextManager, tenantManager, @@ -83,7 +86,8 @@ ICache ascCache setupInfo, pathProvider, logger, - ascCache) + ascCache, + mapper) { _relationshipEventCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_relationshipEvent"); } @@ -117,13 +121,15 @@ public RelationshipEventDao(DbContextManager dbContextManager, SetupInfo setupInfo, PathProvider pathProvider, IOptionsMonitor logger, - ICache ascCache + ICache ascCache, + IMapper mapper ) : - base(dbContextManager, - tenantManager, - securityContext, - logger, - ascCache) + base(dbContextManager, + tenantManager, + securityContext, + logger, + ascCache, + mapper) { FilesIntegration = filesIntegration; TenantUtil = tenantUtil; diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 22938f9fbc3..4591143c00c 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -50,6 +50,8 @@ using ASC.Web.CRM.Classes; using ASC.Web.Files.Api; +using AutoMapper; + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -91,12 +93,14 @@ public ReportDao(DbContextManager dbContextManager, IServiceProvider serviceProvider, CurrencyProvider currencyProvider, DaoFactory daoFactory, - DisplayUserSettingsHelper displayUserSettingsHelper) : + DisplayUserSettingsHelper displayUserSettingsHelper, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { _tenantUtil = tenantUtil; diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index 56e10b336cf..f70f26d6340 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -45,6 +45,8 @@ using ASC.Web.CRM.Configuration; using ASC.Web.CRM.Core.Search; +using AutoMapper; + using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -72,13 +74,15 @@ public SearchDao(DbContextManager dbContextManager, IOptionsMonitor logger, ICache ascCache, WebImageSupplier webImageSupplier, - BundleSearch bundleSearch + BundleSearch bundleSearch, + IMapper mapper ) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { FactoryIndexerTask = tasksDtoIndexer; FactoryIndexerInvoice = invoicesDtoIndexer; diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 031238dad3d..3f8931bf67b 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -37,6 +37,8 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; +using AutoMapper; + using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Options; @@ -51,12 +53,14 @@ public TagDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache ascCache) : + ICache ascCache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index cded672486d..f0bd9742564 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -125,7 +125,6 @@ private void ResetCache(int taskID) [Scope] public class TaskDao : AbstractDao { - private readonly IMapper _mapper; public TaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -141,7 +140,8 @@ public TaskDao(DbContextManager dbContextManager, tenantManager, securityContext, logger, - ascCache) + ascCache, + mapper) { CRMSecurity = crmSecurity; TenantUtil = tenantUtil; diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 8f11b07cce1..d7ffa7c46d8 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -36,6 +36,8 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; +using AutoMapper; + using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -49,13 +51,15 @@ public TaskTemplateContainerDao( TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache cache + ICache cache, + IMapper mapper ) : base(dbContextManager, tenantManager, securityContext, logger, - cache) + cache, + mapper) { } @@ -146,12 +150,14 @@ public TaskTemplateDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, - ICache cache) + ICache cache, + IMapper mapper) : base(dbContextManager, tenantManager, securityContext, logger, - cache) + cache, + mapper) { } diff --git a/products/ASC.CRM/Server/Core/Entities/Cases.cs b/products/ASC.CRM/Server/Core/Entities/Cases.cs index 640ff44f133..571a87413d2 100644 --- a/products/ASC.CRM/Server/Core/Entities/Cases.cs +++ b/products/ASC.CRM/Server/Core/Entities/Cases.cs @@ -28,25 +28,20 @@ using System.Collections.Generic; using ASC.Common.Security; +using ASC.CRM.Core.EF; +using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { - public class Cases : DomainObject, ISecurityObjectId + public class Cases : DomainObject, ISecurityObjectId, IMapFrom { public Guid CreateBy { get; set; } - public DateTime CreateOn { get; set; } - public Guid? LastModifedBy { get; set; } - public DateTime? LastModifedOn { get; set; } - public String Title { get; set; } - public bool IsClosed { get; set; } - public HashSet Members { get; set; } - // TODO: to finish the field public DateTime ClosedDate { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/Comment.cs b/products/ASC.CRM/Server/Core/Entities/Comment.cs index b62375240f8..e42cb13e1d6 100644 --- a/products/ASC.CRM/Server/Core/Entities/Comment.cs +++ b/products/ASC.CRM/Server/Core/Entities/Comment.cs @@ -28,6 +28,8 @@ using System; +using ASC.CRM.Mapping; + #endregion namespace ASC.CRM.Core.Entities @@ -35,17 +37,11 @@ namespace ASC.CRM.Core.Entities public class Comment { public Guid Parent { get; set; } - public string Content { get; set; } - public bool Inactive { get; set; } - public String TargetUniqID { get; set; } - public Guid CreateBy { get; set; } - public DateTime CreateOn { get; set; } - public override int GetHashCode() { return (GetType().FullName + "|" + Content + "|" + CreateBy.GetHashCode() + "|" + Parent.GetHashCode()).GetHashCode(); diff --git a/products/ASC.CRM/Server/Core/Entities/Contact.cs b/products/ASC.CRM/Server/Core/Entities/Contact.cs index 6bfbb970d12..8f300a05b42 100644 --- a/products/ASC.CRM/Server/Core/Entities/Contact.cs +++ b/products/ASC.CRM/Server/Core/Entities/Contact.cs @@ -27,7 +27,9 @@ using System; using ASC.Common.Security; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { @@ -43,11 +45,8 @@ public Person() } public String FirstName { get; set; } - public String LastName { get; set; } - public int CompanyID { get; set; } - public String JobTitle { get; set; } } @@ -111,19 +110,12 @@ protected Contact() } public Guid CreateBy { get; set; } - public DateTime CreateOn { get; set; } - public Guid? LastModifedBy { get; set; } - public DateTime? LastModifedOn { get; set; } - public String About { get; set; } - public String Industry { get; set; } - public int StatusID { get; set; } - public int ContactTypeID { get; set; } public ShareType ShareType { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs index 73bc67f49b3..dc9b9c486b8 100644 --- a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs @@ -28,29 +28,19 @@ using System.Runtime.Serialization; using ASC.CRM.Classes; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; namespace ASC.CRM.Core { - [DataContract] - public class ContactInfo : DomainObject + public class ContactInfo : DomainObject, IMapFrom { - [DataMember(Name = "contactID")] public int ContactID { get; set; } - - [DataMember(Name = "infoType")] public ContactInfoType InfoType { get; set; } - - [DataMember(Name = "category")] public int Category { get; set; } - - [DataMember(Name = "data")] public String Data { get; set; } - - [DataMember(Name = "isPrimary")] public bool IsPrimary { get; set; } - - public static int GetDefaultCategory(ContactInfoType infoTypeEnum) { switch (infoTypeEnum) diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index 6d7f9892c84..10a525cae2c 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -27,26 +27,24 @@ using System; using System.Runtime.Serialization; +using ASC.CRM.Core.EF; +using ASC.CRM.Mapping; using ASC.CRM.Resources; namespace ASC.CRM.Core { - [DataContract] - public class CurrencyInfo + public class CurrencyInfo : IMapFrom { private readonly String _resourceKey; - [DataMember(Name = "title")] public String Title { get { - if (String.IsNullOrEmpty(_resourceKey)) return String.Empty; return CRMCommonResource.ResourceManager.GetString(_resourceKey); - } } @@ -56,6 +54,11 @@ public String Title public bool IsConvertable { get; set; } public bool IsBasic { get; set; } + public CurrencyInfo() + { + + } + public CurrencyInfo(string resourceKey, string abbreviation, string symbol, string cultureName, bool isConvertable, bool isBasic) { _resourceKey = resourceKey; diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs index 83ad8d09415..d288789face 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs @@ -27,26 +27,19 @@ using System; using System.Runtime.Serialization; +using ASC.CRM.Core.EF; +using ASC.CRM.Mapping; + namespace ASC.CRM.Core { - [DataContract] - public class CurrencyRate : DomainObject + public class CurrencyRate : DomainObject, IMapFrom { - [DataMember(Name = "fromCurrency")] public string FromCurrency { get; set; } - - [DataMember(Name = "toCurrency")] public string ToCurrency { get; set; } - - [DataMember(Name = "rate")] public decimal Rate { get; set; } - public Guid CreateBy { get; set; } - public DateTime CreateOn { get; set; } - public Guid? LastModifedBy { get; set; } - public DateTime? LastModifedOn { get; set; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/CustomField.cs b/products/ASC.CRM/Server/Core/Entities/CustomField.cs index 1f3b1a1fc81..dd72efa17c0 100644 --- a/products/ASC.CRM/Server/Core/Entities/CustomField.cs +++ b/products/ASC.CRM/Server/Core/Entities/CustomField.cs @@ -30,6 +30,7 @@ using System.Runtime.Serialization; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; #endregion @@ -44,22 +45,11 @@ public class CustomField : DomainObject [DataMember(Name = "entity_id")] public int EntityID { get; set; } - - [DataMember(Name = "label")] public String Label { get; set; } - - [DataMember(Name = "value")] public String Value { get; set; } - - [DataMember(Name = "fieldType")] public CustomFieldType FieldType { get; set; } - - [DataMember(Name = "position")] public int Position { get; set; } - - [DataMember(Name = "mask")] public String Mask { get; set; } - public override int GetHashCode() { return string.Format("{0}|{1}|{2}|{3}|{4}", GetType().FullName, ID, EntityID, Label, (int)FieldType).GetHashCode(); diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index 8a5bb762ad6..f5c99edff37 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -40,23 +40,14 @@ namespace ASC.CRM.Core.Entities public class Deal : DomainObject, ISecurityObjectId, IMapFrom { public Guid CreateBy { get; set; } - public DateTime CreateOn { get; set; } - public Guid? LastModifedBy { get; set; } - public DateTime? LastModifedOn { get; set; } [DataMember(Name = "contact_id")] public int ContactID { get; set; } - - [DataMember(Name = "contact")] public Contact Contact { get; set; } - - [DataMember(Name = "title")] public string Title { get; set; } - - [DataMember(Name = "description")] public string Description { get; set; } [DataMember(Name = "responsible_id")] diff --git a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs index e1abb32de0d..ef8ffb4c396 100644 --- a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs +++ b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs @@ -29,33 +29,23 @@ using System; using System.Runtime.Serialization; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; #endregion namespace ASC.CRM.Core.Entities { - - [DataContract] - public class DealMilestone : DomainObject + public class DealMilestone : DomainObject, IMapFrom { - [DataMember(Name = "title")] public String Title { get; set; } - - [DataMember(Name = "description")] public String Description { get; set; } - - [DataMember(Name = "color")] public String Color { get; set; } [DataMember(Name = "sort_order")] public int SortOrder { get; set; } - - [DataMember(Name = "probability")] public int Probability { get; set; } - - [DataMember(Name = "status")] public DealMilestoneStatus Status { get; set; } - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs index 8fc0c9ef523..5308924c5de 100644 --- a/products/ASC.CRM/Server/Core/Entities/Invoice.cs +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -29,59 +29,37 @@ using ASC.Common.Security; using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; using ASC.Files.Core; namespace ASC.CRM.Core.Entities { - public class Invoice : DomainObject, ISecurityObjectId + public class Invoice : DomainObject, ISecurityObjectId, IMapFrom { public InvoiceStatus Status { get; set; } - public string Number { get; set; } - public DateTime IssueDate { get; set; } - public InvoiceTemplateType TemplateType { get; set; } - public int ContactID { get; set; } - public int ConsigneeID { get; set; } - public EntityType EntityType { get; set; } - public int EntityID { get; set; } - public DateTime DueDate { get; set; } - public string Language { get; set; } - public string Currency { get; set; } - public decimal ExchangeRate { get; set; } - public string PurchaseOrderNumber { get; set; } - public string Terms { get; set; } - public string Description { get; set; } - public string JsonData { get; set; } - public int FileID { get; set; } - - public DateTime CreateOn { get; set; } - public Guid CreateBy { get; set; } - public DateTime? LastModifedOn { get; set; } - public Guid? LastModifedBy { get; set; } - - - public object SecurityId { get { return ID; } @@ -92,7 +70,6 @@ public Type ObjectType get { return GetType(); } } - public List GetInvoiceLines(DaoFactory daoFactory) { return daoFactory.GetInvoiceLineDao().GetInvoiceLines(ID); diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs index 9b487075c0a..b3068c00223 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs @@ -28,59 +28,31 @@ using System.Runtime.Serialization; using ASC.Common.Security; - +using ASC.CRM.Core.EF; +using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { [DataContract] - public class InvoiceItem : DomainObject, ISecurityObjectId + public class InvoiceItem : DomainObject, ISecurityObjectId, IMapFrom { - [DataMember(Name = "title")] public string Title { get; set; } - - [DataMember(Name = "description")] public string Description { get; set; } - - [DataMember(Name = "stockKeepingUnit")] public string StockKeepingUnit { get; set; } - - [DataMember(Name = "price")] public decimal Price { get; set; } - - [DataMember(Name = "stockQuantity")] public decimal StockQuantity { get; set; } - - [DataMember(Name = "trackInventory")] public bool TrackInventory { get; set; } - - [DataMember(Name = "invoiceTax1ID")] public int InvoiceTax1ID { get; set; } - - [DataMember(Name = "invoiceTax2ID")] public int InvoiceTax2ID { get; set; } - - [DataMember(Name = "currency")] public string Currency { get; set; } - - [DataMember(Name = "createOn")] public DateTime CreateOn { get; set; } - - [DataMember(Name = "createBy")] public Guid CreateBy { get; set; } - - [DataMember(Name = "lastModifedOn")] public DateTime? LastModifedOn { get; set; } - - [DataMember(Name = "lastModifedBy")] public Guid? LastModifedBy { get; set; } - - - public object SecurityId { get { return ID; } } - public Type ObjectType { get { return GetType(); } diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs index b8286344546..9897bcf9f51 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs @@ -23,26 +23,21 @@ * */ +using ASC.CRM.Core.EF; +using ASC.CRM.Mapping; + namespace ASC.CRM.Core.Entities { - public class InvoiceLine : DomainObject + public class InvoiceLine : DomainObject, IMapFrom { public int InvoiceID { get; set; } - public int InvoiceItemID { get; set; } - public int InvoiceTax1ID { get; set; } - public int InvoiceTax2ID { get; set; } - public int SortOrder { get; set; } - public string Description { get; set; } - public decimal Quantity { get; set; } - public decimal Price { get; set; } - public decimal Discount { get; set; } } } diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs index cd76e7d12cd..b6f92f4aa7d 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -38,26 +38,12 @@ namespace ASC.CRM.Core.Entities [DataContract] public class InvoiceTax : DomainObject, ISecurityObjectId, IMapFrom { - [DataMember(Name = "name")] public string Name { get; set; } - - [DataMember(Name = "description")] public string Description { get; set; } - - [DataMember(Name = "rate")] public decimal Rate { get; set; } - - - [DataMember(Name = "createOn")] public DateTime CreateOn { get; set; } - - [DataMember(Name = "createBy")] public Guid CreateBy { get; set; } - - [DataMember(Name = "lastModifedOn")] public DateTime? LastModifedOn { get; set; } - - [DataMember(Name = "lastModifedBy")] public Guid? LastModifedBy { get; set; } public object SecurityId diff --git a/products/ASC.CRM/Server/Core/Entities/ListItem.cs b/products/ASC.CRM/Server/Core/Entities/ListItem.cs index c446ae40f30..6e9ab04206d 100644 --- a/products/ASC.CRM/Server/Core/Entities/ListItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/ListItem.cs @@ -26,20 +26,27 @@ using System.Runtime.Serialization; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { - [DataContract] - public class ListItem : DomainObject + public class ListItem : DomainObject, IMapFrom { - [DataMember(Name = "title")] - public string Title { get; set; } + public ListItem() + { - [DataMember(Name = "description")] - public string Description { get; set; } + } + + public ListItem(string title, string addparams) + { + Title = title; + AdditionalParams = addparams; + } - [DataMember(Name = "color")] + public string Title { get; set; } + public string Description { get; set; } public string Color { get; set; } [DataMember(Name = "sort_order")] @@ -50,16 +57,5 @@ public class ListItem : DomainObject [DataMember(Name = "list_type")] public ListType? ListType { get; set; } - - - public ListItem() - { - } - - public ListItem(string title, string addparams) - { - Title = title; - AdditionalParams = addparams; - } } } diff --git a/products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs b/products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs index 4ed6a28e818..7006dbcf53a 100644 --- a/products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs +++ b/products/ASC.CRM/Server/Core/Entities/ListItemHistory.cs @@ -33,13 +33,9 @@ namespace ASC.CRM.Core.Entities public class ListItemHistory : DomainObject { public int EntityID { get; set; } - public EntityType EntityType { get; set; } - public int StatusID { get; set; } - public DateTime ModifedOn { get; set; } - public Guid ModifedBy { get; set; } } } diff --git a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs index 344127989b8..73a87139f84 100644 --- a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs @@ -29,12 +29,14 @@ using System; using ASC.Common.Security; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; #endregion namespace ASC.CRM.Core.Entities { - public class RelationshipEvent : DomainObject, ISecurityObjectId + public class RelationshipEvent : DomainObject, ISecurityObjectId, IMapFrom { public Guid CreateBy { get; set; } public DateTime CreateOn { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/Task.cs b/products/ASC.CRM/Server/Core/Entities/Task.cs index 82a30164016..78ac785bf2a 100644 --- a/products/ASC.CRM/Server/Core/Entities/Task.cs +++ b/products/ASC.CRM/Server/Core/Entities/Task.cs @@ -68,8 +68,6 @@ public Type ObjectType public void Mapping(Profile profile) { profile.CreateMap(); - // .ForMember(x => x.CreateOn, x => x.ConvertUsing()) - // .ForMember(x => x.LastModifedOn, x => x.ConvertUsing()); } } } diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs new file mode 100644 index 00000000000..20125a11cae --- /dev/null +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs @@ -0,0 +1,52 @@ +/* + * + * (c) Copyright Ascensio System Limited 2010-2018 + * + * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). + * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that + * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. + * + * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html + * + * You can contact Ascensio System SIA by email at sales@onlyoffice.com + * + * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display + * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. + * + * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains + * relevant author attributions when distributing the software. If the display of the logo in its graphic + * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" + * in every copy of the program you distribute. + * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. + * +*/ + + +#region Import + +using System; + +using ASC.CRM.Core.EF; +using ASC.CRM.Mapping; + +#endregion + +namespace ASC.CRM.Core.Entities +{ + public class TaskTemplate : DomainObject, IMapFrom + { + public int ContainerID { get; set; } + public String Title { get; set; } + public String Description { get; set; } + public Guid ResponsibleID { get; set; } + public int CategoryID { get; set; } + public bool isNotify { get; set; } + public TimeSpan Offset { get; set; } + public bool DeadLineIsFixed { get; set; } + public Guid CreateBy { get; set; } + public DateTime CreateOn { get; set; } + + } +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs index 3b93c80871c..954c6648f8d 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs @@ -28,42 +28,18 @@ using System; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; +using ASC.CRM.Mapping; #endregion namespace ASC.CRM.Core.Entities { - public class TaskTemplateContainer : DomainObject + public class TaskTemplateContainer : DomainObject, IMapFrom { - public String Title { get; set; } - public EntityType EntityType { get; set; } } - - public class TaskTemplate : DomainObject - { - public int ContainerID { get; set; } - - public String Title { get; set; } - - public String Description { get; set; } - - public Guid ResponsibleID { get; set; } - - public int CategoryID { get; set; } - - public bool isNotify { get; set; } - - public TimeSpan Offset { get; set; } - - public bool DeadLineIsFixed { get; set; } - - public Guid CreateBy { get; set; } - - public DateTime CreateOn { get; set; } - - } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index 16619e92f42..56d6b9c7a8a 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Linq; +using ASC.Common; using ASC.CRM.Core.Dao; using ASC.Files.Core; using ASC.Files.Core.Security; @@ -125,6 +126,7 @@ public bool CanCustomFilterEdit(FileEntry entry, Guid userId) } } + [Scope] public class FileSecurityProvider : IFileSecurityProvider { public FileSecurityProvider(FilesIntegration filesIntegration, diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index e376e0f7385..34d5110492c 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -33,6 +33,7 @@ public override void ConfigureServices(IServiceCollection services) base.ConfigureServices(services); + DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); @@ -61,6 +62,7 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); + DIHelper.TryAdd(); services.AddAutoMapper(Assembly.GetExecutingAssembly()); } From 9bdc643840dd3935468ac23aace045bd0d554d9f Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 30 Apr 2021 15:33:33 +0300 Subject: [PATCH 43/61] crm: add support WindowsService/systemd for IHostBuilder --- products/ASC.CRM/Server/ASC.CRM.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index d1959c2a240..37a6388282d 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -40,6 +40,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + From 424c6a680613f21d6bcae32429f12acb6e48dfc6 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 30 Apr 2021 17:52:57 +0300 Subject: [PATCH 44/61] migrate base mapper class from ASC.CRM to ASC.Common --- common/ASC.Common/ASC.Common.csproj | 1 + .../Mapping/Common => common/ASC.Common/Mapping}/IMapFrom.cs | 2 +- .../Common => common/ASC.Common/Mapping}/MappingProfile.cs | 2 +- products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs | 1 + products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs | 1 + products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs | 1 + products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs | 1 + products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs | 1 + .../ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs | 1 + .../Server/ApiModels/ResponsesDto/RelationshipEventDto.cs | 1 + products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs | 1 + products/ASC.CRM/Server/Core/Entities/Cases.cs | 1 + products/ASC.CRM/Server/Core/Entities/ContactInfo.cs | 1 + products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs | 1 + products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs | 1 + products/ASC.CRM/Server/Core/Entities/Deal.cs | 1 + products/ASC.CRM/Server/Core/Entities/DealMilestone.cs | 1 + products/ASC.CRM/Server/Core/Entities/Invoice.cs | 1 + products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs | 1 + products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs | 1 + products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs | 1 + products/ASC.CRM/Server/Core/Entities/ListItem.cs | 1 + products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs | 1 + products/ASC.CRM/Server/Core/Entities/Task.cs | 1 + products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs | 1 + products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs | 1 + 33 files changed, 33 insertions(+), 2 deletions(-) rename {products/ASC.CRM/Server/Mapping/Common => common/ASC.Common/Mapping}/IMapFrom.cs (98%) rename {products/ASC.CRM/Server/Mapping/Common => common/ASC.Common/Mapping}/MappingProfile.cs (98%) diff --git a/common/ASC.Common/ASC.Common.csproj b/common/ASC.Common/ASC.Common.csproj index 5663e3d79a5..a0e0576a2b1 100644 --- a/common/ASC.Common/ASC.Common.csproj +++ b/common/ASC.Common/ASC.Common.csproj @@ -32,6 +32,7 @@ + diff --git a/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs b/common/ASC.Common/Mapping/IMapFrom.cs similarity index 98% rename from products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs rename to common/ASC.Common/Mapping/IMapFrom.cs index 3b3f07c7f2e..3be8426f161 100644 --- a/products/ASC.CRM/Server/Mapping/Common/IMapFrom.cs +++ b/common/ASC.Common/Mapping/IMapFrom.cs @@ -25,7 +25,7 @@ using AutoMapper; -namespace ASC.CRM.Mapping +namespace ASC.Common.Mapping { public interface IMapFrom { diff --git a/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs b/common/ASC.Common/Mapping/MappingProfile.cs similarity index 98% rename from products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs rename to common/ASC.Common/Mapping/MappingProfile.cs index f63b8d384ab..2576650f8be 100644 --- a/products/ASC.CRM/Server/Mapping/Common/MappingProfile.cs +++ b/common/ASC.Common/Mapping/MappingProfile.cs @@ -29,7 +29,7 @@ using AutoMapper; -namespace ASC.CRM.Mapping +namespace ASC.Common.Mapping { public class MappingProfile : Profile { diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs index 5d534564085..872b0fb768d 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs @@ -29,6 +29,7 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; using ASC.Web.Api.Models; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs index 618f986678d..ac931c08d56 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -32,6 +32,7 @@ using ASC.Api.Core; using ASC.Common; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs index f9806955c85..9010605407c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs index 7bfe844d966..86a18933d99 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs index 2e50bf4435c..2add9041301 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index 994c0dfc1f3..9d777b0f89c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -28,6 +28,7 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs index 68ddc523b3c..dcc9ddcfb58 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs @@ -27,6 +27,7 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs index 997d96ff0d2..a642490862c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs @@ -26,6 +26,7 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; using ASC.Web.Api.Models; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs index bfefa0a354c..3042b453f39 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs @@ -25,6 +25,7 @@ using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs index cd4f33ccc26..0feeb230c3f 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs @@ -25,6 +25,7 @@ using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Classes; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs index cb7b225c390..03f44a18200 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs @@ -26,6 +26,7 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; using ASC.Web.Api.Models; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index 0ae032b75d2..e97a2302f10 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs index 3b5c83f550e..495d908605c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs @@ -29,6 +29,7 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs index c8b6ae99a0a..e49185d89cd 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs @@ -31,6 +31,7 @@ using ASC.Api.Core; using ASC.Api.Documents; using ASC.Common; +using ASC.Common.Mapping; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs index 8cfb0401a1b..f82b3457735 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs @@ -28,6 +28,7 @@ using System.Runtime.Serialization; using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.CRM.Core.Entities; using ASC.CRM.Mapping; using ASC.Web.Api.Models; diff --git a/products/ASC.CRM/Server/Core/Entities/Cases.cs b/products/ASC.CRM/Server/Core/Entities/Cases.cs index 571a87413d2..7e82ab08528 100644 --- a/products/ASC.CRM/Server/Core/Entities/Cases.cs +++ b/products/ASC.CRM/Server/Core/Entities/Cases.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs index dc9b9c486b8..5c2c17d7f37 100644 --- a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Classes; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index 10a525cae2c..12a59ede30d 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; using ASC.CRM.Resources; diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs index d288789face..45cbf26eb3e 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index f5c99edff37..d35e694cf99 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs index ef8ffb4c396..e4917aff6c3 100644 --- a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs +++ b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs @@ -29,6 +29,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs index 5308924c5de..47e2d3c2bdf 100644 --- a/products/ASC.CRM/Server/Core/Entities/Invoice.cs +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs index b3068c00223..96409c05569 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs index 9897bcf9f51..9f156becbad 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs @@ -23,6 +23,7 @@ * */ +using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs index b6f92f4aa7d..b888df27df6 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -27,6 +27,7 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/ListItem.cs b/products/ASC.CRM/Server/Core/Entities/ListItem.cs index 6e9ab04206d..93f9cafdc10 100644 --- a/products/ASC.CRM/Server/Core/Entities/ListItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/ListItem.cs @@ -26,6 +26,7 @@ using System.Runtime.Serialization; +using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs index 73a87139f84..dce86cebbb8 100644 --- a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs @@ -28,6 +28,7 @@ using System; +using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/Core/Entities/Task.cs b/products/ASC.CRM/Server/Core/Entities/Task.cs index 78ac785bf2a..bf0c47fb531 100644 --- a/products/ASC.CRM/Server/Core/Entities/Task.cs +++ b/products/ASC.CRM/Server/Core/Entities/Task.cs @@ -28,6 +28,7 @@ using System; +using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs index 20125a11cae..78b8dd97df7 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs @@ -28,6 +28,7 @@ using System; +using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Mapping; diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs index 954c6648f8d..b23b9576dc2 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs @@ -28,6 +28,7 @@ using System; +using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; From 2b0949c4c0ade01f1af6cddebf773662dff793c7 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 30 Apr 2021 18:08:15 +0300 Subject: [PATCH 45/61] remove unused project --- products/ASC.CRM/Core/ASC.CRM.Core.csproj | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 products/ASC.CRM/Core/ASC.CRM.Core.csproj diff --git a/products/ASC.CRM/Core/ASC.CRM.Core.csproj b/products/ASC.CRM/Core/ASC.CRM.Core.csproj deleted file mode 100644 index 0c8cf473251..00000000000 --- a/products/ASC.CRM/Core/ASC.CRM.Core.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - netcoreapp3.1 - - - - - - - - - - - - From 92ce702b28ba1f70faaf6f614106def84c0d9b45 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 5 May 2021 17:09:05 +0300 Subject: [PATCH 46/61] crm: refactoring. bugfix --- common/ASC.Api.Core/ASC.Api.Core.csproj | 4 + common/ASC.Api.Core/Core/BaseStartup.cs | 8 +- common/ASC.Common/Mapping/MappingProfile.cs | 4 +- products/ASC.CRM/Server/ASC.CRM.csproj | 1 - .../ASC.CRM/Server/Api/BaseApiController.cs | 4 +- .../ASC.CRM/Server/Api/CasesController.cs | 2 +- .../Server/Api/ContactInfosController.cs | 2 +- .../ASC.CRM/Server/Api/ContactsController.cs | 10 +- .../Server/Api/CurrencyRatesController.cs | 6 +- .../Server/Api/CustomFieldsController.cs | 2 +- .../ASC.CRM/Server/Api/DealsController.cs | 2 +- .../ASC.CRM/Server/Api/InvoicesController.cs | 4 +- .../ASC.CRM/Server/Api/ListItemsController.cs | 2 +- .../Api/RelationshipEventsController.cs | 2 +- .../ASC.CRM/Server/Api/ReportsController.cs | 6 +- products/ASC.CRM/Server/Api/TagsController.cs | 2 +- .../Server/Api/TaskTemplateController.cs | 2 +- .../ASC.CRM/Server/Api/TasksController.cs | 2 +- .../ASC.CRM/Server/Api/UtilsController.cs | 36 +-- products/ASC.CRM/Server/Api/VoipController.cs | 2 +- .../ASC.CRM/Server/Classes/CRMCalendar.cs | 4 +- .../ASC.CRM/Server/Classes/CRMSettings.cs | 10 +- products/ASC.CRM/Server/Classes/Global.cs | 8 +- products/ASC.CRM/Server/Classes/VoipEngine.cs | 4 +- .../CRMsSpaceUsageStatManager.cs | 4 +- .../Server/Configuration/ProductEntryPoint.cs | 226 ++---------------- products/ASC.CRM/Server/Core/CRMConstants.cs | 2 +- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 6 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 10 +- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 10 +- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 4 +- .../Server/Core/Dao/CurrencyInfoDao.cs | 39 ++- .../Server/Core/Dao/CurrencyRateDao.cs | 2 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 10 +- .../Server/Core/Dao/DealMilestoneDao.cs | 4 +- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 2 +- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 16 +- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 10 +- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 4 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 6 +- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 4 +- .../Server/Core/Dao/RelationshipEventDao.cs | 10 +- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 6 +- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 6 +- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 2 +- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 10 +- .../Core/Dao/TaskTemplateContainerDao.cs | 4 +- .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 6 +- .../Server/Core/EF/CrmDbContextSeed.cs | 193 +++++++++++++++ .../Server/Core/Entities/CurrencyInfo.cs | 46 ++-- products/ASC.CRM/Server/Core/Entities/Deal.cs | 5 - .../Security/CRMSecurityObjectProvider.cs | 2 +- .../Server/Core/Security/CRMSecutiry.cs | 6 +- .../Core/Security/FileSecurityProvider.cs | 8 +- .../TypeConverter/CasesDtoTypeConverter.cs | 6 +- .../TypeConverter/ContactDtoTypeConverter.cs | 6 +- .../CustomFieldDtoTypeConverter.cs | 2 + .../DealMilestoneDtoTypeConverter.cs | 2 + .../InvoiceBaseDtoTypeConverter.cs | 6 +- .../TypeConverter/InvoiceDtoTypeConverter.cs | 8 +- .../InvoiceItemDtoTypeConverter.cs | 8 +- .../InvoiceTaxDtoTypeConverter.cs | 6 +- .../TypeConverter/ListItemDtoTypeConverter.cs | 2 + .../OpportunityDtoTypeConverter.cs | 14 +- .../RelationshipEventDtoTypeConverter.cs | 4 +- .../TypeConverter/TaskDtoTypeConverter.cs | 8 +- .../ContactPhotoHandler.cs | 11 +- .../FileHandler.cs | 0 .../FileUploaderHandler.cs | 0 .../ImportFileHandler.cs | 2 +- .../OrganisationLogoHandler.cs | 2 +- .../Middlewares/TenantConfigureMiddleware.cs | 31 +++ .../WebToLeadFromHandler.cs | 6 +- products/ASC.CRM/Server/Program.cs | 3 +- products/ASC.CRM/Server/Startup.cs | 10 +- .../ASC.CRM/Server/Utils/CurrencyProvider.cs | 2 +- .../Utils/Import/CSV/ImportDataOperation.cs | 4 +- .../Server/Utils/Import/CSV/ImportDeals.cs | 2 +- products/ASC.CRM/Server/Utils/MailSender.cs | 2 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 4 +- 81 files changed, 505 insertions(+), 440 deletions(-) create mode 100644 products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs rename products/ASC.CRM/Server/{HttpHandlers => Middlewares}/ContactPhotoHandler.cs (94%) rename products/ASC.CRM/Server/{HttpHandlers => Middlewares}/FileHandler.cs (100%) rename products/ASC.CRM/Server/{HttpHandlers => Middlewares}/FileUploaderHandler.cs (100%) rename products/ASC.CRM/Server/{HttpHandlers => Middlewares}/ImportFileHandler.cs (98%) rename products/ASC.CRM/Server/{HttpHandlers => Middlewares}/OrganisationLogoHandler.cs (99%) create mode 100644 products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs rename products/ASC.CRM/Server/{HttpHandlers => Middlewares}/WebToLeadFromHandler.cs (99%) diff --git a/common/ASC.Api.Core/ASC.Api.Core.csproj b/common/ASC.Api.Core/ASC.Api.Core.csproj index a6f4e553ce2..131a6c284bc 100644 --- a/common/ASC.Api.Core/ASC.Api.Core.csproj +++ b/common/ASC.Api.Core/ASC.Api.Core.csproj @@ -9,6 +9,10 @@ false + + + + diff --git a/common/ASC.Api.Core/Core/BaseStartup.cs b/common/ASC.Api.Core/Core/BaseStartup.cs index 7e257b224ca..b81527c2e95 100644 --- a/common/ASC.Api.Core/Core/BaseStartup.cs +++ b/common/ASC.Api.Core/Core/BaseStartup.cs @@ -1,4 +1,5 @@ -using System.Text.Json.Serialization; +using System.Reflection; +using System.Text.Json.Serialization; using ASC.Api.Core.Auth; using ASC.Api.Core.Convention; @@ -8,6 +9,7 @@ using ASC.Common.Caching; using ASC.Common.DependencyInjection; using ASC.Common.Logging; +using ASC.Common.Mapping; using Autofac; @@ -112,7 +114,9 @@ public virtual void ConfigureServices(IServiceCollection services) if (LogParams != null) { LogNLogExtension.ConfigureLog(DIHelper, LogParams); - } + } + + services.AddAutoMapper(Assembly.GetAssembly(typeof(MappingProfile))); } public virtual void Configure(IApplicationBuilder app, IWebHostEnvironment env) diff --git a/common/ASC.Common/Mapping/MappingProfile.cs b/common/ASC.Common/Mapping/MappingProfile.cs index 2576650f8be..3d16f3f2282 100644 --- a/common/ASC.Common/Mapping/MappingProfile.cs +++ b/common/ASC.Common/Mapping/MappingProfile.cs @@ -35,11 +35,13 @@ public class MappingProfile : Profile { public MappingProfile() { - ApplyMappingsFromAssembly(Assembly.GetExecutingAssembly()); + Array.ForEach(AppDomain.CurrentDomain.GetAssemblies(), a => ApplyMappingsFromAssembly(a)); } private void ApplyMappingsFromAssembly(Assembly assembly) { + if (!assembly.GetName().Name.StartsWith("ASC.")) return; + var types = assembly.GetExportedTypes() .Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>))) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 37a6388282d..fc1ee846013 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -34,7 +34,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/products/ASC.CRM/Server/Api/BaseApiController.cs b/products/ASC.CRM/Server/Api/BaseApiController.cs index 38a9d8a9263..b4130f0f3e4 100644 --- a/products/ASC.CRM/Server/Api/BaseApiController.cs +++ b/products/ASC.CRM/Server/Api/BaseApiController.cs @@ -48,10 +48,10 @@ public abstract class BaseApiController : ControllerBase { protected IMapper _mapper; protected DaoFactory _daoFactory; - protected CRMSecurity _crmSecurity; + protected CrmSecurity _crmSecurity; public BaseApiController(DaoFactory daoFactory, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, IMapper mapper) { _daoFactory = daoFactory; diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index acbd69e6cf2..97ccfc60797 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -61,7 +61,7 @@ public class CasesController : BaseApiController private readonly MessageTarget _messageTarget; private readonly UserManager _userManager; - public CasesController(CRMSecurity crmSecurity, + public CasesController(CrmSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index 12b8a364353..061adaff4f2 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -53,7 +53,7 @@ public class ContactInfosController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public ContactInfosController(CRMSecurity crmSecurity, + public ContactInfosController(CrmSecurity crmSecurity, DaoFactory daoFactory, MessageTarget messageTarget, MessageService messageService, diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index b86925b43eb..4ea4faedede 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -73,7 +73,7 @@ public class ContactsController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public ContactsController(CRMSecurity crmSecurity, + public ContactsController(CrmSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, @@ -374,7 +374,8 @@ public IEnumerable GetContacts( if (contactsOrderBy != null) { - result = _mapper.Map, List>(_daoFactory.GetContactDao().GetContacts( + + var contacts = _daoFactory.GetContactDao().GetContacts( searchString, tags, contactStageInt, @@ -386,7 +387,10 @@ public IEnumerable GetContacts( count, contactsOrderBy, responsibleid, - isShared)); + isShared); + + result = _mapper.Map, List>(contacts); + _apiContext.SetDataPaginated(); _apiContext.SetDataFiltered(); _apiContext.SetDataSorted(); diff --git a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs index 896ab957efd..6ac52f9b239 100644 --- a/products/ASC.CRM/Server/Api/CurrencyRatesController.cs +++ b/products/ASC.CRM/Server/Api/CurrencyRatesController.cs @@ -51,7 +51,7 @@ public class CurrencyRatesController : BaseApiController private readonly Global _global; private readonly MessageService _messageService; - public CurrencyRatesController(CRMSecurity crmSecurity, + public CurrencyRatesController(CrmSecurity crmSecurity, DaoFactory daoFactory, MessageService messageService, SettingsManager settingsManager, @@ -204,8 +204,8 @@ public List SetCurrencyRates( currency = currency.ToUpper(); - var crmSettings = _settingsManager.Load(); - var defaultCurrency = _currencyProvider.Get(_settingsManager.Load().DefaultCurrency); + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(_settingsManager.Load().DefaultCurrency); if (defaultCurrency.Abbreviation != currency) { diff --git a/products/ASC.CRM/Server/Api/CustomFieldsController.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs index 4da9d644382..9a766f70a9f 100644 --- a/products/ASC.CRM/Server/Api/CustomFieldsController.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -49,7 +49,7 @@ public class CustomFieldsController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public CustomFieldsController(CRMSecurity crmSecurity, + public CustomFieldsController(CrmSecurity crmSecurity, DaoFactory daoFactory, MessageTarget messageTarget, MessageService messageService, diff --git a/products/ASC.CRM/Server/Api/DealsController.cs b/products/ASC.CRM/Server/Api/DealsController.cs index 6f573fae14d..35407d9dd72 100644 --- a/products/ASC.CRM/Server/Api/DealsController.cs +++ b/products/ASC.CRM/Server/Api/DealsController.cs @@ -63,7 +63,7 @@ public class DealsController : BaseApiController private readonly UserManager _userManager; private readonly EmployeeWraperHelper _employeeWraperHelper; - public DealsController(CRMSecurity crmSecurity, + public DealsController(CrmSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, diff --git a/products/ASC.CRM/Server/Api/InvoicesController.cs b/products/ASC.CRM/Server/Api/InvoicesController.cs index d79c4c9b3fa..f1105ccd0d5 100644 --- a/products/ASC.CRM/Server/Api/InvoicesController.cs +++ b/products/ASC.CRM/Server/Api/InvoicesController.cs @@ -64,7 +64,7 @@ public class InvoicesController : BaseApiController private readonly MessageTarget _messageTarget; private readonly CurrencyProvider _currencyProvider; - public InvoicesController(CRMSecurity crmSecurity, + public InvoicesController(CrmSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, @@ -125,7 +125,7 @@ public InvoiceDto GetInvoiceByID(int invoiceid) [Read(@"invoice/sample")] public InvoiceDto GetInvoiceSample() { - var crmSettings = _settingsManager.Load(); + var crmSettings = _settingsManager.Load(); var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); var sample = InvoiceDto.GetSample(); diff --git a/products/ASC.CRM/Server/Api/ListItemsController.cs b/products/ASC.CRM/Server/Api/ListItemsController.cs index 812cc428e1a..b879069a0dc 100644 --- a/products/ASC.CRM/Server/Api/ListItemsController.cs +++ b/products/ASC.CRM/Server/Api/ListItemsController.cs @@ -49,7 +49,7 @@ public class ListItemsController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public ListItemsController(CRMSecurity crmSecurity, + public ListItemsController(CrmSecurity crmSecurity, DaoFactory daoFactory, MessageTarget messageTarget, MessageService messageService, diff --git a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs index be56f8b4fe3..87bf6de520c 100644 --- a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs +++ b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs @@ -71,7 +71,7 @@ public class RelationshipEventsController : BaseApiController private readonly NotifyClient _notifyClient; public RelationshipEventsController( - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, diff --git a/products/ASC.CRM/Server/Api/ReportsController.cs b/products/ASC.CRM/Server/Api/ReportsController.cs index 17da3265c4b..2c33e9cf597 100644 --- a/products/ASC.CRM/Server/Api/ReportsController.cs +++ b/products/ASC.CRM/Server/Api/ReportsController.cs @@ -53,7 +53,7 @@ public class ReportsController : BaseApiController private readonly Global _global; private readonly SettingsManager _settingsManager; - public ReportsController(CRMSecurity crmSecurity, + public ReportsController(CrmSecurity crmSecurity, DaoFactory daoFactory, SettingsManager settingsManager, Global global, @@ -89,7 +89,7 @@ public IEnumerable> GetFiles() if (!files.Any()) { - var settings = _settingsManager.Load(); + var settings = _settingsManager.Load(); if (settings.NeedToGenerate) { @@ -97,7 +97,7 @@ public IEnumerable> GetFiles() settings.NeedToGenerate = false; - _settingsManager.Save(settings); + _settingsManager.Save(settings); } } diff --git a/products/ASC.CRM/Server/Api/TagsController.cs b/products/ASC.CRM/Server/Api/TagsController.cs index 3b914e87943..86f685e3826 100644 --- a/products/ASC.CRM/Server/Api/TagsController.cs +++ b/products/ASC.CRM/Server/Api/TagsController.cs @@ -52,7 +52,7 @@ public class TagsController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public TagsController(CRMSecurity crmSecurity, + public TagsController(CrmSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, diff --git a/products/ASC.CRM/Server/Api/TaskTemplateController.cs b/products/ASC.CRM/Server/Api/TaskTemplateController.cs index 5802bb4515e..79a179e2170 100644 --- a/products/ASC.CRM/Server/Api/TaskTemplateController.cs +++ b/products/ASC.CRM/Server/Api/TaskTemplateController.cs @@ -47,7 +47,7 @@ public class TaskTemplateController : BaseApiController { private readonly EmployeeWraperHelper _employeeWraperHelper; - public TaskTemplateController(CRMSecurity crmSecurity, + public TaskTemplateController(CrmSecurity crmSecurity, DaoFactory daoFactory, EmployeeWraperHelper employeeWraperHelper, IMapper mapper) diff --git a/products/ASC.CRM/Server/Api/TasksController.cs b/products/ASC.CRM/Server/Api/TasksController.cs index 8ce9c5cc333..66526646d30 100644 --- a/products/ASC.CRM/Server/Api/TasksController.cs +++ b/products/ASC.CRM/Server/Api/TasksController.cs @@ -28,7 +28,7 @@ public class TasksController : BaseApiController private readonly MessageService _messageService; private readonly MessageTarget _messageTarget; - public TasksController(CRMSecurity crmSecurity, + public TasksController(CrmSecurity crmSecurity, DaoFactory daoFactory, ApiContext apiContext, MessageTarget messageTarget, diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index e5998c080d5..4ae96ab59b6 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -62,7 +62,7 @@ public class UtilsController : BaseApiController private readonly CurrencyProvider _currencyProvider; private readonly MessageService _messageService; - public UtilsController(CRMSecurity crmSecurity, + public UtilsController(CrmSecurity crmSecurity, DaoFactory daoFactory, MessageService messageService, SettingsManager settingsManager, @@ -164,11 +164,11 @@ public IEnumerable GetSummaryTable(String currency) [Update(@"contact/status/settings")] public Boolean? UpdateCRMContactStatusSettings(Boolean? changeContactStatusGroupAuto) { - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.ChangeContactStatusGroupAuto = changeContactStatusGroupAuto; - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); _messageService.Send(MessageAction.ContactTemperatureLevelSettingsUpdated); @@ -188,11 +188,11 @@ public IEnumerable GetSummaryTable(String currency) [Update(@"contact/mailtohistory/settings")] public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAuto) { - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.WriteMailToHistoryAuto = writeMailToHistoryAuto; - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); //MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated); return writeMailToHistoryAuto; @@ -211,10 +211,10 @@ public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAut [Update(@"contact/tag/settings")] public Boolean? UpdateCRMContactTagSettings(Boolean? addTagToContactGroupAuto) { - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.AddTagToContactGroupAuto = addTagToContactGroupAuto; - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); _messageService.Send(MessageAction.ContactsTagSettingsUpdated); @@ -235,12 +235,12 @@ public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.IsConfiguredPortal = configured ?? true; tenantSettings.WebFormKey = webFormKey ?? Guid.NewGuid(); - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); return tenantSettings.IsConfiguredPortal; } @@ -258,7 +258,7 @@ public String UpdateOrganisationSettingsCompanyName(String companyName) { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { @@ -266,7 +266,7 @@ public String UpdateOrganisationSettingsCompanyName(String companyName) } tenantSettings.InvoiceSetting.CompanyName = companyName; - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); _messageService.Send(MessageAction.OrganizationProfileUpdatedCompanyName, companyName); @@ -290,7 +290,7 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { @@ -309,7 +309,7 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit tenantSettings.InvoiceSetting.CompanyAddress = companyAddress; - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); _messageService.Send(MessageAction.OrganizationProfileUpdatedAddress); @@ -345,7 +345,7 @@ public Int32 UpdateOrganisationSettingsLogo(bool reset) companyLogoID = 0; } - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { @@ -353,7 +353,7 @@ public Int32 UpdateOrganisationSettingsLogo(bool reset) } tenantSettings.InvoiceSetting.CompanyLogoID = companyLogoID; - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); _messageService.Send(MessageAction.OrganizationProfileUpdatedInvoiceLogo); @@ -377,7 +377,7 @@ public String GetOrganisationSettingsLogo(int id) } else { - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); if (tenantSettings.InvoiceSetting == null) { @@ -400,11 +400,11 @@ public string ChangeWebToLeadFormKey() { if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException(); - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.WebFormKey = Guid.NewGuid(); - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); _messageService.Send(MessageAction.WebsiteContactFormUpdatedKey); diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index 186f67ab54e..9d243e70273 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -72,7 +72,7 @@ public class VoIPController : BaseApiController private readonly ContactPhotoManager _contactPhotoManager; private readonly Global _global; - public VoIPController(CRMSecurity crmSecurity, + public VoIPController(CrmSecurity crmSecurity, DaoFactory daoFactory, Global global, ContactPhotoManager contactPhotoManager, diff --git a/products/ASC.CRM/Server/Classes/CRMCalendar.cs b/products/ASC.CRM/Server/Classes/CRMCalendar.cs index 46bb16b53f4..2ee8bc11893 100644 --- a/products/ASC.CRM/Server/Classes/CRMCalendar.cs +++ b/products/ASC.CRM/Server/Classes/CRMCalendar.cs @@ -41,7 +41,7 @@ namespace ASC.CRM.Api { [Scope] - public sealed class CRMCalendar : BaseCalendar + public sealed class CrmCalendar : BaseCalendar { [AllDayLongUTC] private class Event : BaseEvent @@ -53,7 +53,7 @@ private class Event : BaseEvent public TenantManager TenantManager { get; } public TenantUtil TenantUtil { get; } - public CRMCalendar(WebItemSecurity webItemSecurity, + public CrmCalendar(WebItemSecurity webItemSecurity, DaoFactory daoFactory, AuthContext authContext, TimeZoneConverter timeZoneConverter, diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index 0fb534467a2..db86e473dfe 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -116,9 +116,9 @@ public InvoiceSetting DefaultSettings [Serializable] [DataContract] - public class CRMSettings : ISettings + public class CrmSettings : ISettings { - public CRMSettings() + public CrmSettings() { } @@ -173,7 +173,7 @@ public ISettings GetDefault(IServiceProvider serviceProvider) var findedCurrency = currencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); - return new CRMSettings() + return new CrmSettings() { DefaultCurrency = findedCurrency != null ? findedCurrency.Abbreviation : "USD", IsConfiguredPortal = false, @@ -189,7 +189,7 @@ public ISettings GetDefault(IServiceProvider serviceProvider) [Serializable] [DataContract] - public class CRMReportSampleSettings : ISettings + public class CrmReportSampleSettings : ISettings { [DataMember(Name = "NeedToGenerate")] public bool NeedToGenerate { get; set; } @@ -201,7 +201,7 @@ public Guid ID public ISettings GetDefault(IServiceProvider serviceProvider) { - return new CRMReportSampleSettings { NeedToGenerate = true }; + return new CrmReportSampleSettings { NeedToGenerate = true }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index f3c4294e493..0fe17aeb859 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -54,7 +54,7 @@ public Global(StorageFactory storageFactory, SecurityContext securityContext, SetupInfo setupInfo, FilesLinkUtility filesLinkUtility, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantManager tenantManager, SettingsManager settingsManager, IConfiguration configuration @@ -97,7 +97,7 @@ IConfiguration configuration public StorageFactory StorageFactory { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public IDataStore GetStore() { @@ -174,10 +174,10 @@ public bool CanCreateReports public void SaveDefaultCurrencySettings(CurrencyInfo currency) { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = SettingsManager.Load(); tenantSettings.DefaultCurrency = currency.Abbreviation; - SettingsManager.Save(tenantSettings); + SettingsManager.Save(tenantSettings); } diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index a7abf947e7a..26dd1a8ac35 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -53,7 +53,7 @@ public class VoipEngine private readonly object Locker = new object(); public VoipEngine(DaoFactory daoFactory, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, SecurityContext securityContext, IOptionsMonitor logger, @@ -83,7 +83,7 @@ public VoipEngine(DaoFactory daoFactory, public TenantUtil TenantUtil { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public VoipCall SaveOrUpdateCall(VoipCall callHistory) { diff --git a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs index be6cfb37f97..e2c3d2373fa 100644 --- a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs +++ b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs @@ -42,9 +42,9 @@ namespace ASC.Web.CRM.Configuration { [Scope] - public class CRMSpaceUsageStatManager : SpaceUsageStatManager + public class CrmSpaceUsageStatManager : SpaceUsageStatManager { - public CRMSpaceUsageStatManager(DbContextManager filesDbContext, + public CrmSpaceUsageStatManager(DbContextManager filesDbContext, PathProvider pathProvider, TenantManager tenantManager) { diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index 7f1b884975c..f30232f5d1a 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -51,43 +51,24 @@ public class ProductEntryPoint : Product public ProductEntryPoint(SecurityContext securityContext, UserManager userManager, PathProvider pathProvider, - DaoFactory daoFactory, - FilesIntegration filesIntegration, - IOptionsMonitor logger, - SettingsManager settingsManager, - CoreConfiguration coreConfiguration, - FileSecurityProvider fileSecurityProvider) + FilesIntegration filesIntegration) { SecurityContext = securityContext; UserManager = userManager; PathProvider = pathProvider; - DaoFactory = daoFactory; FilesIntegration = filesIntegration; - Logger = logger.Get("ASC"); - SettingsManager = settingsManager; - CoreConfiguration = coreConfiguration; - FileSecurityProvider = fileSecurityProvider; } public static readonly Guid ID = WebItemManager.CRMProductID; - - private ProductContext context; - - private static readonly object Locker = new object(); - private static readonly bool registered; - - public FileSecurityProvider FileSecurityProvider { get; } - public CoreConfiguration CoreConfiguration { get; } - public ILog Logger { get; } - public SettingsManager SettingsManager { get; } + private ProductContext _context; public FilesIntegration FilesIntegration { get; } - public DaoFactory DaoFactory { get; } public PathProvider PathProvider { get; } public SecurityContext SecurityContext { get; } public UserManager UserManager { get; } - - // TODO: CRM: Реализовать проперти ApiURL - public override string ApiURL => throw new NotImplementedException(); + public override string ApiURL + { + get => "api/2.0/crm/info.json"; + } public override Guid ProductID { get { return ID; } } public override string Name { get { return CRMCommonResource.ProductName; } } public override string Description @@ -107,12 +88,12 @@ public override string Description public override string HelpURL { get { return string.Concat(PathProvider.BaseVirtualPath, "help.aspx"); } } public override string ProductClassName { get { return "crm"; } } public override bool Visible { get { return true; } } - public override ProductContext Context { get { return context; } } + public override ProductContext Context { get { return _context; } } public string ModuleSysName { get; set; } public override void Init() { - context = new ProductContext + _context = new ProductContext { DisabledIconFileName = "product_disabled_logo.png", IconFileName = "product_logo.png", @@ -124,14 +105,14 @@ public override void Init() UserOpportunities = () => CRMCommonResource.ProductUserOpportunities.Split('|').ToList(), }; - if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) - { - FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", FileSecurityProvider); - } - if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "opportunity")) - { - FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", FileSecurityProvider); - } + //if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common")) + //{ + // FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", FileSecurityProvider); + //} + //if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "opportunity")) + //{ + // FilesIntegration.RegisterFileSecurityProvider("crm", "opportunity", FileSecurityProvider); + //} // SearchHandlerManager.Registry(new SearchHandler()); @@ -143,181 +124,6 @@ public override void Init() // ClientScriptLocalization = new ClientLocalizationResources(); } - - public void ConfigurePortal() - { - var tenantSettings = SettingsManager.Load(); - - if (!tenantSettings.IsConfiguredPortal) - { - // Task Category - var listItemDao = DaoFactory.GetListItemDao(); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Call, "task_category_call.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Deal, "task_category_deal.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Demo, "task_category_demo.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Email, "task_category_email.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Fax, "task_category_fax.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_FollowUP, "task_category_follow_up.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Lunch, "task_category_lunch.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Meeting, "task_category_meeting.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Note, "task_category_note.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Ship, "task_category_ship.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_SocialNetworks, "task_category_social_networks.png")); - listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_ThankYou, "task_category_thank_you.png")); - - // Deal Milestone New - var milestoneDao = DaoFactory.GetDealMilestoneDao(); - - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_InitialContact_Title, - Description = CRMDealResource.DealMilestone_InitialContact_Description, - Probability = 1, - Color = "#e795c1", - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Preapproach_Title, - Description = CRMDealResource.DealMilestone_Preapproach_Description, - Probability = 2, - Color = "#df7895", - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Suspect_Title, - Description = CRMDealResource.DealMilestone_Suspect_Description, - Probability = 3, - Color = "#f48454", - SortOrder = 1, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Champion_Title, - Description = CRMDealResource.DealMilestone_Champion_Description, - Probability = 20, - Color = "#b58fd6", - SortOrder = 2, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Opportunity_Title, - Description = CRMDealResource.DealMilestone_Opportunity_Description, - Probability = 50, - Color = "#d28cc8", - SortOrder = 3, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Prospect_Title, - Description = CRMDealResource.DealMilestone_Prospect_Description, - Probability = 75, - Color = "#ffb45e", - SortOrder = 4, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Verbal_Title, - Description = CRMDealResource.DealMilestone_Verbal_Description, - Probability = 90, - Color = "#ffd267", - SortOrder = 5, - Status = DealMilestoneStatus.Open - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Won_Title, - Description = CRMDealResource.DealMilestone_Won_Description, - Probability = 100, - Color = "#6bbd72", - SortOrder = 6, - Status = DealMilestoneStatus.ClosedAndWon - }); - milestoneDao.Create(new DealMilestone - { - Title = CRMDealResource.DealMilestone_Lost_Title, - Description = CRMDealResource.DealMilestone_Lost_Description, - Probability = 0, - Color = "#f2a9be", - SortOrder = 7, - Status = DealMilestoneStatus.ClosedAndLost - }); - - // Contact Status - listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Cold, Color = "#8a98d8", SortOrder = 1 }); - listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Warm, Color = "#ffd267", SortOrder = 2 }); - listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Hot, Color = "#df7895", SortOrder = 3 }); - // Contact Type - listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Client, SortOrder = 1 }); - listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Supplier, SortOrder = 2 }); - listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Partner, SortOrder = 3 }); - listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Competitor, SortOrder = 4 }); - - // History Category - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Note, "event_category_note.png")); - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Email, "event_category_email.png")); - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png")); - listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Meeting, "event_category_meeting.png")); - // Tags - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Lead, true); - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Customer, true); - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Supplier, true); - DaoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Staff, true); - - tenantSettings.WebFormKey = Guid.NewGuid(); - tenantSettings.IsConfiguredPortal = true; - - if (!SettingsManager.Save(tenantSettings)) - { - throw new Exception("not save CRMSettings"); - } - } - - if (!tenantSettings.IsConfiguredSmtp) - { - var smtp = SettingsManager.Load().SMTPServerSettingOld; - - if (smtp != null && CoreConfiguration.SmtpSettings.IsDefaultSettings) - { - try - { - var newSettings = new SmtpSettings(smtp.Host, smtp.Port, smtp.SenderEmailAddress, - smtp.SenderDisplayName) - { - EnableSSL = smtp.EnableSSL, - EnableAuth = smtp.RequiredHostAuthentication, - }; - - if (!string.IsNullOrEmpty(smtp.HostLogin) && !string.IsNullOrEmpty(smtp.HostPassword)) - { - newSettings.SetCredentials(smtp.HostLogin, smtp.HostPassword); - } - - CoreConfiguration.SmtpSettings = newSettings; - - } - catch (Exception e) - { - Logger.Error("ConfigurePortal", e); - } - } - - - tenantSettings.IsConfiguredSmtp = true; - - if (!SettingsManager.Save(tenantSettings)) - { - throw new Exception("not save CRMSettings"); - } - - } - } - //public override void Shutdown() //{ // if (registered) diff --git a/products/ASC.CRM/Server/Core/CRMConstants.cs b/products/ASC.CRM/Server/Core/CRMConstants.cs index 08c076f7ea4..b160015338f 100644 --- a/products/ASC.CRM/Server/Core/CRMConstants.cs +++ b/products/ASC.CRM/Server/Core/CRMConstants.cs @@ -28,7 +28,7 @@ namespace ASC.CRM.Core { - public static class CRMConstants + public static class CrmConstants { public static readonly String StorageModule = "crm"; public static readonly String DatabaseId = "crm"; diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index 2b5245f1cb6..5d04bd43e2f 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -46,14 +46,14 @@ namespace ASC.CRM.Core.Dao public class AbstractDao { protected readonly List _supportedEntityType = new List(); - public CRMDbContext CRMDbContext { get; } + public CrmDbContext CRMDbContext { get; } protected SecurityContext _securityContext; protected readonly ICache _cache; protected ILog _logger; protected IMapper _mapper; public AbstractDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, @@ -65,7 +65,7 @@ IMapper mapper _logger = logger.Get("ASC.CRM"); _cache = ascCache; - CRMDbContext = dbContextManager.Get(CRMConstants.DatabaseId); + CRMDbContext = dbContextManager.Get(CrmConstants.DatabaseId); TenantID = tenantManager.GetCurrentTenant().TenantId; _securityContext = securityContext; diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index e5bbc97b43f..732566b2698 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -59,10 +59,10 @@ public class CachedCasesDao : CasesDao { private readonly HttpRequestDictionary _casesCache; - public CachedCasesDao(DbContextManager dbContextManager, + public CachedCasesDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, @@ -123,10 +123,10 @@ private void ResetCache(int taskID) public class CasesDao : AbstractDao { public CasesDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, FilesIntegration filesIntegration, AuthorizationManager authorizationManager, @@ -157,7 +157,7 @@ IMapper mapper public TenantUtil TenantUtil { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public void AddMember(int caseID, int memberID) { diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index bd4745020d6..05b0cf2fbed 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -59,10 +59,10 @@ public class CachedContactDao : ContactDao private readonly HttpRequestDictionary _contactCache; public CachedContactDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, IHttpContextAccessor httpContextAccessor, TenantUtil tenantUtil, AuthorizationManager authorizationManager, @@ -139,10 +139,10 @@ private void ResetCache(int contactID) public class ContactDao : AbstractDao { public ContactDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, AuthorizationManager authorizationManager, FilesIntegration filesIntegration, @@ -180,7 +180,7 @@ IMapper mapper public FilesIntegration FilesIntegration { get; } public AuthorizationManager AuthorizationManager { get; } public TenantUtil TenantUtil { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } private readonly String _displayNameSeparator = "!=!"; diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index d545d108990..251431753ac 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -51,7 +51,7 @@ public class CachedContactInfo : ContactInfoDao private readonly HttpRequestDictionary _contactInfoCache; public CachedContactInfo( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, @@ -119,7 +119,7 @@ public override int Update(ContactInfo contactInfo) public class ContactInfoDao : AbstractDao { public ContactInfoDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 5f445cfc405..8e633ed02e5 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -44,7 +44,7 @@ namespace ASC.CRM.Core.Dao [Scope] public class CurrencyInfoDao : AbstractDao { - public CurrencyInfoDao(DbContextManager dbContextManager, + public CurrencyInfoDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, @@ -63,41 +63,36 @@ public CurrencyInfoDao(DbContextManager dbContextManager, public virtual List GetAll() { - return CRMDbContext.CurrencyInfo.ToList().ConvertAll(ToCurrencyInfo); + var dbItems = CRMDbContext.CurrencyInfo.ToList(); + + return _mapper.Map, List>(dbItems); } public virtual CurrencyInfo GetByAbbreviation(string abbreviation) { - return ToCurrencyInfo(CRMDbContext.CurrencyInfo - .FirstOrDefault(x => String.Compare(x.Abbreviation, abbreviation, true) == 0)); + var dbItem = CRMDbContext.CurrencyInfo + .FirstOrDefault(x => String.Compare(x.Abbreviation, abbreviation, true) == 0); + + return _mapper.Map(dbItem); + } public List GetBasic() { - return CRMDbContext.CurrencyInfo + var dbItems = CRMDbContext.CurrencyInfo .Where(x => x.IsBasic) - .ToList() - .ConvertAll(ToCurrencyInfo); + .ToList(); + + return _mapper.Map, List>(dbItems); } public List GetOther() { - return CRMDbContext.CurrencyInfo - .Where(x => !x.IsBasic) - .ToList() - .ConvertAll(ToCurrencyInfo); - } + var dbItems = CRMDbContext.CurrencyInfo + .Where(x => !x.IsBasic) + .ToList(); - private static CurrencyInfo ToCurrencyInfo(DbCurrencyInfo dbCurrencyInfo) - { - return new CurrencyInfo( - dbCurrencyInfo.ResourceKey, - dbCurrencyInfo.Abbreviation, - dbCurrencyInfo.Abbreviation, - dbCurrencyInfo.CultureName, - dbCurrencyInfo.IsConvertable, - dbCurrencyInfo.IsBasic - ); + return _mapper.Map, List>(dbItems); } } } diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index d1ee1e54ce8..48e28a3e9a0 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -44,7 +44,7 @@ namespace ASC.CRM.Core.Dao public class CurrencyRateDao : AbstractDao { public CurrencyRateDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 6e8336b759f..e251575bcd7 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -54,7 +54,7 @@ namespace ASC.CRM.Core.Dao public class CustomFieldDao : AbstractDao { public CustomFieldDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 71f3165e65e..e7546b95c7d 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -59,10 +59,10 @@ public class CachedDealDao : DealDao { private readonly HttpRequestDictionary _dealCache; - public CachedDealDao(DbContextManager dbContextManager, + public CachedDealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, IHttpContextAccessor httpContextAccessor, @@ -122,10 +122,10 @@ private void ResetCache(int dealID) [Scope] public class DealDao : AbstractDao { - public DealDao(DbContextManager dbContextManager, + public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, IOptionsMonitor logger, @@ -153,7 +153,7 @@ public DealDao(DbContextManager dbContextManager, public FactoryIndexerDeal FactoryIndexer { get; } public TenantUtil TenantUtil { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public AuthorizationManager AuthorizationManager { get; } diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 6853fb6d043..4fc5ef67b04 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -53,7 +53,7 @@ public class CachedDealMilestoneDao : DealMilestoneDao { private readonly HttpRequestDictionary _dealMilestoneCache; - public CachedDealMilestoneDao(DbContextManager dbContextManager, + public CachedDealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, @@ -122,7 +122,7 @@ public override void Reorder(int[] ids) public class DealMilestoneDao : AbstractDao { - public DealMilestoneDao(DbContextManager dbContextManager, + public DealMilestoneDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 5acff4fec12..5308a77ca56 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -47,7 +47,7 @@ namespace ASC.CRM.Core.Dao public class FileDao : AbstractDao { public FileDao(FilesIntegration filesIntegration, - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index eefe5a2bd55..33ff1a9252d 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -61,7 +61,7 @@ public class CachedInvoiceDao : InvoiceDao { private readonly HttpRequestDictionary _invoiceCache; - public CachedInvoiceDao(DbContextManager dbContextManager, + public CachedInvoiceDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, FactoryIndexerInvoice factoryIndexer, @@ -71,7 +71,7 @@ public CachedInvoiceDao(DbContextManager dbContextManager, SettingsManager settingsManager, InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, IMapper mapper) : base(dbContextManager, @@ -139,10 +139,10 @@ public class InvoiceDao : AbstractDao private readonly SettingsManager _settingsManager; private readonly FactoryIndexerInvoice _factoryIndexer; private readonly TenantUtil _tenantUtil; - private readonly CRMSecurity _crmSecurity; + private readonly CrmSecurity _crmSecurity; public InvoiceDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -152,7 +152,7 @@ public InvoiceDao( SettingsManager settingsManager, InvoiceSetting invoiceSetting, InvoiceFormattedData invoiceFormattedData, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, IMapper mapper) : base(dbContextManager, @@ -545,7 +545,7 @@ public string GetNewInvoicesNumber() public InvoiceSetting GetSettings() { - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); return tenantSettings.InvoiceSetting ?? _invoiceSetting.DefaultSettings; } @@ -767,10 +767,10 @@ private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) public InvoiceSetting SaveInvoiceSettings(InvoiceSetting invoiceSetting) { - var tenantSettings = _settingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.InvoiceSetting = invoiceSetting; - _settingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); return tenantSettings.InvoiceSetting; } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 3b72ebef33b..e6bde662a4f 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -53,11 +53,11 @@ public class CachedInvoiceItemDao : InvoiceItemDao { private readonly HttpRequestDictionary _invoiceItemCache; - public CachedInvoiceItemDao(DbContextManager dbContextManager, + public CachedInvoiceItemDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, IHttpContextAccessor httpContextAccessor, IOptionsMonitor logger, ICache ascCache, @@ -110,11 +110,11 @@ private void ResetCache(int invoiceItemID) public class InvoiceItemDao : AbstractDao { public InvoiceItemDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, IOptionsMonitor logger, ICache ascCache, IMapper mapper @@ -130,7 +130,7 @@ IMapper mapper } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public TenantUtil TenantUtil { get; } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 3012f0516aa..38bca39f112 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -52,7 +52,7 @@ public class CachedInvoiceLineDao : InvoiceLineDao { private readonly HttpRequestDictionary _invoiceLineCache; - public CachedInvoiceLineDao(DbContextManager dbContextManager, + public CachedInvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, @@ -103,7 +103,7 @@ private void ResetCache(int invoiceLineID) [Scope] public class InvoiceLineDao : AbstractDao { - public InvoiceLineDao(DbContextManager dbContextManager, + public InvoiceLineDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 030c3f772a2..4015a8a88b5 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -50,7 +50,7 @@ public class CachedInvoiceTaxDao : InvoiceTaxDao { private readonly HttpRequestDictionary _invoiceTaxCache; - public CachedInvoiceTaxDao(DbContextManager dbContextManager, + public CachedInvoiceTaxDao(DbContextManager dbContextManager, TenantManager tenantManager, TenantUtil tenantUtil, SecurityContext securityContext, @@ -108,7 +108,7 @@ public class InvoiceTaxDao : AbstractDao private readonly IMapper _mapper; public InvoiceTaxDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, TenantUtil tenantUtil, SecurityContext securityContext, @@ -128,7 +128,7 @@ IMapper mapper } public TenantUtil TenantUtil { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public Boolean IsExist(int invoiceTaxID) { diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index d1c0273e3aa..f200d3a7e98 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -54,7 +54,7 @@ public class CachedListItem : ListItemDao private readonly HttpRequestDictionary _listItemCache; public CachedListItem( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IHttpContextAccessor httpContextAccessor, @@ -126,7 +126,7 @@ private void ResetCache(int id) public class ListItemDao : AbstractDao { public ListItemDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 73dda7ff000..c820c935d4f 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -64,11 +64,11 @@ public class CachedRelationshipEventDao : RelationshipEventDao { private readonly HttpRequestDictionary _relationshipEventCache; - public CachedRelationshipEventDao(DbContextManager dbContextManager, + public CachedRelationshipEventDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, FilesIntegration filesIntegration, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, SetupInfo setupInfo, PathProvider pathProvider, @@ -112,11 +112,11 @@ private void ResetCache(int dealID) public class RelationshipEventDao : AbstractDao { - public RelationshipEventDao(DbContextManager dbContextManager, + public RelationshipEventDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, FilesIntegration filesIntegration, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, SetupInfo setupInfo, PathProvider pathProvider, @@ -143,7 +143,7 @@ IMapper mapper public SetupInfo SetupInfo { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public TenantUtil TenantUtil { get; } diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 4591143c00c..c38cfb190f8 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -79,7 +79,7 @@ public class ReportDao : AbstractDao #region Constructor - public ReportDao(DbContextManager dbContextManager, + public ReportDao(DbContextManager dbContextManager, DbContextManager dbUserContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -111,9 +111,9 @@ public ReportDao(DbContextManager dbContextManager, _serviceProvider = serviceProvider; _daoFactory = daoFactory; - var crmSettings = settingsManager.Load(); + var crmSettings = settingsManager.Load(); - _userDbContext = dbUserContextManager.Get(CRMConstants.DatabaseId); + _userDbContext = dbUserContextManager.Get(CrmConstants.DatabaseId); _defaultCurrency = currencyProvider.Get(crmSettings.DefaultCurrency); diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index f70f26d6340..9ceba7f5c7b 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -63,10 +63,10 @@ public class SearchDao : AbstractDao private DaoFactory DaoFactory { get; set; } - public SearchDao(DbContextManager dbContextManager, + public SearchDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, PathProvider pathProvider, FactoryIndexerTask tasksDtoIndexer, @@ -102,7 +102,7 @@ IMapper mapper public PathProvider PathProvider { get; } public FactoryIndexerTask FactoryIndexerTask { get; } public FactoryIndexerInvoice FactoryIndexerInvoice { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public SearchResultItem[] Search(String searchText) { diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 3f8931bf67b..ba9f2deaf8c 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -49,7 +49,7 @@ namespace ASC.CRM.Core.Dao [Scope] public class TagDao : AbstractDao { - public TagDao(DbContextManager dbContextManager, + public TagDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index f0bd9742564..b5c1842d3a4 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -56,10 +56,10 @@ public class CachedTaskDao : TaskDao private readonly HttpRequestDictionary _contactCache; - public CachedTaskDao(DbContextManager dbContextManager, + public CachedTaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, @@ -125,10 +125,10 @@ private void ResetCache(int taskID) [Scope] public class TaskDao : AbstractDao { - public TaskDao(DbContextManager dbContextManager, + public TaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, TenantUtil tenantUtil, FactoryIndexerTask factoryIndexer, IOptionsMonitor logger, @@ -159,7 +159,7 @@ public TaskDao(DbContextManager dbContextManager, public TenantUtil TenantUtil { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public void OpenTask(int taskId) { diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index d7ffa7c46d8..9d186b838c3 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -47,7 +47,7 @@ namespace ASC.CRM.Core.Dao public class TaskTemplateContainerDao : AbstractDao { public TaskTemplateContainerDao( - DbContextManager dbContextManager, + DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, @@ -146,7 +146,7 @@ protected TaskTemplateContainer ToObject(DbTaskTemplateContainer dbTaskTemplateC [Scope] public class TaskTemplateDao : AbstractDao { - public TaskTemplateDao(DbContextManager dbContextManager, + public TaskTemplateDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, IOptionsMonitor logger, diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index ad01e91f552..816017494e1 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -6,7 +6,7 @@ namespace ASC.CRM.Core.EF { - public partial class CRMDbContext : BaseDbContext + public partial class CrmDbContext : BaseDbContext { public virtual DbSet Cases { get; set; } public virtual DbSet Contacts { get; set; } @@ -467,11 +467,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) } - public static class CRMDbContextExtention + public static class CrmDbContextExtention { public static DIHelper AddCRMDbContextService(this DIHelper services) { - return services.AddDbContextManagerService(); + return services.AddDbContextManagerService(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs b/products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs new file mode 100644 index 00000000000..c9d2b30d10f --- /dev/null +++ b/products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs @@ -0,0 +1,193 @@ +using System; + +using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.Core.Configuration; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; +using ASC.CRM.Resources; +using ASC.Web.CRM.Classes; + +namespace ASC.CRM.Core.EF +{ + public static class CrmDbContextSeed + { + public static void SeedInitPortalData(SettingsManager settingsManager, + DaoFactory daoFactory, + CoreConfiguration coreConfiguration) + { + var tenantSettings = settingsManager.Load(); + + if (!tenantSettings.IsConfiguredPortal) + { + // Task Category + var listItemDao = daoFactory.GetListItemDao(); + + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Call, "task_category_call.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Deal, "task_category_deal.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Demo, "task_category_demo.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Email, "task_category_email.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Fax, "task_category_fax.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_FollowUP, "task_category_follow_up.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Lunch, "task_category_lunch.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Meeting, "task_category_meeting.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Note, "task_category_note.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_Ship, "task_category_ship.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_SocialNetworks, "task_category_social_networks.png")); + listItemDao.CreateItem(ListType.TaskCategory, new ListItem(CRMTaskResource.TaskCategory_ThankYou, "task_category_thank_you.png")); + + // Deal Milestone New + var milestoneDao = daoFactory.GetDealMilestoneDao(); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_InitialContact_Title, + Description = CRMDealResource.DealMilestone_InitialContact_Description, + Probability = 1, + Color = "#e795c1", + Status = DealMilestoneStatus.Open + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Preapproach_Title, + Description = CRMDealResource.DealMilestone_Preapproach_Description, + Probability = 2, + Color = "#df7895", + Status = DealMilestoneStatus.Open + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Suspect_Title, + Description = CRMDealResource.DealMilestone_Suspect_Description, + Probability = 3, + Color = "#f48454", + SortOrder = 1, + Status = DealMilestoneStatus.Open + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Champion_Title, + Description = CRMDealResource.DealMilestone_Champion_Description, + Probability = 20, + Color = "#b58fd6", + SortOrder = 2, + Status = DealMilestoneStatus.Open + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Opportunity_Title, + Description = CRMDealResource.DealMilestone_Opportunity_Description, + Probability = 50, + Color = "#d28cc8", + SortOrder = 3, + Status = DealMilestoneStatus.Open + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Prospect_Title, + Description = CRMDealResource.DealMilestone_Prospect_Description, + Probability = 75, + Color = "#ffb45e", + SortOrder = 4, + Status = DealMilestoneStatus.Open + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Verbal_Title, + Description = CRMDealResource.DealMilestone_Verbal_Description, + Probability = 90, + Color = "#ffd267", + SortOrder = 5, + Status = DealMilestoneStatus.Open + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Won_Title, + Description = CRMDealResource.DealMilestone_Won_Description, + Probability = 100, + Color = "#6bbd72", + SortOrder = 6, + Status = DealMilestoneStatus.ClosedAndWon + }); + + milestoneDao.Create(new DealMilestone + { + Title = CRMDealResource.DealMilestone_Lost_Title, + Description = CRMDealResource.DealMilestone_Lost_Description, + Probability = 0, + Color = "#f2a9be", + SortOrder = 7, + Status = DealMilestoneStatus.ClosedAndLost + }); + + // Contact Status + listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Cold, Color = "#8a98d8", SortOrder = 1 }); + listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Warm, Color = "#ffd267", SortOrder = 2 }); + listItemDao.CreateItem(ListType.ContactStatus, new ListItem { Title = CRMContactResource.ContactStatus_Hot, Color = "#df7895", SortOrder = 3 }); + // Contact Type + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Client, SortOrder = 1 }); + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Supplier, SortOrder = 2 }); + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Partner, SortOrder = 3 }); + listItemDao.CreateItem(ListType.ContactType, new ListItem { Title = CRMContactResource.ContactType_Competitor, SortOrder = 4 }); + + // History Category + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Note, "event_category_note.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Email, "event_category_email.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png")); + listItemDao.CreateItem(ListType.HistoryCategory, new ListItem(CRMCommonResource.HistoryCategory_Meeting, "event_category_meeting.png")); + + // Tags + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Lead, true); + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Customer, true); + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Supplier, true); + daoFactory.GetTagDao().AddTag(EntityType.Contact, CRMContactResource.Staff, true); + + tenantSettings.WebFormKey = Guid.NewGuid(); + tenantSettings.IsConfiguredPortal = true; + + if (!settingsManager.Save(tenantSettings)) + { + throw new Exception("not save CRMSettings"); + } + } + + if (!tenantSettings.IsConfiguredSmtp) + { + var smtp = settingsManager.Load().SMTPServerSettingOld; + + if (smtp != null && coreConfiguration.SmtpSettings.IsDefaultSettings) + { + var newSettings = new SmtpSettings(smtp.Host, smtp.Port, smtp.SenderEmailAddress, + smtp.SenderDisplayName) + { + EnableSSL = smtp.EnableSSL, + EnableAuth = smtp.RequiredHostAuthentication, + }; + + if (!string.IsNullOrEmpty(smtp.HostLogin) && !string.IsNullOrEmpty(smtp.HostPassword)) + { + newSettings.SetCredentials(smtp.HostLogin, smtp.HostPassword); + } + + coreConfiguration.SmtpSettings = newSettings; + + } + + tenantSettings.IsConfiguredSmtp = true; + + if (!settingsManager.Save(tenantSettings)) + { + throw new Exception("not save CRMSettings"); + } + } + } + } +} diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index 12a59ede30d..3b302b4ec7e 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -32,42 +32,44 @@ using ASC.CRM.Mapping; using ASC.CRM.Resources; +using AutoMapper; + namespace ASC.CRM.Core { public class CurrencyInfo : IMapFrom { - private readonly String _resourceKey; + private String _resourceKey; - public String Title + public CurrencyInfo() { - get - { - if (String.IsNullOrEmpty(_resourceKey)) - return String.Empty; - return CRMCommonResource.ResourceManager.GetString(_resourceKey); - } + } + public CurrencyInfo(string resourceKey, string abbreviation, string symbol, string cultureName, bool isConvertable, bool isBasic) + { + _resourceKey = resourceKey; + Symbol = symbol; + Abbreviation = abbreviation; + CultureName = cultureName; + IsConvertable = isConvertable; + IsBasic = isBasic; } + public string Symbol { get; set; } public string Abbreviation { get; set; } public string CultureName { get; set; } public bool IsConvertable { get; set; } public bool IsBasic { get; set; } - public CurrencyInfo() + public String Title { - - } + get + { + if (String.IsNullOrEmpty(_resourceKey)) + return String.Empty; - public CurrencyInfo(string resourceKey, string abbreviation, string symbol, string cultureName, bool isConvertable, bool isBasic) - { - _resourceKey = resourceKey; - Symbol = symbol; - Abbreviation = abbreviation; - CultureName = cultureName; - IsConvertable = isConvertable; - IsBasic = isBasic; + return CRMCommonResource.ResourceManager.GetString(_resourceKey); + } } public override bool Equals(object obj) @@ -85,5 +87,11 @@ public override string ToString() { return string.Concat(Abbreviation, "-", Title); } + + public void Mapping(Profile profile) + { + profile.CreateMap() + .ForMember(dest => dest._resourceKey, opt => opt.MapFrom(src => src.ResourceKey)); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index d35e694cf99..3b826e379e7 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -108,10 +108,5 @@ public Type ObjectType { get { return GetType(); } } - - public void Mapping(Profile profile) - { - profile.CreateMap(); - } } } diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs index d2db45fc9ae..7afa441282f 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecurityObjectProvider.cs @@ -37,7 +37,7 @@ namespace ASC.CRM.Core { - public class CRMSecurityObjectProvider : ISecurityObjectProvider + public class CrmSecurityObjectProvider : ISecurityObjectProvider { public ISecurityObjectId InheritFrom(ISecurityObjectId objectId) { diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index bdd9f23f580..45b7e7d3678 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -54,11 +54,11 @@ namespace ASC.CRM.Core { [Scope] - public class CRMSecurity + public class CrmSecurity { public readonly IAction _actionRead = new Action(new Guid("{6F05C382-8BCA-4469-9424-C807A98C40D7}"), "", true, false); - public CRMSecurity(SecurityContext securityContext, + public CrmSecurity(SecurityContext securityContext, AuthorizationManager authorizationManager, UserManager userManager, DisplayUserSettingsHelper displayUserSettingsHelper, @@ -96,7 +96,7 @@ public CRMSecurity(SecurityContext securityContext, private ISecurityObjectProvider GetCRMSecurityProvider() { - return new CRMSecurityObjectProvider(); + return new CrmSecurityObjectProvider(); } public bool IsPrivate(ISecurityObjectId entity) diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index 56d6b9c7a8a..2b64bbae0c5 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -41,7 +41,7 @@ namespace ASC.CRM.Core public class FileSecurity : IFileSecurity { public FileSecurity(FilesIntegration filesIntegration, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, DaoFactory daoFactory) { FilesIntegration = filesIntegration; @@ -53,7 +53,7 @@ public FileSecurity(FilesIntegration filesIntegration, public FilesIntegration FilesIntegration { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public bool CanCreate(FileEntry entry, Guid userId) { @@ -130,7 +130,7 @@ public bool CanCustomFilterEdit(FileEntry entry, Guid userId) public class FileSecurityProvider : IFileSecurityProvider { public FileSecurityProvider(FilesIntegration filesIntegration, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, DaoFactory daoFactory) { FilesIntegration = filesIntegration; @@ -140,7 +140,7 @@ public FileSecurityProvider(FilesIntegration filesIntegration, public DaoFactory DaoFactory { get; } public FilesIntegration FilesIntegration { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public IFileSecurity GetFileSecurity(string data) { diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs index e95c13056f8..78ca48203b9 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CasesDtoTypeConverter.cs @@ -29,6 +29,7 @@ using System.Linq; using ASC.Api.Core; +using ASC.Common; using ASC.Core.Users; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -41,16 +42,17 @@ namespace ASC.CRM.Mapping { + [Scope] public class CasesDtoTypeConverter : ITypeConverter { private readonly DaoFactory _daoFactory; - private readonly CRMSecurity _CRMSecurity; + private readonly CrmSecurity _CRMSecurity; private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; public CasesDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, DaoFactory daoFactory) { _apiDateTimeHelper = apiDateTimeHelper; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs index ffb0579211c..f1a6ef22622 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ContactDtoTypeConverter.cs @@ -29,6 +29,7 @@ using System.Linq; using ASC.Api.Core; +using ASC.Common; using ASC.Common.Web; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -45,6 +46,7 @@ namespace ASC.CRM.Mapping { + [Scope] public class ContactDtoTypeConverter : ITypeConverter, ITypeConverter, List>, ITypeConverter, @@ -56,7 +58,7 @@ public class ContactDtoTypeConverter : ITypeConverter, { private readonly DaoFactory _daoFactory; - private readonly CRMSecurity _crmSecurity; + private readonly CrmSecurity _crmSecurity; private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeDtoHelper; private readonly CurrencyProvider _currencyProvider; @@ -64,7 +66,7 @@ public class ContactDtoTypeConverter : ITypeConverter, public ContactDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, CurrencyProvider currencyProvider, PathProvider pathProvider, DaoFactory daoFactory) diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs index bc41767b6d9..de589d727d9 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs @@ -1,5 +1,6 @@ using System; +using ASC.Common; using ASC.CRM.ApiModels; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -8,6 +9,7 @@ namespace ASC.CRM.Mapping { + [Scope] public class CustomFieldDtoTypeConverter : ITypeConverter { private readonly DaoFactory _daoFactory; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs index 71b359289b6..c4ce4658806 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/DealMilestoneDtoTypeConverter.cs @@ -26,6 +26,7 @@ using System; +using ASC.Common; using ASC.CRM.ApiModels; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -34,6 +35,7 @@ namespace ASC.CRM.Mapping { + [Scope] public sealed class DealMilestoneDtoTypeConverter : ITypeConverter { private readonly DaoFactory _daoFactory; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs index d729311497e..584721a6bb2 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceBaseDtoTypeConverter.cs @@ -45,14 +45,14 @@ public class InvoiceBaseDtoTypeConverter : ITypeConverter(); + var crmSettings = _settingsManager.Load(); var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); var result = new InvoiceBaseDto diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs index 2bf89600325..da06050d2fc 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceDtoTypeConverter.cs @@ -27,6 +27,7 @@ using System.Linq; using ASC.Api.Core; +using ASC.Common; using ASC.Core.Common.Settings; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -39,6 +40,7 @@ namespace ASC.CRM.Mapping { + [Scope] public class InvoiceDtoTypeConverter : ITypeConverter { private readonly DaoFactory _daoFactory; @@ -46,12 +48,12 @@ public class InvoiceDtoTypeConverter : ITypeConverter private readonly SettingsManager _settingsManager; private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; - private readonly CRMSecurity _crmSecurity; + private readonly CrmSecurity _crmSecurity; private readonly EntityDtoHelper _entityDtoHelper; public InvoiceDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, SettingsManager settingsManager, CurrencyProvider currencyProvider, DaoFactory daoFactory, @@ -69,7 +71,7 @@ public InvoiceDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, public InvoiceDto Convert(Invoice source, InvoiceDto destination, ResolutionContext context) { - var crmSettings = _settingsManager.Load(); + var crmSettings = _settingsManager.Load(); var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); var result = new InvoiceDto diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs index 8c50b3cb480..19800a0aa94 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceItemDtoTypeConverter.cs @@ -26,6 +26,7 @@ using System; using ASC.Api.Core; +using ASC.Common; using ASC.Core.Common.Settings; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -38,6 +39,7 @@ namespace ASC.CRM.Mapping { + [Scope] public class InvoiceItemDtoTypeConverter : ITypeConverter { private readonly DaoFactory _daoFactory; @@ -45,11 +47,11 @@ public class InvoiceItemDtoTypeConverter : ITypeConverter(); + var crmSettings = _settingsManager.Load(); var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); var result = new InvoiceItemDto diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxDtoTypeConverter.cs index ea770b61e42..e8a936d8c28 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/InvoiceTaxDtoTypeConverter.cs @@ -26,6 +26,7 @@ using System; using ASC.Api.Core; +using ASC.Common; using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Entities; @@ -35,15 +36,16 @@ namespace ASC.CRM.Mapping { + [Scope] public class InvoiceTaxDtoTypeConverter : ITypeConverter { private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; - private readonly CRMSecurity _crmSecurity; + private readonly CrmSecurity _crmSecurity; public InvoiceTaxDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity crmSecurity) + CrmSecurity crmSecurity) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs index bb7abb3092d..3cb52355551 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/ListItemDtoTypeConverter.cs @@ -26,6 +26,7 @@ using System; +using ASC.Common; using ASC.CRM.ApiModels; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; @@ -38,6 +39,7 @@ namespace ASC.CRM.Mapping { + [Scope] public sealed class ListItemDtoTypeConverter : ITypeConverter, ITypeConverter, ITypeConverter, diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs index bec288d855e..564bfb42b41 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/OpportunityDtoTypeConverter.cs @@ -28,6 +28,7 @@ using System.Linq; using ASC.Api.Core; +using ASC.Common; using ASC.Common.Web; using ASC.CRM.ApiModels; using ASC.CRM.Core; @@ -41,23 +42,24 @@ namespace ASC.CRM.Mapping { + [Scope] public class OpportunityDtoTypeConverter : ITypeConverter { private readonly CurrencyProvider _currencyProvider; private readonly DaoFactory _daoFactory; - private readonly CRMSecurity _cRMSecurity; + private readonly CrmSecurity _crmSecurity; private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; public OpportunityDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, DaoFactory daoFactory, CurrencyProvider currencyProvider) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _cRMSecurity = crmSecurity; + _crmSecurity = crmSecurity; _daoFactory = daoFactory; _currencyProvider = currencyProvider; } @@ -78,7 +80,7 @@ public OpportunityDto Convert(Deal source, OpportunityDto destination, Resolutio SuccessProbability = source.DealMilestoneProbability, ActualCloseDate = _apiDateTimeHelper.Get(source.ActualCloseDate), ExpectedCloseDate = _apiDateTimeHelper.Get(source.ExpectedCloseDate), - CanEdit = _cRMSecurity.CanEdit(source) + CanEdit = _crmSecurity.CanEdit(source) }; if (source.ContactID > 0) @@ -94,10 +96,10 @@ public OpportunityDto Convert(Deal source, OpportunityDto destination, Resolutio dealDto.Stage = new DealMilestoneBaseDto(dealMilestone); } - dealDto.AccessList = _cRMSecurity.GetAccessSubjectTo(source) + dealDto.AccessList = _crmSecurity.GetAccessSubjectTo(source) .Select(item => _employeeWraperHelper.Get(item.Key)); - dealDto.IsPrivate = _cRMSecurity.IsPrivate(source); + dealDto.IsPrivate = _crmSecurity.IsPrivate(source); if (!string.IsNullOrEmpty(source.BidCurrency)) dealDto.BidCurrency = context.Mapper.Map(_currencyProvider.Get(source.BidCurrency)); diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs index 7d44a9cedfb..f7048be8933 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/RelationshipEventDtoTypeConverter.cs @@ -44,7 +44,7 @@ public class RelationshipEventDtoTypeConverter : ITypeConverter, ITypeConverter { - private readonly CRMSecurity _CRMSecurity; + private readonly CrmSecurity _crmSecurity; private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; private readonly DaoFactory _daoFactory; @@ -50,13 +50,13 @@ public class TaskDtoTypeConverter : ITypeConverter, public TaskDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, EmployeeWraperHelper employeeWraperHelper, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, DaoFactory daoFactory, EntityDtoHelper entityDtoHelper) { _apiDateTimeHelper = apiDateTimeHelper; _employeeWraperHelper = employeeWraperHelper; - _CRMSecurity = crmSecurity; + _crmSecurity = crmSecurity; _daoFactory = daoFactory; _entityDtoHelper = entityDtoHelper; } @@ -96,7 +96,7 @@ public TaskDto Convert(Task source, TaskDto destination, ResolutionContext conte result.Entity = _entityDtoHelper.Get(source.EntityType, source.EntityID); } - result.CanEdit = _CRMSecurity.CanEdit(source); + result.CanEdit = _crmSecurity.CanEdit(source); return result; } diff --git a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs b/products/ASC.CRM/Server/Middlewares/ContactPhotoHandler.cs similarity index 94% rename from products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs rename to products/ASC.CRM/Server/Middlewares/ContactPhotoHandler.cs index a5dcfdaa5a2..5afce5d56c8 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ContactPhotoHandler.cs +++ b/products/ASC.CRM/Server/Middlewares/ContactPhotoHandler.cs @@ -37,6 +37,7 @@ using ASC.Web.Core.Files; using ASC.Web.Core.Utility; using ASC.Web.CRM.Classes; +using ASC.Web.CRM.Configuration; using ASC.Web.Studio.Core; using Microsoft.AspNetCore.Builder; @@ -55,7 +56,7 @@ public ContactPhotoHandlerMiddleware(RequestDelegate next) public async System.Threading.Tasks.Task Invoke(HttpContext context, SetupInfo setupInfo, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, FileSizeComment fileSizeComment, WebItemSecurity webItemSecurity, MessageTarget messageTarget, @@ -64,8 +65,8 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, ContactPhotoManager contactPhotoManager) { - //if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) - // throw crmSecurity.CreateSecurityException(); + if (!webItemSecurity.IsAvailableForMe(ProductEntryPoint.ID)) + throw crmSecurity.CreateSecurityException(); context.Request.EnableBuffering(); @@ -77,8 +78,8 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, { contact = daoFactory.GetContactDao().GetByID(contactId); - //if (!crmSecurity.CanEdit(contact)) - // throw crmSecurity.CreateSecurityException(); + if (!crmSecurity.CanEdit(contact)) + throw crmSecurity.CreateSecurityException(); } var fileUploadResult = new FileUploadResult(); diff --git a/products/ASC.CRM/Server/HttpHandlers/FileHandler.cs b/products/ASC.CRM/Server/Middlewares/FileHandler.cs similarity index 100% rename from products/ASC.CRM/Server/HttpHandlers/FileHandler.cs rename to products/ASC.CRM/Server/Middlewares/FileHandler.cs diff --git a/products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs b/products/ASC.CRM/Server/Middlewares/FileUploaderHandler.cs similarity index 100% rename from products/ASC.CRM/Server/HttpHandlers/FileUploaderHandler.cs rename to products/ASC.CRM/Server/Middlewares/FileUploaderHandler.cs diff --git a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs b/products/ASC.CRM/Server/Middlewares/ImportFileHandler.cs similarity index 98% rename from products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs rename to products/ASC.CRM/Server/Middlewares/ImportFileHandler.cs index af1d0a2240b..1fda895e8d4 100644 --- a/products/ASC.CRM/Server/HttpHandlers/ImportFileHandler.cs +++ b/products/ASC.CRM/Server/Middlewares/ImportFileHandler.cs @@ -51,7 +51,7 @@ public ImportFileHandlerMiddleware( public async Task Invoke(HttpContext context, WebItemSecurity webItemSecurity, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, Global global, ImportFromCSV importFromCSV) { diff --git a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/Middlewares/OrganisationLogoHandler.cs similarity index 99% rename from products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs rename to products/ASC.CRM/Server/Middlewares/OrganisationLogoHandler.cs index b30e7c8686d..78916654254 100644 --- a/products/ASC.CRM/Server/HttpHandlers/OrganisationLogoHandler.cs +++ b/products/ASC.CRM/Server/Middlewares/OrganisationLogoHandler.cs @@ -51,7 +51,7 @@ RequestDelegate next } public async System.Threading.Tasks.Task Invoke(HttpContext context, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, SetupInfo setupInfo, FileSizeComment fileSizeComment, ContactPhotoManager contactPhotoManager, diff --git a/products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs b/products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs new file mode 100644 index 00000000000..01c2ae93175 --- /dev/null +++ b/products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; + +using ASC.Core; +using ASC.Core.Common.Settings; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; + +using Microsoft.AspNetCore.Http; + +namespace ASC.CRM.HttpHandlers +{ + public class TenantConfigureMiddleware + { + private readonly RequestDelegate _next; + + public TenantConfigureMiddleware(RequestDelegate next) + { + _next = next; + } + + public async Task InvokeAsync(HttpContext context, + DaoFactory daoFactory, + SettingsManager settingsManager, + CoreConfiguration coreConfiguration) + { + CrmDbContextSeed.SeedInitPortalData(settingsManager, daoFactory, coreConfiguration); + + await _next.Invoke(context); + } + } +} diff --git a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandler.cs similarity index 99% rename from products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs rename to products/ASC.CRM/Server/Middlewares/WebToLeadFromHandler.cs index 69e5b6378ec..516a28925f0 100644 --- a/products/ASC.CRM/Server/HttpHandlers/WebToLeadFromHandler.cs +++ b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandler.cs @@ -63,7 +63,7 @@ public class WebToLeadFromHandlerMiddleware public Global Global { get; set; } public WebItemSecurity WebItemSecurity { get; set; } public SecurityContext SecurityContext { get; set; } - public CRMSecurity CRMSecurity { get; set; } + public CrmSecurity CRMSecurity { get; set; } public MessageTarget MessageTarget { get; set; } public ILog Logger { get; set; } public NotifyClient NotifyClient { get; set; } @@ -93,7 +93,7 @@ private bool CheckPermission() var webFromKeyAsGuid = new Guid(webFromKey); - var TenantSettings = SettingsManager.Load(); + var TenantSettings = SettingsManager.Load(); return TenantSettings.WebFormKey == webFromKeyAsGuid; } @@ -106,7 +106,7 @@ private bool CheckPermission() public async System.Threading.Tasks.Task Invoke(HttpContext context, WebItemSecurity webItemSecurity, SecurityContext securityContext, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, MessageTarget messageTarget, MessageService messageService, Global global, diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index d8eb74a5afc..ff40afee444 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; -using System.Threading.Tasks; using ASC.Common.DependencyInjection; using ASC.Common.Utils; @@ -18,7 +17,7 @@ namespace ASC.CRM { public class Program { - public async static Task Main(string[] args) + public async static System.Threading.Tasks.Task Main(string[] args) { var host = CreateHostBuilder(args).Build(); diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 34d5110492c..518c884e77b 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,23 +1,29 @@ +using System; using System.Collections.Generic; using System.Reflection; using System.Text; using System.Text.Json.Serialization; +using System.Threading.Tasks; using ASC.Api.Core; using ASC.Common; +using ASC.Common.Mapping; using ASC.CRM.Api; using ASC.CRM.ApiModels; +using ASC.CRM.HttpHandlers; using ASC.CRM.Mapping; using ASC.Web.CRM.HttpHandlers; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace ASC.CRM { + public class Startup : BaseStartup { public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) @@ -63,14 +69,14 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); - - services.AddAutoMapper(Assembly.GetExecutingAssembly()); } public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) { base.Configure(app, env); + app.UseMiddleware(); + app.MapWhen( context => context.Request.Path.ToString().EndsWith("httphandlers/contactphotohandler.ashx"), appBranch => diff --git a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs index 1fa4639d583..0807d1eec3e 100644 --- a/products/ASC.CRM/Server/Utils/CurrencyProvider.cs +++ b/products/ASC.CRM/Server/Utils/CurrencyProvider.cs @@ -168,7 +168,7 @@ public Decimal MoneyConvert(decimal amount, string from, string to) public decimal MoneyConvertToDefaultCurrency(decimal amount, string from) { - var crmSettings = SettingsManager.Load(); + var crmSettings = SettingsManager.Load(); var defaultCurrency = Get(crmSettings.DefaultCurrency); return MoneyConvert(amount, from, defaultCurrency.Abbreviation); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 910a37f2668..76eccf6a305 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -139,7 +139,7 @@ public ImportDataOperation(Global global, IOptionsMonitor logger, UserManager userManager, ImportDataCache importDataCache, - CRMSecurity crmSecurity, + CrmSecurity crmSecurity, NotifyClient notifyClient, SettingsManager settingsManager, CurrencyProvider currencyProvider, @@ -190,7 +190,7 @@ public void Configure(EntityType entityType, public SettingsManager SettingsManager { get; } - public CRMSecurity CRMSecurity { get; } + public CrmSecurity CRMSecurity { get; } public ImportDataCache ImportDataCache { get; } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index da09967df26..fbce023f251 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -103,7 +103,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) var currency = CurrencyProvider.Get(GetPropertyValue("bid_currency")); - var crmSettings = SettingsManager.Load(); + var crmSettings = SettingsManager.Load(); var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); if (currency != null) diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index a463c919057..623d8d79e07 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -119,7 +119,7 @@ CoreConfiguration coreConfiguration _tenantID = tenantManager.GetCurrentTenant().TenantId; - var _crmSettings = settingsManager.Load(); + var _crmSettings = settingsManager.Load(); _smtpSetting = new SMTPServerSetting(coreConfiguration.SmtpSettings); _currUser = SecurityContext.CurrentAccount.ID; diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index d808893baf9..6b389a6486d 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -170,7 +170,7 @@ public List GetMissingRates(ReportType reportType) if (reportType == ReportType.WorkloadByTasks || reportType == ReportType.WorkloadByInvoices || reportType == ReportType.WorkloadByContacts || reportType == ReportType.WorkloadByVoip) return null; - var crmSettings = SettingsManager.Load(); + var crmSettings = SettingsManager.Load(); var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); return reportDao.GetMissingRates(defaultCurrency.Abbreviation); @@ -178,7 +178,7 @@ public List GetMissingRates(ReportType reportType) private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { - var crmSettings = SettingsManager.Load(); + var crmSettings = SettingsManager.Load(); var reportDao = DaoFactory.GetReportDao(); var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency).Abbreviation; From 09ef8ba6606309c5d63d19e5bd1dec70fed4c6f8 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 7 May 2021 17:00:51 +0300 Subject: [PATCH 47/61] crm.server: refactoring. remove obsolete cache class. In future release I will use EF Core cache --- products/ASC.CRM/Server/ASC.CRM.csproj | 1 + .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 46 +-- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 125 ++---- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 381 +++++++----------- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 113 +----- .../Server/Core/Dao/CurrencyInfoDao.cs | 12 +- .../Server/Core/Dao/CurrencyRateDao.cs | 40 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 70 ++-- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 134 ++---- .../Server/Core/Dao/DealMilestoneDao.cs | 133 ++---- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 165 +++----- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 107 ++--- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 98 ++--- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 102 +---- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 196 +++------ .../Server/Core/Dao/RelationshipEventDao.cs | 90 +---- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 192 ++++----- products/ASC.CRM/Server/Core/Dao/SearchDao.cs | 16 +- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 96 ++--- products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 247 ++++-------- .../Core/Dao/TaskTemplateContainerDao.cs | 52 +-- .../Server/Core/Search/FactoryIndexerCase.cs | 4 +- .../Core/Search/FactoryIndexerContact.cs | 4 +- .../Core/Search/FactoryIndexerContactInfo.cs | 4 +- .../Server/Core/Search/FactoryIndexerDeal.cs | 4 +- .../Core/Search/FactoryIndexerEvents.cs | 4 +- .../Core/Search/FactoryIndexerFieldValue.cs | 4 +- .../Core/Search/FactoryIndexerInvoice.cs | 4 +- .../Server/Core/Search/FactoryIndexerTask.cs | 4 +- ...er.cs => ContactPhotoHandlerMiddleware.cs} | 0 ...ileHandler.cs => FileHandlerMiddleware.cs} | 0 ...er.cs => FileUploaderHandlerMiddleware.cs} | 0 ...dler.cs => ImportFileHandlerMiddleware.cs} | 0 ...s => OrganisationLogoHandlerMiddleware.cs} | 0 ...r.cs => WebToLeadFromHandlerMiddleware.cs} | 0 35 files changed, 833 insertions(+), 1615 deletions(-) rename products/ASC.CRM/Server/Middlewares/{ContactPhotoHandler.cs => ContactPhotoHandlerMiddleware.cs} (100%) rename products/ASC.CRM/Server/Middlewares/{FileHandler.cs => FileHandlerMiddleware.cs} (100%) rename products/ASC.CRM/Server/Middlewares/{FileUploaderHandler.cs => FileUploaderHandlerMiddleware.cs} (100%) rename products/ASC.CRM/Server/Middlewares/{ImportFileHandler.cs => ImportFileHandlerMiddleware.cs} (100%) rename products/ASC.CRM/Server/Middlewares/{OrganisationLogoHandler.cs => OrganisationLogoHandlerMiddleware.cs} (100%) rename products/ASC.CRM/Server/Middlewares/{WebToLeadFromHandler.cs => WebToLeadFromHandlerMiddleware.cs} (100%) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index fc1ee846013..3f15b238a66 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -34,6 +34,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index 5d04bd43e2f..708bc002f02 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -46,8 +46,8 @@ namespace ASC.CRM.Core.Dao public class AbstractDao { protected readonly List _supportedEntityType = new List(); - public CrmDbContext CRMDbContext { get; } - protected SecurityContext _securityContext; + public CrmDbContext CrmDbContext { get; } + protected readonly SecurityContext _securityContext; protected readonly ICache _cache; protected ILog _logger; protected IMapper _mapper; @@ -65,7 +65,7 @@ IMapper mapper _logger = logger.Get("ASC.CRM"); _cache = ascCache; - CRMDbContext = dbContextManager.Get(CrmConstants.DatabaseId); + CrmDbContext = dbContextManager.Get(CrmConstants.DatabaseId); TenantID = tenantManager.GetCurrentTenant().TenantId; _securityContext = securityContext; @@ -114,13 +114,13 @@ protected List SearchByTags(EntityType entityType, int[] exceptIDs, IEnumer foreach (var tag in tags) { - tagIDs.Add(CRMDbContext + tagIDs.Add(CrmDbContext .Tags .Where(x => x.EntityType == entityType && String.Compare(x.Title, tag.Trim(), true) == 0) .Select(x => x.Id).Single()); } - var sqlQuery = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && tagIDs.Contains(x.TagId)); + var sqlQuery = CrmDbContext.EntityTags.Where(x => x.EntityType == entityType && tagIDs.Contains(x.TagId)); if (exceptIDs != null && exceptIDs.Length > 0) sqlQuery = sqlQuery.Where(x => exceptIDs.Contains(x.EntityId)); @@ -140,7 +140,7 @@ protected Dictionary GetRelativeToEntity(int[] contactID, EntityType else if (entityID != null && entityID.Length > 0 && (contactID == null || contactID.Length == 0)) exp = x => x.EntityType == entityType && entityID.Contains(x.EntityId); - return CRMDbContext.EntityContact + return CrmDbContext.EntityContact .Where(exp) .Select(x => new { EntityId = x.EntityId, ContactId = x.ContactId }) .ToList() @@ -156,13 +156,13 @@ protected int[] GetRelativeToEntity(int? contactID, EntityType entityType, int? protected int[] GetRelativeToEntityInDb(int? contactID, EntityType entityType, int? entityID) { if (contactID.HasValue && !entityID.HasValue) - return CRMDbContext.EntityContact + return CrmDbContext.EntityContact .Where(x => x.EntityType == entityType && x.ContactId == contactID.Value) .Select(x => x.EntityId) .ToArray(); if (!contactID.HasValue && entityID.HasValue) - return CRMDbContext.EntityContact + return CrmDbContext.EntityContact .Where(x => x.EntityType == entityType && x.EntityId == entityID.Value) .Select(x => x.ContactId) .ToArray(); @@ -175,19 +175,19 @@ protected void SetRelative(int[] contactID, EntityType entityType, int entityID) if (entityID == 0) throw new ArgumentException(); - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var exists = CRMDbContext.EntityContact + var exists = CrmDbContext.EntityContact .Where(x => x.EntityType == entityType && x.EntityId == entityID) .Select(x => x.ContactId) .ToArray(); foreach (var existContact in exists) { - var items = CRMDbContext.EntityContact + var items = CrmDbContext.EntityContact .Where(x => x.EntityType == entityType && x.EntityId == entityID && x.ContactId == existContact); - CRMDbContext.EntityContact.RemoveRange(items); + CrmDbContext.EntityContact.RemoveRange(items); } if (!(contactID == null || contactID.Length == 0)) @@ -199,14 +199,14 @@ protected void SetRelative(int[] contactID, EntityType entityType, int entityID) protected void SetRelative(int contactID, EntityType entityType, int entityID) { - CRMDbContext.EntityContact.Add(new DbEntityContact + CrmDbContext.EntityContact.Add(new DbEntityContact { ContactId = contactID, EntityType = entityType, EntityId = entityID }); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } protected void RemoveRelativeInDb(int[] contactID, EntityType entityType, int[] entityID) @@ -222,11 +222,11 @@ protected void RemoveRelativeInDb(int[] contactID, EntityType entityType, int[] if (entityID != null && entityID.Length > 0) expr = x => entityID.Contains(x.EntityId) && x.EntityType == entityType; - var dbCrmEntity = CRMDbContext.EntityContact; + var dbCrmEntity = CrmDbContext.EntityContact; dbCrmEntity.RemoveRange(dbCrmEntity.Where(expr)); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } protected void RemoveRelative(int contactID, EntityType entityType, int entityID) @@ -255,9 +255,9 @@ public int SaveOrganisationLogo(byte[] bytes) CreateBy = _securityContext.CurrentAccount.ID.ToString() }; - CRMDbContext.OrganisationLogo.Add(entity); + CrmDbContext.OrganisationLogo.Add(entity); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return entity.Id; } @@ -266,7 +266,7 @@ public string GetOrganisationLogoBase64(int logo_id) { if (logo_id <= 0) throw new ArgumentException(); - return Query(CRMDbContext.OrganisationLogo) + return Query(CrmDbContext.OrganisationLogo) .Where(x => x.Id == logo_id) .Select(x => x.Content) .FirstOrDefault(); @@ -274,10 +274,10 @@ public string GetOrganisationLogoBase64(int logo_id) public bool HasActivity() { - return Query(CRMDbContext.Cases).Any() && - Query(CRMDbContext.Deals).Any() && - Query(CRMDbContext.Tasks).Any() && - Query(CRMDbContext.Contacts).Any(); + return Query(CrmDbContext.Cases).Any() && + Query(CrmDbContext.Deals).Any() && + Query(CrmDbContext.Tasks).Any() && + Query(CrmDbContext.Contacts).Any(); } protected IQueryable Query(DbSet set) where T : class, IDbCrm diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 732566b2698..153878120fe 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -46,7 +46,6 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -55,70 +54,6 @@ namespace ASC.CRM.Core.Dao { - public class CachedCasesDao : CasesDao - { - private readonly HttpRequestDictionary _casesCache; - - public CachedCasesDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - CrmSecurity crmSecurity, - TenantUtil tenantUtil, - FilesIntegration filesIntegration, - AuthorizationManager authorizationManager, - IOptionsMonitor logger, - ICache ascCache, - IHttpContextAccessor httpContextAccessor, - BundleSearch bundleSearch, - IMapper mapper) - : - base(dbContextManager, - tenantManager, - securityContext, - crmSecurity, - tenantUtil, - filesIntegration, - authorizationManager, - logger, - ascCache, - bundleSearch, - mapper) - - { - _casesCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_cases"); - } - - public override Cases GetByID(int caseID) - { - return _casesCache.Get(caseID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(caseID)); - } - - private Cases GetByIDBase(int caseID) - { - return base.GetByID(caseID); - } - - public override void UpdateCases(Cases cases) - { - if (cases != null && cases.ID > 0) - ResetCache(cases.ID); - - base.UpdateCases(cases); - } - - public override Cases DeleteCases(int casesID) - { - ResetCache(casesID); - - return base.DeleteCases(casesID); - } - - private void ResetCache(int taskID) - { - _casesCache.Reset(taskID.ToString(CultureInfo.InvariantCulture)); - } - } - [Scope] public class CasesDao : AbstractDao { @@ -184,9 +119,9 @@ public void RemoveMember(int caseID, int memberID) RemoveRelative(memberID, EntityType.Case, caseID); } - public virtual int[] SaveCasesList(List items) + public int[] SaveCasesList(List items) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); var result = items.Select(item => CreateCasesInDb(item.Title)).ToArray(); @@ -220,9 +155,9 @@ public Cases CloseCases(int caseID) Title = cases.Title }; - CRMDbContext.Cases.Update(itemToUpdate); + CrmDbContext.Cases.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); cases.IsClosed = true; @@ -239,7 +174,7 @@ public Cases ReOpenCases(int caseID) CRMSecurity.DemandAccessTo(cases); - CRMDbContext.Cases.Update(new DbCase + CrmDbContext.Cases.Update(new DbCase { Id = cases.ID, CreateBy = cases.CreateBy, @@ -251,7 +186,7 @@ public Cases ReOpenCases(int caseID) Title = cases.Title }); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); cases.IsClosed = false; @@ -280,22 +215,22 @@ private int CreateCasesInDb(String title) TenantId = TenantID }; - CRMDbContext.Cases.Add(dbCase); + CrmDbContext.Cases.Add(dbCase); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return dbCase.Id; } - public virtual void UpdateCases(Cases cases) + public void UpdateCases(Cases cases) { CRMSecurity.DemandEdit(cases); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); - CRMDbContext.Cases.Update(new DbCase + CrmDbContext.Cases.Update(new DbCase { Id = cases.ID, Title = cases.Title, @@ -307,10 +242,10 @@ public virtual void UpdateCases(Cases cases) CreateOn = cases.CreateOn }); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } - public virtual Cases DeleteCases(int casesID) + public Cases DeleteCases(int casesID) { if (casesID <= 0) return null; @@ -327,7 +262,7 @@ public virtual Cases DeleteCases(int casesID) return cases; } - public virtual List DeleteBatchCases(List caseses) + public List DeleteBatchCases(List caseses) { caseses = caseses.FindAll(CRMSecurity.CanDelete).ToList(); @@ -341,7 +276,7 @@ public virtual List DeleteBatchCases(List caseses) return caseses; } - public virtual List DeleteBatchCases(int[] casesID) + public List DeleteBatchCases(int[] casesID) { if (casesID == null || !casesID.Any()) return null; @@ -363,31 +298,31 @@ private void DeleteBatchCasesExecute(List caseses) var tagdao = FilesIntegration.DaoFactory.GetTagDao(); - var tagNames = Query(CRMDbContext.RelationshipEvent) + var tagNames = Query(CrmDbContext.RelationshipEvent) .Where(x => x.HaveFiles && casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case) .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); var filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => Convert.ToInt32(t.EntryId)).ToArray(); - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - CRMDbContext.RemoveRange(Query(CRMDbContext.FieldValue) + CrmDbContext.RemoveRange(Query(CrmDbContext.FieldValue) .Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); - CRMDbContext.RemoveRange(Query(CRMDbContext.RelationshipEvent) + CrmDbContext.RemoveRange(Query(CrmDbContext.RelationshipEvent) .Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); - CRMDbContext.RemoveRange(Query(CRMDbContext.Tasks) + CrmDbContext.RemoveRange(Query(CrmDbContext.Tasks) .Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); - CRMDbContext.RemoveRange(CRMDbContext.EntityTags.Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); + CrmDbContext.RemoveRange(CrmDbContext.EntityTags.Where(x => casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case)); - CRMDbContext.Cases.RemoveRange(caseses.ConvertAll(x => new DbCase + CrmDbContext.Cases.RemoveRange(caseses.ConvertAll(x => new DbCase { Id = x.ID })); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); @@ -460,7 +395,7 @@ public int GetCasesCount( else { - var countWithoutPrivate = Query(CRMDbContext.Cases).Count(); + var countWithoutPrivate = Query(CrmDbContext.Cases).Count(); var privateCount = exceptIDs.Count; @@ -494,7 +429,7 @@ private IQueryable GetDbCasesByFilters( IEnumerable tags) { - var result = Query(CRMDbContext.Cases); + var result = Query(CrmDbContext.Cases); var ids = new List(); @@ -523,7 +458,7 @@ private IQueryable GetDbCasesByFilters( if (contactID > 0) { - var sqlQuery = CRMDbContext.EntityContact + var sqlQuery = CrmDbContext.EntityContact .Where(x => x.ContactId == contactID && x.EntityType == EntityType.Case); if (ids.Count > 0) @@ -570,7 +505,7 @@ public List GetCases(IEnumerable casesID) { if (casesID == null || !casesID.Any()) return new List(); - var result = Query(CRMDbContext.Cases) + var result = Query(CrmDbContext.Cases) .Where(x => casesID.Contains(x.Id)) .ToList(); @@ -626,7 +561,7 @@ public List GetCasesByPrefix(String prefix, int from, int count) var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); - var q = Query(CRMDbContext.Cases); + var q = Query(CrmDbContext.Cases); if (keywords.Length == 1) { @@ -650,9 +585,9 @@ public List GetCasesByPrefix(String prefix, int from, int count) } - public virtual List GetByID(int[] ids) + public List GetByID(int[] ids) { - var result = CRMDbContext.Cases + var result = CrmDbContext.Cases .Where(x => ids.Contains(x.Id)) .ToList(); @@ -660,7 +595,7 @@ public virtual List GetByID(int[] ids) return _mapper.Map, List>(result); } - public virtual Cases GetByID(int id) + public Cases GetByID(int id) { if (id <= 0) return null; diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 05b0cf2fbed..14d91be1155 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -53,88 +53,7 @@ using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Core.Dao -{ - public class CachedContactDao : ContactDao - { - private readonly HttpRequestDictionary _contactCache; - - public CachedContactDao( - DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - CrmSecurity crmSecurity, - IHttpContextAccessor httpContextAccessor, - TenantUtil tenantUtil, - AuthorizationManager authorizationManager, - FilesIntegration filesIntegration, - FactoryIndexerContact factoryIndexerContact, - FactoryIndexerContactInfo factoryIndexerContactInfo, - IOptionsMonitor logger, - ICache ascCache, - DbContextManager coreDbContext, - BundleSearch bundleSearch, - IMapper mapper) : - base(dbContextManager, - tenantManager, - securityContext, - crmSecurity, - tenantUtil, - authorizationManager, - filesIntegration, - factoryIndexerContact, - factoryIndexerContactInfo, - logger, - ascCache, - coreDbContext, - bundleSearch, - mapper) - { - _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact"); - } - - public override Contact GetByID(int contactID) - { - return _contactCache.Get(contactID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(contactID)); - } - - private Contact GetByIDBase(int contactID) - { - return base.GetByID(contactID); - } - - public override Contact DeleteContact(int contactID) - { - ResetCache(contactID); - - return base.DeleteContact(contactID); - } - - public override void UpdateContact(Contact contact) - { - if (contact != null && contact.ID > 0) - ResetCache(contact.ID); - - base.UpdateContact(contact); - } - - - public override int SaveContact(Contact contact) - { - if (contact != null) - { - ResetCache(contact.ID); - } - - return base.SaveContact(contact); - - } - - private void ResetCache(int contactID) - { - _contactCache.Reset(contactID.ToString()); - } - } - +{ [Scope] public class ContactDao : AbstractDao { @@ -191,7 +110,7 @@ public List GetContactsByPrefix(String prefix, int searchType, int from var keywords = prefix.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - var sqlQuery = Query(CRMDbContext.Contacts); + var sqlQuery = Query(CrmDbContext.Contacts); switch (searchType) { @@ -305,7 +224,7 @@ public int GetContactsCount(String searchText, { excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) - .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + .Except(Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true && !x.IsCompany).Select(x => x.Id)) .ToList(); @@ -316,7 +235,7 @@ public int GetContactsCount(String searchText, case ContactListViewType.Company: { excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) - .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + .Except(Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true && x.IsCompany).Select(x => x.Id)) .ToList(); @@ -327,7 +246,7 @@ public int GetContactsCount(String searchText, { excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)) .Union(CRMSecurity.GetPrivateItems(typeof(Person))) - .Except(Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + .Except(Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true && x.IsCompany).Select(x => x.Id)) .ToList(); @@ -387,13 +306,13 @@ public int GetContactsCount(String searchText, } else { - var countWithoutPrivate = Query(CRMDbContext.Contacts).Count(); + var countWithoutPrivate = Query(CrmDbContext.Contacts).Count(); var sharedTypes = new[] { ShareType.Read, ShareType.ReadWrite }.ToList(); var privateCount = CRMSecurity.GetPrivateItemsCount(typeof(Person)) + CRMSecurity.GetPrivateItemsCount(typeof(Company)) - - Query(CRMDbContext.Contacts).Where(x => x.IsShared.HasValue ? + Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true).Count(); if (privateCount < 0) @@ -445,7 +364,7 @@ public List SearchContactsByEmail(string searchText, int maxCount) do { - var query = Query(CRMDbContext.Contacts).Join(CRMDbContext.ContactsInfo, + var query = Query(CrmDbContext.Contacts).Join(CrmDbContext.ContactsInfo, x => new { Column1 = x.TenantId, Column2 = x.Id }, y => new { Column1 = y.TenantId, Column2 = y.ContactId }, (x, y) => new { x, y }) @@ -681,7 +600,7 @@ private IQueryable GetDbContactsByFilters( bool? isShared = null) { - var sqlQuery = Query(CRMDbContext.Contacts); + var sqlQuery = Query(CrmDbContext.Contacts); var ids = new List(); @@ -774,14 +693,14 @@ private IQueryable GetDbContactsByFilters( case ContactListViewType.WithOpportunity: if (ids.Count > 0) { - ids = CRMDbContext.EntityContact.Where(x => ids.Contains(x.ContactId) && x.EntityType == EntityType.Opportunity) + ids = CrmDbContext.EntityContact.Where(x => ids.Contains(x.ContactId) && x.EntityType == EntityType.Opportunity) .Select(x => x.ContactId) .Distinct() .ToList(); } else { - ids = CRMDbContext.EntityContact.Where(x => x.EntityType == EntityType.Opportunity) + ids = CrmDbContext.EntityContact.Where(x => x.EntityType == EntityType.Opportunity) .Select(x => x.ContactId) .Distinct() .ToList(); @@ -841,7 +760,7 @@ private IQueryable GetDbContactsByFilters( if (exceptIDs.Count > _MaxCountForSQLNotIn) { - ids = Query(CRMDbContext.Contacts).Select(x => x.Id).ToList(); + ids = Query(CrmDbContext.Contacts).Select(x => x.Id).ToList(); ids = ids.Except(exceptIDs).ToList(); if (ids.Count == 0) return null; @@ -935,7 +854,7 @@ private List GetCrudeContacts( break; case ContactSortedByType.History: { - dbContactsQuery = dbContactsQuery.GroupJoin(Query(CRMDbContext.RelationshipEvent), + dbContactsQuery = dbContactsQuery.GroupJoin(Query(CrmDbContext.RelationshipEvent), x => x.Id, y => y.ContactId, (x, y) => new { x, y }) @@ -972,7 +891,7 @@ public List GetContactsByName(String title, bool isCompany) if (isCompany) { - return CRMDbContext.Contacts.Where(x => String.Compare(x.DisplayName, title) == 0 && x.IsCompany) + return CrmDbContext.Contacts.Where(x => String.Compare(x.DisplayName, title) == 0 && x.IsCompany) .ToList() .ConvertAll(ToContact) .FindAll(CRMSecurity.CanAccessTo); @@ -985,14 +904,14 @@ public List GetContactsByName(String title, bool isCompany) { if (titleParts.Length == 1) { - return Query(CRMDbContext.Contacts).Where(x => String.Compare(x.DisplayName, title) == 0 && !x.IsCompany) + return Query(CrmDbContext.Contacts).Where(x => String.Compare(x.DisplayName, title) == 0 && !x.IsCompany) .ToList() .ConvertAll(ToContact) .FindAll(CRMSecurity.CanAccessTo); } else { - return Query(CRMDbContext.Contacts).Where(x => String.Compare(x.DisplayName, String.Concat(titleParts[0], _displayNameSeparator, titleParts[1])) == 0 && !x.IsCompany) + return Query(CrmDbContext.Contacts).Where(x => String.Compare(x.DisplayName, String.Concat(titleParts[0], _displayNameSeparator, titleParts[1])) == 0 && !x.IsCompany) .ToList() .ConvertAll(ToContact) .FindAll(CRMSecurity.CanAccessTo); @@ -1016,11 +935,11 @@ public void RemoveMember(int[] peopleID) TenantId = TenantID }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); RemoveRelativeInDb(null, EntityType.Person, peopleID); @@ -1035,10 +954,10 @@ public void RemoveMember(int peopleID) TenantId = TenantID }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); RemoveRelative(0, EntityType.Person, peopleID); } @@ -1053,10 +972,10 @@ public void AddMemberInDb(int peopleID, int companyID) TenantId = TenantID }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); SetRelative(companyID, EntityType.Person, peopleID); } @@ -1071,19 +990,19 @@ public void SetMembers(int companyID, params int[] peopleIDs) if (companyID == 0) throw new ArgumentException(); - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); - CRMDbContext.EntityContact - .RemoveRange(CRMDbContext.EntityContact + CrmDbContext.EntityContact + .RemoveRange(CrmDbContext.EntityContact .Where(x => x.EntityType == EntityType.Person && x.ContactId == companyID)); - var itemsToUpdate = Query(CRMDbContext.Contacts).Where(x => x.CompanyId == companyID).ToList(); + var itemsToUpdate = Query(CrmDbContext.Contacts).Where(x => x.CompanyId == companyID).ToList(); itemsToUpdate.ForEach(x => x.CompanyId = 0); - CRMDbContext.UpdateRange(itemsToUpdate); + CrmDbContext.UpdateRange(itemsToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); if (!(peopleIDs == null || peopleIDs.Length == 0)) { @@ -1096,12 +1015,12 @@ public void SetMembers(int companyID, params int[] peopleIDs) TenantId = TenantID }; - CRMDbContext.Attach(contactItemToUpdate); - CRMDbContext.Entry(contactItemToUpdate).Property(x => x.CompanyId).IsModified = true; - CRMDbContext.Update(contactItemToUpdate); + CrmDbContext.Attach(contactItemToUpdate); + CrmDbContext.Entry(contactItemToUpdate).Property(x => x.CompanyId).IsModified = true; + CrmDbContext.Update(contactItemToUpdate); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); foreach (var peopleID in peopleIDs) { @@ -1115,7 +1034,7 @@ public void SetMembers(int companyID, params int[] peopleIDs) public void SetRelativeContactProject(IEnumerable contactid, int projectid) { - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); foreach (var id in contactid) { @@ -1126,7 +1045,7 @@ public void SetRelativeContactProject(IEnumerable contactid, int projectid) TenantId = TenantID }; - CRMDbContext.Projects.Add(itemToInsert); + CrmDbContext.Projects.Add(itemToInsert); } tx.Commit(); @@ -1135,14 +1054,14 @@ public void SetRelativeContactProject(IEnumerable contactid, int projectid) public void RemoveRelativeContactProject(int contactid, int projectid) { - CRMDbContext.RemoveRange(Query(CRMDbContext.Projects) + CrmDbContext.RemoveRange(Query(CrmDbContext.Projects) .Where(x => x.ContactId == contactid && x.ProjectId == projectid)); } public IEnumerable GetContactsByProjectID(int projectid) { - var contactIds = Query(CRMDbContext.Projects) + var contactIds = Query(CrmDbContext.Projects) .Where(x => x.ProjectId == projectid) .Select(x => x.ContactId); @@ -1163,7 +1082,7 @@ public List GetRestrictedMembers(int companyID) public Dictionary GetMembersCount(int[] companyID) { - return CRMDbContext.EntityContact + return CrmDbContext.EntityContact .Where(x => companyID.Contains(x.ContactId) && x.EntityType == EntityType.Person) .GroupBy(x => x.ContactId) .Select(x => new { GroupId = x.Key, Count = x.Count() }) @@ -1173,14 +1092,14 @@ public Dictionary GetMembersCount(int[] companyID) public int GetMembersCount(int companyID) { - return CRMDbContext.EntityContact + return CrmDbContext.EntityContact .Where(x => x.ContactId == companyID && x.EntityType == EntityType.Person) .Count(); } public List GetMembersIDs(int companyID) { - return CRMDbContext.EntityContact + return CrmDbContext.EntityContact .Where(x => x.ContactId == companyID && x.EntityType == EntityType.Person) .Select(x => x.EntityId) .ToList(); @@ -1188,9 +1107,9 @@ public List GetMembersIDs(int companyID) public Dictionary GetMembersIDsAndShareType(int companyID) { - return CRMDbContext.EntityContact + return CrmDbContext.EntityContact .Where(x => x.ContactId == companyID && x.EntityType == EntityType.Person) - .GroupJoin(CRMDbContext.Contacts, + .GroupJoin(CrmDbContext.Contacts, x => x.EntityId, y => y.Id, (x, y) => new { x, y }) @@ -1202,7 +1121,7 @@ public List GetMembersIDs(int companyID) } - public virtual void UpdateContact(Contact contact) + public void UpdateContact(Contact contact) { UpdateContactFromDb(contact); } @@ -1268,7 +1187,7 @@ private void UpdateContactFromDb(Contact contact) contact.Industry = contact.Industry.Trim(); - var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.Id == contact.ID); + var itemToUpdate = Query(CrmDbContext.Contacts).Single(x => x.Id == contact.ID); itemToUpdate.FirstName = firstName; itemToUpdate.LastName = lastName; @@ -1286,8 +1205,8 @@ private void UpdateContactFromDb(Contact contact) itemToUpdate.Currency = contact.Currency; itemToUpdate.TenantId = TenantID; - CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(itemToUpdate); + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); @@ -1306,12 +1225,12 @@ public void UpdateContactStatus(IEnumerable contactid, int statusid) TenantId = TenantID }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.StatusId).IsModified = true; + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.StatusId).IsModified = true; } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); @@ -1324,7 +1243,7 @@ public List FindDuplicateByEmail(List items, bool resultReal) var result = new List(); var emails = items.ConvertAll(i => i.Data).ToList(); - var sqlQuery = Query(CRMDbContext.ContactsInfo) + var sqlQuery = Query(CrmDbContext.ContactsInfo) .Where(x => emails.Contains(x.Data) && x.Type == ContactInfoType.Email); if (resultReal) @@ -1346,9 +1265,9 @@ public List FindDuplicateByEmail(List items, bool resultReal) return result; } - public virtual Dictionary SaveContactList(List items) + public Dictionary SaveContactList(List items) { - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); var result = new Dictionary(); @@ -1370,9 +1289,9 @@ public virtual Dictionary SaveContactList(List items) return result; } - public virtual void UpdateContactList(List items) + public void UpdateContactList(List items) { - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); for (int index = 0; index < items.Count; index++) { @@ -1401,17 +1320,17 @@ public void MakePublic(int contactId, bool isShared) TenantId = TenantID }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.IsShared).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.IsShared).IsModified = true; + CrmDbContext.SaveChanges(); } - public virtual int SaveContact(Contact contact) + public int SaveContact(Contact contact) { var result = SaveContactToDb(contact); - FactoryIndexerContact.Index(Query(CRMDbContext.Contacts) + FactoryIndexerContact.Index(Query(CrmDbContext.Contacts) .Where(x => x.Id == contact.ID).Single()); // Delete relative keys @@ -1499,8 +1418,8 @@ private int SaveContactToDb(Contact contact) Currency = contact.Currency }; - CRMDbContext.Contacts.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.Contacts.Add(itemToInsert); + CrmDbContext.SaveChanges(); contact.ID = itemToInsert.Id; @@ -1512,12 +1431,12 @@ private int SaveContactToDb(Contact contact) public Boolean IsExist(int contactID) { - return Query(CRMDbContext.Contacts).Where(x => x.Id == contactID).Any(); + return Query(CrmDbContext.Contacts).Where(x => x.Id == contactID).Any(); } public Boolean CanDelete(int contactID) { - return !Query(CRMDbContext.Invoices).Where(x => x.ContactId == contactID || x.ConsigneeId == contactID).Any(); + return !Query(CrmDbContext.Invoices).Where(x => x.ContactId == contactID || x.ConsigneeId == contactID).Any(); } public Dictionary CanDelete(int[] contactID) @@ -1528,10 +1447,10 @@ public Dictionary CanDelete(int[] contactID) var contactIDs = contactID.Distinct().ToList(); - List hasInvoiceIDs = Query(CRMDbContext.Invoices).Where(x => contactID.Contains(x.ContactId)) + List hasInvoiceIDs = Query(CrmDbContext.Invoices).Where(x => contactID.Contains(x.ContactId)) .Distinct() .Select(x => x.ContactId).Union( - Query(CRMDbContext.Invoices).Where(x => contactID.Contains(x.ConsigneeId)) + Query(CrmDbContext.Invoices).Where(x => contactID.Contains(x.ConsigneeId)) .Distinct() .Select(x => x.ConsigneeId)).ToList(); @@ -1544,14 +1463,14 @@ public Dictionary CanDelete(int[] contactID) return result; } - public virtual Contact GetByID(int contactID) + public Contact GetByID(int contactID) { return GetByIDFromDb(contactID); } public Contact GetByIDFromDb(int contactID) { - return ToContact(Query(CRMDbContext.Contacts) + return ToContact(Query(CrmDbContext.Contacts) .FirstOrDefault(x => x.Id == contactID)); } @@ -1559,7 +1478,7 @@ public List GetContacts(int[] contactID) { if (contactID == null || contactID.Length == 0) return new List(); - return Query(CRMDbContext.Contacts) + return Query(CrmDbContext.Contacts) .Where(x => contactID.Contains(x.Id)) .ToList() .ConvertAll(ToContact) @@ -1570,7 +1489,7 @@ public List GetRestrictedContacts(int[] contactID) { if (contactID == null || contactID.Length == 0) return new List(); - return Query(CRMDbContext.Contacts) + return Query(CrmDbContext.Contacts) .Where(x => contactID.Contains(x.Id)) .ToList() .ConvertAll(ToContact) @@ -1581,13 +1500,13 @@ public List GetRestrictedAndAccessedContacts(int[] contactID) { if (contactID == null || contactID.Length == 0) return new List(); - return Query(CRMDbContext.Contacts) + return Query(CrmDbContext.Contacts) .Where(x => contactID.Contains(x.Id)) .ToList() .ConvertAll(ToContact); } - public virtual List DeleteBatchContact(int[] contactID) + public List DeleteBatchContact(int[] contactID) { if (contactID == null || contactID.Length == 0) return null; @@ -1602,7 +1521,7 @@ public virtual List DeleteBatchContact(int[] contactID) return contacts; } - public virtual List DeleteBatchContact(List contacts) + public List DeleteBatchContact(List contacts) { contacts = contacts.FindAll(CRMSecurity.CanDelete).ToList(); if (!contacts.Any()) return contacts; @@ -1615,7 +1534,7 @@ public virtual List DeleteBatchContact(List contacts) return contacts; } - public virtual Contact DeleteContact(int contactID) + public Contact DeleteContact(int contactID) { if (contactID <= 0) return null; @@ -1624,7 +1543,7 @@ public virtual Contact DeleteContact(int contactID) CRMSecurity.DemandDelete(contact); - FactoryIndexerContact.Delete(Query(CRMDbContext.Contacts) + FactoryIndexerContact.Delete(Query(CrmDbContext.Contacts) .Where(x => x.Id == contactID).Single()); DeleteBatchContactsExecute(new List() { contact }); @@ -1654,11 +1573,11 @@ private void DeleteBatchContactsExecute(List contacts) var contactID = newContactID.ToArray(); int[] filesIDs = new int[0]; - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); var tagdao = FilesIntegration.DaoFactory.GetTagDao(); - var tagNames = Query(CRMDbContext.RelationshipEvent).Where(x => contactID.Contains(x.ContactId) && x.HaveFiles) + var tagNames = Query(CrmDbContext.RelationshipEvent).Where(x => contactID.Contains(x.ContactId) && x.HaveFiles) .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); if (0 < tagNames.Length) @@ -1669,32 +1588,32 @@ private void DeleteBatchContactsExecute(List contacts) .ToArray(); } - CRMDbContext.RemoveRange(Query(CRMDbContext.FieldValue) + CrmDbContext.RemoveRange(Query(CrmDbContext.FieldValue) .Where(x => contactID.Contains(x.EntityId)) .Where(x => x.EntityType == EntityType.Contact || x.EntityType == EntityType.Person || x.EntityType == EntityType.Company) ); - CRMDbContext.RemoveRange(Query(CRMDbContext.Tasks) + CrmDbContext.RemoveRange(Query(CrmDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId))); - CRMDbContext.RemoveRange(CRMDbContext.EntityTags + CrmDbContext.RemoveRange(CrmDbContext.EntityTags .Where(x => contactID.Contains(x.EntityId) && x.EntityType == EntityType.Contact)); - CRMDbContext.RemoveRange(CRMDbContext.RelationshipEvent.Where(x => contactID.Contains(x.ContactId))); + CrmDbContext.RemoveRange(CrmDbContext.RelationshipEvent.Where(x => contactID.Contains(x.ContactId))); - var dealToUpdate = CRMDbContext.Deals.Where(x => contactID.Contains(x.ContactId)).ToList(); + var dealToUpdate = CrmDbContext.Deals.Where(x => contactID.Contains(x.ContactId)).ToList(); dealToUpdate.ForEach(x => x.ContactId = 0); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); if (companyID.Count > 0) { - var itemToUpdate = Query(CRMDbContext.Contacts).Where(x => companyID.Contains(x.CompanyId)).ToList(); + var itemToUpdate = Query(CrmDbContext.Contacts).Where(x => companyID.Contains(x.CompanyId)).ToList(); itemToUpdate.ForEach(x => x.CompanyId = 0); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } if (personsID.Count > 0) @@ -1704,15 +1623,15 @@ private void DeleteBatchContactsExecute(List contacts) RemoveRelativeInDb(contactID, EntityType.Any, null); - CRMDbContext.RemoveRange(Query(CRMDbContext.ContactsInfo).Where(x => contactID.Contains(x.ContactId))); + CrmDbContext.RemoveRange(Query(CrmDbContext.ContactsInfo).Where(x => contactID.Contains(x.ContactId))); - CRMDbContext.RemoveRange(contactID.ToList().ConvertAll(x => new DbContact + CrmDbContext.RemoveRange(contactID.ToList().ConvertAll(x => new DbContact { Id = x, TenantId = TenantID })); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); @@ -1771,74 +1690,74 @@ public void MergeDublicate(int fromContactID, int toContactID) if (fromContact == null || toContact == null) throw new ArgumentException(); - using (var tx = CRMDbContext.Database.BeginTransaction()) + using (var tx = CrmDbContext.Database.BeginTransaction()) { - var taskToUpdate = Query(CRMDbContext.Tasks) + var taskToUpdate = Query(CrmDbContext.Tasks) .Where(x => x.ContactId == fromContactID) .ToList(); taskToUpdate.ForEach(x => x.ContactId = toContactID); - CRMDbContext.UpdateRange(taskToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(taskToUpdate); + CrmDbContext.SaveChanges(); // crm_entity_contact - CRMDbContext.EntityContact.RemoveRange( - CRMDbContext.EntityContact - .Join(CRMDbContext.EntityContact, + CrmDbContext.EntityContact.RemoveRange( + CrmDbContext.EntityContact + .Join(CrmDbContext.EntityContact, x => new { x.EntityId, x.EntityType }, y => new { y.EntityId, y.EntityType }, (x, y) => new { x, y }) .Where(x => x.x.ContactId == fromContactID && x.y.ContactId == toContactID) .Select(x => x.x)); - var entityContactToUpdate = CRMDbContext.EntityContact.Where(x => x.ContactId == fromContactID).ToList(); + var entityContactToUpdate = CrmDbContext.EntityContact.Where(x => x.ContactId == fromContactID).ToList(); entityContactToUpdate.ForEach(x => x.ContactId = toContactID); - CRMDbContext.UpdateRange(entityContactToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(entityContactToUpdate); + CrmDbContext.SaveChanges(); // crm_deal - var dealsToUpdate = Query(CRMDbContext.Deals).Where(x => x.ContactId == fromContactID).ToList(); + var dealsToUpdate = Query(CrmDbContext.Deals).Where(x => x.ContactId == fromContactID).ToList(); dealsToUpdate.ForEach(x => x.ContactId = toContactID); - CRMDbContext.UpdateRange(dealsToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(dealsToUpdate); + CrmDbContext.SaveChanges(); // crm_invoice - var invoicesToUpdate = Query(CRMDbContext.Invoices).Where(x => x.ContactId == fromContactID).ToList(); + var invoicesToUpdate = Query(CrmDbContext.Invoices).Where(x => x.ContactId == fromContactID).ToList(); invoicesToUpdate.ForEach(x => x.ContactId = toContactID); - CRMDbContext.UpdateRange(invoicesToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(invoicesToUpdate); + CrmDbContext.SaveChanges(); // crm_projects - var dublicateProjectID = Query(CRMDbContext.Projects) - .Join(CRMDbContext.Projects, + var dublicateProjectID = Query(CrmDbContext.Projects) + .Join(CrmDbContext.Projects, x => x.ProjectId, y => y.ProjectId, (x, y) => new { x, y }) .Where(x => x.x.ContactId == fromContactID && x.y.ContactId == toContactID) .Select(x => x.x.ProjectId); - CRMDbContext.RemoveRange(Query(CRMDbContext.Projects) + CrmDbContext.RemoveRange(Query(CrmDbContext.Projects) .Where(x => x.ContactId == fromContactID && dublicateProjectID.Contains(x.ProjectId))); - var projectsToUpdate = Query(CRMDbContext.Projects).Where(x => x.ContactId == fromContactID).ToList(); + var projectsToUpdate = Query(CrmDbContext.Projects).Where(x => x.ContactId == fromContactID).ToList(); projectsToUpdate.ForEach(x => x.ContactId = toContactID); - CRMDbContext.UpdateRange(projectsToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(projectsToUpdate); + CrmDbContext.SaveChanges(); // crm_relationship_event - var relationshipEventToUpdate = Query(CRMDbContext.RelationshipEvent).Where(x => x.ContactId == fromContactID).ToList(); + var relationshipEventToUpdate = Query(CrmDbContext.RelationshipEvent).Where(x => x.ContactId == fromContactID).ToList(); relationshipEventToUpdate.ForEach(x => x.ContactId = toContactID); - CRMDbContext.UpdateRange(relationshipEventToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(relationshipEventToUpdate); + CrmDbContext.SaveChanges(); // crm_entity_tag - var dublicateTagsID = CRMDbContext.EntityTags.Join(CRMDbContext.EntityTags, + var dublicateTagsID = CrmDbContext.EntityTags.Join(CrmDbContext.EntityTags, x => new { x.TagId, x.EntityType }, y => new { y.TagId, y.EntityType }, (x, y) => new { x, y } @@ -1846,41 +1765,41 @@ public void MergeDublicate(int fromContactID, int toContactID) .Where(x => x.x.EntityId == fromContactID && x.y.EntityId == toContactID) .Select(x => x.x.TagId).ToList(); - CRMDbContext.EntityTags.Where(x => x.EntityId == fromContactID && + CrmDbContext.EntityTags.Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact && dublicateTagsID.Contains(x.TagId)); - var entityTagToUpdate = CRMDbContext.EntityTags.Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact).ToList(); + var entityTagToUpdate = CrmDbContext.EntityTags.Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact).ToList(); entityTagToUpdate.ForEach(x => x.EntityId = toContactID); - CRMDbContext.UpdateRange(entityTagToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(entityTagToUpdate); + CrmDbContext.SaveChanges(); // crm_field_value - var dublicateCustomFieldValueID = Query(CRMDbContext.FieldValue) - .Join(CRMDbContext.FieldValue, + var dublicateCustomFieldValueID = Query(CrmDbContext.FieldValue) + .Join(CrmDbContext.FieldValue, x => new { x.TenantId, x.FieldId, x.EntityType }, y => new { y.TenantId, y.FieldId, y.EntityType }, (x, y) => new { x, y }) .Where(x => x.x.EntityId == fromContactID && x.y.EntityId == toContactID) .Select(x => x.x.FieldId); - CRMDbContext.RemoveRange(CRMDbContext.FieldValue.Where(x => x.EntityId == fromContactID && + CrmDbContext.RemoveRange(CrmDbContext.FieldValue.Where(x => x.EntityId == fromContactID && (new[] { EntityType.Contact, EntityType.Person, EntityType.Company }).Contains(x.EntityType) && dublicateCustomFieldValueID.Contains(x.FieldId))); - var fieldValueToUpdate = Query(CRMDbContext.FieldValue) + var fieldValueToUpdate = Query(CrmDbContext.FieldValue) .Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact).ToList(); fieldValueToUpdate.ForEach(x => x.EntityId = toContactID); - CRMDbContext.UpdateRange(fieldValueToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(fieldValueToUpdate); + CrmDbContext.SaveChanges(); // crm_contact_info - var dublicatePrimaryContactInfoID = Query(CRMDbContext.ContactsInfo) - .Join(CRMDbContext.ContactsInfo, + var dublicatePrimaryContactInfoID = Query(CrmDbContext.ContactsInfo) + .Join(CrmDbContext.ContactsInfo, x => new { x.TenantId, x.Type, x.Category, x.IsPrimary }, y => new { y.TenantId, y.Type, y.Category, y.IsPrimary }, (x, y) => new { x, y }) @@ -1890,17 +1809,17 @@ public void MergeDublicate(int fromContactID, int toContactID) x.y.ContactId == toContactID) .Select(x => x.x.Id); - var contactInfosToUpdate = Query(CRMDbContext.ContactsInfo) + var contactInfosToUpdate = Query(CrmDbContext.ContactsInfo) .Where(x => x.ContactId == fromContactID && dublicatePrimaryContactInfoID.Contains(x.Id)) .ToList(); contactInfosToUpdate.ForEach(x => x.IsPrimary = false); - CRMDbContext.UpdateRange(fieldValueToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(fieldValueToUpdate); + CrmDbContext.SaveChanges(); - var dublicateContactInfoID = Query(CRMDbContext.ContactsInfo) - .Join(CRMDbContext.ContactsInfo, + var dublicateContactInfoID = Query(CrmDbContext.ContactsInfo) + .Join(CrmDbContext.ContactsInfo, x => new { x.TenantId, x.Type, x.IsPrimary, x.Category, x.Data }, y => new { y.TenantId, y.Type, y.IsPrimary, y.Category, y.Data }, (x, y) => new { x, y }) @@ -1908,41 +1827,41 @@ public void MergeDublicate(int fromContactID, int toContactID) .Select(x => x.x.Id) .ToList(); - CRMDbContext.ContactsInfo.RemoveRange(dublicateContactInfoID.ConvertAll(x => new DbContactInfo + CrmDbContext.ContactsInfo.RemoveRange(dublicateContactInfoID.ConvertAll(x => new DbContactInfo { Id = x, ContactId = fromContactID, TenantId = TenantID })); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); - var contactInfoToUpdate = Query(CRMDbContext.ContactsInfo).Where(x => x.ContactId == fromContactID).ToList(); + var contactInfoToUpdate = Query(CrmDbContext.ContactsInfo).Where(x => x.ContactId == fromContactID).ToList(); contactInfoToUpdate.ForEach(x => x.ContactId = toContactID); - CRMDbContext.UpdateRange(contactInfoToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(contactInfoToUpdate); + CrmDbContext.SaveChanges(); MergeContactInfo(fromContact, toContact); // crm_contact if ((fromContact is Company) && (toContact is Company)) { - var contactsToUpdate = Query(CRMDbContext.Contacts).Where(x => x.CompanyId == fromContactID).ToList(); + var contactsToUpdate = Query(CrmDbContext.Contacts).Where(x => x.CompanyId == fromContactID).ToList(); contactsToUpdate.ForEach(x => x.CompanyId = toContactID); - CRMDbContext.UpdateRange(contactsToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.UpdateRange(contactsToUpdate); + CrmDbContext.SaveChanges(); } - CRMDbContext.Contacts.Remove(new DbContact + CrmDbContext.Contacts.Remove(new DbContact { Id = fromContactID }); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); } @@ -1952,7 +1871,7 @@ public void MergeDublicate(int fromContactID, int toContactID) public List GetContactIDsByCompanyIds(List companyIDs) { - return Query(CRMDbContext.Contacts) + return Query(CrmDbContext.Contacts) .Where(x => companyIDs.Contains(x.CompanyId) && !x.IsCompany) .Select(x => x.Id) .Distinct() @@ -1961,7 +1880,7 @@ public List GetContactIDsByCompanyIds(List companyIDs) public List GetContactIDsByContactInfo(ContactInfoType infoType, String data, int? category, bool? isPrimary) { - var q = Query(CRMDbContext.ContactsInfo) + var q = Query(CrmDbContext.ContactsInfo) .Where(x => x.Type == infoType); if (!string.IsNullOrWhiteSpace(data)) @@ -2063,9 +1982,9 @@ public void SetContactCreationDate(int contactId, DateTime creationDate) CreateOn = TenantUtil.DateTimeToUtc(creationDate) }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.CreateOn).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.CreateOn).IsModified = true; + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); @@ -2086,9 +2005,9 @@ public void SetContactLastModifedDate(int contactId, DateTime lastModifedDate) LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate) }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.LastModifedOn).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.LastModifedOn).IsModified = true; + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 251431753ac..6482347394f 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -46,75 +46,6 @@ namespace ASC.CRM.Core.Dao { - public class CachedContactInfo : ContactInfoDao - { - private readonly HttpRequestDictionary _contactInfoCache; - - public CachedContactInfo( - DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - TenantUtil tenantUtil, - IOptionsMonitor logger, - ICache ascCache, - FactoryIndexerContactInfo factoryIndexerContactInfo, - IHttpContextAccessor httpContextAccessor, - IServiceProvider serviceProvider, - IMapper mapper - ) - : base( - dbContextManager, - tenantManager, - securityContext, - tenantUtil, - logger, - ascCache, - factoryIndexerContactInfo, - serviceProvider, - mapper) - { - _contactInfoCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_contact_info"); - } - - public override ContactInfo GetByID(int id) - { - return _contactInfoCache.Get(id.ToString(), () => GetByIDBase(id)); - } - - public override void Delete(int id) - { - - ResetCache(id); - - base.Delete(id); - } - - private ContactInfo GetByIDBase(int id) - { - return base.GetByID(id); - } - - private void ResetCache(int id) - { - _contactInfoCache.Reset(id.ToString()); - } - - public override void DeleteByContact(int contactID) - { - _contactInfoCache.Clear(); - - base.DeleteByContact(contactID); - } - - public override int Update(ContactInfo contactInfo) - { - ResetCache(contactInfo.ID); - - return base.Update(contactInfo); - } - - } - [Scope] public class ContactInfoDao : AbstractDao { @@ -145,43 +76,43 @@ public ContactInfoDao( public TenantUtil TenantUtil { get; } public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } - public virtual ContactInfo GetByID(int id) + public ContactInfo GetByID(int id) { - var dbContactInfo = CRMDbContext.ContactsInfo.SingleOrDefault(x => x.Id == id); + var dbContactInfo = CrmDbContext.ContactsInfo.SingleOrDefault(x => x.Id == id); return _mapper.Map(dbContactInfo); } - public virtual void Delete(int id) + public void Delete(int id) { var itemToDelete = new DbContactInfo { Id = id }; - CRMDbContext.ContactsInfo.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.ContactsInfo.Remove(itemToDelete); + CrmDbContext.SaveChanges(); FactoryIndexerContactInfo.Delete(r => r.Where(a => a.Id, id)); } - public virtual void DeleteByContact(int contactID) + public void DeleteByContact(int contactID) { if (contactID <= 0) return; - CRMDbContext.RemoveRange(Query(CRMDbContext.ContactsInfo) + CrmDbContext.RemoveRange(Query(CrmDbContext.ContactsInfo) .Where(x => x.ContactId == contactID)); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); FactoryIndexerContactInfo.Delete(r => r.Where(a => a.ContactId, contactID)); } - public virtual int Update(ContactInfo contactInfo) + public int Update(ContactInfo contactInfo) { var result = UpdateInDb(contactInfo); - FactoryIndexerContactInfo.Update(Query(CRMDbContext.ContactsInfo) + FactoryIndexerContactInfo.Update(Query(CrmDbContext.ContactsInfo) .Where(x => x.ContactId == contactInfo.ID).Single()); return result; @@ -205,9 +136,9 @@ private int UpdateInDb(ContactInfo contactInfo) TenantId = TenantID }; - CRMDbContext.ContactsInfo.Update(itemToUpdate); + CrmDbContext.ContactsInfo.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return contactInfo.ID; } @@ -219,7 +150,7 @@ public int Save(ContactInfo contactInfo) contactInfo.ID = id; - var dbContactInfo = Query(CRMDbContext.ContactsInfo) + var dbContactInfo = Query(CrmDbContext.ContactsInfo) .Where(x => x.ContactId == contactInfo.ID) .Single(); @@ -243,9 +174,9 @@ private int SaveInDb(ContactInfo contactInfo) }; - CRMDbContext.Add(itemToInsert); + CrmDbContext.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return itemToInsert.Id; @@ -265,16 +196,16 @@ public List GetAll(int[] contactID) { if (contactID == null || contactID.Length == 0) return null; - var result = Query(CRMDbContext.ContactsInfo) + var result = Query(CrmDbContext.ContactsInfo) .Where(x => contactID.Contains(x.ContactId)) .ToList(); return _mapper.Map, List>(result); } - public virtual List GetList(int contactID, ContactInfoType? infoType, int? categoryID, bool? isPrimary) + public List GetList(int contactID, ContactInfoType? infoType, int? categoryID, bool? isPrimary) { - var items = Query(CRMDbContext.ContactsInfo); + var items = Query(CrmDbContext.ContactsInfo); if (contactID > 0) items = items.Where(x => x.ContactId == contactID); @@ -300,7 +231,7 @@ public int[] UpdateList(List items, Contact contact = null) var result = new List(); - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); foreach (var contactInfo in items) result.Add(UpdateInDb(contactInfo)); @@ -311,7 +242,7 @@ public int[] UpdateList(List items, Contact contact = null) { var itemIDs = items.Select(y => y.ID); - var dbContactInfos = Query(CRMDbContext.ContactsInfo) + var dbContactInfos = Query(CrmDbContext.ContactsInfo) .Where(x => itemIDs.Contains(x.Id)); foreach (var dbContactInfo in dbContactInfos) @@ -329,7 +260,7 @@ public int[] SaveList(List items, Contact contact = null) var result = new List(); - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); foreach (var contactInfo in items) { @@ -344,7 +275,7 @@ public int[] SaveList(List items, Contact contact = null) { var itemIDs = items.Select(y => y.ID); - var dbContactInfos = Query(CRMDbContext.ContactsInfo) + var dbContactInfos = Query(CrmDbContext.ContactsInfo) .Where(x => itemIDs.Contains(x.Id)); foreach (var dbContactInfo in dbContactInfos) diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 8e633ed02e5..43359f86b94 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -61,16 +61,16 @@ public CurrencyInfoDao(DbContextManager dbContextManager, } - public virtual List GetAll() + public List GetAll() { - var dbItems = CRMDbContext.CurrencyInfo.ToList(); + var dbItems = CrmDbContext.CurrencyInfo.ToList(); return _mapper.Map, List>(dbItems); } - public virtual CurrencyInfo GetByAbbreviation(string abbreviation) + public CurrencyInfo GetByAbbreviation(string abbreviation) { - var dbItem = CRMDbContext.CurrencyInfo + var dbItem = CrmDbContext.CurrencyInfo .FirstOrDefault(x => String.Compare(x.Abbreviation, abbreviation, true) == 0); return _mapper.Map(dbItem); @@ -79,7 +79,7 @@ public virtual CurrencyInfo GetByAbbreviation(string abbreviation) public List GetBasic() { - var dbItems = CRMDbContext.CurrencyInfo + var dbItems = CrmDbContext.CurrencyInfo .Where(x => x.IsBasic) .ToList(); @@ -88,7 +88,7 @@ public List GetBasic() public List GetOther() { - var dbItems = CRMDbContext.CurrencyInfo + var dbItems = CrmDbContext.CurrencyInfo .Where(x => !x.IsBasic) .ToList(); diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index 48e28a3e9a0..c401e3c576c 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -60,21 +60,23 @@ public CurrencyRateDao( } - public virtual List GetAll() + public List GetAll() { - var rates = CRMDbContext.CurrencyRate.Where(x => x.TenantId == TenantID).ToList(); + var rates = CrmDbContext.CurrencyRate.Where(x => x.TenantId == TenantID).ToList(); return _mapper.Map, List>(rates); } - public virtual CurrencyRate GetByID(int id) + public CurrencyRate GetByID(int id) { - return _mapper.Map(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.Id == id)); + var entity = CrmDbContext.CurrencyRate.Find(id); + + return _mapper.Map(entity); } public CurrencyRate GetByCurrencies(string fromCurrency, string toCurrency) { - return _mapper.Map(CRMDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && + return _mapper.Map(CrmDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && String.Compare(x.ToCurrency, toCurrency, true) == 0)); } @@ -86,7 +88,7 @@ public int SaveOrUpdate(CurrencyRate currencyRate) if (currencyRate.ID > 0 && currencyRate.Rate == 0) return Delete(currencyRate.ID); - if (CRMDbContext.CurrencyRate.Where(x => x.Id == currencyRate.ID).Any()) + if (CrmDbContext.CurrencyRate.Where(x => x.Id == currencyRate.ID).Any()) { var itemToInsert = new DbCurrencyRate { @@ -100,14 +102,14 @@ public int SaveOrUpdate(CurrencyRate currencyRate) TenantId = TenantID }; - CRMDbContext.CurrencyRate.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.CurrencyRate.Add(itemToInsert); + CrmDbContext.SaveChanges(); currencyRate.ID = itemToInsert.Id; } else { - var itemToUpdate = CRMDbContext.CurrencyRate.FirstOrDefault(x => x.Id == currencyRate.ID); + var itemToUpdate = CrmDbContext.CurrencyRate.FirstOrDefault(x => x.Id == currencyRate.ID); itemToUpdate.FromCurrency = currencyRate.FromCurrency.ToUpper(); itemToUpdate.ToCurrency = currencyRate.ToCurrency.ToUpper(); @@ -116,8 +118,8 @@ public int SaveOrUpdate(CurrencyRate currencyRate) itemToUpdate.LastModifedOn = DateTime.UtcNow; itemToUpdate.TenantId = TenantID; - CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(itemToUpdate); + CrmDbContext.SaveChanges(); } return currencyRate.ID; @@ -129,20 +131,20 @@ public int Delete(int id) var itemToDelete = new DbCurrencyRate { Id = id }; - CRMDbContext.CurrencyRate.Attach(itemToDelete); - CRMDbContext.CurrencyRate.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.CurrencyRate.Attach(itemToDelete); + CrmDbContext.CurrencyRate.Remove(itemToDelete); + CrmDbContext.SaveChanges(); return id; } public List SetCurrencyRates(List rates) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var items = CRMDbContext.CurrencyRate.Where(x => x.TenantId == TenantID); + var items = CrmDbContext.CurrencyRate.Where(x => x.TenantId == TenantID); - CRMDbContext.RemoveRange(items); + CrmDbContext.RemoveRange(items); foreach (var rate in rates) { @@ -158,9 +160,9 @@ public List SetCurrencyRates(List rates) TenantId = TenantID }; - CRMDbContext.CurrencyRate.Add(itemToInsert); + CrmDbContext.CurrencyRate.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); rate.ID = itemToInsert.Id; } diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index e251575bcd7..597c42429e1 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -80,7 +80,7 @@ public void SaveList(List items) { if (items == null || items.Count == 0) return; - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); foreach (var customField in items) { @@ -107,11 +107,11 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, fieldValue = fieldValue.Trim(); - var itemToDelete = Query(CRMDbContext.FieldValue) + var itemToDelete = Query(CrmDbContext.FieldValue) .Where(x => x.EntityId == entityID && x.EntityType == entityType && x.FieldId == fieldID); - CRMDbContext.FieldValue.RemoveRange(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.FieldValue.RemoveRange(itemToDelete); + CrmDbContext.SaveChanges(); if (!String.IsNullOrEmpty(fieldValue)) { @@ -128,8 +128,8 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, TenantId = TenantID }; - CRMDbContext.Add(dbFieldValue); - CRMDbContext.SaveChanges(); + CrmDbContext.Add(dbFieldValue); + CrmDbContext.SaveChanges(); var id = dbFieldValue.Id; @@ -236,7 +236,7 @@ public int CreateField(EntityType entityType, String label, CustomFieldType cust throw new ArgumentException(); var resultMask = GetValidMask(customFieldType, mask); - var sortOrder = Query(CRMDbContext.FieldDescription).Select(x => x.SortOrder).Max() + 1; + var sortOrder = Query(CrmDbContext.FieldDescription).Select(x => x.SortOrder).Max() + 1; var itemToInsert = new DbFieldDescription { @@ -248,16 +248,16 @@ public int CreateField(EntityType entityType, String label, CustomFieldType cust TenantId = TenantID }; - CRMDbContext.FieldDescription.Add(itemToInsert); + CrmDbContext.FieldDescription.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return itemToInsert.Id; } public String GetValue(EntityType entityType, int entityID, int fieldID) { - var sqlQuery = Query(CRMDbContext.FieldValue).Where(x => x.FieldId == fieldID && x.EntityId == entityID); + var sqlQuery = Query(CrmDbContext.FieldValue).Where(x => x.FieldId == fieldID && x.EntityId == entityID); if (entityType == EntityType.Company || entityType == EntityType.Person) { @@ -273,7 +273,7 @@ public String GetValue(EntityType entityType, int entityID, int fieldID) public List GetEntityIds(EntityType entityType, int fieldID, String fieldValue) { - var sqlQuery = Query(CRMDbContext.FieldValue) + var sqlQuery = Query(CrmDbContext.FieldValue) .Where(x => x.FieldId == fieldID && String.Compare(x.Value, fieldValue, true) == 0); if (entityType == EntityType.Company || entityType == EntityType.Person) @@ -291,12 +291,12 @@ public List GetEntityIds(EntityType entityType, int fieldID, String field public bool IsExist(int id) { - return Query(CRMDbContext.FieldDescription).Where(x => x.Id == id).Any(); + return Query(CrmDbContext.FieldDescription).Where(x => x.Id == id).Any(); } public int GetFieldId(EntityType entityType, String label, CustomFieldType customFieldType) { - var sqlQuery = Query(CRMDbContext.FieldDescription).Where(x => x.Type == customFieldType && x.Label == label); + var sqlQuery = Query(CrmDbContext.FieldDescription).Where(x => x.Type == customFieldType && x.Label == label); if (entityType == EntityType.Company || entityType == EntityType.Person) { @@ -326,7 +326,7 @@ public void EditItem(CustomField customField) { var resultMask = ""; - var row = Query(CRMDbContext.FieldDescription).Where(x => x.Id == customField.ID).Select(x => new { x.Type, x.Mask }).Single(); + var row = Query(CrmDbContext.FieldDescription).Where(x => x.Id == customField.ID).Select(x => new { x.Type, x.Mask }).Single(); var fieldType = row.Type; var oldMask = row.Mask; @@ -370,27 +370,27 @@ public void EditItem(CustomField customField) throw ex; } - var itemToUpdate = Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); + var itemToUpdate = Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); itemToUpdate.Label = customField.Label; itemToUpdate.Mask = customField.Mask; - CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(itemToUpdate); + CrmDbContext.SaveChanges(); } else { var resultMask = GetValidMask(customField.FieldType, customField.Mask); - var itemToUpdate = Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); + var itemToUpdate = Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); itemToUpdate.Label = customField.Label; itemToUpdate.Type = customField.FieldType; itemToUpdate.Mask = customField.Mask; - CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(itemToUpdate); + CrmDbContext.SaveChanges(); } } @@ -398,19 +398,19 @@ public void ReorderFields(int[] fieldID) { for (int index = 0; index < fieldID.Length; index++) { - var itemToUpdate = Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID[index]); + var itemToUpdate = Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID[index]); itemToUpdate.SortOrder = index; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } } private bool HaveRelativeLink(int fieldID) { - return Query(CRMDbContext.FieldValue) + return Query(CrmDbContext.FieldValue) .Where(x => x.FieldId == fieldID).Any(); } @@ -419,7 +419,7 @@ public String GetContactLinkCountJSON(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.FieldDescription).Join(Query(CRMDbContext.FieldValue), + var sqlQuery = Query(CrmDbContext.FieldDescription).Join(Query(CrmDbContext.FieldValue), x => x.Id, y => y.FieldId, (x, y) => new { x, y } @@ -443,7 +443,7 @@ public int GetContactLinkCount(EntityType entityType, int entityID) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.FieldDescription).Join(Query(CRMDbContext.FieldValue), + var sqlQuery = Query(CrmDbContext.FieldDescription).Join(Query(CrmDbContext.FieldValue), x => x.Id, y => y.FieldId, (x, y) => new { x, y } @@ -480,7 +480,7 @@ private List GetEnityFields(EntityType entityType, int[] entityID, if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.FieldDescription).GroupJoin(Query(CRMDbContext.FieldValue), + var sqlQuery = Query(CrmDbContext.FieldDescription).GroupJoin(Query(CrmDbContext.FieldValue), x => x.Id, y => y.FieldId, (x, y) => new { x, y } @@ -515,7 +515,7 @@ private List GetEnityFields(EntityType entityType, int[] entityID, public CustomField GetFieldDescription(int fieldID) { - return ToCustomField(Query(CRMDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID)); + return ToCustomField(Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID)); } public List GetFieldsDescription(EntityType entityType) @@ -523,7 +523,7 @@ public List GetFieldsDescription(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.FieldDescription); + var sqlQuery = Query(CrmDbContext.FieldDescription); if (entityType == EntityType.Company || entityType == EntityType.Person) { @@ -542,20 +542,20 @@ public void DeleteField(int fieldID) //if (HaveRelativeLink(fieldID)) // throw new ArgumentException(); - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); var fieldDescription = new DbFieldDescription { Id = fieldID }; - CRMDbContext.FieldDescription.Attach(fieldDescription); - CRMDbContext.FieldDescription.Remove(fieldDescription); + CrmDbContext.FieldDescription.Attach(fieldDescription); + CrmDbContext.FieldDescription.Remove(fieldDescription); - var fieldValue = Query(CRMDbContext.FieldValue).FirstOrDefault(x => x.FieldId == fieldID); + var fieldValue = Query(CrmDbContext.FieldValue).FirstOrDefault(x => x.FieldId == fieldID); FactoryIndexer.Delete(fieldValue); - CRMDbContext.Remove(fieldValue); + CrmDbContext.Remove(fieldValue); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); } diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index e7546b95c7d..48588444986 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -55,70 +55,6 @@ namespace ASC.CRM.Core.Dao { - public class CachedDealDao : DealDao - { - private readonly HttpRequestDictionary _dealCache; - - public CachedDealDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - CrmSecurity crmSecurity, - FactoryIndexerDeal factoryIndexer, - FilesIntegration filesIntegration, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - IMapper mapper, - BundleSearch bundleSearch) - : base(dbContextManager, - tenantManager, - securityContext, - crmSecurity, - factoryIndexer, - filesIntegration, - logger, - ascCache, - mapper, - bundleSearch) - { - _dealCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal"); - } - - public override void EditDeal(Deal deal) - { - ResetCache(deal.ID); - base.EditDeal(deal); - } - - public override Deal GetByID(int dealID) - { - return _dealCache.Get(dealID.ToString(), () => GetByIDBase(dealID)); - } - - private Deal GetByIDBase(int dealID) - { - return base.GetByID(dealID); - } - - public override Deal DeleteDeal(int dealID) - { - ResetCache(dealID); - return base.DeleteDeal(dealID); - } - - public override int CreateNewDeal(Deal deal) - { - deal.ID = base.CreateNewDeal(deal); - _dealCache.Add(deal.ID.ToString(), deal); - return deal.ID; - } - - private void ResetCache(int dealID) - { - _dealCache.Reset(dealID.ToString()); - } - } - [Scope] public class DealDao : AbstractDao { @@ -182,31 +118,29 @@ public void RemoveMember(int dealID, int memberID) RemoveRelative(memberID, EntityType.Opportunity, dealID); } - public virtual List GetDeals(int[] id) + public List GetDeals(int[] id) { if (id == null || !id.Any()) return new List(); - var dbDeals = Query(CRMDbContext.Deals).Where(x => id.Contains(x.Id)).ToList(); + var dbDeals = Query(CrmDbContext.Deals).Where(x => id.Contains(x.Id)).ToList(); return _mapper.Map, List>(dbDeals); } - public virtual Deal GetByID(int dealID) - { - if (dealID <= 0) return null; - + public Deal GetByID(int dealID) + { var deals = GetDeals(new[] { dealID }); return deals.Count == 0 ? null : deals[0]; } - public virtual int CreateNewDeal(Deal deal) + public int CreateNewDeal(Deal deal) { var result = CreateNewDealInDb(deal); deal.ID = result; - FactoryIndexer.Index(Query(CRMDbContext.Deals).Where(x => x.Id == deal.ID).FirstOrDefault()); + FactoryIndexer.Index(Query(CrmDbContext.Deals).Where(x => x.Id == deal.ID).FirstOrDefault()); return result; } @@ -240,8 +174,8 @@ private int CreateNewDealInDb(Deal deal) TenantId = TenantID }; - CRMDbContext.Deals.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.Deals.Add(itemToInsert); + CrmDbContext.SaveChanges(); var dealID = itemToInsert.Id; @@ -251,15 +185,15 @@ private int CreateNewDealInDb(Deal deal) return dealID; } - public virtual int[] SaveDealList(List items) + public int[] SaveDealList(List items) { - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); var result = items.Select(item => CreateNewDealInDb(item)).ToArray(); tx.Commit(); - foreach (var deal in Query(CRMDbContext.Deals).Where(x => result.Contains(x.Id))) + foreach (var deal in Query(CrmDbContext.Deals).Where(x => result.Contains(x.Id))) { FactoryIndexer.Index(deal); } @@ -267,7 +201,7 @@ public virtual int[] SaveDealList(List items) return result; } - public virtual void EditDeal(Deal deal) + public void EditDeal(Deal deal) { CRMSecurity.DemandEdit(deal); @@ -278,7 +212,7 @@ public virtual void EditDeal(Deal deal) // AddMember(deal.ID, deal.ContactID); - var itemToUpdate = Query(CRMDbContext.Deals).Single(x => x.Id == deal.ID); + var itemToUpdate = Query(CrmDbContext.Deals).Single(x => x.Id == deal.ID); itemToUpdate.Title = deal.Title; itemToUpdate.Description = deal.Description; @@ -296,8 +230,8 @@ public virtual void EditDeal(Deal deal) itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(itemToUpdate); + CrmDbContext.SaveChanges(); FactoryIndexer.Index(itemToUpdate); } @@ -338,7 +272,7 @@ private IQueryable GetDbDealByFilters( OrderBy orderBy) { - var sqlQuery = Query(CRMDbContext.Deals).Join(CRMDbContext.DealMilestones, + var sqlQuery = Query(CrmDbContext.Deals).Join(CrmDbContext.DealMilestones, x => x.DealMilestoneId, y => y.Id, (x, y) => new { x, y } @@ -592,7 +526,7 @@ public int GetDealsCount(String searchText, else { - var countWithoutPrivate = Query(CRMDbContext.Deals).Count(); + var countWithoutPrivate = Query(CrmDbContext.Deals).Count(); var privateCount = exceptIDs.Count; if (privateCount > countWithoutPrivate) @@ -765,7 +699,7 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); - var sqlQuery = Query(CRMDbContext.Deals); + var sqlQuery = Query(CrmDbContext.Deals); if (keywords.Length == 1) { @@ -799,7 +733,7 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta return _mapper.Map, List>(dbDeals).FindAll(CRMSecurity.CanAccessTo); } - public virtual Deal DeleteDeal(int dealID) + public Deal DeleteDeal(int dealID) { if (dealID <= 0) return null; @@ -808,7 +742,7 @@ public virtual Deal DeleteDeal(int dealID) CRMSecurity.DemandDelete(deal); - FactoryIndexer.Delete(Query(CRMDbContext.Deals).Where(x => x.Id == dealID).Single()); + FactoryIndexer.Delete(Query(CrmDbContext.Deals).Where(x => x.Id == dealID).Single()); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); @@ -851,29 +785,29 @@ private void DeleteBatchDealsExecute(List deals) var tagdao = FilesIntegration.DaoFactory.GetTagDao(); - var tagNames = Query(CRMDbContext.RelationshipEvent) + var tagNames = Query(CrmDbContext.RelationshipEvent) .Where(x => x.HaveFiles && dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) .Select(x => string.Format("RelationshipEvent_{0}", x.Id)).ToArray(); filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); - var tx = CRMDbContext.Database.BeginTransaction(); + var tx = CrmDbContext.Database.BeginTransaction(); - CRMDbContext.RemoveRange(Query(CRMDbContext.FieldValue) + CrmDbContext.RemoveRange(Query(CrmDbContext.FieldValue) .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) ); - CRMDbContext.RemoveRange(CRMDbContext.EntityContact.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + CrmDbContext.RemoveRange(CrmDbContext.EntityContact.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); - CRMDbContext.RemoveRange(Query(CRMDbContext.RelationshipEvent) + CrmDbContext.RemoveRange(Query(CrmDbContext.RelationshipEvent) .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); - CRMDbContext.RemoveRange(Query(CRMDbContext.Tasks).Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + CrmDbContext.RemoveRange(Query(CrmDbContext.Tasks).Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); - CRMDbContext.RemoveRange(CRMDbContext.EntityTags.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + CrmDbContext.RemoveRange(CrmDbContext.EntityTags.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); - CRMDbContext.RemoveRange(Query(CRMDbContext.Deals).Where(x => dealID.Contains(x.Id))); + CrmDbContext.RemoveRange(Query(CrmDbContext.Deals).Where(x => dealID.Contains(x.Id))); tx.Commit(); @@ -934,9 +868,9 @@ public void SetDealCreationDate(int opportunityid, DateTime creationDate) TenantId = TenantID }; - CRMDbContext.Attach(dbDeal); - CRMDbContext.Entry(dbDeal).Property(x => x.CreateOn).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(dbDeal); + CrmDbContext.Entry(dbDeal).Property(x => x.CreateOn).IsModified = true; + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); @@ -956,9 +890,9 @@ public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) TenantId = TenantID }; - CRMDbContext.Attach(dbDeal); - CRMDbContext.Entry(dbDeal).Property(x => x.LastModifedOn).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(dbDeal); + CrmDbContext.Entry(dbDeal).Property(x => x.LastModifedOn).IsModified = true; + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 4fc5ef67b04..cb2beee80d3 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -48,76 +48,7 @@ #endregion namespace ASC.CRM.Core.Dao -{ - public class CachedDealMilestoneDao : DealMilestoneDao - { - private readonly HttpRequestDictionary _dealMilestoneCache; - - public CachedDealMilestoneDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - IMapper mapper) - : base(dbContextManager, - tenantManager, - securityContext, - logger, - ascCache, - mapper) - { - - _dealMilestoneCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_deal_milestone"); - } - - private void ResetCache(int id) - { - _dealMilestoneCache.Reset(id.ToString()); - } - - public override int Create(DealMilestone item) - { - item.ID = base.Create(item); - - _dealMilestoneCache.Add(item.ID.ToString(), item); - - return item.ID; - } - - public override void Delete(int id) - { - ResetCache(id); - - base.Delete(id); - } - - public override void Edit(DealMilestone item) - { - ResetCache(item.ID); - - base.Edit(item); - } - - - private DealMilestone GetByIDBase(int id) - { - return base.GetByID(id); - } - - public override DealMilestone GetByID(int id) - { - return _dealMilestoneCache.Get(id.ToString(), () => GetByIDBase(id)); - } - - public override void Reorder(int[] ids) - { - _dealMilestoneCache.Clear(); - - base.Reorder(ids); - } - } - +{ [Scope] public class DealMilestoneDao : AbstractDao { @@ -141,34 +72,34 @@ public DealMilestoneDao(DbContextManager dbContextManager, } - public virtual void Reorder(int[] ids) + public void Reorder(int[] ids) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); for (int index = 0; index < ids.Length; index++) { - var itemToUpdate = Query(CRMDbContext.DealMilestones).FirstOrDefault(x => x.Id == ids[index]); + var itemToUpdate = Query(CrmDbContext.DealMilestones).FirstOrDefault(x => x.Id == ids[index]); itemToUpdate.SortOrder = index; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); } public int GetCount() { - return Query(CRMDbContext.DealMilestones).Count(); + return Query(CrmDbContext.DealMilestones).Count(); } public Dictionary GetRelativeItemsCount() { - return Query(CRMDbContext.DealMilestones) - .Join(CRMDbContext.Deals, + return Query(CrmDbContext.DealMilestones) + .Join(CrmDbContext.Deals, x => x.Id, x => x.DealMilestoneId, (x, y) => new { x = x, y = y }) @@ -179,11 +110,11 @@ public Dictionary GetRelativeItemsCount() public int GetRelativeItemsCount(int id) { - return Query(CRMDbContext.Deals) + return Query(CrmDbContext.Deals) .Count(x => x.DealMilestoneId == id); } - public virtual int Create(DealMilestone item) + public int Create(DealMilestone item) { if (String.IsNullOrEmpty(item.Title) || String.IsNullOrEmpty(item.Color)) @@ -191,10 +122,10 @@ public virtual int Create(DealMilestone item) int id; - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); if (item.SortOrder == 0) - item.SortOrder = Query(CRMDbContext.DealMilestones).Select(x => x.SortOrder).Max() + 1; + item.SortOrder = Query(CrmDbContext.DealMilestones).Select(x => x.SortOrder).Max() + 1; var itemToAdd = new DbDealMilestone { @@ -207,8 +138,8 @@ public virtual int Create(DealMilestone item) TenantId = TenantID }; - CRMDbContext.DealMilestones.Add(itemToAdd); - CRMDbContext.SaveChanges(); + CrmDbContext.DealMilestones.Add(itemToAdd); + CrmDbContext.SaveChanges(); id = itemToAdd.Id; @@ -217,7 +148,7 @@ public virtual int Create(DealMilestone item) return id; } - public virtual void ChangeColor(int id, String newColor) + public void ChangeColor(int id, String newColor) { var itemToUpdate = new DbDealMilestone { @@ -226,17 +157,17 @@ public virtual void ChangeColor(int id, String newColor) TenantId = TenantID }; - CRMDbContext.Attach(itemToUpdate); - CRMDbContext.Entry(itemToUpdate).Property(x => x.Color).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(itemToUpdate); + CrmDbContext.Entry(itemToUpdate).Property(x => x.Color).IsModified = true; + CrmDbContext.SaveChanges(); } - public virtual void Edit(DealMilestone item) + public void Edit(DealMilestone item) { if (HaveContactLink(item.ID)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.DealMilestoneHasRelatedDeals)); - var itemToUpdate = Query(CRMDbContext.DealMilestones) + var itemToUpdate = Query(CrmDbContext.DealMilestones) .FirstOrDefault(x => x.Id == item.ID); itemToUpdate.Title = item.Title; @@ -245,18 +176,18 @@ public virtual void Edit(DealMilestone item) itemToUpdate.Probability = item.Probability; itemToUpdate.Status = item.Status; - CRMDbContext.DealMilestones.Update(itemToUpdate); + CrmDbContext.DealMilestones.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public bool HaveContactLink(int dealMilestoneID) { - return Query(CRMDbContext.Deals) + return Query(CrmDbContext.Deals) .Any(x => x.DealMilestoneId == dealMilestoneID); } - public virtual void Delete(int id) + public void Delete(int id) { if (HaveContactLink(id)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.DealMilestoneHasRelatedDeals)); @@ -267,27 +198,27 @@ public virtual void Delete(int id) TenantId = TenantID }; - CRMDbContext.DealMilestones.Remove(dbDealMilestones); + CrmDbContext.DealMilestones.Remove(dbDealMilestones); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } - public virtual DealMilestone GetByID(int id) + public DealMilestone GetByID(int id) { - var dbDealMilestone = Query(CRMDbContext.DealMilestones).FirstOrDefault(x => x.Id == id); + var dbDealMilestone = Query(CrmDbContext.DealMilestones).FirstOrDefault(x => x.Id == id); return _mapper.Map(dbDealMilestone); } public Boolean IsExist(int id) { - return Query(CRMDbContext.DealMilestones).Any(x => x.Id == id); + return Query(CrmDbContext.DealMilestones).Any(x => x.Id == id); } public List GetAll(int[] id) { - var result = Query(CRMDbContext.DealMilestones) + var result = Query(CrmDbContext.DealMilestones) .OrderBy(x => x.SortOrder) .Where(x => id.Contains(x.Id)).ToList(); @@ -296,7 +227,7 @@ public List GetAll(int[] id) public List GetAll() { - var result = Query(CRMDbContext.DealMilestones) + var result = Query(CrmDbContext.DealMilestones) .OrderBy(x => x.SortOrder) .ToList(); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 33ff1a9252d..131b61857eb 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -56,72 +56,7 @@ using SecurityContext = ASC.Core.SecurityContext; namespace ASC.CRM.Core.Dao -{ - public class CachedInvoiceDao : InvoiceDao - { - private readonly HttpRequestDictionary _invoiceCache; - - public CachedInvoiceDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - FactoryIndexerInvoice factoryIndexer, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - SettingsManager settingsManager, - InvoiceSetting invoiceSetting, - InvoiceFormattedData invoiceFormattedData, - CrmSecurity crmSecurity, - TenantUtil tenantUtil, - IMapper mapper) - : base(dbContextManager, - tenantManager, - securityContext, - factoryIndexer, - logger, - ascCache, - settingsManager, - invoiceSetting, - invoiceFormattedData, - crmSecurity, - tenantUtil, - mapper - ) - { - _invoiceCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice"); - } - - public override Invoice GetByID(int invoiceID) - { - return _invoiceCache.Get(invoiceID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceID)); - } - - private Invoice GetByIDBase(int invoiceID) - { - return base.GetByID(invoiceID); - } - - public override int SaveOrUpdateInvoice(Invoice invoice) - { - if (invoice != null && invoice.ID > 0) - ResetCache(invoice.ID); - - return base.SaveOrUpdateInvoice(invoice); - } - - public override Invoice DeleteInvoice(int invoiceID) - { - ResetCache(invoiceID); - - return base.DeleteInvoice(invoiceID); - } - - private void ResetCache(int invoiceID) - { - _invoiceCache.Reset(invoiceID.ToString(CultureInfo.InvariantCulture)); - } - } - +{ [Scope] public class InvoiceDao : AbstractDao { @@ -178,7 +113,7 @@ public Boolean IsExist(int invoiceID) public Boolean IsExistFromDb(int invoiceID) { - return Query(CRMDbContext.Invoices).Where(x => x.Id == invoiceID).Any(); + return Query(CrmDbContext.Invoices).Where(x => x.Id == invoiceID).Any(); } public Boolean IsExist(string number) @@ -188,46 +123,46 @@ public Boolean IsExist(string number) public Boolean IsExistFromDb(string number) { - return Query(CRMDbContext.Invoices) + return Query(CrmDbContext.Invoices) .Where(x => x.Number == number) .Any(); } - public virtual List GetAll() + public List GetAll() { - var dbInvoices = Query(CRMDbContext.Invoices) + var dbInvoices = Query(CrmDbContext.Invoices) .ToList(); return _mapper.Map, List>(dbInvoices); } - public virtual List GetByID(int[] ids) + public List GetByID(int[] ids) { - var dbInvoices = Query(CRMDbContext.Invoices) + var dbInvoices = Query(CrmDbContext.Invoices) .Where(x => ids.Contains(x.Id)) .ToList(); return _mapper.Map, List>(dbInvoices); } - public virtual Invoice GetByID(int id) + public Invoice GetByID(int id) { return GetByIDFromDb(id); } - public virtual Invoice GetByIDFromDb(int id) + public Invoice GetByIDFromDb(int id) { - return _mapper.Map(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == id)); + return _mapper.Map(Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == id)); } public Invoice GetByNumber(string number) { - return _mapper.Map(Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Number == number)); + return _mapper.Map(Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Number == number)); } public Invoice GetByFileId(Int32 fileID) { - return _mapper.Map(Query(CRMDbContext.Invoices) + return _mapper.Map(Query(CrmDbContext.Invoices) .FirstOrDefault(x => x.FileId == fileID)); } @@ -359,7 +294,7 @@ public List GetCrudeInvoices( break; case InvoiceSortedByType.Contact: - var subSqlQuery = sqlQuery.GroupJoin(CRMDbContext.Contacts, + var subSqlQuery = sqlQuery.GroupJoin(CrmDbContext.Contacts, x => x.ContactId, y => y.Id, (x, y) => new { x, y }) @@ -396,7 +331,7 @@ public List GetCrudeInvoices( public int GetAllInvoicesCount() { - return Query(CRMDbContext.Invoices).Count(); + return Query(CrmDbContext.Invoices).Count(); } @@ -440,7 +375,7 @@ public int GetInvoicesCount( } else { - var countWithoutPrivate = Query(CRMDbContext.Invoices).Count(); + var countWithoutPrivate = Query(CrmDbContext.Invoices).Count(); var privateCount = exceptIDs.Count; @@ -467,7 +402,7 @@ public List GetInvoices(int[] ids) { if (ids == null || !ids.Any()) return new List(); - var dbInvoices = Query(CRMDbContext.Invoices) + var dbInvoices = Query(CrmDbContext.Invoices) .Where(x => ids.Contains(x.Id)) .ToList(); @@ -485,7 +420,7 @@ public List GetEntityInvoices(EntityType entityType, int entityID) if (entityType == EntityType.Opportunity) { - var sqlQuery = Query(CRMDbContext.Invoices).Where(x => x.EntityId == entityID && x.EntityType == entityType) + var sqlQuery = Query(CrmDbContext.Invoices).Where(x => x.EntityId == entityID && x.EntityType == entityType) .ToList(); return _mapper.Map, List>(sqlQuery) @@ -506,7 +441,7 @@ public List GetContactInvoices(int contactID) if (contactID <= 0) return result; - var dbInvoices = Query(CRMDbContext.Invoices).Where(x => x.ContactId == contactID) + var dbInvoices = Query(CrmDbContext.Invoices).Where(x => x.ContactId == contactID) .ToList(); return _mapper.Map, List>(dbInvoices) @@ -520,7 +455,7 @@ public string GetNewInvoicesNumber() if (!settings.Autogenerated) return string.Empty; - var stringNumber = Query(CRMDbContext.Invoices).OrderByDescending(x => x.Id).Select(x => x.Number).ToString(); + var stringNumber = Query(CrmDbContext.Invoices).OrderByDescending(x => x.Id).Select(x => x.Number).ToString(); if (string.IsNullOrEmpty(stringNumber) || !stringNumber.StartsWith(settings.Prefix)) return string.Concat(settings.Prefix, settings.Number); @@ -550,13 +485,13 @@ public InvoiceSetting GetSettings() return tenantSettings.InvoiceSetting ?? _invoiceSetting.DefaultSettings; } - public virtual int SaveOrUpdateInvoice(Invoice invoice) + public int SaveOrUpdateInvoice(Invoice invoice) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); var result = SaveOrUpdateInvoiceInDb(invoice); - _factoryIndexer.Index(Query(CRMDbContext.Invoices).Where(x => x.Id == invoice.ID).Single()); + _factoryIndexer.Index(Query(CrmDbContext.Invoices).Where(x => x.Id == invoice.ID).Single()); return result; } @@ -606,16 +541,16 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) TenantId = TenantID }; - CRMDbContext.Invoices.Add(itemToInsert); + CrmDbContext.Invoices.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); invoice.ID = itemToInsert.Id; } else { - var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoice.ID); + var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoice.ID); var oldInvoice = _mapper.Map(itemToUpdate); @@ -640,7 +575,7 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; itemToUpdate.TenantId = TenantID; - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } @@ -648,7 +583,7 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) return invoice.ID; } - public virtual Invoice UpdateInvoiceStatus(int invoiceid, InvoiceStatus status) + public Invoice UpdateInvoiceStatus(int invoiceid, InvoiceStatus status) { return UpdateInvoiceStatusInDb(invoiceid, status); } @@ -689,15 +624,15 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) return invoice; } - var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceid); + var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceid); itemToUpdate.Status = status; itemToUpdate.LastModifedOn = DateTime.UtcNow; itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); invoice.Status = status; @@ -705,21 +640,21 @@ private Invoice UpdateInvoiceStatusInDb(int invoiceid, InvoiceStatus status) } - public virtual int UpdateInvoiceJsonData(int invoiceId, string jsonData) + public int UpdateInvoiceJsonData(int invoiceId, string jsonData) { return UpdateInvoiceJsonDataInDb(invoiceId, jsonData); } private int UpdateInvoiceJsonDataInDb(int invoiceId, string jsonData) { - var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); itemToUpdate.JsonData = jsonData; itemToUpdate.LastModifedOn = DateTime.UtcNow; itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(itemToUpdate); + CrmDbContext.SaveChanges(); return invoiceId; } @@ -745,7 +680,7 @@ public void UpdateInvoiceJsonDataAfterLinesUpdated(Invoice invoice) UpdateInvoiceJsonData(invoice.ID, invoice.JsonData); } - public virtual int UpdateInvoiceFileID(int invoiceId, int fileId) + public int UpdateInvoiceFileID(int invoiceId, int fileId) { return UpdateInvoiceFileIDInDb(invoiceId, fileId); } @@ -753,14 +688,14 @@ public virtual int UpdateInvoiceFileID(int invoiceId, int fileId) private int UpdateInvoiceFileIDInDb(int invoiceId, int fileId) { - var sqlToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + var sqlToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); sqlToUpdate.FileId = fileId; sqlToUpdate.LastModifedOn = DateTime.UtcNow; sqlToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - CRMDbContext.Update(sqlToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(sqlToUpdate); + CrmDbContext.SaveChanges(); return invoiceId; } @@ -775,7 +710,7 @@ public InvoiceSetting SaveInvoiceSettings(InvoiceSetting invoiceSetting) return tenantSettings.InvoiceSetting; } - public virtual Invoice DeleteInvoice(int invoiceID) + public Invoice DeleteInvoice(int invoiceID) { if (invoiceID <= 0) return null; @@ -809,14 +744,14 @@ private void DeleteBatchInvoicesExecute(List invoices) { var invoiceID = invoices.Select(x => x.ID).ToArray(); - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var dbInvoicesQuery = Query(CRMDbContext.Invoices).Where(x => invoiceID.Contains(x.Id)); + var dbInvoicesQuery = Query(CrmDbContext.Invoices).Where(x => invoiceID.Contains(x.Id)); - CRMDbContext.InvoiceLine.RemoveRange(Query(CRMDbContext.InvoiceLine).Where(x => invoiceID.Contains(x.InvoiceId))); - CRMDbContext.Invoices.RemoveRange(dbInvoicesQuery); + CrmDbContext.InvoiceLine.RemoveRange(Query(CrmDbContext.InvoiceLine).Where(x => invoiceID.Contains(x.InvoiceId))); + CrmDbContext.Invoices.RemoveRange(dbInvoicesQuery); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); @@ -836,7 +771,7 @@ private IQueryable GetDbInvoceByFilters( int entityID, String currency) { - var sqlQuery = Query(CRMDbContext.Invoices); + var sqlQuery = Query(CrmDbContext.Invoices); if (entityID > 0) { @@ -949,12 +884,12 @@ private bool hasParams( /// public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) { - var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); itemToUpdate.CreateOn = _tenantUtil.DateTimeToUtc(creationDate); - CRMDbContext.Invoices.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Invoices.Update(itemToUpdate); + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -967,13 +902,13 @@ public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) /// public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) { - var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); itemToUpdate.LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate); - CRMDbContext.Invoices.Update(itemToUpdate); + CrmDbContext.Invoices.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index e6bde662a4f..c9060859f35 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -48,64 +48,7 @@ using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao -{ - public class CachedInvoiceItemDao : InvoiceItemDao - { - private readonly HttpRequestDictionary _invoiceItemCache; - - public CachedInvoiceItemDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - TenantUtil tenantUtil, - CrmSecurity crmSecurity, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - IMapper mapper - ) : base(dbContextManager, - tenantManager, - securityContext, - tenantUtil, - crmSecurity, - logger, - ascCache, - mapper) - - { - _invoiceItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_item"); - } - - public override InvoiceItem GetByID(int invoiceItemID) - { - return _invoiceItemCache.Get(invoiceItemID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceItemID)); - } - - private InvoiceItem GetByIDBase(int invoiceItemID) - { - return base.GetByID(invoiceItemID); - } - - public override InvoiceItem SaveOrUpdateInvoiceItem(InvoiceItem invoiceItem) - { - if (invoiceItem != null && invoiceItem.ID > 0) - ResetCache(invoiceItem.ID); - - return base.SaveOrUpdateInvoiceItem(invoiceItem); - } - - public override InvoiceItem DeleteInvoiceItem(int invoiceItemID) - { - ResetCache(invoiceItemID); - - return base.DeleteInvoiceItem(invoiceItemID); - } - - private void ResetCache(int invoiceItemID) - { - _invoiceItemCache.Reset(invoiceItemID.ToString(CultureInfo.InvariantCulture)); - } - } - +{ [Scope] public class InvoiceItemDao : AbstractDao { @@ -141,37 +84,37 @@ public Boolean IsExist(int invoiceItemID) public Boolean IsExistInDb(int invoiceItemID) { - return Query(CRMDbContext.InvoiceItem).Any(x => x.Id == invoiceItemID); + return Query(CrmDbContext.InvoiceItem).Any(x => x.Id == invoiceItemID); } public Boolean CanDelete(int invoiceItemID) { - return Query(CRMDbContext.InvoiceLine).Any(x => x.InvoiceItemId == invoiceItemID); + return Query(CrmDbContext.InvoiceLine).Any(x => x.InvoiceItemId == invoiceItemID); } - public virtual List GetAll() + public List GetAll() { return GetAllInDb(); } - public virtual List GetAllInDb() + public List GetAllInDb() { - var dbInvoiceItems = Query(CRMDbContext.InvoiceItem).ToList(); + var dbInvoiceItems = Query(CrmDbContext.InvoiceItem).ToList(); return _mapper.Map, List>(dbInvoiceItems); } - public virtual List GetByID(int[] ids) + public List GetByID(int[] ids) { - var dbInvoiceItems = Query(CRMDbContext.InvoiceItem) + var dbInvoiceItems = Query(CrmDbContext.InvoiceItem) .Where(x => ids.Contains(x.Id)) .ToList(); return _mapper.Map, List>(dbInvoiceItems); } - public virtual InvoiceItem GetByID(int id) + public InvoiceItem GetByID(int id) { - var dbInvoiceItems = Query(CRMDbContext.InvoiceItem).FirstOrDefault(x => x.Id == id); + var dbInvoiceItems = Query(CrmDbContext.InvoiceItem).FirstOrDefault(x => x.Id == id); return _mapper.Map(dbInvoiceItems); } @@ -180,7 +123,7 @@ public List GetInvoiceItems(IEnumerable ids) { if (ids == null || !ids.Any()) return new List(); - var dbInvoiceItems = Query(CRMDbContext.InvoiceItem) + var dbInvoiceItems = Query(CrmDbContext.InvoiceItem) .Where(x => ids.Contains(x.Id)) .ToList(); @@ -276,7 +219,7 @@ public int GetInvoiceItemsCount( } else { - var countWithoutPrivate = Query(CRMDbContext.InvoiceItem).Count(); + var countWithoutPrivate = Query(CrmDbContext.InvoiceItem).Count(); var privateCount = exceptIDs.Count; @@ -299,7 +242,7 @@ public int GetInvoiceItemsCount( return result; } - public virtual InvoiceItem SaveOrUpdateInvoiceItem(InvoiceItem invoiceItem) + public InvoiceItem SaveOrUpdateInvoiceItem(InvoiceItem invoiceItem) { /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ @@ -346,8 +289,8 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) TenantId = TenantID }; - CRMDbContext.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.Add(itemToInsert); + CrmDbContext.SaveChanges(); invoiceItem.ID = itemToInsert.Id; @@ -357,7 +300,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) else { - var itemToUpdate = Query(CRMDbContext.InvoiceItem).Single(x => x.Id == invoiceItem.ID); + var itemToUpdate = Query(CrmDbContext.InvoiceItem).Single(x => x.Id == invoiceItem.ID); var oldInvoiceItem = _mapper.Map(itemToUpdate); CRMSecurity.DemandEdit(oldInvoiceItem); @@ -375,8 +318,8 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) itemToUpdate.LastModifedOn = invoiceItem.LastModifedOn; itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - CRMDbContext.Add(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Add(itemToUpdate); + CrmDbContext.SaveChanges(); } @@ -384,20 +327,20 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) return invoiceItem; } - public virtual InvoiceItem DeleteInvoiceItem(int invoiceItemID) + public InvoiceItem DeleteInvoiceItem(int invoiceItemID) { var invoiceItem = GetByID(invoiceItemID); if (invoiceItem == null) return null; CRMSecurity.DemandDelete(invoiceItem); - CRMDbContext.Remove(new DbInvoiceItem + CrmDbContext.Remove(new DbInvoiceItem { Id = invoiceItemID, TenantId = TenantID }); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ @@ -405,7 +348,7 @@ public virtual InvoiceItem DeleteInvoiceItem(int invoiceItemID) return invoiceItem; } - public virtual List DeleteBatchInvoiceItems(int[] invoiceItemIDs) + public List DeleteBatchInvoiceItems(int[] invoiceItemIDs) { if (invoiceItemIDs == null || !invoiceItemIDs.Any()) return null; @@ -424,13 +367,13 @@ public virtual List DeleteBatchInvoiceItems(int[] invoiceItemIDs) private void DeleteBatchItemsExecute(List items) { - CRMDbContext.RemoveRange(items.ConvertAll(x => new DbInvoiceItem + CrmDbContext.RemoveRange(items.ConvertAll(x => new DbInvoiceItem { Id = x.ID, TenantId = TenantID })); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } private IQueryable GetDbInvoiceItemByFilters( @@ -440,7 +383,7 @@ private IQueryable GetDbInvoiceItemByFilters( bool? inventoryStock) { - var sqlQuery = Query(CRMDbContext.InvoiceItem); + var sqlQuery = Query(CrmDbContext.InvoiceItem); //if (status > 0) //{ diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 38bca39f112..7d210477966 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -48,58 +48,6 @@ namespace ASC.CRM.Core.Dao { - public class CachedInvoiceLineDao : InvoiceLineDao - { - private readonly HttpRequestDictionary _invoiceLineCache; - - public CachedInvoiceLineDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - IMapper mapper) - : base(dbContextManager, - tenantManager, - securityContext, - logger, - ascCache, - mapper) - { - _invoiceLineCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_line"); - } - - public override InvoiceLine GetByID(int invoiceLineID) - { - return _invoiceLineCache.Get(invoiceLineID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceLineID)); - } - - private InvoiceLine GetByIDBase(int invoiceLineID) - { - return base.GetByID(invoiceLineID); - } - - public override int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) - { - if (invoiceLine != null && invoiceLine.ID > 0) - ResetCache(invoiceLine.ID); - - return base.SaveOrUpdateInvoiceLine(invoiceLine); - } - - public override void DeleteInvoiceLine(int invoiceLineID) - { - ResetCache(invoiceLineID); - - base.DeleteInvoiceLine(invoiceLineID); - } - - private void ResetCache(int invoiceLineID) - { - _invoiceLineCache.Reset(invoiceLineID.ToString(CultureInfo.InvariantCulture)); - } - } - [Scope] public class InvoiceLineDao : AbstractDao { @@ -144,24 +92,24 @@ public static string GetJson(InvoiceTax invoiceTax) }); } - public virtual List GetAll() + public List GetAll() { - var dbInvoiceLines = Query(CRMDbContext.InvoiceLine) + var dbInvoiceLines = Query(CrmDbContext.InvoiceLine) .ToList(); return _mapper.Map, List>(dbInvoiceLines); } - public virtual List GetByID(int[] ids) + public List GetByID(int[] ids) { - var dbInvoiceLines = Query(CRMDbContext.InvoiceLine).Where(x => ids.Contains(x.Id)).ToList(); + var dbInvoiceLines = Query(CrmDbContext.InvoiceLine).Where(x => ids.Contains(x.Id)).ToList(); return _mapper.Map, List>(dbInvoiceLines); } - public virtual InvoiceLine GetByID(int id) + public InvoiceLine GetByID(int id) { - return _mapper.Map(Query(CRMDbContext.InvoiceLine).FirstOrDefault(x => x.Id == id)); + return _mapper.Map(Query(CrmDbContext.InvoiceLine).FirstOrDefault(x => x.Id == id)); } public List GetInvoiceLines(int invoiceID) @@ -171,7 +119,7 @@ public List GetInvoiceLines(int invoiceID) public List GetInvoiceLinesInDb(int invoiceID) { - var dbInvoiceLines = Query(CRMDbContext.InvoiceLine) + var dbInvoiceLines = Query(CrmDbContext.InvoiceLine) .Where(x => x.InvoiceId == invoiceID) .OrderBy(x => x.SortOrder) .ToList(); @@ -179,7 +127,7 @@ public List GetInvoiceLinesInDb(int invoiceID) return _mapper.Map, List>(dbInvoiceLines); } - public virtual int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) + public int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -196,7 +144,7 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) invoiceLine.Description = String.Empty; } - if (Query(CRMDbContext.InvoiceLine).Where(x => x.Id == invoiceLine.ID).Any()) + if (Query(CrmDbContext.InvoiceLine).Where(x => x.Id == invoiceLine.ID).Any()) { var itemToInsert = new DbInvoiceLine @@ -213,14 +161,14 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) TenantId = TenantID }; - CRMDbContext.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.Add(itemToInsert); + CrmDbContext.SaveChanges(); invoiceLine.ID = itemToInsert.Id; } else { - var itemToUpdate = Query(CRMDbContext.InvoiceLine).Single(x => x.Id == invoiceLine.ID); + var itemToUpdate = Query(CrmDbContext.InvoiceLine).Single(x => x.Id == invoiceLine.ID); itemToUpdate.InvoiceId = invoiceLine.InvoiceID; itemToUpdate.InvoiceItemId = invoiceLine.InvoiceItemID; @@ -232,9 +180,9 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) itemToUpdate.Price = invoiceLine.Price; itemToUpdate.Discount = invoiceLine.Discount; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } @@ -242,7 +190,7 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) return invoiceLine.ID; } - public virtual void DeleteInvoiceLine(int invoiceLineID) + public void DeleteInvoiceLine(int invoiceLineID) { var invoiceLine = GetByID(invoiceLineID); @@ -250,9 +198,9 @@ public virtual void DeleteInvoiceLine(int invoiceLineID) var itemToDelete = new DbInvoiceLine { Id = invoiceLineID }; - CRMDbContext.Attach(itemToDelete); - CRMDbContext.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(itemToDelete); + CrmDbContext.Remove(itemToDelete); + CrmDbContext.SaveChanges(); /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ @@ -260,10 +208,10 @@ public virtual void DeleteInvoiceLine(int invoiceLineID) public void DeleteInvoiceLines(int invoiceID) { - var itemToDelete = Query(CRMDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceID); + var itemToDelete = Query(CrmDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceID); - CRMDbContext.RemoveRange(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.RemoveRange(itemToDelete); + CrmDbContext.SaveChanges(); /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceLineCacheKey, String.Empty);*/ @@ -276,13 +224,13 @@ public Boolean CanDelete(int invoiceLineID) public Boolean CanDeleteInDb(int invoiceLineID) { - var invoiceID = Query(CRMDbContext.InvoiceLine) + var invoiceID = Query(CrmDbContext.InvoiceLine) .Where(x => x.Id == invoiceLineID) .Select(x => x.InvoiceId); if (!invoiceID.Any()) return false; - return Query(CRMDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceLineID).Any(); + return Query(CrmDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceLineID).Any(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 4015a8a88b5..fd6df349f71 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -46,67 +46,9 @@ namespace ASC.CRM.Core.Dao { - public class CachedInvoiceTaxDao : InvoiceTaxDao - { - private readonly HttpRequestDictionary _invoiceTaxCache; - - public CachedInvoiceTaxDao(DbContextManager dbContextManager, - TenantManager tenantManager, - TenantUtil tenantUtil, - SecurityContext securityContext, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - IMapper mapper - ) - : base(dbContextManager, - tenantManager, - tenantUtil, - securityContext, - logger, - ascCache, - mapper) - - { - _invoiceTaxCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_invoice_tax"); - } - - public override InvoiceTax GetByID(int invoiceTaxID) - { - return _invoiceTaxCache.Get(invoiceTaxID.ToString(CultureInfo.InvariantCulture), () => GetByIDBase(invoiceTaxID)); - } - - private InvoiceTax GetByIDBase(int invoiceTaxID) - { - return base.GetByID(invoiceTaxID); - } - - public override InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) - { - if (invoiceTax != null && invoiceTax.ID > 0) - ResetCache(invoiceTax.ID); - - return base.SaveOrUpdateInvoiceTax(invoiceTax); - } - - public override InvoiceTax DeleteInvoiceTax(int invoiceTaxID) - { - ResetCache(invoiceTaxID); - - return base.DeleteInvoiceTax(invoiceTaxID); - } - - private void ResetCache(int invoiceTaxID) - { - _invoiceTaxCache.Reset(invoiceTaxID.ToString(CultureInfo.InvariantCulture)); - } - } - [Scope] public class InvoiceTaxDao : AbstractDao { - private readonly IMapper _mapper; - public InvoiceTaxDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -132,53 +74,53 @@ IMapper mapper public Boolean IsExist(int invoiceTaxID) { - return CRMDbContext.InvoiceTax.Where(x => x.Id == invoiceTaxID).Any(); + return CrmDbContext.InvoiceTax.Where(x => x.Id == invoiceTaxID).Any(); } public Boolean IsExist(String invoiceName) { - return Query(CRMDbContext.InvoiceTax).Where(x => String.Compare(x.Name, invoiceName, true) == 0).Any(); + return Query(CrmDbContext.InvoiceTax).Where(x => String.Compare(x.Name, invoiceName, true) == 0).Any(); } public Boolean CanDelete(int invoiceTaxID) { - return !Query(CRMDbContext.InvoiceItem) + return !Query(CrmDbContext.InvoiceItem) .Where(x => x.InvoiceTax1Id == invoiceTaxID || x.InvoiceTax2Id == invoiceTaxID).Any() && - !Query(CRMDbContext.InvoiceLine) + !Query(CrmDbContext.InvoiceLine) .Where(x => x.InvoiceTax1Id == invoiceTaxID || x.InvoiceTax2Id == invoiceTaxID).Any(); } - public virtual List GetAll() + public List GetAll() { - return _mapper.Map, List>(Query(CRMDbContext.InvoiceTax).ToList()); + return _mapper.Map, List>(Query(CrmDbContext.InvoiceTax).ToList()); } public DateTime GetMaxLastModified() { - var result = Query(CRMDbContext.InvoiceTax).Max(x => x.LastModifedOn); + var result = Query(CrmDbContext.InvoiceTax).Max(x => x.LastModifedOn); if (result.HasValue) return result.Value; return DateTime.MinValue; } - public virtual List GetByID(int[] ids) + public List GetByID(int[] ids) { - var result = Query(CRMDbContext.InvoiceTax) + var result = Query(CrmDbContext.InvoiceTax) .Where(x => ids.Contains(x.Id)) .ToList(); return _mapper.Map, List>(result); } - public virtual InvoiceTax GetByID(int id) + public InvoiceTax GetByID(int id) { - var invoiceTax = CRMDbContext.InvoiceTax.FirstOrDefault(x => x.Id == id); + var invoiceTax = CrmDbContext.InvoiceTax.FirstOrDefault(x => x.Id == id); return _mapper.Map(invoiceTax); } - public virtual InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) + public InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) { /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ @@ -194,7 +136,7 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) invoiceTax.LastModifedBy = _securityContext.CurrentAccount.ID; invoiceTax.LastModifedOn = DateTime.UtcNow; - if (!Query(CRMDbContext.InvoiceTax).Where(x => x.Id == invoiceTax.ID).Any()) + if (!Query(CrmDbContext.InvoiceTax).Where(x => x.Id == invoiceTax.ID).Any()) { invoiceTax.CreateOn = DateTime.UtcNow; invoiceTax.CreateBy = _securityContext.CurrentAccount.ID; @@ -211,9 +153,9 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) TenantId = TenantID }; - CRMDbContext.InvoiceTax.Add(itemToInsert); + CrmDbContext.InvoiceTax.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); invoiceTax.ID = itemToInsert.Id; } @@ -223,7 +165,7 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) CRMSecurity.DemandEdit(oldInvoiceTax); - var itemToUpdate = Query(CRMDbContext.InvoiceTax) + var itemToUpdate = Query(CrmDbContext.InvoiceTax) .FirstOrDefault(x => x.Id == invoiceTax.ID); itemToUpdate.Name = invoiceTax.Name; @@ -232,16 +174,16 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) itemToUpdate.LastModifedOn = itemToUpdate.LastModifedOn; itemToUpdate.LastModifedBy = itemToUpdate.LastModifedBy; - CRMDbContext.InvoiceTax.Update(itemToUpdate); + CrmDbContext.InvoiceTax.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } return invoiceTax; } - public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) + public InvoiceTax DeleteInvoiceTax(int invoiceTaxID) { var invoiceTax = GetByID(invoiceTaxID); @@ -254,10 +196,10 @@ public virtual InvoiceTax DeleteInvoiceTax(int invoiceTaxID) Id = invoiceTaxID }; - CRMDbContext.Attach(invoiceTax); - CRMDbContext.Remove(itemToDelete); + CrmDbContext.Attach(invoiceTax); + CrmDbContext.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); /* _cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index f200d3a7e98..8263d18bf34 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -48,80 +48,6 @@ namespace ASC.CRM.Core.Dao { - - public class CachedListItem : ListItemDao - { - private readonly HttpRequestDictionary _listItemCache; - - public CachedListItem( - DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - IMapper mapper) - : base(dbContextManager, - tenantManager, - securityContext, - logger, - ascCache, - mapper) - { - _listItemCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_list_item"); - } - - public override void ChangeColor(int id, string newColor) - { - ResetCache(id); - - base.ChangeColor(id, newColor); - } - - public override void DeleteItem(ListType listType, int itemID, int toItemID) - { - ResetCache(itemID); - - base.DeleteItem(listType, itemID, toItemID); - } - - public override void ChangePicture(int id, string newPicture) - { - ResetCache(id); - - base.ChangePicture(id, newPicture); - } - - public override void EditItem(ListType listType, ListItem enumItem) - { - ResetCache(enumItem.ID); - - base.EditItem(listType, enumItem); - } - - public override void ReorderItems(ListType listType, string[] titles) - { - _listItemCache.Clear(); - - base.ReorderItems(listType, titles); - } - - public override ListItem GetByID(int id) - { - return _listItemCache.Get(id.ToString(), () => GetByIDBase(id)); - } - - private ListItem GetByIDBase(int id) - { - return base.GetByID(id); - } - - private void ResetCache(int id) - { - _listItemCache.Reset(id.ToString()); - } - } - [Scope] public class ListItemDao : AbstractDao { @@ -145,19 +71,19 @@ public ListItemDao( public bool IsExist(ListType listType, String title) { - return CRMDbContext.ListItem + return CrmDbContext.ListItem .Where(x => x.TenantId == TenantID && x.ListType == listType && String.Compare(x.Title, title, true) == 0) .Any(); } public bool IsExist(int id) { - return CRMDbContext.ListItem.Where(x => x.Id == id).Any(); + return CrmDbContext.ListItem.Where(x => x.Id == id).Any(); } public List GetItems() { - var dbListItems = Query(CRMDbContext.ListItem) + var dbListItems = Query(CrmDbContext.ListItem) .OrderBy(x => x.SortOrder) .ToList(); @@ -166,7 +92,7 @@ public List GetItems() public List GetItems(ListType listType) { - var dbListItems = Query(CRMDbContext.ListItem) + var dbListItems = Query(CrmDbContext.ListItem) .Where(x => x.ListType == listType) .OrderBy(x => x.SortOrder) .ToList(); @@ -176,7 +102,7 @@ public List GetItems(ListType listType) public int GetItemsCount(ListType listType) { - return Query(CRMDbContext.ListItem) + return Query(CrmDbContext.ListItem) .Where(x => x.ListType == listType) .OrderBy(x => x.SortOrder).Count(); } @@ -237,25 +163,25 @@ public List GetSystemItems() }; } - public virtual ListItem GetByID(int id) + public ListItem GetByID(int id) { if (id < 0) return GetSystemListItem(id); - return _mapper.Map(Query(CRMDbContext.ListItem).FirstOrDefault(x => x.Id == id)); + return _mapper.Map(Query(CrmDbContext.ListItem).FirstOrDefault(x => x.Id == id)); } - public virtual List GetItems(int[] id) + public List GetItems(int[] id) { - var sqlResult = _mapper.Map, List>(CRMDbContext.ListItem.Where(x => id.Contains(x.Id)).ToList()); + var sqlResult = _mapper.Map, List>(CrmDbContext.ListItem.Where(x => id.Contains(x.Id)).ToList()); var systemItem = id.Where(item => item < 0).Select(GetSystemListItem); return systemItem.Any() ? sqlResult.Union(systemItem).ToList() : sqlResult; } - public virtual List GetAll() + public List GetAll() { - var dbListItems = CRMDbContext + var dbListItems = CrmDbContext .ListItem .ToList(); @@ -263,7 +189,7 @@ public virtual List GetAll() } - public virtual void ChangeColor(int id, string newColor) + public void ChangeColor(int id, string newColor) { var listItem = new DbListItem { @@ -272,16 +198,16 @@ public virtual void ChangeColor(int id, string newColor) }; - CRMDbContext.Attach(listItem); - CRMDbContext.Entry(listItem).Property("Color").IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.Attach(listItem); + CrmDbContext.Entry(listItem).Property("Color").IsModified = true; + CrmDbContext.SaveChanges(); } public NameValueCollection GetColors(ListType listType) { var result = new NameValueCollection(); - Query(CRMDbContext.ListItem) + Query(CrmDbContext.ListItem) .Where(x => x.ListType == listType) .Select(x => new { x.Id, x.Color }) .ToList() @@ -293,7 +219,7 @@ public NameValueCollection GetColors(ListType listType) public ListItem GetByTitle(ListType listType, string title) { - return _mapper.Map(Query(CRMDbContext.ListItem) + return _mapper.Map(Query(CrmDbContext.ListItem) .FirstOrDefault(x => String.Compare(x.Title, title, true) == 0 && x.ListType == listType)); } @@ -304,16 +230,16 @@ public int GetRelativeItemsCount(ListType listType, int id) switch (listType) { case ListType.ContactStatus: - result = Query(CRMDbContext.Contacts).Where(x => x.StatusId == id).Count(); + result = Query(CrmDbContext.Contacts).Where(x => x.StatusId == id).Count(); break; case ListType.ContactType: - result = Query(CRMDbContext.Contacts).Where(x => x.ContactTypeId == id).Count(); + result = Query(CrmDbContext.Contacts).Where(x => x.ContactTypeId == id).Count(); break; case ListType.TaskCategory: - result = Query(CRMDbContext.Tasks).Where(x => x.CategoryId == id).Count(); + result = Query(CrmDbContext.Tasks).Where(x => x.CategoryId == id).Count(); break; case ListType.HistoryCategory: - result = Query(CRMDbContext.RelationshipEvent).Where(x => x.CategoryId == id).Count(); + result = Query(CrmDbContext.RelationshipEvent).Where(x => x.CategoryId == id).Count(); break; default: throw new ArgumentException(); @@ -332,8 +258,8 @@ public Dictionary GetRelativeItemsCount(ListType listType) { case ListType.ContactStatus: { - result = Query(CRMDbContext.ListItem) - .Join(Query(CRMDbContext.Contacts), + result = Query(CrmDbContext.ListItem) + .Join(Query(CrmDbContext.Contacts), x => x.Id, y => y.StatusId, (x, y) => new { x, y }) @@ -346,8 +272,8 @@ public Dictionary GetRelativeItemsCount(ListType listType) } case ListType.ContactType: { - result = Query(CRMDbContext.ListItem) - .Join(Query(CRMDbContext.Contacts), + result = Query(CrmDbContext.ListItem) + .Join(Query(CrmDbContext.Contacts), x => x.Id, y => y.ContactTypeId, (x, y) => new { x, y }) @@ -360,8 +286,8 @@ public Dictionary GetRelativeItemsCount(ListType listType) } case ListType.TaskCategory: { - result = Query(CRMDbContext.ListItem) - .Join(Query(CRMDbContext.Tasks), + result = Query(CrmDbContext.ListItem) + .Join(Query(CrmDbContext.Tasks), x => x.Id, y => y.CategoryId, (x, y) => new { x, y }) @@ -375,8 +301,8 @@ public Dictionary GetRelativeItemsCount(ListType listType) case ListType.HistoryCategory: { - result = Query(CRMDbContext.ListItem) - .Join(Query(CRMDbContext.RelationshipEvent), + result = Query(CrmDbContext.ListItem) + .Join(Query(CrmDbContext.RelationshipEvent), x => x.Id, y => y.CategoryId, (x, y) => new { x, y }) @@ -394,7 +320,7 @@ public Dictionary GetRelativeItemsCount(ListType listType) return result; } - public virtual int CreateItem(ListType listType, ListItem enumItem) + public int CreateItem(ListType listType, ListItem enumItem) { if (IsExist(listType, enumItem.Title)) @@ -416,7 +342,7 @@ public virtual int CreateItem(ListType listType, ListItem enumItem) var sortOrder = enumItem.SortOrder; if (sortOrder == 0) - sortOrder = Query(CRMDbContext.ListItem) + sortOrder = Query(CrmDbContext.ListItem) .Where(x => x.ListType == listType) .Max(x => x.SortOrder) + 1; @@ -431,14 +357,14 @@ public virtual int CreateItem(ListType listType, ListItem enumItem) TenantId = TenantID }; - CRMDbContext.Add(listItem); + CrmDbContext.Add(listItem); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return listItem.Id; } - public virtual void EditItem(ListType listType, ListItem enumItem) + public void EditItem(ListType listType, ListItem enumItem) { if (HaveRelativeItemsLink(listType, enumItem.ID)) { @@ -456,25 +382,25 @@ public virtual void EditItem(ListType listType, ListItem enumItem) } } - var itemToUpdate = Query(CRMDbContext.ListItem).Single(x => x.Id == enumItem.ID); + var itemToUpdate = Query(CrmDbContext.ListItem).Single(x => x.Id == enumItem.ID); itemToUpdate.Description = enumItem.Description; itemToUpdate.Title = enumItem.Title; itemToUpdate.AdditionalParams = enumItem.AdditionalParams; itemToUpdate.Color = enumItem.Color; - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } - public virtual void ChangePicture(int id, String newPicture) + public void ChangePicture(int id, String newPicture) { - var itemToUpdate = Query(CRMDbContext.ListItem).Single(x => x.Id == id); + var itemToUpdate = Query(CrmDbContext.ListItem).Single(x => x.Id == id); itemToUpdate.AdditionalParams = newPicture; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } private bool HaveRelativeItemsLink(ListType listType, int itemID) @@ -484,16 +410,16 @@ private bool HaveRelativeItemsLink(ListType listType, int itemID) switch (listType) { case ListType.ContactStatus: - result = Query(CRMDbContext.Contacts).Where(x => x.StatusId == itemID).Any(); + result = Query(CrmDbContext.Contacts).Where(x => x.StatusId == itemID).Any(); break; case ListType.ContactType: - result = Query(CRMDbContext.Contacts).Where(x => x.ContactTypeId == itemID).Any(); + result = Query(CrmDbContext.Contacts).Where(x => x.ContactTypeId == itemID).Any(); break; case ListType.TaskCategory: - result = Query(CRMDbContext.Tasks).Where(x => x.CategoryId == itemID).Any(); + result = Query(CrmDbContext.Tasks).Where(x => x.CategoryId == itemID).Any(); break; case ListType.HistoryCategory: - result = Query(CRMDbContext.RelationshipEvent).Where(x => x.CategoryId == itemID).Any(); + result = Query(CrmDbContext.RelationshipEvent).Where(x => x.CategoryId == itemID).Any(); break; default: throw new ArgumentException(); @@ -516,46 +442,46 @@ public void ChangeRelativeItemsLink(ListType listType, int fromItemID, int toIte { case ListType.ContactStatus: { - var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.StatusId == fromItemID); + var itemToUpdate = Query(CrmDbContext.Contacts).Single(x => x.StatusId == fromItemID); itemToUpdate.StatusId = toItemID; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); } break; case ListType.ContactType: { - var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.ContactTypeId == fromItemID); + var itemToUpdate = Query(CrmDbContext.Contacts).Single(x => x.ContactTypeId == fromItemID); itemToUpdate.ContactTypeId = toItemID; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); } break; case ListType.TaskCategory: { - var itemToUpdate = Query(CRMDbContext.Tasks).Single(x => x.CategoryId == fromItemID); + var itemToUpdate = Query(CrmDbContext.Tasks).Single(x => x.CategoryId == fromItemID); itemToUpdate.CategoryId = toItemID; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); } break; case ListType.HistoryCategory: { - var itemToUpdate = Query(CRMDbContext.RelationshipEvent).Single(x => x.CategoryId == fromItemID); + var itemToUpdate = Query(CrmDbContext.RelationshipEvent).Single(x => x.CategoryId == fromItemID); itemToUpdate.CategoryId = toItemID; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); } break; default: throw new ArgumentException(); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } - public virtual void DeleteItem(ListType listType, int itemID, int toItemID) + public void DeleteItem(ListType listType, int itemID, int toItemID) { if (HaveRelativeItemsLink(listType, itemID)) { @@ -578,28 +504,28 @@ public virtual void DeleteItem(ListType listType, int itemID, int toItemID) var itemToRemove = new DbListItem { Id = itemID }; - CRMDbContext.Entry(itemToRemove).State = EntityState.Deleted; + CrmDbContext.Entry(itemToRemove).State = EntityState.Deleted; - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } - public virtual void ReorderItems(ListType listType, String[] titles) + public void ReorderItems(ListType listType, String[] titles) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); for (int index = 0; index < titles.Length; index++) { - var itemToUpdate = Query(CRMDbContext.ListItem) + var itemToUpdate = Query(CrmDbContext.ListItem) .Single(x => String.Compare(x.Title, titles[index]) == 0 && x.ListType == listType); itemToUpdate.SortOrder = index; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); } diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index c820c935d4f..b3d64d9691f 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -60,54 +60,6 @@ namespace ASC.CRM.Core.Dao { - public class CachedRelationshipEventDao : RelationshipEventDao - { - private readonly HttpRequestDictionary _relationshipEventCache; - - public CachedRelationshipEventDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - FilesIntegration filesIntegration, - CrmSecurity crmSecurity, - TenantUtil tenantUtil, - SetupInfo setupInfo, - PathProvider pathProvider, - IHttpContextAccessor httpContextAccessor, - IOptionsMonitor logger, - ICache ascCache, - IMapper mapper - ) : - base(dbContextManager, - tenantManager, - securityContext, - filesIntegration, - crmSecurity, - tenantUtil, - setupInfo, - pathProvider, - logger, - ascCache, - mapper) - { - _relationshipEventCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_relationshipEvent"); - } - - public override RelationshipEvent GetByID(int eventID) - { - return _relationshipEventCache.Get(eventID.ToString(), () => GetByIDBase(eventID)); - } - - private RelationshipEvent GetByIDBase(int eventID) - { - return base.GetByID(eventID); - } - - private void ResetCache(int dealID) - { - _relationshipEventCache.Reset(dealID.ToString()); - } - } - [Scope] public class RelationshipEventDao : AbstractDao { @@ -191,9 +143,9 @@ public void AttachFiles(int eventID, int[] fileIDs) TenantId = TenantID }; - CRMDbContext.RelationshipEvent.Attach(dbRelationshipEvent); - CRMDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.RelationshipEvent.Attach(dbRelationshipEvent); + CrmDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; + CrmDbContext.SaveChanges(); } } @@ -207,7 +159,7 @@ private int[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID) if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.RelationshipEvent); + var sqlQuery = Query(CrmDbContext.RelationshipEvent); if (contactID != null && contactID.Length > 0) sqlQuery = sqlQuery.Where(x => contactID.Contains(x.ContactId)); @@ -325,20 +277,20 @@ public List RemoveFile(File file) TenantId = TenantID }; - CRMDbContext.Attach(dbRelationshipEvent); - CRMDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; + CrmDbContext.Attach(dbRelationshipEvent); + CrmDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } } - var itemToUpdate = Query(CRMDbContext.Invoices).FirstOrDefault(x => x.FileId == Convert.ToInt32(file.ID)); + var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.FileId == Convert.ToInt32(file.ID)); itemToUpdate.FileId = 0; - CRMDbContext.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return eventIDs; } @@ -349,7 +301,7 @@ public int GetCount(int[] contactID, EntityType entityType, int entityID) if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case) throw new ArgumentException(); - var sqlQuery = Query(CRMDbContext.RelationshipEvent); + var sqlQuery = Query(CrmDbContext.RelationshipEvent); if (contactID.Length > 0) sqlQuery = sqlQuery.Where(x => contactID.Contains(x.ContactId)); @@ -447,8 +399,8 @@ public RelationshipEvent CreateItem(RelationshipEvent item) HaveFiles = false }; - CRMDbContext.RelationshipEvent.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.RelationshipEvent.Add(itemToInsert); + CrmDbContext.SaveChanges(); item.ID = itemToInsert.Id; @@ -460,15 +412,15 @@ public RelationshipEvent CreateItem(RelationshipEvent item) return item; } - public virtual RelationshipEvent GetByID(int eventID) + public RelationshipEvent GetByID(int eventID) { - return ToRelationshipEvent(Query(CRMDbContext.RelationshipEvent) + return ToRelationshipEvent(Query(CrmDbContext.RelationshipEvent) .FirstOrDefault(x => x.Id == eventID)); } public int GetAllItemsCount() { - return Query(CRMDbContext.RelationshipEvent).Count(); + return Query(CrmDbContext.RelationshipEvent).Count(); } public List GetAllItems() @@ -497,7 +449,7 @@ public List GetItems( OrderBy orderBy) { - var sqlQuery = Query(CRMDbContext.RelationshipEvent); + var sqlQuery = Query(CrmDbContext.RelationshipEvent); if (entityID > 0) switch (entityType) @@ -505,7 +457,7 @@ public List GetItems( case EntityType.Contact: var isCompany = false; - isCompany = Query(CRMDbContext.Contacts).Where(x => x.Id == entityID).Select(x => x.IsCompany).Single(); + isCompany = Query(CrmDbContext.Contacts).Where(x => x.Id == entityID).Select(x => x.IsCompany).Single(); if (isCompany) return GetItems(searchText, EntityType.Company, entityID, createBy, categoryID, fromDate, toDate, from, count, orderBy); @@ -654,13 +606,13 @@ public void DeleteItem(RelationshipEvent item) relativeFiles.ForEach(f => RemoveFile(f)); - var itemToDelete = Query(CRMDbContext.RelationshipEvent).Where(x => x.Id == item.ID).Single(); + var itemToDelete = Query(CrmDbContext.RelationshipEvent).Where(x => x.Id == item.ID).Single(); FactoryIndexer.DeleteAsync(itemToDelete); - CRMDbContext.RelationshipEvent.Remove(itemToDelete); + CrmDbContext.RelationshipEvent.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index c38cfb190f8..3da359beb7b 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -265,11 +265,11 @@ private string GetTimePeriodText(ReportTimePeriod timePeriod) public List GetMissingRates(string defaultCurrency) { - var existingRatesQuery = CRMDbContext.CurrencyRate + var existingRatesQuery = CrmDbContext.CurrencyRate .Where(x => x.ToCurrency == defaultCurrency) .Select(x => x.FromCurrency).Distinct().ToList(); - var missingRatesQuery = Query(CRMDbContext.Deals) + var missingRatesQuery = Query(CrmDbContext.Deals) .Where(x => x.BidCurrency != defaultCurrency && !existingRatesQuery.Contains(x.BidCurrency)) .Select(x => x.BidCurrency) .Distinct(); @@ -332,7 +332,7 @@ public List GetMissingRates(string defaultCurrency) { var filedao = _filesIntegration.DaoFactory.GetFileDao(); - var fileIds = Query(CRMDbContext.ReportFile).Where(x => x.CreateBy == userId).Select(x => x.FileId).ToArray(); + var fileIds = Query(CrmDbContext.ReportFile).Where(x => x.CreateBy == userId).Select(x => x.FileId).ToArray(); return fileIds.Length > 0 ? filedao.GetFiles(fileIds) : new List>(); @@ -340,7 +340,7 @@ public List GetMissingRates(string defaultCurrency) public List GetFileIds(Guid userId) { - return Query(CRMDbContext.ReportFile) + return Query(CrmDbContext.ReportFile) .Where(x => x.CreateBy == userId).Select(x => x.FileId).ToList(); } @@ -351,7 +351,7 @@ public Files.Core.File GetFile(int fileid) public Files.Core.File GetFile(int fileid, Guid userId) { - var exist = Query(CRMDbContext.ReportFile) + var exist = Query(CrmDbContext.ReportFile) .Any(x => x.CreateBy == userId && x.FileId == fileid); var filedao = _filesIntegration.DaoFactory.GetFileDao(); @@ -362,10 +362,10 @@ public Files.Core.File GetFile(int fileid, Guid userId) public void DeleteFile(int fileid) { - var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.FileId == fileid && x.CreateBy == _securityContext.CurrentAccount.ID); + var itemToDelete = Query(CrmDbContext.ReportFile).Where(x => x.FileId == fileid && x.CreateBy == _securityContext.CurrentAccount.ID); - CRMDbContext.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.Remove(itemToDelete); + CrmDbContext.SaveChanges(); var filedao = _filesIntegration.DaoFactory.GetFileDao(); @@ -376,10 +376,10 @@ public void DeleteFiles(Guid userId) { var fileIds = GetFileIds(userId); - var itemToDelete = Query(CRMDbContext.ReportFile).Where(x => x.CreateBy == _securityContext.CurrentAccount.ID); + var itemToDelete = Query(CrmDbContext.ReportFile).Where(x => x.CreateBy == _securityContext.CurrentAccount.ID); - CRMDbContext.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.Remove(itemToDelete); + CrmDbContext.SaveChanges(); var filedao = _filesIntegration.DaoFactory.GetFileDao(); @@ -402,8 +402,8 @@ public void SaveFile(int fileId, int reportType) TenantId = TenantID }; - CRMDbContext.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.Add(itemToInsert); + CrmDbContext.SaveChanges(); } #endregion @@ -419,7 +419,7 @@ public bool CheckSalesByManagersReportData(ReportTimePeriod timePeriod, Guid[] m GetTimePeriod(timePeriod, out fromDate, out toDate); - return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), + return Query(CrmDbContext.Deals).Join(Query(CrmDbContext.DealMilestones), x => x.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -470,13 +470,13 @@ private List BuildSalesByManagersReport(ReportTimePeriod timePer return null; } - var result = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var result = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -796,7 +796,7 @@ public bool CheckSalesForecastReportData(ReportTimePeriod timePeriod, Guid[] man GetTimePeriod(timePeriod, out fromDate, out toDate); - return Query(CRMDbContext.Deals).Join(Query(CRMDbContext.DealMilestones), + return Query(CrmDbContext.Deals).Join(Query(CrmDbContext.DealMilestones), x => x.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -840,13 +840,13 @@ private List BuildSalesForecastReport(ReportTimePeriod timePeriod return null; } - var result = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var result = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -1056,7 +1056,7 @@ public bool CheckSalesFunnelReportData(ReportTimePeriod timePeriod, Guid[] manag GetTimePeriod(timePeriod, out fromDate, out toDate); - return Query(CRMDbContext.Deals) + return Query(CrmDbContext.Deals) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); @@ -1076,13 +1076,13 @@ private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Gu GetTimePeriod(timePeriod, out fromDate, out toDate); - var result = Query(CRMDbContext.DealMilestones) - .GroupJoin(Query(CRMDbContext.Deals), + var result = Query(CrmDbContext.DealMilestones) + .GroupJoin(Query(CrmDbContext.Deals), x => x.Id, y => y.DealMilestoneId, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = y, DealMilestone = x.x }) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.Deal.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) @@ -1187,7 +1187,7 @@ public bool CheckWorkloadByContactsReportData(ReportTimePeriod timePeriod, Guid[ GetTimePeriod(timePeriod, out fromDate, out toDate); - return Query(CRMDbContext.Contacts) + return Query(CrmDbContext.Contacts) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); @@ -1207,13 +1207,13 @@ private List BuildWorkloadByContactsReport(ReportTimePeriod GetTimePeriod(timePeriod, out fromDate, out toDate); - var result = Query(CRMDbContext.Contacts) - .GroupJoin(Query(CRMDbContext.ListItem), + var result = Query(CrmDbContext.Contacts) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.ContactTypeId, y => y.Id, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Contact = x.x, ListItem = y }) - .GroupJoin(Query(CRMDbContext.Deals), + .GroupJoin(Query(CrmDbContext.Deals), x => x.Contact.Id, y => y.ContactId, (x, y) => new { x, y }) @@ -1284,12 +1284,12 @@ public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] m GetTimePeriod(timePeriod, out fromDate, out toDate); - var sqlNewTasksQuery = Query(CRMDbContext.Tasks) + var sqlNewTasksQuery = Query(CrmDbContext.Tasks) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); - var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) + var sqlClosedTasksQuery = Query(CrmDbContext.Tasks) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => x.IsClosed) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) @@ -1297,7 +1297,7 @@ public bool CheckWorkloadByTasksReportData(ReportTimePeriod timePeriod, Guid[] m - var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) + var sqlOverdueTasksQuery = Query(CrmDbContext.Tasks) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => x.IsClosed) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) @@ -1328,8 +1328,8 @@ private Dictionary> BuildWorkloadByTasksReport(Rep GetTimePeriod(timePeriod, out fromDate, out toDate); - var sqlNewTasksQuery = Query(CRMDbContext.Tasks) - .GroupJoin(Query(CRMDbContext.ListItem), + var sqlNewTasksQuery = Query(CrmDbContext.Tasks) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.CategoryId, y => y.Id, (x, y) => new { x, y }) @@ -1356,8 +1356,8 @@ private Dictionary> BuildWorkloadByTasksReport(Rep Count = x.count }); - var sqlClosedTasksQuery = Query(CRMDbContext.Tasks) - .GroupJoin(Query(CRMDbContext.ListItem), + var sqlClosedTasksQuery = Query(CrmDbContext.Tasks) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.CategoryId, y => y.Id, (x, y) => new { x, y }) @@ -1385,8 +1385,8 @@ private Dictionary> BuildWorkloadByTasksReport(Rep Count = x.count }); - var sqlOverdueTasksQuery = Query(CRMDbContext.Tasks) - .GroupJoin(Query(CRMDbContext.ListItem), + var sqlOverdueTasksQuery = Query(CrmDbContext.Tasks) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.CategoryId, y => y.Id, (x, y) => new { x, y }) @@ -1455,7 +1455,7 @@ public bool CheckWorkloadByDealsReportData(ReportTimePeriod timePeriod, Guid[] m GetTimePeriod(timePeriod, out fromDate, out toDate); - return Query(CRMDbContext.Deals) + return Query(CrmDbContext.Deals) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : (x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) || (x.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate))) @@ -1476,13 +1476,13 @@ private List BuildWorkloadByDealsReport(ReportTimePeriod timePe GetTimePeriod(timePeriod, out fromDate, out toDate); - var result = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var result = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -1561,7 +1561,7 @@ public bool CheckWorkloadByInvoicesReportData(ReportTimePeriod timePeriod, Guid[ GetTimePeriod(timePeriod, out fromDate, out toDate); - return Query(CRMDbContext.Invoices) + return Query(CrmDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => (x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= _tenantUtil.DateTimeToUtc(toDate))) || (x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate))) || @@ -1589,7 +1589,7 @@ private List BuildWorkloadByInvoicesReport(ReportTimePeriod GetTimePeriod(timePeriod, out fromDate, out toDate); - var result = Query(CRMDbContext.Invoices) + var result = Query(CrmDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .GroupBy(x => x.CreateBy) .Select(x => new @@ -1655,7 +1655,7 @@ public bool CheckWorkloadByViopReportData(ReportTimePeriod timePeriod, Guid[] ma GetTimePeriod(timePeriod, out fromDate, out toDate); - return Query(CRMDbContext.VoipCalls) + return Query(CrmDbContext.VoipCalls) .Where(x => x.ParentCallId == "") .Where(x => managers != null && managers.Any() ? managers.ToList().Contains(x.AnsweredBy) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? @@ -1678,7 +1678,7 @@ private List BuildWorkloadByViopReport(ReportTimePeriod timePeri GetTimePeriod(timePeriod, out fromDate, out toDate); - var result = Query(CRMDbContext.VoipCalls) + var result = Query(CrmDbContext.VoipCalls) .Where(x => x.ParentCallId == "") .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) @@ -1775,13 +1775,13 @@ public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid GetTimePeriod(timePeriod, out fromDate, out toDate); - var newDealsSqlQuery = Query(CRMDbContext.Deals) + var newDealsSqlQuery = Query(CrmDbContext.Deals) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); - var closedDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.DealMilestones), + var closedDealsSqlQuery = Query(CrmDbContext.Deals) + .Join(Query(CrmDbContext.DealMilestones), x => x.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -1790,8 +1790,8 @@ public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid .Where(x => x.y.Status != DealMilestoneStatus.Open) .Any(); - var overdueDealsSqlQuery = Query(CRMDbContext.Deals) - .Join(Query(CRMDbContext.DealMilestones), + var overdueDealsSqlQuery = Query(CrmDbContext.Deals) + .Join(Query(CrmDbContext.DealMilestones), x => x.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -1801,24 +1801,24 @@ public bool CheckSummaryForThePeriodReportData(ReportTimePeriod timePeriod, Guid (x.y.Status == DealMilestoneStatus.ClosedAndWon && x.x.ActualCloseDate > x.x.ExpectedCloseDate)) .Any(); - var invoicesSqlQuery = Query(CRMDbContext.Invoices) + var invoicesSqlQuery = Query(CrmDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); - var contactsSqlQuery = Query(CRMDbContext.Contacts) + var contactsSqlQuery = Query(CrmDbContext.Contacts) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); - var tasksSqlQuery = Query(CRMDbContext.Tasks) + var tasksSqlQuery = Query(CrmDbContext.Tasks) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); - var voipSqlQuery = Query(CRMDbContext.VoipCalls) + var voipSqlQuery = Query(CrmDbContext.VoipCalls) .Where(x => x.ParentCallId == "") .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) .Where(x => x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) @@ -1849,8 +1849,8 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ GetTimePeriod(timePeriod, out fromDate, out toDate); - var newDealsSqlQuery = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var newDealsSqlQuery = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) @@ -1865,13 +1865,13 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); - var wonDealsSqlQuery = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var wonDealsSqlQuery = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -1887,13 +1887,13 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); - var lostDealsSqlQuery = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var lostDealsSqlQuery = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -1910,13 +1910,13 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ }).ToList(); - var overdueDealsSqlQuery = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var overdueDealsSqlQuery = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -1933,7 +1933,7 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : x.Deal.PerPeriodValue) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); - var invoicesSqlQuery = Query(CRMDbContext.Invoices) + var invoicesSqlQuery = Query(CrmDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .GroupBy(x => x.Status) @@ -1947,8 +1947,8 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ ? 1 : 0) }).ToList(); - var contactsSqlQuery = Query(CRMDbContext.Contacts) - .GroupJoin(Query(CRMDbContext.ListItem), + var contactsSqlQuery = Query(CrmDbContext.Contacts) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.ContactTypeId, y => y.Id, (x, y) => new { x, y }) @@ -1965,8 +1965,8 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ .OrderBy(x => x.title) .ToList(); - var tasksSqlQuery = Query(CRMDbContext.Tasks) - .GroupJoin(Query(CRMDbContext.ListItem), + var tasksSqlQuery = Query(CrmDbContext.Tasks) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.CategoryId, y => y.Id, (x, y) => new { x, y }) @@ -1987,7 +1987,7 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ .ToList(); // .OrderBy("i.sort_order, i.title", true); - var voipSqlQuery = Query(CRMDbContext.VoipCalls) + var voipSqlQuery = Query(CrmDbContext.VoipCalls) .Where(x => String.IsNullOrEmpty(x.ParentCallId)) .Where(x => managers != null && managers.Any() ? managers.Contains(x.AnsweredBy) : true) .Where(x => x.DialDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.DialDate <= _tenantUtil.DateTimeToUtc(toDate)) @@ -2075,8 +2075,8 @@ public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid GetTimePeriod(timePeriod, out fromDate, out toDate); - var dealsSqlQuery = Query(CRMDbContext.Deals) - .Join(CRMDbContext.DealMilestones, + var dealsSqlQuery = Query(CrmDbContext.Deals) + .Join(CrmDbContext.DealMilestones, x => x.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -2086,17 +2086,17 @@ public bool CheckSummaryAtThisMomentReportData(ReportTimePeriod timePeriod, Guid .Any(); - var contactsSqlQuery = Query(CRMDbContext.Contacts) + var contactsSqlQuery = Query(CrmDbContext.Contacts) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); - var tasksSqlQuery = Query(CRMDbContext.Tasks) + var tasksSqlQuery = Query(CrmDbContext.Tasks) .Where(x => managers != null && managers.Any() ? managers.Contains(x.ResponsibleId) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); - var invoicesSqlQuery = Query(CRMDbContext.Invoices) + var invoicesSqlQuery = Query(CrmDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .Any(); @@ -2124,13 +2124,13 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ GetTimePeriod(timePeriod, out fromDate, out toDate); - var openDealsSqlQuery = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var openDealsSqlQuery = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -2146,13 +2146,13 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); - var overdueDealsSqlQuery = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var overdueDealsSqlQuery = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -2170,13 +2170,13 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ }).ToList(); - var nearDealsSqlQuery = Query(CRMDbContext.Deals) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + var nearDealsSqlQuery = Query(CrmDbContext.Deals) + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x, CurrencyRate = y }) - .GroupJoin(Query(CRMDbContext.DealMilestones), + .GroupJoin(Query(CrmDbContext.DealMilestones), x => x.Deal.DealMilestoneId, y => y.Id, (x, y) => new { x, y }) @@ -2193,13 +2193,13 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); - var dealsByStageSqlQuery = Query(CRMDbContext.DealMilestones) - .GroupJoin(Query(CRMDbContext.Deals), + var dealsByStageSqlQuery = Query(CrmDbContext.DealMilestones) + .GroupJoin(Query(CrmDbContext.Deals), x => x.Id, y => y.DealMilestoneId, (x, y) => new { x, y }) .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = y, DealMilestone = x.x }) - .GroupJoin(Query(CRMDbContext.CurrencyRate), + .GroupJoin(Query(CrmDbContext.CurrencyRate), x => x.Deal.BidCurrency, y => y.FromCurrency, (x, y) => new { x, y }) @@ -2216,8 +2216,8 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)) }).ToList(); - var contactsByTypeSqlQuery = Query(CRMDbContext.Contacts) - .GroupJoin(Query(CRMDbContext.ListItem), + var contactsByTypeSqlQuery = Query(CrmDbContext.Contacts) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.ContactTypeId, y => y.Id, (x, y) => new { x, y }) @@ -2234,8 +2234,8 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ .OrderBy(x => x.title) .ToList(); - var contactsByStageSqlQuery = Query(CRMDbContext.Contacts) - .GroupJoin(Query(CRMDbContext.ListItem), + var contactsByStageSqlQuery = Query(CrmDbContext.Contacts) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.StatusId, y => y.Id, (x, y) => new { x, y }) @@ -2252,8 +2252,8 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ .OrderBy(x => x.title) .ToList(); - var tasksSqlQuery = Query(CRMDbContext.Tasks) - .GroupJoin(Query(CRMDbContext.ListItem), + var tasksSqlQuery = Query(CrmDbContext.Tasks) + .GroupJoin(Query(CrmDbContext.ListItem), x => x.CategoryId, y => y.Id, (x, y) => new { x, y }) @@ -2274,7 +2274,7 @@ private object BuildSummaryAtThisMomentReport(ReportTimePeriod timePeriod, Guid[ .ToList(); - var invoicesSqlQuery = Query(CRMDbContext.Invoices) + var invoicesSqlQuery = Query(CrmDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .Where(x => timePeriod == ReportTimePeriod.DuringAllTime ? true : x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate)) .GroupBy(x => x.Status) diff --git a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs index 9ceba7f5c7b..46bd00c7961 100644 --- a/products/ASC.CRM/Server/Core/Dao/SearchDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/SearchDao.cs @@ -161,7 +161,7 @@ public SearchResultItem[] Search(String searchText) private Dictionary> SearchByRelationshipEvent(String[] keywords) { - var sqlQuery = Query(CRMDbContext.RelationshipEvent); + var sqlQuery = Query(CrmDbContext.RelationshipEvent); if (keywords.Length > 0) { @@ -177,7 +177,7 @@ private Dictionary> SearchByRelationshipEvent(Strin private Dictionary> SearchByCustomFields(String[] keywords) { - var sqlQuery = Query(CRMDbContext.FieldValue); + var sqlQuery = Query(CrmDbContext.FieldValue); if (keywords.Length > 0) { @@ -193,7 +193,7 @@ private Dictionary> SearchByCustomFields(String[] k private Dictionary> SearchByContactInfos(String[] keywords) { - var sqlQuery = Query(CRMDbContext.ContactsInfo); + var sqlQuery = Query(CrmDbContext.ContactsInfo); if (keywords.Length > 0) { @@ -217,7 +217,7 @@ private SearchResultItem[] GetSearchResultItems(String[] keywords) if (IncludeToSearch(EntityType.Task)) { - var sqlQuery = Query(CRMDbContext.Tasks); + var sqlQuery = Query(CrmDbContext.Tasks); if (_findedIDs.ContainsKey(EntityType.Task)) { @@ -259,7 +259,7 @@ private SearchResultItem[] GetSearchResultItems(String[] keywords) if (IncludeToSearch(EntityType.Opportunity)) { - var sqlQuery = Query(CRMDbContext.Deals); + var sqlQuery = Query(CrmDbContext.Deals); if (_findedIDs.ContainsKey(EntityType.Opportunity)) { @@ -304,7 +304,7 @@ private SearchResultItem[] GetSearchResultItems(String[] keywords) if (IncludeToSearch(EntityType.Contact)) { - var sqlQuery = Query(CRMDbContext.Contacts); + var sqlQuery = Query(CrmDbContext.Contacts); if (_findedIDs.ContainsKey(EntityType.Contact)) { @@ -357,7 +357,7 @@ private SearchResultItem[] GetSearchResultItems(String[] keywords) if (IncludeToSearch(EntityType.Case)) { - var sqlQuery = Query(CRMDbContext.Cases); + var sqlQuery = Query(CrmDbContext.Cases); if (_findedIDs.ContainsKey(EntityType.Case)) { @@ -401,7 +401,7 @@ private SearchResultItem[] GetSearchResultItems(String[] keywords) if (IncludeToSearch(EntityType.Invoice)) { - var sqlQuery = Query(CRMDbContext.Invoices); + var sqlQuery = Query(CrmDbContext.Invoices); if (_findedIDs.ContainsKey(EntityType.Invoice)) { diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index ba9f2deaf8c..61d6b6f8fdd 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -75,13 +75,13 @@ public bool IsExist(EntityType entityType, String tagName) private bool IsExistInDb(EntityType entityType, String tagName) { - return Query(CRMDbContext.Tags) + return Query(CrmDbContext.Tags) .Where(x => x.EntityType == entityType && String.Compare(x.Title, tagName, true) == 0).Any(); } private int GetTagId(EntityType entityType, String tagName) { - return Query(CRMDbContext.Tags) + return Query(CrmDbContext.Tags) .Where(x => x.EntityType == entityType && String.Compare(x.Title, tagName, true) == 0) .Select(x => x.Id) .SingleOrDefault(); @@ -89,7 +89,7 @@ private int GetTagId(EntityType entityType, String tagName) public String[] GetAllTags(EntityType entityType) { - return CRMDbContext.Tags + return CrmDbContext.Tags .Where(x => x.EntityType == entityType) .OrderBy(x => x.Title) .Select(x => x.Title) @@ -98,7 +98,7 @@ public String[] GetAllTags(EntityType entityType) public List> GetAllTags() { - return Query(CRMDbContext.Tags) + return Query(CrmDbContext.Tags) .OrderBy(x => x.Title) .Select(x => new KeyValuePair(x.EntityType, x.Title)).ToList(); } @@ -111,8 +111,8 @@ public String GetTagsLinkCountJSON(EntityType entityType) public IEnumerable GetTagsLinkCount(EntityType entityType) { - return Query(CRMDbContext.Tags) - .Join(CRMDbContext.EntityTags, + return Query(CrmDbContext.Tags) + .Join(CrmDbContext.EntityTags, x => x.Id, y => y.TagId, (x, y) => new { x, y }) @@ -124,7 +124,7 @@ public IEnumerable GetTagsLinkCount(EntityType entityType) public Dictionary> GetEntitiesTags(EntityType entityType) { - return CRMDbContext.EntityTags.Join(Query(CRMDbContext.Tags), + return CrmDbContext.EntityTags.Join(Query(CrmDbContext.Tags), x => x.TagId, y => y.Id, (x, y) => new { x, y }) @@ -137,8 +137,8 @@ public Dictionary> GetEntitiesTags(EntityType entityType) public String[] GetEntityTags(EntityType entityType, int entityID) { - return Query(CRMDbContext.Tags) - .Join(CRMDbContext.EntityTags, + return Query(CrmDbContext.Tags) + .Join(CrmDbContext.EntityTags, x => x.Id, y => y.TagId, (x, y) => new @@ -153,8 +153,8 @@ public String[] GetEntityTags(EntityType entityType, int entityID) public string[] GetUnusedTags(EntityType entityType) { - return Query(CRMDbContext.Tags) - .Join(CRMDbContext.EntityTags.DefaultIfEmpty(), + return Query(CrmDbContext.Tags) + .Join(CrmDbContext.EntityTags.DefaultIfEmpty(), x => x.Id, y => y.TagId, (x, y) => new { x, y }) @@ -164,7 +164,7 @@ public string[] GetUnusedTags(EntityType entityType) public bool CanDeleteTag(EntityType entityType, String tagName) { - return Query(CRMDbContext.Tags) + return Query(CrmDbContext.Tags) .Where(x => string.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) .Select(x => x.Id).SingleOrDefault() != 0; } @@ -178,34 +178,34 @@ public void DeleteTag(EntityType entityType, String tagName) public void DeleteTagFromEntity(EntityType entityType, int entityID, String tagName) { - var tagID = Query(CRMDbContext.Tags) + var tagID = Query(CrmDbContext.Tags) .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) .Select(x => x.Id).SingleOrDefault(); if (tagID == 0) return; - var itemsToRemove = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && x.TagId == tagID); + var itemsToRemove = CrmDbContext.EntityTags.Where(x => x.EntityType == entityType && x.TagId == tagID); if (entityID > 0) itemsToRemove = itemsToRemove.Where(x => x.EntityId == entityID); - CRMDbContext.RemoveRange(itemsToRemove); + CrmDbContext.RemoveRange(itemsToRemove); if (entityID == 0) - CRMDbContext.Tags.RemoveRange(Query(CRMDbContext.Tags).Where(x => x.Id == tagID && x.EntityType == entityType)); + CrmDbContext.Tags.RemoveRange(Query(CrmDbContext.Tags).Where(x => x.Id == tagID && x.EntityType == entityType)); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public void DeleteAllTagsFromEntity(EntityType entityType, int entityID) { if (entityID <= 0) return; - var itemsToRemove = CRMDbContext.EntityTags.Where(x => x.EntityType == entityType && x.EntityId == entityID); + var itemsToRemove = CrmDbContext.EntityTags.Where(x => x.EntityType == entityType && x.EntityId == entityID); - CRMDbContext.EntityTags.RemoveRange(itemsToRemove); + CrmDbContext.EntityTags.RemoveRange(itemsToRemove); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public void DeleteUnusedTags(EntityType entityType) @@ -213,16 +213,16 @@ public void DeleteUnusedTags(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var itemToDelete = Query(CRMDbContext.Tags) - .Join(CRMDbContext.EntityTags.DefaultIfEmpty(), + var itemToDelete = Query(CrmDbContext.Tags) + .Join(CrmDbContext.EntityTags.DefaultIfEmpty(), x => x.Id, y => y.TagId, (x, y) => new { x, y }) .Where(x => x.x.EntityType == entityType && x.y == null).Select(x => x.x).ToList(); - CRMDbContext.RemoveRange(itemToDelete); + CrmDbContext.RemoveRange(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public int AddTag(EntityType entityType, String tagName, bool returnExisted = false) @@ -252,9 +252,9 @@ private int AddTagInDb(EntityType entityType, String tagName) EntityType = entityType }; - CRMDbContext.Tags.Add(dbTag); + CrmDbContext.Tags.Add(dbTag); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return dbTag.Id; } @@ -264,9 +264,9 @@ public Dictionary GetAndAddTags(EntityType entityType, String[] tag { tags = tags.Select(CorrectTag).Where(t => !string.IsNullOrWhiteSpace(t)).ToArray(); - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var tagNamesAndIds = Query(CRMDbContext.Tags) + var tagNamesAndIds = Query(CrmDbContext.Tags) .Where(x => tags.Contains(x.Title) && x.EntityType == entityType) .Select(x => new { x.Id, x.Title }) .ToDictionary(x => x.Title, x => x.Id); @@ -290,21 +290,21 @@ private int AddTagToEntityInDb(EntityType entityType, int entityID, String tagNa if (String.IsNullOrEmpty(tagName) || entityID == 0) throw new ArgumentException(); - var tagID = Query(CRMDbContext.Tags) + var tagID = Query(CrmDbContext.Tags) .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) .Select(x => x.Id).SingleOrDefault(); if (tagID == 0) tagID = AddTagInDb(entityType, tagName); - CRMDbContext.EntityTags.Add(new DbEntityTag + CrmDbContext.EntityTags.Add(new DbEntityTag { EntityId = entityID, EntityType = entityType, TagId = tagID }); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return tagID; } @@ -321,9 +321,9 @@ public int AddTagToContacts(int[] contactID, String tagName) if (String.IsNullOrEmpty(tagName) || contactID == null || contactID.Length == 0) throw new ArgumentException(); - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var tagID = Query(CRMDbContext.Tags) + var tagID = Query(CrmDbContext.Tags) .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == EntityType.Contact) .Select(x => x.Id).SingleOrDefault(); @@ -332,7 +332,7 @@ public int AddTagToContacts(int[] contactID, String tagName) foreach (var id in contactID) { - CRMDbContext.EntityTags.Add(new DbEntityTag + CrmDbContext.EntityTags.Add(new DbEntityTag { EntityId = id, EntityType = EntityType.Contact, @@ -340,7 +340,7 @@ public int AddTagToContacts(int[] contactID, String tagName) }); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); @@ -352,9 +352,9 @@ public int DeleteTagFromContacts(int[] contactID, String tagName) if (String.IsNullOrEmpty(tagName) || contactID == null || contactID.Length == 0) throw new ArgumentException(); - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var tagID = Query(CRMDbContext.Tags) + var tagID = Query(CrmDbContext.Tags) .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == EntityType.Contact) .Select(x => x.Id) .SingleOrDefault(); @@ -362,15 +362,15 @@ public int DeleteTagFromContacts(int[] contactID, String tagName) if (tagID == 0) throw new ArgumentException(); - var itemsToRemove = CRMDbContext + var itemsToRemove = CrmDbContext .EntityTags .Where(x => x.EntityType == EntityType.Contact && x.TagId == tagID && contactID.Contains(x.EntityId)); - CRMDbContext.EntityTags.RemoveRange(itemsToRemove); + CrmDbContext.EntityTags.RemoveRange(itemsToRemove); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); @@ -379,44 +379,44 @@ public int DeleteTagFromContacts(int[] contactID, String tagName) public void SetTagToEntity(EntityType entityType, int entityID, String[] tags) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var itemsToDelete = CRMDbContext.EntityTags.Where(x => x.EntityId == entityID && x.EntityType == entityType); + var itemsToDelete = CrmDbContext.EntityTags.Where(x => x.EntityId == entityID && x.EntityType == entityType); - CRMDbContext.EntityTags.RemoveRange(itemsToDelete); + CrmDbContext.EntityTags.RemoveRange(itemsToDelete); foreach (var tagName in tags.Where(t => !string.IsNullOrWhiteSpace(t))) { AddTagToEntityInDb(entityType, entityID, tagName); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); } private void AddTagToEntityInDb(EntityType entityType, int entityID, int tagID) { - CRMDbContext.EntityTags.Add(new DbEntityTag + CrmDbContext.EntityTags.Add(new DbEntityTag { EntityId = entityID, EntityType = entityType, TagId = tagID }); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public void AddTagToEntity(EntityType entityType, int entityID, int[] tagIDs) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); foreach (var tagID in tagIDs) { AddTagToEntityInDb(entityType, entityID, tagID); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); } diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index b5c1842d3a4..39dc84143fc 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -30,7 +30,6 @@ using System.Linq; using System.Text.RegularExpressions; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -45,86 +44,19 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao { - public class CachedTaskDao : TaskDao - { - - private readonly HttpRequestDictionary _contactCache; - - public CachedTaskDao(DbContextManager dbContextManager, - TenantManager tenantManager, - SecurityContext securityContext, - CrmSecurity crmSecurity, - TenantUtil tenantUtil, - FactoryIndexerTask factoryIndexer, - IOptionsMonitor logger, - ICache ascCache, - IHttpContextAccessor httpContextAccessor, - DbContextManager userDbContext, - DbContextManager coreDbContext, - IMapper mapper - ) : - base(dbContextManager, - tenantManager, - securityContext, - crmSecurity, - tenantUtil, - factoryIndexer, - logger, - ascCache, - userDbContext, - coreDbContext, - mapper - ) - { - _contactCache = new HttpRequestDictionary(httpContextAccessor?.HttpContext, "crm_task"); - } - - - public override Task GetByID(int taskID) - { - return _contactCache.Get(taskID.ToString(), () => GetByIDBase(taskID)); - - } - - private Task GetByIDBase(int taskID) - { - return base.GetByID(taskID); - } - - public override void DeleteTask(int taskID) - { - ResetCache(taskID); - - base.DeleteTask(taskID); - } - - public override Task SaveOrUpdateTask(Task task) - { - - if (task != null && task.ID > 0) - { - ResetCache(task.ID); - } - - return base.SaveOrUpdateTask(task); - } - - private void ResetCache(int taskID) - { - _contactCache.Reset(taskID.ToString()); - } - - } - [Scope] public class TaskDao : AbstractDao { + private readonly UserDbContext _userDbContext; + private readonly FactoryIndexerTask _factoryIndexer; + private readonly TenantUtil _tenantUtil; + private readonly CrmSecurity _crmSecurity; + public TaskDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -134,7 +66,6 @@ public TaskDao(DbContextManager dbContextManager, IOptionsMonitor logger, ICache ascCache, DbContextManager userDbContext, - DbContextManager coreDbContext, IMapper mapper) : base(dbContextManager, tenantManager, @@ -143,24 +74,13 @@ public TaskDao(DbContextManager dbContextManager, ascCache, mapper) { - CRMSecurity = crmSecurity; - TenantUtil = tenantUtil; - FactoryIndexer = factoryIndexer; - UserDbContext = userDbContext.Value; - CoreDbContext = coreDbContext.Value; + _crmSecurity = crmSecurity; + _tenantUtil = tenantUtil; + _factoryIndexer = factoryIndexer; + _userDbContext = userDbContext.Value; _mapper = mapper; } - public CoreDbContext CoreDbContext { get; } - - public UserDbContext UserDbContext { get; } - - public FactoryIndexerTask FactoryIndexer { get; } - - public TenantUtil TenantUtil { get; } - - public CrmSecurity CRMSecurity { get; } - public void OpenTask(int taskId) { var task = GetByID(taskId); @@ -168,7 +88,7 @@ public void OpenTask(int taskId) if (task == null) throw new ArgumentException(); - CRMSecurity.DemandEdit(task); + _crmSecurity.DemandEdit(task); DbTask entity = new DbTask() { @@ -176,9 +96,9 @@ public void OpenTask(int taskId) IsClosed = false }; - CRMDbContext.Tasks.Update(entity); + CrmDbContext.Tasks.Update(entity); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public void CloseTask(int taskId) @@ -188,7 +108,7 @@ public void CloseTask(int taskId) if (task == null) throw new ArgumentException(); - CRMSecurity.DemandEdit(task); + _crmSecurity.DemandEdit(task); DbTask entity = new DbTask() { @@ -196,18 +116,16 @@ public void CloseTask(int taskId) IsClosed = true }; - CRMDbContext.Tasks.Update(entity); + CrmDbContext.Tasks.Update(entity); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } - public virtual Task GetByID(int taskID) + public Task GetByID(int id) { - var dbTask = CRMDbContext.Tasks.Where(x => x.Id == taskID).SingleOrDefault(); - - if (dbTask == default(DbTask)) return null; + var entity = Query(CrmDbContext.Tasks).FirstOrDefault(x => x.Id == id); - return _mapper.Map(dbTask); + return _mapper.Map(entity); } public List GetTasks(EntityType entityType, int entityID, bool? onlyActiveTask) @@ -217,31 +135,31 @@ public List GetTasks(EntityType entityType, int entityID, bool? onlyActive } public int GetAllTasksCount() { - return CRMDbContext.Tasks.Count(); + return Query(CrmDbContext.Tasks).Count(); } public List GetAllTasks() { - var dbTasks = Query(CRMDbContext.Tasks) + var dbTasks = Query(CrmDbContext.Tasks) .OrderBy(x => x.Deadline) .OrderBy(x => x.Title).ToList(); return _mapper.Map, List>(dbTasks) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } public void ExecAlert(IEnumerable ids) { if (!ids.Any()) return; - CRMDbContext.Tasks.UpdateRange(ids.Select(x => new DbTask { ExecAlert = 1, Id = x })); ; + CrmDbContext.Tasks.UpdateRange(ids.Select(x => new DbTask { ExecAlert = 1, Id = x })); ; - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public List GetInfoForReminder(DateTime scheduleDate) { - return CRMDbContext.Tasks.Where(x => + return CrmDbContext.Tasks.Where(x => x.IsClosed == false && x.AlertValue != 0 && x.ExecAlert == 0 && @@ -263,7 +181,7 @@ public List GetTasks( OrderBy orderBy) { - if (CRMSecurity.IsAdmin) + if (_crmSecurity.IsAdmin) return GetCrudeTasks( searchText, responsibleID, @@ -293,9 +211,9 @@ public List GetTasks( if (crudeTasks.Count == 0) return crudeTasks; - if (crudeTasks.Count < from + count) return CRMSecurity.FilterRead(crudeTasks).Skip(from).ToList(); + if (crudeTasks.Count < from + count) return _crmSecurity.FilterRead(crudeTasks).Skip(from).ToList(); - var result = CRMSecurity.FilterRead(crudeTasks).ToList(); + var result = _crmSecurity.FilterRead(crudeTasks).ToList(); if (result.Count == crudeTasks.Count) return result.Skip(from).ToList(); @@ -319,7 +237,7 @@ public List GetTasks( if (crudeTasks.Count == 0) break; - result.AddRange(CRMSecurity.FilterRead(crudeTasks)); + result.AddRange(_crmSecurity.FilterRead(crudeTasks)); if ((result.Count >= count + from) || (crudeTasks.Count < localCount)) break; @@ -358,7 +276,7 @@ private List GetCrudeTasks( { List tasksIds; - if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out tasksIds)) + if (!_factoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out tasksIds)) { foreach (var k in keywords) { @@ -432,14 +350,14 @@ public int GetTasksCount( 0, null); - if (CRMSecurity.IsAdmin) + if (_crmSecurity.IsAdmin) result = tasks.Count(); else - result = CRMSecurity.FilterRead(tasks).Count(); + result = _crmSecurity.FilterRead(tasks).Count(); } else { - if (CRMSecurity.IsAdmin) + if (_crmSecurity.IsAdmin) { result = GetDbTaskByFilters( responsibleId, @@ -595,7 +513,7 @@ private IQueryable GetDbTaskByFilters( int count, OrderBy orderBy) { - var sqlQuery = Query(CRMDbContext.Tasks); + var sqlQuery = Query(CrmDbContext.Tasks); if (responsibleID != Guid.Empty) sqlQuery = sqlQuery.Where(x => x.ResponsibleId == responsibleID); @@ -604,7 +522,7 @@ private IQueryable GetDbTaskByFilters( switch (entityType) { case EntityType.Contact: - var isCompany = Query(CRMDbContext.Contacts).Where(x => x.Id == entityID).Select(x => x.IsCompany).Single(); + var isCompany = Query(CrmDbContext.Contacts).Where(x => x.Id == entityID).Select(x => x.IsCompany).Single(); if (isCompany) return GetDbTaskByFilters(responsibleID, categoryID, isClosed, fromDate, toDate, EntityType.Company, entityID, from, count, orderBy); @@ -649,15 +567,15 @@ private IQueryable GetDbTaskByFilters( if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.Deadline >= TenantUtil.DateTimeToUtc(fromDate) && x.Deadline <= TenantUtil.DateTimeToUtc(toDate)); + sqlQuery = sqlQuery.Where(x => x.Deadline >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deadline <= _tenantUtil.DateTimeToUtc(toDate)); } else if (fromDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.Deadline > TenantUtil.DateTimeToUtc(fromDate)); + sqlQuery = sqlQuery.Where(x => x.Deadline > _tenantUtil.DateTimeToUtc(fromDate)); } else if (toDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.Deadline < TenantUtil.DateTimeToUtc(toDate)); + sqlQuery = sqlQuery.Where(x => x.Deadline < _tenantUtil.DateTimeToUtc(toDate)); } if (0 < from && from < int.MaxValue) @@ -708,7 +626,7 @@ private IQueryable GetDbTaskByFilters( break; case TaskSortedByType.ContactManager: { - sqlQuery = sqlQuery.GroupJoin(UserDbContext.Users.Where(x => x.Tenant == TenantID), + sqlQuery = sqlQuery.GroupJoin(_userDbContext.Users.Where(x => x.Tenant == TenantID), x => x.ResponsibleId, y => y.Id, (x, y) => new { x, y } @@ -724,7 +642,7 @@ private IQueryable GetDbTaskByFilters( break; case TaskSortedByType.Contact: { - var subSqlQuery = sqlQuery.GroupJoin(CRMDbContext.Contacts, + var subSqlQuery = sqlQuery.GroupJoin(CrmDbContext.Contacts, x => x.ContactId, y => y.Id, (x, y) => new { x, y } @@ -763,7 +681,7 @@ private IQueryable GetDbTaskByFilters( public Dictionary GetNearestTask(int[] contactID) { - return Query(CRMDbContext.Tasks) + return Query(CrmDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed) .GroupBy(x => x.ContactId) .ToDictionary(x => x.Key, y => _mapper.Map(y.Single(x => x.Id == y.Min(x => x.Id)))); @@ -771,7 +689,7 @@ public Dictionary GetNearestTask(int[] contactID) public IEnumerable GetResponsibles(int categoryID) { - var sqlQuery = Query(CRMDbContext.Tasks); + var sqlQuery = Query(CrmDbContext.Tasks); if (0 < categoryID) sqlQuery = sqlQuery.Where(x => x.CategoryId == categoryID); @@ -781,7 +699,7 @@ public IEnumerable GetResponsibles(int categoryID) public Dictionary GetTasksCount(int[] contactID) { - return Query(CRMDbContext.Tasks) + return Query(CrmDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId)) .GroupBy(x => x.ContactId) .Select(x => new { Key = x.Key, Value = x.Count() }) @@ -799,7 +717,7 @@ public int GetTasksCount(int contactID) public Dictionary HaveLateTask(int[] contactID) { - return Query(CRMDbContext.Tasks) + return Query(CrmDbContext.Tasks) .Where(x => contactID.Contains(x.ContactId) && !x.IsClosed && x.Deadline <= DateTime.UtcNow) .GroupBy(x => x.ContactId) .Select(x => new { Key = x.Key, Value = x.Count() }) @@ -815,14 +733,14 @@ public bool HaveLateTask(int contactID) return result[contactID]; } - public virtual Task SaveOrUpdateTask(Task newTask) + public Task SaveOrUpdateTask(Task newTask) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); return SaveOrUpdateTaskInDb(newTask); } - public virtual Task[] SaveOrUpdateTaskList(List newTasks) + public Task[] SaveOrUpdateTaskList(List newTasks) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); @@ -838,11 +756,12 @@ public virtual Task[] SaveOrUpdateTaskList(List newTasks) private Task SaveOrUpdateTaskInDb(Task newTask) { - if (string.IsNullOrEmpty(newTask.Title) || newTask.DeadLine == DateTime.MinValue || + if (string.IsNullOrEmpty(newTask.Title) || + newTask.DeadLine == DateTime.MinValue || newTask.CategoryID <= 0) throw new ArgumentException(); - - if (newTask.ID == 0 || Query(CRMDbContext.Tasks).Where(x => x.Id == newTask.ID).Count() == 0) + + if (newTask.ID == 0 ) { newTask.CreateOn = DateTime.UtcNow; newTask.CreateBy = _securityContext.CurrentAccount.ID; @@ -854,7 +773,7 @@ private Task SaveOrUpdateTaskInDb(Task newTask) { Title = newTask.Title, Description = newTask.Description, - Deadline = TenantUtil.DateTimeToUtc(newTask.DeadLine), + Deadline = _tenantUtil.DateTimeToUtc(newTask.DeadLine), ResponsibleId = newTask.ResponsibleID, ContactId = newTask.ContactID, EntityType = newTask.EntityType, @@ -869,23 +788,24 @@ private Task SaveOrUpdateTaskInDb(Task newTask) TenantId = TenantID }; - CRMDbContext.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.Add(itemToInsert); + + CrmDbContext.SaveChanges(); newTask.ID = itemToInsert.Id; } else { - var itemToUpdate = Query(CRMDbContext.Tasks).FirstOrDefault(x => x.Id == newTask.ID); + var itemToUpdate = Query(CrmDbContext.Tasks).FirstOrDefault(x => x.Id == newTask.ID); var oldTask = _mapper.Map(itemToUpdate); - CRMSecurity.DemandEdit(oldTask); + _crmSecurity.DemandEdit(oldTask); itemToUpdate.Title = newTask.Title; itemToUpdate.Description = newTask.Description; - itemToUpdate.Deadline = TenantUtil.DateTimeToUtc(newTask.DeadLine); + itemToUpdate.Deadline = _tenantUtil.DateTimeToUtc(newTask.DeadLine); itemToUpdate.ResponsibleId = newTask.ResponsibleID; itemToUpdate.ContactId = newTask.ContactID; itemToUpdate.EntityType = newTask.EntityType; @@ -897,8 +817,8 @@ private Task SaveOrUpdateTaskInDb(Task newTask) itemToUpdate.ExecAlert = 0; itemToUpdate.TenantId = TenantID; - CRMDbContext.Update(itemToUpdate); - CRMDbContext.SaveChanges(); + CrmDbContext.Update(itemToUpdate); + CrmDbContext.SaveChanges(); newTask.CreateOn = oldTask.CreateOn; @@ -910,12 +830,12 @@ private Task SaveOrUpdateTaskInDb(Task newTask) newTask.IsClosed = oldTask.IsClosed; } - FactoryIndexer.Index(Query(CRMDbContext.Tasks).Where(x => x.Id == newTask.ID).Single()); + _factoryIndexer.Index(Query(CrmDbContext.Tasks).Where(x => x.Id == newTask.ID).Single()); return newTask; } - public virtual int SaveTask(Task newTask) + public int SaveTask(Task newTask) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); return SaveTaskInDb(newTask); @@ -931,7 +851,7 @@ private int SaveTaskInDb(Task newTask) { Title = newTask.Title, Description = newTask.Description, - Deadline = TenantUtil.DateTimeToUtc(newTask.DeadLine), + Deadline = _tenantUtil.DateTimeToUtc(newTask.DeadLine), ResponsibleId = newTask.ResponsibleID, ContactId = newTask.ContactID, EntityType = newTask.EntityType, @@ -946,21 +866,21 @@ private int SaveTaskInDb(Task newTask) TenantId = TenantID }; - CRMDbContext.Tasks.Add(dbTask); + CrmDbContext.Tasks.Add(dbTask); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); newTask.ID = dbTask.Id; - FactoryIndexer.Index(dbTask); + _factoryIndexer.Index(dbTask); return newTask.ID; } - public virtual int[] SaveTaskList(List items) + public int[] SaveTaskList(List items) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); var result = new List(); @@ -969,27 +889,26 @@ public virtual int[] SaveTaskList(List items) result.Add(SaveTaskInDb(item)); } - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); tx.Commit(); return result.ToArray(); } - - public virtual void DeleteTask(int taskID) + public void DeleteTask(int taskID) { var task = GetByID(taskID); if (task == null) return; - CRMSecurity.DemandEdit(task); + _crmSecurity.DemandEdit(task); - var dbTask = Query(CRMDbContext.Tasks).Where(x => x.Id == taskID).Single(); + var dbTask = Query(CrmDbContext.Tasks).Where(x => x.Id == taskID).Single(); - FactoryIndexer.Delete(dbTask); + _factoryIndexer.Delete(dbTask); - CRMDbContext.Tasks.Remove(new DbTask { Id = taskID }); + CrmDbContext.Tasks.Remove(new DbTask { Id = taskID }); _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); @@ -1001,7 +920,7 @@ public List CreateByTemplate(List templateItems, EntityType var result = new List(); - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); foreach (var templateItem in templateItems) { @@ -1009,10 +928,10 @@ public List CreateByTemplate(List templateItems, EntityType { ResponsibleID = templateItem.ResponsibleID, Description = templateItem.Description, - DeadLine = TenantUtil.DateTimeNow().AddTicks(templateItem.Offset.Ticks), + DeadLine = _tenantUtil.DateTimeNow().AddTicks(templateItem.Offset.Ticks), CategoryID = templateItem.CategoryID, Title = templateItem.Title, - CreateOn = TenantUtil.DateTimeNow(), + CreateOn = _tenantUtil.DateTimeNow(), CreateBy = templateItem.CreateBy }; @@ -1039,7 +958,7 @@ public List CreateByTemplate(List templateItems, EntityType result.Add(task); - CRMDbContext.TaskTemplateTask.Add(new DbTaskTemplateTask + CrmDbContext.TaskTemplateTask.Add(new DbTaskTemplateTask { TaskId = task.ID, TaskTemplateId = templateItem.ID, @@ -1049,7 +968,7 @@ public List CreateByTemplate(List templateItems, EntityType tx.Commit(); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); return result; } @@ -1138,12 +1057,12 @@ public void SetTaskCreationDate(int taskId, DateTime creationDate) DbTask entity = new DbTask() { Id = taskId, - CreateOn = TenantUtil.DateTimeToUtc(creationDate) + CreateOn = _tenantUtil.DateTimeToUtc(creationDate) }; - CRMDbContext.Tasks.Update(entity); + CrmDbContext.Tasks.Update(entity); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); @@ -1159,12 +1078,12 @@ public void SetTaskLastModifedDate(int taskId, DateTime lastModifedDate) DbTask entity = new DbTask() { Id = taskId, - LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate) + LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate) }; - CRMDbContext.Tasks.Update(entity); + CrmDbContext.Tasks.Update(entity); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 9d186b838c3..b7ce9f3fd0a 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -78,20 +78,20 @@ public virtual int SaveOrUpdate(TaskTemplateContainer item) TenantId = TenantID }; - if (item.ID == 0 && Query(CRMDbContext.TaskTemplateContainer).Where(x => x.Id == item.ID).Any()) + if (item.ID == 0 && Query(CrmDbContext.TaskTemplateContainer).Where(x => x.Id == item.ID).Any()) { - CRMDbContext.TaskTemplateContainer.Add(dbTaskTemplateContainer); + CrmDbContext.TaskTemplateContainer.Add(dbTaskTemplateContainer); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); item.ID = dbTaskTemplateContainer.Id; } else { - CRMDbContext.TaskTemplateContainer.Attach(dbTaskTemplateContainer); - CRMDbContext.TaskTemplateContainer.Update(dbTaskTemplateContainer); + CrmDbContext.TaskTemplateContainer.Attach(dbTaskTemplateContainer); + CrmDbContext.TaskTemplateContainer.Update(dbTaskTemplateContainer); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } @@ -105,10 +105,10 @@ public virtual void Delete(int id) var itemToDelete = new DbTaskTemplateContainer { Id = id }; - CRMDbContext.TaskTemplateContainer.Attach(itemToDelete); - CRMDbContext.TaskTemplateContainer.Remove(itemToDelete); + CrmDbContext.TaskTemplateContainer.Attach(itemToDelete); + CrmDbContext.TaskTemplateContainer.Remove(itemToDelete); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } public virtual TaskTemplateContainer GetByID(int id) @@ -116,7 +116,7 @@ public virtual TaskTemplateContainer GetByID(int id) if (id <= 0) throw new ArgumentException(); - return ToObject(Query(CRMDbContext.TaskTemplateContainer).FirstOrDefault(x => x.Id == id)); + return ToObject(Query(CrmDbContext.TaskTemplateContainer).FirstOrDefault(x => x.Id == id)); } public virtual List GetItems(EntityType entityType) @@ -124,7 +124,7 @@ public virtual List GetItems(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException("", entityType.ToString()); - return Query(CRMDbContext.TaskTemplateContainer) + return Query(CrmDbContext.TaskTemplateContainer) .Where(x => x.EntityType == entityType) .ToList() .ConvertAll(ToObject); @@ -185,8 +185,8 @@ public int SaveOrUpdate(TaskTemplate item) itemToInsert.CreateOn = DateTime.UtcNow; itemToInsert.CreateBy = _securityContext.CurrentAccount.ID; - CRMDbContext.TaskTemplates.Add(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.TaskTemplates.Add(itemToInsert); + CrmDbContext.SaveChanges(); } else { @@ -194,10 +194,10 @@ public int SaveOrUpdate(TaskTemplate item) itemToInsert.LastModifedOn = DateTime.UtcNow; itemToInsert.LastModifedBy = _securityContext.CurrentAccount.ID; - CRMDbContext.TaskTemplates.Attach(itemToInsert); - CRMDbContext.TaskTemplates.Update(itemToInsert); + CrmDbContext.TaskTemplates.Attach(itemToInsert); + CrmDbContext.TaskTemplates.Update(itemToInsert); - CRMDbContext.SaveChanges(); + CrmDbContext.SaveChanges(); } return item.ID; @@ -205,10 +205,10 @@ public int SaveOrUpdate(TaskTemplate item) public TaskTemplate GetNext(int taskID) { - using var tx = CRMDbContext.Database.BeginTransaction(); + using var tx = CrmDbContext.Database.BeginTransaction(); - var sqlResult = Query(CRMDbContext.TaskTemplateTask) - .Join(Query(CRMDbContext.TaskTemplates), + var sqlResult = Query(CrmDbContext.TaskTemplateTask) + .Join(Query(CrmDbContext.TaskTemplates), x => x.TaskTemplateId, y => y.Id, (x, y) => new { x, y } @@ -218,11 +218,11 @@ public TaskTemplate GetNext(int taskID) if (sqlResult == null) return null; - var result = ToObject(Query(CRMDbContext.TaskTemplates) + var result = ToObject(Query(CrmDbContext.TaskTemplates) .FirstOrDefault(x => x.ContainerId == sqlResult.ContainerId && x.SortOrder > sqlResult.SortOrder && !x.DeadLineIsFixed)); - CRMDbContext.Remove(new DbTaskTemplateTask + CrmDbContext.Remove(new DbTaskTemplateTask { TaskId = taskID, TenantId = TenantID @@ -235,7 +235,7 @@ public TaskTemplate GetNext(int taskID) public List GetAll() { - return Query(CRMDbContext.TaskTemplates) + return Query(CrmDbContext.TaskTemplates) .OrderBy(x => x.SortOrder) .ToList() .ConvertAll(ToObject); @@ -246,7 +246,7 @@ public List GetList(int containerID) if (containerID <= 0) throw new NotImplementedException(); - return Query(CRMDbContext.TaskTemplates) + return Query(CrmDbContext.TaskTemplates) .Where(x => x.ContainerId == containerID) .OrderBy(x => x.SortOrder) .ToList() @@ -258,7 +258,7 @@ public virtual TaskTemplate GetByID(int id) if (id <= 0) throw new NotImplementedException(); - return ToObject(CRMDbContext.TaskTemplates.FirstOrDefault(x => x.Id == id)); + return ToObject(CrmDbContext.TaskTemplates.FirstOrDefault(x => x.Id == id)); } public virtual void Delete(int id) @@ -271,8 +271,8 @@ public virtual void Delete(int id) Id = id }; - CRMDbContext.Entry(itemToRemove).State = EntityState.Deleted; - CRMDbContext.SaveChanges(); + CrmDbContext.Entry(itemToRemove).State = EntityState.Deleted; + CrmDbContext.SaveChanges(); } protected TaskTemplate ToObject(DbTaskTemplate dbTaskTemplate) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs index de72fbb78f0..0e5ab011b00 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs @@ -66,7 +66,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = casesDao.CRMDbContext.Cases + var q = casesDao.CrmDbContext.Cases .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -77,7 +77,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - casesDao.CRMDbContext.Cases + casesDao.CrmDbContext.Cases .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs index eb7922fcdef..fada7227b39 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs @@ -66,7 +66,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = contactDao.CRMDbContext.Contacts + var q = contactDao.CrmDbContext.Contacts .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -77,7 +77,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - contactDao.CRMDbContext.Contacts + contactDao.CrmDbContext.Contacts .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs index 433240e72a3..56026e851b3 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs @@ -66,7 +66,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = contactInfoDao.CRMDbContext.ContactsInfo + var q = contactInfoDao.CrmDbContext.ContactsInfo .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -77,7 +77,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - contactInfoDao.CRMDbContext.ContactsInfo + contactInfoDao.CrmDbContext.ContactsInfo .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs index 93fe4867691..a8a7044bf3e 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs @@ -40,7 +40,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = dealDao.CRMDbContext.ContactsInfo + var q = dealDao.CrmDbContext.ContactsInfo .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -51,7 +51,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - dealDao.CRMDbContext.Deals + dealDao.CrmDbContext.Deals .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs index 7597932b76b..761496dedf3 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs @@ -65,7 +65,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = eventsDao.CRMDbContext.RelationshipEvent + var q = eventsDao.CrmDbContext.RelationshipEvent .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -76,7 +76,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - eventsDao.CRMDbContext.RelationshipEvent + eventsDao.CrmDbContext.RelationshipEvent .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs index 9639f5c2f49..b5134374b92 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs @@ -66,7 +66,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = fieldValueDao.CRMDbContext.FieldValue + var q = fieldValueDao.CrmDbContext.FieldValue .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -77,7 +77,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - fieldValueDao.CRMDbContext.FieldValue + fieldValueDao.CrmDbContext.FieldValue .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs index f7ee6cfd6ea..6f961fe288f 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs @@ -66,7 +66,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = invoiceDao.CRMDbContext.Invoices + var q = invoiceDao.CrmDbContext.Invoices .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -77,7 +77,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - invoiceDao.CRMDbContext.Invoices + invoiceDao.CrmDbContext.Invoices .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs index b1dd5e6169c..97d8d2c08d9 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs @@ -66,7 +66,7 @@ public override void IndexAll() (int, int, int) getCount(DateTime lastIndexed) { - var q = taskDao.CRMDbContext.Tasks + var q = taskDao.CrmDbContext.Tasks .Where(r => r.LastModifedOn >= lastIndexed); var count = q.GroupBy(a => a.Id).Count(); @@ -77,7 +77,7 @@ public override void IndexAll() } List getData(long i, long step, DateTime lastIndexed) => - taskDao.CRMDbContext.Tasks + taskDao.CrmDbContext.Tasks .Where(r => r.LastModifedOn >= lastIndexed) .Where(r => r.Id >= i && r.Id <= i + step) .Select(r => r) diff --git a/products/ASC.CRM/Server/Middlewares/ContactPhotoHandler.cs b/products/ASC.CRM/Server/Middlewares/ContactPhotoHandlerMiddleware.cs similarity index 100% rename from products/ASC.CRM/Server/Middlewares/ContactPhotoHandler.cs rename to products/ASC.CRM/Server/Middlewares/ContactPhotoHandlerMiddleware.cs diff --git a/products/ASC.CRM/Server/Middlewares/FileHandler.cs b/products/ASC.CRM/Server/Middlewares/FileHandlerMiddleware.cs similarity index 100% rename from products/ASC.CRM/Server/Middlewares/FileHandler.cs rename to products/ASC.CRM/Server/Middlewares/FileHandlerMiddleware.cs diff --git a/products/ASC.CRM/Server/Middlewares/FileUploaderHandler.cs b/products/ASC.CRM/Server/Middlewares/FileUploaderHandlerMiddleware.cs similarity index 100% rename from products/ASC.CRM/Server/Middlewares/FileUploaderHandler.cs rename to products/ASC.CRM/Server/Middlewares/FileUploaderHandlerMiddleware.cs diff --git a/products/ASC.CRM/Server/Middlewares/ImportFileHandler.cs b/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs similarity index 100% rename from products/ASC.CRM/Server/Middlewares/ImportFileHandler.cs rename to products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs diff --git a/products/ASC.CRM/Server/Middlewares/OrganisationLogoHandler.cs b/products/ASC.CRM/Server/Middlewares/OrganisationLogoHandlerMiddleware.cs similarity index 100% rename from products/ASC.CRM/Server/Middlewares/OrganisationLogoHandler.cs rename to products/ASC.CRM/Server/Middlewares/OrganisationLogoHandlerMiddleware.cs diff --git a/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandler.cs b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs similarity index 100% rename from products/ASC.CRM/Server/Middlewares/WebToLeadFromHandler.cs rename to products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs From d85f6c0c1c49d4bd5c636b839fd9b7626296684d Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 12 May 2021 20:58:22 +0300 Subject: [PATCH 48/61] crm:refactoring --- .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 14 +- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 142 ++++----- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 295 +++++++++--------- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 36 +-- .../Server/Core/Dao/CurrencyInfoDao.cs | 12 +- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 14 +- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 81 +++-- products/ASC.CRM/Server/Core/Dao/FileDao.cs | 16 +- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 22 +- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 14 +- .../Server/Core/Dao/RelationshipEventDao.cs | 77 ++--- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 3 + products/ASC.CRM/Server/Core/Dao/TaskDao.cs | 272 ++++++---------- .../Server/Core/Security/CRMSecutiry.cs | 189 ++++++----- 14 files changed, 522 insertions(+), 665 deletions(-) diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index 708bc002f02..885ee98e159 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -65,7 +65,9 @@ IMapper mapper _logger = logger.Get("ASC.CRM"); _cache = ascCache; + CrmDbContext = dbContextManager.Get(CrmConstants.DatabaseId); + TenantID = tenantManager.GetCurrentTenant().TenantId; _securityContext = securityContext; @@ -199,12 +201,14 @@ protected void SetRelative(int[] contactID, EntityType entityType, int entityID) protected void SetRelative(int contactID, EntityType entityType, int entityID) { - CrmDbContext.EntityContact.Add(new DbEntityContact + var dbEntity = new DbEntityContact { ContactId = contactID, EntityType = entityType, EntityId = entityID - }); + }; + + CrmDbContext.EntityContact.Add(dbEntity); CrmDbContext.SaveChanges(); } @@ -248,18 +252,18 @@ protected void RemoveRelative(int contactID, EntityType entityType, int entityID public int SaveOrganisationLogo(byte[] bytes) { - var entity = new DbOrganisationLogo + var dbEntity = new DbOrganisationLogo { Content = Convert.ToBase64String(bytes), CreateOn = DateTime.UtcNow, CreateBy = _securityContext.CurrentAccount.ID.ToString() }; - CrmDbContext.OrganisationLogo.Add(entity); + CrmDbContext.OrganisationLogo.Add(dbEntity); CrmDbContext.SaveChanges(); - return entity.Id; + return dbEntity.Id; } public string GetOrganisationLogoBase64(int logo_id) diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 153878120fe..5ca6d93ce07 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -57,6 +57,12 @@ namespace ASC.CRM.Core.Dao [Scope] public class CasesDao : AbstractDao { + private readonly BundleSearch _bundleSearch; + private readonly AuthorizationManager _authorizationManager; + private readonly FilesIntegration _filesIntegration; + private readonly TenantUtil _tenantUtil; + private readonly CrmSecurity _crmSecurity; + public CasesDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -77,28 +83,17 @@ IMapper mapper ascCache, mapper) { - CRMSecurity = crmSecurity; - TenantUtil = tenantUtil; - FilesIntegration = filesIntegration; - AuthorizationManager = authorizationManager; - BundleSearch = bundleSearch; + _crmSecurity = crmSecurity; + _tenantUtil = tenantUtil; + _filesIntegration = filesIntegration; + _authorizationManager = authorizationManager; + _bundleSearch = bundleSearch; } - public BundleSearch BundleSearch { get; } - - public AuthorizationManager AuthorizationManager { get; } - - public FilesIntegration FilesIntegration { get; } - - public TenantUtil TenantUtil { get; } - - public CrmSecurity CRMSecurity { get; } - public void AddMember(int caseID, int memberID) { SetRelative(memberID, EntityType.Case, caseID); } - public Dictionary GetMembers(int[] caseID) { return GetRelativeToEntity(null, EntityType.Case, caseID); @@ -133,64 +128,46 @@ public int[] SaveCasesList(List items) return result; } - public Cases CloseCases(int caseID) + public Cases CloseCases(int id) { - if (caseID <= 0) throw new ArgumentException(); + var dbEntity = CrmDbContext.Cases.Find(id); - var cases = GetByID(caseID); + if (dbEntity == null) + throw new ArgumentException(); - if (cases == null) return null; + var entity = _mapper.Map(dbEntity); - CRMSecurity.DemandAccessTo(cases); + if (dbEntity.IsClosed) return entity; + if (dbEntity.TenantId != TenantID) return null; - var itemToUpdate = new DbCase - { - Id = cases.ID, - CreateBy = cases.CreateBy, - CreateOn = cases.CreateOn, - IsClosed = true, - LastModifedBy = cases.LastModifedBy, - LastModifedOn = cases.LastModifedOn, - TenantId = TenantID, - Title = cases.Title - }; + _crmSecurity.DemandEdit(entity); - CrmDbContext.Cases.Update(itemToUpdate); + dbEntity.IsClosed = true; CrmDbContext.SaveChanges(); - cases.IsClosed = true; - - return cases; + return entity; } - public Cases ReOpenCases(int caseID) + public Cases ReOpenCases(int id) { - if (caseID <= 0) throw new ArgumentException(); + var dbEntity = CrmDbContext.Cases.Find(id); + + if (dbEntity == null) + throw new ArgumentException(); - var cases = GetByID(caseID); + var entity = _mapper.Map(dbEntity); - if (cases == null) return null; + if (!dbEntity.IsClosed) return entity; + if (dbEntity.TenantId != TenantID) return null; - CRMSecurity.DemandAccessTo(cases); + _crmSecurity.DemandEdit(entity); - CrmDbContext.Cases.Update(new DbCase - { - Id = cases.ID, - CreateBy = cases.CreateBy, - CreateOn = cases.CreateOn, - IsClosed = false, - LastModifedBy = cases.LastModifedBy, - LastModifedOn = cases.LastModifedOn, - TenantId = TenantID, - Title = cases.Title - }); + dbEntity.IsClosed = false; CrmDbContext.SaveChanges(); - cases.IsClosed = false; - - return cases; + return entity; } public int CreateCases(String title) @@ -208,9 +185,9 @@ private int CreateCasesInDb(String title) { Title = title, IsClosed = false, - CreateOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + CreateOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), CreateBy = _securityContext.CurrentAccount.ID, - LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -225,7 +202,7 @@ private int CreateCasesInDb(String title) public void UpdateCases(Cases cases) { - CRMSecurity.DemandEdit(cases); + _crmSecurity.DemandEdit(cases); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -235,7 +212,7 @@ public void UpdateCases(Cases cases) Id = cases.ID, Title = cases.Title, IsClosed = cases.IsClosed, - LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID, CreateBy = cases.CreateBy, @@ -253,7 +230,7 @@ public Cases DeleteCases(int casesID) if (cases == null) return null; - CRMSecurity.DemandDelete(cases); + _crmSecurity.DemandDelete(cases); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "invoice.*")); @@ -264,7 +241,7 @@ public Cases DeleteCases(int casesID) public List DeleteBatchCases(List caseses) { - caseses = caseses.FindAll(CRMSecurity.CanDelete).ToList(); + caseses = caseses.FindAll(_crmSecurity.CanDelete).ToList(); if (!caseses.Any()) return caseses; @@ -280,7 +257,7 @@ public List DeleteBatchCases(int[] casesID) { if (casesID == null || !casesID.Any()) return null; - var cases = GetCases(casesID).FindAll(CRMSecurity.CanDelete).ToList(); + var cases = GetCases(casesID).FindAll(_crmSecurity.CanDelete).ToList(); if (!cases.Any()) return cases; @@ -296,7 +273,7 @@ private void DeleteBatchCasesExecute(List caseses) { var casesID = caseses.Select(x => x.ID).ToArray(); - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); var tagNames = Query(CrmDbContext.RelationshipEvent) .Where(x => x.HaveFiles && casesID.Contains(x.EntityId) && x.EntityType == EntityType.Case) @@ -326,11 +303,11 @@ private void DeleteBatchCasesExecute(List caseses) tx.Commit(); - caseses.ForEach(item => AuthorizationManager.RemoveAllAces(item)); + caseses.ForEach(item => _authorizationManager.RemoveAllAces(item)); if (0 < tagNames.Length) { - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); foreach (var filesID in filesIDs) { @@ -381,7 +358,7 @@ public int GetCasesCount( (tags == null || !tags.Any())); - var exceptIDs = CRMSecurity.GetPrivateItems(typeof(Cases)).ToList(); + var exceptIDs = _crmSecurity.GetPrivateItems(typeof(Cases)).ToList(); int result; @@ -429,7 +406,7 @@ private IQueryable GetDbCasesByFilters( IEnumerable tags) { - var result = Query(CrmDbContext.Cases); + var result = Query(CrmDbContext.Cases).AsNoTracking(); var ids = new List(); @@ -442,7 +419,7 @@ private IQueryable GetDbCasesByFilters( if (keywords.Length > 0) { - if (!BundleSearch.TrySelectCase(searchText, out ids)) + if (!_bundleSearch.TrySelectCase(searchText, out ids)) { foreach (var k in keywords) { @@ -507,10 +484,11 @@ public List GetCases(IEnumerable casesID) var result = Query(CrmDbContext.Cases) .Where(x => casesID.Contains(x.Id)) + .AsNoTracking() .ToList(); return _mapper.Map, List>(result) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } public List GetCases( @@ -522,7 +500,7 @@ public List GetCases( int count, OrderBy orderBy) { - var dbCasesQuery = GetDbCasesByFilters(CRMSecurity.GetPrivateItems(typeof(Cases)).ToList(), searchText, + var dbCasesQuery = GetDbCasesByFilters(_crmSecurity.GetPrivateItems(typeof(Cases)).ToList(), searchText, contactID, isClosed, tags); @@ -561,7 +539,7 @@ public List GetCasesByPrefix(String prefix, int from, int count) var keywords = prefix.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); - var q = Query(CrmDbContext.Cases); + var q = Query(CrmDbContext.Cases).AsNoTracking(); if (keywords.Length == 1) { @@ -581,27 +559,31 @@ public List GetCasesByPrefix(String prefix, int from, int count) q = q.OrderBy(x => x.Title); return _mapper.Map, List>(q.ToList()) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } public List GetByID(int[] ids) { - var result = CrmDbContext.Cases + var result = Query(CrmDbContext.Cases) .Where(x => ids.Contains(x.Id)) + .AsNoTracking() .ToList(); - return _mapper.Map, List>(result); } public Cases GetByID(int id) - { - if (id <= 0) return null; +{ + var dbEntity = CrmDbContext.Cases.Find(id); + + if (dbEntity.TenantId != TenantID) return null; + + var entity = _mapper.Map(dbEntity); - var cases = GetByID(new[] { id }); + _crmSecurity.DemandAccessTo(entity); - return cases.Count == 0 ? null : cases[0]; + return _mapper.Map(dbEntity); } public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) @@ -610,14 +592,14 @@ public void ReassignCasesResponsible(Guid fromUserId, Guid toUserId) foreach (var item in cases) { - var responsibles = CRMSecurity.GetAccessSubjectGuidsTo(item); + var responsibles = _crmSecurity.GetAccessSubjectGuidsTo(item); if (!responsibles.Any()) continue; responsibles.Remove(fromUserId); responsibles.Add(toUserId); - CRMSecurity.SetAccessTo(item, responsibles.Distinct().ToList()); + _crmSecurity.SetAccessTo(item, responsibles.Distinct().ToList()); } } } diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 14d91be1155..15c979fc5ec 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -47,16 +47,24 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Core.Dao -{ +{ [Scope] public class ContactDao : AbstractDao { + private readonly BundleSearch _bundleSearch; + private readonly CoreDbContext _coreDbContext; + private readonly FactoryIndexerContact _factoryIndexerContact; + private readonly FactoryIndexerContactInfo _factoryIndexerContactInfo; + private readonly FilesIntegration _filesIntegration; + private readonly AuthorizationManager _authorizationManager; + private readonly TenantUtil _tenantUtil; + private readonly CrmSecurity _crmSecurity; + public ContactDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -77,29 +85,19 @@ IMapper mapper tenantManager, securityContext, logger, - ascCache, + ascCache, mapper) { - CRMSecurity = crmSecurity; - TenantUtil = tenantUtil; - AuthorizationManager = authorizationManager; - FilesIntegration = filesIntegration; - FactoryIndexerContact = factoryIndexerContact; - FactoryIndexerContactInfo = factoryIndexerContactInfo; - CoreDbContext = coreDbContext.Value; - BundleSearch = bundleSearch; - + _crmSecurity = crmSecurity; + _tenantUtil = tenantUtil; + _authorizationManager = authorizationManager; + _filesIntegration = filesIntegration; + _factoryIndexerContact = factoryIndexerContact; + _factoryIndexerContactInfo = factoryIndexerContactInfo; + _coreDbContext = coreDbContext.Value; + _bundleSearch = bundleSearch; } - public BundleSearch BundleSearch { get; } - public CoreDbContext CoreDbContext { get; } - public FactoryIndexerContact FactoryIndexerContact { get; } - public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } - - public FilesIntegration FilesIntegration { get; } - public AuthorizationManager AuthorizationManager { get; } - public TenantUtil TenantUtil { get; } - public CrmSecurity CRMSecurity { get; } private readonly String _displayNameSeparator = "!=!"; @@ -110,7 +108,7 @@ public List GetContactsByPrefix(String prefix, int searchType, int from var keywords = prefix.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); - var sqlQuery = Query(CrmDbContext.Contacts); + var sqlQuery = Query(CrmDbContext.Contacts).AsNoTracking(); switch (searchType) { @@ -135,10 +133,10 @@ public List GetContactsByPrefix(String prefix, int searchType, int from sqlQuery = sqlQuery.OrderBy(x => x.DisplayName); - if (!CRMSecurity.IsAdmin) + if (!_crmSecurity.IsAdmin) { - var idsFromAcl = CoreDbContext.Acl.Where(x => x.Tenant == TenantID && - x.Action == CRMSecurity._actionRead.ID && + var idsFromAcl = _coreDbContext.Acl.Where(x => x.Tenant == TenantID && + x.Action == _crmSecurity._actionRead.ID && x.Subject == _securityContext.CurrentAccount.ID && (Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName + "%") || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Person).FullName + "%"))) @@ -223,7 +221,7 @@ public int GetContactsCount(String searchText, case ContactListViewType.Person: { - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) + excludedContactIDs = _crmSecurity.GetPrivateItems(typeof(Person)) .Except(Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true && !x.IsCompany).Select(x => x.Id)) @@ -234,7 +232,7 @@ public int GetContactsCount(String searchText, } case ContactListViewType.Company: { - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Person)) + excludedContactIDs = _crmSecurity.GetPrivateItems(typeof(Person)) .Except(Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true && x.IsCompany).Select(x => x.Id)) @@ -244,8 +242,8 @@ public int GetContactsCount(String searchText, } default: { - excludedContactIDs = CRMSecurity.GetPrivateItems(typeof(Company)) - .Union(CRMSecurity.GetPrivateItems(typeof(Person))) + excludedContactIDs = _crmSecurity.GetPrivateItems(typeof(Company)) + .Union(_crmSecurity.GetPrivateItems(typeof(Person))) .Except(Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true && x.IsCompany).Select(x => x.Id)) @@ -284,7 +282,7 @@ public int GetContactsCount(String searchText, var resultFakeContactsOldScheme_Count = fakeContactsOldScheme.Where(fc => { - var accessSubjectToContact = CRMSecurity.GetAccessSubjectTo(fc); + var accessSubjectToContact = _crmSecurity.GetAccessSubjectTo(fc); if (isShared.Value == true) { return !accessSubjectToContact.Any(); @@ -310,8 +308,8 @@ public int GetContactsCount(String searchText, var sharedTypes = new[] { ShareType.Read, ShareType.ReadWrite }.ToList(); - var privateCount = CRMSecurity.GetPrivateItemsCount(typeof(Person)) + - CRMSecurity.GetPrivateItemsCount(typeof(Company)) - + var privateCount = _crmSecurity.GetPrivateItemsCount(typeof(Person)) + + _crmSecurity.GetPrivateItemsCount(typeof(Company)) - Query(CrmDbContext.Contacts).Where(x => x.IsShared.HasValue ? sharedTypes.Contains(x.IsShared.Value) : true).Count(); @@ -348,7 +346,7 @@ public List SearchContactsByEmail(string searchText, int maxCount) IReadOnlyCollection dbContactInfos; - if (FactoryIndexerContactInfo.TrySelect(s => s.MatchAll(searchText), out dbContactInfos)) + if (_factoryIndexerContactInfo.TrySelect(s => s.MatchAll(searchText), out dbContactInfos)) { if (!dbContactInfos.Any()) return contacts; @@ -356,7 +354,7 @@ public List SearchContactsByEmail(string searchText, int maxCount) ids = dbContactInfos.Select(r => r.Id).ToList(); } - var isAdmin = CRMSecurity.IsAdmin; + var isAdmin = _crmSecurity.IsAdmin; const int count_per_query = 100; @@ -396,7 +394,7 @@ public List SearchContactsByEmail(string searchText, int maxCount) if (maxCount - contacts.Count == 0) return contacts; - if (isAdmin || CRMSecurity.CanAccessTo(partContact)) + if (isAdmin || _crmSecurity.CanAccessTo(partContact)) contacts.Add(partContact); } @@ -423,7 +421,7 @@ public List GetContacts(String searchText, Guid? responsibleId = null, bool? isShared = null) { - if (CRMSecurity.IsAdmin) + if (_crmSecurity.IsAdmin) { if (!isShared.HasValue) { @@ -521,10 +519,10 @@ public List GetContacts(String searchText, if (crudeContacts.Count < from + count) { - return tmp.FindAll(CRMSecurity.CanAccessTo).Skip(from).ToList(); + return tmp.FindAll(_crmSecurity.CanAccessTo).Skip(from).ToList(); } - var result = tmp.FindAll(CRMSecurity.CanAccessTo); + var result = tmp.FindAll(_crmSecurity.CanAccessTo); if (result.Count == crudeContacts.Count) return result.Skip(from).ToList(); @@ -552,7 +550,7 @@ public List GetContacts(String searchText, tmp = isShared.HasValue ? crudeContacts.Where(c => (isShared.Value == true ? c.ShareType != ShareType.None : c.ShareType == ShareType.None)).ToList() : crudeContacts; - result.AddRange(tmp.Where(CRMSecurity.CanAccessTo)); + result.AddRange(tmp.Where(_crmSecurity.CanAccessTo)); if ((result.Count >= count + from) || (crudeContacts.Count < localCount)) break; @@ -600,7 +598,7 @@ private IQueryable GetDbContactsByFilters( bool? isShared = null) { - var sqlQuery = Query(CrmDbContext.Contacts); + var sqlQuery = Query(CrmDbContext.Contacts).AsNoTracking(); var ids = new List(); @@ -609,7 +607,7 @@ private IQueryable GetDbContactsByFilters( if (responsibleid != default(Guid)) { - ids = CRMSecurity.GetContactsIdByManager(responsibleid.Value).ToList(); + ids = _crmSecurity.GetContactsIdByManager(responsibleid.Value).ToList(); if (ids.Count == 0) return null; } else @@ -617,7 +615,7 @@ private IQueryable GetDbContactsByFilters( if (exceptIDs == null) exceptIDs = new List(); - exceptIDs = exceptIDs.Union(CRMSecurity.GetContactsIdByManager(Guid.Empty)).ToList(); + exceptIDs = exceptIDs.Union(_crmSecurity.GetContactsIdByManager(Guid.Empty)).ToList(); if (!exceptIDs.Any()) // HACK exceptIDs.Add(0); @@ -633,7 +631,7 @@ private IQueryable GetDbContactsByFilters( .ToArray(); List contactsIds; - if (!BundleSearch.TrySelectContact(searchText, out contactsIds)) + if (!_bundleSearch.TrySelectContact(searchText, out contactsIds)) { _logger.Debug("FullTextSearch.SupportModule('CRM.Contacts') = false"); @@ -719,15 +717,15 @@ private IQueryable GetDbContactsByFilters( if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); + sqlQuery = sqlQuery.Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); } else if (fromDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate)); + sqlQuery = sqlQuery.Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate)); } else if (toDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.CreateOn <= TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); + sqlQuery = sqlQuery.Where(x => x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); } if (isShared.HasValue) @@ -891,10 +889,12 @@ public List GetContactsByName(String title, bool isCompany) if (isCompany) { - return CrmDbContext.Contacts.Where(x => String.Compare(x.DisplayName, title) == 0 && x.IsCompany) + return Query(CrmDbContext.Contacts) + .AsNoTracking() + .Where(x => String.Compare(x.DisplayName, title) == 0 && x.IsCompany) .ToList() .ConvertAll(ToContact) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } else { @@ -904,17 +904,21 @@ public List GetContactsByName(String title, bool isCompany) { if (titleParts.Length == 1) { - return Query(CrmDbContext.Contacts).Where(x => String.Compare(x.DisplayName, title) == 0 && !x.IsCompany) + return Query(CrmDbContext.Contacts) + .AsNoTracking() + .Where(x => String.Compare(x.DisplayName, title) == 0 && !x.IsCompany) .ToList() .ConvertAll(ToContact) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } else { - return Query(CrmDbContext.Contacts).Where(x => String.Compare(x.DisplayName, String.Concat(titleParts[0], _displayNameSeparator, titleParts[1])) == 0 && !x.IsCompany) + return Query(CrmDbContext.Contacts) + .AsNoTracking() + .Where(x => String.Compare(x.DisplayName, String.Concat(titleParts[0], _displayNameSeparator, titleParts[1])) == 0 && !x.IsCompany) .ToList() .ConvertAll(ToContact) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } } } @@ -928,34 +932,29 @@ public void RemoveMember(int[] peopleID) foreach (var id in peopleID) { - var itemToUpdate = new DbContact - { - Id = id, - CompanyId = 0, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.Contacts.Find(id); - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + if (dbEntity.TenantId != TenantID) continue; + + dbEntity.CompanyId = 0; } CrmDbContext.SaveChanges(); RemoveRelativeInDb(null, EntityType.Person, peopleID); - } public void RemoveMember(int peopleID) { - var itemToUpdate = new DbContact - { - Id = peopleID, - CompanyId = 0, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.Contacts.Find(peopleID); - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + if (dbEntity.TenantId != TenantID) return; + + var entity = _mapper.Map(dbEntity); + + _crmSecurity.DemandEdit(entity); + + dbEntity.CompanyId = 0; CrmDbContext.SaveChanges(); @@ -964,16 +963,15 @@ public void RemoveMember(int peopleID) public void AddMemberInDb(int peopleID, int companyID) { + var dbEntity = CrmDbContext.Contacts.Find(peopleID); - var itemToUpdate = new DbContact - { - Id = peopleID, - CompanyId = companyID, - TenantId = TenantID - }; + if (dbEntity.TenantId != TenantID) return; - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.CompanyId).IsModified = true; + var entity = _mapper.Map(dbEntity); + + _crmSecurity.DemandEdit(entity); + + dbEntity.CompanyId = companyID; CrmDbContext.SaveChanges(); @@ -996,28 +994,24 @@ public void SetMembers(int companyID, params int[] peopleIDs) .RemoveRange(CrmDbContext.EntityContact .Where(x => x.EntityType == EntityType.Person && x.ContactId == companyID)); - var itemsToUpdate = Query(CrmDbContext.Contacts).Where(x => x.CompanyId == companyID).ToList(); + var itemsToUpdate = Query(CrmDbContext.Contacts) + .Where(x => x.CompanyId == companyID).ToList(); itemsToUpdate.ForEach(x => x.CompanyId = 0); - CrmDbContext.UpdateRange(itemsToUpdate); - CrmDbContext.SaveChanges(); if (!(peopleIDs == null || peopleIDs.Length == 0)) { - foreach (var id in peopleIDs) + + foreach(var id in peopleIDs) { - var contactItemToUpdate = new DbContact - { - Id = id, - CompanyId = companyID, - TenantId = TenantID - }; - - CrmDbContext.Attach(contactItemToUpdate); - CrmDbContext.Entry(contactItemToUpdate).Property(x => x.CompanyId).IsModified = true; - CrmDbContext.Update(contactItemToUpdate); + var dbContactEntity = CrmDbContext.Contacts.Find(id); + + if (dbContactEntity.TenantId != TenantID) continue; + + dbContactEntity.CompanyId = companyID; + } CrmDbContext.SaveChanges(); @@ -1130,7 +1124,7 @@ private void UpdateContactFromDb(Contact contact) { var originalContact = GetByID(contact.ID); if (originalContact == null) throw new ArgumentException(); - CRMSecurity.DemandEdit(originalContact); + _crmSecurity.DemandEdit(originalContact); String firstName; String lastName; @@ -1197,7 +1191,7 @@ private void UpdateContactFromDb(Contact contact) itemToUpdate.Industry = contact.Industry; itemToUpdate.StatusId = contact.StatusID; itemToUpdate.CompanyId = companyID; - itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); + itemToUpdate.LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()); itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; itemToUpdate.DisplayName = displayName; itemToUpdate.IsShared = contact.ShareType; @@ -1211,7 +1205,7 @@ private void UpdateContactFromDb(Contact contact) // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); - FactoryIndexerContact.Update(itemToUpdate); + _factoryIndexerContact.Update(itemToUpdate); } public void UpdateContactStatus(IEnumerable contactid, int statusid) @@ -1330,7 +1324,7 @@ public int SaveContact(Contact contact) { var result = SaveContactToDb(contact); - FactoryIndexerContact.Index(Query(CrmDbContext.Contacts) + _factoryIndexerContact.Index(Query(CrmDbContext.Contacts) .Where(x => x.Id == contact.ID).Single()); // Delete relative keys @@ -1409,8 +1403,8 @@ private int SaveContactToDb(Contact contact) StatusId = contact.StatusID, CompanyId = companyID, CreateBy = _securityContext.CurrentAccount.ID, - CreateOn = TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn), - LastModifedOn = TenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : contact.CreateOn), + CreateOn = _tenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? _tenantUtil.DateTimeNow() : contact.CreateOn), + LastModifedOn = _tenantUtil.DateTimeToUtc(contact.CreateOn == DateTime.MinValue ? _tenantUtil.DateTimeNow() : contact.CreateOn), LastModifedBy = _securityContext.CurrentAccount.ID, DisplayName = displayName, IsShared = contact.ShareType, @@ -1482,7 +1476,7 @@ public List GetContacts(int[] contactID) .Where(x => contactID.Contains(x.Id)) .ToList() .ConvertAll(ToContact) - .FindAll(CRMSecurity.CanAccessTo); + .FindAll(_crmSecurity.CanAccessTo); } public List GetRestrictedContacts(int[] contactID) @@ -1493,7 +1487,7 @@ public List GetRestrictedContacts(int[] contactID) .Where(x => contactID.Contains(x.Id)) .ToList() .ConvertAll(ToContact) - .FindAll(cont => !CRMSecurity.CanAccessTo(cont)); + .FindAll(cont => !_crmSecurity.CanAccessTo(cont)); } public List GetRestrictedAndAccessedContacts(int[] contactID) @@ -1510,7 +1504,7 @@ public List DeleteBatchContact(int[] contactID) { if (contactID == null || contactID.Length == 0) return null; - var contacts = GetContacts(contactID).Where(CRMSecurity.CanDelete).ToList(); + var contacts = GetContacts(contactID).Where(_crmSecurity.CanDelete).ToList(); if (!contacts.Any()) return contacts; // Delete relative keys @@ -1523,7 +1517,7 @@ public List DeleteBatchContact(int[] contactID) public List DeleteBatchContact(List contacts) { - contacts = contacts.FindAll(CRMSecurity.CanDelete).ToList(); + contacts = contacts.FindAll(_crmSecurity.CanDelete).ToList(); if (!contacts.Any()) return contacts; // Delete relative keys @@ -1541,9 +1535,9 @@ public Contact DeleteContact(int contactID) var contact = GetByID(contactID); if (contact == null) return null; - CRMSecurity.DemandDelete(contact); + _crmSecurity.DemandDelete(contact); - FactoryIndexerContact.Delete(Query(CrmDbContext.Contacts) + _factoryIndexerContact.Delete(Query(CrmDbContext.Contacts) .Where(x => x.Id == contactID).Single()); DeleteBatchContactsExecute(new List() { contact }); @@ -1575,7 +1569,7 @@ private void DeleteBatchContactsExecute(List contacts) var tx = CrmDbContext.Database.BeginTransaction(); - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); var tagNames = Query(CrmDbContext.RelationshipEvent).Where(x => contactID.Contains(x.ContactId) && x.HaveFiles) .Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray(); @@ -1635,9 +1629,9 @@ private void DeleteBatchContactsExecute(List contacts) tx.Commit(); - contacts.ForEach(contact => AuthorizationManager.RemoveAllAces(contact)); + contacts.ForEach(contact => _authorizationManager.RemoveAllAces(contact)); - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); foreach (var filesID in filesIDs) { @@ -1697,8 +1691,6 @@ public void MergeDublicate(int fromContactID, int toContactID) .ToList(); taskToUpdate.ForEach(x => x.ContactId = toContactID); - - CrmDbContext.UpdateRange(taskToUpdate); CrmDbContext.SaveChanges(); // crm_entity_contact @@ -1712,23 +1704,28 @@ public void MergeDublicate(int fromContactID, int toContactID) .Select(x => x.x)); var entityContactToUpdate = CrmDbContext.EntityContact.Where(x => x.ContactId == fromContactID).ToList(); - entityContactToUpdate.ForEach(x => x.ContactId = toContactID); - CrmDbContext.UpdateRange(entityContactToUpdate); + entityContactToUpdate.ForEach(x => x.ContactId = toContactID); CrmDbContext.SaveChanges(); // crm_deal - var dealsToUpdate = Query(CrmDbContext.Deals).Where(x => x.ContactId == fromContactID).ToList(); + var dealsToUpdate = Query(CrmDbContext.Deals) + .AsNoTracking() + .Where(x => x.ContactId == fromContactID) + .ToList(); + dealsToUpdate.ForEach(x => x.ContactId = toContactID); - CrmDbContext.UpdateRange(dealsToUpdate); CrmDbContext.SaveChanges(); // crm_invoice - var invoicesToUpdate = Query(CrmDbContext.Invoices).Where(x => x.ContactId == fromContactID).ToList(); + var invoicesToUpdate = Query(CrmDbContext.Invoices) + .AsNoTracking() + .Where(x => x.ContactId == fromContactID) + .ToList(); + invoicesToUpdate.ForEach(x => x.ContactId = toContactID); - CrmDbContext.UpdateRange(invoicesToUpdate); CrmDbContext.SaveChanges(); // crm_projects @@ -1743,17 +1740,22 @@ public void MergeDublicate(int fromContactID, int toContactID) CrmDbContext.RemoveRange(Query(CrmDbContext.Projects) .Where(x => x.ContactId == fromContactID && dublicateProjectID.Contains(x.ProjectId))); - var projectsToUpdate = Query(CrmDbContext.Projects).Where(x => x.ContactId == fromContactID).ToList(); + var projectsToUpdate = Query(CrmDbContext.Projects) + .AsNoTracking() + .Where(x => x.ContactId == fromContactID).ToList(); + projectsToUpdate.ForEach(x => x.ContactId = toContactID); - CrmDbContext.UpdateRange(projectsToUpdate); CrmDbContext.SaveChanges(); // crm_relationship_event - var relationshipEventToUpdate = Query(CrmDbContext.RelationshipEvent).Where(x => x.ContactId == fromContactID).ToList(); + var relationshipEventToUpdate = Query(CrmDbContext.RelationshipEvent) + .AsNoTracking() + .Where(x => x.ContactId == fromContactID) + .ToList(); + relationshipEventToUpdate.ForEach(x => x.ContactId = toContactID); - CrmDbContext.UpdateRange(relationshipEventToUpdate); CrmDbContext.SaveChanges(); // crm_entity_tag @@ -1774,7 +1776,6 @@ public void MergeDublicate(int fromContactID, int toContactID) entityTagToUpdate.ForEach(x => x.EntityId = toContactID); - CrmDbContext.UpdateRange(entityTagToUpdate); CrmDbContext.SaveChanges(); // crm_field_value @@ -1791,10 +1792,11 @@ public void MergeDublicate(int fromContactID, int toContactID) dublicateCustomFieldValueID.Contains(x.FieldId))); var fieldValueToUpdate = Query(CrmDbContext.FieldValue) - .Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact).ToList(); - fieldValueToUpdate.ForEach(x => x.EntityId = toContactID); + .AsNoTracking() + .Where(x => x.EntityId == fromContactID && x.EntityType == EntityType.Contact) + .ToList(); - CrmDbContext.UpdateRange(fieldValueToUpdate); + fieldValueToUpdate.ForEach(x => x.EntityId = toContactID); CrmDbContext.SaveChanges(); // crm_contact_info @@ -1815,7 +1817,6 @@ public void MergeDublicate(int fromContactID, int toContactID) contactInfosToUpdate.ForEach(x => x.IsPrimary = false); - CrmDbContext.UpdateRange(fieldValueToUpdate); CrmDbContext.SaveChanges(); var dublicateContactInfoID = Query(CrmDbContext.ContactsInfo) @@ -1836,10 +1837,12 @@ public void MergeDublicate(int fromContactID, int toContactID) CrmDbContext.SaveChanges(); - var contactInfoToUpdate = Query(CrmDbContext.ContactsInfo).Where(x => x.ContactId == fromContactID).ToList(); + var contactInfoToUpdate = Query(CrmDbContext.ContactsInfo) + .Where(x => x.ContactId == fromContactID) + .ToList(); + contactInfoToUpdate.ForEach(x => x.ContactId = toContactID); - CrmDbContext.UpdateRange(contactInfoToUpdate); CrmDbContext.SaveChanges(); MergeContactInfo(fromContact, toContact); @@ -1847,11 +1850,12 @@ public void MergeDublicate(int fromContactID, int toContactID) // crm_contact if ((fromContact is Company) && (toContact is Company)) { - var contactsToUpdate = Query(CrmDbContext.Contacts).Where(x => x.CompanyId == fromContactID).ToList(); + var contactsToUpdate = Query(CrmDbContext.Contacts) + .Where(x => x.CompanyId == fromContactID) + .ToList(); contactsToUpdate.ForEach(x => x.CompanyId = toContactID); - CrmDbContext.UpdateRange(contactsToUpdate); CrmDbContext.SaveChanges(); } @@ -1866,7 +1870,7 @@ public void MergeDublicate(int fromContactID, int toContactID) tx.Commit(); } - AuthorizationManager.RemoveAllAces(fromContact); + _authorizationManager.RemoveAllAces(fromContact); } public List GetContactIDsByCompanyIds(List companyIDs) @@ -1927,14 +1931,14 @@ protected Contact ToContact(DbContact dbContact) contact.About = dbContact.Notes; contact.Industry = dbContact.Industry; contact.StatusID = dbContact.StatusId; - contact.CreateOn = TenantUtil.DateTimeFromUtc(dbContact.CreateOn); + contact.CreateOn = _tenantUtil.DateTimeFromUtc(dbContact.CreateOn); contact.CreateBy = dbContact.CreateBy; contact.ContactTypeID = dbContact.ContactTypeId; contact.Currency = dbContact.Currency; if (dbContact.IsShared == null) { - var accessSubjectToContact = CRMSecurity.GetAccessSubjectTo(contact); + var accessSubjectToContact = _crmSecurity.GetAccessSubjectTo(contact); contact.ShareType = !accessSubjectToContact.Any() ? ShareType.ReadWrite : ShareType.None; } @@ -1948,7 +1952,7 @@ protected Contact ToContact(DbContact dbContact) public void ReassignContactsResponsible(Guid fromUserId, Guid toUserId) { - var ids = CRMSecurity.GetContactsIdByManager(fromUserId).ToList(); + var ids = _crmSecurity.GetContactsIdByManager(fromUserId).ToList(); foreach (var id in ids) { @@ -1956,14 +1960,14 @@ public void ReassignContactsResponsible(Guid fromUserId, Guid toUserId) if (contact == null) continue; - var responsibles = CRMSecurity.GetAccessSubjectGuidsTo(contact); + var responsibles = _crmSecurity.GetAccessSubjectGuidsTo(contact); if (!responsibles.Any()) continue; responsibles.Remove(fromUserId); responsibles.Add(toUserId); - CRMSecurity.SetAccessTo(contact, responsibles.Distinct().ToList()); + _crmSecurity.SetAccessTo(contact, responsibles.Distinct().ToList()); } } @@ -1973,17 +1977,12 @@ public void ReassignContactsResponsible(Guid fromUserId, Guid toUserId) /// /// /// - public void SetContactCreationDate(int contactId, DateTime creationDate) + public void SetContactCreationDate(int id, DateTime creationDate) { - var itemToUpdate = new DbContact - { - Id = contactId, - TenantId = TenantID, - CreateOn = TenantUtil.DateTimeToUtc(creationDate) - }; + var entity = CrmDbContext.Contacts.Find(id); + + entity.CreateOn = _tenantUtil.DateTimeToUtc(creationDate); - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.CreateOn).IsModified = true; CrmDbContext.SaveChanges(); // Delete relative keys @@ -1995,18 +1994,12 @@ public void SetContactCreationDate(int contactId, DateTime creationDate) /// /// /// - public void SetContactLastModifedDate(int contactId, DateTime lastModifedDate) + public void SetContactLastModifedDate(int id, DateTime lastModifedDate) { + var entity = CrmDbContext.Contacts.Find(id); - var itemToUpdate = new DbContact - { - Id = contactId, - TenantId = TenantID, - LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate) - }; + entity.LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate); - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.LastModifedOn).IsModified = true; CrmDbContext.SaveChanges(); // Delete relative keys diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 6482347394f..8cbab23b828 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -49,6 +49,9 @@ namespace ASC.CRM.Core.Dao [Scope] public class ContactInfoDao : AbstractDao { + private TenantUtil _tenantUtil; + private FactoryIndexerContactInfo _factoryIndexerContactInfo; + public ContactInfoDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -57,7 +60,6 @@ public ContactInfoDao( IOptionsMonitor logger, ICache ascCache, FactoryIndexerContactInfo factoryIndexerContactInfo, - IServiceProvider serviceProvider, IMapper mapper) : base(dbContextManager, tenantManager, @@ -66,21 +68,15 @@ public ContactInfoDao( ascCache, mapper) { - TenantUtil = tenantUtil; - ServiceProvider = serviceProvider; - - FactoryIndexerContactInfo = factoryIndexerContactInfo; + _tenantUtil = tenantUtil; + _factoryIndexerContactInfo = factoryIndexerContactInfo; } - public IServiceProvider ServiceProvider { get; } - public TenantUtil TenantUtil { get; } - public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } - public ContactInfo GetByID(int id) { - var dbContactInfo = CrmDbContext.ContactsInfo.SingleOrDefault(x => x.Id == id); - - return _mapper.Map(dbContactInfo); + var dbEntity = CrmDbContext.ContactsInfo.Find(id); + + return _mapper.Map(dbEntity); } public void Delete(int id) @@ -93,7 +89,7 @@ public void Delete(int id) CrmDbContext.ContactsInfo.Remove(itemToDelete); CrmDbContext.SaveChanges(); - FactoryIndexerContactInfo.Delete(r => r.Where(a => a.Id, id)); + _factoryIndexerContactInfo.Delete(r => r.Where(a => a.Id, id)); } public void DeleteByContact(int contactID) @@ -105,14 +101,14 @@ public void DeleteByContact(int contactID) CrmDbContext.SaveChanges(); - FactoryIndexerContactInfo.Delete(r => r.Where(a => a.ContactId, contactID)); + _factoryIndexerContactInfo.Delete(r => r.Where(a => a.ContactId, contactID)); } public int Update(ContactInfo contactInfo) { var result = UpdateInDb(contactInfo); - FactoryIndexerContactInfo.Update(Query(CrmDbContext.ContactsInfo) + _factoryIndexerContactInfo.Update(Query(CrmDbContext.ContactsInfo) .Where(x => x.ContactId == contactInfo.ID).Single()); return result; @@ -131,7 +127,7 @@ private int UpdateInDb(ContactInfo contactInfo) IsPrimary = contactInfo.IsPrimary, ContactId = contactInfo.ContactID, Type = contactInfo.InfoType, - LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -154,7 +150,7 @@ public int Save(ContactInfo contactInfo) .Where(x => x.ContactId == contactInfo.ID) .Single(); - FactoryIndexerContactInfo.Index(dbContactInfo); + _factoryIndexerContactInfo.Index(dbContactInfo); return id; } @@ -168,7 +164,7 @@ private int SaveInDb(ContactInfo contactInfo) IsPrimary = contactInfo.IsPrimary, ContactId = contactInfo.ContactID, Type = contactInfo.InfoType, - LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()), + LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()), LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID @@ -247,7 +243,7 @@ public int[] UpdateList(List items, Contact contact = null) foreach (var dbContactInfo in dbContactInfos) { - FactoryIndexerContactInfo.Index(dbContactInfo); + _factoryIndexerContactInfo.Index(dbContactInfo); } } @@ -280,7 +276,7 @@ public int[] SaveList(List items, Contact contact = null) foreach (var dbContactInfo in dbContactInfos) { - FactoryIndexerContactInfo.Index(dbContactInfo); + _factoryIndexerContactInfo.Index(dbContactInfo); } } diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index 43359f86b94..b620881e27e 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -37,6 +37,7 @@ using AutoMapper; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -63,17 +64,18 @@ public CurrencyInfoDao(DbContextManager dbContextManager, public List GetAll() { - var dbItems = CrmDbContext.CurrencyInfo.ToList(); + var dbEntities = CrmDbContext.CurrencyInfo + .AsNoTracking() + .ToList(); - return _mapper.Map, List>(dbItems); + return _mapper.Map, List>(dbEntities); } public CurrencyInfo GetByAbbreviation(string abbreviation) { - var dbItem = CrmDbContext.CurrencyInfo - .FirstOrDefault(x => String.Compare(x.Abbreviation, abbreviation, true) == 0); + var dbEntity = CrmDbContext.CurrencyInfo.Find(abbreviation); - return _mapper.Map(dbItem); + return _mapper.Map(dbEntity); } diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 597c42429e1..55b55e48ab4 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -53,6 +53,9 @@ namespace ASC.CRM.Core.Dao [Scope] public class CustomFieldDao : AbstractDao { + + private TenantUtil _tenantUtil; + private FactoryIndexerFieldValue _factoryIndexer; public CustomFieldDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -69,12 +72,9 @@ IMapper mapper ascCache, mapper) { - TenantUtil = tenantUtil; + _tenantUtil = tenantUtil; } - public TenantUtil TenantUtil { get; } - - public FactoryIndexerFieldValue FactoryIndexer { get; } public void SaveList(List items) { @@ -115,7 +115,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, if (!String.IsNullOrEmpty(fieldValue)) { - var lastModifiedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); + var lastModifiedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()); var dbFieldValue = new DbFieldValue { @@ -133,7 +133,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, var id = dbFieldValue.Id; - FactoryIndexer.Index(dbFieldValue); + _factoryIndexer.Index(dbFieldValue); } } @@ -551,7 +551,7 @@ public void DeleteField(int fieldID) var fieldValue = Query(CrmDbContext.FieldValue).FirstOrDefault(x => x.FieldId == fieldID); - FactoryIndexer.Delete(fieldValue); + _factoryIndexer.Delete(fieldValue); CrmDbContext.Remove(fieldValue); diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 48588444986..d867fa0b81c 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -58,6 +58,13 @@ namespace ASC.CRM.Core.Dao [Scope] public class DealDao : AbstractDao { + private BundleSearch _bundleSearch; + private FilesIntegration _filesIntegration; + private FactoryIndexerDeal _factoryIndexer; + private TenantUtil _tenantUtil; + private CrmSecurity _crmSecurity; + private AuthorizationManager _authorizationManager; + public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -75,23 +82,13 @@ public DealDao(DbContextManager dbContextManager, ascCache, mapper) { - CRMSecurity = crmSecurity; - FactoryIndexer = factoryIndexer; - FilesIntegration = filesIntegration; - BundleSearch = bundleSearch; + _crmSecurity = crmSecurity; + _factoryIndexer = factoryIndexer; + _filesIntegration = filesIntegration; + _bundleSearch = bundleSearch; _mapper = mapper; } - public BundleSearch BundleSearch { get; } - - public FilesIntegration FilesIntegration { get; } - - public FactoryIndexerDeal FactoryIndexer { get; } - - public TenantUtil TenantUtil { get; } - public CrmSecurity CRMSecurity { get; } - - public AuthorizationManager AuthorizationManager { get; } public void AddMember(int dealID, int memberID) { @@ -140,7 +137,7 @@ public int CreateNewDeal(Deal deal) deal.ID = result; - FactoryIndexer.Index(Query(CrmDbContext.Deals).Where(x => x.Id == deal.ID).FirstOrDefault()); + _factoryIndexer.Index(Query(CrmDbContext.Deals).Where(x => x.Id == deal.ID).FirstOrDefault()); return result; } @@ -167,9 +164,9 @@ private int CreateNewDealInDb(Deal deal) ExpectedCloseDate = deal.ExpectedCloseDate, ActualCloseDate = deal.ActualCloseDate, PerPeriodValue = deal.PerPeriodValue, - CreateOn = TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn), + CreateOn = _tenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? _tenantUtil.DateTimeNow() : deal.CreateOn), CreateBy = _securityContext.CurrentAccount.ID, - LastModifedOn = TenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? TenantUtil.DateTimeNow() : deal.CreateOn), + LastModifedOn = _tenantUtil.DateTimeToUtc(deal.CreateOn == DateTime.MinValue ? _tenantUtil.DateTimeNow() : deal.CreateOn), LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -195,7 +192,7 @@ public int[] SaveDealList(List items) foreach (var deal in Query(CrmDbContext.Deals).Where(x => result.Contains(x.Id))) { - FactoryIndexer.Index(deal); + _factoryIndexer.Index(deal); } return result; @@ -203,7 +200,7 @@ public int[] SaveDealList(List items) public void EditDeal(Deal deal) { - CRMSecurity.DemandEdit(deal); + _crmSecurity.DemandEdit(deal); // var oldDeal = GetByID(deal.ID); @@ -226,14 +223,14 @@ public void EditDeal(Deal deal) itemToUpdate.ExpectedCloseDate = deal.ExpectedCloseDate; itemToUpdate.PerPeriodValue = deal.PerPeriodValue; - itemToUpdate.ActualCloseDate = TenantUtil.DateTimeToUtc(deal.ActualCloseDate); - itemToUpdate.LastModifedOn = TenantUtil.DateTimeToUtc(TenantUtil.DateTimeNow()); + itemToUpdate.ActualCloseDate = _tenantUtil.DateTimeToUtc(deal.ActualCloseDate); + itemToUpdate.LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()); itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; CrmDbContext.Update(itemToUpdate); CrmDbContext.SaveChanges(); - FactoryIndexer.Index(itemToUpdate); + _factoryIndexer.Index(itemToUpdate); } @@ -288,7 +285,7 @@ private IQueryable GetDbDealByFilters( if (keywords.Length > 0) { - if (!BundleSearch.TrySelectOpportunity(searchText, out ids)) + if (!_bundleSearch.TrySelectOpportunity(searchText, out ids)) { foreach (var k in keywords) { @@ -368,8 +365,8 @@ private IQueryable GetDbDealByFilters( sqlQuery = sqlQuery.Where(x => x.y.Status == stageType.Value); if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) - sqlQuery = sqlQuery.Where(x => x.y.Status == 0 ? x.x.ExpectedCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= TenantUtil.DateTimeToUtc(toDate) - : x.x.ActualCloseDate >= TenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= TenantUtil.DateTimeToUtc(toDate)); + sqlQuery = sqlQuery.Where(x => x.y.Status == 0 ? x.x.ExpectedCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.x.ExpectedCloseDate <= _tenantUtil.DateTimeToUtc(toDate) + : x.x.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.x.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)); } @@ -503,7 +500,7 @@ public int GetDealsCount(String searchText, fromDate == DateTime.MinValue && toDate == DateTime.MinValue); - ICollection exceptIDs = CRMSecurity.GetPrivateItems(typeof(Deal)).ToList(); + ICollection exceptIDs = _crmSecurity.GetPrivateItems(typeof(Deal)).ToList(); int result; @@ -561,7 +558,7 @@ public List GetDeals( OrderBy orderBy) { - if (CRMSecurity.IsAdmin) + if (_crmSecurity.IsAdmin) return GetCrudeDeals(searchText, responsibleID, milestoneID, @@ -590,9 +587,9 @@ public List GetDeals( if (crudeDeals.Count == 0) return crudeDeals; - if (crudeDeals.Count < from + count) return crudeDeals.FindAll(CRMSecurity.CanAccessTo).Skip(from).ToList(); + if (crudeDeals.Count < from + count) return crudeDeals.FindAll(_crmSecurity.CanAccessTo).Skip(from).ToList(); - var result = crudeDeals.FindAll(CRMSecurity.CanAccessTo); + var result = crudeDeals.FindAll(_crmSecurity.CanAccessTo); if (result.Count == crudeDeals.Count) return result.Skip(from).ToList(); @@ -616,7 +613,7 @@ public List GetDeals( if (crudeDeals.Count == 0) break; - result.AddRange(crudeDeals.Where(CRMSecurity.CanAccessTo)); + result.AddRange(crudeDeals.Where(_crmSecurity.CanAccessTo)); if ((result.Count >= count + from) || (crudeDeals.Count < localCount)) break; @@ -730,7 +727,7 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta var dbDeals = sqlQuery.ToList(); - return _mapper.Map, List>(dbDeals).FindAll(CRMSecurity.CanAccessTo); + return _mapper.Map, List>(dbDeals).FindAll(_crmSecurity.CanAccessTo); } public Deal DeleteDeal(int dealID) @@ -740,9 +737,9 @@ public Deal DeleteDeal(int dealID) var deal = GetByID(dealID); if (deal == null) return null; - CRMSecurity.DemandDelete(deal); + _crmSecurity.DemandDelete(deal); - FactoryIndexer.Delete(Query(CrmDbContext.Deals).Where(x => x.Id == dealID).Single()); + _factoryIndexer.Delete(Query(CrmDbContext.Deals).Where(x => x.Id == dealID).Single()); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); @@ -754,7 +751,7 @@ public Deal DeleteDeal(int dealID) public List DeleteBatchDeals(int[] dealID) { - var deals = GetDeals(dealID).FindAll(CRMSecurity.CanDelete).ToList(); + var deals = GetDeals(dealID).FindAll(_crmSecurity.CanDelete).ToList(); if (!deals.Any()) return deals; // Delete relative keys @@ -766,7 +763,7 @@ public List DeleteBatchDeals(int[] dealID) public List DeleteBatchDeals(List deals) { - deals = deals.FindAll(CRMSecurity.CanDelete).ToList(); + deals = deals.FindAll(_crmSecurity.CanDelete).ToList(); if (!deals.Any()) return deals; // Delete relative keys @@ -783,7 +780,7 @@ private void DeleteBatchDealsExecute(List deals) var dealID = deals.Select(x => x.ID).ToArray(); object[] filesIDs; - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); var tagNames = Query(CrmDbContext.RelationshipEvent) .Where(x => x.HaveFiles && dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) @@ -811,9 +808,9 @@ private void DeleteBatchDealsExecute(List deals) tx.Commit(); - deals.ForEach(deal => AuthorizationManager.RemoveAllAces(deal)); + deals.ForEach(deal => _authorizationManager.RemoveAllAces(deal)); - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); foreach (var filesID in filesIDs) { @@ -843,14 +840,14 @@ public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) EditDeal(deal); - var responsibles = CRMSecurity.GetAccessSubjectGuidsTo(deal); + var responsibles = _crmSecurity.GetAccessSubjectGuidsTo(deal); if (!responsibles.Any()) continue; responsibles.Remove(fromUserId); responsibles.Add(toUserId); - CRMSecurity.SetAccessTo(deal, responsibles.Distinct().ToList()); + _crmSecurity.SetAccessTo(deal, responsibles.Distinct().ToList()); } } @@ -864,7 +861,7 @@ public void SetDealCreationDate(int opportunityid, DateTime creationDate) var dbDeal = new DbDeal { Id = opportunityid, - CreateOn = TenantUtil.DateTimeToUtc(creationDate), + CreateOn = _tenantUtil.DateTimeToUtc(creationDate), TenantId = TenantID }; @@ -886,7 +883,7 @@ public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) var dbDeal = new DbDeal { Id = opportunityid, - LastModifedOn = TenantUtil.DateTimeToUtc(lastModifedDate), + LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate), TenantId = TenantID }; diff --git a/products/ASC.CRM/Server/Core/Dao/FileDao.cs b/products/ASC.CRM/Server/Core/Dao/FileDao.cs index 5308a77ca56..aa5c6821847 100644 --- a/products/ASC.CRM/Server/Core/Dao/FileDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/FileDao.cs @@ -46,6 +46,7 @@ namespace ASC.CRM.Core.Dao [Scope] public class FileDao : AbstractDao { + private FilesIntegration _filesIntegration; public FileDao(FilesIntegration filesIntegration, DbContextManager dbContextManager, TenantManager tenantManager, @@ -60,14 +61,13 @@ public FileDao(FilesIntegration filesIntegration, ascCache, mapper) { - FilesIntegration = filesIntegration; + _filesIntegration = filesIntegration; } - public FilesIntegration FilesIntegration { get; } public File GetFile(int id, int version) { - var dao = FilesIntegration.DaoFactory.GetFileDao(); + var dao = _filesIntegration.DaoFactory.GetFileDao(); var file = 0 < version ? dao.GetFile(id, version) : dao.GetFile(id); @@ -76,31 +76,31 @@ public File GetFile(int id, int version) public void DeleteFile(int id) { - var dao = FilesIntegration.DaoFactory.GetFileDao(); + var dao = _filesIntegration.DaoFactory.GetFileDao(); dao.DeleteFile(id); } public int GetRoot() { - return FilesIntegration.RegisterBunch("crm", "crm_common", ""); + return _filesIntegration.RegisterBunch("crm", "crm_common", ""); } public int GetMy() { - return FilesIntegration.RegisterBunch("files", "my", _securityContext.CurrentAccount.ID.ToString()); + return _filesIntegration.RegisterBunch("files", "my", _securityContext.CurrentAccount.ID.ToString()); } public File SaveFile(File file, System.IO.Stream stream) { - var dao = FilesIntegration.DaoFactory.GetFileDao(); + var dao = _filesIntegration.DaoFactory.GetFileDao(); return dao.SaveFile(file, stream); } public List GetEventsByFile(int id) { - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); var tags = tagdao.GetTags(id, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index c9060859f35..3f13f1bd6fd 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -52,6 +52,9 @@ namespace ASC.CRM.Core.Dao [Scope] public class InvoiceItemDao : AbstractDao { + private CrmSecurity _crmSecurity { get; } + private TenantUtil _tTenantUtil { get; } + public InvoiceItemDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -68,15 +71,10 @@ IMapper mapper ascCache, mapper) { - TenantUtil = tenantUtil; - CRMSecurity = crmSecurity; + _tTenantUtil = tenantUtil; + _crmSecurity = crmSecurity; } - - public CrmSecurity CRMSecurity { get; } - - public TenantUtil TenantUtil { get; } - public Boolean IsExist(int invoiceItemID) { return IsExistInDb(invoiceItemID); @@ -207,7 +205,7 @@ public int GetInvoiceItemsCount( if (fromCache != null) return Convert.ToInt32(fromCache); - var exceptIDs = CRMSecurity.GetPrivateItems(typeof(InvoiceItem)).ToList(); + var exceptIDs = _crmSecurity.GetPrivateItems(typeof(InvoiceItem)).ToList(); int result; @@ -258,7 +256,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) if (invoiceItem.Price > Global.MaxInvoiceItemPrice) throw new ArgumentException("Max Invoice Item Price: " + Global.MaxInvoiceItemPrice); - if (!CRMSecurity.IsAdmin) CRMSecurity.CreateSecurityException(); + if (!_crmSecurity.IsAdmin) _crmSecurity.CreateSecurityException(); if (String.IsNullOrEmpty(invoiceItem.Description)) { @@ -303,7 +301,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) var itemToUpdate = Query(CrmDbContext.InvoiceItem).Single(x => x.Id == invoiceItem.ID); var oldInvoiceItem = _mapper.Map(itemToUpdate); - CRMSecurity.DemandEdit(oldInvoiceItem); + _crmSecurity.DemandEdit(oldInvoiceItem); itemToUpdate.Title = invoiceItem.Title; itemToUpdate.Description = invoiceItem.Description; @@ -332,7 +330,7 @@ public InvoiceItem DeleteInvoiceItem(int invoiceItemID) var invoiceItem = GetByID(invoiceItemID); if (invoiceItem == null) return null; - CRMSecurity.DemandDelete(invoiceItem); + _crmSecurity.DemandDelete(invoiceItem); CrmDbContext.Remove(new DbInvoiceItem { @@ -352,7 +350,7 @@ public List DeleteBatchInvoiceItems(int[] invoiceItemIDs) { if (invoiceItemIDs == null || !invoiceItemIDs.Any()) return null; - var items = GetInvoiceItems(invoiceItemIDs).Where(CRMSecurity.CanDelete).ToList(); + var items = GetInvoiceItems(invoiceItemIDs).Where(_crmSecurity.CanDelete).ToList(); if (!items.Any()) return items; diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index fd6df349f71..487a3ef3496 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -49,6 +49,9 @@ namespace ASC.CRM.Core.Dao [Scope] public class InvoiceTaxDao : AbstractDao { + private TenantUtil _tenantUtil { get; } + private CrmSecurity _crmSecurity { get; } + public InvoiceTaxDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -65,12 +68,9 @@ IMapper mapper ascCache, mapper) { - TenantUtil = tenantUtil; + _tenantUtil = tenantUtil; _mapper = mapper; - } - - public TenantUtil TenantUtil { get; } - public CrmSecurity CRMSecurity { get; } + } public Boolean IsExist(int invoiceTaxID) { @@ -163,7 +163,7 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) { var oldInvoiceTax = GetByID(invoiceTax.ID); - CRMSecurity.DemandEdit(oldInvoiceTax); + _crmSecurity.DemandEdit(oldInvoiceTax); var itemToUpdate = Query(CrmDbContext.InvoiceTax) .FirstOrDefault(x => x.Id == invoiceTax.ID); @@ -189,7 +189,7 @@ public InvoiceTax DeleteInvoiceTax(int invoiceTaxID) if (invoiceTax == null) return null; - CRMSecurity.DemandDelete(invoiceTax); + _crmSecurity.DemandDelete(invoiceTax); var itemToDelete = new DbInvoiceTax { diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index b3d64d9691f..1ca246a8630 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -63,6 +63,10 @@ namespace ASC.CRM.Core.Dao [Scope] public class RelationshipEventDao : AbstractDao { + private CrmSecurity _crmSecurity; + private TenantUtil _tenantUtil; + private FilesIntegration _filesIntegration; + private FactoryIndexerEvents _factoryIndexer; public RelationshipEventDao(DbContextManager dbContextManager, TenantManager tenantManager, @@ -70,8 +74,6 @@ public RelationshipEventDao(DbContextManager dbContextManager, FilesIntegration filesIntegration, CrmSecurity crmSecurity, TenantUtil tenantUtil, - SetupInfo setupInfo, - PathProvider pathProvider, IOptionsMonitor logger, ICache ascCache, IMapper mapper @@ -83,26 +85,11 @@ IMapper mapper ascCache, mapper) { - FilesIntegration = filesIntegration; - TenantUtil = tenantUtil; - CRMSecurity = crmSecurity; - SetupInfo = setupInfo; - PathProvider = pathProvider; + _filesIntegration = filesIntegration; + _tenantUtil = tenantUtil; + _crmSecurity = crmSecurity; } - - public PathProvider PathProvider { get; } - - public SetupInfo SetupInfo { get; } - - public CrmSecurity CRMSecurity { get; } - - public TenantUtil TenantUtil { get; } - - public FilesIntegration FilesIntegration { get; } - - public FactoryIndexerEvents FactoryIndexer { get; } - public RelationshipEvent AttachFiles(int contactID, EntityType entityType, int entityID, int[] fileIDs) { if (entityID > 0 && !_supportedEntityType.Contains(entityType)) @@ -128,7 +115,7 @@ public void AttachFiles(int eventID, int[] fileIDs) { if (fileIDs.Length == 0) return; - var dao = FilesIntegration.DaoFactory.GetTagDao(); + var dao = _filesIntegration.DaoFactory.GetTagDao(); var tags = fileIDs.ToList().ConvertAll(fileID => new Tag("RelationshipEvent_" + eventID, TagType.System, Guid.Empty) { EntryType = FileEntryType.File, EntryId = fileID }); @@ -170,7 +157,7 @@ private int[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID) sqlQuery = sqlQuery.Where(x => x.HaveFiles); var tagNames = sqlQuery.Select(x => String.Format("RelationshipEvent_{0}", x.Id)); - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); return tagdao.GetTags(tagNames.ToArray(), TagType.System) .Where(t => t.EntryType == FileEntryType.File) @@ -180,12 +167,12 @@ private int[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID) public List> GetAllFiles(int[] contactID, EntityType entityType, int entityID) { - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); var ids = GetFilesIDs(contactID, entityType, entityID); var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List>(); - files.ForEach(CRMSecurity.SetAccessTo); + files.ForEach(_crmSecurity.SetAccessTo); return files.ToList(); } @@ -195,8 +182,8 @@ public Dictionary>> GetFiles(int[] eventID) if (eventID == null || eventID.Length == 0) throw new ArgumentException("eventID"); - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); var findedTags = tagdao.GetTags(eventID.Select(item => String.Concat("RelationshipEvent_", item)).ToArray(), TagType.System).Where(t => t.EntryType == FileEntryType.File); @@ -222,13 +209,13 @@ public List> GetFiles(int eventID) if (eventID == 0) throw new ArgumentException("eventID"); - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); - var filedao = FilesIntegration.DaoFactory.GetFileDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); + var filedao = _filesIntegration.DaoFactory.GetFileDao(); var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => Convert.ToInt32(t.EntryId)).ToArray(); var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List>(); - files.ForEach(CRMSecurity.SetAccessTo); + files.ForEach(_crmSecurity.SetAccessTo); return files.ToList(); } @@ -242,7 +229,7 @@ private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID var files = GetAllFiles(contactID, entityType, entityID); - var dao = FilesIntegration.DaoFactory.GetFileDao(); + var dao = _filesIntegration.DaoFactory.GetFileDao(); foreach (var file in files) { @@ -252,17 +239,17 @@ private void RemoveAllFiles(int[] contactID, EntityType entityType, int entityID public List RemoveFile(File file) { - CRMSecurity.DemandDelete(file); + _crmSecurity.DemandDelete(file); List eventIDs; - var tagdao = FilesIntegration.DaoFactory.GetTagDao(); + var tagdao = _filesIntegration.DaoFactory.GetTagDao(); var tags = tagdao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_")); eventIDs = tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList(); - var dao = FilesIntegration.DaoFactory.GetFileDao(); + var dao = _filesIntegration.DaoFactory.GetFileDao(); dao.DeleteFile(file.ID); @@ -314,12 +301,12 @@ public int GetCount(int[] contactID, EntityType entityType, int entityID) public RelationshipEvent CreateItem(RelationshipEvent item) { - CRMSecurity.DemandCreateOrUpdate(item); + _crmSecurity.DemandCreateOrUpdate(item); var htmlBody = String.Empty; if (item.CreateOn == DateTime.MinValue) - item.CreateOn = TenantUtil.DateTimeNow(); + item.CreateOn = _tenantUtil.DateTimeNow(); item.CreateBy = _securityContext.CurrentAccount.ID; item.LastModifedBy = _securityContext.CurrentAccount.ID; @@ -388,7 +375,7 @@ public RelationshipEvent CreateItem(RelationshipEvent item) { ContactId = item.ContactID, Content = item.Content, - CreateOn = TenantUtil.DateTimeToUtc(item.CreateOn), + CreateOn = _tenantUtil.DateTimeToUtc(item.CreateOn), CreateBy = item.CreateBy, EntityType = item.EntityType, EntityId = item.EntityID, @@ -405,9 +392,9 @@ public RelationshipEvent CreateItem(RelationshipEvent item) item.ID = itemToInsert.Id; if (item.CreateOn.Kind == DateTimeKind.Utc) - item.CreateOn = TenantUtil.DateTimeFromUtc(item.CreateOn); + item.CreateOn = _tenantUtil.DateTimeFromUtc(item.CreateOn); - FactoryIndexer.Index(itemToInsert); + _factoryIndexer.Index(itemToInsert); return item; } @@ -489,15 +476,15 @@ public List GetItems( if (fromDate != DateTime.MinValue && toDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= TenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); + sqlQuery = sqlQuery.Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate.AddDays(1).AddMinutes(-1))); } else if (fromDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.CreateOn >= TenantUtil.DateTimeToUtc(fromDate)); + sqlQuery = sqlQuery.Where(x => x.CreateOn >= _tenantUtil.DateTimeToUtc(fromDate)); } else if (toDate != DateTime.MinValue) { - sqlQuery = sqlQuery.Where(x => x.CreateOn <= TenantUtil.DateTimeToUtc(toDate).AddDays(1).AddMinutes(-1)); + sqlQuery = sqlQuery.Where(x => x.CreateOn <= _tenantUtil.DateTimeToUtc(toDate).AddDays(1).AddMinutes(-1)); } if (createBy != Guid.Empty) @@ -519,7 +506,7 @@ public List GetItems( List eventsIds; - if (!FactoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out eventsIds)) + if (!_factoryIndexer.TrySelectIds(s => s.MatchAll(searchText), out eventsIds)) { if (keywords.Length > 0) { @@ -577,7 +564,7 @@ private RelationshipEvent ToRelationshipEvent(DbRelationshipEvent relationshipEv Content = relationshipEvent.Content, EntityID = relationshipEvent.EntityId, EntityType = relationshipEvent.EntityType, - CreateOn = TenantUtil.DateTimeFromUtc(relationshipEvent.CreateOn), + CreateOn = _tenantUtil.DateTimeFromUtc(relationshipEvent.CreateOn), CreateBy = relationshipEvent.CreateBy, CategoryID = relationshipEvent.CategoryId, LastModifedBy = relationshipEvent.LastModifedBy, @@ -595,7 +582,7 @@ public void DeleteItem(int id) public void DeleteItem(RelationshipEvent item) { - CRMSecurity.DemandDelete(item); + _crmSecurity.DemandDelete(item); var relativeFiles = GetFiles(item.ID); @@ -608,7 +595,7 @@ public void DeleteItem(RelationshipEvent item) var itemToDelete = Query(CrmDbContext.RelationshipEvent).Where(x => x.Id == item.ID).Single(); - FactoryIndexer.DeleteAsync(itemToDelete); + _factoryIndexer.DeleteAsync(itemToDelete); CrmDbContext.RelationshipEvent.Remove(itemToDelete); diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 61d6b6f8fdd..85335fe670a 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -39,6 +39,7 @@ using AutoMapper; +using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Options; @@ -99,6 +100,7 @@ public String[] GetAllTags(EntityType entityType) public List> GetAllTags() { return Query(CrmDbContext.Tags) + .AsNoTracking() .OrderBy(x => x.Title) .Select(x => new KeyValuePair(x.EntityType, x.Title)).ToList(); } @@ -112,6 +114,7 @@ public String GetTagsLinkCountJSON(EntityType entityType) public IEnumerable GetTagsLinkCount(EntityType entityType) { return Query(CrmDbContext.Tags) + .AsNoTracking() .Join(CrmDbContext.EntityTags, x => x.Id, y => y.TagId, diff --git a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs index 39dc84143fc..aeb91cb32b8 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskDao.cs @@ -81,51 +81,54 @@ public TaskDao(DbContextManager dbContextManager, _mapper = mapper; } - public void OpenTask(int taskId) + public void OpenTask(int id) { - var task = GetByID(taskId); + var dbEntity = CrmDbContext.Tasks.Find(id); - if (task == null) + if (dbEntity == null) throw new ArgumentException(); - _crmSecurity.DemandEdit(task); + if (!dbEntity.IsClosed) return; + if (dbEntity.TenantId != TenantID) return; - DbTask entity = new DbTask() - { - Id = taskId, - IsClosed = false - }; + var entity = _mapper.Map(dbEntity); - CrmDbContext.Tasks.Update(entity); + _crmSecurity.DemandEdit(entity); + + dbEntity.IsClosed = false; CrmDbContext.SaveChanges(); } - public void CloseTask(int taskId) + public void CloseTask(int id) { - var task = GetByID(taskId); + var dbEntity = CrmDbContext.Tasks.Find(id); - if (task == null) + if (dbEntity == null) throw new ArgumentException(); - _crmSecurity.DemandEdit(task); + if (dbEntity.IsClosed) return; - DbTask entity = new DbTask() - { - Id = taskId, - IsClosed = true - }; + var entity = _mapper.Map(dbEntity); + + _crmSecurity.DemandEdit(entity); - CrmDbContext.Tasks.Update(entity); + dbEntity.IsClosed = true; CrmDbContext.SaveChanges(); } public Task GetByID(int id) { - var entity = Query(CrmDbContext.Tasks).FirstOrDefault(x => x.Id == id); + var dbEntity = CrmDbContext.Tasks.Find(id); + + if (dbEntity.TenantId != TenantID) return null; + + var entity = _mapper.Map(dbEntity); - return _mapper.Map(entity); + _crmSecurity.DemandAccessTo(entity); + + return entity; } public List GetTasks(EntityType entityType, int entityID, bool? onlyActiveTask) @@ -142,7 +145,9 @@ public List GetAllTasks() { var dbTasks = Query(CrmDbContext.Tasks) .OrderBy(x => x.Deadline) - .OrderBy(x => x.Title).ToList(); + .OrderBy(x => x.Title) + .AsNoTracking() + .ToList(); return _mapper.Map, List>(dbTasks) .FindAll(_crmSecurity.CanAccessTo); @@ -152,19 +157,29 @@ public void ExecAlert(IEnumerable ids) { if (!ids.Any()) return; - CrmDbContext.Tasks.UpdateRange(ids.Select(x => new DbTask { ExecAlert = 1, Id = x })); ; + foreach (var id in ids) + { + var dbEntity = CrmDbContext.Tasks.Find(id); + + if (dbEntity.TenantId != TenantID) + throw new Exception("Get data from another tenant"); + + dbEntity.ExecAlert = 1; + } CrmDbContext.SaveChanges(); } public List GetInfoForReminder(DateTime scheduleDate) { - return CrmDbContext.Tasks.Where(x => + return Query(CrmDbContext.Tasks).Where(x => x.IsClosed == false && x.AlertValue != 0 && x.ExecAlert == 0 && (x.Deadline.AddMinutes(-x.AlertValue) >= scheduleDate.AddHours(-1) && x.Deadline.AddMinutes(-x.AlertValue) <= scheduleDate.AddHours(-1)) - ).Select(x => new object[] { x.TenantId, x.Id, x.Deadline, x.AlertValue, x.ResponsibleId }).ToList(); + ) + .Select(x => new object[] { x.TenantId, x.Id, x.Deadline, x.AlertValue, x.ResponsibleId }) + .ToList(); } public List GetTasks( @@ -513,7 +528,7 @@ private IQueryable GetDbTaskByFilters( int count, OrderBy orderBy) { - var sqlQuery = Query(CrmDbContext.Tasks); + var sqlQuery = Query(CrmDbContext.Tasks).AsNoTracking(); if (responsibleID != Guid.Empty) sqlQuery = sqlQuery.Where(x => x.ResponsibleId == responsibleID); @@ -756,88 +771,44 @@ public Task[] SaveOrUpdateTaskList(List newTasks) private Task SaveOrUpdateTaskInDb(Task newTask) { - if (string.IsNullOrEmpty(newTask.Title) || + if (string.IsNullOrEmpty(newTask.Title) || newTask.DeadLine == DateTime.MinValue || newTask.CategoryID <= 0) throw new ArgumentException(); - - if (newTask.ID == 0 ) - { - newTask.CreateOn = DateTime.UtcNow; - newTask.CreateBy = _securityContext.CurrentAccount.ID; - - newTask.LastModifedOn = DateTime.UtcNow; - newTask.LastModifedBy = _securityContext.CurrentAccount.ID; - - var itemToInsert = new DbTask - { - Title = newTask.Title, - Description = newTask.Description, - Deadline = _tenantUtil.DateTimeToUtc(newTask.DeadLine), - ResponsibleId = newTask.ResponsibleID, - ContactId = newTask.ContactID, - EntityType = newTask.EntityType, - EntityId = newTask.EntityID, - IsClosed = newTask.IsClosed, - CategoryId = newTask.CategoryID, - CreateOn = newTask.CreateOn, - CreateBy = newTask.CreateBy, - LastModifedOn = newTask.LastModifedOn, - LastModifedBy = newTask.LastModifedBy, - AlertValue = newTask.AlertValue, - TenantId = TenantID - }; - CrmDbContext.Add(itemToInsert); - - CrmDbContext.SaveChanges(); - - newTask.ID = itemToInsert.Id; - } - else + var dbEntity = new DbTask { + Id = newTask.ID, + Title = newTask.Title, + Description = newTask.Description, + Deadline = _tenantUtil.DateTimeToUtc(newTask.DeadLine), + ResponsibleId = newTask.ResponsibleID, + ContactId = newTask.ContactID, + EntityType = newTask.EntityType, + EntityId = newTask.EntityID, + IsClosed = newTask.IsClosed, + CategoryId = newTask.CategoryID, + CreateOn = newTask.CreateOn == DateTime.MinValue ? DateTime.UtcNow : newTask.CreateOn, + CreateBy = newTask.CreateBy == Guid.Empty ? _securityContext.CurrentAccount.ID : newTask.CreateBy, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = _securityContext.CurrentAccount.ID, + AlertValue = newTask.AlertValue, + ExecAlert = 0, + TenantId = TenantID + }; - var itemToUpdate = Query(CrmDbContext.Tasks).FirstOrDefault(x => x.Id == newTask.ID); - - var oldTask = _mapper.Map(itemToUpdate); - - _crmSecurity.DemandEdit(oldTask); - - itemToUpdate.Title = newTask.Title; - itemToUpdate.Description = newTask.Description; - itemToUpdate.Deadline = _tenantUtil.DateTimeToUtc(newTask.DeadLine); - itemToUpdate.ResponsibleId = newTask.ResponsibleID; - itemToUpdate.ContactId = newTask.ContactID; - itemToUpdate.EntityType = newTask.EntityType; - itemToUpdate.EntityId = newTask.EntityID; - itemToUpdate.CategoryId = newTask.CategoryID; - itemToUpdate.LastModifedOn = newTask.LastModifedOn; - itemToUpdate.LastModifedBy = newTask.LastModifedBy; - itemToUpdate.AlertValue = newTask.AlertValue; - itemToUpdate.ExecAlert = 0; - itemToUpdate.TenantId = TenantID; - - CrmDbContext.Update(itemToUpdate); - CrmDbContext.SaveChanges(); - - - newTask.CreateOn = oldTask.CreateOn; - newTask.CreateBy = oldTask.CreateBy; - - newTask.LastModifedOn = DateTime.UtcNow; - newTask.LastModifedBy = _securityContext.CurrentAccount.ID; - - newTask.IsClosed = oldTask.IsClosed; - } + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); - _factoryIndexer.Index(Query(CrmDbContext.Tasks).Where(x => x.Id == newTask.ID).Single()); + _factoryIndexer.Index(dbEntity); - return newTask; + return _mapper.Map(dbEntity); } public int SaveTask(Task newTask) { _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); + return SaveTaskInDb(newTask); } @@ -879,7 +850,6 @@ private int SaveTaskInDb(Task newTask) public int[] SaveTaskList(List items) { - using var tx = CrmDbContext.Database.BeginTransaction(); var result = new List(); @@ -896,19 +866,19 @@ public int[] SaveTaskList(List items) return result.ToArray(); } - public void DeleteTask(int taskID) + public void DeleteTask(int id) { - var task = GetByID(taskID); + var task = GetByID(id); if (task == null) return; _crmSecurity.DemandEdit(task); - var dbTask = Query(CrmDbContext.Tasks).Where(x => x.Id == taskID).Single(); + var dbEntity = CrmDbContext.Tasks.Find(id); - _factoryIndexer.Delete(dbTask); + _factoryIndexer.Delete(dbEntity); - CrmDbContext.Tasks.Remove(new DbTask { Id = taskID }); + CrmDbContext.Tasks.Remove(dbEntity); _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "tasks.*")); @@ -973,94 +943,30 @@ public List CreateByTemplate(List templateItems, EntityType return result; } - #region Private Methods - - //private String[] GetTaskColumnsTable(String alias) - //{ - // if (!String.IsNullOrEmpty(alias)) - // alias = alias + "."; - - // var result = new List - // { - // "id", - // "contact_id", - // "title", - // "description", - // "deadline", - // "responsible_id", - // "is_closed", - // "category_id", - // "entity_id", - // "entity_type", - // "create_on", - // "create_by", - // "alert_value" - // }; - - // if (String.IsNullOrEmpty(alias)) return result.ToArray(); - - // return result.ConvertAll(item => String.Concat(alias, item)).ToArray(); - //} - - //private SqlQuery GetTaskQuery(Exp where, String alias) - //{ - - // var sqlQuery = Query("crm_task"); - - // if (!String.IsNullOrEmpty(alias)) - // { - // sqlQuery = new SqlQuery(String.Concat("crm_task ", alias)) - // .Where(Exp.Eq(alias + ".tenant_id", TenantID)); - // sqlQuery.Select(GetTaskColumnsTable(alias)); - - // } - // else - // sqlQuery.Select(GetTaskColumnsTable(String.Empty)); - - - // if (where != null) - // sqlQuery.Where(where); - - // return sqlQuery; - - //} - - //private SqlQuery GetTaskQuery(Exp where) - //{ - // return GetTaskQuery(where, String.Empty); - - //} - - - #endregion - public void ReassignTasksResponsible(Guid fromUserId, Guid toUserId) { - var tasks = GetTasks(String.Empty, fromUserId, 0, false, DateTime.MinValue, DateTime.MinValue, - EntityType.Any, 0, 0, 0, null); + var dbEntities = Query(CrmDbContext.Tasks) + .Where(x => x.ResponsibleId == fromUserId) + .ToList(); - foreach (var task in tasks) + foreach (var dbEntity in dbEntities) { - task.ResponsibleID = toUserId; - - SaveOrUpdateTask(task); + dbEntity.ResponsibleId = toUserId; } + + CrmDbContext.SaveChanges(); } /// /// Test method /// - /// + /// /// - public void SetTaskCreationDate(int taskId, DateTime creationDate) + public void SetTaskCreationDate(int id, DateTime creationDate) { - DbTask entity = new DbTask() - { - Id = taskId, - CreateOn = _tenantUtil.DateTimeToUtc(creationDate) - }; + var dbEntity = CrmDbContext.Tasks.Find(id); - CrmDbContext.Tasks.Update(entity); + dbEntity.LastModifedOn = _tenantUtil.DateTimeToUtc(creationDate); CrmDbContext.SaveChanges(); @@ -1071,17 +977,13 @@ public void SetTaskCreationDate(int taskId, DateTime creationDate) /// /// Test method /// - /// + /// /// - public void SetTaskLastModifedDate(int taskId, DateTime lastModifedDate) + public void SetTaskLastModifedDate(int id, DateTime lastModifedDate) { - DbTask entity = new DbTask() - { - Id = taskId, - LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate) - }; + var dbEntity = CrmDbContext.Tasks.Find(id); - CrmDbContext.Tasks.Update(entity); + dbEntity.LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate); CrmDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 45b7e7d3678..0b0daf3cc02 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -56,6 +56,15 @@ namespace ASC.CRM.Core [Scope] public class CrmSecurity { + private readonly CurrencyProvider _currencyProvider; + private readonly PermissionContext _permissionContext; + private readonly WebItemSecurity _webItemSecurity; + private readonly DaoFactory _daoFactory; + private readonly SecurityContext _securityContext; + private readonly AuthorizationManager _authorizationManager; + private readonly DisplayUserSettingsHelper _displayUserSettingsHelper; + private readonly UserManager _userManager; + public readonly IAction _actionRead = new Action(new Guid("{6F05C382-8BCA-4469-9424-C807A98C40D7}"), "", true, false); public CrmSecurity(SecurityContext securityContext, @@ -65,35 +74,19 @@ public CrmSecurity(SecurityContext securityContext, DaoFactory daoFactory, WebItemSecurity webItemSecurity, PermissionContext permissionContext, - CurrencyProvider currencyProvider) + CurrencyProvider currencyProvider, + TenantManager tenantManager) { - SecurityContext = securityContext; - AuthorizationManager = authorizationManager; - UserManager = userManager; - DisplayUserSettingsHelper = displayUserSettingsHelper; - DaoFactory = daoFactory; - WebItemSecurity = webItemSecurity; - PermissionContext = permissionContext; - CurrencyProvider = currencyProvider; + _securityContext = securityContext; + _authorizationManager = authorizationManager; + _userManager = userManager; + _displayUserSettingsHelper = displayUserSettingsHelper; + _daoFactory = daoFactory; + _webItemSecurity = webItemSecurity; + _permissionContext = permissionContext; + _currencyProvider = currencyProvider; } - - public CurrencyProvider CurrencyProvider { get; } - - public PermissionContext PermissionContext { get; } - - public WebItemSecurity WebItemSecurity { get; } - - public DaoFactory DaoFactory { get; } - - public SecurityContext SecurityContext { get; } - - public AuthorizationManager AuthorizationManager { get; } - - public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } - - public UserManager UserManager { get; } - private ISecurityObjectProvider GetCRMSecurityProvider() { return new CrmSecurityObjectProvider(); @@ -106,12 +99,12 @@ public bool IsPrivate(ISecurityObjectId entity) public bool CanAccessTo(ISecurityObjectId entity) { - return CanAccessTo(entity, SecurityContext.CurrentAccount.ID); + return CanAccessTo(entity, _securityContext.CurrentAccount.ID); } public bool CanAccessTo(ISecurityObjectId entity, Guid userId) { - return IsAdministrator(userId) || PermissionContext.CheckPermissions(entity, GetCRMSecurityProvider(), _actionRead); + return IsAdministrator(userId) || _permissionContext.CheckPermissions(entity, GetCRMSecurityProvider(), _actionRead); } public void MakePublic(ISecurityObjectId entity) @@ -128,7 +121,7 @@ public IEnumerable GetPrivateItems(Type objectType) private IEnumerable GetPrivateItems(Type objectType, Guid userId, bool withoutUser) { - var query = AuthorizationManager + var query = _authorizationManager .GetAces(userId, _actionRead.ID) .Where( item => @@ -141,7 +134,7 @@ private IEnumerable GetPrivateItems(Type objectType, Guid userId, bool with if (userId != Guid.Empty) query = query.Where(item => !item.Contains(userId)); else - query = query.Where(item => !item.Contains(SecurityContext.CurrentAccount.ID)); + query = query.Where(item => !item.Contains(_securityContext.CurrentAccount.ID)); } @@ -163,7 +156,7 @@ public int GetPrivateItemsCount(Type objectType) private Dictionary GetAccessSubjectTo(ISecurityObjectId entity, EmployeeStatus employeeStatus) { - var allAces = AuthorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, + var allAces = _authorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, GetCRMSecurityProvider()) .Where(item => item.SubjectId != Constants.GroupEveryone.ID); @@ -173,10 +166,10 @@ private Dictionary GetAccessSubjectTo(ISecurityObjectId entity, Em { if (!result.ContainsKey(azRecord.SubjectId)) { - var userInfo = UserManager.GetUsers(azRecord.SubjectId); + var userInfo = _userManager.GetUsers(azRecord.SubjectId); var displayName = employeeStatus == EmployeeStatus.All || userInfo.Status == employeeStatus - ? userInfo.DisplayUserName(DisplayUserSettingsHelper) - : Constants.LostUser.DisplayUserName(DisplayUserSettingsHelper); + ? userInfo.DisplayUserName(_displayUserSettingsHelper) + : Constants.LostUser.DisplayUserName(_displayUserSettingsHelper); result.Add(azRecord.SubjectId, displayName); } } @@ -190,7 +183,7 @@ public Dictionary GetAccessSubjectTo(ISecurityObjectId entity) public List GetAccessSubjectGuidsTo(ISecurityObjectId entity) { - var allAces = AuthorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, + var allAces = _authorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, GetCRMSecurityProvider()) .Where(item => item.SubjectId != Constants.GroupEveryone.ID); @@ -209,16 +202,16 @@ public void SetAccessTo(ISecurityObjectId entity, List subjectID) if (subjectID.Count == 0) { - AuthorizationManager.RemoveAllAces(entity); + _authorizationManager.RemoveAllAces(entity); return; } - var aces = AuthorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, GetCRMSecurityProvider()); + var aces = _authorizationManager.GetAcesWithInherits(Guid.Empty, _actionRead.ID, entity, GetCRMSecurityProvider()); foreach (var r in aces) { if (!subjectID.Contains(r.SubjectId) && (r.SubjectId != Constants.GroupEveryone.ID || r.Reaction != AceType.Allow)) { - AuthorizationManager.RemoveAce(r); + _authorizationManager.RemoveAce(r); } } @@ -228,16 +221,16 @@ public void SetAccessTo(ISecurityObjectId entity, List subjectID) { if (!oldSubjects.Contains(s)) { - AuthorizationManager.AddAce(new AzRecord(s, _actionRead.ID, AceType.Allow, entity)); + _authorizationManager.AddAce(new AzRecord(s, _actionRead.ID, AceType.Allow, entity)); } } - AuthorizationManager.AddAce(new AzRecord(Constants.GroupEveryone.ID, _actionRead.ID, AceType.Deny, entity)); + _authorizationManager.AddAce(new AzRecord(Constants.GroupEveryone.ID, _actionRead.ID, AceType.Deny, entity)); } public void SetAccessTo(File file) { - if (IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID) + if (IsAdmin || file.CreateBy == _securityContext.CurrentAccount.ID || file.ModifiedBy == _securityContext.CurrentAccount.ID) file.Access = FileShare.None; else file.Access = FileShare.Read; @@ -245,7 +238,7 @@ public void SetAccessTo(File file) public void SetAccessTo(Deal deal, List subjectID) { - if (IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID) + if (IsAdmin || deal.CreateBy == _securityContext.CurrentAccount.ID) { SetAccessTo((ISecurityObjectId)deal, subjectID); } @@ -253,7 +246,7 @@ public void SetAccessTo(Deal deal, List subjectID) public void SetAccessTo(Cases cases, List subjectID) { - if (IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID) + if (IsAdmin || cases.CreateBy == _securityContext.CurrentAccount.ID) { SetAccessTo((ISecurityObjectId)cases, subjectID); } @@ -261,7 +254,7 @@ public void SetAccessTo(Cases cases, List subjectID) public bool CanAccessTo(RelationshipEvent relationshipEvent) { - return CanAccessTo(relationshipEvent, SecurityContext.CurrentAccount.ID); + return CanAccessTo(relationshipEvent, _securityContext.CurrentAccount.ID); } public bool CanAccessTo(RelationshipEvent relationshipEvent, Guid userId) @@ -271,19 +264,19 @@ public bool CanAccessTo(RelationshipEvent relationshipEvent, Guid userId) if (relationshipEvent.ContactID > 0) { - var contactObj = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); + var contactObj = _daoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); if (contactObj != null) return CanAccessTo(contactObj, userId); } if (relationshipEvent.EntityType == EntityType.Case) { - var caseObj = DaoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); + var caseObj = _daoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); if (caseObj != null) return CanAccessTo(caseObj, userId); } if (relationshipEvent.EntityType == EntityType.Opportunity) { - var dealObj = DaoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); + var dealObj = _daoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); if (dealObj != null) return CanAccessTo(dealObj, userId); } @@ -292,7 +285,7 @@ public bool CanAccessTo(RelationshipEvent relationshipEvent, Guid userId) public bool CanAccessTo(Contact contact) { - return CanAccessTo(contact, SecurityContext.CurrentAccount.ID); + return CanAccessTo(contact, _securityContext.CurrentAccount.ID); } public bool CanAccessTo(Contact contact, Guid userId) @@ -312,19 +305,19 @@ public bool CanAccessTo(int contactID, EntityType entityType, ShareType? shareTy if (entityType == EntityType.Company) { var fakeContact = new Company() { ID = contactID }; - return GetAccessSubjectTo(fakeContact).ContainsKey(SecurityContext.CurrentAccount.ID); + return GetAccessSubjectTo(fakeContact).ContainsKey(_securityContext.CurrentAccount.ID); } else if (entityType == EntityType.Person) { var fakeContact = new Person() { ID = contactID, CompanyID = companyID }; - return GetAccessSubjectTo(fakeContact).ContainsKey(SecurityContext.CurrentAccount.ID); + return GetAccessSubjectTo(fakeContact).ContainsKey(_securityContext.CurrentAccount.ID); } return false; } public bool CanAccessTo(Task task) { - return CanAccessTo(task, SecurityContext.CurrentAccount.ID); + return CanAccessTo(task, _securityContext.CurrentAccount.ID); } public bool CanAccessTo(Task task, Guid userId) @@ -335,19 +328,19 @@ public bool CanAccessTo(Task task, Guid userId) if (task.ContactID > 0) { - var contactObj = DaoFactory.GetContactDao().GetByID(task.ContactID); + var contactObj = _daoFactory.GetContactDao().GetByID(task.ContactID); if (contactObj != null) return CanAccessTo(contactObj, userId); } if (task.EntityType == EntityType.Case) { - var caseObj = DaoFactory.GetCasesDao().GetByID(task.EntityID); + var caseObj = _daoFactory.GetCasesDao().GetByID(task.EntityID); if (caseObj != null) return CanAccessTo(caseObj, userId); } if (task.EntityType == EntityType.Opportunity) { - var dealObj = DaoFactory.GetDealDao().GetByID(task.EntityID); + var dealObj = _daoFactory.GetDealDao().GetByID(task.EntityID); if (dealObj != null) return CanAccessTo(dealObj, userId); } @@ -357,7 +350,7 @@ public bool CanAccessTo(Task task, Guid userId) public bool CanAccessTo(Invoice invoice) { - return CanAccessTo(invoice, SecurityContext.CurrentAccount.ID); + return CanAccessTo(invoice, _securityContext.CurrentAccount.ID); } public bool CanAccessTo(Invoice invoice, Guid userId) @@ -365,10 +358,10 @@ public bool CanAccessTo(Invoice invoice, Guid userId) if (IsAdministrator(userId) || invoice.CreateBy == userId) return true; if (invoice.ContactID > 0) - return CanAccessTo(DaoFactory.GetContactDao().GetByID(invoice.ContactID), userId); + return CanAccessTo(_daoFactory.GetContactDao().GetByID(invoice.ContactID), userId); if (invoice.EntityType == EntityType.Opportunity) - return CanAccessTo(DaoFactory.GetDealDao().GetByID(invoice.EntityID), userId); + return CanAccessTo(_daoFactory.GetDealDao().GetByID(invoice.EntityID), userId); return false; @@ -376,7 +369,7 @@ public bool CanAccessTo(Invoice invoice, Guid userId) public bool CanAccessTo(InvoiceTax invoiceTax) { - return CanAccessTo(invoiceTax, SecurityContext.CurrentAccount.ID); + return CanAccessTo(invoiceTax, _securityContext.CurrentAccount.ID); } public bool CanAccessTo(InvoiceTax invoiceTax, Guid userId) @@ -388,7 +381,7 @@ public bool CanAccessTo(InvoiceTax invoiceTax, Guid userId) public bool CanEdit(File file) { - if (!(IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID)) + if (!(IsAdmin || file.CreateBy == _securityContext.CurrentAccount.ID || file.ModifiedBy == _securityContext.CurrentAccount.ID)) return false; if ((file.FileStatus & FileStatus.IsEditing) == FileStatus.IsEditing) @@ -399,20 +392,20 @@ public bool CanEdit(File file) public bool CanEdit(Deal deal) { - return (IsAdmin || deal.ResponsibleID == SecurityContext.CurrentAccount.ID || deal.CreateBy == SecurityContext.CurrentAccount.ID || - !IsPrivate(deal) || GetAccessSubjectTo(deal).ContainsKey(SecurityContext.CurrentAccount.ID)); + return (IsAdmin || deal.ResponsibleID == _securityContext.CurrentAccount.ID || deal.CreateBy == _securityContext.CurrentAccount.ID || + !IsPrivate(deal) || GetAccessSubjectTo(deal).ContainsKey(_securityContext.CurrentAccount.ID)); } public bool CanEdit(RelationshipEvent relationshipEvent) { - var userId = SecurityContext.CurrentAccount.ID; + var userId = _securityContext.CurrentAccount.ID; if (IsAdmin) return true; if (relationshipEvent.ContactID > 0) { - var contactObj = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); + var contactObj = _daoFactory.GetContactDao().GetByID(relationshipEvent.ContactID); if (contactObj != null) { if (CanEdit(contactObj)) return true; @@ -423,7 +416,7 @@ public bool CanEdit(RelationshipEvent relationshipEvent) if (relationshipEvent.EntityType == EntityType.Case) { - var caseObj = DaoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); + var caseObj = _daoFactory.GetCasesDao().GetByID(relationshipEvent.EntityID); if (caseObj != null) { if (CanEdit(caseObj)) return true; @@ -434,7 +427,7 @@ public bool CanEdit(RelationshipEvent relationshipEvent) if (relationshipEvent.EntityType == EntityType.Opportunity) { - var dealObj = DaoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); + var dealObj = _daoFactory.GetDealDao().GetByID(relationshipEvent.EntityID); if (dealObj != null) { if (CanEdit(dealObj)) return true; @@ -448,23 +441,23 @@ public bool CanEdit(RelationshipEvent relationshipEvent) public bool CanEdit(Contact contact) { - return contact.ShareType == ShareType.ReadWrite || IsAdmin || GetAccessSubjectTo(contact).ContainsKey(SecurityContext.CurrentAccount.ID); + return contact.ShareType == ShareType.ReadWrite || IsAdmin || GetAccessSubjectTo(contact).ContainsKey(_securityContext.CurrentAccount.ID); } public bool CanEdit(Task task) { - return (IsAdmin || task.ResponsibleID == SecurityContext.CurrentAccount.ID || task.CreateBy == SecurityContext.CurrentAccount.ID); + return (IsAdmin || task.ResponsibleID == _securityContext.CurrentAccount.ID || task.CreateBy == _securityContext.CurrentAccount.ID); } public bool CanEdit(Cases cases) { - return (IsAdmin || cases.CreateBy == SecurityContext.CurrentAccount.ID || - !IsPrivate(cases) || GetAccessSubjectTo(cases).ContainsKey(SecurityContext.CurrentAccount.ID)); + return (IsAdmin || cases.CreateBy == _securityContext.CurrentAccount.ID || + !IsPrivate(cases) || GetAccessSubjectTo(cases).ContainsKey(_securityContext.CurrentAccount.ID)); } public bool CanEdit(Invoice invoice) { - return (IsAdmin || invoice.CreateBy == SecurityContext.CurrentAccount.ID) && invoice.Status == InvoiceStatus.Draft; + return (IsAdmin || invoice.CreateBy == _securityContext.CurrentAccount.ID) && invoice.Status == InvoiceStatus.Draft; } public bool CanEdit(InvoiceTax invoiceTax) @@ -480,23 +473,23 @@ public bool CanEdit(InvoiceItem invoiceItem) public bool CanDelete(Contact contact) { - return CanEdit(contact) && DaoFactory.GetContactDao().CanDelete(contact.ID); + return CanEdit(contact) && _daoFactory.GetContactDao().CanDelete(contact.ID); } public bool CanDelete(Invoice invoice) { - return (IsAdmin || invoice.CreateBy == SecurityContext.CurrentAccount.ID); + return (IsAdmin || invoice.CreateBy == _securityContext.CurrentAccount.ID); } public bool CanDelete(InvoiceItem invoiceItem) { - return CanEdit(invoiceItem) && DaoFactory.GetInvoiceItemDao().CanDelete(invoiceItem.ID); + return CanEdit(invoiceItem) && _daoFactory.GetInvoiceItemDao().CanDelete(invoiceItem.ID); } public bool CanDelete(InvoiceTax invoiceTax) { - return CanEdit(invoiceTax) && DaoFactory.GetInvoiceTaxDao().CanDelete(invoiceTax.ID); + return CanEdit(invoiceTax) && _daoFactory.GetInvoiceTaxDao().CanDelete(invoiceTax.ID); } @@ -666,12 +659,12 @@ public void DemandCreateOrUpdate(Deal deal) deal.DealMilestoneID <= 0 || string.IsNullOrEmpty(deal.BidCurrency)) throw new ArgumentException(); - var listItem = DaoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); + var listItem = _daoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID); if (listItem == null) throw new ArgumentException(CRMErrorsResource.DealMilestoneNotFound); if (deal.ContactID != 0) { - var contact = DaoFactory.GetContactDao().GetByID(deal.ContactID); + var contact = _daoFactory.GetContactDao().GetByID(deal.ContactID); if (contact == null) throw new ArgumentException(); if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); @@ -682,7 +675,7 @@ public void DemandCreateOrUpdate(Deal deal) } else { - if (CurrencyProvider.Get(deal.BidCurrency.ToUpper()) == null) + if (_currencyProvider.Get(deal.BidCurrency.ToUpper()) == null) { throw new ArgumentException(); } @@ -699,13 +692,13 @@ public void DemandCreateOrUpdate(InvoiceLine line, Invoice targetInvoice) if (targetInvoice == null || targetInvoice.ID != line.InvoiceID) throw new ArgumentException(); if (!CanEdit(targetInvoice)) throw CreateSecurityException(); - if (!DaoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) + if (!_daoFactory.GetInvoiceItemDao().IsExist(line.InvoiceItemID)) throw new ArgumentException(); - if (line.InvoiceTax1ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) + if (line.InvoiceTax1ID > 0 && !_daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax1ID)) throw new ArgumentException(); - if (line.InvoiceTax2ID > 0 && !DaoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) + if (line.InvoiceTax2ID > 0 && !_daoFactory.GetInvoiceTaxDao().IsExist(line.InvoiceTax2ID)) throw new ArgumentException(); } @@ -720,29 +713,29 @@ public void DemandCreateOrUpdate(Invoice invoice) String.IsNullOrEmpty(invoice.Terms)) throw new ArgumentException(); - var contact = DaoFactory.GetContactDao().GetByID(invoice.ContactID); + var contact = _daoFactory.GetContactDao().GetByID(invoice.ContactID); if (contact == null) throw new ArgumentException(); if (!CanAccessTo(contact)) throw new SecurityException(CRMErrorsResource.AccessDenied); if (invoice.ConsigneeID != 0 && invoice.ConsigneeID != invoice.ContactID) { - var consignee = DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID); + var consignee = _daoFactory.GetContactDao().GetByID(invoice.ConsigneeID); if (consignee == null) throw new ArgumentException(); if (!CanAccessTo(consignee)) throw new SecurityException(CRMErrorsResource.AccessDenied); } if (invoice.EntityID != 0) { - var deal = DaoFactory.GetDealDao().GetByID(invoice.EntityID); + var deal = _daoFactory.GetDealDao().GetByID(invoice.EntityID); if (deal == null) throw new ArgumentException(); if (!CanAccessTo(deal)) throw new SecurityException(CRMErrorsResource.AccessDenied); - var dealMembers = DaoFactory.GetDealDao().GetMembers(invoice.EntityID); + var dealMembers = _daoFactory.GetDealDao().GetMembers(invoice.EntityID); if (!dealMembers.Contains(invoice.ContactID)) throw new ArgumentException(); } - if (CurrencyProvider.Get(invoice.Currency.ToUpper()) == null) + if (_currencyProvider.Get(invoice.Currency.ToUpper()) == null) { throw new ArgumentException(); } @@ -757,13 +750,13 @@ public bool IsAdmin { get { - return IsAdministrator(SecurityContext.CurrentAccount.ID); + return IsAdministrator(_securityContext.CurrentAccount.ID); } } public bool IsAdministrator(Guid userId) { - return WebItemSecurity.IsProductAdministrator(ProductEntryPoint.ID, userId); + return _webItemSecurity.IsProductAdministrator(ProductEntryPoint.ID, userId); } public IEnumerable FilterRead(IEnumerable tasks) @@ -774,54 +767,54 @@ public IEnumerable FilterRead(IEnumerable tasks) var result = tasks.ToList(); var contactIDs = result - .Where(x => x.ResponsibleID != SecurityContext.CurrentAccount.ID) + .Where(x => x.ResponsibleID != _securityContext.CurrentAccount.ID) .Select(x => x.ContactID) .Distinct() .ToList(); if (contactIDs.Any()) { - contactIDs = DaoFactory.GetContactDao() + contactIDs = _daoFactory.GetContactDao() .GetContacts(contactIDs.ToArray()) .Select(x => x.ID) .ToList(); - result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); + result = result.Where(x => x.ContactID == 0 || contactIDs.Contains(x.ContactID) || x.ResponsibleID == _securityContext.CurrentAccount.ID).ToList(); if (!result.Any()) return Enumerable.Empty(); } - var casesIds = result.Where(x => x.EntityType == EntityType.Case && x.ResponsibleID != SecurityContext.CurrentAccount.ID) + var casesIds = result.Where(x => x.EntityType == EntityType.Case && x.ResponsibleID != _securityContext.CurrentAccount.ID) .Select(x => x.EntityID) .Distinct() .ToList(); if (casesIds.Any()) { - casesIds = DaoFactory.GetCasesDao() + casesIds = _daoFactory.GetCasesDao() .GetCases(casesIds.ToArray()) .Select(x => x.ID) .ToList(); - result = result.Where(x => x.EntityID == 0 || casesIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID).ToList(); + result = result.Where(x => x.EntityID == 0 || casesIds.Contains(x.EntityID) || x.ResponsibleID == _securityContext.CurrentAccount.ID).ToList(); if (!result.Any()) return Enumerable.Empty(); } - var dealsIds = result.Where(x => x.EntityType == EntityType.Opportunity && x.ResponsibleID != SecurityContext.CurrentAccount.ID) + var dealsIds = result.Where(x => x.EntityType == EntityType.Opportunity && x.ResponsibleID != _securityContext.CurrentAccount.ID) .Select(x => x.EntityID) .Distinct() .ToList(); if (dealsIds.Any()) { - dealsIds = DaoFactory.GetDealDao() + dealsIds = _daoFactory.GetDealDao() .GetDeals(dealsIds.ToArray()) .Select(x => x.ID) .ToList(); result = result - .Where(x => x.EntityID == 0 || dealsIds.Contains(x.EntityID) || x.ResponsibleID == SecurityContext.CurrentAccount.ID) + .Where(x => x.EntityID == 0 || dealsIds.Contains(x.EntityID) || x.ResponsibleID == _securityContext.CurrentAccount.ID) .ToList(); if (!result.Any()) return Enumerable.Empty(); @@ -843,7 +836,7 @@ public IEnumerable FilterRead(IEnumerable invoices) if (contactIDs.Any()) { - contactIDs = DaoFactory.GetContactDao() + contactIDs = _daoFactory.GetContactDao() .GetContacts(contactIDs.ToArray()) .Select(x => x.ID) .ToList(); @@ -858,7 +851,7 @@ public IEnumerable FilterRead(IEnumerable invoices) public bool CanGoToFeed(Task task) { - return IsAdmin || task.ResponsibleID == SecurityContext.CurrentAccount.ID || task.CreateBy == SecurityContext.CurrentAccount.ID; + return IsAdmin || task.ResponsibleID == _securityContext.CurrentAccount.ID || task.CreateBy == _securityContext.CurrentAccount.ID; } } } \ No newline at end of file From f1ca0971fdaae2087a1e5a7a11f7aa30ecf8f997 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Sat, 15 May 2021 17:42:16 +0300 Subject: [PATCH 49/61] crm: fixed work with sql queries --- products/ASC.CRM/Server/Classes/Global.cs | 47 ++--- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 23 ++- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 136 +++++-------- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 105 ++++------ .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 107 ++++------ .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 85 ++++---- .../Server/Core/Dao/RelationshipEventDao.cs | 103 ++++------ products/ASC.CRM/Server/Core/Dao/TagDao.cs | 18 +- .../Core/Dao/TaskTemplateContainerDao.cs | 187 ++++++------------ .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 46 ++--- products/ASC.CRM/Server/Core/EF/DbCase.cs | 6 +- products/ASC.CRM/Server/Core/EF/DbContact.cs | 8 +- .../ASC.CRM/Server/Core/EF/DbContactInfo.cs | 4 +- products/ASC.CRM/Server/Core/EF/DbDeal.cs | 8 +- .../ASC.CRM/Server/Core/EF/DbFieldValue.cs | 6 +- .../Server/Core/EF/DbRelationshipEvent.cs | 8 +- products/ASC.CRM/Server/Core/EF/DbTask.cs | 12 +- .../Server/Core/Entities/TaskTemplate.cs | 8 + .../Core/Entities/TaskTemplateContainer.cs | 3 + 19 files changed, 369 insertions(+), 551 deletions(-) diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 0fe17aeb859..81b0828747e 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -111,38 +111,39 @@ public IDataStore GetStoreTemplate() public bool CanCreateProjects() { - try - { - var apiUrl = String.Format("{0}project/securityinfo.json", SetupInfo.WebApiBaseUrl); + throw new NotImplementedException(); - var cacheKey = String.Format("{0}-{1}", SecurityContext.CurrentAccount.ID, apiUrl); + //try + //{ + // var apiUrl = String.Format("{0}project/securityinfo.json", SetupInfo.WebApiBaseUrl); - bool canCreateProject = false; + // var cacheKey = String.Format("{0}-{1}", SecurityContext.CurrentAccount.ID, apiUrl); - throw new NotImplementedException(); - //if (HttpRuntime.Cache[cacheKey] != null) - // return Convert.ToBoolean(HttpRuntime.Cache[cacheKey]); + // bool canCreateProject = false; - //var apiServer = new Api.ApiServer(); + // //if (HttpRuntime.Cache[cacheKey] != null) + // // return Convert.ToBoolean(HttpRuntime.Cache[cacheKey]); - //var responseApi = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(apiServer.GetApiResponse(apiUrl, "GET"))))["response"]; + // //var apiServer = new Api.ApiServer(); - //if (responseApi.HasValues) - // canCreateProject = Convert.ToBoolean(responseApi["canCreateProject"].Value()); - //else - // canCreateProject = false; + // //var responseApi = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(apiServer.GetApiResponse(apiUrl, "GET"))))["response"]; - //HttpRuntime.Cache.Remove(cacheKey); - //HttpRuntime.Cache.Insert(cacheKey, canCreateProject, null, System.Web.Caching.Cache.NoAbsoluteExpiration, - // TimeSpan.FromMinutes(5)); + // //if (responseApi.HasValues) + // // canCreateProject = Convert.ToBoolean(responseApi["canCreateProject"].Value()); + // //else + // // canCreateProject = false; - return canCreateProject; + // //HttpRuntime.Cache.Remove(cacheKey); + // //HttpRuntime.Cache.Insert(cacheKey, canCreateProject, null, System.Web.Caching.Cache.NoAbsoluteExpiration, + // // TimeSpan.FromMinutes(5)); - } - catch - { - return false; - } + // return canCreateProject; + + //} + //catch + //{ + // return false; + //} } diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 8cbab23b828..f667ee076b8 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -42,6 +42,7 @@ using AutoMapper; using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -65,7 +66,7 @@ public ContactInfoDao( tenantManager, securityContext, logger, - ascCache, + ascCache, mapper) { _tenantUtil = tenantUtil; @@ -75,18 +76,17 @@ public ContactInfoDao( public ContactInfo GetByID(int id) { var dbEntity = CrmDbContext.ContactsInfo.Find(id); - + + if (dbEntity.TenantId != TenantID) return null; + return _mapper.Map(dbEntity); } public void Delete(int id) { - var itemToDelete = new DbContactInfo - { - Id = id - }; - - CrmDbContext.ContactsInfo.Remove(itemToDelete); + var dbEntity = CrmDbContext.ContactsInfo.Find(id); + + CrmDbContext.Remove(dbEntity); CrmDbContext.SaveChanges(); _factoryIndexerContactInfo.Delete(r => r.Where(a => a.Id, id)); @@ -96,8 +96,11 @@ public void DeleteByContact(int contactID) { if (contactID <= 0) return; - CrmDbContext.RemoveRange(Query(CrmDbContext.ContactsInfo) - .Where(x => x.ContactId == contactID)); + var dbEntities = Query(CrmDbContext.ContactsInfo) + .AsNoTracking() + .Where(x => x.ContactId == contactID); + + CrmDbContext.RemoveRange(dbEntities); CrmDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 3f13f1bd6fd..2dde6fc07fd 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -53,13 +53,11 @@ namespace ASC.CRM.Core.Dao public class InvoiceItemDao : AbstractDao { private CrmSecurity _crmSecurity { get; } - private TenantUtil _tTenantUtil { get; } public InvoiceItemDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, - TenantUtil tenantUtil, CrmSecurity crmSecurity, IOptionsMonitor logger, ICache ascCache, @@ -71,7 +69,6 @@ IMapper mapper ascCache, mapper) { - _tTenantUtil = tenantUtil; _crmSecurity = crmSecurity; } @@ -96,7 +93,9 @@ public List GetAll() } public List GetAllInDb() { - var dbInvoiceItems = Query(CrmDbContext.InvoiceItem).ToList(); + var dbInvoiceItems = Query(CrmDbContext.InvoiceItem) + .AsNoTracking() + .ToList(); return _mapper.Map, List>(dbInvoiceItems); } @@ -104,6 +103,7 @@ public List GetAllInDb() public List GetByID(int[] ids) { var dbInvoiceItems = Query(CrmDbContext.InvoiceItem) + .AsNoTracking() .Where(x => ids.Contains(x.Id)) .ToList(); @@ -112,9 +112,9 @@ public List GetByID(int[] ids) public InvoiceItem GetByID(int id) { - var dbInvoiceItems = Query(CrmDbContext.InvoiceItem).FirstOrDefault(x => x.Id == id); + var dbEntity = CrmDbContext.InvoiceItem.Find(id); - return _mapper.Map(dbInvoiceItems); + return _mapper.Map(dbEntity); } public List GetInvoiceItems(IEnumerable ids) @@ -122,11 +122,11 @@ public List GetInvoiceItems(IEnumerable ids) if (ids == null || !ids.Any()) return new List(); var dbInvoiceItems = Query(CrmDbContext.InvoiceItem) - .Where(x => ids.Contains(x.Id)) - .ToList(); + .AsNoTracking() + .Where(x => ids.Contains(x.Id)) + .ToList(); return _mapper.Map, List>(dbInvoiceItems); - } public List GetInvoiceItems( @@ -250,7 +250,7 @@ public InvoiceItem SaveOrUpdateInvoiceItem(InvoiceItem invoiceItem) private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) { - if (invoiceItem.Price <= 0 || String.IsNullOrEmpty(invoiceItem.Title)) + if (invoiceItem.Price <= 0 || string.IsNullOrEmpty(invoiceItem.Title)) throw new ArgumentException(); if (invoiceItem.Price > Global.MaxInvoiceItemPrice) @@ -258,69 +258,28 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) if (!_crmSecurity.IsAdmin) _crmSecurity.CreateSecurityException(); - if (String.IsNullOrEmpty(invoiceItem.Description)) - { - invoiceItem.Description = String.Empty; - } - if (String.IsNullOrEmpty(invoiceItem.StockKeepingUnit)) - { - invoiceItem.StockKeepingUnit = String.Empty; - } - if (!IsExistInDb(invoiceItem.ID)) + var dbEntity = new DbInvoiceItem { - var itemToInsert = new DbInvoiceItem - { - Title = invoiceItem.Title, - Description = invoiceItem.Description, - StockKeepingUnit = invoiceItem.StockKeepingUnit, - Price = invoiceItem.Price, - StockQuantity = invoiceItem.StockQuantity, - TrackInventory = invoiceItem.TrackInventory, - InvoiceTax1Id = invoiceItem.InvoiceTax1ID, - InvoiceTax2Id = invoiceItem.InvoiceTax2ID, - Currency = String.Empty, - CreateOn = DateTime.UtcNow, - CreateBy = _securityContext.CurrentAccount.ID, - LastModifedOn = DateTime.Now, - LastModifedBy = _securityContext.CurrentAccount.ID, - TenantId = TenantID - }; - - CrmDbContext.Add(itemToInsert); - CrmDbContext.SaveChanges(); - - invoiceItem.ID = itemToInsert.Id; - - - - } - else - { - - var itemToUpdate = Query(CrmDbContext.InvoiceItem).Single(x => x.Id == invoiceItem.ID); - var oldInvoiceItem = _mapper.Map(itemToUpdate); - - _crmSecurity.DemandEdit(oldInvoiceItem); - - itemToUpdate.Title = invoiceItem.Title; - itemToUpdate.Description = invoiceItem.Description; - itemToUpdate.StockKeepingUnit = invoiceItem.StockKeepingUnit; - itemToUpdate.Price = invoiceItem.Price; - itemToUpdate.StockQuantity = invoiceItem.StockQuantity; - itemToUpdate.TrackInventory = invoiceItem.TrackInventory; - itemToUpdate.InvoiceTax1Id = invoiceItem.InvoiceTax1ID; - itemToUpdate.InvoiceTax2Id = invoiceItem.InvoiceTax2ID; - - itemToUpdate.Currency = invoiceItem.Currency; - itemToUpdate.LastModifedOn = invoiceItem.LastModifedOn; - itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - - CrmDbContext.Add(itemToUpdate); - CrmDbContext.SaveChanges(); - + Id = invoiceItem.ID, + Title = invoiceItem.Title, + Description = invoiceItem.Description, + StockKeepingUnit = invoiceItem.StockKeepingUnit, + Price = invoiceItem.Price, + StockQuantity = invoiceItem.StockQuantity, + TrackInventory = invoiceItem.TrackInventory, + InvoiceTax1Id = invoiceItem.InvoiceTax1ID, + InvoiceTax2Id = invoiceItem.InvoiceTax2ID, + Currency = String.Empty, + CreateOn = DateTime.UtcNow, + CreateBy = _securityContext.CurrentAccount.ID, + LastModifedOn = DateTime.Now, + LastModifedBy = _securityContext.CurrentAccount.ID, + TenantId = TenantID + }; - } + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); return invoiceItem; } @@ -328,6 +287,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) public InvoiceItem DeleteInvoiceItem(int invoiceItemID) { var invoiceItem = GetByID(invoiceItemID); + if (invoiceItem == null) return null; _crmSecurity.DemandDelete(invoiceItem); @@ -346,37 +306,35 @@ public InvoiceItem DeleteInvoiceItem(int invoiceItemID) return invoiceItem; } - public List DeleteBatchInvoiceItems(int[] invoiceItemIDs) + public List DeleteBatchInvoiceItems(int[] ids) { - if (invoiceItemIDs == null || !invoiceItemIDs.Any()) return null; + var result = new List(); - var items = GetInvoiceItems(invoiceItemIDs).Where(_crmSecurity.CanDelete).ToList(); + foreach (var id in ids) + { + var dbEntity = CrmDbContext.InvoiceItem.Find(id); - if (!items.Any()) return items; + var entity = _mapper.Map(dbEntity); - // Delete relative keys - /*_cache.Remove(_invoiceItemCacheKey); - _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ + result.Add(entity); - DeleteBatchItemsExecute(items); + _crmSecurity.DemandDelete(entity); - return items; - } - - private void DeleteBatchItemsExecute(List items) - { - CrmDbContext.RemoveRange(items.ConvertAll(x => new DbInvoiceItem - { - Id = x.ID, - TenantId = TenantID - })); + CrmDbContext.Remove(dbEntity); + } CrmDbContext.SaveChanges(); + + // Delete relative keys + /*_cache.Remove(_invoiceItemCacheKey); + _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ + + return result; } private IQueryable GetDbInvoiceItemByFilters( ICollection exceptIDs, - String searchText, + string searchText, int status, bool? inventoryStock) { diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 7d210477966..273684ed70c 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -42,6 +42,7 @@ using AutoMapper; using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Newtonsoft.Json; @@ -94,22 +95,30 @@ public static string GetJson(InvoiceTax invoiceTax) public List GetAll() { - var dbInvoiceLines = Query(CrmDbContext.InvoiceLine) + var dbEntities = Query(CrmDbContext.InvoiceLine) + .AsNoTracking() .ToList(); - return _mapper.Map, List>(dbInvoiceLines); + return _mapper.Map, List>(dbEntities); } public List GetByID(int[] ids) { - var dbInvoiceLines = Query(CrmDbContext.InvoiceLine).Where(x => ids.Contains(x.Id)).ToList(); + var dbEntities = Query(CrmDbContext.InvoiceLine) + .AsNoTracking() + .Where(x => ids.Contains(x.Id)) + .ToList(); - return _mapper.Map, List>(dbInvoiceLines); + return _mapper.Map, List>(dbEntities); } public InvoiceLine GetByID(int id) { - return _mapper.Map(Query(CrmDbContext.InvoiceLine).FirstOrDefault(x => x.Id == id)); + var dbEntity = CrmDbContext.InvoiceLine.Find(id); + + if (dbEntity.TenantId != TenantID) return null; + + return _mapper.Map(dbEntity); } public List GetInvoiceLines(int invoiceID) @@ -124,7 +133,7 @@ public List GetInvoiceLinesInDb(int invoiceID) .OrderBy(x => x.SortOrder) .ToList(); - return _mapper.Map, List>(dbInvoiceLines); + return _mapper.Map, List>(dbInvoiceLines); } public int SaveOrUpdateInvoiceLine(InvoiceLine invoiceLine) @@ -139,67 +148,32 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) if (invoiceLine.InvoiceID <= 0 || invoiceLine.InvoiceItemID <= 0) throw new ArgumentException(); - if (String.IsNullOrEmpty(invoiceLine.Description)) - { - invoiceLine.Description = String.Empty; - } - - if (Query(CrmDbContext.InvoiceLine).Where(x => x.Id == invoiceLine.ID).Any()) - { - - var itemToInsert = new DbInvoiceLine - { - InvoiceId = invoiceLine.InvoiceItemID, - InvoiceItemId = invoiceLine.InvoiceItemID, - InvoiceTax1Id = invoiceLine.InvoiceTax1ID, - InvoiceTax2Id = invoiceLine.InvoiceTax2ID, - SortOrder = invoiceLine.SortOrder, - Description = invoiceLine.Description, - Quantity = invoiceLine.Quantity, - Price = invoiceLine.Price, - Discount = invoiceLine.Discount, - TenantId = TenantID - }; - - CrmDbContext.Add(itemToInsert); - CrmDbContext.SaveChanges(); - - invoiceLine.ID = itemToInsert.Id; - } - else + var dbEntity = new DbInvoiceLine { - var itemToUpdate = Query(CrmDbContext.InvoiceLine).Single(x => x.Id == invoiceLine.ID); - - itemToUpdate.InvoiceId = invoiceLine.InvoiceID; - itemToUpdate.InvoiceItemId = invoiceLine.InvoiceItemID; - itemToUpdate.InvoiceTax1Id = invoiceLine.InvoiceTax1ID; - itemToUpdate.InvoiceTax2Id = invoiceLine.InvoiceTax2ID; - itemToUpdate.SortOrder = invoiceLine.SortOrder; - itemToUpdate.Description = invoiceLine.Description; - itemToUpdate.Quantity = invoiceLine.Quantity; - itemToUpdate.Price = invoiceLine.Price; - itemToUpdate.Discount = invoiceLine.Discount; - - CrmDbContext.Update(itemToUpdate); - - CrmDbContext.SaveChanges(); - - - } + Id = invoiceLine.ID, + InvoiceId = invoiceLine.InvoiceItemID, + InvoiceItemId = invoiceLine.InvoiceItemID, + InvoiceTax1Id = invoiceLine.InvoiceTax1ID, + InvoiceTax2Id = invoiceLine.InvoiceTax2ID, + SortOrder = invoiceLine.SortOrder, + Description = invoiceLine.Description, + Quantity = invoiceLine.Quantity, + Price = invoiceLine.Price, + Discount = invoiceLine.Discount, + TenantId = TenantID + }; + + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); - return invoiceLine.ID; + return dbEntity.Id; } - public void DeleteInvoiceLine(int invoiceLineID) + public void DeleteInvoiceLine(int id) { - var invoiceLine = GetByID(invoiceLineID); - - if (invoiceLine == null) return; - - var itemToDelete = new DbInvoiceLine { Id = invoiceLineID }; - - CrmDbContext.Attach(itemToDelete); - CrmDbContext.Remove(itemToDelete); + var dbEntity = CrmDbContext.InvoiceLine.Find(id); + + CrmDbContext.Remove(dbEntity); CrmDbContext.SaveChanges(); /*_cache.Remove(_invoiceItemCacheKey); @@ -208,7 +182,8 @@ public void DeleteInvoiceLine(int invoiceLineID) public void DeleteInvoiceLines(int invoiceID) { - var itemToDelete = Query(CrmDbContext.InvoiceLine).Where(x => x.InvoiceId == invoiceID); + var itemToDelete = Query(CrmDbContext.InvoiceLine) + .Where(x => x.InvoiceId == invoiceID); CrmDbContext.RemoveRange(itemToDelete); CrmDbContext.SaveChanges(); @@ -225,8 +200,8 @@ public Boolean CanDelete(int invoiceLineID) public Boolean CanDeleteInDb(int invoiceLineID) { var invoiceID = Query(CrmDbContext.InvoiceLine) - .Where(x => x.Id == invoiceLineID) - .Select(x => x.InvoiceId); + .Where(x => x.Id == invoiceLineID) + .Select(x => x.InvoiceId); if (!invoiceID.Any()) return false; diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 487a3ef3496..6d1ec6642df 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -26,22 +26,19 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; -using ASC.Core.Tenants; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using AutoMapper; -using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -49,13 +46,11 @@ namespace ASC.CRM.Core.Dao [Scope] public class InvoiceTaxDao : AbstractDao { - private TenantUtil _tenantUtil { get; } private CrmSecurity _crmSecurity { get; } public InvoiceTaxDao( DbContextManager dbContextManager, TenantManager tenantManager, - TenantUtil tenantUtil, SecurityContext securityContext, IOptionsMonitor logger, ICache ascCache, @@ -68,13 +63,12 @@ IMapper mapper ascCache, mapper) { - _tenantUtil = tenantUtil; _mapper = mapper; } - public Boolean IsExist(int invoiceTaxID) + public Boolean IsExist(int id) { - return CrmDbContext.InvoiceTax.Where(x => x.Id == invoiceTaxID).Any(); + return CrmDbContext.InvoiceTax.Where(x => x.Id == id).Any(); } public Boolean IsExist(String invoiceName) @@ -92,7 +86,11 @@ public Boolean CanDelete(int invoiceTaxID) public List GetAll() { - return _mapper.Map, List>(Query(CrmDbContext.InvoiceTax).ToList()); + var dbEntities = Query(CrmDbContext.InvoiceTax) + .AsNoTracking() + .ToList(); + + return _mapper.Map, List>(dbEntities); } public DateTime GetMaxLastModified() @@ -106,18 +104,21 @@ public DateTime GetMaxLastModified() public List GetByID(int[] ids) { - var result = Query(CrmDbContext.InvoiceTax) + var dbEntities = Query(CrmDbContext.InvoiceTax) + .AsNoTracking() .Where(x => ids.Contains(x.Id)) .ToList(); - return _mapper.Map, List>(result); + return _mapper.Map, List>(dbEntities); } public InvoiceTax GetByID(int id) { - var invoiceTax = CrmDbContext.InvoiceTax.FirstOrDefault(x => x.Id == id); + var dbEntity = CrmDbContext.InvoiceTax.Find(id); - return _mapper.Map(invoiceTax); + if (dbEntity.TenantId != TenantID) return null; + + return _mapper.Map(dbEntity); } public InvoiceTax SaveOrUpdateInvoiceTax(InvoiceTax invoiceTax) @@ -133,77 +134,43 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) if (String.IsNullOrEmpty(invoiceTax.Name)) throw new ArgumentException(); - invoiceTax.LastModifedBy = _securityContext.CurrentAccount.ID; - invoiceTax.LastModifedOn = DateTime.UtcNow; - - if (!Query(CrmDbContext.InvoiceTax).Where(x => x.Id == invoiceTax.ID).Any()) + var dbEntity = new DbInvoiceTax { - invoiceTax.CreateOn = DateTime.UtcNow; - invoiceTax.CreateBy = _securityContext.CurrentAccount.ID; - - var itemToInsert = new DbInvoiceTax - { - Name = invoiceTax.Name, - Description = invoiceTax.Description, - Rate = invoiceTax.Rate, - CreateOn = invoiceTax.CreateOn, - CreateBy = _securityContext.CurrentAccount.ID, - LastModifedBy = invoiceTax.LastModifedBy, - LastModifedOn = invoiceTax.LastModifedOn, - TenantId = TenantID - }; - - CrmDbContext.InvoiceTax.Add(itemToInsert); - - CrmDbContext.SaveChanges(); - - invoiceTax.ID = itemToInsert.Id; - } - else - { - var oldInvoiceTax = GetByID(invoiceTax.ID); - - _crmSecurity.DemandEdit(oldInvoiceTax); - - var itemToUpdate = Query(CrmDbContext.InvoiceTax) - .FirstOrDefault(x => x.Id == invoiceTax.ID); - - itemToUpdate.Name = invoiceTax.Name; - itemToUpdate.Description = invoiceTax.Description; - itemToUpdate.Rate = invoiceTax.Rate; - itemToUpdate.LastModifedOn = itemToUpdate.LastModifedOn; - itemToUpdate.LastModifedBy = itemToUpdate.LastModifedBy; - - CrmDbContext.InvoiceTax.Update(itemToUpdate); + Id = invoiceTax.ID, + Name = invoiceTax.Name, + Description = invoiceTax.Description, + Rate = invoiceTax.Rate, + CreateOn = invoiceTax.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoiceTax.CreateOn, + CreateBy = invoiceTax.CreateBy == Guid.Empty ? _securityContext.CurrentAccount.ID : invoiceTax.CreateBy, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = _securityContext.CurrentAccount.ID, + TenantId = TenantID + }; - CrmDbContext.SaveChanges(); - } + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); return invoiceTax; } - public InvoiceTax DeleteInvoiceTax(int invoiceTaxID) + public InvoiceTax DeleteInvoiceTax(int id) { - var invoiceTax = GetByID(invoiceTaxID); + var dbEntity = CrmDbContext.InvoiceTax.Find(id); + + var entity = _mapper.Map(dbEntity); - if (invoiceTax == null) return null; + if (entity == null) return null; - _crmSecurity.DemandDelete(invoiceTax); - - var itemToDelete = new DbInvoiceTax - { - Id = invoiceTaxID - }; - - CrmDbContext.Attach(invoiceTax); - CrmDbContext.Remove(itemToDelete); + _crmSecurity.DemandDelete(entity); + + CrmDbContext.InvoiceTax.Remove(dbEntity); CrmDbContext.SaveChanges(); /* _cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceTaxCacheKey, String.Empty);*/ - return invoiceTax; + return entity; } } diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 8263d18bf34..722a5777bdb 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -52,6 +52,7 @@ namespace ASC.CRM.Core.Dao public class ListItemDao : AbstractDao { public ListItemDao( + CrmSecurity crmSecurity, DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, @@ -66,45 +67,47 @@ public ListItemDao( mapper) { - } public bool IsExist(ListType listType, String title) { - return CrmDbContext.ListItem + return Query(CrmDbContext.ListItem) .Where(x => x.TenantId == TenantID && x.ListType == listType && String.Compare(x.Title, title, true) == 0) .Any(); } public bool IsExist(int id) { - return CrmDbContext.ListItem.Where(x => x.Id == id).Any(); + return Query(CrmDbContext.ListItem).Where(x => x.Id == id).Any(); } public List GetItems() { var dbListItems = Query(CrmDbContext.ListItem) - .OrderBy(x => x.SortOrder) - .ToList(); + .AsNoTracking() + .OrderBy(x => x.SortOrder) + .ToList(); return _mapper.Map, List>(dbListItems); } public List GetItems(ListType listType) { - var dbListItems = Query(CrmDbContext.ListItem) - .Where(x => x.ListType == listType) - .OrderBy(x => x.SortOrder) - .ToList(); + var dbEntities = Query(CrmDbContext.ListItem) + .AsNoTracking() + .Where(x => x.ListType == listType) + .OrderBy(x => x.SortOrder) + .ToList(); - return _mapper.Map, List>(dbListItems); + return _mapper.Map, List>(dbEntities); } public int GetItemsCount(ListType listType) { return Query(CrmDbContext.ListItem) .Where(x => x.ListType == listType) - .OrderBy(x => x.SortOrder).Count(); + .OrderBy(x => x.SortOrder) + .Count(); } public ListItem GetSystemListItem(int id) @@ -167,39 +170,42 @@ public ListItem GetByID(int id) { if (id < 0) return GetSystemListItem(id); - return _mapper.Map(Query(CrmDbContext.ListItem).FirstOrDefault(x => x.Id == id)); + var dbEntity = CrmDbContext.ListItem.Find(id); + + if (dbEntity.TenantId != TenantID) return null; + + return _mapper.Map(dbEntity); } public List GetItems(int[] id) { - var sqlResult = _mapper.Map, List>(CrmDbContext.ListItem.Where(x => id.Contains(x.Id)).ToList()); + var dbEntities = Query(CrmDbContext.ListItem) + .AsNoTracking() + .Where(x => id.Contains(x.Id)) + .ToList(); + + var entities = _mapper.Map, List>(dbEntities); var systemItem = id.Where(item => item < 0).Select(GetSystemListItem); - return systemItem.Any() ? sqlResult.Union(systemItem).ToList() : sqlResult; + return systemItem.Any() ? entities.Union(systemItem).ToList() : entities; } public List GetAll() { - var dbListItems = CrmDbContext - .ListItem - .ToList(); + var dbListItems = Query(CrmDbContext.ListItem) + .AsNoTracking() + .ToList(); return _mapper.Map, List>(dbListItems); - } public void ChangeColor(int id, string newColor) { - var listItem = new DbListItem - { - Id = id, - Color = newColor - }; + var dbEntity = CrmDbContext.ListItem.Find(id); + + dbEntity.Color = newColor; - - CrmDbContext.Attach(listItem); - CrmDbContext.Entry(listItem).Property("Color").IsModified = true; CrmDbContext.SaveChanges(); } @@ -207,7 +213,7 @@ public NameValueCollection GetColors(ListType listType) { var result = new NameValueCollection(); - Query(CrmDbContext.ListItem) + Query(CrmDbContext.ListItem) .Where(x => x.ListType == listType) .Select(x => new { x.Id, x.Color }) .ToList() @@ -219,8 +225,10 @@ public NameValueCollection GetColors(ListType listType) public ListItem GetByTitle(ListType listType, string title) { - return _mapper.Map(Query(CrmDbContext.ListItem) - .FirstOrDefault(x => String.Compare(x.Title, title, true) == 0 && x.ListType == listType)); + var dbEntity = Query(CrmDbContext.ListItem) + .FirstOrDefault(x => String.Compare(x.Title, title, true) == 0 && x.ListType == listType); + + return _mapper.Map(dbEntity); } public int GetRelativeItemsCount(ListType listType, int id) @@ -502,32 +510,25 @@ public void DeleteItem(ListType listType, int itemID, int toItemID) } } - var itemToRemove = new DbListItem { Id = itemID }; + var dbEntity = CrmDbContext.ListItem.Find(itemID); - CrmDbContext.Entry(itemToRemove).State = EntityState.Deleted; + CrmDbContext.ListItem.Remove(dbEntity); CrmDbContext.SaveChanges(); } - public void ReorderItems(ListType listType, String[] titles) + public void ReorderItems(ListType listType, string[] titles) { - using var tx = CrmDbContext.Database.BeginTransaction(); - for (int index = 0; index < titles.Length; index++) { - var itemToUpdate = Query(CrmDbContext.ListItem) - .Single(x => String.Compare(x.Title, titles[index]) == 0 && x.ListType == listType); - - itemToUpdate.SortOrder = index; + var dbEntity = Query(CrmDbContext.ListItem) + .Single(x => string.Compare(x.Title, titles[index]) == 0 && x.ListType == listType); - CrmDbContext.Update(itemToUpdate); + dbEntity.SortOrder = index; } - CrmDbContext.SaveChanges(); - - tx.Commit(); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 1ca246a8630..573cb53398a 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -63,15 +63,16 @@ namespace ASC.CRM.Core.Dao [Scope] public class RelationshipEventDao : AbstractDao { - private CrmSecurity _crmSecurity; - private TenantUtil _tenantUtil; - private FilesIntegration _filesIntegration; - private FactoryIndexerEvents _factoryIndexer; + private readonly CrmSecurity _crmSecurity; + private readonly TenantUtil _tenantUtil; + private readonly FilesIntegration _filesIntegration; + private readonly FactoryIndexerEvents _factoryIndexer; public RelationshipEventDao(DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, FilesIntegration filesIntegration, + FactoryIndexerEvents factoryIndexerEvents, CrmSecurity crmSecurity, TenantUtil tenantUtil, IOptionsMonitor logger, @@ -88,6 +89,7 @@ IMapper mapper _filesIntegration = filesIntegration; _tenantUtil = tenantUtil; _crmSecurity = crmSecurity; + _factoryIndexer = factoryIndexerEvents; } public RelationshipEvent AttachFiles(int contactID, EntityType entityType, int entityID, int[] fileIDs) @@ -123,15 +125,10 @@ public void AttachFiles(int eventID, int[] fileIDs) if (fileIDs.Length > 0) { - var dbRelationshipEvent = new DbRelationshipEvent - { - Id = eventID, - HaveFiles = true, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.RelationshipEvent.Find(eventID); - CrmDbContext.RelationshipEvent.Attach(dbRelationshipEvent); - CrmDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; + dbEntity.HaveFiles = true; + CrmDbContext.SaveChanges(); } } @@ -257,15 +254,11 @@ public List RemoveFile(File file) { if (GetFiles(eventID).Count == 0) { - var dbRelationshipEvent = new DbRelationshipEvent - { - Id = eventID, - HaveFiles = false, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.RelationshipEvent.Find(eventID); + + if (dbEntity.TenantId != TenantID) continue; - CrmDbContext.Attach(dbRelationshipEvent); - CrmDbContext.Entry(dbRelationshipEvent).Property(x => x.HaveFiles).IsModified = true; + dbEntity.HaveFiles = false; CrmDbContext.SaveChanges(); } @@ -275,8 +268,6 @@ public List RemoveFile(File file) itemToUpdate.FileId = 0; - CrmDbContext.Update(itemToUpdate); - CrmDbContext.SaveChanges(); return eventIDs; @@ -399,10 +390,18 @@ public RelationshipEvent CreateItem(RelationshipEvent item) return item; } - public RelationshipEvent GetByID(int eventID) + public RelationshipEvent GetByID(int id) { - return ToRelationshipEvent(Query(CrmDbContext.RelationshipEvent) - .FirstOrDefault(x => x.Id == eventID)); + var dbEntity = CrmDbContext.RelationshipEvent.Find(id); + + if (dbEntity.TenantId != TenantID) return null; + + var entity = _mapper.Map(dbEntity); + + _crmSecurity.DemandAccessTo(entity); + + return entity; + } public int GetAllItemsCount() @@ -436,7 +435,7 @@ public List GetItems( OrderBy orderBy) { - var sqlQuery = Query(CrmDbContext.RelationshipEvent); + var sqlQuery = Query(CrmDbContext.RelationshipEvent).AsNoTracking(); if (entityID > 0) switch (entityType) @@ -531,6 +530,8 @@ public List GetItems( sqlQuery = sqlQuery.Take(count); if (orderBy != null && Enum.IsDefined(typeof(RelationshipEventByType), orderBy.SortedBy)) + { + switch ((RelationshipEventByType)orderBy.SortedBy) { case RelationshipEventByType.Category: @@ -546,30 +547,13 @@ public List GetItems( sqlQuery = sqlQuery.OrderBy(x => x.CreateOn); break; } + } else + { sqlQuery = sqlQuery.OrderBy(x => x.CreateOn); + } - return sqlQuery.ToList().ConvertAll(ToRelationshipEvent); - } - - - private RelationshipEvent ToRelationshipEvent(DbRelationshipEvent relationshipEvent) - { - if (relationshipEvent == null) return null; - - return new RelationshipEvent - { - ID = relationshipEvent.Id, - ContactID = relationshipEvent.ContactId, - Content = relationshipEvent.Content, - EntityID = relationshipEvent.EntityId, - EntityType = relationshipEvent.EntityType, - CreateOn = _tenantUtil.DateTimeFromUtc(relationshipEvent.CreateOn), - CreateBy = relationshipEvent.CreateBy, - CategoryID = relationshipEvent.CategoryId, - LastModifedBy = relationshipEvent.LastModifedBy, - LastModifedOn = relationshipEvent.LastModifedOn - }; + return _mapper.Map, List>(sqlQuery.ToList()); } public void DeleteItem(int id) @@ -595,7 +579,7 @@ public void DeleteItem(RelationshipEvent item) var itemToDelete = Query(CrmDbContext.RelationshipEvent).Where(x => x.Id == item.ID).Single(); - _factoryIndexer.DeleteAsync(itemToDelete); + _factoryIndexer.Delete(itemToDelete); CrmDbContext.RelationshipEvent.Remove(itemToDelete); @@ -606,39 +590,17 @@ public void DeleteItem(RelationshipEvent item) [DataContract] internal class CrmHistoryContent { - public string to; - - public string from; - - public string cc; - - public string bcc; - - public string subject; - - public bool important; - - public string chain_id; - - public bool is_sended; - - public string date_created; - - public string introduction; - - public long message_id; - } private static string GetHistoryContentJson(JObject apiResponse) @@ -663,6 +625,7 @@ private static string GetHistoryContentJson(JObject apiResponse) using (var stream = new System.IO.MemoryStream()) { serializer.WriteObject(stream, content_struct); + return Encoding.UTF8.GetString(stream.ToArray()); } } diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 85335fe670a..62ffebe99dc 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -77,7 +77,8 @@ public bool IsExist(EntityType entityType, String tagName) private bool IsExistInDb(EntityType entityType, String tagName) { return Query(CrmDbContext.Tags) - .Where(x => x.EntityType == entityType && String.Compare(x.Title, tagName, true) == 0).Any(); + .Where(x => x.EntityType == entityType && String.Compare(x.Title, tagName, true) == 0) + .Any(); } private int GetTagId(EntityType entityType, String tagName) @@ -100,7 +101,6 @@ public String[] GetAllTags(EntityType entityType) public List> GetAllTags() { return Query(CrmDbContext.Tags) - .AsNoTracking() .OrderBy(x => x.Title) .Select(x => new KeyValuePair(x.EntityType, x.Title)).ToList(); } @@ -108,13 +108,13 @@ public List> GetAllTags() public String GetTagsLinkCountJSON(EntityType entityType) { int[] tags = GetTagsLinkCount(entityType).ToArray(); + return JsonConvert.SerializeObject(tags); } public IEnumerable GetTagsLinkCount(EntityType entityType) { return Query(CrmDbContext.Tags) - .AsNoTracking() .Join(CrmDbContext.EntityTags, x => x.Id, y => y.TagId, @@ -151,7 +151,8 @@ public String[] GetEntityTags(EntityType entityType, int entityID) }) .Where(x => x.y.EntityId == entityID && x.y.EntityType == entityType) - .Select(x => x.x.Title).ToArray(); + .Select(x => x.x.Title) + .ToArray(); } public string[] GetUnusedTags(EntityType entityType) @@ -162,14 +163,16 @@ public string[] GetUnusedTags(EntityType entityType) y => y.TagId, (x, y) => new { x, y }) .Where(x => x.y == null && x.x.EntityType == entityType) - .Select(x => x.x.Title).ToArray(); + .Select(x => x.x.Title) + .ToArray(); } public bool CanDeleteTag(EntityType entityType, String tagName) { return Query(CrmDbContext.Tags) .Where(x => string.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) - .Select(x => x.Id).SingleOrDefault() != 0; + .Select(x => x.Id) + .SingleOrDefault() != 0; } public void DeleteTag(EntityType entityType, String tagName) @@ -183,7 +186,8 @@ public void DeleteTagFromEntity(EntityType entityType, int entityID, String tagN { var tagID = Query(CrmDbContext.Tags) .Where(x => String.Compare(x.Title, tagName, true) == 0 && x.EntityType == entityType) - .Select(x => x.Id).SingleOrDefault(); + .Select(x => x.Id) + .SingleOrDefault(); if (tagID == 0) return; diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index b7ce9f3fd0a..bb359f29f08 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -64,82 +64,55 @@ IMapper mapper } - public virtual int SaveOrUpdate(TaskTemplateContainer item) + public int SaveOrUpdate(TaskTemplateContainer item) { - var dbTaskTemplateContainer = new DbTaskTemplateContainer + var dbEntity = new DbTaskTemplateContainer { Id = item.ID, Title = item.Title, EntityType = item.EntityType, - CreateOn = DateTime.UtcNow, - CreateBy = _securityContext.CurrentAccount.ID, + CreateOn = item.CreateOn == DateTime.MinValue ? DateTime.UtcNow : item.CreateOn, + CreateBy = item.CreateBy == Guid.Empty ? _securityContext.CurrentAccount.ID : item.CreateBy, LastModifedOn = DateTime.UtcNow, LastModifedBy = _securityContext.CurrentAccount.ID, - TenantId = TenantID + TenantId = TenantID }; - if (item.ID == 0 && Query(CrmDbContext.TaskTemplateContainer).Where(x => x.Id == item.ID).Any()) - { - CrmDbContext.TaskTemplateContainer.Add(dbTaskTemplateContainer); - - CrmDbContext.SaveChanges(); - - item.ID = dbTaskTemplateContainer.Id; - } - else - { - CrmDbContext.TaskTemplateContainer.Attach(dbTaskTemplateContainer); - CrmDbContext.TaskTemplateContainer.Update(dbTaskTemplateContainer); - - CrmDbContext.SaveChanges(); - } - + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); - return item.ID; + return dbEntity.Id; } - public virtual void Delete(int id) + public void Delete(int id) { - if (id <= 0) - throw new ArgumentException(); + var dbEntity = CrmDbContext.TaskTemplateContainer.Find(id); - var itemToDelete = new DbTaskTemplateContainer { Id = id }; - - CrmDbContext.TaskTemplateContainer.Attach(itemToDelete); - CrmDbContext.TaskTemplateContainer.Remove(itemToDelete); + CrmDbContext.TaskTemplateContainer.Remove(dbEntity); CrmDbContext.SaveChanges(); } - public virtual TaskTemplateContainer GetByID(int id) + public TaskTemplateContainer GetByID(int id) { - if (id <= 0) - throw new ArgumentException(); + var dbEntity = CrmDbContext.TaskTemplateContainer.Find(id); + + if (dbEntity.TenantId != TenantID) return null; - return ToObject(Query(CrmDbContext.TaskTemplateContainer).FirstOrDefault(x => x.Id == id)); + return _mapper.Map(dbEntity); } - public virtual List GetItems(EntityType entityType) + public List GetItems(EntityType entityType) { if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException("", entityType.ToString()); - return Query(CrmDbContext.TaskTemplateContainer) - .Where(x => x.EntityType == entityType) - .ToList() - .ConvertAll(ToObject); - } - - protected TaskTemplateContainer ToObject(DbTaskTemplateContainer dbTaskTemplateContainer) - { - if (dbTaskTemplateContainer == null) return null; + var dbEntities = Query(CrmDbContext.TaskTemplateContainer) + .AsNoTracking() + .Where(x => x.EntityType == entityType) + .ToList(); - return new TaskTemplateContainer - { - ID = dbTaskTemplateContainer.Id, - Title = dbTaskTemplateContainer.Title, - EntityType = dbTaskTemplateContainer.EntityType - }; + return _mapper.Map, List>(dbEntities); } } @@ -156,7 +129,7 @@ public TaskTemplateDao(DbContextManager dbContextManager, tenantManager, securityContext, logger, - cache, + cache, mapper) { @@ -164,7 +137,7 @@ public TaskTemplateDao(DbContextManager dbContextManager, public int SaveOrUpdate(TaskTemplate item) { - var itemToInsert = new DbTaskTemplate + var dbEntity = new DbTaskTemplate { Id = item.ID, Title = item.Title, @@ -175,38 +148,23 @@ public int SaveOrUpdate(TaskTemplate item) Offset = item.Offset.Ticks, DeadLineIsFixed = item.DeadLineIsFixed, ContainerId = item.ContainerID, - CreateOn = item.CreateOn, - CreateBy = item.CreateBy, + CreateOn = item.CreateOn == DateTime.MinValue ? DateTime.UtcNow : item.CreateOn, + CreateBy = item.CreateBy == Guid.Empty ? _securityContext.CurrentAccount.ID : item.CreateBy, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = _securityContext.CurrentAccount.ID, + SortOrder = item.SortOrder, TenantId = TenantID }; - if (item.ID == 0) - { - itemToInsert.CreateOn = DateTime.UtcNow; - itemToInsert.CreateBy = _securityContext.CurrentAccount.ID; - - CrmDbContext.TaskTemplates.Add(itemToInsert); - CrmDbContext.SaveChanges(); - } - else - { - - itemToInsert.LastModifedOn = DateTime.UtcNow; - itemToInsert.LastModifedBy = _securityContext.CurrentAccount.ID; - - CrmDbContext.TaskTemplates.Attach(itemToInsert); - CrmDbContext.TaskTemplates.Update(itemToInsert); + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); - CrmDbContext.SaveChanges(); - } + return dbEntity.Id; - return item.ID; } public TaskTemplate GetNext(int taskID) { - using var tx = CrmDbContext.Database.BeginTransaction(); - var sqlResult = Query(CrmDbContext.TaskTemplateTask) .Join(Query(CrmDbContext.TaskTemplates), x => x.TaskTemplateId, @@ -218,82 +176,59 @@ public TaskTemplate GetNext(int taskID) if (sqlResult == null) return null; - var result = ToObject(Query(CrmDbContext.TaskTemplates) - .FirstOrDefault(x => x.ContainerId == sqlResult.ContainerId && - x.SortOrder > sqlResult.SortOrder && !x.DeadLineIsFixed)); + var dbEntity = Query(CrmDbContext.TaskTemplates) + .FirstOrDefault(x => x.ContainerId == sqlResult.ContainerId && + x.SortOrder > sqlResult.SortOrder && !x.DeadLineIsFixed); - CrmDbContext.Remove(new DbTaskTemplateTask - { - TaskId = taskID, - TenantId = TenantID - }); + var result = _mapper.Map(dbEntity); - tx.Commit(); + var dbEntityToDelete = CrmDbContext.TaskTemplateTask.Find(taskID); + + if (dbEntityToDelete.TenantId != TenantID) return null; + + CrmDbContext.Remove(dbEntityToDelete); + CrmDbContext.SaveChanges(); return result; } public List GetAll() { - return Query(CrmDbContext.TaskTemplates) + var dbEntities = Query(CrmDbContext.TaskTemplates) + .AsNoTracking() .OrderBy(x => x.SortOrder) - .ToList() - .ConvertAll(ToObject); + .ToList(); + + return _mapper.Map, List>(dbEntities); } public List GetList(int containerID) { - if (containerID <= 0) - throw new NotImplementedException(); - - return Query(CrmDbContext.TaskTemplates) - .Where(x => x.ContainerId == containerID) - .OrderBy(x => x.SortOrder) - .ToList() - .ConvertAll(ToObject); + var dbEntities = Query(CrmDbContext.TaskTemplates) + .AsNoTracking() + .Where(x => x.ContainerId == containerID) + .OrderBy(x => x.SortOrder) + .ToList(); + + return _mapper.Map, List>(dbEntities); } - public virtual TaskTemplate GetByID(int id) + public TaskTemplate GetByID(int id) { - if (id <= 0) - throw new NotImplementedException(); + var dbEntity = CrmDbContext.TaskTemplates.Find(id); - return ToObject(CrmDbContext.TaskTemplates.FirstOrDefault(x => x.Id == id)); + if (dbEntity.TenantId != TenantID) return null; + + return _mapper.Map(dbEntity); } public virtual void Delete(int id) { - if (id <= 0) - throw new NotImplementedException(); + var dbEntity = CrmDbContext.TaskTemplateContainer.Find(id); - var itemToRemove = new DbTaskTemplate - { - Id = id - }; + CrmDbContext.Remove(dbEntity); - CrmDbContext.Entry(itemToRemove).State = EntityState.Deleted; CrmDbContext.SaveChanges(); } - - protected TaskTemplate ToObject(DbTaskTemplate dbTaskTemplate) - { - if (dbTaskTemplate == null) return null; - - return new TaskTemplate - { - ID = dbTaskTemplate.Id, - Title = dbTaskTemplate.Title, - CategoryID = dbTaskTemplate.CategoryId, - Description = dbTaskTemplate.Description, - ResponsibleID = dbTaskTemplate.ResponsibleId, - isNotify = dbTaskTemplate.IsNotify, - Offset = TimeSpan.FromTicks(dbTaskTemplate.Offset), - DeadLineIsFixed = dbTaskTemplate.DeadLineIsFixed, - ContainerID = dbTaskTemplate.ContainerId, - CreateOn = dbTaskTemplate.CreateOn, - CreateBy = dbTaskTemplate.CreateBy - }; - } } - } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index 816017494e1..0d09c75d7ca 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -76,10 +76,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.FromCurrency) - .HasName("from_currency"); + .HasDatabaseName("from_currency"); entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") @@ -103,7 +103,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.Color) .HasDefaultValueSql("'0'") @@ -125,7 +125,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("PRIMARY"); entity.HasIndex(e => e.ContactId) - .HasName("IX_Contact"); + .HasDatabaseName("IX_Contact"); }); modelBuilder.Entity(entity => @@ -134,13 +134,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("PRIMARY"); entity.HasIndex(e => e.TagId) - .HasName("tag_id"); + .HasDatabaseName("tag_id"); }); modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.EntityType, e.SortOrder }) - .HasName("entity_type"); + .HasDatabaseName("entity_type"); entity.Property(e => e.Label) .HasCharSet("utf8") @@ -155,7 +155,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.ConsigneeId).HasDefaultValueSql("'-1'"); @@ -207,7 +207,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") @@ -237,7 +237,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.Description) .HasCharSet("utf8") @@ -247,7 +247,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") @@ -269,7 +269,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.ListType }) - .HasName("list_type"); + .HasDatabaseName("list_type"); entity.Property(e => e.AdditionalParams) .HasCharSet("utf8") @@ -291,7 +291,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.Content) .HasCharSet("utf8") @@ -308,10 +308,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("PRIMARY"); entity.HasIndex(e => new { e.TenantId, e.ContactId }) - .HasName("contact_id"); + .HasDatabaseName("contact_id"); entity.HasIndex(e => new { e.TenantId, e.ProjectId }) - .HasName("project_id"); + .HasDatabaseName("project_id"); }); @@ -321,13 +321,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .HasName("PRIMARY"); entity.HasIndex(e => e.CreateBy) - .HasName("create_by"); + .HasDatabaseName("create_by"); entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); + .HasDatabaseName("create_on"); entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") @@ -337,7 +337,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.Title) .HasCharSet("utf8") @@ -348,7 +348,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.ContainerId }) - .HasName("template_id"); + .HasDatabaseName("template_id"); entity.Property(e => e.CreateBy) .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") @@ -377,7 +377,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => new { e.TenantId, e.EntityType }) - .HasName("entity_type"); + .HasDatabaseName("entity_type"); entity.Property(e => e.CreateBy) .HasDefaultValueSql("'0'") @@ -403,10 +403,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.HasIndex(e => new { e.ParentCallId, e.TenantId }) - .HasName("parent_call_id"); + .HasDatabaseName("parent_call_id"); entity.Property(e => e.Id) .HasCharSet("utf8") @@ -441,7 +441,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.Id) .HasCharSet("utf8") diff --git a/products/ASC.CRM/Server/Core/EF/DbCase.cs b/products/ASC.CRM/Server/Core/EF/DbCase.cs index 745c85540a8..f5be96586a3 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCase.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCase.cs @@ -75,13 +75,13 @@ private static void MySqlAddDbCase(this ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); + .HasDatabaseName("create_on"); entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); + .HasDatabaseName("last_modifed_on"); entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") diff --git a/products/ASC.CRM/Server/Core/EF/DbContact.cs b/products/ASC.CRM/Server/Core/EF/DbContact.cs index 8c2c81cd79e..7da0184da78 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContact.cs @@ -110,16 +110,16 @@ private static void MySqlAddDbContact(this ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); + .HasDatabaseName("create_on"); entity.HasIndex(e => new { e.LastModifedOn, e.TenantId }) - .HasName("last_modifed_on"); + .HasDatabaseName("last_modifed_on"); entity.HasIndex(e => new { e.TenantId, e.CompanyId }) - .HasName("company_id"); + .HasDatabaseName("company_id"); entity.HasIndex(e => new { e.TenantId, e.DisplayName }) - .HasName("display_name"); + .HasDatabaseName("display_name"); entity.Property(e => e.CompanyName) .HasCharSet("utf8") diff --git a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs index 37008145775..c9934313d53 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs @@ -80,10 +80,10 @@ private static void MySqlAddDbContactInfo(this ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); + .HasDatabaseName("last_modifed_on"); entity.HasIndex(e => new { e.TenantId, e.ContactId }) - .HasName("IX_Contact"); + .HasDatabaseName("IX_Contact"); entity.Property(e => e.Data) .HasCharSet("utf8") diff --git a/products/ASC.CRM/Server/Core/EF/DbDeal.cs b/products/ASC.CRM/Server/Core/EF/DbDeal.cs index 9161ab609d1..ae566dae4ae 100644 --- a/products/ASC.CRM/Server/Core/EF/DbDeal.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDeal.cs @@ -145,10 +145,10 @@ private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); entity.HasIndex(e => new { e.TenantId, e.ContactId }) - .HasName("contact_id"); + .HasDatabaseName("contact_id"); entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); + .HasDatabaseName("create_on"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") @@ -159,10 +159,10 @@ private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) .HasCollation("utf8_general_ci"); entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); + .HasDatabaseName("last_modifed_on"); entity.HasIndex(e => e.DealMilestoneId) - .HasName("deal_milestone_id"); + .HasDatabaseName("deal_milestone_id"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") diff --git a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs index b45254a8f62..0156b60474d 100644 --- a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs @@ -76,13 +76,13 @@ private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.FieldId) - .HasName("field_id"); + .HasDatabaseName("field_id"); entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); + .HasDatabaseName("last_modifed_on"); entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType, e.FieldId }) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") diff --git a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index e172cf810ae..b02aa04c090 100644 --- a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -92,16 +92,16 @@ private static void MySqlAddDbRelationshipEvent(this ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.ContactId) - .HasName("IX_Contact"); + .HasDatabaseName("IX_Contact"); entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); + .HasDatabaseName("last_modifed_on"); entity.HasIndex(e => e.TenantId) - .HasName("tenant_id"); + .HasDatabaseName("tenant_id"); entity.HasIndex(e => new { e.EntityId, e.EntityType }) - .HasName("IX_Entity"); + .HasDatabaseName("IX_Entity"); entity.Property(e => e.Content) .HasCharSet("utf8") diff --git a/products/ASC.CRM/Server/Core/EF/DbTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs index 46dd2b21a83..a891888fb84 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -105,22 +105,22 @@ public static void MySqlAddDbTask(this ModelBuilder modelBuilder) entity.ToTable("crm_task"); entity.HasIndex(e => e.CreateOn) - .HasName("create_on"); + .HasDatabaseName("create_on"); entity.HasIndex(e => e.Deadline) - .HasName("deadline"); + .HasDatabaseName("deadline"); entity.HasIndex(e => e.LastModifedOn) - .HasName("last_modifed_on"); + .HasDatabaseName("last_modifed_on"); entity.HasIndex(e => new { e.TenantId, e.ContactId }) - .HasName("IX_Contact"); + .HasDatabaseName("IX_Contact"); entity.HasIndex(e => new { e.TenantId, e.ResponsibleId }) - .HasName("responsible_id"); + .HasDatabaseName("responsible_id"); entity.HasIndex(e => new { e.TenantId, e.EntityId, e.EntityType }) - .HasName("IX_Entity"); + .HasDatabaseName("IX_Entity"); entity.Property(e => e.ContactId).HasDefaultValueSql("'-1'"); diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs index 78b8dd97df7..72640e043c3 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs @@ -32,6 +32,8 @@ using ASC.CRM.Core.EF; using ASC.CRM.Mapping; +using AutoMapper; + #endregion namespace ASC.CRM.Core.Entities @@ -48,6 +50,12 @@ public class TaskTemplate : DomainObject, IMapFrom public bool DeadLineIsFixed { get; set; } public Guid CreateBy { get; set; } public DateTime CreateOn { get; set; } + public int SortOrder { get; set; } + public void Mapping(Profile profile) + { + profile.CreateMap() + .ForMember(dest => dest.Offset, opt => opt.MapFrom(src => TimeSpan.FromTicks(src.Offset))); + } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs index b23b9576dc2..311a6b5984f 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs @@ -41,6 +41,9 @@ public class TaskTemplateContainer : DomainObject, IMapFrom Date: Mon, 17 May 2021 17:50:55 +0300 Subject: [PATCH 50/61] crm: code refactoring --- .../Server/Api/CustomFieldsController.cs | 4 +- .../Server/Core/Dao/CurrencyRateDao.cs | 83 ++++----- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 134 +++++++------- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 101 +++++++---- .../Server/Core/Dao/DealMilestoneDao.cs | 72 ++++---- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 171 ++++++++---------- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 12 +- .../Server/Core/Entities/CustomField.cs | 20 +- .../CustomFieldDtoTypeConverter.cs | 4 +- .../WebToLeadFromHandlerMiddleware.cs | 2 +- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 6 +- .../Server/Utils/Import/CSV/ImportCases.cs | 2 +- .../Server/Utils/Import/CSV/ImportContacts.cs | 2 +- .../Server/Utils/Import/CSV/ImportDeals.cs | 2 +- products/ASC.CRM/Server/Utils/MailSender.cs | 6 +- 15 files changed, 295 insertions(+), 326 deletions(-) diff --git a/products/ASC.CRM/Server/Api/CustomFieldsController.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs index 9a766f70a9f..8a1f6723118 100644 --- a/products/ASC.CRM/Server/Api/CustomFieldsController.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -268,11 +268,11 @@ public CustomFieldDto UpdateCustomFieldValue(int id, string entityType, string l var customField = new CustomField { EntityType = entityTypeObj, - FieldType = (CustomFieldType)fieldType, + Type = (CustomFieldType)fieldType, ID = id, Mask = mask, Label = label, - Position = position + SortOrder = position }; _daoFactory.GetCustomFieldDao().EditItem(customField); diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index c401e3c576c..11cc0eb7d8c 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -36,6 +36,7 @@ using AutoMapper; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -62,7 +63,7 @@ public CurrencyRateDao( public List GetAll() { - var rates = CrmDbContext.CurrencyRate.Where(x => x.TenantId == TenantID).ToList(); + var rates = Query(CrmDbContext.CurrencyRate).ToList(); return _mapper.Map, List>(rates); } @@ -71,68 +72,54 @@ public CurrencyRate GetByID(int id) { var entity = CrmDbContext.CurrencyRate.Find(id); + if (entity.TenantId != TenantID) return null; + return _mapper.Map(entity); } public CurrencyRate GetByCurrencies(string fromCurrency, string toCurrency) { - return _mapper.Map(CrmDbContext.CurrencyRate.FirstOrDefault(x => x.TenantId == TenantID && String.Compare(x.FromCurrency, fromCurrency, true) == 0 && - String.Compare(x.ToCurrency, toCurrency, true) == 0)); + var dbEntity = Query(CrmDbContext.CurrencyRate).FirstOrDefault(x => + string.Compare(x.FromCurrency, fromCurrency, true) == 0 && + string.Compare(x.ToCurrency, toCurrency, true) == 0); + + return _mapper.Map(dbEntity); + } - public int SaveOrUpdate(CurrencyRate currencyRate) + public int SaveOrUpdate(CurrencyRate entity) { - if (String.IsNullOrEmpty(currencyRate.FromCurrency) || String.IsNullOrEmpty(currencyRate.ToCurrency) || currencyRate.Rate < 0) + if (String.IsNullOrEmpty(entity.FromCurrency) || String.IsNullOrEmpty(entity.ToCurrency) || entity.Rate < 0) throw new ArgumentException(); - if (currencyRate.ID > 0 && currencyRate.Rate == 0) - return Delete(currencyRate.ID); - - if (CrmDbContext.CurrencyRate.Where(x => x.Id == currencyRate.ID).Any()) - { - var itemToInsert = new DbCurrencyRate - { - FromCurrency = currencyRate.FromCurrency.ToUpper(), - ToCurrency = currencyRate.ToCurrency.ToUpper(), - Rate = currencyRate.Rate, - CreateBy = _securityContext.CurrentAccount.ID, - CreateOn = DateTime.UtcNow, - LastModifedBy = _securityContext.CurrentAccount.ID, - LastModifedOn = DateTime.UtcNow, - TenantId = TenantID - }; - - CrmDbContext.CurrencyRate.Add(itemToInsert); - CrmDbContext.SaveChanges(); - - currencyRate.ID = itemToInsert.Id; - } - else - { - var itemToUpdate = CrmDbContext.CurrencyRate.FirstOrDefault(x => x.Id == currencyRate.ID); - - itemToUpdate.FromCurrency = currencyRate.FromCurrency.ToUpper(); - itemToUpdate.ToCurrency = currencyRate.ToCurrency.ToUpper(); - itemToUpdate.Rate = currencyRate.Rate; - itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - itemToUpdate.LastModifedOn = DateTime.UtcNow; - itemToUpdate.TenantId = TenantID; - - CrmDbContext.Update(itemToUpdate); - CrmDbContext.SaveChanges(); - } + if (entity.ID > 0 && entity.Rate == 0) + return Delete(entity.ID); + + var dbEntity = new DbCurrencyRate + { + Id = entity.ID, + FromCurrency = entity.FromCurrency.ToUpper(), + ToCurrency = entity.ToCurrency.ToUpper(), + Rate = entity.Rate, + CreateOn = entity.CreateOn == DateTime.MinValue ? DateTime.UtcNow : entity.CreateOn, + CreateBy = entity.CreateBy == Guid.Empty ? _securityContext.CurrentAccount.ID : entity.CreateBy, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = _securityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); - return currencyRate.ID; + return dbEntity.Id; } public int Delete(int id) { - if (id <= 0) throw new ArgumentException(); + var dbEntity = CrmDbContext.CurrencyRate.Find(id); - var itemToDelete = new DbCurrencyRate { Id = id }; + CrmDbContext.Remove(dbEntity); - CrmDbContext.CurrencyRate.Attach(itemToDelete); - CrmDbContext.CurrencyRate.Remove(itemToDelete); CrmDbContext.SaveChanges(); return id; @@ -142,8 +129,8 @@ public List SetCurrencyRates(List rates) { using var tx = CrmDbContext.Database.BeginTransaction(); - var items = CrmDbContext.CurrencyRate.Where(x => x.TenantId == TenantID); - + var items = Query(CrmDbContext.CurrencyRate).AsNoTracking(); + CrmDbContext.RemoveRange(items); foreach (var rate in rates) diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 55b55e48ab4..6d13dab0c1d 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -43,6 +43,7 @@ using AutoMapper; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Newtonsoft.Json; @@ -53,14 +54,15 @@ namespace ASC.CRM.Core.Dao [Scope] public class CustomFieldDao : AbstractDao { - - private TenantUtil _tenantUtil; - private FactoryIndexerFieldValue _factoryIndexer; + private readonly TenantUtil _tenantUtil; + private readonly FactoryIndexerFieldValue _factoryIndexer; + public CustomFieldDao( DbContextManager dbContextManager, TenantManager tenantManager, SecurityContext securityContext, TenantUtil tenantUtil, + FactoryIndexerFieldValue factoryIndexer, IOptionsMonitor logger, ICache ascCache, IMapper mapper @@ -73,6 +75,7 @@ IMapper mapper mapper) { _tenantUtil = tenantUtil; + _factoryIndexer = factoryIndexer; } @@ -100,41 +103,34 @@ public void SetFieldValue(EntityType entityType, int entityID, int fieldID, Stri SetFieldValueInDb(entityType, entityID, fieldID, fieldValue); } - private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, String fieldValue) + private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, string fieldValue) { if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); fieldValue = fieldValue.Trim(); - var itemToDelete = Query(CrmDbContext.FieldValue) - .Where(x => x.EntityId == entityID && x.EntityType == entityType && x.FieldId == fieldID); - - CrmDbContext.FieldValue.RemoveRange(itemToDelete); - CrmDbContext.SaveChanges(); + var dbEntity = Query(CrmDbContext.FieldValue) + .FirstOrDefault(x => x.EntityId == entityID && + x.EntityType == entityType && + x.FieldId == fieldID); - if (!String.IsNullOrEmpty(fieldValue)) + if (string.IsNullOrEmpty(fieldValue)) { - var lastModifiedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()); + _factoryIndexer.Delete(dbEntity); - var dbFieldValue = new DbFieldValue - { - EntityId = entityID, - Value = fieldValue, - FieldId = fieldID, - EntityType = entityType, - LastModifedOn = lastModifiedOn, - LastModifedBy = _securityContext.CurrentAccount.ID, - TenantId = TenantID - }; - - CrmDbContext.Add(dbFieldValue); - CrmDbContext.SaveChanges(); - - var id = dbFieldValue.Id; + CrmDbContext.Remove(dbEntity); + } + else + { + dbEntity.Value = fieldValue; + dbEntity.LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()); + dbEntity.LastModifedBy = _securityContext.CurrentAccount.ID; - _factoryIndexer.Index(dbFieldValue); + _factoryIndexer.Index(dbEntity); } + + CrmDbContext.SaveChanges(); } private string GetValidMask(CustomFieldType customFieldType, String mask) @@ -224,7 +220,7 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) { _logger.Error(ex); - throw ex; + throw; } } return JsonConvert.SerializeObject(resultMask); @@ -234,11 +230,12 @@ public int CreateField(EntityType entityType, String label, CustomFieldType cust { if (!_supportedEntityType.Contains(entityType) || String.IsNullOrEmpty(label)) throw new ArgumentException(); + var resultMask = GetValidMask(customFieldType, mask); var sortOrder = Query(CrmDbContext.FieldDescription).Select(x => x.SortOrder).Max() + 1; - var itemToInsert = new DbFieldDescription + var dbEntity = new DbFieldDescription { Label = label, Type = customFieldType, @@ -248,11 +245,11 @@ public int CreateField(EntityType entityType, String label, CustomFieldType cust TenantId = TenantID }; - CrmDbContext.FieldDescription.Add(itemToInsert); + CrmDbContext.FieldDescription.Add(dbEntity); CrmDbContext.SaveChanges(); - return itemToInsert.Id; + return dbEntity.Id; } public String GetValue(EntityType entityType, int entityID, int fieldID) @@ -317,7 +314,7 @@ public int GetFieldId(EntityType entityType, String label, CustomFieldType custo public void EditItem(CustomField customField) { - if (String.IsNullOrEmpty(customField.Label)) + if (string.IsNullOrEmpty(customField.Label)) throw new ArgumentException(); if (HaveRelativeLink(customField.ID)) @@ -367,7 +364,7 @@ public void EditItem(CustomField customField) { _logger.Error(ex); - throw ex; + throw; } var itemToUpdate = Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); @@ -375,37 +372,37 @@ public void EditItem(CustomField customField) itemToUpdate.Label = customField.Label; itemToUpdate.Mask = customField.Mask; - CrmDbContext.Update(itemToUpdate); CrmDbContext.SaveChanges(); } else { - var resultMask = GetValidMask(customField.FieldType, customField.Mask); + var resultMask = GetValidMask(customField.Type, customField.Mask); var itemToUpdate = Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == customField.ID); itemToUpdate.Label = customField.Label; - itemToUpdate.Type = customField.FieldType; + itemToUpdate.Type = customField.Type; itemToUpdate.Mask = customField.Mask; - CrmDbContext.Update(itemToUpdate); CrmDbContext.SaveChanges(); } } - public void ReorderFields(int[] fieldID) + public void ReorderFields(int[] ids) { - for (int index = 0; index < fieldID.Length; index++) - { - var itemToUpdate = Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID[index]); + var tx = CrmDbContext.Database.BeginTransaction(); - itemToUpdate.SortOrder = index; + for (int index = 0; index < ids.Length; index++) + { + var dbEntity = CrmDbContext.FieldDescription.Find(ids[index]); - CrmDbContext.Update(itemToUpdate); + dbEntity.SortOrder = index; CrmDbContext.SaveChanges(); } + + tx.Commit(); } private bool HaveRelativeLink(int fieldID) @@ -509,13 +506,17 @@ private List GetEnityFields(EntityType entityType, int[] entityID, if (!includeEmptyFields) sqlQuery = sqlQuery.Where(x => x.y != null || x.x.Type == CustomFieldType.Heading); - return sqlQuery.ToList().ConvertAll(x => ToCustomField(x.x, x.y)); + } - public CustomField GetFieldDescription(int fieldID) + public CustomField GetFieldDescription(int id) { - return ToCustomField(Query(CrmDbContext.FieldDescription).FirstOrDefault(x => x.Id == fieldID)); + var dbEntity = CrmDbContext.FieldDescription.Find(id); + + if (dbEntity.TenantId != TenantID) return null; + + return _mapper.Map(dbEntity); } public List GetFieldsDescription(EntityType entityType) @@ -523,7 +524,8 @@ public List GetFieldsDescription(EntityType entityType) if (!_supportedEntityType.Contains(entityType)) throw new ArgumentException(); - var sqlQuery = Query(CrmDbContext.FieldDescription); + var sqlQuery = Query(CrmDbContext.FieldDescription) + .AsNoTracking(); if (entityType == EntityType.Company || entityType == EntityType.Person) { @@ -534,26 +536,27 @@ public List GetFieldsDescription(EntityType entityType) sqlQuery = sqlQuery.Where(x => x.EntityType == entityType); } - return sqlQuery.ToList().ConvertAll(x => ToCustomField(x)); + var dbEntities = sqlQuery.ToList(); + + return _mapper.Map, List>(dbEntities); } - public void DeleteField(int fieldID) + public void DeleteField(int id) { - //if (HaveRelativeLink(fieldID)) - // throw new ArgumentException(); + if (HaveRelativeLink(id)) + throw new ArgumentException(); var tx = CrmDbContext.Database.BeginTransaction(); - var fieldDescription = new DbFieldDescription { Id = fieldID }; + var dbFieldDescription = CrmDbContext.FieldDescription.Find(id); - CrmDbContext.FieldDescription.Attach(fieldDescription); - CrmDbContext.FieldDescription.Remove(fieldDescription); + CrmDbContext.Remove(dbFieldDescription); - var fieldValue = Query(CrmDbContext.FieldValue).FirstOrDefault(x => x.FieldId == fieldID); + var dbFieldValue = Query(CrmDbContext.FieldValue).FirstOrDefault(x => x.FieldId == id); - _factoryIndexer.Delete(fieldValue); + _factoryIndexer.Delete(dbFieldValue); - CrmDbContext.Remove(fieldValue); + CrmDbContext.Remove(dbFieldValue); CrmDbContext.SaveChanges(); @@ -561,22 +564,11 @@ public void DeleteField(int fieldID) } public CustomField ToCustomField(DbFieldDescription dbFieldDescription, - DbFieldValue dbFieldValue = null) + DbFieldValue dbFieldValue = null) { - if (dbFieldDescription == null) return null; - - var customField = new CustomField - { - ID = dbFieldDescription.Id, - EntityType = dbFieldDescription.EntityType, - FieldType = dbFieldDescription.Type, - Label = dbFieldDescription.Label, - Mask = dbFieldDescription.Mask, - Position = dbFieldDescription.SortOrder - - }; + var customField = _mapper.Map(dbFieldDescription); - if (dbFieldValue != null) + if (customField != null && dbFieldValue != null) { customField.Value = dbFieldValue.Value; customField.EntityID = dbFieldValue.EntityId; diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index d867fa0b81c..54e4c58dd72 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -58,12 +58,12 @@ namespace ASC.CRM.Core.Dao [Scope] public class DealDao : AbstractDao { - private BundleSearch _bundleSearch; - private FilesIntegration _filesIntegration; - private FactoryIndexerDeal _factoryIndexer; - private TenantUtil _tenantUtil; - private CrmSecurity _crmSecurity; - private AuthorizationManager _authorizationManager; + private readonly BundleSearch _bundleSearch; + private readonly FilesIntegration _filesIntegration; + private readonly FactoryIndexerDeal _factoryIndexer; + private readonly TenantUtil _tenantUtil; + private readonly CrmSecurity _crmSecurity; + private readonly AuthorizationManager _authorizationManager; public DealDao(DbContextManager dbContextManager, TenantManager tenantManager, @@ -71,6 +71,8 @@ public DealDao(DbContextManager dbContextManager, CrmSecurity crmSecurity, FactoryIndexerDeal factoryIndexer, FilesIntegration filesIntegration, + TenantUtil tenantUtil, + AuthorizationManager authorizationManager, IOptionsMonitor logger, ICache ascCache, IMapper mapper, @@ -87,6 +89,8 @@ public DealDao(DbContextManager dbContextManager, _filesIntegration = filesIntegration; _bundleSearch = bundleSearch; _mapper = mapper; + _tenantUtil = tenantUtil; + _authorizationManager = authorizationManager; } @@ -137,6 +141,7 @@ public int CreateNewDeal(Deal deal) deal.ID = result; + _factoryIndexer.Index(Query(CrmDbContext.Deals).Where(x => x.Id == deal.ID).FirstOrDefault()); return result; @@ -190,7 +195,9 @@ public int[] SaveDealList(List items) tx.Commit(); - foreach (var deal in Query(CrmDbContext.Deals).Where(x => result.Contains(x.Id))) + var dbDeals = Query(CrmDbContext.Deals).Where(x => result.Contains(x.Id)); + + foreach (var deal in dbDeals) { _factoryIndexer.Index(deal); } @@ -209,7 +216,10 @@ public void EditDeal(Deal deal) // AddMember(deal.ID, deal.ContactID); - var itemToUpdate = Query(CrmDbContext.Deals).Single(x => x.Id == deal.ID); + var itemToUpdate = CrmDbContext.Deals.Find(deal.ID); + + if (itemToUpdate.TenantId != TenantID) + throw new ArgumentException(); itemToUpdate.Title = deal.Title; itemToUpdate.Description = deal.Description; @@ -222,18 +232,15 @@ public void EditDeal(Deal deal) itemToUpdate.DealMilestoneProbability = deal.DealMilestoneProbability; itemToUpdate.ExpectedCloseDate = deal.ExpectedCloseDate; itemToUpdate.PerPeriodValue = deal.PerPeriodValue; - itemToUpdate.ActualCloseDate = _tenantUtil.DateTimeToUtc(deal.ActualCloseDate); itemToUpdate.LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()); itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - CrmDbContext.Update(itemToUpdate); CrmDbContext.SaveChanges(); _factoryIndexer.Index(itemToUpdate); } - public int GetDealsCount() { return GetDealsCount(String.Empty, Guid.Empty, 0, null, 0, null, null, DateTime.MinValue, DateTime.MinValue); @@ -730,16 +737,19 @@ public List GetDealsByPrefix(String prefix, int from, int count, int conta return _mapper.Map, List>(dbDeals).FindAll(_crmSecurity.CanAccessTo); } - public Deal DeleteDeal(int dealID) + public Deal DeleteDeal(int id) { - if (dealID <= 0) return null; + if (id <= 0) return null; - var deal = GetByID(dealID); + var deal = GetByID(id); + if (deal == null) return null; _crmSecurity.DemandDelete(deal); - _factoryIndexer.Delete(Query(CrmDbContext.Deals).Where(x => x.Id == dealID).Single()); + var dbEntity = CrmDbContext.Deals.Find(id); + + _factoryIndexer.Delete(dbEntity); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); @@ -752,6 +762,7 @@ public Deal DeleteDeal(int dealID) public List DeleteBatchDeals(int[] dealID) { var deals = GetDeals(dealID).FindAll(_crmSecurity.CanDelete).ToList(); + if (!deals.Any()) return deals; // Delete relative keys @@ -764,12 +775,14 @@ public List DeleteBatchDeals(int[] dealID) public List DeleteBatchDeals(List deals) { deals = deals.FindAll(_crmSecurity.CanDelete).ToList(); + if (!deals.Any()) return deals; // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "deals.*")); DeleteBatchDealsExecute(deals); + return deals; } @@ -778,13 +791,15 @@ private void DeleteBatchDealsExecute(List deals) if (deals == null || !deals.Any()) return; var dealID = deals.Select(x => x.ID).ToArray(); + object[] filesIDs; var tagdao = _filesIntegration.DaoFactory.GetTagDao(); var tagNames = Query(CrmDbContext.RelationshipEvent) .Where(x => x.HaveFiles && dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) - .Select(x => string.Format("RelationshipEvent_{0}", x.Id)).ToArray(); + .Select(x => string.Format("RelationshipEvent_{0}", x.Id)) + .ToArray(); filesIDs = tagdao.GetTags(tagNames, TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray(); @@ -792,19 +807,29 @@ private void DeleteBatchDealsExecute(List deals) CrmDbContext.RemoveRange(Query(CrmDbContext.FieldValue) + .AsNoTracking() .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity) ); - CrmDbContext.RemoveRange(CrmDbContext.EntityContact.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + CrmDbContext.RemoveRange(CrmDbContext.EntityContact + .AsNoTracking() + .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); CrmDbContext.RemoveRange(Query(CrmDbContext.RelationshipEvent) + .AsNoTracking() .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); - CrmDbContext.RemoveRange(Query(CrmDbContext.Tasks).Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + CrmDbContext.RemoveRange(Query(CrmDbContext.Tasks) + .AsNoTracking() + .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); - CrmDbContext.RemoveRange(CrmDbContext.EntityTags.Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); + CrmDbContext.RemoveRange(CrmDbContext.EntityTags + .AsNoTracking() + .Where(x => dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)); - CrmDbContext.RemoveRange(Query(CrmDbContext.Deals).Where(x => dealID.Contains(x.Id))); + CrmDbContext.RemoveRange(Query(CrmDbContext.Deals) + .AsNoTracking() + .Where(x => dealID.Contains(x.Id))); tx.Commit(); @@ -854,19 +879,17 @@ public void ReassignDealsResponsible(Guid fromUserId, Guid toUserId) /// /// Test method /// - /// + /// /// - public void SetDealCreationDate(int opportunityid, DateTime creationDate) + public void SetDealCreationDate(int id, DateTime creationDate) { - var dbDeal = new DbDeal - { - Id = opportunityid, - CreateOn = _tenantUtil.DateTimeToUtc(creationDate), - TenantId = TenantID - }; + var dbEntity = CrmDbContext.Deals.Find(id); + + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); + + dbEntity.CreateOn = _tenantUtil.DateTimeToUtc(creationDate); - CrmDbContext.Attach(dbDeal); - CrmDbContext.Entry(dbDeal).Property(x => x.CreateOn).IsModified = true; CrmDbContext.SaveChanges(); // Delete relative keys @@ -876,19 +899,17 @@ public void SetDealCreationDate(int opportunityid, DateTime creationDate) /// /// Test method /// - /// + /// /// - public void SetDealLastModifedDate(int opportunityid, DateTime lastModifedDate) + public void SetDealLastModifedDate(int id, DateTime lastModifedDate) { - var dbDeal = new DbDeal - { - Id = opportunityid, - LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate), - TenantId = TenantID - }; + var dbEntity = CrmDbContext.Deals.Find(id); + + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); + + dbEntity.LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate); - CrmDbContext.Attach(dbDeal); - CrmDbContext.Entry(dbDeal).Property(x => x.LastModifedOn).IsModified = true; CrmDbContext.SaveChanges(); // Delete relative keys diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index cb2beee80d3..393827954bc 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -43,6 +43,7 @@ using AutoMapper; using Microsoft.AspNetCore.Http; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; #endregion @@ -116,18 +117,13 @@ public int GetRelativeItemsCount(int id) public int Create(DealMilestone item) { - if (String.IsNullOrEmpty(item.Title) || String.IsNullOrEmpty(item.Color)) throw new ArgumentException(); - int id; - - using var tx = CrmDbContext.Database.BeginTransaction(); - if (item.SortOrder == 0) item.SortOrder = Query(CrmDbContext.DealMilestones).Select(x => x.SortOrder).Max() + 1; - var itemToAdd = new DbDealMilestone + var dbEntity = new DbDealMilestone { Title = item.Title, Description = item.Description, @@ -138,27 +134,21 @@ public int Create(DealMilestone item) TenantId = TenantID }; - CrmDbContext.DealMilestones.Add(itemToAdd); + CrmDbContext.DealMilestones.Add(dbEntity); CrmDbContext.SaveChanges(); - id = itemToAdd.Id; - - tx.Commit(); - - return id; + return dbEntity.Id; } public void ChangeColor(int id, String newColor) { - var itemToUpdate = new DbDealMilestone - { - Id = id, - Color = newColor, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.DealMilestones.Find(id); + + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); + + dbEntity.Color = newColor; - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.Color).IsModified = true; CrmDbContext.SaveChanges(); } @@ -167,24 +157,24 @@ public void Edit(DealMilestone item) if (HaveContactLink(item.ID)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeEdited, CRMErrorsResource.DealMilestoneHasRelatedDeals)); - var itemToUpdate = Query(CrmDbContext.DealMilestones) - .FirstOrDefault(x => x.Id == item.ID); + var dbEntity = CrmDbContext.DealMilestones.Find(item.ID); - itemToUpdate.Title = item.Title; - itemToUpdate.Description = item.Description; - itemToUpdate.Color = item.Color; - itemToUpdate.Probability = item.Probability; - itemToUpdate.Status = item.Status; + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); - CrmDbContext.DealMilestones.Update(itemToUpdate); + dbEntity.Title = item.Title; + dbEntity.Description = item.Description; + dbEntity.Color = item.Color; + dbEntity.Probability = item.Probability; + dbEntity.Status = item.Status; CrmDbContext.SaveChanges(); } - public bool HaveContactLink(int dealMilestoneID) + public bool HaveContactLink(int id) { return Query(CrmDbContext.Deals) - .Any(x => x.DealMilestoneId == dealMilestoneID); + .Any(x => x.DealMilestoneId == id); } public void Delete(int id) @@ -192,23 +182,24 @@ public void Delete(int id) if (HaveContactLink(id)) throw new ArgumentException(String.Format("{0}. {1}.", CRMErrorsResource.BasicCannotBeDeleted, CRMErrorsResource.DealMilestoneHasRelatedDeals)); - var dbDealMilestones = new DbDealMilestone - { - Id = id, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.DealMilestones.Find(id); - CrmDbContext.DealMilestones.Remove(dbDealMilestones); + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); - CrmDbContext.SaveChanges(); + CrmDbContext.DealMilestones.Remove(dbEntity); + CrmDbContext.SaveChanges(); } public DealMilestone GetByID(int id) { - var dbDealMilestone = Query(CrmDbContext.DealMilestones).FirstOrDefault(x => x.Id == id); + var dbEntity = CrmDbContext.DealMilestones.Find(id); - return _mapper.Map(dbDealMilestone); + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); + + return _mapper.Map(dbEntity); } public Boolean IsExist(int id) @@ -219,6 +210,7 @@ public Boolean IsExist(int id) public List GetAll(int[] id) { var result = Query(CrmDbContext.DealMilestones) + .AsNoTracking() .OrderBy(x => x.SortOrder) .Where(x => id.Contains(x.Id)).ToList(); @@ -228,11 +220,11 @@ public List GetAll(int[] id) public List GetAll() { var result = Query(CrmDbContext.DealMilestones) + .AsNoTracking() .OrderBy(x => x.SortOrder) .ToList(); return _mapper.Map, List>(result); - } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 131b61857eb..9765cca1c8c 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -47,7 +47,6 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -79,7 +78,6 @@ public class InvoiceDao : AbstractDao public InvoiceDao( DbContextManager dbContextManager, TenantManager tenantManager, - SecurityContext securityContext, FactoryIndexerInvoice factoryIndexer, IOptionsMonitor logger, @@ -111,9 +109,9 @@ public Boolean IsExist(int invoiceID) return IsExistFromDb(invoiceID); } - public Boolean IsExistFromDb(int invoiceID) + public Boolean IsExistFromDb(int id) { - return Query(CrmDbContext.Invoices).Where(x => x.Id == invoiceID).Any(); + return Query(CrmDbContext.Invoices).Where(x => x.Id == id).Any(); } public Boolean IsExist(string number) @@ -139,8 +137,9 @@ public List GetAll() public List GetByID(int[] ids) { var dbInvoices = Query(CrmDbContext.Invoices) - .Where(x => ids.Contains(x.Id)) - .ToList(); + .AsNoTracking() + .Where(x => ids.Contains(x.Id)) + .ToList(); return _mapper.Map, List>(dbInvoices); } @@ -152,12 +151,19 @@ public Invoice GetByID(int id) public Invoice GetByIDFromDb(int id) { - return _mapper.Map(Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == id)); + var dbEntity = CrmDbContext.Invoices.Find(id); + + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); + + return _mapper.Map(dbEntity); } public Invoice GetByNumber(string number) { - return _mapper.Map(Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Number == number)); + var dbEntity = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Number == number); + + return _mapper.Map(dbEntity); } public Invoice GetByFileId(Int32 fileID) @@ -403,6 +409,7 @@ public List GetInvoices(int[] ids) if (ids == null || !ids.Any()) return new List(); var dbInvoices = Query(CrmDbContext.Invoices) + .AsNoTracking() .Where(x => ids.Contains(x.Id)) .ToList(); @@ -420,8 +427,10 @@ public List GetEntityInvoices(EntityType entityType, int entityID) if (entityType == EntityType.Opportunity) { - var sqlQuery = Query(CrmDbContext.Invoices).Where(x => x.EntityId == entityID && x.EntityType == entityType) - .ToList(); + var sqlQuery = Query(CrmDbContext.Invoices) + .AsNoTracking() + .Where(x => x.EntityId == entityID && x.EntityType == entityType) + .ToList(); return _mapper.Map, List>(sqlQuery) .FindAll(_crmSecurity.CanAccessTo); @@ -441,8 +450,10 @@ public List GetContactInvoices(int contactID) if (contactID <= 0) return result; - var dbInvoices = Query(CrmDbContext.Invoices).Where(x => x.ContactId == contactID) - .ToList(); + var dbInvoices = Query(CrmDbContext.Invoices) + .AsNoTracking() + .Where(x => x.ContactId == contactID) + .ToList(); return _mapper.Map, List>(dbInvoices) .FindAll(_crmSecurity.CanAccessTo); @@ -491,6 +502,8 @@ public int SaveOrUpdateInvoice(Invoice invoice) var result = SaveOrUpdateInvoiceInDb(invoice); + + _factoryIndexer.Index(Query(CrmDbContext.Invoices).Where(x => x.Id == invoice.ID).Single()); return result; @@ -506,81 +519,40 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) invoice.ExchangeRate <= 0 || String.IsNullOrEmpty(invoice.Terms)) throw new ArgumentException(); - - - invoice.PurchaseOrderNumber = !String.IsNullOrEmpty(invoice.PurchaseOrderNumber) ? invoice.PurchaseOrderNumber : String.Empty; - - if (!IsExistFromDb(invoice.ID)) - { - if (IsExistFromDb(invoice.Number)) - throw new ArgumentException(); - - var itemToInsert = new DbInvoice - { - Status = invoice.Status, - Number = invoice.Number, - IssueDate = _tenantUtil.DateTimeToUtc(invoice.IssueDate), - TemplateType = invoice.TemplateType, - ContactId = invoice.ContactID, - ConsigneeId = invoice.ConsigneeID, - EntityType = invoice.EntityType, - EntityId = invoice.EntityID, - DueDate = _tenantUtil.DateTimeToUtc(invoice.DueDate), - Language = invoice.Language, - Currency = invoice.Currency, - ExchangeRate = invoice.ExchangeRate, - PurchaseOrderNumber = invoice.PurchaseOrderNumber, - Terms = invoice.Terms, - Description = invoice.Description, - JsonData = invoice.JsonData, - FileId = invoice.FileID, - CreateOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, - CreateBy = _securityContext.CurrentAccount.ID, - LastModifedOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, - LastModifedBy = _securityContext.CurrentAccount.ID, - TenantId = TenantID - }; - - CrmDbContext.Invoices.Add(itemToInsert); - - CrmDbContext.SaveChanges(); - - invoice.ID = itemToInsert.Id; - - } - else + + var dbEntity = new DbInvoice { - var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoice.ID); - - var oldInvoice = _mapper.Map(itemToUpdate); - - _crmSecurity.DemandEdit(oldInvoice); - - itemToUpdate.Status = invoice.Status; - itemToUpdate.IssueDate = _tenantUtil.DateTimeToUtc(invoice.IssueDate); - itemToUpdate.TemplateType = invoice.TemplateType; - itemToUpdate.ContactId = invoice.ContactID; - itemToUpdate.ConsigneeId = invoice.ConsigneeID; - itemToUpdate.EntityType = invoice.EntityType; - itemToUpdate.EntityId = invoice.EntityID; - itemToUpdate.DueDate = _tenantUtil.DateTimeToUtc(invoice.DueDate); - itemToUpdate.Language = invoice.Language; - itemToUpdate.Currency = invoice.Currency; - itemToUpdate.ExchangeRate = invoice.ExchangeRate; - itemToUpdate.PurchaseOrderNumber = invoice.PurchaseOrderNumber; - itemToUpdate.Description = invoice.Description; - itemToUpdate.JsonData = null; - itemToUpdate.FileId = 0; - itemToUpdate.LastModifedOn = DateTime.UtcNow; - itemToUpdate.LastModifedBy = _securityContext.CurrentAccount.ID; - itemToUpdate.TenantId = TenantID; - - CrmDbContext.SaveChanges(); - - - } + Id = invoice.ID, + Status = invoice.Status, + Number = invoice.Number, + IssueDate = _tenantUtil.DateTimeToUtc(invoice.IssueDate), + TemplateType = invoice.TemplateType, + ContactId = invoice.ContactID, + ConsigneeId = invoice.ConsigneeID, + EntityType = invoice.EntityType, + EntityId = invoice.EntityID, + DueDate = _tenantUtil.DateTimeToUtc(invoice.DueDate), + Language = invoice.Language, + Currency = invoice.Currency, + ExchangeRate = invoice.ExchangeRate, + PurchaseOrderNumber = invoice.PurchaseOrderNumber, + Terms = invoice.Terms, + Description = invoice.Description, + JsonData = invoice.JsonData, + FileId = invoice.FileID, + CreateOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, + CreateBy = _securityContext.CurrentAccount.ID, + LastModifedOn = DateTime.UtcNow, + LastModifedBy = _securityContext.CurrentAccount.ID, + TenantId = TenantID + }; + + dbEntity.PurchaseOrderNumber = !String.IsNullOrEmpty(invoice.PurchaseOrderNumber) ? invoice.PurchaseOrderNumber : String.Empty; + + CrmDbContext.Update(dbEntity); + CrmDbContext.SaveChanges(); - return invoice.ID; + return dbEntity.Id; } public Invoice UpdateInvoiceStatus(int invoiceid, InvoiceStatus status) @@ -756,12 +728,11 @@ private void DeleteBatchInvoicesExecute(List invoices) tx.Commit(); dbInvoicesQuery.ToList().ForEach(invoice => _factoryIndexer.Delete(invoice)); - } private IQueryable GetDbInvoceByFilters( ICollection exceptIDs, - String searchText, + string searchText, InvoiceStatus? status, DateTime issueDateFrom, DateTime issueDateTo, @@ -771,7 +742,8 @@ private IQueryable GetDbInvoceByFilters( int entityID, String currency) { - var sqlQuery = Query(CrmDbContext.Invoices); + var sqlQuery = Query(CrmDbContext.Invoices) + .AsNoTracking(); if (entityID > 0) { @@ -880,15 +852,16 @@ private bool hasParams( /// /// Test method /// - /// + /// /// - public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) + public void SetInvoiceCreationDate(int id, DateTime creationDate) { - var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + var dbEntity = CrmDbContext.Invoices.Find(id); + + var entity = _mapper.Map(dbEntity); - itemToUpdate.CreateOn = _tenantUtil.DateTimeToUtc(creationDate); + dbEntity.CreateOn = _tenantUtil.DateTimeToUtc(creationDate); - CrmDbContext.Invoices.Update(itemToUpdate); CrmDbContext.SaveChanges(); // Delete relative keys @@ -898,15 +871,17 @@ public void SetInvoiceCreationDate(int invoiceId, DateTime creationDate) /// /// Test method /// - /// + /// /// - public void SetInvoiceLastModifedDate(int invoiceId, DateTime lastModifedDate) + public void SetInvoiceLastModifedDate(int id, DateTime lastModifedDate) { - var itemToUpdate = Query(CrmDbContext.Invoices).FirstOrDefault(x => x.Id == invoiceId); + var dbEntity = CrmDbContext.Invoices.Find(id); + + var entity = _mapper.Map(dbEntity); - itemToUpdate.LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate); + _crmSecurity.DemandAccessTo(entity); - CrmDbContext.Invoices.Update(itemToUpdate); + dbEntity.LastModifedOn = _tenantUtil.DateTimeToUtc(lastModifedDate); CrmDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 2dde6fc07fd..7d67a3481f6 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -72,19 +72,19 @@ IMapper mapper _crmSecurity = crmSecurity; } - public Boolean IsExist(int invoiceItemID) + public Boolean IsExist(int id) { - return IsExistInDb(invoiceItemID); + return IsExistInDb(id); } - public Boolean IsExistInDb(int invoiceItemID) + public Boolean IsExistInDb(int id) { - return Query(CrmDbContext.InvoiceItem).Any(x => x.Id == invoiceItemID); + return Query(CrmDbContext.InvoiceItem).Any(x => x.Id == id); } - public Boolean CanDelete(int invoiceItemID) + public Boolean CanDelete(int id) { - return Query(CrmDbContext.InvoiceLine).Any(x => x.InvoiceItemId == invoiceItemID); + return Query(CrmDbContext.InvoiceLine).Any(x => x.InvoiceItemId == id); } public List GetAll() diff --git a/products/ASC.CRM/Server/Core/Entities/CustomField.cs b/products/ASC.CRM/Server/Core/Entities/CustomField.cs index dd72efa17c0..aba5e6b45b6 100644 --- a/products/ASC.CRM/Server/Core/Entities/CustomField.cs +++ b/products/ASC.CRM/Server/Core/Entities/CustomField.cs @@ -29,30 +29,32 @@ using System; using System.Runtime.Serialization; +using ASC.Common.Mapping; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; using ASC.CRM.Mapping; +using AutoMapper; + +using DocuSign.eSign.Model; + #endregion namespace ASC.CRM.Core.Entities { - - [DataContract] - public class CustomField : DomainObject + public class CustomField : DomainObject, IMapFrom { - [DataMember(Name = "entity_type")] public EntityType EntityType { get; set; } - - [DataMember(Name = "entity_id")] public int EntityID { get; set; } public String Label { get; set; } public String Value { get; set; } - public CustomFieldType FieldType { get; set; } - public int Position { get; set; } + public CustomFieldType Type { get; set; } + public int SortOrder { get; set; } public String Mask { get; set; } + public override int GetHashCode() { - return string.Format("{0}|{1}|{2}|{3}|{4}", GetType().FullName, ID, EntityID, Label, (int)FieldType).GetHashCode(); + return string.Format("{0}|{1}|{2}|{3}|{4}", GetType().FullName, ID, EntityID, Label, (int)Type).GetHashCode(); } } } diff --git a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs index de589d727d9..d3fc8821d7d 100644 --- a/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/CustomFieldDtoTypeConverter.cs @@ -29,11 +29,11 @@ public CustomFieldDto Convert(CustomField source, CustomFieldDto destination, Re { Id = source.ID, EntityId = source.EntityID, - FieldType = source.FieldType, + FieldType = source.Type, FieldValue = source.Value, Label = source.Label, Mask = source.Mask, - Position = source.Position, + Position = source.SortOrder, RelativeItemsCount = _daoFactory.GetCustomFieldDao().GetContactLinkCount(source.EntityType, source.ID) }; diff --git a/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs index 516a28925f0..fce961a6b58 100644 --- a/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs +++ b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs @@ -248,7 +248,7 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, customField.EntityType == EntityType.Company && isCompany || customField.EntityType == EntityType.Person && !isCompany)) continue; - if (customField.FieldType == CustomFieldType.CheckBox) + if (customField.Type == CustomFieldType.CheckBox) { fieldValue = fieldValue == "on" || fieldValue == "true" ? "true" : "false"; } diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 0ac69874969..0c3825dc023 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -583,7 +583,7 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String fieldsDescription.ForEach( item => { - if (item.FieldType == CustomFieldType.Heading) return; + if (item.Type == CustomFieldType.Heading) return; dataTable.Columns.Add( new DataColumn @@ -820,7 +820,7 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) customFieldDao.GetFieldsDescription(EntityType.Opportunity).ForEach( item => { - if (item.FieldType == CustomFieldType.Heading) return; + if (item.Type == CustomFieldType.Heading) return; dataTable.Columns.Add(new DataColumn { @@ -939,7 +939,7 @@ private String ExportCasesToCsv(IEnumerable cases, customFieldDao.GetFieldsDescription(EntityType.Case).ForEach( item => { - if (item.FieldType == CustomFieldType.Heading) return; + if (item.Type == CustomFieldType.Heading) return; dataTable.Columns.Add(new DataColumn { diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index 87684503922..6c6cf109611 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -92,7 +92,7 @@ private void ImportCaseData(DaoFactory _daoFactory) EntityID = objCases.ID, EntityType = EntityType.Case, ID = fieldID, - Value = field.FieldType == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue + Value = field.Type == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue }); } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index ee3b53fe13c..4942c2c551b 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -519,7 +519,7 @@ private void _ReadCustomField(JProperty jToken, String propertyValue, Contact co EntityID = contact.ID, EntityType = contact is Person ? EntityType.Person : EntityType.Company, ID = fieldID, - Value = field.FieldType == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue + Value = field.Type == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue }); } } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index fbce023f251..e9e2dee9b53 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -257,7 +257,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) EntityID = obj.ID, EntityType = EntityType.Opportunity, ID = fieldID, - Value = field.FieldType == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue + Value = field.Type == CustomFieldType.CheckBox ? (propertyValue == "on" || propertyValue == "true" ? "true" : "false") : propertyValue }); } } diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index 623d8d79e07..6502c6c7d25 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -1082,10 +1082,10 @@ public List GetTags(bool isCompany) foreach (var customField in customFields) { - if (customField.FieldType == CustomFieldType.SelectBox) continue; - if (customField.FieldType == CustomFieldType.CheckBox) continue; + if (customField.Type == CustomFieldType.SelectBox) continue; + if (customField.Type == CustomFieldType.CheckBox) continue; - if (customField.FieldType == CustomFieldType.Heading) + if (customField.Type == CustomFieldType.Heading) { if (!String.IsNullOrEmpty(customField.Label)) category = customField.Label; From 86a7802ada31c12dc5be1795e88061c8960265c5 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 17 May 2021 19:32:05 +0300 Subject: [PATCH 51/61] crm: refactoring --- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 42 +++++++++---------- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 18 +++++--- .../Server/Core/Dao/DealMilestoneDao.cs | 4 +- .../Core/Dao/TaskTemplateContainerDao.cs | 2 + 4 files changed, 37 insertions(+), 29 deletions(-) diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 15c979fc5ec..290a87619ad 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -1210,22 +1210,24 @@ private void UpdateContactFromDb(Contact contact) public void UpdateContactStatus(IEnumerable contactid, int statusid) { - foreach (var item in contactid) + var tx = CrmDbContext.Database.BeginTransaction(); + + foreach (var id in contactid) { - var itemToUpdate = new DbContact - { - Id = item, - StatusId = statusid, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.Contacts.Find(id); - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.StatusId).IsModified = true; + if (dbEntity.TenantId != TenantID) + throw new ArgumentException(); + dbEntity.Id = id; + dbEntity.StatusId = statusid; + } CrmDbContext.SaveChanges(); + tx.Commit(); + // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); } @@ -1307,25 +1309,20 @@ public void MakePublic(int contactId, bool isShared) { if (contactId <= 0) throw new ArgumentException(); - var itemToUpdate = new DbContact - { - Id = contactId, - IsShared = isShared ? ShareType.ReadWrite : ShareType.None, - TenantId = TenantID - }; + var dbEntity = CrmDbContext.Contacts.Find(contactId); - CrmDbContext.Attach(itemToUpdate); - CrmDbContext.Entry(itemToUpdate).Property(x => x.IsShared).IsModified = true; - CrmDbContext.SaveChanges(); + dbEntity.IsShared = isShared ? ShareType.ReadWrite : ShareType.None; + CrmDbContext.SaveChanges(); } public int SaveContact(Contact contact) { var result = SaveContactToDb(contact); - _factoryIndexerContact.Index(Query(CrmDbContext.Contacts) - .Where(x => x.Id == contact.ID).Single()); + var dbEntity = CrmDbContext.Contacts.Find(contact.ID); + + _factoryIndexerContact.Index(dbEntity); // Delete relative keys _cache.Remove(new Regex(TenantID.ToString(CultureInfo.InvariantCulture) + "contacts.*")); @@ -1537,8 +1534,9 @@ public Contact DeleteContact(int contactID) _crmSecurity.DemandDelete(contact); - _factoryIndexerContact.Delete(Query(CrmDbContext.Contacts) - .Where(x => x.Id == contactID).Single()); + var dbEntity = CrmDbContext.Contacts.Find(contactID); + + _factoryIndexerContact.Delete(dbEntity); DeleteBatchContactsExecute(new List() { contact }); diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index f667ee076b8..51fdbaead78 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -111,8 +111,12 @@ public int Update(ContactInfo contactInfo) { var result = UpdateInDb(contactInfo); - _factoryIndexerContactInfo.Update(Query(CrmDbContext.ContactsInfo) - .Where(x => x.ContactId == contactInfo.ID).Single()); + var dbEntity = Query(CrmDbContext.ContactsInfo) + .AsNoTracking() + .Where(x => x.ContactId == contactInfo.ID) + .Single(); + + _factoryIndexerContactInfo.Update(dbEntity); return result; } @@ -135,7 +139,7 @@ private int UpdateInDb(ContactInfo contactInfo) TenantId = TenantID }; - CrmDbContext.ContactsInfo.Update(itemToUpdate); + CrmDbContext.Update(itemToUpdate); CrmDbContext.SaveChanges(); @@ -149,11 +153,12 @@ public int Save(ContactInfo contactInfo) contactInfo.ID = id; - var dbContactInfo = Query(CrmDbContext.ContactsInfo) + var dbEntity = Query(CrmDbContext.ContactsInfo) + .AsNoTracking() .Where(x => x.ContactId == contactInfo.ID) .Single(); - _factoryIndexerContactInfo.Index(dbContactInfo); + _factoryIndexerContactInfo.Index(dbEntity); return id; } @@ -204,7 +209,8 @@ public List GetAll(int[] contactID) public List GetList(int contactID, ContactInfoType? infoType, int? categoryID, bool? isPrimary) { - var items = Query(CrmDbContext.ContactsInfo); + var items = Query(CrmDbContext.ContactsInfo) + .AsNoTracking(); if (contactID > 0) items = items.Where(x => x.ContactId == contactID); diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 393827954bc..5850571746a 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -79,7 +79,9 @@ public void Reorder(int[] ids) for (int index = 0; index < ids.Length; index++) { - var itemToUpdate = Query(CrmDbContext.DealMilestones).FirstOrDefault(x => x.Id == ids[index]); + var itemToUpdate = CrmDbContext.DealMilestones.Find(ids[index]); + + if (itemToUpdate.TenantId != TenantID) continue; itemToUpdate.SortOrder = index; diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index bb359f29f08..0c2b0123fc2 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -226,6 +226,8 @@ public virtual void Delete(int id) { var dbEntity = CrmDbContext.TaskTemplateContainer.Find(id); + if (dbEntity.TenantId != TenantID) return; + CrmDbContext.Remove(dbEntity); CrmDbContext.SaveChanges(); From c8e5c5a93c335261b2e3e2f0ede4269014f29517 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 24 May 2021 12:56:49 +0300 Subject: [PATCH 52/61] crm: migrate from ProgressQueue to DistributedTaskQueue --- .../Server/Classes/ContactPhotoManager.cs | 118 ++++--- products/ASC.CRM/Server/Classes/VoipEngine.cs | 114 ++++--- .../Server/Core/Enums/ProgressStatus.cs | 36 --- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 208 +++--------- .../Server/Utils/Import/CSV/ImportCases.cs | 45 +-- .../Server/Utils/Import/CSV/ImportContacts.cs | 82 +---- .../Utils/Import/CSV/ImportDataOperation.cs | 168 ++-------- .../Server/Utils/Import/CSV/ImportDeals.cs | 72 +---- .../Server/Utils/Import/CSV/ImportFromCSV.cs | 58 ++-- .../Server/Utils/Import/CSV/ImportTasks.cs | 6 +- products/ASC.CRM/Server/Utils/MailSender.cs | 299 +++++------------- .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 73 +++-- 12 files changed, 368 insertions(+), 911 deletions(-) delete mode 100644 products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs index a0e807edaec..d9a2902c0ad 100644 --- a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -35,7 +35,7 @@ using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; -using ASC.Common.Threading.Workers; +using ASC.Common.Threading; using ASC.CRM.Resources; using ASC.Data.Storage; using ASC.Web.Core; @@ -46,7 +46,7 @@ namespace ASC.Web.CRM.Classes { - public class ResizeWorkerItem + public class ResizeWorkerItem : DistributedTask { public int ContactID { get; set; } @@ -78,42 +78,16 @@ public override int GetHashCode() [Scope] public class ContactPhotoManager { - public ContactPhotoManager(Global global, - WebImageSupplier webImageSupplier, - IOptionsMonitor logger, - ICache cache, - ICacheNotify cacheNotify, - WorkerQueueOptionsManager workerQueueOptionsManager) - { - Global = global; - WebImageSupplier = webImageSupplier; - CacheNotify = cacheNotify; - Cache = cache; - ResizeQueue = workerQueueOptionsManager.Value; - Logger = logger.Get("ASC.CRM"); - - CacheNotify.Subscribe((x) => - { - Cache.Remove($"contact_photo_cache_key_id_{x.Id}"); - - }, CacheNotifyAction.Remove); - } - - public ILog Logger { get; } - - public Global Global { get; } - - public WebImageSupplier WebImageSupplier { get; } - - #region Members + public readonly ILog _logger; + public readonly Global _global; + public readonly WebImageSupplier _webImageSupplier; + private readonly DistributedTaskQueue _resizeQueue; + private readonly ICacheNotify _cacheNotify; + private readonly ICache _cache; private const string PhotosBaseDirName = "photos"; private const string PhotosDefaultTmpDirName = "temp"; - private readonly WorkerQueue ResizeQueue; - private readonly ICacheNotify CacheNotify; - private readonly ICache Cache; - private static readonly Size _oldBigSize = new Size(145, 145); private readonly Size _bigSize = new Size(200, 200); @@ -122,13 +96,33 @@ public ContactPhotoManager(Global global, private readonly object locker = new object(); - #endregion + + public ContactPhotoManager(Global global, + WebImageSupplier webImageSupplier, + IOptionsMonitor logger, + ICache cache, + ICacheNotify cacheNotify, + DistributedTaskQueueOptionsManager optionsQueue) + { + _global = global; + _webImageSupplier = webImageSupplier; + _cacheNotify = cacheNotify; + _cache = cache; + _resizeQueue = optionsQueue.Get(); + _logger = logger.Get("ASC.CRM"); + + _cacheNotify.Subscribe((x) => + { + _cache.Remove($"contact_photo_cache_key_id_{x.Id}"); + + }, CacheNotifyAction.Remove); + } #region Cache and DataStore Methods private String FromCache(int contactID, Size photoSize) { - var cacheItem = Cache.Get>($"contact_photo_cache_key_id_{contactID}"); + var cacheItem = _cache.Get>($"contact_photo_cache_key_id_{contactID}"); if (cacheItem is null) return String.Empty; @@ -139,14 +133,14 @@ private String FromCache(int contactID, Size photoSize) private void ToCache(int contactID, String photoUri, Size photoSize) { - var photoUriBySize = Cache.Get>($"contact_photo_cache_key_id_{contactID}"); + var photoUriBySize = _cache.Get>($"contact_photo_cache_key_id_{contactID}"); if (photoUriBySize.ContainsKey(photoSize)) photoUriBySize[photoSize] = photoUri; else photoUriBySize.Add(photoSize, photoUri); - Cache.Insert($"contact_photo_cache_key_id_{contactID}", photoUriBySize, TimeSpan.FromMinutes(15)); + _cache.Insert($"contact_photo_cache_key_id_{contactID}", photoUriBySize, TimeSpan.FromMinutes(15)); } private String FromDataStore(int contactID, Size photoSize) @@ -160,11 +154,11 @@ private String FromDataStore(int contactID, Size photoSize, Boolean isTmpDir, St ? BuildFileDirectory(contactID) : (String.IsNullOrEmpty(tmpDirName) ? BuildFileTmpDirectory(contactID) : BuildFileTmpDirectory(tmpDirName)); - var filesURI = Global.GetStore().ListFiles(directoryPath, BuildFileName(contactID, photoSize) + "*", false); + var filesURI = _global.GetStore().ListFiles(directoryPath, BuildFileName(contactID, photoSize) + "*", false); if (filesURI.Length == 0 && photoSize == _bigSize) { - filesURI = Global.GetStore().ListFiles(directoryPath, BuildFileName(contactID, _oldBigSize) + "*", false); + filesURI = _global.GetStore().ListFiles(directoryPath, BuildFileName(contactID, _oldBigSize) + "*", false); } if (filesURI.Length == 0) @@ -181,11 +175,11 @@ private String FromDataStoreRelative(int contactID, Size photoSize, Boolean isTm ? BuildFileDirectory(contactID) : (String.IsNullOrEmpty(tmpDirName) ? BuildFileTmpDirectory(contactID) : BuildFileTmpDirectory(tmpDirName)); - var filesPaths = Global.GetStore().ListFilesRelative("", directoryPath, BuildFileName(contactID, photoSize) + "*", false); + var filesPaths = _global.GetStore().ListFilesRelative("", directoryPath, BuildFileName(contactID, photoSize) + "*", false); if (filesPaths.Length == 0 && photoSize == _bigSize) { - filesPaths = Global.GetStore().ListFilesRelative("", directoryPath, BuildFileName(contactID, _oldBigSize) + "*", false); + filesPaths = _global.GetStore().ListFilesRelative("", directoryPath, BuildFileName(contactID, _oldBigSize) + "*", false); } if (filesPaths.Length == 0) @@ -200,10 +194,10 @@ private PhotoData FromDataStore(Size photoSize, String tmpDirName) { var directoryPath = BuildFileTmpDirectory(tmpDirName); - if (!Global.GetStore().IsDirectory(directoryPath)) + if (!_global.GetStore().IsDirectory(directoryPath)) return null; - var filesURI = Global.GetStore().ListFiles(directoryPath, BuildFileName(0, photoSize) + "*", false); + var filesURI = _global.GetStore().ListFiles(directoryPath, BuildFileName(0, photoSize) + "*", false); if (filesURI.Length == 0) return null; @@ -329,9 +323,9 @@ private String GetDefaultPhoto(bool isCompany, Size photoSize) if (!String.IsNullOrEmpty(defaultPhotoUri)) return defaultPhotoUri; if (isCompany) - defaultPhotoUri = WebImageSupplier.GetAbsoluteWebPath(String.Format("empty_company_logo_{0}_{1}.png", photoSize.Height, photoSize.Width), ProductEntryPoint.ID); + defaultPhotoUri = _webImageSupplier.GetAbsoluteWebPath(String.Format("empty_company_logo_{0}_{1}.png", photoSize.Height, photoSize.Width), ProductEntryPoint.ID); else - defaultPhotoUri = WebImageSupplier.GetAbsoluteWebPath(String.Format("empty_people_logo_{0}_{1}.png", photoSize.Height, photoSize.Width), ProductEntryPoint.ID); + defaultPhotoUri = _webImageSupplier.GetAbsoluteWebPath(String.Format("empty_people_logo_{0}_{1}.png", photoSize.Height, photoSize.Width), ProductEntryPoint.ID); ToCache(contactID, defaultPhotoUri, photoSize); @@ -354,17 +348,18 @@ public void DeletePhoto(int contactID, bool isTmpDir, string tmpDirName, bool re lock (locker) { - ResizeQueue.GetItems().Where(item => item.ContactID == contactID) + _resizeQueue.GetTasks().Where(item => item.ContactID == contactID) .All(item => { - ResizeQueue.Remove(item); + _resizeQueue.RemoveTask(item.Id); + return true; }); var photoDirectory = !isTmpDir ? BuildFileDirectory(contactID) : (String.IsNullOrEmpty(tmpDirName) ? BuildFileTmpDirectory(contactID) : BuildFileTmpDirectory(tmpDirName)); - var store = Global.GetStore(); + var store = _global.GetStore(); if (store.IsDirectory(photoDirectory)) { @@ -377,8 +372,8 @@ public void DeletePhoto(int contactID, bool isTmpDir, string tmpDirName, bool re if (!isTmpDir) { - Cache.Remove($"contact_photo_cache_key_id_{contactID}"); - CacheNotify.Publish(new ContactPhotoManagerCacheItem { Id = contactID }, CacheNotifyAction.Remove); + _cache.Remove($"contact_photo_cache_key_id_{contactID}"); + _cacheNotify.Publish(new ContactPhotoManagerCacheItem { Id = contactID }, CacheNotifyAction.Remove); } } } @@ -389,7 +384,7 @@ public void DeletePhoto(string tmpDirName) { var photoDirectory = BuildFileTmpDirectory(tmpDirName); - var store = Global.GetStore(); + var store = _global.GetStore(); if (store.IsDirectory(photoDirectory)) { @@ -403,7 +398,7 @@ public void DeletePhoto(string tmpDirName) public void TryUploadPhotoFromTmp(int contactID, bool isNewContact, string tmpDirName) { var directoryPath = BuildFileDirectory(contactID); - var dataStore = Global.GetStore(); + var dataStore = _global.GetStore(); try { @@ -436,7 +431,7 @@ public void TryUploadPhotoFromTmp(int contactID, bool isNewContact, string tmpDi } catch (Exception ex) { - Logger.ErrorFormat("TryUploadPhotoFromTmp for contactID={0} failed witth error: {1}", contactID, ex); + _logger.ErrorFormat("TryUploadPhotoFromTmp for contactID={0} failed witth error: {1}", contactID, ex); return; } @@ -483,7 +478,7 @@ private PhotoData ResizeToBigSize(byte[] imageData, int contactID, bool uploadOn UploadOnly = uploadOnly, RequireFotoSize = new[] { _bigSize }, ImageData = imageData, - DataStore = Global.GetStore(), + DataStore = _global.GetStore(), TmpDirName = tmpDirName }; @@ -522,14 +517,15 @@ private void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadO UploadOnly = uploadOnly, RequireFotoSize = new[] { _mediumSize, _smallSize }, ImageData = imageData, - DataStore = Global.GetStore(), + DataStore = _global.GetStore(), TmpDirName = tmpDirName }; - - if (!ResizeQueue.GetItems().Contains(resizeWorkerItem)) - ResizeQueue.Add(resizeWorkerItem); - - if (!ResizeQueue.IsStarted) ResizeQueue.Start(ExecResizeImage); + + if (!_resizeQueue.GetTasks().Contains(resizeWorkerItem)) + { + //Add + _resizeQueue.QueueTask((a, b) => ExecResizeImage(resizeWorkerItem), resizeWorkerItem); + } } private byte[] ToByteArray(Stream inputStream, int streamLength) diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index 26dd1a8ac35..9dcc896d538 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -30,7 +30,7 @@ using ASC.Common; using ASC.Common.Logging; -using ASC.Common.Threading.Workers; +using ASC.Common.Threading; using ASC.Core; using ASC.Core.Tenants; using ASC.CRM.Core; @@ -48,46 +48,42 @@ namespace ASC.Web.CRM.Classes [Scope] public class VoipEngine { - private readonly WorkerQueue Queue = new WorkerQueue(); + private readonly DistributedTaskQueue _queue; + + public readonly DaoFactory _daoFactory; + public readonly VoipDao _voipDao; + public readonly TenantManager _tenantManager; + public readonly ILog _logger; + public readonly int _tenantId; + public readonly SecurityContext _securityContext; + public readonly TenantUtil _tenantUtil; + public readonly CrmSecurity _crmSecurity; private readonly object Locker = new object(); public VoipEngine(DaoFactory daoFactory, CrmSecurity crmSecurity, TenantUtil tenantUtil, + DistributedTaskQueueOptionsManager optionsManager, SecurityContext securityContext, IOptionsMonitor logger, TenantManager tenantManager, VoipDao voipDao) { - CRMSecurity = crmSecurity; - TenantUtil = tenantUtil; - SecurityContext = securityContext; - Logger = logger.Get("ASC.CRM"); - TenantManager = tenantManager; - VoipDao = voipDao; - DaoFactory = daoFactory; + _crmSecurity = crmSecurity; + _tenantUtil = tenantUtil; + _securityContext = securityContext; + _queue = optionsManager.Get(); + _logger = logger.Get("ASC.CRM"); + _tenantManager = tenantManager; + _voipDao = voipDao; + _daoFactory = daoFactory; } - public DaoFactory DaoFactory { get; } - - public VoipDao VoipDao { get; } - - public TenantManager TenantManager { get; } - - public ILog Logger { get; } - - public int TenantId { get; } - - public SecurityContext SecurityContext { get; } - - public TenantUtil TenantUtil { get; } - - public CrmSecurity CRMSecurity { get; } public VoipCall SaveOrUpdateCall(VoipCall callHistory) { - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(callHistory.Id) ?? callHistory; if (string.IsNullOrEmpty(call.ParentID)) @@ -165,8 +161,10 @@ public void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) category = new ListItem(CRMCommonResource.HistoryCategory_Call, "event_category_call.png"); category.ID = listItemDao.CreateItem(ListType.HistoryCategory, category); } + var contact = daoFactory.GetContactDao().GetByID(call.ContactId); - if (contact != null && CRMSecurity.CanAccessTo(contact)) + + if (contact != null && _crmSecurity.CanAccessTo(contact)) { var note = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? CRMContactResource.HistoryVoipIncomingNote @@ -180,8 +178,8 @@ public void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) EntityID = 0, Content = content, ContactID = contact.ID, - CreateOn = TenantUtil.DateTimeFromUtc(DateTime.UtcNow), - CreateBy = SecurityContext.CurrentAccount.ID + CreateOn = _tenantUtil.DateTimeFromUtc(DateTime.UtcNow), + CreateBy = _securityContext.CurrentAccount.ID }; daoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent); @@ -197,14 +195,14 @@ public Contact GetContact(VoipCall call) var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To; - var newContactIds = DaoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); + var newContactIds = _daoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone.TrimStart('+'), null, true); foreach (var newContactId in newContactIds) { if (newContactId != 0) { - var existContact = DaoFactory.GetContactDao().GetByID(newContactId); - if (CRMSecurity.CanAccessTo(existContact)) + var existContact = _daoFactory.GetContactDao().GetByID(newContactId); + if (_crmSecurity.CanAccessTo(existContact)) { call.ContactId = newContactId; return existContact; @@ -225,13 +223,10 @@ public List GetContacts(string contactPhone, DaoFactory daoFactory) public void SaveAdditionalInfo(string callId) { lock (Locker) - { - if (!Queue.IsStarted) - { - Queue.Start(SaveAdditionalInfoAction); - } + { + var _queueItem = new QueueItem { CallID = callId, TenantID = _tenantId }; - Queue.Add(new QueueItem { CallID = callId, TenantID = TenantId }); + _queue.QueueTask((a, b) => SaveAdditionalInfoAction(_queueItem), _queueItem); ; } } @@ -239,17 +234,18 @@ private void SaveAdditionalInfoAction(QueueItem queueItem) { try { - TenantManager.SetCurrentTenant(queueItem.TenantID); + _tenantManager.SetCurrentTenant(queueItem.TenantID); - var voipEngine = new VoipEngine(DaoFactory, - CRMSecurity, - TenantUtil, - SecurityContext, + var voipEngine = new VoipEngine(_daoFactory, + _crmSecurity, + _tenantUtil, + null, + _securityContext, null, - TenantManager, - VoipDao); + _tenantManager, + _voipDao); - var dao = DaoFactory.GetVoipDao(); + var dao = _daoFactory.GetVoipDao(); var call = dao.GetCall(queueItem.CallID); @@ -268,33 +264,35 @@ private void SaveAdditionalInfoAction(QueueItem queueItem) if (!string.IsNullOrEmpty(call.VoipRecord.Id)) { - call.VoipRecord = VoipDao.GetProvider().GetRecord((string)call.Id, (string)call.VoipRecord.Id); + call.VoipRecord = _voipDao.GetProvider().GetRecord((string)call.Id, (string)call.VoipRecord.Id); voipEngine.SaveOrUpdateCall(call); } - SecurityContext.AuthenticateMe(call.AnsweredBy); - AddHistoryToCallContact(call, DaoFactory); + _securityContext.AuthenticateMe(call.AnsweredBy); + AddHistoryToCallContact(call, _daoFactory); } catch (Exception ex) { - Logger.ErrorFormat("SaveAdditionalInfo {0}, {1}", ex, ex.StackTrace); + _logger.ErrorFormat("SaveAdditionalInfo {0}, {1}", ex, ex.StackTrace); } } private void GetPriceAndDuration(VoipCall call) { - var provider = VoipDao.GetProvider(); + var provider = _voipDao.GetProvider(); var twilioCall = provider.GetCall(call.Id); + call.Price = twilioCall.Price; call.DialDuration = twilioCall.DialDuration; } public void AnswerCall(VoipCall call) { - call.AnsweredBy = SecurityContext.CurrentAccount.ID; + call.AnsweredBy = _securityContext.CurrentAccount.ID; call.Status = VoipCallStatus.Answered; - DaoFactory.GetVoipDao().SaveOrUpdateCall(call); + + _daoFactory.GetVoipDao().SaveOrUpdateCall(call); } public Contact CreateContact(string contactPhone) @@ -302,15 +300,15 @@ public Contact CreateContact(string contactPhone) var contact = new Person { FirstName = contactPhone, - LastName = TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), + LastName = _tenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), ShareType = ShareType.None, - CreateBy = SecurityContext.CurrentAccount.ID, + CreateBy = _securityContext.CurrentAccount.ID, CreateOn = DateTime.UtcNow }; - contact.ID = DaoFactory.GetContactDao().SaveContact(contact); + contact.ID = _daoFactory.GetContactDao().SaveContact(contact); - DaoFactory.GetContactInfoDao() + _daoFactory.GetContactInfoDao() .Save(new ContactInfo { ContactID = contact.ID, @@ -319,12 +317,12 @@ public Contact CreateContact(string contactPhone) Data = contactPhone }); - CRMSecurity.SetAccessTo(contact, new List { SecurityContext.CurrentAccount.ID }); + _crmSecurity.SetAccessTo(contact, new List { _securityContext.CurrentAccount.ID }); return contact; } - private class QueueItem + private class QueueItem : DistributedTask { public int TenantID { get; set; } public string CallID { get; set; } diff --git a/products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs b/products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs deleted file mode 100644 index 9c31f8297ea..00000000000 --- a/products/ASC.CRM/Server/Core/Enums/ProgressStatus.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -namespace ASC.CRM.Core.Enums -{ - public enum ProgressStatus - { - Queued, - Started, - Done, - Failed - } -} diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 0c3825dc023..9377e05f2f8 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -37,6 +37,7 @@ using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Security.Authentication; +using ASC.Common.Threading; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.Core.Users; @@ -62,58 +63,9 @@ using Newtonsoft.Json.Linq; namespace ASC.Web.CRM.Classes -{ - [Singletone] - public class ExportDataCache - { - public ExportDataCache(ICache ascCache) - { - Cache = ascCache; - } - - public readonly ICache Cache; - - public String GetStateCacheKey(string key) - { - return String.Format("{0}:crm:queue:exporttocsv", key); - } - - public String GetCancelCacheKey(string key) - { - return String.Format("{0}:crm:queue:exporttocsv:cancel", key); - } - - public ExportDataOperation Get(string key) - { - return Cache.Get(GetStateCacheKey(key)); - } - - public void Insert(string key, ExportDataOperation data) - { - Cache.Insert(GetStateCacheKey(key), data, TimeSpan.FromMinutes(1)); - } - - public bool CheckCancelFlag(string key) - { - var fromCache = Cache.Get(GetCancelCacheKey(key)); - - return !String.IsNullOrEmpty(fromCache); - } - - public void SetCancelFlag(string key) - { - Cache.Insert(GetCancelCacheKey(key), "true", TimeSpan.FromMinutes(1)); - } - - public void ResetAll(string key) - { - Cache.Remove(GetStateCacheKey(key)); - Cache.Remove(GetCancelCacheKey(key)); - } - } - +{ [Transient] - public class ExportDataOperation : IProgressItem + public class ExportDataOperation : DistributedTaskProgress, IProgressItem { public ExportDataOperation(UserManager userManager, FileUtility fileUtility, @@ -121,7 +73,6 @@ public ExportDataOperation(UserManager userManager, IOptionsMonitor logger, TenantManager tenantManager, Global global, - ExportDataCache exportDataCache, CommonLinkUtility commonLinkUtility, NotifyClient notifyClient, DaoFactory daoFactory, @@ -145,13 +96,11 @@ public ExportDataOperation(UserManager userManager, _log = logger.Get("ASC.CRM"); - Status = ProgressStatus.Queued; Error = null; Percentage = 0; IsCompleted = false; FileUrl = null; - ExportDataCache = exportDataCache; SecurityContext = securityContext; CommonLinkUtility = commonLinkUtility; @@ -166,7 +115,7 @@ public void Configure(object id, FilterObject filterObject, string fileName) { FileName = fileName ?? CRMSettingResource.Export + (filterObject == null ? ".zip" : ".csv"); _filterObject = filterObject; - Id = id; + Id = id.ToString(); } @@ -180,7 +129,6 @@ public void Configure(object id, FilterObject filterObject, string fileName) public CommonLinkUtility CommonLinkUtility { get; } public SecurityContext SecurityContext { get; } public DaoFactory DaoFactory { get; } - public ExportDataCache ExportDataCache { get; } public UserManager UserManager { get; } public FileUtility FileUtility { get; } @@ -218,17 +166,9 @@ public object Clone() { return MemberwiseClone(); } - - public object Id { get; set; } - - public object Status { get; set; } - + public object Error { get; set; } - public double Percentage { get; set; } - - public bool IsCompleted { get; set; } - public string FileName { get; set; } public string FileUrl { get; set; } @@ -272,12 +212,10 @@ private String DataTableToCsv(DataTable dataTable) return result.ToString(); } - public void RunJob() + protected override void DoJob() { try { - Status = ProgressStatus.Started; - TenantManager.SetCurrentTenant(_tenantId); SecurityContext.AuthenticateMe(_author); @@ -287,44 +225,37 @@ public void RunJob() System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; _log.Debug("Start Export Data"); - - ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); - + if (_filterObject == null) ExportAllData(DaoFactory); else ExportPartData(DaoFactory); - Complete(100, ProgressStatus.Done, null); + Complete(100, DistributedTaskStatus.Completed, null); _log.Debug("Export is completed"); } catch (OperationCanceledException) { - Complete(0, ProgressStatus.Done, null); + Complete(0, DistributedTaskStatus.Completed, null); _log.Debug("Export is cancel"); } catch (Exception ex) { - Complete(0, ProgressStatus.Failed, ex.Message); + Complete(0, DistributedTaskStatus.Failted, ex.Message); _log.Error(ex); } - finally - { - ExportDataCache.ResetAll((string)Id); - } } - private void Complete(double percentage, ProgressStatus status, object error) + private void Complete(double percentage, DistributedTaskStatus status, object error) { IsCompleted = true; Percentage = percentage; Status = status; Error = error; - ExportDataCache.Insert((string)Id, (ExportDataOperation)Clone()); } private void ExportAllData(DaoFactory daoFactory) @@ -604,16 +535,9 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String foreach (var contact in contacts) { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - Percentage += 1.0 * 100 / _totalCount; + PublishChanges(); + var isCompany = contact is Company; @@ -838,16 +762,9 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) foreach (var deal in deals) { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); Percentage += 1.0 * 100 / _totalCount; + PublishChanges(); var contactTags = String.Empty; @@ -956,16 +873,8 @@ private String ExportCasesToCsv(IEnumerable cases, foreach (var item in cases) { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - Percentage += 1.0 * 100 / _totalCount; + PublishChanges(); var contactTags = String.Empty; @@ -1031,16 +940,8 @@ private String ExportHistoryToCsv(IEnumerable events, DaoFact foreach (var item in events) { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - Percentage += 1.0 * 100 / _totalCount; + PublishChanges(); var entityTitle = String.Empty; @@ -1166,16 +1067,8 @@ private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) foreach (var item in tasks) { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - Percentage += 1.0 * 100 / _totalCount; + PublishChanges(); var entityTitle = String.Empty; @@ -1298,16 +1191,8 @@ private String ExportInvoiceItemsToCsv(IEnumerable invoiceItems, Da foreach (var item in invoiceItems) { - if (ExportDataCache.CheckCancelFlag(key)) - { - ExportDataCache.ResetAll(key); - - throw new OperationCanceledException(); - } - - ExportDataCache.Insert(key, (ExportDataOperation)Clone()); - Percentage += 1.0 * 100 / _totalCount; + PublishChanges(); var tax1 = item.InvoiceTax1ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax1ID) : null; var tax2 = item.InvoiceTax2ID != 0 ? taxes.Find(t => t.ID == item.InvoiceTax2ID) : null; @@ -1359,34 +1244,29 @@ private String SaveCsvFileInMyDocument(String title, String data) public class ExportToCsv { private readonly object Locker = new object(); - - private readonly ProgressQueue Queue; + private readonly DistributedTaskQueue _queue; + private readonly ExportDataOperation _exportDataOperation; + private readonly SecurityContext _securityContext; + protected readonly int _tenantID; public ExportToCsv(SecurityContext securityContext, - ExportDataCache exportDataCache, TenantManager tenantManager, - ProgressQueueOptionsManager progressQueueOptionsManager, + DistributedTaskQueueOptionsManager queueOptions, ExportDataOperation exportDataOperation) { - SecurityContext = securityContext; - ExportDataCache = exportDataCache; - TenantID = tenantManager.GetCurrentTenant().TenantId; - Queue = progressQueueOptionsManager.Value; - ExportDataOperation = exportDataOperation; + _securityContext = securityContext; + _tenantID = tenantManager.GetCurrentTenant().TenantId; + _queue = queueOptions.Get(); + _exportDataOperation = exportDataOperation; } - protected int TenantID { get; private set; } - - public ExportDataOperation ExportDataOperation { get; } - public ExportDataCache ExportDataCache { get; } - - public SecurityContext SecurityContext { get; } - public IProgressItem GetStatus(bool partialDataExport) { var key = GetKey(partialDataExport); - return Queue.GetStatus(key) ?? ExportDataCache.Get(key); + var operation = _queue.GetTasks().FirstOrDefault(x => x.Id == key); + + return operation; } public IProgressItem Start(FilterObject filterObject, string fileName) @@ -1395,27 +1275,21 @@ public IProgressItem Start(FilterObject filterObject, string fileName) { var key = GetKey(filterObject != null); - var operation = Queue.GetStatus(key); + var operation = _queue.GetTasks().FirstOrDefault(x => x.Id == key); - if (operation == null) + if (operation != null && operation.IsCompleted) { - var fromCache = ExportDataCache.Get(key); - - if (fromCache != null) - return fromCache; + _queue.RemoveTask(operation.Id); + operation = null; } if (operation == null) { + _exportDataOperation.Configure(key, filterObject, fileName); - ExportDataOperation.Configure(key, filterObject, fileName); - - Queue.Add(ExportDataOperation); + _queue.QueueTask(_exportDataOperation); } - if (!Queue.IsStarted) - Queue.Start(x => x.RunJob()); - return operation; } } @@ -1426,21 +1300,19 @@ public void Cancel(bool partialDataExport) { var key = GetKey(partialDataExport); - var findedItem = Queue.GetItems().FirstOrDefault(elem => (string)elem.Id == key); + var findedItem = _queue.GetTasks().FirstOrDefault(x => x.Id == key); if (findedItem != null) { - Queue.Remove(findedItem); + _queue.RemoveTask(findedItem.Id); } - - ExportDataCache.SetCancelFlag(key); } } public string GetKey(bool partialDataExport) { - return string.Format("{0}_{1}", TenantID, - partialDataExport ? SecurityContext.CurrentAccount.ID : Guid.Empty); + return string.Format("{0}_{1}", _tenantID, + partialDataExport ? _securityContext.CurrentAccount.ID : Guid.Empty); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index 6c6cf109611..e88a30dfddd 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -47,7 +47,7 @@ public partial class ImportDataOperation { private void ImportCaseData(DaoFactory _daoFactory) { - using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { int currentIndex = 0; @@ -153,15 +153,7 @@ private void ImportCaseData(DaoFactory _daoFactory) } Percentage = 62.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Case)) - { - ImportDataCache.ResetAll(EntityType.Case); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + PublishChanges(); var newIDs = casesDao.SaveCasesList(findedCases); findedCases.ForEach(d => d.ID = newIDs[d.ID]); @@ -171,15 +163,7 @@ private void ImportCaseData(DaoFactory _daoFactory) customFieldDao.SaveList(findedCustomField); Percentage += 12.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Case)) - { - ImportDataCache.ResetAll(EntityType.Case); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + PublishChanges(); foreach (var findedCasesMemberKey in findedCasesMembers.Keys) { @@ -187,15 +171,7 @@ private void ImportCaseData(DaoFactory _daoFactory) } Percentage += 12.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Case)) - { - ImportDataCache.ResetAll(EntityType.Case); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); + PublishChanges(); foreach (var findedTagKey in findedTags.Keys) @@ -204,20 +180,11 @@ private void ImportCaseData(DaoFactory _daoFactory) } if (_importSettings.IsPrivate) - findedCases.ForEach(dealItem => CRMSecurity.SetAccessTo(dealItem, _importSettings.AccessList)); + findedCases.ForEach(dealItem => _crmSecurity.SetAccessTo(dealItem, _importSettings.AccessList)); Percentage += 12.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Case)) - { - ImportDataCache.ResetAll(EntityType.Case); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Case, (ImportDataOperation)Clone()); - + PublishChanges(); } Complete(); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index 4942c2c551b..1e9e28c0951 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -67,7 +67,7 @@ private void ImportContactsData(DaoFactory _daoFactory) var findedContactInfos = new List(); #region Read csv - using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) { CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings); @@ -128,17 +128,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #endregion Percentage = 37.5; - - #region Check Cancel flag | Insert Operation InCache - if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) - { - ImportDataCache.ResetAll(EntityType.Contact); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); - #endregion + PublishChanges(); #region Processing duplicate rule @@ -154,17 +144,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #endregion Percentage += 12.5; - - #region Check Cancel flag | Insert Operation InCache - if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) - { - ImportDataCache.ResetAll(EntityType.Contact); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); - #endregion + PublishChanges(); #region Manipulation for saving Companies for persons + CRMSecurity @@ -190,7 +170,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #region CRMSecurity set -by every item- - portion.ForEach(ct => CRMSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); + portion.ForEach(ct => _crmSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); #endregion @@ -236,7 +216,7 @@ private void ImportContactsData(DaoFactory _daoFactory) findedCompany.ID = contactDao.SaveContact(findedCompany); person.CompanyID = findedCompany.ID; - CRMSecurity.SetAccessTo(findedCompany, _importSettings.ContactManagers); + _crmSecurity.SetAccessTo(findedCompany, _importSettings.ContactManagers); if (_importSettings.Tags.Count != 0) { @@ -271,7 +251,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #region CRMSecurity set -by every item- - portion.ForEach(ct => CRMSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); + portion.ForEach(ct => _crmSecurity.SetAccessTo(ct, _importSettings.ContactManagers)); #endregion @@ -287,17 +267,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #endregion Percentage += 12.5; - - #region Check Cancel flag | Insert Operation InCache - if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) - { - ImportDataCache.ResetAll(EntityType.Contact); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); - #endregion + PublishChanges(); #region Save contact infos -by portions- @@ -323,17 +293,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #endregion Percentage += 12.5; - - #region Check Cancel flag | Insert Operation InCache - if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) - { - ImportDataCache.ResetAll(EntityType.Contact); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); - #endregion + PublishChanges(); #region Save custom fields -by portions- @@ -359,17 +319,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #endregion Percentage += 12.5; - - #region Check Cancel flag | Insert Operation InCache - if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) - { - ImportDataCache.ResetAll(EntityType.Contact); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); - #endregion + PublishChanges(); #region Save tags @@ -391,17 +341,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #endregion Percentage += 12.5; - - #region Check Cancel flag | Insert Operation InCache - if (ImportDataCache.CheckCancelFlag(EntityType.Contact)) - { - ImportDataCache.ResetAll(EntityType.Contact); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Contact, (ImportDataOperation)Clone()); - #endregion + PublishChanges(); Complete(); } @@ -416,6 +356,8 @@ private bool _CommonData(int currentIndex, DaoFactory _daoFactory, ref Contact c return false; Percentage += 1.0 * 100 / (ImportFromCSV.MaxRoxCount * 3); + PublishChanges(); + var listItemDao = _daoFactory.GetListItemDao(); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 76eccf6a305..6055fb1d9c8 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -32,6 +32,7 @@ using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Security.Authentication; +using ASC.Common.Threading; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.Core.Common.Settings; @@ -46,99 +47,33 @@ namespace ASC.Web.CRM.Classes { - [Scope] - public class ImportDataCache - { - public ImportDataCache(TenantManager tenantManager, - ICache cache) - { - TenantID = tenantManager.GetCurrentTenant().TenantId; - Cache = cache; - } - - public int TenantID { get; } - - public readonly ICache Cache; - - public String GetStateCacheKey(EntityType entityType, int tenantId = -1) - { - if (tenantId == -1) - { - tenantId = TenantID; - } - - return String.Format("{0}:crm:queue:importtocsv:{1}", tenantId.ToString(CultureInfo.InvariantCulture), entityType.ToString()); - } - - public String GetCancelCacheKey(EntityType entityType, int tenantId = -1) - { - if (tenantId == -1) - { - tenantId = TenantID; - } - - return String.Format("{0}:crm:queue:importtocsv:{1}:cancel", tenantId.ToString(CultureInfo.InvariantCulture), entityType.ToString()); - } - - public ImportDataOperation Get(EntityType entityType) - { - return Cache.Get(GetStateCacheKey(entityType)); - } - - public void Insert(EntityType entityType, ImportDataOperation data) - { - Cache.Insert(GetStateCacheKey(entityType), data, TimeSpan.FromMinutes(1)); - } - - public bool CheckCancelFlag(EntityType entityType) - { - var fromCache = Cache.Get(GetCancelCacheKey(entityType)); - - if (!String.IsNullOrEmpty(fromCache)) - return true; - - return false; - - } - - public void SetCancelFlag(EntityType entityType) - { - Cache.Insert(GetCancelCacheKey(entityType), true, TimeSpan.FromMinutes(1)); - } - - public void ResetAll(EntityType entityType, int tenantId = -1) - { - Cache.Remove(GetStateCacheKey(entityType, tenantId)); - Cache.Remove(GetCancelCacheKey(entityType, tenantId)); - } - } - [Transient] - public partial class ImportDataOperation : IProgressItem + public partial class ImportDataOperation : DistributedTaskProgress, IProgressItem { private readonly ILog _log; - private readonly IDataStore _dataStore; - private readonly IAccount _author; - private readonly int _tenantID; - - private string _CSVFileURI; - + private string _csvFileURI; private ImportCSVSettings _importSettings; - private EntityType _entityType; - private string[] _columns; - private bool _IsConfigure; + public readonly CurrencyProvider _currencyProvider; + public readonly NotifyClient _notifyClient; + public readonly SettingsManager _settingsManager; + public readonly CrmSecurity _crmSecurity; + public readonly TenantManager _tenantManager; + public readonly SecurityContext _securityContext; + public readonly UserManager _userManager; + public readonly DaoFactory _daoFactory; + public readonly ILog _logManager; + public ImportDataOperation(Global global, TenantManager tenantManager, IOptionsMonitor logger, UserManager userManager, - ImportDataCache importDataCache, CrmSecurity crmSecurity, NotifyClient notifyClient, SettingsManager settingsManager, @@ -147,27 +82,24 @@ public ImportDataOperation(Global global, SecurityContext securityContext ) { - ImportDataCache = importDataCache; + _userManager = userManager; - UserManager = userManager; - - - SecurityContext = securityContext; + _securityContext = securityContext; _dataStore = global.GetStore(); _tenantID = tenantManager.GetCurrentTenant().TenantId; - _author = SecurityContext.CurrentAccount; + _author = _securityContext.CurrentAccount; - NotifyClient = notifyClient; + _notifyClient = notifyClient; Id = String.Format("{0}_{1}", _tenantID, (int)_entityType); _log = logger.Get("ASC.CRM"); - CRMSecurity = crmSecurity; - SettingsManager = settingsManager; - CurrencyProvider = currencyProvider; - DaoFactory = daoFactory; + _crmSecurity = crmSecurity; + _settingsManager = settingsManager; + _currencyProvider = currencyProvider; + _daoFactory = daoFactory; } public void Configure(EntityType entityType, @@ -176,7 +108,7 @@ public void Configure(EntityType entityType, { _entityType = entityType; - _CSVFileURI = CSVFileURI; + _csvFileURI = CSVFileURI; if (!String.IsNullOrEmpty(importSettingsJSON)) _importSettings = new ImportCSVSettings(importSettingsJSON); @@ -184,26 +116,7 @@ public void Configure(EntityType entityType, _IsConfigure = true; } - public CurrencyProvider CurrencyProvider { get; } - - public NotifyClient NotifyClient { get; } - - public SettingsManager SettingsManager { get; } - - public CrmSecurity CRMSecurity { get; } - - public ImportDataCache ImportDataCache { get; } - - public TenantManager TenantManager { get; } - - public SecurityContext SecurityContext { get; } - - public UserManager UserManager { get; } - - public DaoFactory DaoFactory { get; } - - public ILog LogManager { get; } - + public override bool Equals(object obj) { @@ -227,16 +140,9 @@ public object Clone() return MemberwiseClone(); } - public object Id { get; set; } - - public object Status { get; set; } - + public object Error { get; set; } - public double Percentage { get; set; } - - public bool IsCompleted { get; set; } - private String GetPropertyValue(String propertyName) { if (_importSettings.ColumnMapping[propertyName] == null) return String.Empty; @@ -257,41 +163,37 @@ private void Complete() _log.Debug("Import is completed"); - NotifyClient.SendAboutImportCompleted(_author.ID, _entityType); - - ImportDataCache.Insert(_entityType, (ImportDataOperation)Clone()); + _notifyClient.SendAboutImportCompleted(_author.ID, _entityType); } - public void RunJob() + protected override void DoJob() { try { if (!_IsConfigure) throw new Exception("Is not configure. Please, call configure method."); - TenantManager.SetCurrentTenant(_tenantID); - SecurityContext.AuthenticateMe(_author); + _tenantManager.SetCurrentTenant(_tenantID); + _securityContext.AuthenticateMe(_author); - var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + var userCulture = _userManager.GetUsers(_securityContext.CurrentAccount.ID).GetCulture(); System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; - ImportDataCache.Insert(_entityType, (ImportDataOperation)Clone()); - switch (_entityType) { case EntityType.Contact: - ImportContactsData(DaoFactory); + ImportContactsData(_daoFactory); break; case EntityType.Opportunity: - ImportOpportunityData(DaoFactory); + ImportOpportunityData(_daoFactory); break; case EntityType.Case: - ImportCaseData(DaoFactory); + ImportCaseData(_daoFactory); break; case EntityType.Task: - ImportTaskData(DaoFactory); + ImportTaskData(_daoFactory); break; default: throw new ArgumentException(CRMErrorsResource.EntityTypeUnknown); @@ -302,10 +204,6 @@ public void RunJob() { _log.Debug("Queue canceled"); } - finally - { - ImportDataCache.ResetAll(_entityType, _tenantID); - } } } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index e9e2dee9b53..f58552274c6 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -49,9 +49,9 @@ public partial class ImportDataOperation { private void ImportOpportunityData(DaoFactory _daoFactory) { - var allUsers = UserManager.GetUsers(EmployeeStatus.All).ToList(); + var allUsers = _userManager.GetUsers(EmployeeStatus.All).ToList(); - using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { int currentIndex = 0; @@ -101,10 +101,10 @@ private void ImportOpportunityData(DaoFactory _daoFactory) if (DateTime.TryParse(GetPropertyValue("expected_close_date"), out expectedCloseDate)) obj.ExpectedCloseDate = expectedCloseDate; - var currency = CurrencyProvider.Get(GetPropertyValue("bid_currency")); + var currency = _currencyProvider.Get(GetPropertyValue("bid_currency")); - var crmSettings = SettingsManager.Load(); - var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); if (currency != null) obj.BidCurrency = currency.Abbreviation; @@ -263,15 +263,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) } Percentage += 1.0 * 100 / (ImportFromCSV.MaxRoxCount * 2); - - if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) - { - ImportDataCache.ResetAll(EntityType.Opportunity); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + PublishChanges(); findedDeals.Add(obj); @@ -282,44 +274,21 @@ private void ImportOpportunityData(DaoFactory _daoFactory) } Percentage = 50; + PublishChanges(); - if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) - { - ImportDataCache.ResetAll(EntityType.Opportunity); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); var newDealIDs = dealDao.SaveDealList(findedDeals); findedDeals.ForEach(d => d.ID = newDealIDs[d.ID]); Percentage += 12.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) - { - ImportDataCache.ResetAll(EntityType.Opportunity); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + PublishChanges(); findedCustomField.ForEach(item => item.EntityID = newDealIDs[item.EntityID]); customFieldDao.SaveList(findedCustomField); Percentage += 12.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) - { - ImportDataCache.ResetAll(EntityType.Opportunity); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + PublishChanges(); foreach (var findedDealMemberKey in findedDealMembers.Keys) { @@ -327,15 +296,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) } Percentage += 12.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) - { - ImportDataCache.ResetAll(EntityType.Opportunity); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); + PublishChanges(); foreach (var findedTagKey in findedTags.Keys) { @@ -343,19 +304,10 @@ private void ImportOpportunityData(DaoFactory _daoFactory) } if (_importSettings.IsPrivate) - findedDeals.ForEach(dealItem => CRMSecurity.SetAccessTo(dealItem, _importSettings.AccessList)); + findedDeals.ForEach(dealItem => _crmSecurity.SetAccessTo(dealItem, _importSettings.AccessList)); Percentage += 12.5; - - if (ImportDataCache.CheckCancelFlag(EntityType.Opportunity)) - { - ImportDataCache.ResetAll(EntityType.Opportunity); - - throw new OperationCanceledException(); - } - - ImportDataCache.Insert(EntityType.Opportunity, (ImportDataOperation)Clone()); - + PublishChanges(); } Complete(); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index 3e00fe26a92..8993aa3c6b9 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -29,6 +29,7 @@ using System.Linq; using ASC.Common; +using ASC.Common.Threading; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.CRM.Core.Enums; @@ -43,26 +44,18 @@ namespace ASC.Web.CRM.Classes public class ImportFromCSV { public ImportFromCSV(TenantManager tenantProvider, - ImportDataCache importDataCache, - ProgressQueueOptionsManager progressQueueOptionsManager, + DistributedTaskQueueOptionsManager progressQueueOptionsManager, ImportDataOperation importDataOperation) { - TenantId = tenantProvider.GetCurrentTenant().TenantId; - ImportDataCache = importDataCache; - _importQueue = progressQueueOptionsManager.Value; - ImportDataOperation = importDataOperation; + _tenantId = tenantProvider.GetCurrentTenant().TenantId; + _importQueue = progressQueueOptionsManager.Get(); + _importDataOperation = importDataOperation; } - public ImportDataOperation ImportDataOperation { get; } - - public ImportDataCache ImportDataCache { get; } - - public int TenantId { get; } - + private readonly ImportDataOperation _importDataOperation; + private readonly int _tenantId; private readonly object _syncObj = new object(); - - private readonly ProgressQueue _importQueue; - + private readonly DistributedTaskQueue _importQueue; public readonly int MaxRoxCount = 10000; public int GetQuotas() @@ -120,38 +113,37 @@ public JObject GetInfo(Stream CSVFileStream, String jsonSettings) } - public IProgressItem GetStatus(EntityType entityType) + protected String GetKey(EntityType entityType) { - var result = _importQueue.GetStatus(String.Format("{0}_{1}", TenantId, (int)entityType)); + return String.Format("{0}_{1}", _tenantId, (int)entityType); + } - if (result == null) - { - return ImportDataCache.Get(entityType); - } + public IProgressItem GetStatus(EntityType entityType) + { + var operation = _importQueue.GetTasks().FirstOrDefault(x => x.Id == GetKey(entityType)); - return result; + return operation; } public IProgressItem Start(EntityType entityType, String CSVFileURI, String importSettingsJSON) { lock (_syncObj) { - var operation = GetStatus(entityType); + var operation = _importQueue.GetTasks().FirstOrDefault(x => x.Id == GetKey(entityType)); - if (operation == null) + if (operation != null && operation.IsCompleted) { - var fromCache = ImportDataCache.Get(entityType); - - if (fromCache != null) - return fromCache; + _importQueue.RemoveTask(operation.Id); + + operation = null; - ImportDataOperation.Configure(entityType, CSVFileURI, importSettingsJSON); - - _importQueue.Add(ImportDataOperation); } - if (!_importQueue.IsStarted) - _importQueue.Start(x => x.RunJob()); + if (operation == null) + { + _importDataOperation.Configure(entityType, CSVFileURI, importSettingsJSON); + _importQueue.QueueTask(_importDataOperation); + } return operation; } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs index 7640c793465..7ae303c4de1 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs @@ -62,7 +62,7 @@ public ImportDataOperation(TenantUtil tenantUtil, private void ImportTaskData(DaoFactory _daoFactory) { - using (var CSVFileStream = _dataStore.GetReadStream("temp", _CSVFileURI)) + using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { int currentIndex = 0; @@ -74,7 +74,7 @@ private void ImportTaskData(DaoFactory _daoFactory) var findedTasks = new List(); var taskCategories = listItemDao.GetItems(ListType.TaskCategory); - var allUsers = UserManager.GetUsers(EmployeeStatus.All).ToList(); + var allUsers = _userManager.GetUsers(EmployeeStatus.All).ToList(); while (csv.ReadNextRecord()) { @@ -170,10 +170,12 @@ private void ImportTaskData(DaoFactory _daoFactory) } Percentage = 50; + PublishChanges(); taskDao.SaveTaskList(findedTasks); Percentage += 12.5; + PublishChanges(); Complete(); diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index 6502c6c7d25..4d983160797 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -39,6 +39,7 @@ using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; +using ASC.Common.Threading; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.Core.Common.Settings; @@ -72,7 +73,7 @@ namespace ASC.Web.CRM.Classes { [Transient] - public class SendBatchEmailsOperation : IProgressItem, IDisposable + public class SendBatchEmailsOperation : DistributedTaskProgress, IProgressItem, IDisposable { private bool _storeInHistory; private readonly ILog _log; @@ -86,11 +87,16 @@ public class SendBatchEmailsOperation : IProgressItem, IDisposable private int historyCategory; private double _exactPercentageValue = 0; - public object Id { get; set; } - public object Status { get; set; } + private DaoFactory _daoFactory; + private FilesIntegration _filesIntegration; + private AuthManager _authManager; + private UserManager _userManager; + private TenantManager _tenantManager; + private SecurityContext _securityContext; + private TenantUtil _tenantUtil; + + public object Error { get; set; } - public double Percentage { get; set; } - public bool IsCompleted { get; set; } private SendBatchEmailsOperation() { @@ -105,41 +111,32 @@ public SendBatchEmailsOperation( UserManager userManager, AuthManager authManager, SettingsManager settingsManager, - MailSenderDataCache mailSenderDataCache, DaoFactory daoFactory, - CoreConfiguration coreConfiguration + CoreConfiguration coreConfiguration, + FilesIntegration filesIntegration ) { - TenantUtil = tenantUtil; - SecurityContext = securityContext; + _tenantUtil = tenantUtil; + _securityContext = securityContext; Percentage = 0; _log = logger.Get("ASC.CRM.MailSender"); _tenantID = tenantManager.GetCurrentTenant().TenantId; - + var _crmSettings = settingsManager.Load(); _smtpSetting = new SMTPServerSetting(coreConfiguration.SmtpSettings); - _currUser = SecurityContext.CurrentAccount.ID; - + _currUser = _securityContext.CurrentAccount.ID; - - AuthManager = authManager; - UserManager = userManager; - MailSenderDataCache = mailSenderDataCache; - DaoFactory = daoFactory; + _authManager = authManager; + _userManager = userManager; + _daoFactory = daoFactory; + _tenantManager = tenantManager; + _filesIntegration = filesIntegration; } - public DaoFactory DaoFactory { get; } - public FilesIntegration FilesIntegration { get; } - public MailSenderDataCache MailSenderDataCache { get; } - public AuthManager AuthManager { get; } - public UserManager UserManager { get; } - public TenantManager TenantManager { get; } - public SecurityContext SecurityContext { get; } - public TenantUtil TenantUtil { get; } public void Configure(List fileID, List contactID, @@ -153,12 +150,9 @@ public void Configure(List fileID, _bodyTempate = bodyTempate; _storeInHistory = storeInHistory; - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = 0, - DeliveryCount = 0 - }; + SetProperty("RecipientCount", _contactID.Count); + SetProperty("EstimatedTime", 0); + SetProperty("DeliveryCount", 0); } private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) @@ -170,7 +164,7 @@ private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) ContactID = contactID, Content = content, CreateBy = _currUser, - CreateOn = TenantUtil.DateTimeNow(), + CreateOn = _tenantUtil.DateTimeNow(), }; if (historyCategory == 0) { @@ -199,17 +193,17 @@ private void AddToHistory(int contactID, String content, DaoFactory _daoFactory) } } - public void RunJob() + protected override void DoJob() { SmtpClient smtpClient = null; try { - TenantManager.SetCurrentTenant(_tenantID); - SecurityContext.AuthenticateMe(AuthManager.GetAccountByID(_tenantID, _currUser)); + _tenantManager.SetCurrentTenant(_tenantID); + _securityContext.AuthenticateMe(_authManager.GetAccountByID(_tenantID, _currUser)); smtpClient = GetSmtpClient(); - var userCulture = UserManager.GetUsers(_currUser).GetCulture(); + var userCulture = _userManager.GetUsers(_currUser).GetCulture(); Thread.CurrentThread.CurrentCulture = userCulture; Thread.CurrentThread.CurrentUICulture = userCulture; @@ -222,11 +216,9 @@ public void RunJob() return; } - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - var from = new MailboxAddress(_smtpSetting.SenderDisplayName, _smtpSetting.SenderEmailAddress); var filePaths = new List(); - var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + var fileDao = _filesIntegration.DaoFactory.GetFileDao(); foreach (var fileID in _fileID) { @@ -254,7 +246,7 @@ public void RunJob() } } - var templateManager = new MailTemplateManager(DaoFactory); + var templateManager = new MailTemplateManager(_daoFactory); var deliveryCount = 0; try @@ -264,10 +256,11 @@ public void RunJob() { _exactPercentageValue += 100.0 / contactCount; Percentage = Math.Round(_exactPercentageValue); + PublishChanges(); if (IsCompleted) break; // User selected cancel - var contactInfoDao = DaoFactory.GetContactInfoDao(); + var contactInfoDao = _daoFactory.GetContactInfoDao(); var startDate = DateTime.Now; @@ -331,7 +324,7 @@ public void RunJob() { if (_storeInHistory) { - AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), DaoFactory); + AddToHistory(contactID, string.Format(CRMCommonResource.MailHistoryEventTemplate, mimeMessage.Subject), _daoFactory); } var endDate = DateTime.Now; @@ -342,36 +335,15 @@ public void RunJob() var estimatedTime = TimeSpan.FromTicks(waitInterval.Ticks * (_contactID.Count - deliveryCount)); - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = estimatedTime.ToString(), - DeliveryCount = deliveryCount - }; - } - - if (MailSenderDataCache.CheckCancelFlag()) - { - MailSenderDataCache.ResetAll(); - - throw new OperationCanceledException(); + SetProperty("RecipientCount", _contactID.Count); + SetProperty("EstimatedTime", estimatedTime.ToString()); + SetProperty("DeliveryCount", deliveryCount); } - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - if (Percentage > 100) { Percentage = 100; - - if (MailSenderDataCache.CheckCancelFlag()) - { - MailSenderDataCache.ResetAll(); - - throw new OperationCanceledException(); - } - - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - + PublishChanges(); } } } @@ -390,48 +362,9 @@ public void RunJob() } } - Status = new - { - RecipientCount = _contactID.Count, - EstimatedTime = TimeSpan.Zero.ToString(), - DeliveryCount = deliveryCount - }; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + SetProperty("RecipientCount", _contactID.Count); + SetProperty("EstimatedTime", TimeSpan.Zero.ToString()); + SetProperty("DeliveryCount", deliveryCount); } catch (SocketException e) { @@ -486,7 +419,7 @@ private void DeleteFiles() { if (_fileID == null || _fileID.Count == 0) return; - var fileDao = FilesIntegration.DaoFactory.GetFileDao(); + var fileDao = _filesIntegration.DaoFactory.GetFileDao(); foreach (var fileID in _fileID) { @@ -523,11 +456,6 @@ private void Complete() IsCompleted = true; Percentage = 100; _log.Debug("Completed"); - - MailSenderDataCache.Insert((SendBatchEmailsOperation)Clone()); - - Thread.Sleep(10000); - MailSenderDataCache.ResetAll(); } public override bool Equals(object obj) @@ -549,85 +477,35 @@ public void Dispose() } } - [Scope] - public class MailSenderDataCache - { - public MailSenderDataCache(TenantManager tenantManager, - ICache cache) - { - TenantID = tenantManager.GetCurrentTenant().TenantId; - Cache = cache; - } - - public int TenantID { get; } - - public readonly ICache Cache; - - public string GetStateCacheKey() - { - return string.Format("{0}:crm:queue:sendbatchemails", TenantID); - } - - public string GetCancelCacheKey() - { - return string.Format("{0}:crm:queue:sendbatchemails:cancel", TenantID); - } - - public SendBatchEmailsOperation Get() - { - return Cache.Get(GetStateCacheKey()); - } - - public void Insert(SendBatchEmailsOperation data) - { - Cache.Insert(GetStateCacheKey(), data, TimeSpan.FromMinutes(1)); - } - - public bool CheckCancelFlag() - { - var fromCache = Cache.Get(GetCancelCacheKey()); - - if (!String.IsNullOrEmpty(fromCache)) - return true; - - return false; - - } - - public void SetCancelFlag() - { - Cache.Insert(GetCancelCacheKey(), "true", TimeSpan.FromMinutes(1)); - } - - public void ResetAll() - { - Cache.Remove(GetStateCacheKey()); - Cache.Remove(GetCancelCacheKey()); - } - } - [Scope] public class MailSender { private readonly Object _syncObj = new Object(); - private readonly ProgressQueue _mailQueue; + private readonly DistributedTaskQueue _mailQueue; private readonly int quotas = 50; + private readonly TenantManager _tenantManager; + private readonly SettingsManager _settingsManager; + private readonly SendBatchEmailsOperation _sendBatchEmailsOperation; + private readonly int _tenantID; + private readonly CoreConfiguration _coreConfiguration; + private readonly IOptionsMonitor _logManager; + public MailSender( IConfiguration configuration, TenantManager tenantManager, SettingsManager settingsManager, - MailSenderDataCache mailSenderDataCache, - ProgressQueueOptionsManager progressQueueOptionsManager, + DistributedTaskQueueOptionsManager progressQueueOptionsManager, SendBatchEmailsOperation sendBatchEmailsOperation, - CoreConfiguration coreConfiguration - ) + CoreConfiguration coreConfiguration, + IOptionsMonitor logger + ) { - SendBatchEmailsOperation = sendBatchEmailsOperation; - TenantID = tenantManager.GetCurrentTenant().TenantId; - MailSenderDataCache = mailSenderDataCache; - _mailQueue = progressQueueOptionsManager.Value; - CoreConfiguration = coreConfiguration; + _sendBatchEmailsOperation = sendBatchEmailsOperation; + _tenantID = tenantManager.GetCurrentTenant().TenantId; + _mailQueue = progressQueueOptionsManager.Get(); + _coreConfiguration = coreConfiguration; + _logManager = logger; int parsed; @@ -636,20 +514,12 @@ CoreConfiguration coreConfiguration quotas = parsed; } - TenantManager = tenantManager; - SettingsManager = settingsManager; + _tenantManager = tenantManager; + _settingsManager = settingsManager; // LogManager = logger.Get(); } - public TenantManager TenantManager { get; } - public SettingsManager SettingsManager { get; } - public SendBatchEmailsOperation SendBatchEmailsOperation { get; } - public MailSenderDataCache MailSenderDataCache { get; } - public int TenantID { get; } - public CoreConfiguration CoreConfiguration { get; } - public IOptionsMonitor LogManager { get; } - public int GetQuotas() { return quotas; @@ -659,14 +529,12 @@ public IProgressItem Start(List fileID, List contactID, String subject { lock (_syncObj) { - var operation = _mailQueue.GetStatus(TenantID); + var operation = _mailQueue.GetTasks().FirstOrDefault(x => Convert.ToInt32(x.Id) == _tenantID); - if (operation == null) + if (operation != null && operation.IsCompleted) { - var mailSender = MailSenderDataCache.Get(); - - if (mailSender != null) - return mailSender; + _mailQueue.RemoveTask(operation.Id); + operation = null; } if (operation == null) @@ -686,15 +554,11 @@ public IProgressItem Start(List fileID, List contactID, String subject contactID = contactID.Take(GetQuotas()).ToList(); } - SendBatchEmailsOperation.Configure(fileID, contactID, subject, bodyTemplate, storeInHistory); + _sendBatchEmailsOperation.Configure(fileID, contactID, subject, bodyTemplate, storeInHistory); - _mailQueue.Add(operation); + _mailQueue.QueueTask(_sendBatchEmailsOperation); } - if (!_mailQueue.IsStarted) - { - _mailQueue.Start(x => x.RunJob()); - } return operation; } } @@ -720,15 +584,15 @@ private SmtpClient GetSmtpClient(SMTPServerSetting smtpSetting) public void StartSendTestMail(string recipientEmail, string mailSubj, string mailBody) { - var log = LogManager.Get("ASC.CRM.MailSender"); + var log = _logManager.Get("ASC.CRM.MailSender"); if (!recipientEmail.TestEmailRegex()) { throw new Exception(string.Format(CRMCommonResource.MailSender_InvalidEmail, recipientEmail)); } - TenantManager.SetCurrentTenant(TenantID); - var smtpSetting = new SMTPServerSetting(CoreConfiguration.SmtpSettings); + _tenantManager.SetCurrentTenant(_tenantID); + var smtpSetting = new SMTPServerSetting(_coreConfiguration.SmtpSettings); ThreadPool.QueueUserWorkItem(_ => { @@ -769,30 +633,21 @@ public void StartSendTestMail(string recipientEmail, string mailSubj, string mai public IProgressItem GetStatus() { - var result = _mailQueue.GetStatus(TenantID); - - if (result == null) - return MailSenderDataCache.Get(); + var findedItem = _mailQueue.GetTasks().FirstOrDefault(x => Convert.ToInt32(x.Id) == _tenantID); - return result; + return findedItem; } public void Cancel() { lock (_syncObj) { - var findedItem = _mailQueue.GetItems().Where(elem => (int)elem.Id == TenantID); + var findedItem = _mailQueue.GetTasks().FirstOrDefault(x => Convert.ToInt32(x.Id) == _tenantID); - if (findedItem.Any()) - { - _mailQueue.Remove(findedItem.ElementAt(0)); + if (findedItem == null) return; + + _mailQueue.RemoveTask(findedItem.Id); - MailSenderDataCache.ResetAll(); - } - else - { - MailSenderDataCache.SetCancelFlag(); - } } } } diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index eae84882bb4..39045edc790 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -25,9 +25,16 @@ using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Net; using System.Web; using ASC.Common; +using ASC.Common.Threading; using ASC.Common.Threading.Progress; using ASC.Core; using ASC.CRM.Core.Enums; @@ -41,16 +48,17 @@ namespace ASC.Web.CRM.Classes [Transient] public class PdfQueueWorker { - private readonly ProgressQueue Queue; + private readonly DistributedTaskQueue Queue; private readonly int tenantId; private readonly Guid userId; + private readonly object Locker = new object(); - public PdfQueueWorker(ProgressQueueOptionsManager progressQueueOptionsManager, + public PdfQueueWorker(DistributedTaskQueueOptionsManager queueOptions, PdfProgressItem pdfProgressItem, TenantManager tenantProvider, SecurityContext securityContext) { - Queue = progressQueueOptionsManager.Value; + Queue = queueOptions.Get(); PdfProgressItem = pdfProgressItem; tenantId = tenantProvider.GetCurrentTenant().TenantId; userId = securityContext.CurrentAccount.ID; @@ -67,7 +75,9 @@ public PdfProgressItem GetTaskStatus(int tenantId, int invoiceId) { var id = GetTaskId(tenantId, invoiceId); - return Queue.GetStatus(id) as PdfProgressItem; + var findedItem = Queue.GetTasks().FirstOrDefault(x => x.Id == id); + + return findedItem; } public void TerminateTask(int invoiceId) @@ -75,60 +85,50 @@ public void TerminateTask(int invoiceId) var item = GetTaskStatus(tenantId, invoiceId); if (item != null) - Queue.Remove(item); + Queue.RemoveTask(item.Id); } public PdfProgressItem StartTask(int invoiceId) { - lock (Queue.SynchRoot) + lock (Locker) { var task = GetTaskStatus(tenantId, invoiceId); if (task != null && task.IsCompleted) { - Queue.Remove(task); + Queue.RemoveTask(task.Id); task = null; } if (task == null) { - PdfProgressItem.Configure(GetTaskId(tenantId, invoiceId), tenantId, userId, invoiceId); - - Queue.Add(PdfProgressItem); + Queue.QueueTask(PdfProgressItem); } - if (!Queue.IsStarted) - Queue.Start(x => x.RunJob()); - return task; } } } [Transient] - public class PdfProgressItem : IProgressItem + public class PdfProgressItem : DistributedTaskProgress, IProgressItem { private readonly string _contextUrl; private int _tenantId; private int _invoiceId; private Guid _userId; - public object Id { get; set; } - public object Status { get; set; } public object Error { get; set; } - public double Percentage { get; set; } - public bool IsCompleted { get; set; } - public PdfCreator PdfCreator { get; } - public SecurityContext SecurityContext { get; } - public TenantManager TenantManager { get; } + private readonly PdfCreator PdfCreator; + private readonly SecurityContext SecurityContext; + private readonly TenantManager TenantManager; public PdfProgressItem(IHttpContextAccessor httpContextAccessor) { _contextUrl = httpContextAccessor.HttpContext != null ? httpContextAccessor.HttpContext.Request.GetUrlRewriter().ToString() : null; - Status = ProgressStatus.Queued; Error = null; Percentage = 0; IsCompleted = false; @@ -139,18 +139,18 @@ public void Configure(object id, Guid userId, int invoiceId) { - Id = id; + Id = id.ToString(); _tenantId = tenantId; _invoiceId = invoiceId; _userId = userId; } - public void RunJob() + + protected override void DoJob() { try { Percentage = 0; - Status = ProgressStatus.Started; TenantManager.SetCurrentTenant(_tenantId); @@ -166,14 +166,16 @@ public void RunJob() PdfCreator.CreateAndSaveFile(_invoiceId); Percentage = 100; - Status = ProgressStatus.Done; + PublishChanges(); + + Status = DistributedTaskStatus.Completed; } catch (Exception ex) { LogManager.GetLogger("ASC.Web").Error(ex); Percentage = 0; - Status = ProgressStatus.Failed; + Status = DistributedTaskStatus.Failted; Error = ex.Message; } finally @@ -192,6 +194,23 @@ public void RunJob() } } + public override bool Equals(object obj) + { + if (obj == null) return false; + + if (obj is PdfProgressItem) + { + return ((PdfProgressItem)obj).Id == Id; + } + + return base.Equals(obj); + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } + public object Clone() { return MemberwiseClone(); From 401c8ca2e2996d55da059eaf11d7b7e6c12c91ee Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 28 May 2021 18:18:55 +0300 Subject: [PATCH 53/61] crm: migrate from newtonsoft to system.text.json --- .../Server/Api/ContactInfosController.cs | 34 ++-- .../ASC.CRM/Server/Api/UtilsController.cs | 3 +- .../ApiModels/ResponsesDto/ContactInfoDto.cs | 18 +- products/ASC.CRM/Server/Classes/Global.cs | 24 ++- .../Server/Classes/ImportFromCSVManager.cs | 12 +- .../Server/Classes/InvoiceFormattedData.cs | 122 +++++++------- .../ASC.CRM/Server/Core/Dao/CustomFieldDao.cs | 66 ++++---- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 7 +- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 8 +- .../Server/Core/Dao/RelationshipEventDao.cs | 32 ++-- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 5 +- .../ASC.CRM/Server/Core/Entities/Filter.cs | 158 ++++++++++-------- .../ImportFileHandlerMiddleware.cs | 8 +- .../WebToLeadFromHandlerMiddleware.cs | 21 ++- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 110 ++++++------ .../Utils/Import/CSV/ImportCSVSettings.cs | 66 ++++---- .../Server/Utils/Import/CSV/ImportCases.cs | 5 +- .../Server/Utils/Import/CSV/ImportContacts.cs | 29 ++-- .../Utils/Import/CSV/ImportDataOperation.cs | 12 +- .../Server/Utils/Import/CSV/ImportDeals.cs | 5 +- .../Server/Utils/Import/CSV/ImportFromCSV.cs | 26 +-- products/ASC.CRM/Server/Utils/MailSender.cs | 6 +- products/ASC.CRM/Server/Utils/ReportHelper.cs | 5 +- 23 files changed, 386 insertions(+), 396 deletions(-) diff --git a/products/ASC.CRM/Server/Api/ContactInfosController.cs b/products/ASC.CRM/Server/Api/ContactInfosController.cs index 061adaff4f2..7314d0ab646 100644 --- a/products/ASC.CRM/Server/Api/ContactInfosController.cs +++ b/products/ASC.CRM/Server/Api/ContactInfosController.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using ASC.Api.CRM; using ASC.Common.Web; @@ -43,9 +44,6 @@ using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - namespace ASC.CRM.Api { public class ContactInfosController : BaseApiController @@ -161,10 +159,10 @@ public ContactInfoDto GetContactInfoByID(int contactid, int id) /// [Create(@"contact/{contactid:int}/data")] public ContactInfoDto CreateContactInfo( - [FromRoute] int contactid, - [FromForm] ContactInfoType infoType, - [FromForm] string data, - [FromForm] bool isPrimary, + [FromRoute] int contactid, + [FromForm] ContactInfoType infoType, + [FromForm] string data, + [FromForm] bool isPrimary, [FromForm] string category) { if (string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException(); @@ -241,13 +239,10 @@ public ContactInfoDto CreateContactInfoAddress([FromRoute] int contactid, Addres address.CategoryName = ((AddressCategory)address.Category).ToLocalizedString(); - var settings = new JsonSerializerSettings + var settings = new JsonSerializerOptions { - ContractResolver = new DefaultContractResolver - { - NamingStrategy = new CamelCaseNamingStrategy() - }, - Formatting = Formatting.Indented + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true }; var contactInfo = new ContactInfo @@ -256,7 +251,7 @@ public ContactInfoDto CreateContactInfoAddress([FromRoute] int contactid, Addres ContactID = contactid, IsPrimary = address.IsPrimary, Category = address.Category, - Data = JsonConvert.SerializeObject(address, settings) + Data = JsonSerializer.Serialize(address, settings) }; contactInfo.ID = _daoFactory.GetContactInfoDao().Save(contactInfo); @@ -415,18 +410,15 @@ public ContactInfoDto UpdateContactInfoAddress(int id, int contactid, Address ad address.CategoryName = ((AddressCategory)address.Category).ToLocalizedString(); - var settings = new JsonSerializerSettings + var settings = new JsonSerializerOptions { - ContractResolver = new DefaultContractResolver - { - NamingStrategy = new CamelCaseNamingStrategy() - }, - Formatting = Formatting.Indented + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + WriteIndented = true }; contactInfo.IsPrimary = address.IsPrimary; contactInfo.Category = address.Category; - contactInfo.Data = JsonConvert.SerializeObject(address, settings); + contactInfo.Data = JsonSerializer.Serialize(address, settings); _daoFactory.GetContactInfoDao().Update(contactInfo); diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index 4ae96ab59b6..fa1b9968557 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Linq; using System.Security; +using System.Text.Json; using ASC.Api.CRM; using ASC.Common.Threading.Progress; @@ -297,7 +298,7 @@ public String UpdateOrganisationSettingsCompanyAddress(String street, String cit tenantSettings.InvoiceSetting = _invoiceSetting.DefaultSettings; } - var companyAddress = Newtonsoft.Json.JsonConvert.SerializeObject(new + var companyAddress = JsonSerializer.Serialize(new { type = AddressCategory.Billing.ToString(), street, diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs index 9010605407c..6a2b7abde50 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs @@ -26,17 +26,15 @@ using System; using System.Runtime.Serialization; +using System.Text.Json; using ASC.Common.Mapping; using ASC.CRM.Classes; using ASC.CRM.Core; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; using AutoMapper; -using Newtonsoft.Json.Linq; - namespace ASC.CRM.ApiModels { /// @@ -53,11 +51,13 @@ public Address(ContactInfo contactInfo) { if (contactInfo.InfoType != ContactInfoType.Address) throw new ArgumentException(); - City = JObject.Parse(contactInfo.Data)["city"].Value(); - Country = JObject.Parse(contactInfo.Data)["country"].Value(); - State = JObject.Parse(contactInfo.Data)["state"].Value(); - Street = JObject.Parse(contactInfo.Data)["street"].Value(); - Zip = JObject.Parse(contactInfo.Data)["zip"].Value(); + var jsonElement = JsonDocument.Parse(contactInfo.Data).RootElement; + + City = jsonElement.GetProperty("city").GetString(); + Country = jsonElement.GetProperty("country").GetString(); + State = jsonElement.GetProperty("state").GetString(); + Street = jsonElement.GetProperty("street").GetString(); + Zip = jsonElement.GetProperty("zip").GetString(); Category = contactInfo.Category; CategoryName = contactInfo.CategoryToString(); IsPrimary = contactInfo.IsPrimary; @@ -73,7 +73,7 @@ public static bool TryParse(ContactInfo contactInfo, out Address res) try { - res = Newtonsoft.Json.JsonConvert.DeserializeObject
    (contactInfo.Data); + res = JsonSerializer.Deserialize
    (contactInfo.Data); res.Category = contactInfo.Category; res.CategoryName = contactInfo.CategoryToString(); res.IsPrimary = contactInfo.IsPrimary; diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 81b0828747e..65df85ed9fe 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -29,6 +29,8 @@ using System.Drawing.Imaging; using System.Globalization; using System.IO; +using System.Text; +using System.Text.Json; using ASC.Common; using ASC.Core; @@ -42,9 +44,6 @@ using Microsoft.Extensions.Configuration; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - namespace ASC.Web.CRM.Classes { [Scope] @@ -262,13 +261,20 @@ public static DateTime ApiDateTimeParse(string data) throw new ArgumentException(CRMErrorsResource.DateTimeFormatInvalid); } - public static JObject JObjectParseWithDateAsString(string data) + public static JsonDocument JObjectParseWithDateAsString(string data) { - JsonReader reader = new JsonTextReader( - new StringReader(data) - ); - reader.DateParseHandling = DateParseHandling.None; - return JObject.Load(reader); + var readOnlySpan = new ReadOnlySpan(Encoding.UTF8.GetBytes(data)); + + Utf8JsonReader reader = new Utf8JsonReader(readOnlySpan); + + JsonDocument result; + + if (JsonDocument.TryParseValue(ref reader, out result)) + { + return result; + } + + return null; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs index 41d93cc8893..0714db5e179 100644 --- a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs +++ b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs @@ -27,15 +27,15 @@ #region Import using System; +using System.Collections.Generic; using System.IO; +using System.Text.Json; using ASC.Common; using ASC.CRM.Core.Enums; using ASC.MessagingSystem; using ASC.Web.Core.Utility; -using Newtonsoft.Json.Linq; - #endregion namespace ASC.Web.CRM.Classes @@ -71,7 +71,7 @@ public FileUploadResult ProcessUploadFake(string fileTemp, string importSettings if (!Global.GetStore().IsFile("temp", fileTemp)) return fileUploadResult; - JObject jObject; + JsonDocument jObject; //Read contents using (Stream storeStream = Global.GetStore().GetReadStream("temp", fileTemp)) @@ -91,10 +91,12 @@ public FileUploadResult ProcessUploadFake(string fileTemp, string importSettings } } - jObject.Add("assignedPath", fileTemp); + var jsonDocumentAsDictionary = JsonSerializer.Deserialize>(jObject.ToString()); + + jsonDocumentAsDictionary.Add("assignedPath", fileTemp); fileUploadResult.Success = true; - fileUploadResult.Data = Global.EncodeTo64(jObject.ToString()); + fileUploadResult.Data = Global.EncodeTo64(JsonSerializer.Serialize(jsonDocumentAsDictionary)); return fileUploadResult; } diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 9306996769c..bdc355c9f04 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -27,7 +27,9 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Text; +using System.Text.Json; using ASC.Common; using ASC.CRM.Core.Dao; @@ -35,8 +37,6 @@ using ASC.CRM.Core.Enums; using ASC.CRM.Resources; -using Newtonsoft.Json.Linq; - namespace ASC.Web.CRM.Classes { [Scope] @@ -116,25 +116,25 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i if (!string.IsNullOrEmpty(invoiceSettings.CompanyAddress)) { - var obj = JObject.Parse(invoiceSettings.CompanyAddress); + var obj = JsonDocument.Parse(invoiceSettings.CompanyAddress).RootElement; - var str = obj.Value("street"); + var str = obj.GetProperty("street").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("city"); + str = obj.GetProperty("city").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("state"); + str = obj.GetProperty("state").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("zip"); + str = obj.GetProperty("zip").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("country"); + str = obj.GetProperty("country").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); @@ -206,25 +206,25 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i { list = new List(); - var obj = JObject.Parse(billingAddress.Data); + var obj = JsonDocument.Parse(billingAddress.Data).RootElement; - var str = obj.Value("street"); + var str = obj.GetProperty("street").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("city"); + str = obj.GetProperty("city").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("state"); + str = obj.GetProperty("state").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("zip"); + str = obj.GetProperty("zip").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("country"); + str = obj.GetProperty("country").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); @@ -389,25 +389,25 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i { list = new List(); - var obj = JObject.Parse(deliveryAddress.Data); + var obj = JsonDocument.Parse(deliveryAddress.Data).RootElement; - var str = obj.Value("street"); + var str = obj.GetProperty("street").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("city"); + str = obj.GetProperty("city").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("state"); + str = obj.GetProperty("state").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("zip"); + str = obj.GetProperty("zip").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); - str = obj.Value("country"); + str = obj.GetProperty("country").GetString(); if (!string.IsNullOrEmpty(str)) list.Add(str); @@ -439,27 +439,25 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i private InvoiceFormattedData ReadData(string jsonData) { var data = new InvoiceFormattedData(DaoFactory, OrganisationLogoManager); - - var jsonObj = JObject.Parse(jsonData); - + var jsonObj = JsonDocument.Parse(jsonData).RootElement; #region TemplateType - data.TemplateType = jsonObj.Value("TemplateType"); + data.TemplateType = jsonObj.GetProperty("TemplateType").GetInt32(); #endregion #region Seller, LogoBase64, LogoSrcFormat - var seller = jsonObj.Value("Seller"); - if (seller != null) + JsonElement seller; + if (jsonObj.TryGetProperty("Seller", out seller)) { - data.Seller = seller.ToObject>(); + data.Seller = JsonSerializer.Deserialize>(seller.ToString()); } - data.LogoBase64 = jsonObj.Value("LogoBase64"); - data.LogoBase64Id = !String.IsNullOrEmpty(jsonObj.Value("LogoBase64Id")) ? jsonObj.Value("LogoBase64Id") : 0; + data.LogoBase64 = jsonObj.GetProperty("LogoBase64").GetString(); + data.LogoBase64Id = !String.IsNullOrEmpty(jsonObj.GetProperty("LogoBase64Id").GetString()) ? jsonObj.GetProperty("LogoBase64Id").GetInt32() : 0; if (string.IsNullOrEmpty(data.LogoBase64) && data.LogoBase64Id != 0) { @@ -467,17 +465,17 @@ private InvoiceFormattedData ReadData(string jsonData) } - data.LogoSrcFormat = jsonObj.Value("LogoSrcFormat"); + data.LogoSrcFormat = jsonObj.GetProperty("LogoSrcFormat").GetString(); #endregion #region Number - var number = jsonObj.Value("Number"); - if (number != null) + JsonElement number; + if (jsonObj.TryGetProperty("Number", out number)) { - data.Number = number.ToObject>(); + data.Number = JsonSerializer.Deserialize>(number.ToString()); } #endregion @@ -485,10 +483,10 @@ private InvoiceFormattedData ReadData(string jsonData) #region Invoice - var invoice = jsonObj.Value("Invoice"); - if (invoice != null) + JsonElement invoice; + if (jsonObj.TryGetProperty("Invoice", out invoice)) { - data.Invoice = invoice.ToObject>>(); + data.Invoice = JsonSerializer.Deserialize>>(invoice.ToString()); } #endregion @@ -496,10 +494,10 @@ private InvoiceFormattedData ReadData(string jsonData) #region Customer - var customer = jsonObj.Value("Customer"); - if (customer != null) + JsonElement customer; + if (jsonObj.TryGetProperty("Customer", out customer)) { - data.Customer = customer.ToObject>(); + data.Customer = JsonSerializer.Deserialize>(customer.ToString()); } #endregion @@ -507,28 +505,28 @@ private InvoiceFormattedData ReadData(string jsonData) #region TableHeaderRow, TableBodyRows, TableFooterRows, Total - var tableHeaderRow = jsonObj.Value("TableHeaderRow"); - if (tableHeaderRow != null) + JsonElement tableHeaderRow; + if (jsonObj.TryGetProperty("TableHeaderRow", out tableHeaderRow)) { - data.TableHeaderRow = tableHeaderRow.ToObject>(); + data.TableHeaderRow = tableHeaderRow.EnumerateArray().Select(x => x.GetString()).ToList(); } - var tableBodyRows = jsonObj.Value("TableBodyRows"); - if (tableBodyRows != null) + JsonElement tableBodyRows; + if (jsonObj.TryGetProperty("TableBodyRows", out tableBodyRows)) { - data.TableBodyRows = tableBodyRows.ToObject>>(); + data.TableBodyRows = JsonSerializer.Deserialize>>(tableBodyRows.ToString()); } - var tableFooterRows = jsonObj.Value("TableFooterRows"); - if (tableFooterRows != null) + JsonElement tableFooterRows; + if (jsonObj.TryGetProperty("TableFooterRows", out tableFooterRows)) { - data.TableFooterRows = tableFooterRows.ToObject>>(); + data.TableFooterRows = JsonSerializer.Deserialize>>(tableFooterRows.ToString()); } - var tableTotalRow = jsonObj.Value("TableTotalRow"); - if (tableTotalRow != null) + JsonElement tableTotalRow; + if (jsonObj.TryGetProperty("TableTotalRow", out tableTotalRow)) { - data.TableTotalRow = tableTotalRow.ToObject>(); + data.TableTotalRow = JsonSerializer.Deserialize>(tableTotalRow.ToString()); } #endregion @@ -536,10 +534,10 @@ private InvoiceFormattedData ReadData(string jsonData) #region Terms - var terms = jsonObj.Value("Terms"); - if (terms != null) + JsonElement terms; + if (jsonObj.TryGetProperty("Terms", out terms)) { - data.Terms = terms.ToObject>(); + data.Terms = JsonSerializer.Deserialize>(terms.ToString()); } #endregion @@ -547,10 +545,10 @@ private InvoiceFormattedData ReadData(string jsonData) #region Notes - var notes = jsonObj.Value("Notes"); - if (notes != null) + JsonElement notes; + if (jsonObj.TryGetProperty("Notes", out notes)) { - data.Notes = notes.ToObject>(); + data.Notes = JsonSerializer.Deserialize>(notes.ToString()); } #endregion @@ -558,10 +556,10 @@ private InvoiceFormattedData ReadData(string jsonData) #region Consignee - var consignee = jsonObj.Value("Consignee"); - if (consignee != null) + JsonElement consignee; + if (jsonObj.TryGetProperty("Consignee", out consignee)) { - data.Consignee = consignee.ToObject>(); + data.Consignee = JsonSerializer.Deserialize>(consignee.ToString()); } #endregion @@ -569,8 +567,8 @@ private InvoiceFormattedData ReadData(string jsonData) #region Addresses - data.DeliveryAddressID = !String.IsNullOrEmpty(jsonObj.Value("DeliveryAddressID")) ? jsonObj.Value("DeliveryAddressID") : 0; - data.BillingAddressID = !String.IsNullOrEmpty(jsonObj.Value("BillingAddressID")) ? jsonObj.Value("BillingAddressID") : 0; + data.DeliveryAddressID = !String.IsNullOrEmpty(jsonObj.GetProperty("DeliveryAddressID").GetString()) ? jsonObj.GetProperty("DeliveryAddressID").GetInt32() : 0; + data.BillingAddressID = !String.IsNullOrEmpty(jsonObj.GetProperty("BillingAddressID").GetString()) ? jsonObj.GetProperty("BillingAddressID").GetInt32() : 0; #endregion diff --git a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs index 6d13dab0c1d..cfd0eabed9f 100644 --- a/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CustomFieldDao.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using ASC.Common; using ASC.Common.Caching; @@ -46,9 +47,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - namespace ASC.CRM.Core.Dao { [Scope] @@ -56,7 +54,7 @@ public class CustomFieldDao : AbstractDao { private readonly TenantUtil _tenantUtil; private readonly FactoryIndexerFieldValue _factoryIndexer; - + public CustomFieldDao( DbContextManager dbContextManager, TenantManager tenantManager, @@ -71,7 +69,7 @@ IMapper mapper tenantManager, securityContext, logger, - ascCache, + ascCache, mapper) { _tenantUtil = tenantUtil; @@ -111,8 +109,8 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, fieldValue = fieldValue.Trim(); var dbEntity = Query(CrmDbContext.FieldValue) - .FirstOrDefault(x => x.EntityId == entityID && - x.EntityType == entityType && + .FirstOrDefault(x => x.EntityId == entityID && + x.EntityType == entityType && x.FieldId == fieldID); if (string.IsNullOrEmpty(fieldValue)) @@ -122,7 +120,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, CrmDbContext.Remove(dbEntity); } else - { + { dbEntity.Value = fieldValue; dbEntity.LastModifedOn = _tenantUtil.DateTimeToUtc(_tenantUtil.DateTimeNow()); dbEntity.LastModifedBy = _securityContext.CurrentAccount.ID; @@ -135,7 +133,7 @@ private void SetFieldValueInDb(EntityType entityType, int entityID, int fieldID, private string GetValidMask(CustomFieldType customFieldType, String mask) { - var resultMask = new JObject(); + var resultMask = new Dictionary(); if (customFieldType == CustomFieldType.CheckBox || customFieldType == CustomFieldType.Heading || customFieldType == CustomFieldType.Date) return String.Empty; @@ -145,10 +143,10 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) try { - var maskObj = JToken.Parse(mask); + var maskObj = JsonDocument.Parse(mask).RootElement; if (customFieldType == CustomFieldType.TextField) { - var size = maskObj.Value("size"); + var size = maskObj.GetProperty("size").GetInt32(); if (size == 0) { resultMask.Add("size", 1); @@ -164,8 +162,8 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) } if (customFieldType == CustomFieldType.TextArea) { - var rows = maskObj.Value("rows"); - var cols = maskObj.Value("cols"); + var rows = maskObj.GetProperty("rows").GetInt32(); + var cols = maskObj.GetProperty("cols").GetInt32(); if (rows == 0) { @@ -195,11 +193,14 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) } if (customFieldType == CustomFieldType.SelectBox) { - if (maskObj is JArray) + try { + var arrayLength = maskObj.GetArrayLength(); + return mask; + } - else + catch (Exception ex) { throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); } @@ -223,14 +224,14 @@ private string GetValidMask(CustomFieldType customFieldType, String mask) throw; } } - return JsonConvert.SerializeObject(resultMask); + return JsonSerializer.Serialize(resultMask); } public int CreateField(EntityType entityType, String label, CustomFieldType customFieldType, String mask) { if (!_supportedEntityType.Contains(entityType) || String.IsNullOrEmpty(label)) throw new ArgumentException(); - + var resultMask = GetValidMask(customFieldType, mask); var sortOrder = Query(CrmDbContext.FieldDescription).Select(x => x.SortOrder).Max() + 1; @@ -336,19 +337,20 @@ public void EditItem(CustomField customField) } else { - var maskObjOld = JToken.Parse(oldMask); - var maskObjNew = JToken.Parse(customField.Mask); - - if (!(maskObjOld is JArray && maskObjNew is JArray)) - { - throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); - } - var inm = (((JArray)maskObjNew).ToList()).Intersect(((JArray)maskObjOld).ToList()).ToList(); - if (inm.Count == ((JArray)maskObjOld).ToList().Count) + try { - resultMask = customField.Mask; + + var maskObjOld = JsonSerializer.Deserialize>(oldMask); + var maskObjNew = JsonSerializer.Deserialize>(customField.Mask); + + var inm = maskObjNew.Intersect(maskObjOld).ToList(); + + if (inm.Count == maskObjOld.Count) + { + resultMask = customField.Mask; + } } - else + catch (Exception ex) { throw new ArgumentException(CRMErrorsResource.CustomFieldMaskNotValid); } @@ -431,8 +433,8 @@ public String GetContactLinkCountJSON(EntityType entityType) sqlQuery = sqlQuery.Where(x => x.x.EntityType == entityType); } - return JsonConvert.SerializeObject(sqlQuery.GroupBy(x => x.x.Id) - .Select(x => x.Count()).ToList()); + return JsonSerializer.Serialize(sqlQuery.GroupBy(x => x.x.Id) + .Select(x => x.Count()).ToList()); } public int GetContactLinkCount(EntityType entityType, int entityID) @@ -538,7 +540,7 @@ public List GetFieldsDescription(EntityType entityType) var dbEntities = sqlQuery.ToList(); - return _mapper.Map, List>(dbEntities); + return _mapper.Map, List>(dbEntities); } public void DeleteField(int id) @@ -568,7 +570,7 @@ public CustomField ToCustomField(DbFieldDescription dbFieldDescription, { var customField = _mapper.Map(dbFieldDescription); - if (customField != null && dbFieldValue != null) + if (customField != null && dbFieldValue != null) { customField.Value = dbFieldValue.Value; customField.EntityID = dbFieldValue.EntityId; diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index 9765cca1c8c..e49abe28107 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Text.Json; using System.Text.RegularExpressions; using ASC.Collections; @@ -50,8 +51,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using Newtonsoft.Json; - using SecurityContext = ASC.Core.SecurityContext; namespace ASC.CRM.Core.Dao @@ -638,7 +637,9 @@ public void UpdateInvoiceJsonData(Invoice invoice, int billingAddressID, int del { jsonData.LogoBase64 = null; } - invoice.JsonData = JsonConvert.SerializeObject(jsonData); + + invoice.JsonData = JsonSerializer.Serialize(jsonData); + UpdateInvoiceJsonData(invoice.ID, invoice.JsonData); } diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 273684ed70c..22797531585 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Text.Json; using System.Text.RegularExpressions; using ASC.Collections; @@ -41,12 +42,9 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using Newtonsoft.Json; - namespace ASC.CRM.Core.Dao { [Scope] @@ -73,7 +71,7 @@ public static string GetJson(InvoiceItem invoiceItem) { return invoiceItem == null ? string.Empty : - JsonConvert.SerializeObject(new + JsonSerializer.Serialize(new { id = invoiceItem.ID, title = invoiceItem.Title, @@ -84,7 +82,7 @@ public static string GetJson(InvoiceTax invoiceTax) { return invoiceTax == null ? string.Empty : - JsonConvert.SerializeObject(new + JsonSerializer.Serialize(new { id = invoiceTax.ID, name = invoiceTax.Name, diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 573cb53398a..c7ee86fd0e1 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -30,6 +30,7 @@ using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; +using System.Text.Json; using ASC.Collections; using ASC.Common; @@ -50,12 +51,9 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; -using Newtonsoft.Json.Linq; - using OrderBy = ASC.CRM.Core.Entities.OrderBy; namespace ASC.CRM.Core.Dao @@ -304,8 +302,8 @@ public RelationshipEvent CreateItem(RelationshipEvent item) if (item.CategoryID == (int)HistoryCategorySystem.MailMessage) { - var jsonObj = JObject.Parse(item.Content); - var messageId = jsonObj.Value("message_id"); + var jsonObj = JsonDocument.Parse(item.Content).RootElement; + var messageId = jsonObj.GetProperty("message_id").GetInt32(); //var apiServer = new ApiServer(); //var msg = apiServer.GetApiResponse( @@ -603,21 +601,21 @@ internal class CrmHistoryContent public long message_id; } - private static string GetHistoryContentJson(JObject apiResponse) + private static string GetHistoryContentJson(JsonElement apiResponse) { var content_struct = new CrmHistoryContent { - @from = apiResponse.Value("from"), - to = apiResponse.Value("to"), - cc = apiResponse.Value("cc"), - bcc = apiResponse.Value("bcc"), - subject = apiResponse.Value("subject"), - important = apiResponse.Value("important"), - chain_id = apiResponse.Value("chainId"), - is_sended = apiResponse.Value("folder") == 1, - date_created = apiResponse.Value("date"), - introduction = apiResponse.Value("introduction"), - message_id = apiResponse.Value("id") + @from = apiResponse.GetProperty("from").GetString(), + to = apiResponse.GetProperty("to").GetString(), + cc = apiResponse.GetProperty("cc").GetString(), + bcc = apiResponse.GetProperty("bcc").GetString(), + subject = apiResponse.GetProperty("subject").GetString(), + important = apiResponse.GetProperty("important").GetBoolean(), + chain_id = apiResponse.GetProperty("chainId").GetString(), + is_sended = apiResponse.GetProperty("folder").GetInt32() == 1, + date_created = apiResponse.GetProperty("date").GetString(), + introduction = apiResponse.GetProperty("introduction").GetString(), + message_id = apiResponse.GetProperty("id").GetInt32() }; var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent)); diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index 62ffebe99dc..eb1c70c8c67 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using ASC.Common; using ASC.Common.Caching; @@ -43,8 +44,6 @@ using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Options; -using Newtonsoft.Json; - namespace ASC.CRM.Core.Dao { [Scope] @@ -109,7 +108,7 @@ public String GetTagsLinkCountJSON(EntityType entityType) { int[] tags = GetTagsLinkCount(entityType).ToArray(); - return JsonConvert.SerializeObject(tags); + return JsonSerializer.Serialize(tags); } public IEnumerable GetTagsLinkCount(EntityType entityType) diff --git a/products/ASC.CRM/Server/Core/Entities/Filter.cs b/products/ASC.CRM/Server/Core/Entities/Filter.cs index fa403126fdd..72a73799e26 100644 --- a/products/ASC.CRM/Server/Core/Entities/Filter.cs +++ b/products/ASC.CRM/Server/Core/Entities/Filter.cs @@ -31,14 +31,12 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Enums; using ASC.Web.CRM.Classes; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - using EnumExtension = ASC.CRM.Classes.EnumExtension; #endregion @@ -83,32 +81,32 @@ public CasesFilterObject(string base64String) foreach (var filterItem in jsonArray) { - var filterObj = JObject.Parse(filterItem); + var filterObj = JsonDocument.Parse(filterItem).RootElement; - var paramString = filterObj.Value("params"); + var paramString = filterObj.GetProperty("params").GetString(); if (string.IsNullOrEmpty(paramString)) continue; - var filterParam = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + var filterParam = JsonDocument.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))).RootElement; - switch (filterObj.Value("id")) + switch (filterObj.GetProperty("id").GetString()) { case "sorter": - SortBy = filterParam.Value("id"); - SortOrder = filterParam.Value("sortOrder"); + SortBy = filterParam.GetProperty("id").GetString(); + SortOrder = filterParam.GetProperty("sortOrder").GetString(); break; case "text": - FilterValue = filterParam.Value("value"); + FilterValue = filterParam.GetProperty("value").GetString(); break; case "closed": case "opened": - IsClosed = filterParam.Value("value"); + IsClosed = filterParam.GetProperty("value").GetBoolean(); break; case "tags": - Tags = filterParam.Value("value").ToList().ConvertAll(n => n.ToString()); + Tags = filterParam.GetProperty("value").EnumerateArray().Select(x => x.GetString()).ToList(); break; } } @@ -160,36 +158,42 @@ public TaskFilterObject(string base64String) foreach (var filterItem in jsonArray) { - var filterObj = JObject.Parse(filterItem); + var filterObj = JsonDocument.Parse(filterItem).RootElement; - var paramString = filterObj.Value("params"); + var paramString = filterObj.GetProperty("params").GetString(); if (string.IsNullOrEmpty(paramString)) continue; - var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))).RootElement; - switch (filterObj.Value("id")) + switch (filterObj.GetProperty("id").GetString()) { case "sorter": - SortBy = filterParam.Value("id"); - SortOrder = filterParam.Value("sortOrder"); + SortBy = filterParam.GetProperty("id").GetString(); + SortOrder = filterParam.GetProperty("sortOrder").GetString(); break; case "text": - FilterValue = filterParam.Value("value"); + FilterValue = filterParam.GetProperty("value").GetString(); break; case "my": case "responsibleID": - ResponsibleId = new Guid(filterParam.Value("value")); + ResponsibleId = filterParam.GetProperty("value").GetGuid(); break; case "overdue": case "today": case "theNext": - var valueString = filterParam.Value("value"); - var fromToArray = JsonConvert.DeserializeObject>(valueString); + var valueString = filterParam.GetProperty("value").GetString(); + var fromToArray = JsonDocument.Parse(valueString) + .RootElement + .EnumerateArray() + .Select(x => x.GetString()) + .ToList(); + if (fromToArray.Count != 2) continue; + FromDate = !String.IsNullOrEmpty(fromToArray[0]) ? Global.ApiDateTimeParse(fromToArray[0]) : DateTime.MinValue; ToDate = !String.IsNullOrEmpty(fromToArray[1]) @@ -197,21 +201,21 @@ public TaskFilterObject(string base64String) break; case "fromToDate": - FromDate = filterParam.Value("from"); - ToDate = (filterParam.Value("to")).AddDays(1).AddSeconds(-1); + FromDate = filterParam.GetProperty("from").GetDateTime(); + ToDate = (filterParam.GetProperty("to").GetDateTime()).AddDays(1).AddSeconds(-1); break; case "categoryID": - CategoryId = filterParam.Value("value"); + CategoryId = filterParam.GetProperty("value").GetInt32(); break; case "openTask": case "closedTask": - IsClosed = filterParam.Value("value"); + IsClosed = filterParam.GetProperty("value").GetBoolean(); break; case "contactID": - ContactId = filterParam.Value("id"); + ContactId = filterParam.GetProperty("id").GetInt32(); break; } } @@ -269,68 +273,72 @@ public DealFilterObject(string base64String) foreach (var filterItem in jsonArray) { - var filterObj = JObject.Parse(filterItem); + var filterObj = JsonDocument.Parse(filterItem).RootElement; - var paramString = filterObj.Value("params"); + var paramString = filterObj.GetProperty("params").GetString(); if (string.IsNullOrEmpty(paramString)) continue; - var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))).RootElement; - switch (filterObj.Value("id")) + switch (filterObj.GetProperty("id").GetString()) { case "sorter": - SortBy = filterParam.Value("id"); - SortOrder = filterParam.Value("sortOrder"); + SortBy = filterParam.GetProperty("id").GetString(); + SortOrder = filterParam.GetProperty("sortOrder").GetString(); break; case "text": - FilterValue = filterParam.Value("value"); + FilterValue = filterParam.GetProperty("value").GetString(); break; case "my": case "responsibleID": - ResponsibleId = new Guid(filterParam.Value("value")); + ResponsibleId = filterParam.GetProperty("value").GetGuid(); + break; - case "stageTypeOpen": case "stageTypeClosedAndWon": case "stageTypeClosedAndLost": - StageType = filterParam.Value("value"); + StageType = filterParam.GetProperty("value").GetString(); break; - case "opportunityStagesID": - OpportunityStageId = filterParam.Value("value"); + OpportunityStageId = filterParam.GetProperty("value").GetInt32(); break; - case "lastMonth": case "yesterday": case "today": case "thisMonth": - var valueString = filterParam.Value("value"); - var fromToArray = JsonConvert.DeserializeObject>(valueString); + var valueString = filterParam.GetProperty("value").GetString(); + var fromToArray = JsonDocument.Parse(valueString) + .RootElement + .EnumerateArray() + .Select(x => x.GetString()) + .ToList(); + if (fromToArray.Count != 2) continue; + FromDate = Global.ApiDateTimeParse(fromToArray[0]); ToDate = Global.ApiDateTimeParse(fromToArray[1]); break; case "fromToDate": - FromDate = Global.ApiDateTimeParse(filterParam.Value("from")); - ToDate = Global.ApiDateTimeParse(filterParam.Value("to")); + FromDate = Global.ApiDateTimeParse(filterParam.GetProperty("from").GetString()); + ToDate = Global.ApiDateTimeParse(filterParam.GetProperty("to").GetString()); break; case "participantID": - ContactId = filterParam.Value("id"); + ContactId = filterParam.GetProperty("id").GetInt32(); ContactAlsoIsParticipant = true; break; case "contactID": - ContactId = filterParam.Value("id"); + ContactId = filterParam.GetProperty("id").GetInt32(); ContactAlsoIsParticipant = false; break; case "tags": - Tags = filterParam.Value("value").ToList().ConvertAll(n => n.ToString()); + Tags = filterParam.GetProperty("value").EnumerateArray().Select(x => x.GetString()).ToList(); break; } } @@ -399,68 +407,74 @@ public ContactFilterObject(string base64String) foreach (var filterItem in jsonArray) { - var filterObj = JObject.Parse(filterItem); + var filterObj = JsonDocument.Parse(filterItem).RootElement; - var paramString = filterObj.Value("params"); + var paramString = filterObj.GetProperty("params").GetString(); if (string.IsNullOrEmpty(paramString)) continue; - var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + var filterParam = Global.JObjectParseWithDateAsString(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))).RootElement; - switch (filterObj.Value("id")) + switch (filterObj.GetProperty("id").GetString()) { case "sorter": - SortBy = filterParam.Value("id"); - SortOrder = filterParam.Value("sortOrder"); + SortBy = filterParam.GetProperty("id").GetString(); + SortOrder = filterParam.GetProperty("sortOrder").GetString(); break; case "text": - FilterValue = filterParam.Value("value"); + FilterValue = filterParam.GetProperty("value").GetString(); break; case "my": case "responsibleID": case "noresponsible": - ResponsibleId = new Guid(filterParam.Value("value")); + ResponsibleId = filterParam.GetProperty("value").GetGuid(); break; case "tags": - Tags = filterParam.Value("value").ToList().ConvertAll(n => n.ToString()); + Tags = filterParam.GetProperty("value").EnumerateArray().Select(x => x.GetString()).ToList(); break; case "withopportunity": case "person": case "company": - ContactListView = filterParam.Value("value"); + ContactListView = filterParam.GetProperty("value").GetString(); break; case "contactType": - ContactType = filterParam.Value("value"); + ContactType = filterParam.GetProperty("value").GetInt32(); break; case "contactStage": - ContactStage = filterParam.Value("value"); + ContactStage = filterParam.GetProperty("value").GetInt32(); break; case "lastMonth": case "yesterday": case "today": case "thisMonth": - var valueString = filterParam.Value("value"); - var fromToArray = JsonConvert.DeserializeObject>(valueString); + var valueString = filterParam.GetProperty("value").GetString(); + var fromToArray = JsonDocument.Parse(valueString) + .RootElement + .EnumerateArray() + .Select(x => x.GetString()) + .ToList(); + if (fromToArray.Count != 2) continue; + FromDate = Global.ApiDateTimeParse(fromToArray[0]); ToDate = Global.ApiDateTimeParse(fromToArray[1]); break; case "fromToDate": - FromDate = Global.ApiDateTimeParse(filterParam.Value("from")); - ToDate = Global.ApiDateTimeParse(filterParam.Value("to")); + FromDate = Global.ApiDateTimeParse(filterParam.GetProperty("from").GetString()); + ToDate = Global.ApiDateTimeParse(filterParam.GetProperty("to").GetString()); break; case "restricted": case "shared": - IsShared = filterParam.Value("value"); + IsShared = filterParam.GetProperty("value").GetBoolean(); break; } } @@ -514,28 +528,28 @@ public InvoiceItemFilterObject(string base64String) foreach (var filterItem in jsonArray) { - var filterObj = JObject.Parse(filterItem); + var filterObj = JsonDocument.Parse(filterItem).RootElement; - var paramString = filterObj.Value("params"); + var paramString = filterObj.GetProperty("params").GetString(); if (string.IsNullOrEmpty(paramString)) continue; - var filterParam = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))); + var filterParam = JsonDocument.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(paramString))).RootElement; - switch (filterObj.Value("id")) + switch (filterObj.GetProperty("id").GetString()) { case "sorter": - SortBy = filterParam.Value("id"); - SortOrder = filterParam.Value("sortOrder"); + SortBy = filterParam.GetProperty("id").GetString(); + SortOrder = filterParam.GetProperty("sortOrder").GetString(); break; case "text": - FilterValue = filterParam.Value("value"); + FilterValue = filterParam.GetProperty("value").GetString(); break; case "withInventoryStock": case "withoutInventoryStock": - InventoryStock = filterParam.Value("value"); + InventoryStock = filterParam.GetProperty("value").GetBoolean(); break; } } diff --git a/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs b/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs index 1fda895e8d4..5712a06a68a 100644 --- a/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs +++ b/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs @@ -25,6 +25,8 @@ using System; +using System.Collections.Generic; +using System.Runtime.InteropServices.ComTypes; using System.Text.Json; using System.Threading.Tasks; @@ -74,10 +76,12 @@ public async Task Invoke(HttpContext context, var jObject = importFromCSV.GetInfo(context.Request.Form.Files[0].OpenReadStream(), context.Request.Form["importSettings"]); - jObject.Add("assignedPath", assignedPath); + var jsonDocumentAsDictionary = JsonSerializer.Deserialize>(jObject.ToString()); + + jsonDocumentAsDictionary.Add("assignedPath", assignedPath); fileUploadResult.Success = true; - fileUploadResult.Data = Global.EncodeTo64(jObject.ToString()); + fileUploadResult.Data = Global.EncodeTo64(JsonSerializer.Serialize(jsonDocumentAsDictionary)); await context.Response.WriteAsync(JsonSerializer.Serialize(fileUploadResult)); } diff --git a/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs index fce961a6b58..4a1e9d30213 100644 --- a/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs +++ b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs @@ -30,6 +30,7 @@ using System.Linq; using System.Net; using System.Text; +using System.Text.Json; using System.Web; using ASC.Common.Logging; @@ -51,7 +52,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; -using Newtonsoft.Json.Linq; +using SimpleJson; namespace ASC.Web.CRM.HttpHandlers { @@ -146,10 +147,12 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, var fieldCollector = new NameValueCollection(); - var addressTemplate = new JObject(); + var addressTemplate = new Dictionary(); + foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) addressTemplate.Add(addressPartName.ToLower(), ""); - var addressTemplateStr = addressTemplate.ToString(); + + var addressTemplateStr = JsonSerializer.Serialize(addressTemplate); var isCompany = false; @@ -290,11 +293,11 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, contactInfos.Add(findedAddress); } - var addressParts = JObject.Parse(findedAddress.Data); - + Dictionary addressParts = JsonSerializer.Deserialize>(findedAddress.Data); addressParts[addressPart.ToString().ToLower()] = GetValue(key); - - findedAddress.Data = addressParts.ToString(); + string newJson = JsonSerializer.Serialize(addressParts); + + findedAddress.Data = JsonSerializer.Serialize(addressParts); continue; } @@ -372,12 +375,12 @@ private String PrepareteDataToView(ContactInfoType contactInfoType, String data) { if (contactInfoType != ContactInfoType.Address) return data; - var addressParts = JObject.Parse(data); + var addressParts = JsonDocument.Parse(data).RootElement; var address = new StringBuilder(); foreach (AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart))) - address.Append(addressParts[addressPartEnum.ToString().ToLower()] + " "); + address.Append(addressParts.GetProperty(addressPartEnum.ToString().ToLower()).GetString() + " "); return address.ToString(); } diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 9377e05f2f8..6ee1ab74f92 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -32,6 +32,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Text.Json; using ASC.Common; using ASC.Common.Caching; @@ -60,13 +61,32 @@ using Microsoft.Extensions.Options; -using Newtonsoft.Json.Linq; - namespace ASC.Web.CRM.Classes { [Transient] public class ExportDataOperation : DistributedTaskProgress, IProgressItem { + + private readonly DisplayUserSettingsHelper _displayUserSettingsHelper; + private readonly FilesLinkUtility _filesLinkUtility; + private readonly FileMarker _fileMarker; + private readonly IDaoFactory _fileDaoFactory; + private readonly GlobalFolder _globalFolder; + private readonly FileUploader _fileUploader; + private readonly TenantManager _tenantManager; + private readonly CommonLinkUtility _commonLinkUtility; + private readonly SecurityContext _securityContext; + private readonly DaoFactory _daoFactory; + private readonly UserManager _userManager; + private readonly FileUtility _fileUtility; + private readonly int _tenantId; + private readonly IAccount _author; + private readonly IDataStore _dataStore; + private readonly NotifyClient _notifyClient; + private FilterObject _filterObject; + private readonly ILog _log; + private int _totalCount; + public ExportDataOperation(UserManager userManager, FileUtility fileUtility, SecurityContext securityContext, @@ -83,10 +103,10 @@ public ExportDataOperation(UserManager userManager, FilesLinkUtility filesLinkUtility, DisplayUserSettingsHelper displayUserSettingsHelper) { - DaoFactory = daoFactory; - UserManager = userManager; - FileUtility = fileUtility; - FileUploader = fileUploader; + _daoFactory = daoFactory; + _userManager = userManager; + _fileUtility = fileUtility; + _fileUploader = fileUploader; _tenantId = tenantManager.GetCurrentTenant().TenantId; @@ -101,14 +121,14 @@ public ExportDataOperation(UserManager userManager, IsCompleted = false; FileUrl = null; - SecurityContext = securityContext; + _securityContext = securityContext; - CommonLinkUtility = commonLinkUtility; - GlobalFolder = globalFolder; - FileMarker = fileMarker; - FileDaoFactory = fileDaoFactory; - FilesLinkUtility = filesLinkUtility; - DisplayUserSettingsHelper = displayUserSettingsHelper; + _commonLinkUtility = commonLinkUtility; + _globalFolder = globalFolder; + _fileMarker = fileMarker; + _fileDaoFactory = fileDaoFactory; + _filesLinkUtility = filesLinkUtility; + _displayUserSettingsHelper = displayUserSettingsHelper; } public void Configure(object id, FilterObject filterObject, string fileName) @@ -118,34 +138,6 @@ public void Configure(object id, FilterObject filterObject, string fileName) Id = id.ToString(); } - - public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } - public FilesLinkUtility FilesLinkUtility { get; } - public FileMarker FileMarker { get; } - public IDaoFactory FileDaoFactory { get; } - public GlobalFolder GlobalFolder { get; } - public FileUploader FileUploader { get; } - public TenantManager TenantManager { get; } - public CommonLinkUtility CommonLinkUtility { get; } - public SecurityContext SecurityContext { get; } - public DaoFactory DaoFactory { get; } - public UserManager UserManager { get; } - public FileUtility FileUtility { get; } - - private readonly int _tenantId; - - private readonly IAccount _author; - - private readonly IDataStore _dataStore; - - private readonly NotifyClient _notifyClient; - - private FilterObject _filterObject; - - private readonly ILog _log; - - private int _totalCount; - public override bool Equals(object obj) { if (obj == null) return false; @@ -168,9 +160,7 @@ public object Clone() } public object Error { get; set; } - public string FileName { get; set; } - public string FileUrl { get; set; } private String WrapDoubleQuote(String value) @@ -216,10 +206,10 @@ protected override void DoJob() { try { - TenantManager.SetCurrentTenant(_tenantId); - SecurityContext.AuthenticateMe(_author); + _tenantManager.SetCurrentTenant(_tenantId); + _securityContext.AuthenticateMe(_author); - var userCulture = UserManager.GetUsers(SecurityContext.CurrentAccount.ID).GetCulture(); + var userCulture = _userManager.GetUsers(_securityContext.CurrentAccount.ID).GetCulture(); System.Threading.Thread.CurrentThread.CurrentCulture = userCulture; System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; @@ -227,9 +217,9 @@ protected override void DoJob() _log.Debug("Start Export Data"); if (_filterObject == null) - ExportAllData(DaoFactory); + ExportAllData(_daoFactory); else - ExportPartData(DaoFactory); + ExportPartData(_daoFactory); Complete(100, DistributedTaskStatus.Completed, null); @@ -255,7 +245,6 @@ private void Complete(double percentage, DistributedTaskStatus status, object er Percentage = percentage; Status = status; Error = error; - } private void ExportAllData(DaoFactory daoFactory) @@ -321,7 +310,6 @@ private void ExportAllData(DaoFactory daoFactory) zipEntryData.CopyTo(zipStream); } - zipStream.PutNextEntry(new ZipEntry(CRMCommonResource.TaskModuleName + ".csv")); var taskData = taskDao.GetAllTasks(); @@ -355,7 +343,7 @@ private void ExportAllData(DaoFactory daoFactory) stream.Position = 0; } - FileUrl = CommonLinkUtility.GetFullAbsolutePath(_dataStore.SavePrivate(String.Empty, FileName, stream, DateTime.Now.AddDays(1))); + FileUrl = _commonLinkUtility.GetFullAbsolutePath(_dataStore.SavePrivate(String.Empty, FileName, stream, DateTime.Now.AddDays(1))); _notifyClient.SendAboutExportCompleted(_author.ID, FileName, FileUrl); } @@ -632,10 +620,10 @@ private String ExportContactsToCsv(IReadOnlyCollection contacts, String { if (!String.IsNullOrEmpty(columnValue)) { - var addresses = JArray.Parse(String.Concat("[", columnValue, "]")); + var addresses = JsonSerializer.Deserialize>>(String.Concat("[", columnValue, "]")); - dataRowItems.AddRange((from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) - select String.Join(",", addresses.Select(item => (String)item.SelectToken(addressPartEnum.ToString().ToLower())).ToArray())).ToArray()); + dataRowItems.AddRange(from AddressPart addressPartEnum in Enum.GetValues(typeof(AddressPart)) + select String.Join(",", addresses.Select(x => x[addressPartEnum.ToString().ToLower()]).ToArray())); } else { @@ -817,7 +805,7 @@ private String ExportDealsToCsv(IEnumerable deals, DaoFactory daoFactory) deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(), //deal.ExpectedCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern), //deal.ActualCloseDate.Date == DateTime.MinValue.Date ? "" : deal.ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern), - UserManager.GetUsers(deal.ResponsibleID).DisplayUserName(DisplayUserSettingsHelper), + _userManager.GetUsers(deal.ResponsibleID).DisplayUserName(_displayUserSettingsHelper), currentDealMilestone.Title, currentDealMilestoneStatus, deal.DealMilestoneProbability.ToString(CultureInfo.InvariantCulture), @@ -997,7 +985,7 @@ private String ExportHistoryToCsv(IEnumerable events, DaoFact categoryTitle, contactTitle, entityTitle, - UserManager.GetUsers(item.CreateBy).DisplayUserName(DisplayUserSettingsHelper), + _userManager.GetUsers(item.CreateBy).DisplayUserName(_displayUserSettingsHelper), // item.CreateOn.ToShortString() item.CreateOn }); @@ -1107,7 +1095,7 @@ private String ExportTasksToCsv(IEnumerable tasks, DaoFactory daoFactory) ? "" // : item.DeadLine.ToShortString(), : item.DeadLine.ToString(), - UserManager.GetUsers(item.ResponsibleID).DisplayUserName(DisplayUserSettingsHelper), + _userManager.GetUsers(item.ResponsibleID).DisplayUserName(_displayUserSettingsHelper), contactTitle, item.IsClosed ? CRMTaskResource.TaskStatus_Closed @@ -1222,18 +1210,18 @@ private String SaveCsvFileInMyDocument(String title, String data) using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(data))) { - var file = FileUploader.Exec(GlobalFolder.GetFolderMy(FileMarker, FileDaoFactory).ToString(), title, memStream.Length, memStream, true); + var file = _fileUploader.Exec(_globalFolder.GetFolderMy(_fileMarker, _fileDaoFactory).ToString(), title, memStream.Length, memStream, true); - if (FileUtility.CanWebView(title) || FileUtility.CanWebEdit(title)) + if (_fileUtility.CanWebView(title) || _fileUtility.CanWebEdit(title)) { - fileUrl = FilesLinkUtility.GetFileWebEditorUrl(file.ID); + fileUrl = _filesLinkUtility.GetFileWebEditorUrl(file.ID); fileUrl += string.Format("&options={{\"delimiter\":{0},\"codePage\":{1}}}", (int)FileUtility.CsvDelimiter.Comma, Encoding.UTF8.CodePage); } else { - fileUrl = FilesLinkUtility.GetFileDownloadUrl(file.ID); + fileUrl = _filesLinkUtility.GetFileDownloadUrl(file.ID); } } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs index c70f5061ebd..5db3ee3c196 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs @@ -28,76 +28,66 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json; using ASC.CRM.Core.Enums; -using Newtonsoft.Json.Linq; - namespace ASC.Web.CRM.Classes { public class ImportCSVSettings { public ImportCSVSettings(String jsonStr) { - var json = JObject.Parse(jsonStr); - - if (json == null) return; + var jsonDocument = JsonDocument.Parse(jsonStr); - HasHeader = json["has_header"].Value(); - DelimiterCharacter = Convert.ToChar(json["delimiter_character"].Value()); - Encoding = Encoding.GetEncoding(json["encoding"].Value()); - QuoteType = Convert.ToChar(json["quote_character"].Value()); + if (jsonDocument == null) return; - JToken columnMappingToken; + var jsonElement = jsonDocument.RootElement; - if (json.TryGetValue("column_mapping", out columnMappingToken)) - ColumnMapping = (JObject)columnMappingToken; + HasHeader = jsonElement.GetProperty("has_header").GetBoolean(); + DelimiterCharacter = Convert.ToChar(jsonElement.GetProperty("delimiter_character").GetInt32()); + Encoding = Encoding.GetEncoding(jsonElement.GetProperty("encoding").GetInt32()); + QuoteType = Convert.ToChar(jsonElement.GetProperty("quote_character").GetInt32()); - JToken duplicateRecordRuleToken; + JsonElement columnMappingToken; + if (jsonElement.TryGetProperty("column_mapping", out columnMappingToken)) + ColumnMapping = columnMappingToken; - if (json.TryGetValue("removing_duplicates_behavior", out duplicateRecordRuleToken)) - DuplicateRecordRule = duplicateRecordRuleToken.Value(); - - JToken isPrivateToken; - if (json.TryGetValue("is_private", out isPrivateToken)) + JsonElement duplicateRecordRuleToken; + if (jsonElement.TryGetProperty("removing_duplicates_behavior", out duplicateRecordRuleToken)) + DuplicateRecordRule = duplicateRecordRuleToken.GetInt32(); + + JsonElement isPrivateToken; + if (jsonElement.TryGetProperty("is_private", out isPrivateToken)) { - IsPrivate = isPrivateToken.Value(); - AccessList = json["access_list"].Values().Select(item => new Guid(item)).ToList(); + IsPrivate = isPrivateToken.GetBoolean(); + AccessList = jsonElement.GetProperty("access_list").EnumerateArray().Select(x => x.GetGuid()).ToList(); } - - JToken shareTypeToken; - if (json.TryGetValue("share_type", out shareTypeToken)) + + JsonElement shareTypeToken; + if (jsonElement.TryGetProperty("share_type", out shareTypeToken)) { - ShareType = (ShareType)(shareTypeToken.Value()); - ContactManagers = json["contact_managers"].Values().Select(item => new Guid(item)).ToList(); + ShareType = (ShareType)(shareTypeToken.GetInt32()); + ContactManagers = jsonElement.GetProperty("contact_managers").EnumerateArray().Select(x => x.GetGuid()).ToList(); } - if (json["tags"] != null) + JsonElement tagsToken; + if (jsonElement.TryGetProperty("tags", out tagsToken)) { - Tags = json["tags"].Values().ToList(); + Tags = tagsToken.EnumerateArray().Select(x => x.GetString()).ToList(); } } public bool IsPrivate { get; set; } - public ShareType ShareType { get; set; } - public int DuplicateRecordRule { get; set; } - public bool HasHeader { get; set; } - public char DelimiterCharacter { get; set; } - public char QuoteType { get; set; } - public Encoding Encoding { get; set; } - public List AccessList { get; set; } - public List ContactManagers { get; set; } - - public JObject ColumnMapping { get; set; } - + public JsonElement ColumnMapping { get; set; } public List Tags { get; set; } } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index e88a30dfddd..b801fbbf7b4 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using ASC.CRM.Core; using ASC.CRM.Core.Dao; @@ -37,8 +38,6 @@ using LumenWorks.Framework.IO.Csv; -using Newtonsoft.Json.Linq; - #endregion namespace ASC.Web.CRM.Classes @@ -73,7 +72,7 @@ private void ImportCaseData(DaoFactory _daoFactory) if (String.IsNullOrEmpty(objCases.Title)) continue; - foreach (JProperty jToken in _importSettings.ColumnMapping.Children()) + foreach (JsonProperty jToken in _importSettings.ColumnMapping.EnumerateObject()) { var propertyValue = GetPropertyValue(jToken.Name); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index 1e9e28c0951..58bacf5216f 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using ASC.CRM.Core; using ASC.CRM.Core.Dao; @@ -37,8 +38,6 @@ using LumenWorks.Framework.IO.Csv; -using Newtonsoft.Json.Linq; - #endregion namespace ASC.Web.CRM.Classes @@ -47,9 +46,6 @@ public partial class ImportDataOperation { private readonly Int32 DaoIterationStep = 200; - - - private void ImportContactsData(DaoFactory _daoFactory) { var index = 0; @@ -97,24 +93,25 @@ private void ImportContactsData(DaoFactory _daoFactory) var primaryFields = new List(); - foreach (JProperty jToken in _importSettings.ColumnMapping.Children()) + foreach (JsonProperty jProperty in _importSettings.ColumnMapping.EnumerateObject()) { - var propertyValue = GetPropertyValue(jToken.Name); + var propertyValue = GetPropertyValue(jProperty.Name); if (String.IsNullOrEmpty(propertyValue)) continue; - if (jToken.Name.StartsWith("customField_")) + if (jProperty.Name.StartsWith("customField_")) { - _ReadCustomField(jToken, propertyValue, contact, ref findedCustomField, customFieldDao); + _ReadCustomField(jProperty, propertyValue, contact, ref findedCustomField, customFieldDao); } - else if (jToken.Name.StartsWith("contactInfo_")) + else if (jProperty.Name.StartsWith("contactInfo_")) { - var addressTemplate = new JObject(); + var addressTemplate = new Dictionary(); + foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) addressTemplate.Add(addressPartName.ToLower(), ""); var addressTemplateStr = addressTemplate.ToString(); - _ReadContactInfo(jToken, propertyValue, contact, ref findedContactInfos, ref primaryFields, addressTemplateStr); + _ReadContactInfo(jProperty, propertyValue, contact, ref findedContactInfos, ref primaryFields, addressTemplateStr); } } #endregion @@ -449,7 +446,7 @@ private void _ReadTags(ref Dictionary> findedTags, Contact con } } - private void _ReadCustomField(JProperty jToken, String propertyValue, Contact contact, ref List findedCustomField, CustomFieldDao customFieldDao) + private void _ReadCustomField(JsonProperty jToken, String propertyValue, Contact contact, ref List findedCustomField, CustomFieldDao customFieldDao) { var fieldID = Convert.ToInt32(jToken.Name.Split(new[] { '_' })[1]); var field = customFieldDao.GetFieldDescription(fieldID); @@ -466,7 +463,7 @@ private void _ReadCustomField(JProperty jToken, String propertyValue, Contact co } } - private void _ReadContactInfo(JProperty jToken, String propertyValue, Contact contact, ref List findedContactInfos, ref List primaryFields, String addressTemplateStr) + private void _ReadContactInfo(JsonProperty jToken, String propertyValue, Contact contact, ref List findedContactInfos, ref List primaryFields, String addressTemplateStr) { var nameParts = jToken.Name.Split(new[] { '_' }).Skip(1).ToList(); var contactInfoType = @@ -522,11 +519,11 @@ private void _ReadContactInfo(JProperty jToken, String propertyValue, Contact co findedContactInfos.Add(findedAddress); } - var addressParts = JObject.Parse(findedAddress.Data); + var addressParts = JsonSerializer.Deserialize>(findedAddress.Data); addressParts[addressPart.ToString().ToLower()] = propertyValue; - findedAddress.Data = addressParts.ToString(); + findedAddress.Data = JsonSerializer.Serialize(addressParts); return; } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 6055fb1d9c8..18810905f3c 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -27,6 +27,7 @@ using System; using System.Globalization; using System.Linq; +using System.Text.Json; using ASC.Common; using ASC.Common.Caching; @@ -114,9 +115,7 @@ public void Configure(EntityType entityType, _importSettings = new ImportCSVSettings(importSettingsJSON); _IsConfigure = true; - } - - + } public override bool Equals(object obj) { @@ -145,10 +144,11 @@ public object Clone() private String GetPropertyValue(String propertyName) { - if (_importSettings.ColumnMapping[propertyName] == null) return String.Empty; + JsonElement jsonElement; + + if (!_importSettings.ColumnMapping.TryGetProperty(propertyName, out jsonElement)) return String.Empty; - var values = - _importSettings.ColumnMapping[propertyName].Values().ToList().ConvertAll(columnIndex => _columns[columnIndex]); + var values = jsonElement.EnumerateArray().Select(x => x.GetInt32()).ToList().ConvertAll(columnIndex => _columns[columnIndex]); values.RemoveAll(item => item == String.Empty); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index f58552274c6..b56763cfe73 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; using ASC.Core.Users; using ASC.CRM.Core; @@ -39,8 +40,6 @@ using LumenWorks.Framework.IO.Csv; -using Newtonsoft.Json.Linq; - #endregion namespace ASC.Web.CRM.Classes @@ -239,7 +238,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) findedDealMembers.Add(obj.ID, localMembersDeal); - foreach (JProperty jToken in _importSettings.ColumnMapping.Children()) + foreach (JsonProperty jToken in _importSettings.ColumnMapping.EnumerateObject()) { var propertyValue = GetPropertyValue(jToken.Name); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index 8993aa3c6b9..033a1b9e8d5 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -27,6 +27,7 @@ using System; using System.IO; using System.Linq; +using System.Text.Json; using ASC.Common; using ASC.Common.Threading; @@ -36,7 +37,7 @@ using LumenWorks.Framework.IO.Csv; -using Newtonsoft.Json.Linq; +using Microsoft.EntityFrameworkCore.Storage; namespace ASC.Web.CRM.Classes { @@ -85,12 +86,13 @@ public String GetRow(Stream CSVFileStream, int index, String jsonSettings) while (countRows++ != index && csv.ReadNextRecord()) ; - return new JObject(new JProperty("data", new JArray(csv.GetCurrentRowFields(false).ToArray())), - new JProperty("isMaxIndex", csv.EndOfStream)).ToString(); - + return JsonSerializer.Serialize(new { + data = csv.GetCurrentRowFields(false).ToArray(), + isMaxIndex = csv.EndOfStream + }); } - public JObject GetInfo(Stream CSVFileStream, String jsonSettings) + public JsonDocument GetInfo(Stream CSVFileStream, String jsonSettings) { var importCSVSettings = new ImportCSVSettings(jsonSettings); @@ -105,12 +107,12 @@ public JObject GetInfo(Stream CSVFileStream, String jsonSettings) if (!importCSVSettings.HasHeader) headerRowFields = firstRowFields; - return new JObject( - new JProperty("headerColumns", new JArray(headerRowFields)), - new JProperty("firstContactFields", new JArray(firstRowFields)), - new JProperty("isMaxIndex", csv.EndOfStream) - ); - + return JsonDocument.Parse(JsonSerializer.Serialize(new + { + headerColumns = headerRowFields, + firstContactFields = firstRowFields, + isMaxIndex = csv.EndOfStream + })); } protected String GetKey(EntityType entityType) @@ -134,7 +136,7 @@ public IProgressItem Start(EntityType entityType, String CSVFileURI, String impo if (operation != null && operation.IsCompleted) { _importQueue.RemoveTask(operation.Id); - + operation = null; } diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index 4d983160797..de63cc3c7c1 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -33,6 +33,7 @@ using System.Net.Sockets; using System.Runtime.Serialization; using System.Text; +using System.Text.Json; using System.Text.RegularExpressions; using System.Threading; @@ -63,8 +64,6 @@ using MimeKit; -using Newtonsoft.Json.Linq; - using File = System.IO.File; using SmtpClient = MailKit.Net.Smtp.SmtpClient; @@ -810,8 +809,7 @@ private String Apply(String template, IEnumerable templateTags, { var addressPart = (AddressPart)Enum.Parse(typeof(AddressPart), tagParts[3]); - tagValue = JObject.Parse(contactInfo.Data)[addressPart.ToString().ToLower()].Value(); - + tagValue = JsonDocument.Parse(contactInfo.Data).RootElement.GetProperty(addressPart.ToString().ToLower()).GetString(); } else tagValue = contactInfo.Data; diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index 6b389a6486d..34925c852c4 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Text.Json; using ASC.Common; using ASC.Core; @@ -41,8 +42,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json; - namespace ASC.Web.CRM.Classes { [Scope] @@ -219,7 +218,7 @@ private string GetReportScript(object data, ReportType type, string fileName) throw new Exception(CRMReportResource.BuildErrorEmptyDocbuilderTemplate); return script.Replace("${outputFilePath}", fileName) - .Replace("${reportData}", JsonConvert.SerializeObject(data)); + .Replace("${reportData}", JsonSerializer.Serialize(data)); } private void SaveReportFile(ReportState state, string url) From a9a7c0a4b7ea084377dca537d52f4d01a6665380 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 28 May 2021 20:20:12 +0300 Subject: [PATCH 54/61] crm: refactoring --- .../ASC.CRM/Server/Classes/CRMCalendar.cs | 24 ++--- products/ASC.CRM/Server/Classes/Global.cs | 53 +++++------ .../Server/Classes/ImportFromCSVManager.cs | 24 ++--- .../Server/Classes/InvoiceFormattedData.cs | 48 +++++----- .../Server/Classes/OrganisationLogoManager.cs | 33 ++++--- .../ASC.CRM/Server/Classes/PathProvider.cs | 14 +-- .../ASC.CRM/Server/Classes/SignalRHelper.cs | 14 +-- .../Server/Classes/SubscriptionManager.cs | 9 +- .../CRMsSpaceUsageStatManager.cs | 21 +++-- .../Server/Configuration/ProductEntryPoint.cs | 27 +++--- .../Server/Configuration/VoipModule.cs | 13 +-- .../Services/NotifyService/NotifyClient.cs | 26 +++--- .../Server/Utils/Import/CSV/ImportCases.cs | 4 +- .../Server/Utils/Import/CSV/ImportContacts.cs | 6 +- .../Utils/Import/CSV/ImportDataOperation.cs | 18 ++-- .../Server/Utils/Import/CSV/ImportDeals.cs | 8 +- .../Server/Utils/Import/CSV/ImportFromCSV.cs | 11 ++- .../Server/Utils/Import/CSV/ImportTasks.cs | 24 ++--- products/ASC.CRM/Server/Utils/MailSender.cs | 1 - products/ASC.CRM/Server/Utils/PdfCreator.cs | 92 +++++++++---------- .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 30 +++--- products/ASC.CRM/Server/Utils/ReportHelper.cs | 76 +++++++-------- 22 files changed, 288 insertions(+), 288 deletions(-) diff --git a/products/ASC.CRM/Server/Classes/CRMCalendar.cs b/products/ASC.CRM/Server/Classes/CRMCalendar.cs index 2ee8bc11893..cf1616bc293 100644 --- a/products/ASC.CRM/Server/Classes/CRMCalendar.cs +++ b/products/ASC.CRM/Server/Classes/CRMCalendar.cs @@ -48,10 +48,10 @@ private class Event : BaseEvent { } - public WebItemSecurity WebItemSecurity { get; } - public DaoFactory DaoFactory { get; } - public TenantManager TenantManager { get; } - public TenantUtil TenantUtil { get; } + private WebItemSecurity _webItemSecurity; + private DaoFactory _daoFactory; + private TenantManager _tenantManager; + private TenantUtil _tenantUtil; public CrmCalendar(WebItemSecurity webItemSecurity, DaoFactory daoFactory, @@ -61,10 +61,10 @@ public CrmCalendar(WebItemSecurity webItemSecurity, TenantUtil tenantUtil ) : base(authContext, timeZoneConverter) { - TenantUtil = tenantUtil; - TenantManager = tenantManager; - WebItemSecurity = webItemSecurity; - DaoFactory = daoFactory; + _tenantUtil = tenantUtil; + _tenantManager = tenantManager; + _webItemSecurity = webItemSecurity; + _daoFactory = daoFactory; Context.HtmlBackgroundColor = ""; Context.HtmlTextColor = ""; @@ -84,12 +84,12 @@ public override List LoadEvents(Guid userId, DateTime startDate, DateTim var events = new List(); if ( - !WebItemSecurity.IsAvailableForMe(WebItemManager.CRMProductID)) + !_webItemSecurity.IsAvailableForMe(WebItemManager.CRMProductID)) { return events; } - var tasks = DaoFactory.GetTaskDao().GetTasks(String.Empty, userId, 0, false, DateTime.MinValue, + var tasks = _daoFactory.GetTaskDao().GetTasks(String.Empty, userId, 0, false, DateTime.MinValue, DateTime.MinValue, EntityType.Any, 0, 0, 0, null); foreach (var t in tasks) @@ -97,7 +97,7 @@ public override List LoadEvents(Guid userId, DateTime startDate, DateTim if (t.DeadLine == DateTime.MinValue) continue; var allDayEvent = t.DeadLine.Hour == 0 && t.DeadLine.Minute == 0; - var utcDate = allDayEvent ? t.DeadLine.Date : TenantUtil.DateTimeToUtc(t.DeadLine); + var utcDate = allDayEvent ? t.DeadLine.Date : _tenantUtil.DateTimeToUtc(t.DeadLine); var e = new Event { @@ -121,7 +121,7 @@ public override List LoadEvents(Guid userId, DateTime startDate, DateTim public override TimeZoneInfo TimeZone { - get { return TimeZoneInfo.FindSystemTimeZoneById(TenantManager.GetCurrentTenant().TimeZone); } + get { return TimeZoneInfo.FindSystemTimeZoneById(_tenantManager.GetCurrentTenant().TimeZone); } } private bool IsVisibleEvent(DateTime startDate, DateTime endDate, DateTime eventStartDate, DateTime eventEndDate) diff --git a/products/ASC.CRM/Server/Classes/Global.cs b/products/ASC.CRM/Server/Classes/Global.cs index 65df85ed9fe..498feadc422 100644 --- a/products/ASC.CRM/Server/Classes/Global.cs +++ b/products/ASC.CRM/Server/Classes/Global.cs @@ -49,6 +49,16 @@ namespace ASC.Web.CRM.Classes [Scope] public class Global { + + private IConfiguration _configuration; + private SettingsManager _settingsManager; + protected int _tenantID; + private FilesLinkUtility _filesLinkUtility; + private SetupInfo _setupInfo; + private SecurityContext _securityContext; + private StorageFactory _storageFactory; + private CrmSecurity _crmSecurity; + public Global(StorageFactory storageFactory, SecurityContext securityContext, SetupInfo setupInfo, @@ -59,19 +69,16 @@ public Global(StorageFactory storageFactory, IConfiguration configuration ) { - StorageFactory = storageFactory; - FilesLinkUtility = filesLinkUtility; - SetupInfo = setupInfo; - SecurityContext = securityContext; - CRMSecurity = crmSecurity; - TenantID = tenantManager.GetCurrentTenant().TenantId; - SettingsManager = settingsManager; - Configuration = configuration; + _storageFactory = storageFactory; + _filesLinkUtility = filesLinkUtility; + _setupInfo = setupInfo; + _securityContext = securityContext; + _crmSecurity = crmSecurity; + _tenantID = tenantManager.GetCurrentTenant().TenantId; + _settingsManager = settingsManager; + _configuration = configuration; } - public IConfiguration Configuration { get; } - - public SettingsManager SettingsManager { get; } public static readonly int EntryCountOnPage = 25; public static readonly int VisiblePageCount = 10; @@ -87,25 +94,15 @@ IConfiguration configuration public static readonly int MaxHistoryEventCharacters = 65000; public static readonly decimal MaxInvoiceItemPrice = (decimal)99999999.99; - protected int TenantID { get; private set; } - - public FilesLinkUtility FilesLinkUtility { get; } - - public SetupInfo SetupInfo { get; } - public SecurityContext SecurityContext { get; } - - public StorageFactory StorageFactory { get; } - - public CrmSecurity CRMSecurity { get; } public IDataStore GetStore() { - return StorageFactory.GetStorage(TenantID.ToString(), "crm"); + return _storageFactory.GetStorage(_tenantID.ToString(), "crm"); } public IDataStore GetStoreTemplate() { - return StorageFactory.GetStorage(String.Empty, "crm_template"); + return _storageFactory.GetStorage(String.Empty, "crm_template"); } public bool CanCreateProjects() @@ -150,12 +147,12 @@ public bool CanDownloadInvoices { get { - var value = Configuration["crm:invoice:download:enable"]; + var value = _configuration["crm:invoice:download:enable"]; if (string.IsNullOrEmpty(value)) return false; bool canDownloadFiles = Convert.ToBoolean(value); - if (canDownloadFiles && string.IsNullOrEmpty(FilesLinkUtility.DocServiceConverterUrl)) + if (canDownloadFiles && string.IsNullOrEmpty(_filesLinkUtility.DocServiceConverterUrl)) { canDownloadFiles = false; } @@ -168,16 +165,16 @@ public bool CanCreateReports { get { - return !string.IsNullOrEmpty(FilesLinkUtility.DocServiceDocbuilderUrl) && CRMSecurity.IsAdmin; + return !string.IsNullOrEmpty(_filesLinkUtility.DocServiceDocbuilderUrl) && _crmSecurity.IsAdmin; } } public void SaveDefaultCurrencySettings(CurrencyInfo currency) { - var tenantSettings = SettingsManager.Load(); + var tenantSettings = _settingsManager.Load(); tenantSettings.DefaultCurrency = currency.Abbreviation; - SettingsManager.Save(tenantSettings); + _settingsManager.Save(tenantSettings); } diff --git a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs index 0714db5e179..5da675c55ec 100644 --- a/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs +++ b/products/ASC.CRM/Server/Classes/ImportFromCSVManager.cs @@ -43,24 +43,24 @@ namespace ASC.Web.CRM.Classes [Scope] public class ImportFromCSVManager { + private MessageService _messageService; + private ImportFromCSV _importFromCSV; + private Global _global; + public ImportFromCSVManager(Global global, ImportFromCSV importFromCSV, MessageService messageService) { - Global = global; - ImportFromCSV = importFromCSV; - MessageService = messageService; + _global = global; + _importFromCSV = importFromCSV; + _messageService = messageService; } - public MessageService MessageService { get; } - public ImportFromCSV ImportFromCSV { get; } - public Global Global { get; } - public void StartImport(EntityType entityType, String CSVFileURI, String importSettingsJSON) { - ImportFromCSV.Start(entityType, CSVFileURI, importSettingsJSON); + _importFromCSV.Start(entityType, CSVFileURI, importSettingsJSON); - MessageService.Send(GetMessageAction(entityType)); + _messageService.Send(GetMessageAction(entityType)); } public FileUploadResult ProcessUploadFake(string fileTemp, string importSettingsJSON) @@ -69,12 +69,12 @@ public FileUploadResult ProcessUploadFake(string fileTemp, string importSettings if (String.IsNullOrEmpty(fileTemp) || String.IsNullOrEmpty(importSettingsJSON)) return fileUploadResult; - if (!Global.GetStore().IsFile("temp", fileTemp)) return fileUploadResult; + if (!_global.GetStore().IsFile("temp", fileTemp)) return fileUploadResult; JsonDocument jObject; //Read contents - using (Stream storeStream = Global.GetStore().GetReadStream("temp", fileTemp)) + using (Stream storeStream = _global.GetStore().GetReadStream("temp", fileTemp)) { using (var CSVFileStream = new MemoryStream()) { @@ -87,7 +87,7 @@ public FileUploadResult ProcessUploadFake(string fileTemp, string importSettings } CSVFileStream.Position = 0; - jObject = ImportFromCSV.GetInfo(CSVFileStream, importSettingsJSON); + jObject = _importFromCSV.GetInfo(CSVFileStream, importSettingsJSON); } } diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index bdc355c9f04..7482c153d16 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -42,16 +42,16 @@ namespace ASC.Web.CRM.Classes [Scope] public class InvoiceFormattedData { + private OrganisationLogoManager _organisationLogoManager; + private DaoFactory _daoFactory; + public InvoiceFormattedData(DaoFactory daoFactory, OrganisationLogoManager organisationLogoManager) { - DaoFactory = daoFactory; - OrganisationLogoManager = organisationLogoManager; + _daoFactory = daoFactory; + _organisationLogoManager = organisationLogoManager; } - public OrganisationLogoManager OrganisationLogoManager { get; } - - public DaoFactory DaoFactory { get; } public int TemplateType { get; set; } public Tuple Seller { get; set; } @@ -92,7 +92,7 @@ public InvoiceFormattedData GetDataAfterLinesUpdated(Invoice invoice) private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, int deliveryAddressID) { - var data = new InvoiceFormattedData(DaoFactory, OrganisationLogoManager); + var data = new InvoiceFormattedData(_daoFactory, _organisationLogoManager); var sb = new StringBuilder(); var list = new List(); var cultureInfo = string.IsNullOrEmpty(invoice.Language) @@ -107,7 +107,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i #region Seller, LogoBase64, LogoSrcFormat - var invoiceSettings = DaoFactory.GetInvoiceDao().GetSettings(); + var invoiceSettings = _daoFactory.GetInvoiceDao().GetSettings(); if (!string.IsNullOrEmpty(invoiceSettings.CompanyName)) { @@ -153,7 +153,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i { data.LogoBase64Id = invoiceSettings.CompanyLogoID; //data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(invoiceSettings.CompanyLogoID); - data.LogoSrcFormat = OrganisationLogoManager.OrganisationLogoSrcFormat; + data.LogoSrcFormat = _organisationLogoManager.OrganisationLogoSrcFormat; } #endregion @@ -190,7 +190,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i #region Customer - var customer = DaoFactory.GetContactDao().GetByID(invoice.ContactID); + var customer = _daoFactory.GetContactDao().GetByID(invoice.ContactID); if (customer != null) { @@ -199,7 +199,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i sb.Append(customer.GetTitle()); var billingAddress = billingAddressID != 0 - ? DaoFactory.GetContactInfoDao().GetByID(billingAddressID) + ? _daoFactory.GetContactInfoDao().GetByID(billingAddressID) : null; if (billingAddress != null && billingAddress.InfoType == ContactInfoType.Address && billingAddress.Category == (int)AddressCategory.Billing) @@ -258,7 +258,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i data.TableBodyRows = new List>(); - var invoiceLines = invoice.GetInvoiceLines(DaoFactory); + var invoiceLines = invoice.GetInvoiceLines(_daoFactory); var invoiceTaxes = new Dictionary(); decimal subtotal = 0; @@ -267,12 +267,12 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i foreach (var line in invoiceLines) { - var item = DaoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); + var item = _daoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); var tax1 = line.InvoiceTax1ID > 0 - ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) + ? _daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) : null; var tax2 = line.InvoiceTax2ID > 0 - ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) + ? _daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) : null; var subtotalValue = Math.Round(line.Quantity * line.Price, 2); @@ -332,7 +332,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i foreach (var invoiceTax in invoiceTaxes) { - var iTax = DaoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); + var iTax = _daoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); data.TableFooterRows.Add(new Tuple( string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); @@ -373,7 +373,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i #region Consignee - var consignee = DaoFactory.GetContactDao().GetByID(invoice.ConsigneeID); + var consignee = _daoFactory.GetContactDao().GetByID(invoice.ConsigneeID); if (consignee != null) { @@ -382,7 +382,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i sb.Append(consignee.GetTitle()); var deliveryAddress = deliveryAddressID != 0 - ? DaoFactory.GetContactInfoDao().GetByID(deliveryAddressID) + ? _daoFactory.GetContactInfoDao().GetByID(deliveryAddressID) : null; if (deliveryAddress != null && deliveryAddress.InfoType == ContactInfoType.Address && deliveryAddress.Category == (int)AddressCategory.Postal) @@ -438,7 +438,7 @@ private InvoiceFormattedData CreateData(Invoice invoice, int billingAddressID, i private InvoiceFormattedData ReadData(string jsonData) { - var data = new InvoiceFormattedData(DaoFactory, OrganisationLogoManager); + var data = new InvoiceFormattedData(_daoFactory, _organisationLogoManager); var jsonObj = JsonDocument.Parse(jsonData).RootElement; #region TemplateType @@ -461,7 +461,7 @@ private InvoiceFormattedData ReadData(string jsonData) if (string.IsNullOrEmpty(data.LogoBase64) && data.LogoBase64Id != 0) { - data.LogoBase64 = OrganisationLogoManager.GetOrganisationLogoBase64(data.LogoBase64Id); + data.LogoBase64 = _organisationLogoManager.GetOrganisationLogoBase64(data.LogoBase64Id); } @@ -588,7 +588,7 @@ private InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, data.TableBodyRows = new List>(); - var invoiceLines = invoice.GetInvoiceLines(DaoFactory); + var invoiceLines = invoice.GetInvoiceLines(_daoFactory); var invoiceTaxes = new Dictionary(); decimal subtotal = 0; @@ -597,12 +597,12 @@ private InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, foreach (var line in invoiceLines) { - var item = DaoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); + var item = _daoFactory.GetInvoiceItemDao().GetByID(line.InvoiceItemID); var tax1 = line.InvoiceTax1ID > 0 - ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) + ? _daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax1ID) : null; var tax2 = line.InvoiceTax2ID > 0 - ? DaoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) + ? _daoFactory.GetInvoiceTaxDao().GetByID(line.InvoiceTax2ID) : null; var subtotalValue = Math.Round(line.Quantity * line.Price, 2); @@ -662,7 +662,7 @@ private InvoiceFormattedData CreateDataAfterLinesUpdated(Invoice invoice, foreach (var invoiceTax in invoiceTaxes) { - var iTax = DaoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); + var iTax = _daoFactory.GetInvoiceTaxDao().GetByID(invoiceTax.Key); data.TableFooterRows.Add(new Tuple( string.Format("{0} ({1}%)", iTax.Name, iTax.Rate), invoiceTax.Value.ToString(CultureInfo.InvariantCulture))); diff --git a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs index b7287b6ae36..bbb932eb0eb 100644 --- a/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs +++ b/products/ASC.CRM/Server/Classes/OrganisationLogoManager.cs @@ -44,23 +44,22 @@ namespace ASC.Web.CRM.Classes [Scope] public class OrganisationLogoManager { + private DaoFactory _daoFactory; + private ILog _logger; + private Global _global; + private WebImageSupplier _webImageSupplier; + public OrganisationLogoManager(WebImageSupplier webImageSupplier, Global global, IOptionsMonitor logger, DaoFactory daoFactory) { - WebImageSupplier = webImageSupplier; - Global = global; - Logger = logger.Get("ASC.CRM"); - DaoFactory = daoFactory; + _webImageSupplier = webImageSupplier; + _global = global; + _logger = logger.Get("ASC.CRM"); + _daoFactory = daoFactory; } - public DaoFactory DaoFactory { get; } - public ILog Logger { get; } - - public Global Global { get; } - - public WebImageSupplier WebImageSupplier { get; } #region Members @@ -120,14 +119,14 @@ private String ExecResizeImage(byte[] imageData, Size fotoSize, IDataStore dataS public String GetDefaultLogoUrl() { - return WebImageSupplier.GetAbsoluteWebPath("org_logo_default.png", ProductEntryPoint.ID); + return _webImageSupplier.GetAbsoluteWebPath("org_logo_default.png", ProductEntryPoint.ID); } public String GetOrganisationLogoBase64(int logoID) { if (logoID <= 0) { return ""; } - return DaoFactory.GetInvoiceDao().GetOrganisationLogoBase64(logoID); + return _daoFactory.GetInvoiceDao().GetOrganisationLogoBase64(logoID); } @@ -141,7 +140,7 @@ public String GetOrganisationLogoSrc(int logoID) public void DeletePhoto(bool recursive) { var photoDirectory = BuildFileDirectory(); - var store = Global.GetStore(); + var store = _global.GetStore(); lock (_synchronizedObj) { @@ -159,14 +158,14 @@ public void DeletePhoto(bool recursive) public int TryUploadOrganisationLogoFromTmp(DaoFactory factory) { var directoryPath = BuildFileDirectory(); - var dataStore = Global.GetStore(); + var dataStore = _global.GetStore(); if (!dataStore.IsDirectory(directoryPath)) return 0; try { - var photoPaths = Global.GetStore().ListFilesRelative("", directoryPath, OrganisationLogoImgName + "*", false); + var photoPaths = _global.GetStore().ListFilesRelative("", directoryPath, OrganisationLogoImgName + "*", false); if (photoPaths.Length == 0) return 0; @@ -183,7 +182,7 @@ public int TryUploadOrganisationLogoFromTmp(DaoFactory factory) catch (Exception ex) { - Logger.ErrorFormat("TryUploadOrganisationLogoFromTmp failed with error: {0}", ex); + _logger.ErrorFormat("TryUploadOrganisationLogoFromTmp failed with error: {0}", ex); return 0; } @@ -193,7 +192,7 @@ public String UploadLogo(byte[] imageData, ImageFormat imageFormat) { var photoPath = BuildFilePath("." + Global.GetImgFormatName(imageFormat)); - return ExecResizeImage(imageData, OrganisationLogoSize, Global.GetStore(), photoPath); + return ExecResizeImage(imageData, OrganisationLogoSize, _global.GetStore(), photoPath); } } } diff --git a/products/ASC.CRM/Server/Classes/PathProvider.cs b/products/ASC.CRM/Server/Classes/PathProvider.cs index 66b9a3b953a..0002a9c38bb 100644 --- a/products/ASC.CRM/Server/Classes/PathProvider.cs +++ b/products/ASC.CRM/Server/Classes/PathProvider.cs @@ -41,19 +41,19 @@ namespace ASC.Web.CRM [Scope] public class PathProvider { + private HttpContext _httpContext; + private CommonLinkUtility _commonLinkUtility; + private WebPath _webPath; + public PathProvider(IHttpContextAccessor httpContextAccessor, CommonLinkUtility commonLinkUtility) { - CommonLinkUtility = commonLinkUtility; - HttpContext = httpContextAccessor.HttpContext; + _commonLinkUtility = commonLinkUtility; + _httpContext = httpContextAccessor.HttpContext; - BaseAbsolutePath = CommonLinkUtility.ToAbsolute(BaseVirtualPath); + BaseAbsolutePath = _commonLinkUtility.ToAbsolute(BaseVirtualPath); } - public HttpContext HttpContext { get; } - - public CommonLinkUtility CommonLinkUtility { get; } - public WebPath WebPath { get; } public readonly String BaseVirtualPath = "~/Products/CRM/"; public readonly String BaseAbsolutePath; diff --git a/products/ASC.CRM/Server/Classes/SignalRHelper.cs b/products/ASC.CRM/Server/Classes/SignalRHelper.cs index 92a5663d5d5..d780aa1efe7 100644 --- a/products/ASC.CRM/Server/Classes/SignalRHelper.cs +++ b/products/ASC.CRM/Server/Classes/SignalRHelper.cs @@ -36,38 +36,38 @@ public class SignalRHelper { private readonly string numberId; - public SignalrServiceClient SignalrServiceClient { get; } + private SignalrServiceClient _signalrServiceClient; public SignalRHelper(string numberId, SignalrServiceClient signalrServiceClient) { - SignalrServiceClient = signalrServiceClient; + _signalrServiceClient = signalrServiceClient; this.numberId = numberId.TrimStart('+'); } public void Enqueue(string call, string agent) { - SignalrServiceClient.EnqueueCall(numberId, call, agent); + _signalrServiceClient.EnqueueCall(numberId, call, agent); } public void Incoming(string call, string agent) { - SignalrServiceClient.IncomingCall(call, agent); + _signalrServiceClient.IncomingCall(call, agent); } public void MissCall(string call, string agent) { - SignalrServiceClient.MissCall(numberId, call, agent); + _signalrServiceClient.MissCall(numberId, call, agent); } public void Reload(string agentId = null) { - SignalrServiceClient.Reload(numberId, agentId); + _signalrServiceClient.Reload(numberId, agentId); } public Tuple GetAgent(List contactsResponsibles) { - return SignalrServiceClient.GetAgent>(numberId, contactsResponsibles); + return _signalrServiceClient.GetAgent>(numberId, contactsResponsibles); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs index 1052e86ba44..608a788d3ab 100644 --- a/products/ASC.CRM/Server/Classes/SubscriptionManager.cs +++ b/products/ASC.CRM/Server/Classes/SubscriptionManager.cs @@ -49,13 +49,14 @@ public class ProductSubscriptionManager : IProductSubscriptionManager private readonly Guid _importCompleted = new Guid("{6A717AAD-16AE-4713-A782-B887766BEB9F}"); private readonly Guid _createNewContact = new Guid("{ADAC1E70-4163-41c1-8968-67A44E4D24E7}"); + private CoreBaseSettings _coreBaseSettings; + public ProductSubscriptionManager(CoreBaseSettings coreBaseSettings, NotifySource notifySource) { - CoreBaseSettings = coreBaseSettings; + _coreBaseSettings = coreBaseSettings; } public NotifySource NotifySource { get; } - public CoreBaseSettings CoreBaseSettings { get; } public List GetSubscriptionObjects(Guid subItem) { @@ -102,7 +103,7 @@ public List GetSubscriptionTypes() { ID = _exportCompleted, Name = CRMCommonResource.SubscriptionType_ExportCompleted, - NotifyAction = CoreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, + NotifyAction = _coreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted, Single = true, CanSubscribe = true }, @@ -110,7 +111,7 @@ public List GetSubscriptionTypes() { ID = _importCompleted, Name = CRMCommonResource.SubscriptionType_ImportCompleted, - NotifyAction = CoreBaseSettings.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, + NotifyAction = _coreBaseSettings.CustomMode ? NotifyConstants.Event_ImportCompletedCustomMode : NotifyConstants.Event_ImportCompleted, Single = true, CanSubscribe = true }, diff --git a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs index e2c3d2373fa..08ed2f1c381 100644 --- a/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs +++ b/products/ASC.CRM/Server/Configuration/CRMsSpaceUsageStatManager.cs @@ -44,31 +44,32 @@ namespace ASC.Web.CRM.Configuration [Scope] public class CrmSpaceUsageStatManager : SpaceUsageStatManager { + private int _tenantId; + private FilesDbContext _filesDbContext; + private PathProvider _pathProvider; + public CrmSpaceUsageStatManager(DbContextManager filesDbContext, PathProvider pathProvider, TenantManager tenantManager) { - PathProvider = pathProvider; - FilesDbContext = filesDbContext.Value; - TenantId = tenantManager.GetCurrentTenant().TenantId; + _pathProvider = pathProvider; + _filesDbContext = filesDbContext.Value; + _tenantId = tenantManager.GetCurrentTenant().TenantId; } - public int TenantId { get; } - public FilesDbContext FilesDbContext { get; } - public PathProvider PathProvider { get; } public override List GetStatData() { - var spaceUsage = FilesDbContext.Files.Join(FilesDbContext.Tree, + var spaceUsage = _filesDbContext.Files.Join(_filesDbContext.Tree, x => x.FolderId, y => y.FolderId, (x, y) => new { x, y } ) - .Join(FilesDbContext.BunchObjects, + .Join(_filesDbContext.BunchObjects, x => x.y.ParentId, y => Convert.ToInt32(y.LeftNode), (x, y) => new { x, y }) - .Where(x => x.y.TenantId == TenantId && + .Where(x => x.y.TenantId == _tenantId && Microsoft.EntityFrameworkCore.EF.Functions.Like(x.y.RightNode, "crm/crm_common/%")) .Sum(x => x.x.x.ContentLength); @@ -78,7 +79,7 @@ public override List GetStatData() Name = CRMCommonResource.WholeCRMModule, SpaceUsage = spaceUsage, - Url = VirtualPathUtility.ToAbsolute(PathProvider.StartURL()) + Url = VirtualPathUtility.ToAbsolute(_pathProvider.StartURL()) } }; diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index f30232f5d1a..f84578bd41a 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -48,23 +48,24 @@ namespace ASC.Web.CRM.Configuration [Scope] public class ProductEntryPoint : Product { + private ProductContext _context; + private FilesIntegration _filesIntegration; + private PathProvider _pathProvider; + private SecurityContext _securityContext; + private UserManager _userManager; + public ProductEntryPoint(SecurityContext securityContext, UserManager userManager, PathProvider pathProvider, FilesIntegration filesIntegration) { - SecurityContext = securityContext; - UserManager = userManager; - PathProvider = pathProvider; - FilesIntegration = filesIntegration; + _securityContext = securityContext; + _userManager = userManager; + _pathProvider = pathProvider; + _filesIntegration = filesIntegration; } public static readonly Guid ID = WebItemManager.CRMProductID; - private ProductContext _context; - public FilesIntegration FilesIntegration { get; } - public PathProvider PathProvider { get; } - public SecurityContext SecurityContext { get; } - public UserManager UserManager { get; } public override string ApiURL { get => "api/2.0/crm/info.json"; @@ -75,17 +76,17 @@ public override string Description { get { - var id = SecurityContext.CurrentAccount.ID; + var id = _securityContext.CurrentAccount.ID; - if (UserManager.IsUserInGroup(id, ASC.Core.Users.Constants.GroupAdmin.ID) || UserManager.IsUserInGroup(id, ID)) + if (_userManager.IsUserInGroup(id, ASC.Core.Users.Constants.GroupAdmin.ID) || _userManager.IsUserInGroup(id, ID)) return CRMCommonResource.ProductDescriptionEx; return CRMCommonResource.ProductDescription; } } - public override string StartURL { get { return PathProvider.StartURL(); } } - public override string HelpURL { get { return string.Concat(PathProvider.BaseVirtualPath, "help.aspx"); } } + public override string StartURL { get { return _pathProvider.StartURL(); } } + public override string HelpURL { get { return string.Concat(_pathProvider.BaseVirtualPath, "help.aspx"); } } public override string ProductClassName { get { return "crm"; } } public override bool Visible { get { return true; } } public override ProductContext Context { get { return _context; } } diff --git a/products/ASC.CRM/Server/Configuration/VoipModule.cs b/products/ASC.CRM/Server/Configuration/VoipModule.cs index 22102a7cfc3..7e57c0e9f67 100644 --- a/products/ASC.CRM/Server/Configuration/VoipModule.cs +++ b/products/ASC.CRM/Server/Configuration/VoipModule.cs @@ -36,15 +36,16 @@ namespace ASC.Web.CRM.Configuration [WebZone(WebZoneType.CustomProductList)] public class VoipModule : IAddon { + private PathProvider _pathProvider; + private SetupInfo _setupInfo; + public VoipModule(PathProvider pathProvider, SetupInfo setupInfo) { - PathProvider = pathProvider; - SetupInfo = setupInfo; + _pathProvider = pathProvider; + _setupInfo = setupInfo; } - public PathProvider PathProvider { get; } - public SetupInfo SetupInfo { get; } public Guid ID { @@ -63,7 +64,7 @@ public string Description public string StartURL { - get { return PathProvider.StartURL() + "settings.aspx?type=voip.common&sysname=/modules/voip"; } + get { return _pathProvider.StartURL() + "settings.aspx?type=voip.common&sysname=/modules/voip"; } } public string HelpURL @@ -73,7 +74,7 @@ public string HelpURL public string ProductClassName { get { return "voip"; } } - public bool Visible { get { return SetupInfo.VoipEnabled; } } + public bool Visible { get { return _setupInfo.VoipEnabled; } } public AddonContext Context { get; private set; } diff --git a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs index fc74f298be5..db879363054 100644 --- a/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs +++ b/products/ASC.CRM/Server/Services/NotifyService/NotifyClient.cs @@ -54,20 +54,20 @@ namespace ASC.Web.CRM.Services.NotifyService [Scope] public class NotifyClient { + private IServiceProvider _serviceProvider; + public NotifyClient(IServiceProvider serviceProvider) { - ServiceProvider = serviceProvider; + _serviceProvider = serviceProvider; } - public IServiceProvider ServiceProvider { get; } - public void SendAboutCreateNewContact(List recipientID, int contactID, string contactTitle, NameValueCollection fields) { if ((recipientID.Count == 0) || String.IsNullOrEmpty(contactTitle)) return; - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -86,7 +86,7 @@ public void SendAboutSetAccess(EntityType entityType, int entityID, DaoFactory d { if (userID.Length == 0) return; - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -105,7 +105,7 @@ public void SendAboutSetAccess(EntityType entityType, int entityID, DaoFactory d private NameValueCollection ExtractBaseDataFrom(EntityType entityType, int entityID, DaoFactory daoFactory) { - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var pathProvider = scope.ServiceProvider.GetService(); var result = new NameValueCollection(); @@ -154,7 +154,7 @@ public void SendAboutAddRelationshipEventAdd(RelationshipEvent entity, Hashtable { if (userID.Length == 0) return; - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var pathProvider = scope.ServiceProvider.GetService(); var securityContext = scope.ServiceProvider.GetService(); @@ -219,7 +219,7 @@ public void SendAboutExportCompleted(Guid recipientID, String fileName, String f { if (recipientID == Guid.Empty) return; - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var coreBaseSettings = scope.ServiceProvider.GetService(); var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -239,7 +239,7 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) { if (recipientID == Guid.Empty) return; - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var coreBaseSettings = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -282,7 +282,7 @@ public void SendAboutImportCompleted(Guid recipientID, EntityType entityType) public void SendAutoReminderAboutTask(DateTime scheduleDate) { - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var defaultDao = scope.ServiceProvider.GetService(); var tenantManager = scope.ServiceProvider.GetService(); @@ -379,7 +379,7 @@ public void SendAutoReminderAboutTask(DateTime scheduleDate) public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal) { - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); @@ -447,7 +447,7 @@ public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskCo public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Contact taskContact, Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal, Hashtable fileListInfoHashtable) { - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); var tenantUtil = scope.ServiceProvider.GetService(); @@ -518,7 +518,7 @@ public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Cont public void SendAboutResponsibleForOpportunity(Deal deal) { - using var scope = ServiceProvider.CreateScope(); + using var scope = _serviceProvider.CreateScope(); var notifySource = scope.ServiceProvider.GetService(); var securityContext = scope.ServiceProvider.GetService(); var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index b801fbbf7b4..d445ffce8f4 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -47,7 +47,7 @@ public partial class ImportDataOperation private void ImportCaseData(DaoFactory _daoFactory) { using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) - using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) + using (CsvReader csv = _importFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { int currentIndex = 0; @@ -146,7 +146,7 @@ private void ImportCaseData(DaoFactory _daoFactory) findedCases.Add(objCases); - if (currentIndex + 1 > ImportFromCSV.MaxRoxCount) break; + if (currentIndex + 1 > _importFromCSV.MaxRoxCount) break; currentIndex++; } diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs index 58bacf5216f..ac24dc0d0a1 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportContacts.cs @@ -65,7 +65,7 @@ private void ImportContactsData(DaoFactory _daoFactory) #region Read csv using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) { - CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings); + CsvReader csv = _importFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings); int currentIndex = 0; @@ -116,7 +116,7 @@ private void ImportContactsData(DaoFactory _daoFactory) } #endregion - if (currentIndex + 1 > ImportFromCSV.MaxRoxCount) break; + if (currentIndex + 1 > _importFromCSV.MaxRoxCount) break; currentIndex++; } } @@ -352,7 +352,7 @@ private bool _CommonData(int currentIndex, DaoFactory _daoFactory, ref Contact c if (String.IsNullOrEmpty(firstName) && String.IsNullOrEmpty(lastName) && String.IsNullOrEmpty(companyName)) return false; - Percentage += 1.0 * 100 / (ImportFromCSV.MaxRoxCount * 3); + Percentage += 1.0 * 100 / (_importFromCSV.MaxRoxCount * 3); PublishChanges(); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 18810905f3c..88b29449933 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -61,15 +61,15 @@ public partial class ImportDataOperation : DistributedTaskProgress, IProgressIte private string[] _columns; private bool _IsConfigure; - public readonly CurrencyProvider _currencyProvider; - public readonly NotifyClient _notifyClient; - public readonly SettingsManager _settingsManager; - public readonly CrmSecurity _crmSecurity; - public readonly TenantManager _tenantManager; - public readonly SecurityContext _securityContext; - public readonly UserManager _userManager; - public readonly DaoFactory _daoFactory; - public readonly ILog _logManager; + private readonly CurrencyProvider _currencyProvider; + private readonly NotifyClient _notifyClient; + private readonly SettingsManager _settingsManager; + private readonly CrmSecurity _crmSecurity; + private readonly TenantManager _tenantManager; + private readonly SecurityContext _securityContext; + private readonly UserManager _userManager; + private readonly DaoFactory _daoFactory; + private readonly ILog _logManager; public ImportDataOperation(Global global, TenantManager tenantManager, diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index b56763cfe73..b23f37e50c3 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -51,7 +51,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) var allUsers = _userManager.GetUsers(EmployeeStatus.All).ToList(); using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) - using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) + using (CsvReader csv = _importFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { int currentIndex = 0; @@ -83,7 +83,7 @@ private void ImportOpportunityData(DaoFactory _daoFactory) obj.Description = GetPropertyValue("description"); var csvResponsibleValue = GetPropertyValue("responsible"); - var responsible = allUsers.Where(n => n.DisplayUserName(DisplayUserSettingsHelper).Equals(csvResponsibleValue)).FirstOrDefault(); + var responsible = allUsers.Where(n => n.DisplayUserName(_displayUserSettingsHelper).Equals(csvResponsibleValue)).FirstOrDefault(); if (responsible != null) obj.ResponsibleID = responsible.ID; @@ -261,12 +261,12 @@ private void ImportOpportunityData(DaoFactory _daoFactory) } } - Percentage += 1.0 * 100 / (ImportFromCSV.MaxRoxCount * 2); + Percentage += 1.0 * 100 / (_importFromCSV.MaxRoxCount * 2); PublishChanges(); findedDeals.Add(obj); - if (currentIndex + 1 > ImportFromCSV.MaxRoxCount) break; + if (currentIndex + 1 > _importFromCSV.MaxRoxCount) break; currentIndex++; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index 033a1b9e8d5..a54c72bd836 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -44,6 +44,12 @@ namespace ASC.Web.CRM.Classes [Scope] public class ImportFromCSV { + private readonly ImportDataOperation _importDataOperation; + private readonly int _tenantId; + private readonly object _syncObj = new object(); + private readonly DistributedTaskQueue _importQueue; + public readonly int MaxRoxCount = 10000; + public ImportFromCSV(TenantManager tenantProvider, DistributedTaskQueueOptionsManager progressQueueOptionsManager, ImportDataOperation importDataOperation) @@ -53,11 +59,6 @@ public ImportFromCSV(TenantManager tenantProvider, _importDataOperation = importDataOperation; } - private readonly ImportDataOperation _importDataOperation; - private readonly int _tenantId; - private readonly object _syncObj = new object(); - private readonly DistributedTaskQueue _importQueue; - public readonly int MaxRoxCount = 10000; public int GetQuotas() { diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs index 7ae303c4de1..a11c917ba4c 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs @@ -47,23 +47,23 @@ namespace ASC.Web.CRM.Classes { public partial class ImportDataOperation { + private ImportFromCSV _importFromCSV; + private TenantUtil _tenantUtil; + private DisplayUserSettingsHelper _displayUserSettingsHelper; + public ImportDataOperation(TenantUtil tenantUtil, ImportFromCSV importFromCSV, DisplayUserSettingsHelper displayUserSettingsHelper) { - TenantUtil = tenantUtil; - ImportFromCSV = importFromCSV; - DisplayUserSettingsHelper = displayUserSettingsHelper; + _tenantUtil = tenantUtil; + _importFromCSV = importFromCSV; + _displayUserSettingsHelper = displayUserSettingsHelper; } - - public ImportFromCSV ImportFromCSV { get; } - public TenantUtil TenantUtil { get; } - public DisplayUserSettingsHelper DisplayUserSettingsHelper { get; } - + private void ImportTaskData(DaoFactory _daoFactory) { using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) - using (CsvReader csv = ImportFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) + using (CsvReader csv = _importFromCSV.CreateCsvReaderInstance(CSVFileStream, _importSettings)) { int currentIndex = 0; @@ -95,10 +95,10 @@ private void ImportTaskData(DaoFactory _daoFactory) if (DateTime.TryParse(GetPropertyValue("due_date"), out deadline)) obj.DeadLine = deadline; else - obj.DeadLine = TenantUtil.DateTimeNow(); + obj.DeadLine = _tenantUtil.DateTimeNow(); var csvResponsibleValue = GetPropertyValue("responsible"); - var responsible = allUsers.Where(n => n.DisplayUserName(DisplayUserSettingsHelper).Equals(csvResponsibleValue)).FirstOrDefault(); + var responsible = allUsers.Where(n => n.DisplayUserName(_displayUserSettingsHelper).Equals(csvResponsibleValue)).FirstOrDefault(); if (responsible != null) obj.ResponsibleID = responsible.ID; @@ -163,7 +163,7 @@ private void ImportTaskData(DaoFactory _daoFactory) findedTasks.Add(obj); - if ((currentIndex + 1) > ImportFromCSV.MaxRoxCount) break; + if ((currentIndex + 1) > _importFromCSV.MaxRoxCount) break; currentIndex++; diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index de63cc3c7c1..e8f563586d2 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -94,7 +94,6 @@ public class SendBatchEmailsOperation : DistributedTaskProgress, IProgressItem, private SecurityContext _securityContext; private TenantUtil _tenantUtil; - public object Error { get; set; } private SendBatchEmailsOperation() diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index a9eef7152c3..e19f6a6899d 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -49,6 +49,15 @@ namespace ASC.Web.CRM.Classes [Scope] public class PdfCreator { + private InvoiceFormattedData _invoiceFormattedData; + private DaoFactory _daoFactory; + private IServiceProvider _serviceProvider; + private DocumentServiceConnector _documentServiceConnector; + private OrganisationLogoManager _organisationLogoManager; + private Files.Classes.PathProvider _filesPathProvider; + private ILog _logger; + + public PdfCreator(IOptionsMonitor logger, Files.Classes.PathProvider filesPathProvider, DocumentServiceConnector documentServiceConnector, @@ -57,20 +66,17 @@ public PdfCreator(IOptionsMonitor logger, DaoFactory daoFactory, InvoiceFormattedData invoiceFormattedData) { - FilesPathProvider = filesPathProvider; + _filesPathProvider = filesPathProvider; - Logger = logger.Get("ASC.CRM"); + _logger = logger.Get("ASC.CRM"); - DocumentServiceConnector = documentServiceConnector; - ServiceProvider = serviceProvider; - OrganisationLogoManager = organisationLogoManager; - DaoFactory = daoFactory; - InvoiceFormattedData = invoiceFormattedData; + _documentServiceConnector = documentServiceConnector; + _serviceProvider = serviceProvider; + _organisationLogoManager = organisationLogoManager; + _daoFactory = daoFactory; + _invoiceFormattedData = invoiceFormattedData; } - public InvoiceFormattedData InvoiceFormattedData { get; } - - public DaoFactory DaoFactory { get; } private Stream Template { @@ -81,12 +87,6 @@ private Stream Template } } - public IServiceProvider ServiceProvider { get; } - public DocumentServiceConnector DocumentServiceConnector { get; } - public OrganisationLogoManager OrganisationLogoManager { get; } - public Files.Classes.PathProvider FilesPathProvider { get; } - - public ILog Logger { get; } private const string FormatPdf = ".pdf"; private const string FormatDocx = ".docx"; @@ -95,20 +95,20 @@ private Stream Template public void CreateAndSaveFile(int invoiceId) { - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}", invoiceId); + _logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}", invoiceId); try { - var invoice = DaoFactory.GetInvoiceDao().GetByID(invoiceId); + var invoice = _daoFactory.GetInvoiceDao().GetByID(invoiceId); if (invoice == null) { - Logger.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); + _logger.Warn(CRMErrorsResource.InvoiceNotFound + ". Invoice ID = " + invoiceId); return; } - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. Convertation", invoiceId); + _logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. Convertation", invoiceId); string urlToFile; @@ -117,13 +117,13 @@ public void CreateAndSaveFile(int invoiceId) urlToFile = GetUrlToFile(docxStream); } - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, + _logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UrlToFile = {1}", invoiceId, urlToFile); - var file = ServiceProvider.GetService>(); + var file = _serviceProvider.GetService>(); file.Title = string.Format("{0}{1}", invoice.Number, FormatPdf); - file.FolderID = DaoFactory.GetFileDao().GetRoot(); + file.FolderID = _daoFactory.GetFileDao().GetRoot(); var request = WebRequest.Create(urlToFile); @@ -132,8 +132,8 @@ public void CreateAndSaveFile(int invoiceId) { file.ContentLength = response.ContentLength; - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); - file = DaoFactory.GetFileDao().SaveFile(file, stream); + _logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. SaveFile", invoiceId); + file = _daoFactory.GetFileDao().SaveFile(file, stream); } if (file == null) @@ -143,17 +143,17 @@ public void CreateAndSaveFile(int invoiceId) invoice.FileID = Int32.Parse(file.ID.ToString()); - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); + _logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. UpdateInvoiceFileID. FileID = {1}", invoiceId, file.ID); - DaoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); + _daoFactory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID); - Logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); + _logger.DebugFormat("PdfCreator. CreateAndSaveFile. Invoice ID = {0}. AttachFiles. FileID = {1}", invoiceId, file.ID); - DaoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); + _daoFactory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID }); } catch (Exception e) { - Logger.Error(e); + _logger.Error(e); } } @@ -170,7 +170,7 @@ public File CreateFile(Invoice data, DaoFactory daoFactory) } catch (Exception e) { - Logger.Error(e); + _logger.Error(e); throw; } @@ -178,19 +178,19 @@ public File CreateFile(Invoice data, DaoFactory daoFactory) private string GetUrlToFile(Stream docxStream) { - var externalUri = FilesPathProvider.GetTempUrl(docxStream, FormatDocx); + var externalUri = _filesPathProvider.GetTempUrl(docxStream, FormatDocx); - externalUri = DocumentServiceConnector.ReplaceCommunityAdress(externalUri); + externalUri = _documentServiceConnector.ReplaceCommunityAdress(externalUri); - Logger.DebugFormat("PdfCreator. GetUrlToFile. externalUri = {0}", externalUri); + _logger.DebugFormat("PdfCreator. GetUrlToFile. externalUri = {0}", externalUri); var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); string urlToFile; - DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, false, out urlToFile); + _documentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, false, out urlToFile); - Logger.DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); + _logger.DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); return urlToFile; @@ -200,15 +200,15 @@ public ConverterData StartCreationFileAsync(Invoice data) { using (var docxStream = GetStreamDocx(data)) { - var externalUri = FilesPathProvider.GetTempUrl(docxStream, FormatDocx); + var externalUri = _filesPathProvider.GetTempUrl(docxStream, FormatDocx); - externalUri = DocumentServiceConnector.ReplaceCommunityAdress(externalUri); + externalUri = _documentServiceConnector.ReplaceCommunityAdress(externalUri); var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); string urlToFile; - DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, true, out urlToFile); + _documentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, true, out urlToFile); return new ConverterData { @@ -228,14 +228,14 @@ public File GetConvertedFile(ConverterData data, DaoFactory daoFactory) string urlToFile; - DocumentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, true, out urlToFile); + _documentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, true, out urlToFile); if (string.IsNullOrEmpty(urlToFile)) { return null; } - var invoice = DaoFactory.GetInvoiceDao().GetByID(data.InvoiceId); + var invoice = _daoFactory.GetInvoiceDao().GetByID(data.InvoiceId); return SaveFile(invoice, urlToFile, daoFactory); } @@ -252,10 +252,10 @@ private File SaveFile(Invoice data, string url, DaoFactory daoFactory) { if (stream != null) { - var document = ServiceProvider.GetService>(); + var document = _serviceProvider.GetService>(); document.Title = string.Format("{0}{1}", data.Number, FormatPdf); - document.FolderID = DaoFactory.GetFileDao().GetRoot(); + document.FolderID = _daoFactory.GetFileDao().GetRoot(); document.ContentLength = response.ContentLength; if (data.GetInvoiceFile(daoFactory) != null) @@ -263,7 +263,7 @@ private File SaveFile(Invoice data, string url, DaoFactory daoFactory) document.ID = data.FileID; } - file = DaoFactory.GetFileDao().SaveFile(document, stream); + file = _daoFactory.GetFileDao().SaveFile(document, stream); } } } @@ -273,7 +273,7 @@ private File SaveFile(Invoice data, string url, DaoFactory daoFactory) private Stream GetStreamDocx(Invoice data) { - var invoiceData = InvoiceFormattedData.GetData(data, 0, 0); + var invoiceData = _invoiceFormattedData.GetData(data, 0, 0); var logo = new byte[] { }; if (!string.IsNullOrEmpty(invoiceData.LogoBase64)) @@ -282,7 +282,7 @@ private Stream GetStreamDocx(Invoice data) } else if (invoiceData.LogoBase64Id != 0) { - logo = Convert.FromBase64String(OrganisationLogoManager.GetOrganisationLogoBase64(invoiceData.LogoBase64Id)); + logo = Convert.FromBase64String(_organisationLogoManager.GetOrganisationLogoBase64(invoiceData.LogoBase64Id)); } var result = new MemoryStream(); diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index 39045edc790..9e72cdb63e5 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -48,23 +48,23 @@ namespace ASC.Web.CRM.Classes [Transient] public class PdfQueueWorker { - private readonly DistributedTaskQueue Queue; - private readonly int tenantId; - private readonly Guid userId; + private readonly DistributedTaskQueue _queue; + private readonly int _tenantId; + private readonly Guid _userId; private readonly object Locker = new object(); + private PdfProgressItem _pdfProgressItem; public PdfQueueWorker(DistributedTaskQueueOptionsManager queueOptions, PdfProgressItem pdfProgressItem, TenantManager tenantProvider, SecurityContext securityContext) { - Queue = queueOptions.Get(); - PdfProgressItem = pdfProgressItem; - tenantId = tenantProvider.GetCurrentTenant().TenantId; - userId = securityContext.CurrentAccount.ID; + _queue = queueOptions.Get(); + _pdfProgressItem = pdfProgressItem; + _tenantId = tenantProvider.GetCurrentTenant().TenantId; + _userId = securityContext.CurrentAccount.ID; } - public PdfProgressItem PdfProgressItem { get; } public string GetTaskId(int tenantId, int invoiceId) { @@ -75,35 +75,35 @@ public PdfProgressItem GetTaskStatus(int tenantId, int invoiceId) { var id = GetTaskId(tenantId, invoiceId); - var findedItem = Queue.GetTasks().FirstOrDefault(x => x.Id == id); + var findedItem = _queue.GetTasks().FirstOrDefault(x => x.Id == id); return findedItem; } public void TerminateTask(int invoiceId) { - var item = GetTaskStatus(tenantId, invoiceId); + var item = GetTaskStatus(_tenantId, invoiceId); if (item != null) - Queue.RemoveTask(item.Id); + _queue.RemoveTask(item.Id); } public PdfProgressItem StartTask(int invoiceId) { lock (Locker) { - var task = GetTaskStatus(tenantId, invoiceId); + var task = GetTaskStatus(_tenantId, invoiceId); if (task != null && task.IsCompleted) { - Queue.RemoveTask(task.Id); + _queue.RemoveTask(task.Id); task = null; } if (task == null) { - PdfProgressItem.Configure(GetTaskId(tenantId, invoiceId), tenantId, userId, invoiceId); - Queue.QueueTask(PdfProgressItem); + _pdfProgressItem.Configure(GetTaskId(_tenantId, invoiceId), _tenantId, _userId, invoiceId); + _queue.QueueTask(_pdfProgressItem); } diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index 34925c852c4..ecc04c6d41f 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -47,6 +47,17 @@ namespace ASC.Web.CRM.Classes [Scope] public class ReportHelper { + private CurrencyProvider _currencyProvider; + private IHttpContextAccessor _httpContext; + private SecurityContext _securityContext; + private DocbuilderReportsUtilityHelper _docbuilderReportsUtilityHelper; + private DaoFactory _daoFactory; + private IServiceProvider _serviceProvider; + private Global _global; + private SettingsManager _settingsManager; + private TenantUtil _tenantUtil; + private TenantManager _tenantManager; + public ReportHelper(TenantManager tenantManager, TenantUtil tenantUtil, Global global, @@ -59,29 +70,18 @@ public ReportHelper(TenantManager tenantManager, CurrencyProvider currencyProvider ) { - TenantManager = tenantManager; - TenantUtil = tenantUtil; - Global = global; - SettingsManager = settingsManager; - ServiceProvider = serviceProvider; - DaoFactory = daoFactory; - DocbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; - SecurityContext = securityContext; - HttpContext = httpContextAccessor; - CurrencyProvider = currencyProvider; + _tenantManager = tenantManager; + _tenantUtil = tenantUtil; + _global = global; + _settingsManager = settingsManager; + _serviceProvider = serviceProvider; + _daoFactory = daoFactory; + _docbuilderReportsUtilityHelper = docbuilderReportsUtilityHelper; + _securityContext = securityContext; + _httpContext = httpContextAccessor; + _currencyProvider = currencyProvider; } - private CurrencyProvider CurrencyProvider { get; } - public IHttpContextAccessor HttpContext { get; } - public SecurityContext SecurityContext { get; } - public DocbuilderReportsUtilityHelper DocbuilderReportsUtilityHelper { get; } - public DaoFactory DaoFactory { get; } - public IServiceProvider ServiceProvider { get; } - - public Global Global { get; } - public SettingsManager SettingsManager { get; } - public TenantUtil TenantUtil { get; } - public TenantManager TenantManager { get; } private string GetFileName(ReportType reportType) { string reportName; @@ -125,13 +125,13 @@ private string GetFileName(ReportType reportType) return string.Format("{0} ({1} {2}).xlsx", reportName, - TenantUtil.DateTimeNow().ToShortDateString(), - TenantUtil.DateTimeNow().ToShortTimeString()); + _tenantUtil.DateTimeNow().ToShortDateString(), + _tenantUtil.DateTimeNow().ToShortTimeString()); } public bool CheckReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { - var reportDao = DaoFactory.GetReportDao(); + var reportDao = _daoFactory.GetReportDao(); throw new NotImplementedException(); @@ -164,23 +164,23 @@ public bool CheckReportData(ReportType reportType, ReportTimePeriod timePeriod, public List GetMissingRates(ReportType reportType) { - var reportDao = DaoFactory.GetReportDao(); + var reportDao = _daoFactory.GetReportDao(); if (reportType == ReportType.WorkloadByTasks || reportType == ReportType.WorkloadByInvoices || reportType == ReportType.WorkloadByContacts || reportType == ReportType.WorkloadByVoip) return null; - var crmSettings = SettingsManager.Load(); - var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency); + var crmSettings = _settingsManager.Load(); + var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency); return reportDao.GetMissingRates(defaultCurrency.Abbreviation); } private object GetReportData(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { - var crmSettings = SettingsManager.Load(); + var crmSettings = _settingsManager.Load(); - var reportDao = DaoFactory.GetReportDao(); - var defaultCurrency = CurrencyProvider.Get(crmSettings.DefaultCurrency).Abbreviation; + var reportDao = _daoFactory.GetReportDao(); + var defaultCurrency = _currencyProvider.Get(crmSettings.DefaultCurrency).Abbreviation; switch (reportType) { @@ -227,15 +227,15 @@ private void SaveReportFile(ReportState state, string url) using (var stream = new System.IO.MemoryStream(data)) { - var document = ServiceProvider.GetService>(); + var document = _serviceProvider.GetService>(); document.Title = state.FileName; - document.FolderID = DaoFactory.GetFileDao().GetRoot(); + document.FolderID = _daoFactory.GetFileDao().GetRoot(); document.ContentLength = stream.Length; - var file = DaoFactory.GetFileDao().SaveFile(document, stream); + var file = _daoFactory.GetFileDao().SaveFile(document, stream); - DaoFactory.GetReportDao().SaveFile((int)file.ID, state.ReportType); + _daoFactory.GetReportDao().SaveFile((int)file.ID, state.ReportType); state.FileId = (int)file.ID; } @@ -264,12 +264,12 @@ public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod tim ReportOrigin.CRM, SaveReportFile, null, - TenantManager.GetCurrentTenant().TenantId, - SecurityContext.CurrentAccount.ID); + _tenantManager.GetCurrentTenant().TenantId, + _securityContext.CurrentAccount.ID); - var state = new ReportState(ServiceProvider, reportStateData, HttpContext); + var state = new ReportState(_serviceProvider, reportStateData, _httpContext); - DocbuilderReportsUtilityHelper.Enqueue(state); + _docbuilderReportsUtilityHelper.Enqueue(state); return state; } From ccd30b7b900c7e0d447671d8bbc6ed43b9808132 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 31 May 2021 19:14:59 +0300 Subject: [PATCH 55/61] crm: refactoring. used JsonPropertyName instead of DataMember --- .../Server/ApiModels/ResponsesDto/CasesDto.cs | 3 -- .../ApiModels/ResponsesDto/ContactDto.cs | 1 - .../ApiModels/ResponsesDto/ContactInfoDto.cs | 26 ---------------- .../ApiModels/ResponsesDto/CurrencyInfoDto.cs | 1 - .../ApiModels/ResponsesDto/CurrencyRateDto.cs | 2 -- .../ApiModels/ResponsesDto/CustomFieldDto.cs | 2 -- .../ApiModels/ResponsesDto/ListItemDto.cs | 5 ---- .../ApiModels/ResponsesDto/OpportunityDto.cs | 3 -- .../ResponsesDto/RelationshipEventDto.cs | 9 ------ .../ResponsesDto/TaskTemplateContainerDto.cs | 25 ---------------- .../ASC.CRM/Server/Classes/CRMSettings.cs | 30 ++++++------------- .../Server/Core/Dao/RelationshipEventDao.cs | 11 +------ products/ASC.CRM/Server/Core/DomainObject.cs | 3 +- products/ASC.CRM/Server/Core/Entities/Deal.cs | 21 ++++++------- .../Server/Core/Entities/DealMilestone.cs | 3 +- .../Server/Core/Entities/InvoiceTax.cs | 1 - .../ASC.CRM/Server/Core/Entities/ListItem.cs | 7 +++-- products/ASC.CRM/Server/Utils/MailSender.cs | 11 +++---- 18 files changed, 35 insertions(+), 129 deletions(-) diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs index 872b0fb768d..e284215a227 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CasesDto.cs @@ -26,7 +26,6 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; using ASC.Api.Core; using ASC.Common.Mapping; @@ -38,7 +37,6 @@ namespace ASC.CRM.ApiModels { - [DataContract(Name = "case", Namespace = "")] public class CasesDto : IMapFrom { public CasesDto() @@ -46,7 +44,6 @@ public CasesDto() } - [DataMember(Name = "id")] public int Id { get; set; } public IEnumerable Members { get; set; } public EmployeeWraper CreateBy { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs index ac931c08d56..bcfc4872e3a 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -233,7 +233,6 @@ public ContactBaseDto() } - [DataMember(Name = "id")] public int Id { get; set; } public String SmallFotoUrl { get; set; } public String MediumFotoUrl { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs index 6a2b7abde50..79325478384 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs @@ -86,28 +86,13 @@ public static bool TryParse(ContactInfo contactInfo, out Address res) } } - [DataMember(Order = 1, IsRequired = false, EmitDefaultValue = false)] public String Street { get; set; } - - [DataMember(Order = 2, IsRequired = false, EmitDefaultValue = false)] public String City { get; set; } - - [DataMember(Order = 3, IsRequired = false, EmitDefaultValue = false)] public String State { get; set; } - - [DataMember(Order = 4, IsRequired = false, EmitDefaultValue = false)] public String Zip { get; set; } - - [DataMember(Order = 5, IsRequired = false, EmitDefaultValue = false)] public String Country { get; set; } - - [DataMember(Order = 6, IsRequired = false, EmitDefaultValue = false)] public int Category { get; set; } - - [DataMember(Order = 7, IsRequired = false, EmitDefaultValue = false)] public String CategoryName { get; set; } - - [DataMember(Order = 8, IsRequired = false, EmitDefaultValue = false)] public Boolean IsPrimary { get; set; } public static Address GetSample() @@ -136,22 +121,11 @@ public ContactInfoDto() { } - [DataMember(Name = "id")] public int Id { get; set; } - - [DataMember(Order = 1)] public ContactInfoType InfoType { get; set; } - - [DataMember(Order = 2)] public int Category { get; set; } - - [DataMember(Order = 3)] public String Data { get; set; } - - [DataMember(Order = 4)] public String CategoryName { get; set; } - - [DataMember(Order = 5)] public bool IsPrimary { get; set; } public static ContactInfoDto GetSample() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs index 86a18933d99..848e79abfa7 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs @@ -25,7 +25,6 @@ using System; -using System.Runtime.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs index 2add9041301..2ecc16c231b 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs @@ -45,8 +45,6 @@ public CurrencyRateDto() { } - - [DataMember(Name = "id")] public int Id { get; set; } public String FromCurrency { get; set; } public String ToCurrency { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index 9d777b0f89c..ac76722fb5b 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -78,8 +78,6 @@ public CustomFieldBaseDto() { } - - [DataMember(Name = "id")] public int Id { get; set; } public int EntityId { get; set; } public String Label { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index e97a2302f10..c7fbc9c41ba 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -363,12 +363,8 @@ public TagDto(String tag, int relativeItemsCount = 0) RelativeItemsCount = relativeItemsCount; } - [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } - - public int RelativeItemsCount { get; set; } - public static TagDto GetSample() { return new TagDto @@ -397,7 +393,6 @@ protected ListItemDto(ListItem listItem) SortOrder = listItem.SortOrder; } - [DataMember(Name = "id")] public int Id { get; set; } public String Title { get; set; } public String Description { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs index 495d908605c..8bffa81f87a 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs @@ -50,14 +50,11 @@ public OpportunityDto() { } - [DataMember(Name = "id")] public int Id { get; set; } public EmployeeWraper CreateBy { get; set; } public ApiDateTime Created { get; set; } public IEnumerable Members { get; set; } public ContactBaseDto Contact { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } public String Description { get; set; } public EmployeeWraper Responsible { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs index e49185d89cd..e21e4af1ca0 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs @@ -114,25 +114,16 @@ public RelationshipEventDto() } - [DataMember(Name = "id")] public int Id { get; set; } - - public EmployeeWraper CreateBy { get; set; } - [DataMember(IsRequired = true, EmitDefaultValue = false)] public ApiDateTime Created { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Content { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public HistoryCategoryBaseDto Category { get; set; } public ContactBaseDto Contact { get; set; } public EntityDto Entity { get; set; } public bool CanEdit { get; set; } public IEnumerable> Files { get; set; } - public static RelationshipEventDto GetSample() { return new RelationshipEventDto diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs index 4d947c9defc..e9e94f5a21a 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs @@ -40,18 +40,10 @@ public TaskTemplateContainerDto() } - [DataMember(Name = "id")] public int Id { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = true)] public String Title { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = true)] public String EntityType { get; set; } - - public IEnumerable Items { get; set; } - public static TaskTemplateContainerDto GetSample() { return new TaskTemplateContainerDto @@ -74,31 +66,14 @@ public TaskTemplateDto() } - [DataMember(Name = "id")] public int Id { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public int ContainerID { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public String Title { get; set; } - - public String Description { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public EmployeeWraper Responsible { get; set; } - - [DataMember(IsRequired = true, EmitDefaultValue = false)] public TaskCategoryDto Category { get; set; } - - public bool isNotify { get; set; } - - public long OffsetTicks { get; set; } - - public bool DeadLineIsFixed { get; set; } public static TaskTemplateDto GetSample() diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index db86e473dfe..d3119dd0193 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -25,21 +25,16 @@ using System; -using System.Runtime.Serialization; using System.Text.Json.Serialization; using ASC.Common; -using ASC.Core; using ASC.Core.Common.Settings; -using ASC.CRM.Core; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace ASC.Web.CRM.Classes { - [Serializable] - [DataContract] public class SMTPServerSetting { public SMTPServerSetting() @@ -70,8 +65,6 @@ public SMTPServerSetting(ASC.Core.Configuration.SmtpSettings smtpSettings) } - [Serializable] - [DataContract] [Scope] public class InvoiceSetting { @@ -114,8 +107,6 @@ public InvoiceSetting DefaultSettings public String CompanyAddress { get; set; } } - [Serializable] - [DataContract] public class CrmSettings : ISettings { public CrmSettings() @@ -128,25 +119,25 @@ public Guid ID get { return new Guid("fdf39b9a-ec96-4eb7-aeab-63f2c608eada"); } } - [DataMember(Name = "SMTPServerSetting")] + [JsonPropertyName("SMTPServerSetting")] public SMTPServerSetting SMTPServerSettingOld { get; set; } public InvoiceSetting InvoiceSetting { get; set; } public Guid WebFormKey { get; set; } - [DataMember(Name = "DefaultCurrency")] + [JsonPropertyName("DefaultCurrency")] public String DefaultCurrency { get; set; } - [DataMember(Name = "ChangeContactStatusGroupAuto")] + [JsonPropertyName("ChangeContactStatusGroupAuto")] public string ChangeContactStatusGroupAutoDto { get; set; } - [IgnoreDataMember] + [JsonIgnore] public Boolean? ChangeContactStatusGroupAuto { get { return string.IsNullOrEmpty(ChangeContactStatusGroupAutoDto) ? null : (bool?)bool.Parse(ChangeContactStatusGroupAutoDto); } set { ChangeContactStatusGroupAutoDto = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } } - [DataMember(Name = "AddTagToContactGroupAuto")] + [JsonPropertyName("AddTagToContactGroupAuto")] public string AddTagToContactGroupAutoDto { get; set; } [JsonIgnore] @@ -156,13 +147,13 @@ public Boolean? AddTagToContactGroupAuto set { AddTagToContactGroupAutoDto = value.HasValue ? value.Value.ToString().ToLowerInvariant() : null; } } - [DataMember(Name = "WriteMailToHistoryAuto")] + [JsonPropertyName("WriteMailToHistoryAuto")] public Boolean WriteMailToHistoryAuto { get; set; } - [DataMember(Name = "IsConfiguredPortal")] + [JsonPropertyName("IsConfiguredPortal")] public bool IsConfiguredPortal { get; set; } - [DataMember(Name = "IsConfiguredSmtp")] + [JsonPropertyName("IsConfiguredSmtp")] public bool IsConfiguredSmtp { get; set; } public ISettings GetDefault(IServiceProvider serviceProvider) { @@ -186,12 +177,9 @@ public ISettings GetDefault(IServiceProvider serviceProvider) } } - - [Serializable] - [DataContract] public class CrmReportSampleSettings : ISettings { - [DataMember(Name = "NeedToGenerate")] + [JsonPropertyName("NeedToGenerate")] public bool NeedToGenerate { get; set; } public Guid ID diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index c7ee86fd0e1..64ed64c98e7 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; using System.Text.Json; @@ -585,7 +584,6 @@ public void DeleteItem(RelationshipEvent item) } - [DataContract] internal class CrmHistoryContent { public string to; @@ -618,14 +616,7 @@ private static string GetHistoryContentJson(JsonElement apiResponse) message_id = apiResponse.GetProperty("id").GetInt32() }; - var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent)); - - using (var stream = new System.IO.MemoryStream()) - { - serializer.WriteObject(stream, content_struct); - - return Encoding.UTF8.GetString(stream.ToArray()); - } + return JsonSerializer.Serialize(content_struct); } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/DomainObject.cs b/products/ASC.CRM/Server/Core/DomainObject.cs index 11f336f82b0..0778d201c7a 100644 --- a/products/ASC.CRM/Server/Core/DomainObject.cs +++ b/products/ASC.CRM/Server/Core/DomainObject.cs @@ -28,6 +28,7 @@ using System; using System.Runtime.Serialization; +using System.Text.Json.Serialization; #endregion @@ -38,7 +39,7 @@ namespace ASC.CRM.Core public class DomainObject { - [DataMember(Name = "id")] + [JsonPropertyName("id")] public virtual int ID { get; diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index 3b826e379e7..e1b9ca09deb 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -26,6 +26,7 @@ using System; using System.Runtime.Serialization; +using System.Text.Json.Serialization; using ASC.Common.Mapping; using ASC.Common.Security; @@ -45,34 +46,34 @@ public class Deal : DomainObject, ISecurityObjectId, IMapFrom public Guid? LastModifedBy { get; set; } public DateTime? LastModifedOn { get; set; } - [DataMember(Name = "contact_id")] + [JsonPropertyName("contact_id")] public int ContactID { get; set; } public Contact Contact { get; set; } public string Title { get; set; } public string Description { get; set; } - [DataMember(Name = "responsible_id")] + [JsonPropertyName("responsible_id")] public Guid ResponsibleID { get; set; } - [DataMember(Name = "bid_type")] + [JsonPropertyName("bid_type")] public BidType BidType { get; set; } - [DataMember(Name = "bid_value")] + [JsonPropertyName("bid_value")] public decimal BidValue { get; set; } - [DataMember(Name = "bid_currency")] + [JsonPropertyName("bid_currency")] public string BidCurrency { get; set; } - [DataMember(Name = "per_period_value")] + [JsonPropertyName("per_period_value")] public int PerPeriodValue { get; set; } - [DataMember(Name = "deal_milestone")] + [JsonPropertyName("deal_milestone")] public int DealMilestoneID { get; set; } - [DataMember(Name = "deal_milestone_probability")] + [JsonPropertyName("deal_milestone_probability")] public int DealMilestoneProbability { get; set; } - [DataMember(Name = "actual_close_date")] + [JsonPropertyName("actual_close_date")] public DateTime ActualCloseDate { get; set; } //[DataMember(Name = "actual_close_date")] @@ -86,7 +87,7 @@ public class Deal : DomainObject, ISecurityObjectId, IMapFrom // set { ; } //} - [DataMember(Name = "expected_close_date")] + [JsonPropertyName("expected_close_date")] public DateTime ExpectedCloseDate { get; set; } //private String ExpectedCloseDateStr diff --git a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs index e4917aff6c3..45b31c5764e 100644 --- a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs +++ b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs @@ -28,6 +28,7 @@ using System; using System.Runtime.Serialization; +using System.Text.Json.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core.EF; @@ -44,7 +45,7 @@ public class DealMilestone : DomainObject, IMapFrom public String Description { get; set; } public String Color { get; set; } - [DataMember(Name = "sort_order")] + [JsonPropertyName("sort_order")] public int SortOrder { get; set; } public int Probability { get; set; } public DealMilestoneStatus Status { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs index b888df27df6..9ec7da2e3dc 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -36,7 +36,6 @@ namespace ASC.CRM.Core.Entities { - [DataContract] public class InvoiceTax : DomainObject, ISecurityObjectId, IMapFrom { public string Name { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/ListItem.cs b/products/ASC.CRM/Server/Core/Entities/ListItem.cs index 93f9cafdc10..e85abd5decf 100644 --- a/products/ASC.CRM/Server/Core/Entities/ListItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/ListItem.cs @@ -25,6 +25,7 @@ using System.Runtime.Serialization; +using System.Text.Json.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core.EF; @@ -50,13 +51,13 @@ public ListItem(string title, string addparams) public string Description { get; set; } public string Color { get; set; } - [DataMember(Name = "sort_order")] + [JsonPropertyName("sort_order")] public int SortOrder { get; set; } - [DataMember(Name = "additional_params")] + [JsonPropertyName("additional_params")] public string AdditionalParams { get; set; } - [DataMember(Name = "list_type")] + [JsonPropertyName("list_type")] public ListType? ListType { get; set; } } } diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index e8f563586d2..7485d7c3cf7 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -34,6 +34,7 @@ using System.Runtime.Serialization; using System.Text; using System.Text.Json; +using System.Text.Json.Serialization; using System.Text.RegularExpressions; using System.Threading; @@ -654,19 +655,19 @@ public void Cancel() [DataContract] public class MailTemplateTag { - [DataMember(Name = "sysname")] + [JsonPropertyName("sysname")] public String SysName { get; set; } - [DataMember(Name = "display_name")] + [JsonPropertyName("display_name")] public String DisplayName { get; set; } - [DataMember(Name = "category")] + [JsonPropertyName("category")] public String Category { get; set; } - [DataMember(Name = "is_company")] + [JsonPropertyName("is_company")] public bool isCompany { get; set; } - [DataMember(Name = "name")] + [JsonPropertyName("name")] public String Name { get; set; } } From d7e3e7119493a7e7381951a87e7c14f318cdc991 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Mon, 31 May 2021 19:37:00 +0300 Subject: [PATCH 56/61] crm: removed DataContract attribute. --- .../Server/ApiModels/ResponsesDto/ContactDto.cs | 15 +-------------- .../ApiModels/ResponsesDto/ContactInfoDto.cs | 4 +--- .../ApiModels/ResponsesDto/CurrencyInfoDto.cs | 3 +-- .../ApiModels/ResponsesDto/CurrencyRateDto.cs | 3 +-- .../ApiModels/ResponsesDto/CustomFieldDto.cs | 4 +--- .../Server/ApiModels/ResponsesDto/InvoiceDto.cs | 4 +--- .../ApiModels/ResponsesDto/InvoiceItemDto.cs | 3 +-- .../ApiModels/ResponsesDto/InvoiceLineDto.cs | 3 +-- .../ApiModels/ResponsesDto/InvoiceStatusDto.cs | 3 +-- .../ApiModels/ResponsesDto/InvoiceTaxDto.cs | 3 +-- .../Server/ApiModels/ResponsesDto/ListItemDto.cs | 15 +-------------- .../ApiModels/ResponsesDto/OpportunityDto.cs | 3 +-- .../ResponsesDto/RelationshipEventDto.cs | 4 +--- .../Server/ApiModels/ResponsesDto/ReportDto.cs | 3 +-- .../Server/ApiModels/ResponsesDto/TaskDto.cs | 4 +--- .../ResponsesDto/TaskTemplateContainerDto.cs | 4 +--- .../Server/ApiModels/ResponsesDto/VoipCallDto.cs | 3 +-- products/ASC.CRM/Server/Core/DomainObject.cs | 4 ---- .../ASC.CRM/Server/Core/Entities/ContactInfo.cs | 2 -- .../ASC.CRM/Server/Core/Entities/CurrencyInfo.cs | 2 -- .../ASC.CRM/Server/Core/Entities/CurrencyRate.cs | 2 -- .../ASC.CRM/Server/Core/Entities/CustomField.cs | 6 ------ products/ASC.CRM/Server/Core/Entities/Deal.cs | 5 ----- .../ASC.CRM/Server/Core/Entities/DealMilestone.cs | 2 -- .../ASC.CRM/Server/Core/Entities/InvoiceItem.cs | 3 --- .../ASC.CRM/Server/Core/Entities/InvoiceTax.cs | 2 -- products/ASC.CRM/Server/Core/Entities/ListItem.cs | 2 -- products/ASC.CRM/Server/Core/Enums/ShareType.cs | 8 +------- products/ASC.CRM/Server/Utils/MailSender.cs | 4 +--- 29 files changed, 19 insertions(+), 104 deletions(-) diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs index bcfc4872e3a..ffa3dc7f065 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactDto.cs @@ -26,7 +26,7 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; + using System.Text.Json; using System.Text.Json.Serialization; @@ -42,10 +42,6 @@ namespace ASC.CRM.ApiModels { - /// - /// Person - /// - [DataContract(Name = "person", Namespace = "")] public class PersonDto : ContactDto { public String FirstName { get; set; } @@ -95,10 +91,6 @@ public PersonDto GetQuick(Person person) } } - /// - /// Company - /// - [DataContract(Name = "company", Namespace = "")] public class CompanyDto : ContactDto { public String CompanyName { get; set; } @@ -118,7 +110,6 @@ public class CompanyDto : ContactDto } } - [DataContract(Name = "contact", Namespace = "")] public class ContactDto : ContactBaseDto, IMapFrom { public ContactDto() @@ -176,13 +167,11 @@ public void Mapping(Profile profile) } } - [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithEmailDto : ContactBaseDto { public ContactInfoDto Email { get; set; } } - [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseWithPhoneDto : ContactBaseDto { public ContactInfoDto Phone { get; set; } @@ -225,7 +214,6 @@ public override void Write(Utf8JsonWriter writer, ContactDto value, JsonSerializ /// /// Contact base information /// - [DataContract(Name = "contactBase", Namespace = "")] public class ContactBaseDto { public ContactBaseDto() @@ -258,7 +246,6 @@ public static ContactBaseDto GetSample() } } - [DataContract(Name = "contact_task", Namespace = "")] public class ContactWithTaskDto { public TaskBaseDto Task { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs index 79325478384..cbe9e81833e 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs @@ -25,7 +25,7 @@ using System; -using System.Runtime.Serialization; + using System.Text.Json; using ASC.Common.Mapping; @@ -40,7 +40,6 @@ namespace ASC.CRM.ApiModels /// /// Address /// - [DataContract(Name = "address", Namespace = "")] public class Address { public Address() @@ -114,7 +113,6 @@ public static Address GetSample() /// /// Contact information /// - [DataContract(Name = "commonDataItem", Namespace = "")] public class ContactInfoDto : IMapFrom { public ContactInfoDto() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs index 848e79abfa7..c1f78578684 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs @@ -26,6 +26,7 @@ using System; + using ASC.Common.Mapping; using ASC.CRM.Core; using ASC.CRM.Mapping; @@ -37,7 +38,6 @@ namespace ASC.CRM.ApiModels /// /// Currency information /// - [DataContract(Name = "currencyInfo", Namespace = "")] public class CurrencyInfoDto : IMapFrom { public CurrencyInfoDto() @@ -73,7 +73,6 @@ public void Mapping(Profile profile) /// /// Currency rate information /// - [DataContract(Name = "currencyRateInfo", Namespace = "")] public class CurrencyRateInfoDto : CurrencyInfoDto, IMapFrom { public CurrencyRateInfoDto() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs index 2ecc16c231b..5c7c0fca3a6 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs @@ -25,7 +25,7 @@ using System; -using System.Runtime.Serialization; + using ASC.Common.Mapping; using ASC.CRM.Core; @@ -38,7 +38,6 @@ namespace ASC.CRM.ApiModels /// /// Currency rate /// - [DataContract(Name = "currencyRate", Namespace = "")] public class CurrencyRateDto : IMapFrom { public CurrencyRateDto() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs index ac76722fb5b..38c43b5c16e 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CustomFieldDto.cs @@ -25,7 +25,7 @@ using System; -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Common.Mapping; @@ -37,7 +37,6 @@ namespace ASC.CRM.ApiModels { - [DataContract(Name = "customField", Namespace = "")] public class CustomFieldDto : CustomFieldBaseDto, IMapFrom { public CustomFieldDto() @@ -71,7 +70,6 @@ public void Mapping(Profile profile) /// /// User custom fields /// - [DataContract(Name = "customField", Namespace = "")] public class CustomFieldBaseDto : IMapFrom { public CustomFieldBaseDto() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs index dcc9ddcfb58..f8c9a029835 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceDto.cs @@ -24,7 +24,7 @@ */ using System.Collections.Generic; -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Common.Mapping; @@ -40,7 +40,6 @@ namespace ASC.CRM.ApiModels /// /// Invoice /// - [DataContract(Name = "invoiceBase", Namespace = "")] public class InvoiceBaseDto : IMapFrom { public int Id { get; set; } @@ -74,7 +73,6 @@ public void Mapping(Profile profile) /// /// Invoice /// - [DataContract(Name = "invoice", Namespace = "")] public class InvoiceDto : InvoiceBaseDto { public List InvoiceLines { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs index a642490862c..fadf9a6fcba 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceItemDto.cs @@ -23,7 +23,7 @@ * */ -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Common.Mapping; @@ -38,7 +38,6 @@ namespace ASC.CRM.ApiModels /// /// Invoice Item /// - [DataContract(Name = "invoiceItem", Namespace = "")] public class InvoiceItemDto : IMapFrom { public string Title { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs index 3042b453f39..1da616a9286 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs @@ -23,7 +23,7 @@ * */ -using System.Runtime.Serialization; + using ASC.Common.Mapping; using ASC.CRM.Core.Entities; @@ -34,7 +34,6 @@ namespace ASC.CRM.ApiModels /// /// Invoice Line /// - [DataContract(Name = "invoiceLine", Namespace = "")] public class InvoiceLineDto : IMapFrom { public int Id { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs index 0feeb230c3f..ee0a0928ba1 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs @@ -23,7 +23,7 @@ * */ -using System.Runtime.Serialization; + using ASC.Common.Mapping; using ASC.CRM.Classes; @@ -37,7 +37,6 @@ namespace ASC.CRM.ApiModels /// /// Invoice Status /// - [DataContract(Name = "invoiceStatus", Namespace = "")] public class InvoiceStatusDto : IMapFrom { public int Id { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs index 03f44a18200..c76812501b6 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceTaxDto.cs @@ -23,7 +23,7 @@ * */ -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Common.Mapping; @@ -51,7 +51,6 @@ namespace ASC.CRM.ApiModels /// /// Invoice Tax /// - [DataContract(Name = "invoiceTax", Namespace = "")] public class InvoiceTaxDto : IMapFrom { public int Id { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index c7fbc9c41ba..08e886254ef 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -25,7 +25,7 @@ using System; -using System.Runtime.Serialization; + using ASC.Common.Mapping; using ASC.CRM.Core.Entities; @@ -38,8 +38,6 @@ namespace ASC.CRM.ApiModels { #region History Category - - [DataContract(Name = "historyCategoryBase", Namespace = "")] public class HistoryCategoryBaseDto : ListItemDto { public HistoryCategoryBaseDto() @@ -67,7 +65,6 @@ public static HistoryCategoryBaseDto GetSample() } } - [DataContract(Name = "historyCategory", Namespace = "")] public class HistoryCategoryDto : HistoryCategoryBaseDto { public HistoryCategoryDto() @@ -100,7 +97,6 @@ public HistoryCategoryDto(ListItem listItem) #region Deal Milestone - [DataContract(Name = "opportunityStagesBase", Namespace = "")] public class DealMilestoneBaseDto : ListItemDto { public DealMilestoneBaseDto() @@ -132,7 +128,6 @@ public static DealMilestoneBaseDto GetSample() } } - [DataContract(Name = "opportunityStages", Namespace = "")] public class DealMilestoneDto : DealMilestoneBaseDto, IMapFrom { public DealMilestoneDto() @@ -169,7 +164,6 @@ public override void Mapping(Profile profile) #region Task Category - [DataContract(Name = "taskCategoryBase", Namespace = "")] public class TaskCategoryBaseDto : ListItemDto { public TaskCategoryBaseDto() @@ -198,7 +192,6 @@ public static TaskCategoryBaseDto GetSample() } - [DataContract(Name = "taskCategory", Namespace = "")] public class TaskCategoryDto : TaskCategoryBaseDto { public TaskCategoryDto() @@ -237,7 +230,6 @@ public TaskCategoryDto(ListItem listItem) : base(listItem) #region Contact Status - [DataContract(Name = "contactStatusBase", Namespace = "")] public class ContactStatusBaseDto : ListItemDto { public ContactStatusBaseDto() @@ -260,7 +252,6 @@ public static ContactStatusBaseDto GetSample() } } - [DataContract(Name = "contactStatus", Namespace = "")] public class ContactStatusDto : ContactStatusBaseDto { public ContactStatusDto() @@ -291,7 +282,6 @@ public ContactStatusDto(ListItem listItem) #region Contact Type - [DataContract(Name = "contactTypeBase", Namespace = "")] public class ContactTypeBaseDto : ListItemDto { public ContactTypeBaseDto() @@ -316,7 +306,6 @@ public static ContactTypeBaseDto GetSample() } } - [DataContract(Name = "contactType", Namespace = "")] public class ContactTypeDto : ContactTypeBaseDto { public ContactTypeDto() @@ -348,7 +337,6 @@ public ContactTypeDto(ListItem listItem) #region Tags - [DataContract(Name = "tagDto", Namespace = "")] public class TagDto { public TagDto() @@ -377,7 +365,6 @@ public static TagDto GetSample() #endregion - [DataContract(Name = "listItem", Namespace = "")] public class ListItemDto : IMapFrom { public ListItemDto() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs index 8bffa81f87a..f04d8c47f18 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/OpportunityDto.cs @@ -26,7 +26,7 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Common.Mapping; @@ -42,7 +42,6 @@ namespace ASC.CRM.ApiModels /// /// Opportunity /// - [DataContract(Name = "opportunity", Namespace = "")] public class OpportunityDto : IMapFrom { diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs index e21e4af1ca0..1e141834600 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/RelationshipEventDto.cs @@ -26,7 +26,7 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Api.Documents; @@ -42,7 +42,6 @@ namespace ASC.CRM.ApiModels { - [DataContract(Name = "entity", Namespace = "")] public class EntityDto { public String EntityType { get; set; } @@ -106,7 +105,6 @@ public EntityDto Get(EntityType entityType, int entityID) } } - [DataContract(Name = "historyEvent", Namespace = "")] public class RelationshipEventDto : IMapFrom { public RelationshipEventDto() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs index 4ff6bb84378..1c51a46274d 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ReportDto.cs @@ -26,11 +26,10 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; + namespace ASC.CRM.ApiModels { - [DataContract] public class ReportDto { public String ReportTitle { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs index f82b3457735..0d9dde56c2d 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskDto.cs @@ -25,7 +25,7 @@ using System; -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.Common.Mapping; @@ -40,7 +40,6 @@ namespace ASC.CRM.ApiModels /// /// Task /// - [DataContract(Name = "task", Namespace = "")] public class TaskDto : IMapFrom { public int Id { get; set; } @@ -77,7 +76,6 @@ public void Mapping(Profile profile) } } - [DataContract(Name = "taskBase", Namespace = "")] public class TaskBaseDto { public int Id { get; set; } diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs index e9e94f5a21a..c1b8dd6080c 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/TaskTemplateContainerDto.cs @@ -26,13 +26,12 @@ using System; using System.Collections.Generic; -using System.Runtime.Serialization; + using ASC.Web.Api.Models; namespace ASC.CRM.ApiModels { - [DataContract(Namespace = "taskTemplateContainer")] public class TaskTemplateContainerDto { public TaskTemplateContainerDto() @@ -58,7 +57,6 @@ public static TaskTemplateContainerDto GetSample() } } - [DataContract(Namespace = "taskTemplate")] public class TaskTemplateDto { public TaskTemplateDto() diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs index 287acd47059..b112a219fce 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs @@ -25,7 +25,7 @@ using System.Collections.Generic; -using System.Runtime.Serialization; + using ASC.Api.Core; using ASC.VoipService; @@ -33,7 +33,6 @@ namespace ASC.CRM.ApiModels { - [DataContract(Name = "voipCall", Namespace = "")] public class VoipCallDto { public string Id { get; set; } diff --git a/products/ASC.CRM/Server/Core/DomainObject.cs b/products/ASC.CRM/Server/Core/DomainObject.cs index 0778d201c7a..7dccd101317 100644 --- a/products/ASC.CRM/Server/Core/DomainObject.cs +++ b/products/ASC.CRM/Server/Core/DomainObject.cs @@ -26,16 +26,12 @@ #region Import -using System; -using System.Runtime.Serialization; using System.Text.Json.Serialization; #endregion namespace ASC.CRM.Core { - [DataContract] - [Serializable] public class DomainObject { diff --git a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs index 5c2c17d7f37..9e20e630d55 100644 --- a/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/ContactInfo.cs @@ -25,13 +25,11 @@ using System; -using System.Runtime.Serialization; using ASC.Common.Mapping; using ASC.CRM.Classes; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; namespace ASC.CRM.Core { diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index 3b302b4ec7e..e61da8b80c0 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -25,11 +25,9 @@ using System; -using System.Runtime.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core.EF; -using ASC.CRM.Mapping; using ASC.CRM.Resources; using AutoMapper; diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs index 45cbf26eb3e..65927c35443 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyRate.cs @@ -25,11 +25,9 @@ using System; -using System.Runtime.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core.EF; -using ASC.CRM.Mapping; namespace ASC.CRM.Core { diff --git a/products/ASC.CRM/Server/Core/Entities/CustomField.cs b/products/ASC.CRM/Server/Core/Entities/CustomField.cs index aba5e6b45b6..07170bc34ac 100644 --- a/products/ASC.CRM/Server/Core/Entities/CustomField.cs +++ b/products/ASC.CRM/Server/Core/Entities/CustomField.cs @@ -27,16 +27,10 @@ #region Import using System; -using System.Runtime.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; - -using AutoMapper; - -using DocuSign.eSign.Model; #endregion diff --git a/products/ASC.CRM/Server/Core/Entities/Deal.cs b/products/ASC.CRM/Server/Core/Entities/Deal.cs index e1b9ca09deb..e48f87a4745 100644 --- a/products/ASC.CRM/Server/Core/Entities/Deal.cs +++ b/products/ASC.CRM/Server/Core/Entities/Deal.cs @@ -25,20 +25,15 @@ using System; -using System.Runtime.Serialization; using System.Text.Json.Serialization; using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; - -using AutoMapper; namespace ASC.CRM.Core.Entities { - [DataContract] public class Deal : DomainObject, ISecurityObjectId, IMapFrom { public Guid CreateBy { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs index 45b31c5764e..8a1abcd7e79 100644 --- a/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs +++ b/products/ASC.CRM/Server/Core/Entities/DealMilestone.cs @@ -27,13 +27,11 @@ #region Import using System; -using System.Runtime.Serialization; using System.Text.Json.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; #endregion diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs index 96409c05569..e473b11afb7 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceItem.cs @@ -25,16 +25,13 @@ using System; -using System.Runtime.Serialization; using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; -using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { - [DataContract] public class InvoiceItem : DomainObject, ISecurityObjectId, IMapFrom { public string Title { get; set; } diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs index 9ec7da2e3dc..65267f9c4d0 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceTax.cs @@ -25,12 +25,10 @@ using System; -using System.Runtime.Serialization; using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; -using ASC.CRM.Mapping; using AutoMapper; diff --git a/products/ASC.CRM/Server/Core/Entities/ListItem.cs b/products/ASC.CRM/Server/Core/Entities/ListItem.cs index e85abd5decf..89d0cc999ff 100644 --- a/products/ASC.CRM/Server/Core/Entities/ListItem.cs +++ b/products/ASC.CRM/Server/Core/Entities/ListItem.cs @@ -24,13 +24,11 @@ */ -using System.Runtime.Serialization; using System.Text.Json.Serialization; using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { diff --git a/products/ASC.CRM/Server/Core/Enums/ShareType.cs b/products/ASC.CRM/Server/Core/Enums/ShareType.cs index 2b6bb9fcb61..e3e12977b63 100644 --- a/products/ASC.CRM/Server/Core/Enums/ShareType.cs +++ b/products/ASC.CRM/Server/Core/Enums/ShareType.cs @@ -24,20 +24,14 @@ */ -using System.Runtime.Serialization; + namespace ASC.CRM.Core.Enums { - [DataContract(Name = "contactShare", Namespace = "")] public enum ShareType { - [EnumMember(Value = "0")] None, - - [EnumMember(Value = "1")] ReadWrite, - - [EnumMember(Value = "2")] Read } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index 7485d7c3cf7..d315f164b8e 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -31,7 +31,7 @@ using System.IO; using System.Linq; using System.Net.Sockets; -using System.Runtime.Serialization; + using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -651,8 +651,6 @@ public void Cancel() } } - [Serializable] - [DataContract] public class MailTemplateTag { [JsonPropertyName("sysname")] From e75e048e49e869c2ed7f3ca72a2d70f7537c15cd Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Wed, 2 Jun 2021 18:24:49 +0300 Subject: [PATCH 57/61] crm: fixed build --- products/ASC.CRM/Server/ASC.CRM.csproj | 2 +- .../ASC.CRM/Server/Api/TasksController.cs | 5 +- .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 130 +++++++++--------- products/ASC.CRM/Server/Core/EF/DbCase.cs | 15 +- products/ASC.CRM/Server/Core/EF/DbContact.cs | 29 ++-- .../ASC.CRM/Server/Core/EF/DbContactInfo.cs | 13 +- products/ASC.CRM/Server/Core/EF/DbDeal.cs | 21 ++- .../ASC.CRM/Server/Core/EF/DbFieldValue.cs | 13 +- products/ASC.CRM/Server/Core/EF/DbInvoice.cs | 9 +- .../Server/Core/EF/DbRelationshipEvent.cs | 15 +- products/ASC.CRM/Server/Core/EF/DbTask.cs | 19 ++- .../Server/Core/Search/FactoryIndexerCase.cs | 57 ++++++-- .../Core/Search/FactoryIndexerContact.cs | 55 ++++++-- .../Core/Search/FactoryIndexerContactInfo.cs | 54 ++++++-- .../Server/Core/Search/FactoryIndexerDeal.cs | 54 ++++++-- .../Core/Search/FactoryIndexerEvents.cs | 54 ++++++-- .../Core/Search/FactoryIndexerFieldValue.cs | 55 ++++++-- .../Core/Search/FactoryIndexerInvoice.cs | 55 ++++++-- .../Server/Core/Search/FactoryIndexerTask.cs | 55 ++++++-- products/ASC.CRM/Server/Program.cs | 28 ++++ products/ASC.CRM/Server/Utils/ExportToCSV.cs | 9 +- products/ASC.CRM/Server/Utils/PdfCreator.cs | 6 +- 22 files changed, 520 insertions(+), 233 deletions(-) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 3f15b238a66..2bd3bcdd034 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -42,7 +42,7 @@ - + diff --git a/products/ASC.CRM/Server/Api/TasksController.cs b/products/ASC.CRM/Server/Api/TasksController.cs index 66526646d30..a957c6aaa62 100644 --- a/products/ASC.CRM/Server/Api/TasksController.cs +++ b/products/ASC.CRM/Server/Api/TasksController.cs @@ -13,6 +13,7 @@ using ASC.CRM.Resources; using ASC.MessagingSystem; using ASC.Web.Api.Routing; +using ASC.Web.CRM.Core.Search; using ASC.Web.CRM.Services.NotifyService; using AutoMapper; @@ -34,7 +35,8 @@ public TasksController(CrmSecurity crmSecurity, MessageTarget messageTarget, MessageService messageService, NotifyClient notifyClient, - IMapper mapper) + IMapper mapper, + FactoryIndexerCase factoryIndexerCase) : base(daoFactory, crmSecurity, mapper) { _apiContext = apiContext; @@ -59,6 +61,7 @@ public TaskDto GetTaskByID(int taskid) if (taskid <= 0) throw new ArgumentException(); var task = _daoFactory.GetTaskDao().GetByID(taskid); + if (task == null) throw new ItemNotFoundException(); if (!_crmSecurity.CanAccessTo(task)) diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index 0d09c75d7ca..c1230d232f5 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -35,6 +35,7 @@ public partial class CrmDbContext : BaseDbContext public virtual DbSet TaskTemplateTask { get; set; } public virtual DbSet VoipCalls { get; set; } public virtual DbSet VoipNumber { get; set; } + public virtual DbSet Tenants { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -45,12 +46,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .AddDbCase() .AddDbRelationshipEvent() .AddDbDeal() - .AddDbTask(); - - - - - + .AddDbTask() + .AddDbTenant(); + modelBuilder.Entity(entity => { entity.HasKey(e => e.Abbreviation) @@ -58,19 +56,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Abbreviation) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.CultureName) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.ResourceKey) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Symbol) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -83,19 +81,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.FromCurrency) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.ToCurrency) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); ; @@ -108,15 +106,15 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Color) .HasDefaultValueSql("'0'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -144,11 +142,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Label) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Mask) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); @@ -163,15 +161,15 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Currency) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.ExchangeRate).HasDefaultValueSql("'1.00'"); @@ -179,29 +177,29 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.JsonData) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Language) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Number) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.PurchaseOrderNumber) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Status).HasDefaultValueSql("'1'"); entity.Property(e => e.Terms) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -211,27 +209,27 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Currency) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.StockKeepingUnit) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -241,7 +239,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -251,19 +249,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Name) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -273,19 +271,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.AdditionalParams) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Color) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -295,11 +293,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Content) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -331,7 +329,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -341,7 +339,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_bin"); + .UseCollation("utf8_bin"); }); @@ -353,25 +351,25 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.ResponsibleId) .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -382,16 +380,16 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasDefaultValueSql("'0'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasDefaultValueSql("'0'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -410,32 +408,32 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Id) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.AnsweredBy) .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.NumberFrom) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.NumberTo) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.ParentCallId) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.RecordSid) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.RecordUrl) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); modelBuilder.Entity(entity => @@ -445,19 +443,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.Id) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Alias) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Number) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Settings) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); OnModelCreatingPartial(modelBuilder); diff --git a/products/ASC.CRM/Server/Core/EF/DbCase.cs b/products/ASC.CRM/Server/Core/EF/DbCase.cs index f5be96586a3..813a2fad149 100644 --- a/products/ASC.CRM/Server/Core/EF/DbCase.cs +++ b/products/ASC.CRM/Server/Core/EF/DbCase.cs @@ -6,6 +6,7 @@ using ASC.Core.Common.EF; using ASC.Core.Common.EF.Model; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Microsoft.EntityFrameworkCore; @@ -51,13 +52,9 @@ public string IndexName } } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Title }; - } + return (a) => new[] { Title }; } } @@ -85,15 +82,15 @@ private static void MySqlAddDbCase(this ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); } } diff --git a/products/ASC.CRM/Server/Core/EF/DbContact.cs b/products/ASC.CRM/Server/Core/EF/DbContact.cs index 7da0184da78..6a35bf18d9e 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContact.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContact.cs @@ -7,6 +7,7 @@ using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Microsoft.EntityFrameworkCore; @@ -84,13 +85,9 @@ public string IndexName } } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Title }; - } + return (a) => new[] { Title }; } } @@ -123,43 +120,43 @@ private static void MySqlAddDbContact(this ModelBuilder modelBuilder) entity.Property(e => e.CompanyName) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Currency) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.DisplayName) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.FirstName) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Industry) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastName) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Notes) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); } diff --git a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs index c9934313d53..6cdf3e138c4 100644 --- a/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs +++ b/products/ASC.CRM/Server/Core/EF/DbContactInfo.cs @@ -7,6 +7,7 @@ using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Microsoft.EntityFrameworkCore; @@ -55,13 +56,9 @@ public string IndexName } } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Data }; - } + return (a) => new[] { Data }; } } @@ -87,11 +84,11 @@ private static void MySqlAddDbContactInfo(this ModelBuilder modelBuilder) entity.Property(e => e.Data) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); } } diff --git a/products/ASC.CRM/Server/Core/EF/DbDeal.cs b/products/ASC.CRM/Server/Core/EF/DbDeal.cs index ae566dae4ae..c2cac665c9a 100644 --- a/products/ASC.CRM/Server/Core/EF/DbDeal.cs +++ b/products/ASC.CRM/Server/Core/EF/DbDeal.cs @@ -31,6 +31,7 @@ using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Microsoft.EntityFrameworkCore; @@ -105,13 +106,9 @@ public string IndexName } } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Title, Description }; - } + return (a) => new[] { Title, Description }; } } @@ -134,15 +131,15 @@ private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.ResponsibleId) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.HasIndex(e => new { e.TenantId, e.ContactId }) .HasDatabaseName("contact_id"); @@ -152,11 +149,11 @@ private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.BidCurrency) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.HasIndex(e => e.LastModifedOn) .HasDatabaseName("last_modifed_on"); @@ -166,7 +163,7 @@ private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); } diff --git a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs index 0156b60474d..c9af6b6fa76 100644 --- a/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs +++ b/products/ASC.CRM/Server/Core/EF/DbFieldValue.cs @@ -6,6 +6,7 @@ using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Microsoft.EntityFrameworkCore; @@ -50,13 +51,9 @@ public string IndexName } } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Value }; - } + return (a) => new[] { Value }; } } @@ -86,11 +83,11 @@ private static void MySqlAddDbDeal(this ModelBuilder modelBuilder) entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Value) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); } diff --git a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs index 47288e573bd..9505c5a7869 100644 --- a/products/ASC.CRM/Server/Core/EF/DbInvoice.cs +++ b/products/ASC.CRM/Server/Core/EF/DbInvoice.cs @@ -5,6 +5,7 @@ using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Nest; @@ -98,13 +99,9 @@ public string IndexName } } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Description }; - } + return (a) => new[] { Description }; } } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs index b02aa04c090..82195e71bd8 100644 --- a/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/EF/DbRelationshipEvent.cs @@ -7,6 +7,7 @@ using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Microsoft.EntityFrameworkCore; @@ -67,13 +68,9 @@ public string IndexName } } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Content }; - } + return (a) => new[] { Content }; } } @@ -105,15 +102,15 @@ private static void MySqlAddDbRelationshipEvent(this ModelBuilder modelBuilder) entity.Property(e => e.Content) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); } diff --git a/products/ASC.CRM/Server/Core/EF/DbTask.cs b/products/ASC.CRM/Server/Core/EF/DbTask.cs index a891888fb84..58ea383b4ed 100644 --- a/products/ASC.CRM/Server/Core/EF/DbTask.cs +++ b/products/ASC.CRM/Server/Core/EF/DbTask.cs @@ -7,6 +7,7 @@ using ASC.Core.Common.EF.Model; using ASC.CRM.Core.Enums; using ASC.ElasticSearch; +using ASC.ElasticSearch.Core; using Microsoft.EntityFrameworkCore; @@ -78,13 +79,9 @@ public string IndexName get => "crm_task"; } - [Ignore] - public Expression> SearchContentFields + public Expression> GetSearchContentFields(SearchSettingsHelper searchSettings) { - get - { - return (a) => new[] { Title, Description }; - } + return (a) => new[] { Title, Description }; } } @@ -126,24 +123,24 @@ public static void MySqlAddDbTask(this ModelBuilder modelBuilder) entity.Property(e => e.CreateBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Description) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.LastModifedBy) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.ResponsibleId) .HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'") .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); entity.Property(e => e.Title) .HasCharSet("utf8") - .HasCollation("utf8_general_ci"); + .UseCollation("utf8_general_ci"); }); } } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs index 0e5ab011b00..e9421d1f767 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs @@ -36,7 +36,9 @@ using ASC.CRM.Core.EF; using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using ASC.Web.Files.Core.Search; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -62,30 +64,64 @@ public FactoryIndexerCase( public override void IndexAll() { - var casesDao = DaoFactory.GetCasesDao(); + var entityDao = DaoFactory.GetCasesDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.Cases + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = casesDao.CrmDbContext.Cases - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - casesDao.CrmDbContext.Cases - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } + try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } @@ -93,6 +129,7 @@ List getData(long i, long step, DateTime lastIndexed) => catch (Exception e) { Logger.Error(e); + throw; } } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs index fada7227b39..84961f456e8 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs @@ -32,11 +32,13 @@ using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; +using ASC.CRM.ApiModels; using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -62,30 +64,63 @@ public FactoryIndexerContact( public override void IndexAll() { - var contactDao = DaoFactory.GetContactDao(); + var entityDao = DaoFactory.GetContactDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.Contacts + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = contactDao.CrmDbContext.Contacts - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - contactDao.CrmDbContext.Contacts - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs index 56026e851b3..569494840e2 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContactInfo.cs @@ -37,6 +37,7 @@ using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -62,30 +63,63 @@ public FactoryIndexerContactInfo( public override void IndexAll() { - var contactInfoDao = DaoFactory.GetContactInfoDao(); + var entityDao = DaoFactory.GetContactInfoDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.ContactsInfo + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = contactInfoDao.CrmDbContext.ContactsInfo - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - contactInfoDao.CrmDbContext.ContactsInfo - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs index a8a7044bf3e..a891a61665b 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerDeal.cs @@ -11,6 +11,7 @@ using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -36,30 +37,63 @@ public FactoryIndexerDeal( public override void IndexAll() { - var dealDao = DaoFactory.GetDealDao(); + var entityDao = DaoFactory.GetDealDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.Deals + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = dealDao.CrmDbContext.ContactsInfo - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - dealDao.CrmDbContext.Deals - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs index 761496dedf3..3a3352a4ff5 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerEvents.cs @@ -36,6 +36,7 @@ using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -61,30 +62,63 @@ public FactoryIndexerEvents( public override void IndexAll() { - var eventsDao = DaoFactory.GetRelationshipEventDao(); + var entityDao = DaoFactory.GetRelationshipEventDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.RelationshipEvent + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = eventsDao.CrmDbContext.RelationshipEvent - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - eventsDao.CrmDbContext.RelationshipEvent - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs index b5134374b92..abab0749690 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerFieldValue.cs @@ -37,6 +37,7 @@ using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -62,30 +63,64 @@ public FactoryIndexerFieldValue( public override void IndexAll() { - var fieldValueDao = DaoFactory.GetCustomFieldDao(); + var entityDao = DaoFactory.GetCustomFieldDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.FieldValue + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = fieldValueDao.CrmDbContext.FieldValue - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - fieldValueDao.CrmDbContext.FieldValue - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } + try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs index 6f961fe288f..0170f1848f7 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerInvoice.cs @@ -37,6 +37,7 @@ using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -62,30 +63,64 @@ public FactoryIndexerInvoice( public override void IndexAll() { - var invoiceDao = DaoFactory.GetInvoiceDao(); + var entityDao = DaoFactory.GetInvoiceDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.Invoices + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = invoiceDao.CrmDbContext.Invoices - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - invoiceDao.CrmDbContext.Invoices - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } + try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs index 97d8d2c08d9..f9ccb649810 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerTask.cs @@ -37,6 +37,7 @@ using ASC.ElasticSearch; using ASC.ElasticSearch.Core; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Core.Search @@ -62,30 +63,64 @@ public FactoryIndexerTask( public override void IndexAll() { - var taskDao = DaoFactory.GetTaskDao(); + var entityDao = DaoFactory.GetTaskDao(); + + IQueryable GetBaseQuery(DateTime lastIndexed) => + entityDao.CrmDbContext.Tasks + .Where(r => r.LastModifedOn >= lastIndexed) + .Join(entityDao.CrmDbContext.Tenants, r => r.TenantId, r => r.Id, (f, t) => new { DbEntity = f, DbTenant = t }) + .Where(r => r.DbTenant.Status == ASC.Core.Tenants.TenantStatus.Active) + .Select(r => r.DbEntity); (int, int, int) getCount(DateTime lastIndexed) { - var q = taskDao.CrmDbContext.Tasks - .Where(r => r.LastModifedOn >= lastIndexed); + var q = GetBaseQuery(lastIndexed); - var count = q.GroupBy(a => a.Id).Count(); + var count = q.Count(); var min = count > 0 ? q.Min(r => r.Id) : 0; var max = count > 0 ? q.Max(r => r.Id) : 0; return (count, max, min); } - List getData(long i, long step, DateTime lastIndexed) => - taskDao.CrmDbContext.Tasks - .Where(r => r.LastModifedOn >= lastIndexed) - .Where(r => r.Id >= i && r.Id <= i + step) - .Select(r => r) + List getData(long start, long stop, DateTime lastIndexed) => + GetBaseQuery(lastIndexed) + .Where(r => r.Id >= start && r.Id <= stop) .ToList(); + List getIds(DateTime lastIndexed) + { + long start = 0; + + var result = new List(); + + while (true) + { + var id = GetBaseQuery(lastIndexed) + .AsNoTracking() + .Where(r => r.Id >= start) + .OrderBy(x => x.Id) + .Skip(BaseIndexer.QueryLimit) + .Select(x => x.Id) + .FirstOrDefault(); + + if (id != 0) + { + start = id; + result.Add(id); + } + else + { + break; + } + } + + return result; + } + try { - foreach (var data in Indexer.IndexAll(getCount, getData)) + foreach (var data in Indexer.IndexAll(getCount, getIds, getData)) { Index(data); } diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index ff40afee444..6c40570fbd6 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -3,14 +3,19 @@ using System.IO; using System.Runtime.InteropServices; +using ASC.Common.Caching; +using ASC.Common; using ASC.Common.DependencyInjection; +using ASC.Common.Logging; using ASC.Common.Utils; +using ASC.Web.Files.Core.Search; using Autofac; using Autofac.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace ASC.CRM @@ -75,6 +80,29 @@ public static IHostBuilder CreateHostBuilder(string[] args) => {"pathToConf", path} }); }) + .ConfigureServices((hostContext, services) => + { + services.AddMemoryCache(); + + var diHelper = new DIHelper(services); + + diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>)); + + diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath); + //services.AddHostedService(); + //diHelper.TryAdd(); + + //services.AddHostedService(); + //diHelper.TryAdd(); + + //services.AddHostedService(); + //diHelper.TryAdd(); + + LogNLogExtension.ConfigureLog(diHelper, "ASC.Files", "ASC.Feed.Agregator"); + //diHelper.TryAdd(); + diHelper.TryAdd(); + diHelper.TryAdd(); + }) .ConfigureContainer((context, builder) => { builder.Register(context.Configuration, true, false); diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 6ee1ab74f92..16e9edb20fc 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -83,6 +83,7 @@ public class ExportDataOperation : DistributedTaskProgress, IProgressItem private readonly IAccount _author; private readonly IDataStore _dataStore; private readonly NotifyClient _notifyClient; + private readonly TempStream _tempStream; private FilterObject _filterObject; private readonly ILog _log; private int _totalCount; @@ -101,14 +102,16 @@ public ExportDataOperation(UserManager userManager, FileMarker fileMarker, IDaoFactory fileDaoFactory, FilesLinkUtility filesLinkUtility, - DisplayUserSettingsHelper displayUserSettingsHelper) + DisplayUserSettingsHelper displayUserSettingsHelper, + TempStream tempStream) { _daoFactory = daoFactory; _userManager = userManager; _fileUtility = fileUtility; _fileUploader = fileUploader; - + _tenantManager = tenantManager; _tenantId = tenantManager.GetCurrentTenant().TenantId; + _tempStream = tempStream; _author = securityContext.CurrentAccount; _dataStore = global.GetStore(); @@ -249,7 +252,7 @@ private void Complete(double percentage, DistributedTaskStatus status, object er private void ExportAllData(DaoFactory daoFactory) { - using (var stream = TempStream.Create()) + using (var stream = _tempStream.Create()) { var contactDao = daoFactory.GetContactDao(); var contactInfoDao = daoFactory.GetContactInfoDao(); diff --git a/products/ASC.CRM/Server/Utils/PdfCreator.cs b/products/ASC.CRM/Server/Utils/PdfCreator.cs index e19f6a6899d..639716f077e 100644 --- a/products/ASC.CRM/Server/Utils/PdfCreator.cs +++ b/products/ASC.CRM/Server/Utils/PdfCreator.cs @@ -188,7 +188,7 @@ private string GetUrlToFile(Stream docxStream) string urlToFile; - _documentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, false, out urlToFile); + _documentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, null, null, false, out urlToFile); _logger.DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); @@ -208,7 +208,7 @@ public ConverterData StartCreationFileAsync(Invoice data) string urlToFile; - _documentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, true, out urlToFile); + _documentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, null, null, true, out urlToFile); return new ConverterData { @@ -228,7 +228,7 @@ public File GetConvertedFile(ConverterData data, DaoFactory daoFactory) string urlToFile; - _documentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, true, out urlToFile); + _documentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, null, null, true, out urlToFile); if (string.IsNullOrEmpty(urlToFile)) { From c04dc44e367357f13aa61c44ffdc69550512cdc4 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Thu, 3 Jun 2021 15:51:29 +0300 Subject: [PATCH 58/61] crm: refacroting --- products/ASC.CRM/Server/ASC.CRM.csproj | 7 --- .../Server/Core/Search/BundleSearch.cs | 54 +++++++++---------- .../Core/Security/FileSecurityProvider.cs | 29 +++++----- products/ASC.CRM/Server/Program.cs | 23 -------- products/ASC.CRM/Server/Startup.cs | 12 ++++- 5 files changed, 51 insertions(+), 74 deletions(-) diff --git a/products/ASC.CRM/Server/ASC.CRM.csproj b/products/ASC.CRM/Server/ASC.CRM.csproj index 2bd3bcdd034..af1f4be2857 100644 --- a/products/ASC.CRM/Server/ASC.CRM.csproj +++ b/products/ASC.CRM/Server/ASC.CRM.csproj @@ -33,8 +33,6 @@ - - all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -43,14 +41,9 @@ - - - - - diff --git a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs index 8f2608dc7bc..648e6893e6b 100644 --- a/products/ASC.CRM/Server/Core/Search/BundleSearch.cs +++ b/products/ASC.CRM/Server/Core/Search/BundleSearch.cs @@ -35,6 +35,15 @@ namespace ASC.Web.CRM.Core.Search [Scope] public class BundleSearch { + private readonly FactoryIndexerContact _factoryIndexerContact; + private readonly FactoryIndexerContactInfo _factoryIndexerContactInfo; + private readonly FactoryIndexerFieldValue _factoryIndexerFieldValue; + private readonly FactoryIndexerEvents _factoryIndexerEvents; + private readonly FactoryIndexerDeal _factoryIndexerDeal; + private readonly FactoryIndexerTask _factoryIndexerTask; + private readonly FactoryIndexerCase _factoryIndexerCase; + private readonly FactoryIndexerInvoice _factoryIndexerInvoice; + public BundleSearch(FactoryIndexerContact factoryIndexerContact, FactoryIndexerContactInfo factoryIndexerContactInfo, FactoryIndexerFieldValue factoryIndexerFieldValue, @@ -44,25 +53,16 @@ public BundleSearch(FactoryIndexerContact factoryIndexerContact, FactoryIndexerCase factoryIndexerCase, FactoryIndexerInvoice factoryIndexerInvoice) { - FactoryIndexerContact = factoryIndexerContact; - FactoryIndexerContactInfo = factoryIndexerContactInfo; - FactoryIndexerFieldValue = factoryIndexerFieldValue; - FactoryIndexerEvents = factoryIndexerEvents; - FactoryIndexerDeal = factoryIndexerDeal; - FactoryIndexerTask = factoryIndexerTask; - FactoryIndexerCase = factoryIndexerCase; - FactoryIndexerInvoice = factoryIndexerInvoice; + _factoryIndexerContact = factoryIndexerContact; + _factoryIndexerContactInfo = factoryIndexerContactInfo; + _factoryIndexerFieldValue = factoryIndexerFieldValue; + _factoryIndexerEvents = factoryIndexerEvents; + _factoryIndexerDeal = factoryIndexerDeal; + _factoryIndexerTask = factoryIndexerTask; + _factoryIndexerCase = factoryIndexerCase; + _factoryIndexerInvoice = factoryIndexerInvoice; } - public FactoryIndexerContact FactoryIndexerContact { get; } - public FactoryIndexerContactInfo FactoryIndexerContactInfo { get; } - public FactoryIndexerFieldValue FactoryIndexerFieldValue { get; } - public FactoryIndexerEvents FactoryIndexerEvents { get; } - public FactoryIndexerDeal FactoryIndexerDeal { get; } - public FactoryIndexerTask FactoryIndexerTask { get; } - public FactoryIndexerCase FactoryIndexerCase { get; } - public FactoryIndexerInvoice FactoryIndexerInvoice { get; } - public bool TrySelectCase(string text, out List result) { var success = false; @@ -70,14 +70,14 @@ public bool TrySelectCase(string text, out List result) List casesId; - if (FactoryIndexerCase.TrySelectIds(s => s.MatchAll(text), out casesId)) + if (_factoryIndexerCase.TrySelectIds(s => s.MatchAll(text), out casesId)) { result.AddRange(casesId); success = true; } IReadOnlyCollection casesCustom; - if (FactoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 7), out casesCustom)) + if (_factoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 7), out casesCustom)) { result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); success = true; @@ -85,7 +85,7 @@ public bool TrySelectCase(string text, out List result) IReadOnlyCollection events; - if (!FactoryIndexerEvents.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) + if (!_factoryIndexerEvents.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 7).Gt(r => r.EntityId, 0), out events)) { result.AddRange(events.Select(r => r.EntityId).ToList()); success = true; @@ -101,7 +101,7 @@ public bool TrySelectContact(string text, out List result) List contactsId; - if (FactoryIndexerContact.TrySelectIds(s => s.MatchAll(text), out contactsId)) + if (_factoryIndexerContact.TrySelectIds(s => s.MatchAll(text), out contactsId)) { result.AddRange(contactsId); success = true; @@ -109,7 +109,7 @@ public bool TrySelectContact(string text, out List result) IReadOnlyCollection infos; - if (FactoryIndexerContactInfo.TrySelect(s => s.MatchAll(text), out infos)) + if (_factoryIndexerContactInfo.TrySelect(s => s.MatchAll(text), out infos)) { result.AddRange(infos.Select(r => r.ContactId).ToList()); success = true; @@ -117,7 +117,7 @@ public bool TrySelectContact(string text, out List result) IReadOnlyCollection personCustom; - if (FactoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] { 0, 4, 5 }), out personCustom)) + if (_factoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] { 0, 4, 5 }), out personCustom)) { result.AddRange(personCustom.Select(r => r.EntityId).ToList()); success = true; @@ -125,7 +125,7 @@ public bool TrySelectContact(string text, out List result) IReadOnlyCollection events; - if (FactoryIndexerEvents.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events)) + if (_factoryIndexerEvents.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events)) { result.AddRange(events.Select(r => r.ContactId).ToList()); success = true; @@ -141,7 +141,7 @@ public bool TrySelectOpportunity(string text, out List result) List dealsId; - if (FactoryIndexerDeal.TrySelectIds(s => s.MatchAll(text), out dealsId)) + if (_factoryIndexerDeal.TrySelectIds(s => s.MatchAll(text), out dealsId)) { result.AddRange(dealsId); success = true; @@ -149,7 +149,7 @@ public bool TrySelectOpportunity(string text, out List result) IReadOnlyCollection casesCustom; - if (FactoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 1), out casesCustom)) + if (_factoryIndexerFieldValue.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 1), out casesCustom)) { result.AddRange(casesCustom.Select(r => r.EntityId).ToList()); success = true; @@ -157,7 +157,7 @@ public bool TrySelectOpportunity(string text, out List result) IReadOnlyCollection events; - if (!FactoryIndexerEvents.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 1).Gt(r => r.EntityId, 0), out events)) + if (!_factoryIndexerEvents.TrySelect(s => s.MatchAll(text).Where(r => (int)r.EntityType, 1).Gt(r => r.EntityId, 0), out events)) { result.AddRange(events.Select(r => r.EntityId).ToList()); success = true; diff --git a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs index 2b64bbae0c5..1e475e7908d 100644 --- a/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs +++ b/products/ASC.CRM/Server/Core/Security/FileSecurityProvider.cs @@ -40,20 +40,19 @@ namespace ASC.CRM.Core { public class FileSecurity : IFileSecurity { + private readonly DaoFactory _daoFactory; + private readonly FilesIntegration _filesIntegration; + private readonly CrmSecurity _crmSecurity; + public FileSecurity(FilesIntegration filesIntegration, CrmSecurity crmSecurity, DaoFactory daoFactory) { - FilesIntegration = filesIntegration; - CRMSecurity = crmSecurity; - DaoFactory = daoFactory; + _filesIntegration = filesIntegration; + _crmSecurity = crmSecurity; + _daoFactory = daoFactory; } - public DaoFactory DaoFactory { get; } - - public FilesIntegration FilesIntegration { get; } - - public CrmSecurity CRMSecurity { get; } public bool CanCreate(FileEntry entry, Guid userId) { @@ -84,23 +83,23 @@ public bool CanEdit(FileEntry entry, Guid userId) { return CanRead(entry, userId) && - entry.CreateBy == userId || entry.ModifiedBy == userId || CRMSecurity.IsAdministrator(userId); + entry.CreateBy == userId || entry.ModifiedBy == userId || _crmSecurity.IsAdministrator(userId); } public bool CanRead(FileEntry entry, Guid userId) { if (entry.FileEntryType == FileEntryType.Folder) return false; - var invoice = DaoFactory.GetInvoiceDao().GetByFileId(Convert.ToInt32(entry.ID)); + var invoice = _daoFactory.GetInvoiceDao().GetByFileId(Convert.ToInt32(entry.ID)); if (invoice != null) - return CRMSecurity.CanAccessTo(invoice, userId); + return _crmSecurity.CanAccessTo(invoice, userId); - var reportFile = DaoFactory.GetReportDao().GetFile(Convert.ToInt32(entry.ID), userId); + var reportFile = _daoFactory.GetReportDao().GetFile(Convert.ToInt32(entry.ID), userId); if (reportFile != null) return true; - var tagDao = FilesIntegration.DaoFactory.GetTagDao(); + var tagDao = _filesIntegration.DaoFactory.GetTagDao(); var eventIds = tagDao.GetTags(entry.ID, FileEntryType.File, TagType.System) .Where(x => x.TagName.StartsWith("RelationshipEvent_")) @@ -109,9 +108,9 @@ public bool CanRead(FileEntry entry, Guid userId) if (!eventIds.Any()) return false; - var eventItem = DaoFactory.GetRelationshipEventDao().GetByID(eventIds.First()); + var eventItem = _daoFactory.GetRelationshipEventDao().GetByID(eventIds.First()); - return CRMSecurity.CanAccessTo(eventItem, userId); + return _crmSecurity.CanAccessTo(eventItem, userId); } diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index 6c40570fbd6..cc1cb2fab85 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -80,29 +80,6 @@ public static IHostBuilder CreateHostBuilder(string[] args) => {"pathToConf", path} }); }) - .ConfigureServices((hostContext, services) => - { - services.AddMemoryCache(); - - var diHelper = new DIHelper(services); - - diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>)); - - diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath); - //services.AddHostedService(); - //diHelper.TryAdd(); - - //services.AddHostedService(); - //diHelper.TryAdd(); - - //services.AddHostedService(); - //diHelper.TryAdd(); - - LogNLogExtension.ConfigureLog(diHelper, "ASC.Files", "ASC.Feed.Agregator"); - //diHelper.TryAdd(); - diHelper.TryAdd(); - diHelper.TryAdd(); - }) .ConfigureContainer((context, builder) => { builder.Register(context.Configuration, true, false); diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 518c884e77b..c2d72b73d92 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -12,6 +12,7 @@ using ASC.CRM.ApiModels; using ASC.CRM.HttpHandlers; using ASC.CRM.Mapping; +using ASC.Web.CRM.Core.Search; using ASC.Web.CRM.HttpHandlers; using Microsoft.AspNetCore.Builder; @@ -35,8 +36,6 @@ public override void ConfigureServices(IServiceCollection services) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - services.AddMemoryCache(); - base.ConfigureServices(services); DIHelper.TryAdd(); @@ -69,6 +68,15 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); + + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); + DIHelper.TryAdd(); } public override void Configure(IApplicationBuilder app, IWebHostEnvironment env) From 58e7e41cdd0e74b99c495a0ac4ef9e59ee6a5f84 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 4 Jun 2021 17:38:42 +0300 Subject: [PATCH 59/61] crm: code cleanup --- .../ASC.CRM/Server/Api/CasesController.cs | 2 +- .../ASC.CRM/Server/Api/ContactsController.cs | 2 +- .../Server/Api/CustomFieldsController.cs | 8 ++--- .../ASC.CRM/Server/Api/ListItemsController.cs | 14 ++++---- .../Api/RelationshipEventsController.cs | 6 ++-- .../ASC.CRM/Server/Api/ReportsController.cs | 2 +- .../ASC.CRM/Server/Api/UtilsController.cs | 2 +- products/ASC.CRM/Server/Api/VoipController.cs | 2 +- .../RequestsDto/AddHistoryToRequestDto.cs | 2 -- .../RequestsDto/UploadFileInCRMRequestDto.cs | 5 +-- .../ApiModels/ResponsesDto/ContactInfoDto.cs | 2 +- .../ApiModels/ResponsesDto/CurrencyInfoDto.cs | 1 - .../ApiModels/ResponsesDto/CurrencyRateDto.cs | 1 - .../ApiModels/ResponsesDto/InvoiceLineDto.cs | 1 - .../ResponsesDto/InvoiceStatusDto.cs | 1 - .../ApiModels/ResponsesDto/ListItemDto.cs | 2 +- .../ASC.CRM/Server/Classes/CRMSettings.cs | 8 ++--- .../Server/Classes/ContactPhotoManager.cs | 2 +- .../Server/Classes/InvoiceFormattedData.cs | 4 +-- products/ASC.CRM/Server/Classes/VoipEngine.cs | 10 +++--- .../Server/Configuration/ProductEntryPoint.cs | 10 ------ .../ASC.CRM/Server/Core/Dao/AbstractDao.cs | 6 ++-- products/ASC.CRM/Server/Core/Dao/CasesDao.cs | 9 +++-- .../ASC.CRM/Server/Core/Dao/ContactDao.cs | 11 +++--- .../ASC.CRM/Server/Core/Dao/ContactInfoDao.cs | 6 ++-- .../Server/Core/Dao/CurrencyInfoDao.cs | 3 +- .../Server/Core/Dao/CurrencyRateDao.cs | 14 ++++---- products/ASC.CRM/Server/Core/Dao/DealDao.cs | 10 +++--- .../Server/Core/Dao/DealMilestoneDao.cs | 8 ++--- .../ASC.CRM/Server/Core/Dao/InvoiceDao.cs | 15 ++++---- .../ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs | 15 ++++---- .../ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs | 5 ++- .../ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs | 8 ++--- .../ASC.CRM/Server/Core/Dao/ListItemDao.cs | 20 +++++------ .../Server/Core/Dao/RelationshipEventDao.cs | 7 +--- products/ASC.CRM/Server/Core/Dao/ReportDao.cs | 35 +++++++++---------- products/ASC.CRM/Server/Core/Dao/TagDao.cs | 3 +- .../Core/Dao/TaskTemplateContainerDao.cs | 4 +-- .../ASC.CRM/Server/Core/EF/CRMDbContext.cs | 2 +- .../Server/Core/EF/CrmDbContextSeed.cs | 2 +- .../ASC.CRM/Server/Core/Entities/Cases.cs | 1 - .../ASC.CRM/Server/Core/Entities/Comment.cs | 2 -- .../ASC.CRM/Server/Core/Entities/Contact.cs | 2 -- .../Server/Core/Entities/CurrencyInfo.cs | 2 +- .../ASC.CRM/Server/Core/Entities/Filter.cs | 14 ++++---- .../ASC.CRM/Server/Core/Entities/Invoice.cs | 1 - .../Server/Core/Entities/InvoiceLine.cs | 1 - .../Server/Core/Entities/RelationshipEvent.cs | 1 - products/ASC.CRM/Server/Core/Entities/Task.cs | 1 - .../Server/Core/Entities/TaskTemplate.cs | 1 - .../Core/Entities/TaskTemplateContainer.cs | 1 - .../Server/Core/Search/FactoryIndexerCase.cs | 1 - .../Core/Search/FactoryIndexerContact.cs | 1 - .../Server/Core/Security/CRMSecutiry.cs | 2 +- .../ImportFileHandlerMiddleware.cs | 1 - .../Middlewares/TenantConfigureMiddleware.cs | 2 +- .../WebToLeadFromHandlerMiddleware.cs | 10 +++--- products/ASC.CRM/Server/Program.cs | 5 --- products/ASC.CRM/Server/Startup.cs | 5 --- products/ASC.CRM/Server/Utils/ExportToCSV.cs | 9 +++-- .../Utils/Import/CSV/ImportCSVSettings.cs | 4 +-- .../Server/Utils/Import/CSV/ImportCases.cs | 1 - .../Utils/Import/CSV/ImportDataOperation.cs | 6 ++-- .../Server/Utils/Import/CSV/ImportDeals.cs | 1 - .../Server/Utils/Import/CSV/ImportFromCSV.cs | 5 ++- .../Server/Utils/Import/CSV/ImportTasks.cs | 3 +- products/ASC.CRM/Server/Utils/MailSender.cs | 5 +-- .../ASC.CRM/Server/Utils/PdfQueueWorker.cs | 10 ++---- products/ASC.CRM/Server/Utils/ReportHelper.cs | 2 +- 69 files changed, 143 insertions(+), 227 deletions(-) diff --git a/products/ASC.CRM/Server/Api/CasesController.cs b/products/ASC.CRM/Server/Api/CasesController.cs index 97ccfc60797..a74a02454c6 100644 --- a/products/ASC.CRM/Server/Api/CasesController.cs +++ b/products/ASC.CRM/Server/Api/CasesController.cs @@ -634,7 +634,7 @@ public IEnumerable GetCasesMembers(int caseid) /// Participant /// [Create(@"case/{caseid:int}/contact")] - public ContactDto AddMemberToCases([FromRoute] int caseid,[FromForm] int contactid) + public ContactDto AddMemberToCases([FromRoute] int caseid, [FromForm] int contactid) { if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException(); diff --git a/products/ASC.CRM/Server/Api/ContactsController.cs b/products/ASC.CRM/Server/Api/ContactsController.cs index 4ea4faedede..56a722aca99 100644 --- a/products/ASC.CRM/Server/Api/ContactsController.cs +++ b/products/ASC.CRM/Server/Api/ContactsController.cs @@ -390,7 +390,7 @@ public IEnumerable GetContacts( isShared); result = _mapper.Map, List>(contacts); - + _apiContext.SetDataPaginated(); _apiContext.SetDataFiltered(); _apiContext.SetDataSorted(); diff --git a/products/ASC.CRM/Server/Api/CustomFieldsController.cs b/products/ASC.CRM/Server/Api/CustomFieldsController.cs index 8a1f6723118..dafe225a685 100644 --- a/products/ASC.CRM/Server/Api/CustomFieldsController.cs +++ b/products/ASC.CRM/Server/Api/CustomFieldsController.cs @@ -105,8 +105,8 @@ public IEnumerable GetCustomFieldForSubject(string entityTyp /// [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")] public CustomFieldBaseDto SetEntityCustomFieldValue( - [FromRoute] string entityType, - [FromRoute] int entityid, + [FromRoute] string entityType, + [FromRoute] int entityid, [FromRoute] int fieldid, [FromForm] string fieldValue) { @@ -217,9 +217,9 @@ public CustomFieldBaseDto SetEntityCustomFieldValue( [Create(@"{entityType:regex(contact|person|company|opportunity|case)}/customfield")] public CustomFieldDto CreateCustomFieldValue( [FromRoute] string entityType, - [FromForm] string label, + [FromForm] string label, [FromForm] int fieldType, - [FromForm] int position, + [FromForm] int position, [FromForm] string mask) { if (!(_crmSecurity.IsAdmin)) throw _crmSecurity.CreateSecurityException(); diff --git a/products/ASC.CRM/Server/Api/ListItemsController.cs b/products/ASC.CRM/Server/Api/ListItemsController.cs index b879069a0dc..9cf985deee7 100644 --- a/products/ASC.CRM/Server/Api/ListItemsController.cs +++ b/products/ASC.CRM/Server/Api/ListItemsController.cs @@ -257,8 +257,8 @@ public DealMilestoneDto DeleteDealMilestone(int id) /// [Create(@"history/category")] public HistoryCategoryDto CreateHistoryCategory( - [FromForm] string title, - [FromForm] string description, + [FromForm] string title, + [FromForm] string description, [FromForm] string imageName, [FromForm] int sortOrder) { @@ -429,7 +429,7 @@ public HistoryCategoryDto DeleteHistoryCategory(int id) [Create(@"task/category")] public TaskCategoryDto CreateTaskCategory( [FromForm] string title, - [FromForm] string description, + [FromForm] string description, [FromForm] string imageName, [FromForm] int sortOrder) { @@ -599,8 +599,8 @@ public TaskCategoryDto DeleteTaskCategory(int categoryid, int newcategoryid) /// [Create(@"contact/status")] public ContactStatusDto CreateContactStatus( - [FromForm] string title, - [FromForm] string description, + [FromForm] string title, + [FromForm] string description, [FromForm] string color, [FromForm] int sortOrder) { @@ -718,7 +718,7 @@ public IEnumerable UpdateContactStatusesOrder(IEnumerable x.ID)), result.Select(x => x.Title)); - return _mapper.Map,List>(result); + return _mapper.Map, List>(result); } /// @@ -1086,7 +1086,7 @@ public IEnumerable GetDealMilestones() return result; } - + private DealMilestoneDto ToDealMilestoneDto(DealMilestone dealMilestone) { var result = new DealMilestoneDto(dealMilestone) diff --git a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs index 87bf6de520c..a90e35e22fa 100644 --- a/products/ASC.CRM/Server/Api/RelationshipEventsController.cs +++ b/products/ASC.CRM/Server/Api/RelationshipEventsController.cs @@ -474,7 +474,7 @@ public RelationshipEventDto AddHistoryTo([FromForm] AddHistoryToRequestDto inDto if (files.Any()) { var fileAttachAction = GetFilesAttachAction(entityTypeObj, contactId); - + _messageService.Send(fileAttachAction, _messageTarget.Create(item.ID), entityTitle, files.Select(x => x.Title)); } } @@ -483,7 +483,7 @@ public RelationshipEventDto AddHistoryTo([FromForm] AddHistoryToRequestDto inDto { _notifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, _daoFactory, notifyUserList.ToArray()); } - + var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId); _messageService.Send(historyCreatedAction, _messageTarget.Create(item.ID), entityTitle, category.Title); @@ -504,7 +504,7 @@ public RelationshipEventDto AddHistoryTo([FromForm] AddHistoryToRequestDto inDto /// Entity with the file attached [Create(@"{entityType:regex(contact|opportunity|case)}/{entityid:int}/files")] public RelationshipEventDto AttachFiles( - [FromRoute] string entityType, + [FromRoute] string entityType, [FromRoute] int entityid, [FromForm] IEnumerable fileids) { diff --git a/products/ASC.CRM/Server/Api/ReportsController.cs b/products/ASC.CRM/Server/Api/ReportsController.cs index 2c33e9cf597..2f16efd3e58 100644 --- a/products/ASC.CRM/Server/Api/ReportsController.cs +++ b/products/ASC.CRM/Server/Api/ReportsController.cs @@ -190,7 +190,7 @@ public object CheckReportData( public ReportState GenerateReport([FromForm] ReportType type, [FromForm] ReportTimePeriod timePeriod, [FromForm] Guid[] managers) { if (!_global.CanCreateReports) - throw _crmSecurity.CreateSecurityException(); + throw _crmSecurity.CreateSecurityException(); return _reportHelper.RunGenareteReport(type, timePeriod, managers); } diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index fa1b9968557..649ef638923 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -514,7 +514,7 @@ public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string /// false [Create(@"import/uploadfake")] - public FileUploadResult ProcessUploadFake( [FromForm] string csvFileURI, [FromForm] string jsonSettings) + public FileUploadResult ProcessUploadFake([FromForm] string csvFileURI, [FromForm] string jsonSettings) { return _importFromCSVManager.ProcessUploadFake(csvFileURI, jsonSettings); } diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index 9d243e70273..bfb60485a78 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -755,7 +755,7 @@ public VoipCallDto ReditectCall([FromRoute] string callId, [FromForm] string to) /// [Create(@"voip/call/{callId:regex(\w+)}")] public VoipCallDto SaveCall( - [FromRoute] string callId, + [FromRoute] string callId, [FromForm] string from, [FromForm] string to, [FromForm] Guid answeredBy, diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs index c58a3be22c6..fb2031da167 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/AddHistoryToRequestDto.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using ASC.Api.Core; diff --git a/products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs b/products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs index 230831fa189..7d82b6a420e 100644 --- a/products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs +++ b/products/ASC.CRM/Server/ApiModels/RequestsDto/UploadFileInCRMRequestDto.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net.Mime; -using System.Threading.Tasks; using Microsoft.AspNetCore.Http; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs index cbe9e81833e..339a78bd6b9 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ContactInfoDto.cs @@ -50,7 +50,7 @@ public Address(ContactInfo contactInfo) { if (contactInfo.InfoType != ContactInfoType.Address) throw new ArgumentException(); - var jsonElement = JsonDocument.Parse(contactInfo.Data).RootElement; + var jsonElement = JsonDocument.Parse(contactInfo.Data).RootElement; City = jsonElement.GetProperty("city").GetString(); Country = jsonElement.GetProperty("country").GetString(); diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs index c1f78578684..81f767ac37e 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs @@ -29,7 +29,6 @@ using ASC.Common.Mapping; using ASC.CRM.Core; -using ASC.CRM.Mapping; using AutoMapper; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs index 5c7c0fca3a6..a747a8c8804 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyRateDto.cs @@ -29,7 +29,6 @@ using ASC.Common.Mapping; using ASC.CRM.Core; -using ASC.CRM.Mapping; using AutoMapper; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs index 1da616a9286..88d49ef8e36 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceLineDto.cs @@ -27,7 +27,6 @@ using ASC.Common.Mapping; using ASC.CRM.Core.Entities; -using ASC.CRM.Mapping; namespace ASC.CRM.ApiModels { diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs index ee0a0928ba1..7ac778973ed 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/InvoiceStatusDto.cs @@ -28,7 +28,6 @@ using ASC.Common.Mapping; using ASC.CRM.Classes; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; using AutoMapper; diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs index 08e886254ef..e343943b1b9 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/ListItemDto.cs @@ -394,5 +394,5 @@ public virtual void Mapping(Profile profile) profile.CreateMap().ConvertUsing(); profile.CreateMap().ConvertUsing(); } - } + } } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Classes/CRMSettings.cs b/products/ASC.CRM/Server/Classes/CRMSettings.cs index d3119dd0193..e88f7d54a67 100644 --- a/products/ASC.CRM/Server/Classes/CRMSettings.cs +++ b/products/ASC.CRM/Server/Classes/CRMSettings.cs @@ -70,7 +70,7 @@ public class InvoiceSetting { public InvoiceSetting() { - + } public InvoiceSetting(IConfiguration configuration) @@ -111,7 +111,7 @@ public class CrmSettings : ISettings { public CrmSettings() { - + } public Guid ID @@ -126,7 +126,7 @@ public Guid ID [JsonPropertyName("DefaultCurrency")] public String DefaultCurrency { get; set; } - + [JsonPropertyName("ChangeContactStatusGroupAuto")] public string ChangeContactStatusGroupAutoDto { get; set; } @@ -159,7 +159,7 @@ public ISettings GetDefault(IServiceProvider serviceProvider) { var currencyProvider = serviceProvider.GetService(); var configuration = serviceProvider.GetService(); - + var languageName = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; var findedCurrency = currencyProvider.GetAll().Find(item => String.Compare(item.CultureName, languageName, true) == 0); diff --git a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs index d9a2902c0ad..78324513f02 100644 --- a/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs +++ b/products/ASC.CRM/Server/Classes/ContactPhotoManager.cs @@ -520,7 +520,7 @@ private void ExecGenerateThumbnail(byte[] imageData, int contactID, bool uploadO DataStore = _global.GetStore(), TmpDirName = tmpDirName }; - + if (!_resizeQueue.GetTasks().Contains(resizeWorkerItem)) { //Add diff --git a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs index 7482c153d16..8fee0d4dc94 100644 --- a/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs +++ b/products/ASC.CRM/Server/Classes/InvoiceFormattedData.cs @@ -514,7 +514,7 @@ private InvoiceFormattedData ReadData(string jsonData) JsonElement tableBodyRows; if (jsonObj.TryGetProperty("TableBodyRows", out tableBodyRows)) { - data.TableBodyRows = JsonSerializer.Deserialize>>(tableBodyRows.ToString()); + data.TableBodyRows = JsonSerializer.Deserialize>>(tableBodyRows.ToString()); } JsonElement tableFooterRows; @@ -545,7 +545,7 @@ private InvoiceFormattedData ReadData(string jsonData) #region Notes - JsonElement notes; + JsonElement notes; if (jsonObj.TryGetProperty("Notes", out notes)) { data.Notes = JsonSerializer.Deserialize>(notes.ToString()); diff --git a/products/ASC.CRM/Server/Classes/VoipEngine.cs b/products/ASC.CRM/Server/Classes/VoipEngine.cs index 9dcc896d538..ac776c178a3 100644 --- a/products/ASC.CRM/Server/Classes/VoipEngine.cs +++ b/products/ASC.CRM/Server/Classes/VoipEngine.cs @@ -163,7 +163,7 @@ public void AddHistoryToCallContact(VoipCall call, DaoFactory daoFactory) } var contact = daoFactory.GetContactDao().GetByID(call.ContactId); - + if (contact != null && _crmSecurity.CanAccessTo(contact)) { var note = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered @@ -223,7 +223,7 @@ public List GetContacts(string contactPhone, DaoFactory daoFactory) public void SaveAdditionalInfo(string callId) { lock (Locker) - { + { var _queueItem = new QueueItem { CallID = callId, TenantID = _tenantId }; _queue.QueueTask((a, b) => SaveAdditionalInfoAction(_queueItem), _queueItem); ; @@ -240,7 +240,7 @@ private void SaveAdditionalInfoAction(QueueItem queueItem) _crmSecurity, _tenantUtil, null, - _securityContext, + _securityContext, null, _tenantManager, _voipDao); @@ -282,7 +282,7 @@ private void GetPriceAndDuration(VoipCall call) { var provider = _voipDao.GetProvider(); var twilioCall = provider.GetCall(call.Id); - + call.Price = twilioCall.Price; call.DialDuration = twilioCall.DialDuration; } @@ -291,7 +291,7 @@ public void AnswerCall(VoipCall call) { call.AnsweredBy = _securityContext.CurrentAccount.ID; call.Status = VoipCallStatus.Answered; - + _daoFactory.GetVoipDao().SaveOrUpdateCall(call); } diff --git a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs index f84578bd41a..3704e50e7e9 100644 --- a/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs +++ b/products/ASC.CRM/Server/Configuration/ProductEntryPoint.cs @@ -27,21 +27,11 @@ using System.Linq; using ASC.Common; -using ASC.Common.Logging; using ASC.Core; -using ASC.Core.Common.Settings; -using ASC.Core.Configuration; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.CRM.Core.Entities; -using ASC.CRM.Core.Enums; using ASC.CRM.Resources; using ASC.Web.Core; -using ASC.Web.CRM.Classes; using ASC.Web.Files.Api; -using Microsoft.Extensions.Options; - namespace ASC.Web.CRM.Configuration { diff --git a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs index 885ee98e159..4c7e4add004 100644 --- a/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/AbstractDao.cs @@ -46,7 +46,7 @@ namespace ASC.CRM.Core.Dao public class AbstractDao { protected readonly List _supportedEntityType = new List(); - public CrmDbContext CrmDbContext { get; } + public CrmDbContext CrmDbContext { get; } protected readonly SecurityContext _securityContext; protected readonly ICache _cache; protected ILog _logger; @@ -65,9 +65,9 @@ IMapper mapper _logger = logger.Get("ASC.CRM"); _cache = ascCache; - + CrmDbContext = dbContextManager.Get(CrmConstants.DatabaseId); - + TenantID = tenantManager.GetCurrentTenant().TenantId; _securityContext = securityContext; diff --git a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs index 5ca6d93ce07..8c3296d124b 100644 --- a/products/ASC.CRM/Server/Core/Dao/CasesDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CasesDao.cs @@ -30,7 +30,6 @@ using System.Linq; using System.Text.RegularExpressions; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -485,7 +484,7 @@ public List GetCases(IEnumerable casesID) var result = Query(CrmDbContext.Cases) .Where(x => casesID.Contains(x.Id)) .AsNoTracking() - .ToList(); + .ToList(); return _mapper.Map, List>(result) .FindAll(_crmSecurity.CanAccessTo); @@ -557,7 +556,7 @@ public List GetCasesByPrefix(String prefix, int from, int count) if (0 < count && count < int.MaxValue) q = q.Take(count); q = q.OrderBy(x => x.Title); - + return _mapper.Map, List>(q.ToList()) .FindAll(_crmSecurity.CanAccessTo); } @@ -570,11 +569,11 @@ public List GetByID(int[] ids) .AsNoTracking() .ToList(); - return _mapper.Map, List>(result); + return _mapper.Map, List>(result); } public Cases GetByID(int id) -{ + { var dbEntity = CrmDbContext.Cases.Find(id); if (dbEntity.TenantId != TenantID) return null; diff --git a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs index 290a87619ad..0bcfcb3a0a5 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactDao.cs @@ -30,7 +30,6 @@ using System.Linq; using System.Text.RegularExpressions; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -1004,7 +1003,7 @@ public void SetMembers(int companyID, params int[] peopleIDs) if (!(peopleIDs == null || peopleIDs.Length == 0)) { - foreach(var id in peopleIDs) + foreach (var id in peopleIDs) { var dbContactEntity = CrmDbContext.Contacts.Find(id); @@ -1221,7 +1220,7 @@ public void UpdateContactStatus(IEnumerable contactid, int statusid) dbEntity.Id = id; dbEntity.StatusId = statusid; - + } CrmDbContext.SaveChanges(); @@ -1718,10 +1717,10 @@ public void MergeDublicate(int fromContactID, int toContactID) // crm_invoice var invoicesToUpdate = Query(CrmDbContext.Invoices) - .AsNoTracking() + .AsNoTracking() .Where(x => x.ContactId == fromContactID) .ToList(); - + invoicesToUpdate.ForEach(x => x.ContactId = toContactID); CrmDbContext.SaveChanges(); @@ -1751,7 +1750,7 @@ public void MergeDublicate(int fromContactID, int toContactID) .AsNoTracking() .Where(x => x.ContactId == fromContactID) .ToList(); - + relationshipEventToUpdate.ForEach(x => x.ContactId = toContactID); CrmDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs index 51fdbaead78..9633570343c 100644 --- a/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ContactInfoDao.cs @@ -27,7 +27,6 @@ using System.Collections.Generic; using System.Linq; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -41,7 +40,6 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -84,8 +82,8 @@ public ContactInfo GetByID(int id) public void Delete(int id) { - var dbEntity = CrmDbContext.ContactsInfo.Find(id); - + var dbEntity = CrmDbContext.ContactsInfo.Find(id); + CrmDbContext.Remove(dbEntity); CrmDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs index b620881e27e..ab6b2f26bf8 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyInfoDao.cs @@ -24,7 +24,6 @@ */ -using System; using System.Collections.Generic; using System.Linq; @@ -68,7 +67,7 @@ public List GetAll() .AsNoTracking() .ToList(); - return _mapper.Map, List>(dbEntities); + return _mapper.Map, List>(dbEntities); } public CurrencyInfo GetByAbbreviation(string abbreviation) diff --git a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs index 11cc0eb7d8c..19d7b2ff107 100644 --- a/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/CurrencyRateDao.cs @@ -79,9 +79,9 @@ public CurrencyRate GetByID(int id) public CurrencyRate GetByCurrencies(string fromCurrency, string toCurrency) { - var dbEntity = Query(CrmDbContext.CurrencyRate).FirstOrDefault(x => - string.Compare(x.FromCurrency, fromCurrency, true) == 0 && - string.Compare(x.ToCurrency, toCurrency, true) == 0); + var dbEntity = Query(CrmDbContext.CurrencyRate).FirstOrDefault(x => + string.Compare(x.FromCurrency, fromCurrency, true) == 0 && + string.Compare(x.ToCurrency, toCurrency, true) == 0); return _mapper.Map(dbEntity); @@ -96,8 +96,8 @@ public int SaveOrUpdate(CurrencyRate entity) return Delete(entity.ID); var dbEntity = new DbCurrencyRate - { - Id = entity.ID, + { + Id = entity.ID, FromCurrency = entity.FromCurrency.ToUpper(), ToCurrency = entity.ToCurrency.ToUpper(), Rate = entity.Rate, @@ -105,7 +105,7 @@ public int SaveOrUpdate(CurrencyRate entity) CreateBy = entity.CreateBy == Guid.Empty ? _securityContext.CurrentAccount.ID : entity.CreateBy, LastModifedOn = DateTime.UtcNow, LastModifedBy = _securityContext.CurrentAccount.ID, - TenantId = TenantID + TenantId = TenantID }; CrmDbContext.Update(dbEntity); @@ -130,7 +130,7 @@ public List SetCurrencyRates(List rates) using var tx = CrmDbContext.Database.BeginTransaction(); var items = Query(CrmDbContext.CurrencyRate).AsNoTracking(); - + CrmDbContext.RemoveRange(items); foreach (var rate in rates) diff --git a/products/ASC.CRM/Server/Core/Dao/DealDao.cs b/products/ASC.CRM/Server/Core/Dao/DealDao.cs index 54e4c58dd72..3035c6ecade 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealDao.cs @@ -30,7 +30,6 @@ using System.Linq; using System.Text.RegularExpressions; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -47,7 +46,6 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -129,7 +127,7 @@ public List GetDeals(int[] id) } public Deal GetByID(int dealID) - { + { var deals = GetDeals(new[] { dealID }); return deals.Count == 0 ? null : deals[0]; @@ -742,7 +740,7 @@ public Deal DeleteDeal(int id) if (id <= 0) return null; var deal = GetByID(id); - + if (deal == null) return null; _crmSecurity.DemandDelete(deal); @@ -762,7 +760,7 @@ public Deal DeleteDeal(int id) public List DeleteBatchDeals(int[] dealID) { var deals = GetDeals(dealID).FindAll(_crmSecurity.CanDelete).ToList(); - + if (!deals.Any()) return deals; // Delete relative keys @@ -775,7 +773,7 @@ public List DeleteBatchDeals(int[] dealID) public List DeleteBatchDeals(List deals) { deals = deals.FindAll(_crmSecurity.CanDelete).ToList(); - + if (!deals.Any()) return deals; // Delete relative keys diff --git a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs index 5850571746a..214d1bb1cab 100644 --- a/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/DealMilestoneDao.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Linq; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -42,14 +41,13 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; #endregion namespace ASC.CRM.Core.Dao -{ +{ [Scope] public class DealMilestoneDao : AbstractDao { @@ -216,12 +214,12 @@ public List GetAll(int[] id) .OrderBy(x => x.SortOrder) .Where(x => id.Contains(x.Id)).ToList(); - return _mapper.Map, List>(result); + return _mapper.Map, List>(result); } public List GetAll() { - var result = Query(CrmDbContext.DealMilestones) + var result = Query(CrmDbContext.DealMilestones) .AsNoTracking() .OrderBy(x => x.SortOrder) .ToList(); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs index e49abe28107..e054367fdf6 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceDao.cs @@ -31,7 +31,6 @@ using System.Text.Json; using System.Text.RegularExpressions; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -54,7 +53,7 @@ using SecurityContext = ASC.Core.SecurityContext; namespace ASC.CRM.Core.Dao -{ +{ [Scope] public class InvoiceDao : AbstractDao { @@ -419,7 +418,7 @@ public List GetInvoices(int[] ids) public List GetEntityInvoices(EntityType entityType, int entityID) { var result = new List(); - + if (entityID <= 0) return result; @@ -518,7 +517,7 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) invoice.ExchangeRate <= 0 || String.IsNullOrEmpty(invoice.Terms)) throw new ArgumentException(); - + var dbEntity = new DbInvoice { Id = invoice.ID, @@ -541,7 +540,7 @@ private int SaveOrUpdateInvoiceInDb(Invoice invoice) FileId = invoice.FileID, CreateOn = invoice.CreateOn == DateTime.MinValue ? DateTime.UtcNow : invoice.CreateOn, CreateBy = _securityContext.CurrentAccount.ID, - LastModifedOn = DateTime.UtcNow, + LastModifedOn = DateTime.UtcNow, LastModifedBy = _securityContext.CurrentAccount.ID, TenantId = TenantID }; @@ -637,9 +636,9 @@ public void UpdateInvoiceJsonData(Invoice invoice, int billingAddressID, int del { jsonData.LogoBase64 = null; } - + invoice.JsonData = JsonSerializer.Serialize(jsonData); - + UpdateInvoiceJsonData(invoice.ID, invoice.JsonData); } @@ -858,7 +857,7 @@ private bool hasParams( public void SetInvoiceCreationDate(int id, DateTime creationDate) { var dbEntity = CrmDbContext.Invoices.Find(id); - + var entity = _mapper.Map(dbEntity); dbEntity.CreateOn = _tenantUtil.DateTimeToUtc(creationDate); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs index 7d67a3481f6..ebaa033dca1 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceItemDao.cs @@ -29,13 +29,11 @@ using System.Globalization; using System.Linq; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; using ASC.Core.Common.EF; -using ASC.Core.Tenants; using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; @@ -43,12 +41,11 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao -{ +{ [Scope] public class InvoiceItemDao : AbstractDao { @@ -261,7 +258,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) var dbEntity = new DbInvoiceItem { - Id = invoiceItem.ID, + Id = invoiceItem.ID, Title = invoiceItem.Title, Description = invoiceItem.Description, StockKeepingUnit = invoiceItem.StockKeepingUnit, @@ -287,7 +284,7 @@ private InvoiceItem SaveOrUpdateInvoiceItemInDb(InvoiceItem invoiceItem) public InvoiceItem DeleteInvoiceItem(int invoiceItemID) { var invoiceItem = GetByID(invoiceItemID); - + if (invoiceItem == null) return null; _crmSecurity.DemandDelete(invoiceItem); @@ -324,14 +321,14 @@ public List DeleteBatchInvoiceItems(int[] ids) } CrmDbContext.SaveChanges(); - + // Delete relative keys /*_cache.Remove(_invoiceItemCacheKey); _cache.Insert(_invoiceItemCacheKey, String.Empty);*/ - + return result; } - + private IQueryable GetDbInvoiceItemByFilters( ICollection exceptIDs, string searchText, diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs index 22797531585..6156e1b1d67 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceLineDao.cs @@ -31,7 +31,6 @@ using System.Text.Json; using System.Text.RegularExpressions; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -157,7 +156,7 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) Description = invoiceLine.Description, Quantity = invoiceLine.Quantity, Price = invoiceLine.Price, - Discount = invoiceLine.Discount, + Discount = invoiceLine.Discount, TenantId = TenantID }; @@ -170,7 +169,7 @@ private int SaveOrUpdateInvoiceLineInDb(InvoiceLine invoiceLine) public void DeleteInvoiceLine(int id) { var dbEntity = CrmDbContext.InvoiceLine.Find(id); - + CrmDbContext.Remove(dbEntity); CrmDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs index 6d1ec6642df..5dacbcc6bbb 100644 --- a/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/InvoiceTaxDao.cs @@ -64,7 +64,7 @@ IMapper mapper mapper) { _mapper = mapper; - } + } public Boolean IsExist(int id) { @@ -117,7 +117,7 @@ public InvoiceTax GetByID(int id) var dbEntity = CrmDbContext.InvoiceTax.Find(id); if (dbEntity.TenantId != TenantID) return null; - + return _mapper.Map(dbEntity); } @@ -157,13 +157,13 @@ private InvoiceTax SaveOrUpdateInvoiceTaxInDb(InvoiceTax invoiceTax) public InvoiceTax DeleteInvoiceTax(int id) { var dbEntity = CrmDbContext.InvoiceTax.Find(id); - + var entity = _mapper.Map(dbEntity); if (entity == null) return null; _crmSecurity.DemandDelete(entity); - + CrmDbContext.InvoiceTax.Remove(dbEntity); CrmDbContext.SaveChanges(); diff --git a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs index 722a5777bdb..582c036f112 100644 --- a/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ListItemDao.cs @@ -28,7 +28,6 @@ using System.Collections.Specialized; using System.Linq; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -42,7 +41,6 @@ using AutoMapper; -using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; @@ -174,7 +172,7 @@ public ListItem GetByID(int id) if (dbEntity.TenantId != TenantID) return null; - return _mapper.Map(dbEntity); + return _mapper.Map(dbEntity); } public List GetItems(int[] id) @@ -183,7 +181,7 @@ public List GetItems(int[] id) .AsNoTracking() .Where(x => id.Contains(x.Id)) .ToList(); - + var entities = _mapper.Map, List>(dbEntities); var systemItem = id.Where(item => item < 0).Select(GetSystemListItem); @@ -203,8 +201,8 @@ public List GetAll() public void ChangeColor(int id, string newColor) { var dbEntity = CrmDbContext.ListItem.Find(id); - - dbEntity.Color = newColor; + + dbEntity.Color = newColor; CrmDbContext.SaveChanges(); } @@ -213,11 +211,11 @@ public NameValueCollection GetColors(ListType listType) { var result = new NameValueCollection(); - Query(CrmDbContext.ListItem) - .Where(x => x.ListType == listType) - .Select(x => new { x.Id, x.Color }) - .ToList() - .ForEach(x => result.Add(x.Id.ToString(), x.Color.ToString())); + Query(CrmDbContext.ListItem) + .Where(x => x.ListType == listType) + .Select(x => new { x.Id, x.Color }) + .ToList() + .ForEach(x => result.Add(x.Id.ToString(), x.Color.ToString())); return result; diff --git a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs index 64ed64c98e7..0367e98b01b 100644 --- a/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/RelationshipEventDao.cs @@ -27,11 +27,8 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.Serialization.Json; -using System.Text; using System.Text.Json; -using ASC.Collections; using ASC.Common; using ASC.Common.Caching; using ASC.Common.Logging; @@ -43,10 +40,8 @@ using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.Files.Core; -using ASC.Web.CRM; using ASC.Web.CRM.Core.Search; using ASC.Web.Files.Api; -using ASC.Web.Studio.Core; using AutoMapper; @@ -125,7 +120,7 @@ public void AttachFiles(int eventID, int[] fileIDs) var dbEntity = CrmDbContext.RelationshipEvent.Find(eventID); dbEntity.HaveFiles = true; - + CrmDbContext.SaveChanges(); } } diff --git a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs index 3da359beb7b..e6c6b9e8c49 100644 --- a/products/ASC.CRM/Server/Core/Dao/ReportDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/ReportDao.cs @@ -31,7 +31,6 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Linq.Expressions; using ASC.Common; using ASC.Common.Caching; @@ -450,20 +449,20 @@ private List BuildSalesByManagersReport(ReportTimePeriod timePer case ReportTimePeriod.Today: case ReportTimePeriod.Yesterday: exp = x => x ?? x.Value.Date.AddHours(x.Value.Hour); - + break; case ReportTimePeriod.CurrentWeek: case ReportTimePeriod.PreviousWeek: case ReportTimePeriod.CurrentMonth: case ReportTimePeriod.PreviousMonth: - exp = x => x??x.Value.Date; - + exp = x => x ?? x.Value.Date; + break; case ReportTimePeriod.CurrentQuarter: case ReportTimePeriod.PreviousQuarter: case ReportTimePeriod.CurrentYear: case ReportTimePeriod.PreviousYear: - exp = x => x??x.Value.Date.AddDays(-(x.Value.Day - 1)); + exp = x => x ?? x.Value.Date.AddDays(-(x.Value.Day - 1)); break; default: @@ -483,7 +482,7 @@ private List BuildSalesByManagersReport(ReportTimePeriod timePer .SelectMany(x => x.y.DefaultIfEmpty(), (x, y) => new { Deal = x.x.Deal, CurrencyRate = x.x.CurrencyRate, DealMilestone = y }) .Where(x => managers != null && managers.Any() ? managers.Contains(x.Deal.ResponsibleId) : true) .Where(x => x.Deal.ActualCloseDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.Deal.ActualCloseDate <= _tenantUtil.DateTimeToUtc(toDate)) - .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon) + .Where(x => x.DealMilestone.Status == DealMilestoneStatus.ClosedAndWon) .GroupBy(x => new { x.Deal.ResponsibleId, x.Deal.ActualCloseDate, x.DealMilestone.Status }) .Select(x => new { @@ -860,7 +859,7 @@ private List BuildSalesForecastReport(ReportTimePeriod timePeriod deals_value = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) : x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate)), - value_with_probability = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) * x.Deal.DealMilestoneProbability/100.0m : + value_with_probability = x.Sum(x => x.Deal.BidType == 0 ? x.Deal.BidValue * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) * x.Deal.DealMilestoneProbability / 100.0m : x.Deal.BidValue * (x.Deal.PerPeriodValue == 0 ? 1.0m : Convert.ToDecimal(x.Deal.PerPeriodValue)) * (x.Deal.BidCurrency == defaultCurrency ? 1.0m : x.CurrencyRate.Rate) * x.Deal.DealMilestoneProbability / 100.0m), close_date = exp.Invoke(x.Key.ExpectedCloseDate) }).ToList() @@ -1111,7 +1110,7 @@ private List BuildSalesFunnelReport(ReportTimePeriod timePeriod, Gu Duration = Convert.ToInt32(x.deals_duration) }); - return result; + return result; } private object GenerateReportData(ReportTimePeriod timePeriod, List data) @@ -1234,12 +1233,12 @@ private List BuildWorkloadByContactsReport(ReportTimePeriod .ToList() .ConvertAll(x => new WorkloadByContacts { - UserId = x.create_by, - UserName = _displayUserSettings.GetFullUserName(x.create_by), - CategoryId = x.id, - CategoryName = x.title, - Count = x.total, - WithDeals = x.with_deals + UserId = x.create_by, + UserName = _displayUserSettings.GetFullUserName(x.create_by), + CategoryId = x.id, + CategoryName = x.title, + Count = x.total, + WithDeals = x.with_deals }); // .OrderBy("i.sort_order, i.title", true); @@ -1588,13 +1587,13 @@ private List BuildWorkloadByInvoicesReport(ReportTimePeriod DateTime toDate; GetTimePeriod(timePeriod, out fromDate, out toDate); - + var result = Query(CrmDbContext.Invoices) .Where(x => managers != null && managers.Any() ? managers.Contains(x.CreateBy) : true) .GroupBy(x => x.CreateBy) .Select(x => new { - createBy = x.Key, + createBy = x.Key, sent = x.Sum(x => x.Status != InvoiceStatus.Draft && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.IssueDate >= _tenantUtil.DateTimeToUtc(fromDate) && x.IssueDate <= _tenantUtil.DateTimeToUtc(toDate)) ? 1 : 0), paid = x.Sum(x => x.Status == InvoiceStatus.Paid && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) ? 1 : 0), rejected = x.Sum(x => x.Status == InvoiceStatus.Rejected && (timePeriod == ReportTimePeriod.DuringAllTime ? true : x.LastModifedOn >= _tenantUtil.DateTimeToUtc(fromDate) && x.LastModifedOn <= _tenantUtil.DateTimeToUtc(toDate)) ? 1 : 0), @@ -1608,7 +1607,7 @@ private List BuildWorkloadByInvoicesReport(ReportTimePeriod SentCount = x.sent, PaidCount = x.paid, RejectedCount = x.rejected, - OverdueCount = x.overdue + OverdueCount = x.overdue }); return result; @@ -1985,7 +1984,7 @@ private object BuildSummaryForThePeriodReport(ReportTimePeriod timePeriod, Guid[ }) .OrderBy(x => x.title) .ToList(); - // .OrderBy("i.sort_order, i.title", true); + // .OrderBy("i.sort_order, i.title", true); var voipSqlQuery = Query(CrmDbContext.VoipCalls) .Where(x => String.IsNullOrEmpty(x.ParentCallId)) diff --git a/products/ASC.CRM/Server/Core/Dao/TagDao.cs b/products/ASC.CRM/Server/Core/Dao/TagDao.cs index eb1c70c8c67..f76a084f838 100644 --- a/products/ASC.CRM/Server/Core/Dao/TagDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TagDao.cs @@ -41,7 +41,6 @@ using AutoMapper; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Internal; using Microsoft.Extensions.Options; namespace ASC.CRM.Core.Dao @@ -59,7 +58,7 @@ public TagDao(DbContextManager dbContextManager, tenantManager, securityContext, logger, - ascCache, + ascCache, mapper) { diff --git a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs index 0c2b0123fc2..1f632a2828d 100644 --- a/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs +++ b/products/ASC.CRM/Server/Core/Dao/TaskTemplateContainerDao.cs @@ -75,7 +75,7 @@ public int SaveOrUpdate(TaskTemplateContainer item) CreateBy = item.CreateBy == Guid.Empty ? _securityContext.CurrentAccount.ID : item.CreateBy, LastModifedOn = DateTime.UtcNow, LastModifedBy = _securityContext.CurrentAccount.ID, - TenantId = TenantID + TenantId = TenantID }; CrmDbContext.Update(dbEntity); @@ -176,7 +176,7 @@ public TaskTemplate GetNext(int taskID) if (sqlResult == null) return null; - var dbEntity = Query(CrmDbContext.TaskTemplates) + var dbEntity = Query(CrmDbContext.TaskTemplates) .FirstOrDefault(x => x.ContainerId == sqlResult.ContainerId && x.SortOrder > sqlResult.SortOrder && !x.DeadLineIsFixed); diff --git a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs index c1230d232f5..fea8586c832 100644 --- a/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs +++ b/products/ASC.CRM/Server/Core/EF/CRMDbContext.cs @@ -48,7 +48,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .AddDbDeal() .AddDbTask() .AddDbTenant(); - + modelBuilder.Entity(entity => { entity.HasKey(e => e.Abbreviation) diff --git a/products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs b/products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs index c9d2b30d10f..5fb8c452df5 100644 --- a/products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs +++ b/products/ASC.CRM/Server/Core/EF/CrmDbContextSeed.cs @@ -189,5 +189,5 @@ public static void SeedInitPortalData(SettingsManager settingsManager, } } } - } + } } diff --git a/products/ASC.CRM/Server/Core/Entities/Cases.cs b/products/ASC.CRM/Server/Core/Entities/Cases.cs index 7e82ab08528..ad120838355 100644 --- a/products/ASC.CRM/Server/Core/Entities/Cases.cs +++ b/products/ASC.CRM/Server/Core/Entities/Cases.cs @@ -30,7 +30,6 @@ using ASC.Common.Mapping; using ASC.Common.Security; using ASC.CRM.Core.EF; -using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { diff --git a/products/ASC.CRM/Server/Core/Entities/Comment.cs b/products/ASC.CRM/Server/Core/Entities/Comment.cs index e42cb13e1d6..7ad5e47e78c 100644 --- a/products/ASC.CRM/Server/Core/Entities/Comment.cs +++ b/products/ASC.CRM/Server/Core/Entities/Comment.cs @@ -28,8 +28,6 @@ using System; -using ASC.CRM.Mapping; - #endregion namespace ASC.CRM.Core.Entities diff --git a/products/ASC.CRM/Server/Core/Entities/Contact.cs b/products/ASC.CRM/Server/Core/Entities/Contact.cs index 8f300a05b42..6f03c0fc4e5 100644 --- a/products/ASC.CRM/Server/Core/Entities/Contact.cs +++ b/products/ASC.CRM/Server/Core/Entities/Contact.cs @@ -27,9 +27,7 @@ using System; using ASC.Common.Security; -using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { diff --git a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs index e61da8b80c0..63375828526 100644 --- a/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs +++ b/products/ASC.CRM/Server/Core/Entities/CurrencyInfo.cs @@ -86,7 +86,7 @@ public override string ToString() return string.Concat(Abbreviation, "-", Title); } - public void Mapping(Profile profile) + public void Mapping(Profile profile) { profile.CreateMap() .ForMember(dest => dest._resourceKey, opt => opt.MapFrom(src => src.ResourceKey)); diff --git a/products/ASC.CRM/Server/Core/Entities/Filter.cs b/products/ASC.CRM/Server/Core/Entities/Filter.cs index 72a73799e26..b220ca1598b 100644 --- a/products/ASC.CRM/Server/Core/Entities/Filter.cs +++ b/products/ASC.CRM/Server/Core/Entities/Filter.cs @@ -193,7 +193,7 @@ public TaskFilterObject(string base64String) .ToList(); if (fromToArray.Count != 2) continue; - + FromDate = !String.IsNullOrEmpty(fromToArray[0]) ? Global.ApiDateTimeParse(fromToArray[0]) : DateTime.MinValue; ToDate = !String.IsNullOrEmpty(fromToArray[1]) @@ -294,13 +294,13 @@ public DealFilterObject(string base64String) case "my": case "responsibleID": - ResponsibleId = filterParam.GetProperty("value").GetGuid(); - + ResponsibleId = filterParam.GetProperty("value").GetGuid(); + break; case "stageTypeOpen": case "stageTypeClosedAndWon": case "stageTypeClosedAndLost": - StageType = filterParam.GetProperty("value").GetString(); + StageType = filterParam.GetProperty("value").GetString(); break; case "opportunityStagesID": OpportunityStageId = filterParam.GetProperty("value").GetInt32(); @@ -315,9 +315,9 @@ public DealFilterObject(string base64String) .EnumerateArray() .Select(x => x.GetString()) .ToList(); - + if (fromToArray.Count != 2) continue; - + FromDate = Global.ApiDateTimeParse(fromToArray[0]); ToDate = Global.ApiDateTimeParse(fromToArray[1]); break; @@ -460,7 +460,7 @@ public ContactFilterObject(string base64String) .EnumerateArray() .Select(x => x.GetString()) .ToList(); - + if (fromToArray.Count != 2) continue; FromDate = Global.ApiDateTimeParse(fromToArray[0]); diff --git a/products/ASC.CRM/Server/Core/Entities/Invoice.cs b/products/ASC.CRM/Server/Core/Entities/Invoice.cs index 47e2d3c2bdf..0d60ca42263 100644 --- a/products/ASC.CRM/Server/Core/Entities/Invoice.cs +++ b/products/ASC.CRM/Server/Core/Entities/Invoice.cs @@ -32,7 +32,6 @@ using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; using ASC.Files.Core; diff --git a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs index 9f156becbad..e67a4f8d723 100644 --- a/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs +++ b/products/ASC.CRM/Server/Core/Entities/InvoiceLine.cs @@ -25,7 +25,6 @@ using ASC.Common.Mapping; using ASC.CRM.Core.EF; -using ASC.CRM.Mapping; namespace ASC.CRM.Core.Entities { diff --git a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs index dce86cebbb8..6928857c61a 100644 --- a/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs +++ b/products/ASC.CRM/Server/Core/Entities/RelationshipEvent.cs @@ -32,7 +32,6 @@ using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; #endregion namespace ASC.CRM.Core.Entities diff --git a/products/ASC.CRM/Server/Core/Entities/Task.cs b/products/ASC.CRM/Server/Core/Entities/Task.cs index bf0c47fb531..54cd2e3628e 100644 --- a/products/ASC.CRM/Server/Core/Entities/Task.cs +++ b/products/ASC.CRM/Server/Core/Entities/Task.cs @@ -32,7 +32,6 @@ using ASC.Common.Security; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; using AutoMapper; diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs index 72640e043c3..44fa0a73d11 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplate.cs @@ -30,7 +30,6 @@ using ASC.Common.Mapping; using ASC.CRM.Core.EF; -using ASC.CRM.Mapping; using AutoMapper; diff --git a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs index 311a6b5984f..8f3bd47a0e7 100644 --- a/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs +++ b/products/ASC.CRM/Server/Core/Entities/TaskTemplateContainer.cs @@ -31,7 +31,6 @@ using ASC.Common.Mapping; using ASC.CRM.Core.EF; using ASC.CRM.Core.Enums; -using ASC.CRM.Mapping; #endregion diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs index e9421d1f767..039847b7990 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerCase.cs @@ -36,7 +36,6 @@ using ASC.CRM.Core.EF; using ASC.ElasticSearch; using ASC.ElasticSearch.Core; -using ASC.Web.Files.Core.Search; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; diff --git a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs index 84961f456e8..d906c5726f9 100644 --- a/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs +++ b/products/ASC.CRM/Server/Core/Search/FactoryIndexerContact.cs @@ -32,7 +32,6 @@ using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Core; -using ASC.CRM.ApiModels; using ASC.CRM.Core.Dao; using ASC.CRM.Core.EF; using ASC.ElasticSearch; diff --git a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs index 0b0daf3cc02..487a326667e 100644 --- a/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs +++ b/products/ASC.CRM/Server/Core/Security/CRMSecutiry.cs @@ -64,7 +64,7 @@ public class CrmSecurity private readonly AuthorizationManager _authorizationManager; private readonly DisplayUserSettingsHelper _displayUserSettingsHelper; private readonly UserManager _userManager; - + public readonly IAction _actionRead = new Action(new Guid("{6F05C382-8BCA-4469-9424-C807A98C40D7}"), "", true, false); public CrmSecurity(SecurityContext securityContext, diff --git a/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs b/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs index 5712a06a68a..1e495a831ba 100644 --- a/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs +++ b/products/ASC.CRM/Server/Middlewares/ImportFileHandlerMiddleware.cs @@ -26,7 +26,6 @@ using System; using System.Collections.Generic; -using System.Runtime.InteropServices.ComTypes; using System.Text.Json; using System.Threading.Tasks; diff --git a/products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs b/products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs index 01c2ae93175..351c4b9b34d 100644 --- a/products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs +++ b/products/ASC.CRM/Server/Middlewares/TenantConfigureMiddleware.cs @@ -22,7 +22,7 @@ public async Task InvokeAsync(HttpContext context, DaoFactory daoFactory, SettingsManager settingsManager, CoreConfiguration coreConfiguration) - { + { CrmDbContextSeed.SeedInitPortalData(settingsManager, daoFactory, coreConfiguration); await _next.Invoke(context); diff --git a/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs index 4a1e9d30213..f81b4103db8 100644 --- a/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs +++ b/products/ASC.CRM/Server/Middlewares/WebToLeadFromHandlerMiddleware.cs @@ -52,8 +52,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; -using SimpleJson; - namespace ASC.Web.CRM.HttpHandlers { public class WebToLeadFromHandlerMiddleware @@ -147,11 +145,11 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, var fieldCollector = new NameValueCollection(); - var addressTemplate = new Dictionary(); - + var addressTemplate = new Dictionary(); + foreach (String addressPartName in Enum.GetNames(typeof(AddressPart))) addressTemplate.Add(addressPartName.ToLower(), ""); - + var addressTemplateStr = JsonSerializer.Serialize(addressTemplate); var isCompany = false; @@ -296,7 +294,7 @@ public async System.Threading.Tasks.Task Invoke(HttpContext context, Dictionary addressParts = JsonSerializer.Deserialize>(findedAddress.Data); addressParts[addressPart.ToString().ToLower()] = GetValue(key); string newJson = JsonSerializer.Serialize(addressParts); - + findedAddress.Data = JsonSerializer.Serialize(addressParts); continue; diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index cc1cb2fab85..ff40afee444 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -3,19 +3,14 @@ using System.IO; using System.Runtime.InteropServices; -using ASC.Common.Caching; -using ASC.Common; using ASC.Common.DependencyInjection; -using ASC.Common.Logging; using ASC.Common.Utils; -using ASC.Web.Files.Core.Search; using Autofac; using Autofac.Extensions.DependencyInjection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace ASC.CRM diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index c2d72b73d92..8a1bd6ac061 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -1,13 +1,9 @@ -using System; using System.Collections.Generic; -using System.Reflection; using System.Text; using System.Text.Json.Serialization; -using System.Threading.Tasks; using ASC.Api.Core; using ASC.Common; -using ASC.Common.Mapping; using ASC.CRM.Api; using ASC.CRM.ApiModels; using ASC.CRM.HttpHandlers; @@ -17,7 +13,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/products/ASC.CRM/Server/Utils/ExportToCSV.cs b/products/ASC.CRM/Server/Utils/ExportToCSV.cs index 16e9edb20fc..dacb709e89b 100644 --- a/products/ASC.CRM/Server/Utils/ExportToCSV.cs +++ b/products/ASC.CRM/Server/Utils/ExportToCSV.cs @@ -35,7 +35,6 @@ using System.Text.Json; using ASC.Common; -using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Security.Authentication; using ASC.Common.Threading; @@ -62,7 +61,7 @@ using Microsoft.Extensions.Options; namespace ASC.Web.CRM.Classes -{ +{ [Transient] public class ExportDataOperation : DistributedTaskProgress, IProgressItem { @@ -161,7 +160,7 @@ public object Clone() { return MemberwiseClone(); } - + public object Error { get; set; } public string FileName { get; set; } public string FileUrl { get; set; } @@ -218,7 +217,7 @@ protected override void DoJob() System.Threading.Thread.CurrentThread.CurrentUICulture = userCulture; _log.Debug("Start Export Data"); - + if (_filterObject == null) ExportAllData(_daoFactory); else @@ -1242,7 +1241,7 @@ public class ExportToCsv public ExportToCsv(SecurityContext securityContext, TenantManager tenantManager, - DistributedTaskQueueOptionsManager queueOptions, + DistributedTaskQueueOptionsManager queueOptions, ExportDataOperation exportDataOperation) { _securityContext = securityContext; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs index 5db3ee3c196..673e868bb4e 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCSVSettings.cs @@ -56,14 +56,14 @@ public ImportCSVSettings(String jsonStr) JsonElement duplicateRecordRuleToken; if (jsonElement.TryGetProperty("removing_duplicates_behavior", out duplicateRecordRuleToken)) DuplicateRecordRule = duplicateRecordRuleToken.GetInt32(); - + JsonElement isPrivateToken; if (jsonElement.TryGetProperty("is_private", out isPrivateToken)) { IsPrivate = isPrivateToken.GetBoolean(); AccessList = jsonElement.GetProperty("access_list").EnumerateArray().Select(x => x.GetGuid()).ToList(); } - + JsonElement shareTypeToken; if (jsonElement.TryGetProperty("share_type", out shareTypeToken)) { diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs index d445ffce8f4..3c7931d531a 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportCases.cs @@ -31,7 +31,6 @@ using System.Linq; using System.Text.Json; -using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs index 88b29449933..f8712f5a66f 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDataOperation.cs @@ -25,12 +25,10 @@ using System; -using System.Globalization; using System.Linq; using System.Text.Json; using ASC.Common; -using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Security.Authentication; using ASC.Common.Threading; @@ -115,7 +113,7 @@ public void Configure(EntityType entityType, _importSettings = new ImportCSVSettings(importSettingsJSON); _IsConfigure = true; - } + } public override bool Equals(object obj) { @@ -139,7 +137,7 @@ public object Clone() return MemberwiseClone(); } - + public object Error { get; set; } private String GetPropertyValue(String propertyName) diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs index b23f37e50c3..92fe4b6a69b 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportDeals.cs @@ -32,7 +32,6 @@ using System.Text.Json; using ASC.Core.Users; -using ASC.CRM.Core; using ASC.CRM.Core.Dao; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs index a54c72bd836..353b453c2b7 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportFromCSV.cs @@ -37,8 +37,6 @@ using LumenWorks.Framework.IO.Csv; -using Microsoft.EntityFrameworkCore.Storage; - namespace ASC.Web.CRM.Classes { [Scope] @@ -87,7 +85,8 @@ public String GetRow(Stream CSVFileStream, int index, String jsonSettings) while (countRows++ != index && csv.ReadNextRecord()) ; - return JsonSerializer.Serialize(new { + return JsonSerializer.Serialize(new + { data = csv.GetCurrentRowFields(false).ToArray(), isMaxIndex = csv.EndOfStream }); diff --git a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs index a11c917ba4c..208b1c1a0d4 100644 --- a/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs +++ b/products/ASC.CRM/Server/Utils/Import/CSV/ImportTasks.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Linq; -using ASC.Core; using ASC.Core.Tenants; using ASC.Core.Users; using ASC.CRM.Core.Dao; @@ -59,7 +58,7 @@ public ImportDataOperation(TenantUtil tenantUtil, _importFromCSV = importFromCSV; _displayUserSettingsHelper = displayUserSettingsHelper; } - + private void ImportTaskData(DaoFactory _daoFactory) { using (var CSVFileStream = _dataStore.GetReadStream("temp", _csvFileURI)) diff --git a/products/ASC.CRM/Server/Utils/MailSender.cs b/products/ASC.CRM/Server/Utils/MailSender.cs index d315f164b8e..faa4254a0fa 100644 --- a/products/ASC.CRM/Server/Utils/MailSender.cs +++ b/products/ASC.CRM/Server/Utils/MailSender.cs @@ -39,7 +39,6 @@ using System.Threading; using ASC.Common; -using ASC.Common.Caching; using ASC.Common.Logging; using ASC.Common.Threading; using ASC.Common.Threading.Progress; @@ -54,8 +53,6 @@ using ASC.CRM.Resources; using ASC.Web.Files.Api; -using Autofac; - using MailKit; using MailKit.Net.Smtp; using MailKit.Security; @@ -123,7 +120,7 @@ FilesIntegration filesIntegration _log = logger.Get("ASC.CRM.MailSender"); _tenantID = tenantManager.GetCurrentTenant().TenantId; - + var _crmSettings = settingsManager.Load(); _smtpSetting = new SMTPServerSetting(coreConfiguration.SmtpSettings); diff --git a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs index 9e72cdb63e5..bfe95c9fdc8 100644 --- a/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs +++ b/products/ASC.CRM/Server/Utils/PdfQueueWorker.cs @@ -25,19 +25,13 @@ using System; -using System.Collections.Generic; -using System.Drawing; -using System.Drawing.Imaging; -using System.IO; using System.Linq; -using System.Net; using System.Web; using ASC.Common; using ASC.Common.Threading; using ASC.Common.Threading.Progress; using ASC.Core; -using ASC.CRM.Core.Enums; using log4net; @@ -200,10 +194,10 @@ public override bool Equals(object obj) if (obj is PdfProgressItem) { - return ((PdfProgressItem)obj).Id == Id; + return ((PdfProgressItem)obj).Id == Id; } - return base.Equals(obj); + return base.Equals(obj); } public override int GetHashCode() diff --git a/products/ASC.CRM/Server/Utils/ReportHelper.cs b/products/ASC.CRM/Server/Utils/ReportHelper.cs index ecc04c6d41f..a01547114ef 100644 --- a/products/ASC.CRM/Server/Utils/ReportHelper.cs +++ b/products/ASC.CRM/Server/Utils/ReportHelper.cs @@ -245,7 +245,7 @@ private void SaveReportFile(ReportState state, string url) public ReportState RunGenareteReport(ReportType reportType, ReportTimePeriod timePeriod, Guid[] managers) { var reportData = GetReportData(reportType, timePeriod, managers); - + if (reportData == null) throw new Exception(CRMReportResource.ErrorNullReportData); From fc20a742a16ff7bbbb1ac70456dd30d33c9144a6 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Fri, 4 Jun 2021 19:27:44 +0300 Subject: [PATCH 60/61] crm: refactoring --- .../ASC.CRM/Server/Api/UtilsController.cs | 15 +++-- products/ASC.CRM/Server/Api/VoipController.cs | 48 ++++++-------- .../ApiModels/ResponsesDto/CurrencyInfoDto.cs | 6 +- .../ApiModels/ResponsesDto/VoipCallDto.cs | 4 +- .../Helpers/CurrencyRateInfoDtoHelper.cs | 60 ----------------- .../VoipCallDtoTypeConverter.cs} | 64 +++++++++++++------ products/ASC.CRM/Server/Startup.cs | 1 + 7 files changed, 78 insertions(+), 120 deletions(-) delete mode 100644 products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs rename products/ASC.CRM/Server/{Helpers/VoipCallDtoHelper.cs => Mapping/TypeConverter/VoipCallDtoTypeConverter.cs} (53%) diff --git a/products/ASC.CRM/Server/Api/UtilsController.cs b/products/ASC.CRM/Server/Api/UtilsController.cs index 649ef638923..df390d9df77 100644 --- a/products/ASC.CRM/Server/Api/UtilsController.cs +++ b/products/ASC.CRM/Server/Api/UtilsController.cs @@ -36,6 +36,7 @@ using ASC.CRM.ApiModels; using ASC.CRM.Core; using ASC.CRM.Core.Dao; +using ASC.CRM.Core.EF; using ASC.CRM.Core.Entities; using ASC.CRM.Core.Enums; using ASC.CRM.Resources; @@ -58,7 +59,6 @@ public class UtilsController : BaseApiController private readonly OrganisationLogoManager _organisationLogoManager; private readonly ImportFromCSVManager _importFromCSVManager; private readonly InvoiceSetting _invoiceSetting; - private readonly CurrencyRateInfoDtoHelper _currencyRateInfoDtoHelper; private readonly SettingsManager _settingsManager; private readonly CurrencyProvider _currencyProvider; private readonly MessageService _messageService; @@ -68,7 +68,6 @@ public UtilsController(CrmSecurity crmSecurity, MessageService messageService, SettingsManager settingsManager, CurrencyProvider currencyProvider, - CurrencyRateInfoDtoHelper currencyRateInfoDtoHelper, InvoiceSetting invoiceSetting, ImportFromCSVManager importFromCSVManager, OrganisationLogoManager organisationLogoManager, @@ -81,7 +80,6 @@ public UtilsController(CrmSecurity crmSecurity, _messageService = messageService; _currencyProvider = currencyProvider; _settingsManager = settingsManager; - _currencyRateInfoDtoHelper = currencyRateInfoDtoHelper; _invoiceSetting = invoiceSetting; _importFromCSVManager = importFromCSVManager; _organisationLogoManager = organisationLogoManager; @@ -145,9 +143,16 @@ public IEnumerable GetSummaryTable(String currency) if (cur == null) throw new ArgumentException(); - var table = _currencyProvider.MoneyConvert(cur); + var table = _currencyProvider.MoneyConvert(cur).ToList(); - table.ToList().ForEach(tableItem => result.Add(_currencyRateInfoDtoHelper.Get(tableItem.Key, tableItem.Value))); + foreach (var row in table) + { + var currencyInfoDto = _mapper.Map(row.Key); + + currencyInfoDto.Rate = row.Value; + + result.Add(currencyInfoDto); + } return result; } diff --git a/products/ASC.CRM/Server/Api/VoipController.cs b/products/ASC.CRM/Server/Api/VoipController.cs index bfb60485a78..d5462fd574f 100644 --- a/products/ASC.CRM/Server/Api/VoipController.cs +++ b/products/ASC.CRM/Server/Api/VoipController.cs @@ -53,6 +53,8 @@ using AutoMapper; +using Grpc.Core; + using Microsoft.AspNetCore.Mvc; using SecurityContext = ASC.Core.SecurityContext; @@ -65,7 +67,6 @@ public class VoIPController : BaseApiController private readonly ApiContext _apiContext; private readonly VoipEngine _voipEngine; private readonly TenantUtil _tenantUtil; - private readonly VoipCallDtoHelper _voipCallDtoHelper; private readonly SecurityContext _securityContext; private readonly CommonLinkUtility _commonLinkUtility; private readonly StorageFactory _storageFactory; @@ -79,7 +80,6 @@ public VoIPController(CrmSecurity crmSecurity, StorageFactory storageFactory, CommonLinkUtility commonLinkUtility, SecurityContext securityContext, - VoipCallDtoHelper voipCallDtoHelper, TenantUtil tenantUtil, VoipEngine voipEngine, ApiContext apiContext, @@ -92,7 +92,6 @@ public VoIPController(CrmSecurity crmSecurity, _storageFactory = storageFactory; _commonLinkUtility = commonLinkUtility; _securityContext = securityContext; - _voipCallDtoHelper = voipCallDtoHelper; _tenantUtil = tenantUtil; _voipEngine = voipEngine; _apiContext = apiContext; @@ -677,7 +676,7 @@ public VoipCallDto MakeCall([FromForm] string to, [FromForm] string contactId) var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture)); - return _voipCallDtoHelper.Get(call, contact); + return _mapper.Map(call); } @@ -696,7 +695,7 @@ public VoipCallDto AnswerCall([FromRoute] string callId) number.AnswerQueueCall(call.Id); - return _voipCallDtoHelper.Get(call); + return _mapper.Map(call); } @@ -715,7 +714,7 @@ public VoipCallDto RejectCall([FromRoute] string callId) number.RejectQueueCall(call.Id); - return _voipCallDtoHelper.Get(call); + return _mapper.Map(call); } /// @@ -744,7 +743,8 @@ public VoipCallDto ReditectCall([FromRoute] string callId, [FromForm] string to) } number.RedirectCall(call.Id, to); - return _voipCallDtoHelper.Get(call); + + return _mapper.Map(call); } /// @@ -826,19 +826,7 @@ public VoipCallDto SaveCall( call = dao.SaveOrUpdateCall(call); - if (call.ContactId == 0) return _voipCallDtoHelper.Get(call); - - try - { - var contact = _mapper.Map(_daoFactory.GetContactDao().GetByID(call.ContactId)); - contact = GetContactWithFotos(contact); - - return _voipCallDtoHelper.Get(call, contact); - } - catch (Exception) - { - return _voipCallDtoHelper.Get(call); - } + return _mapper.Map(call); } @@ -909,7 +897,11 @@ public IEnumerable GetCalls(string callType, ApiDateTime from, ApiD contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } - return _voipCallDtoHelper.Get(r, contact); + var item = _mapper.Map(r); + + item.Contact = contact; + + return item; }).ToList(); @@ -947,7 +939,11 @@ public IEnumerable GetMissedCalls() contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 }; } - return _voipCallDtoHelper.Get(r, contact); + var item = _mapper.Map(r); + + item.Contact = contact; + + return item; }).ToList(); @@ -972,13 +968,7 @@ public VoipCallDto GetCall(string callId) _voipEngine.GetContact(call); - if (call.ContactId == 0) return _voipCallDtoHelper.Get(call); - - var contact = _mapper.Map(_daoFactory.GetContactDao().GetByID(call.ContactId)); - - contact = GetContactWithFotos(contact); - - return _voipCallDtoHelper.Get(call, contact); + return _mapper.Map(call); } private ContactDto GetContactWithFotos(ContactDto contact) diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs index 81f767ac37e..10bbaaf3ba8 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/CurrencyInfoDto.cs @@ -28,7 +28,9 @@ using ASC.Common.Mapping; +using ASC.Core.Common.EF; using ASC.CRM.Core; +using ASC.Web.Core.Calendars; using AutoMapper; @@ -63,10 +65,6 @@ public static CurrencyInfoDto GetSample() }; } - public void Mapping(Profile profile) - { - profile.CreateMap(); - } } /// diff --git a/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs index b112a219fce..c59c04e12cf 100644 --- a/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs +++ b/products/ASC.CRM/Server/ApiModels/ResponsesDto/VoipCallDto.cs @@ -28,12 +28,13 @@ using ASC.Api.Core; +using ASC.Common.Mapping; using ASC.VoipService; using ASC.Web.Api.Models; namespace ASC.CRM.ApiModels { - public class VoipCallDto + public class VoipCallDto : IMapFrom { public string Id { get; set; } public string From { get; set; } @@ -49,4 +50,5 @@ public class VoipCallDto public int RecordDuration { get; set; } } + } \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs b/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs deleted file mode 100644 index 26e19cfa90a..00000000000 --- a/products/ASC.CRM/Server/Helpers/CurrencyRateInfoDtoHelper.cs +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2018 - * - * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU - * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html). - * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that - * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights. - * - * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR - * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html - * - * You can contact Ascensio System SIA by email at sales@onlyoffice.com - * - * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display - * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3. - * - * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains - * relevant author attributions when distributing the software. If the display of the logo in its graphic - * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE" - * in every copy of the program you distribute. - * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks. - * -*/ - - -using ASC.Common; -using ASC.CRM.Core; - -using AutoMapper; - -namespace ASC.CRM.ApiModels -{ - [Scope] - public class CurrencyRateInfoDtoHelper - { - private readonly IMapper _mapper; - - public CurrencyRateInfoDtoHelper(IMapper mapper) - { - _mapper = mapper; - } - - public CurrencyRateInfoDto Get(CurrencyInfo currencyInfo, decimal rate) - { - var currencyInfoDto = _mapper.Map(currencyInfo); - - return new CurrencyRateInfoDto - { - Abbreviation = currencyInfoDto.Abbreviation, - CultureName = currencyInfoDto.CultureName, - Symbol = currencyInfoDto.Symbol, - Title = currencyInfoDto.Title, - IsConvertable = currencyInfoDto.IsConvertable, - IsBasic = currencyInfoDto.IsBasic, - Rate = rate - }; - } - } -} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs b/products/ASC.CRM/Server/Mapping/TypeConverter/VoipCallDtoTypeConverter.cs similarity index 53% rename from products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs rename to products/ASC.CRM/Server/Mapping/TypeConverter/VoipCallDtoTypeConverter.cs index 76b397e2e4e..7ce2da0db42 100644 --- a/products/ASC.CRM/Server/Helpers/VoipCallDtoHelper.cs +++ b/products/ASC.CRM/Server/Mapping/TypeConverter/VoipCallDtoTypeConverter.cs @@ -23,52 +23,74 @@ * */ - +using System; using System.Linq; using ASC.Api.Core; using ASC.Common; +using ASC.CRM.ApiModels; +using ASC.CRM.Core; +using ASC.CRM.Core.Dao; +using ASC.CRM.Core.Entities; +using ASC.CRM.Core.Enums; using ASC.VoipService; using ASC.Web.Api.Models; -namespace ASC.CRM.ApiModels +using AutoMapper; + +using Grpc.Core; + +namespace ASC.CRM.Mapping { [Scope] - public class VoipCallDtoHelper + public class VoipCallDtoTypeConverter : ITypeConverter { private readonly ApiDateTimeHelper _apiDateTimeHelper; private readonly EmployeeWraperHelper _employeeWraperHelper; + private readonly DaoFactory _daoFactory; - public VoipCallDtoHelper(EmployeeWraperHelper employeeWraper, - ApiDateTimeHelper apiDateTimeHelper) + public VoipCallDtoTypeConverter(ApiDateTimeHelper apiDateTimeHelper, + EmployeeWraperHelper employeeWraperHelper, + DaoFactory daoFactory) { - _employeeWraperHelper = employeeWraper; + _daoFactory = daoFactory; _apiDateTimeHelper = apiDateTimeHelper; + _employeeWraperHelper = employeeWraperHelper; } - public VoipCallDto Get(VoipCall call, ContactDto contact = null) + public VoipCallDto Convert(VoipCall source, VoipCallDto destination, ResolutionContext context) { + if (destination != null) + throw new NotImplementedException(); + var result = new VoipCallDto { - Id = call.Id, - From = call.From, - To = call.To, - Status = call.Status, - AnsweredBy = _employeeWraperHelper.Get(call.AnsweredBy), - DialDate = _apiDateTimeHelper.Get(call.DialDate), - DialDuration = call.DialDuration, - Cost = call.Price + call.ChildCalls.Sum(r => r.Price) + call.VoipRecord.Price, - Contact = contact, - RecordUrl = call.VoipRecord.Uri, - RecordDuration = call.VoipRecord.Duration + Id = source.Id, + From = source.From, + To = source.To, + Status = source.Status, + AnsweredBy = _employeeWraperHelper.Get(source.AnsweredBy), + DialDate = _apiDateTimeHelper.Get(source.DialDate), + DialDuration = source.DialDuration, + Cost = source.Price + source.ChildCalls.Sum(r => r.Price) + source.VoipRecord.Price, + RecordUrl = source.VoipRecord.Uri, + RecordDuration = source.VoipRecord.Duration }; - if (call.ChildCalls.Any()) + if (source.ContactId > 0) +{ + result.Contact = context.Mapper.Map(_daoFactory.GetContactDao().GetByID(source.ContactId)); + } + + if (source.ChildCalls.Any()) { - result.Calls = call.ChildCalls.Select(childCall => Get(childCall)); + result.Calls = source.ChildCalls.Select(childCall => context.Mapper.Map(childCall)); } + return result; } } -} \ No newline at end of file +} + + diff --git a/products/ASC.CRM/Server/Startup.cs b/products/ASC.CRM/Server/Startup.cs index 8a1bd6ac061..e38fad6353a 100644 --- a/products/ASC.CRM/Server/Startup.cs +++ b/products/ASC.CRM/Server/Startup.cs @@ -63,6 +63,7 @@ public override void ConfigureServices(IServiceCollection services) DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); + DIHelper.TryAdd(); DIHelper.TryAdd(); DIHelper.TryAdd(); From 89264cc48d2c1860efe4fbd46bbda0bb7cb765d1 Mon Sep 17 00:00:00 2001 From: Alexey Bannov Date: Tue, 15 Jun 2021 13:41:17 +0300 Subject: [PATCH 61/61] crm: created common project for common services --- ASC.Web.sln | 6 ++ build/run/CrmBackgroundTasks.bat | 2 + build/run/CrmServer.bat | 2 +- .../ASC.CRM.BackgroundTasks.csproj | 8 ++ products/ASC.CRM/BackgroundTasks/Program.cs | 93 +++++++++++++++++++ .../Properties/launchSettings.json | 27 ++++++ .../ASC.CRM/BackgroundTasks/appsettings.json | 3 + products/ASC.CRM/BackgroundTasks/search.json | 76 +++++++++++++++ products/ASC.CRM/Server/Program.cs | 6 +- 9 files changed, 217 insertions(+), 6 deletions(-) create mode 100644 build/run/CrmBackgroundTasks.bat create mode 100644 products/ASC.CRM/BackgroundTasks/ASC.CRM.BackgroundTasks.csproj create mode 100644 products/ASC.CRM/BackgroundTasks/Program.cs create mode 100644 products/ASC.CRM/BackgroundTasks/Properties/launchSettings.json create mode 100644 products/ASC.CRM/BackgroundTasks/appsettings.json create mode 100644 products/ASC.CRM/BackgroundTasks/search.json diff --git a/ASC.Web.sln b/ASC.Web.sln index 7b5fd23d0d6..f8af10e8e5f 100644 --- a/ASC.Web.sln +++ b/ASC.Web.sln @@ -87,6 +87,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Calendar", "products\AS EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.SsoAuth.Svc", "common\services\ASC.SsoAuth.Svc\ASC.SsoAuth.Svc.csproj", "{6AD828EA-FBA2-4D30-B969-756B3BE78E4E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.CRM.BackgroundTasks", "products\ASC.CRM\BackgroundTasks\ASC.CRM.BackgroundTasks.csproj", "{E52C0E35-A05C-437F-8FF2-3E0AC9F81433}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -245,6 +247,10 @@ Global {6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Debug|Any CPU.Build.0 = Debug|Any CPU {6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Release|Any CPU.ActiveCfg = Release|Any CPU {6AD828EA-FBA2-4D30-B969-756B3BE78E4E}.Release|Any CPU.Build.0 = Release|Any CPU + {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build/run/CrmBackgroundTasks.bat b/build/run/CrmBackgroundTasks.bat new file mode 100644 index 00000000000..0e43feef227 --- /dev/null +++ b/build/run/CrmBackgroundTasks.bat @@ -0,0 +1,2 @@ +echo "RUN ASC.CRM.BackgroundTasks" +call dotnet run --project ..\..\products\ASC.CRM\BackgroundTasks\ASC.CRM.BackgroundTasks.csproj --no-build --$STORAGE_ROOT=..\..\..\Data --log__dir=..\..\..\Logs --log__name=crm \ No newline at end of file diff --git a/build/run/CrmServer.bat b/build/run/CrmServer.bat index e7b7ed0acd5..ed214856031 100644 --- a/build/run/CrmServer.bat +++ b/build/run/CrmServer.bat @@ -1,2 +1,2 @@ -echo "RUN ASC.CRM" +echo "RUN ASC.CRM.Server" call dotnet run --project ..\..\products\ASC.CRM\Server\ASC.CRM.csproj --no-build --$STORAGE_ROOT=..\..\..\Data --log__dir=..\..\..\Logs --log__name=crm \ No newline at end of file diff --git a/products/ASC.CRM/BackgroundTasks/ASC.CRM.BackgroundTasks.csproj b/products/ASC.CRM/BackgroundTasks/ASC.CRM.BackgroundTasks.csproj new file mode 100644 index 00000000000..27569b88aea --- /dev/null +++ b/products/ASC.CRM/BackgroundTasks/ASC.CRM.BackgroundTasks.csproj @@ -0,0 +1,8 @@ + + + net5.0 + + + + + diff --git a/products/ASC.CRM/BackgroundTasks/Program.cs b/products/ASC.CRM/BackgroundTasks/Program.cs new file mode 100644 index 00000000000..5445498c51a --- /dev/null +++ b/products/ASC.CRM/BackgroundTasks/Program.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +using ASC.Common; +using ASC.Common.Caching; +using ASC.Common.Logging; +using ASC.Common.Utils; +using ASC.ElasticSearch; +using ASC.Web.CRM.Core.Search; + +using Autofac; +using Autofac.Extensions.DependencyInjection; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using ASC.Common.DependencyInjection; + + +namespace ASC.CRM.BackgroundTasks +{ + class Program + { + public async static Task Main(string[] args) + { + var host = CreateHostBuilder(args).Build(); + + await host.RunAsync(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .UseSystemd() + .UseWindowsService() + .UseServiceProviderFactory(new AutofacServiceProviderFactory()) + .ConfigureAppConfiguration((hostContext, config) => + { + var buided = config.Build(); + var path = buided["pathToConf"]; + if (!Path.IsPathRooted(path)) + { + path = Path.GetFullPath(CrossPlatform.PathCombine(hostContext.HostingEnvironment.ContentRootPath, path)); + } + config.SetBasePath(path); + var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); + config + .AddInMemoryCollection(new Dictionary + { + {"pathToConf", path } + } + ) + .AddJsonFile("appsettings.json") + .AddJsonFile($"appsettings.{env}.json", true) + .AddJsonFile($"appsettings.services.json", true) + .AddJsonFile("storage.json") + .AddJsonFile("notify.json") + .AddJsonFile("kafka.json") + .AddJsonFile($"kafka.{env}.json", true) + .AddEnvironmentVariables() + .AddCommandLine(args); + }) + .ConfigureServices((hostContext, services) => + { + services.AddMemoryCache(); + + var diHelper = new DIHelper(services); + + diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>)); + + diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath); + + services.AddHostedService(); + diHelper.TryAdd(); + + LogNLogExtension.ConfigureLog(diHelper, "ASC.Files", "ASC.Feed.Agregator"); + + diHelper.TryAdd(); + diHelper.TryAdd(); + diHelper.TryAdd(); + diHelper.TryAdd(); + diHelper.TryAdd(); + diHelper.TryAdd(); + diHelper.TryAdd(); + diHelper.TryAdd(); + }) + .ConfigureContainer((context, builder) => + { + builder.Register(context.Configuration, true, false, "search.json"); + }); + } +} diff --git a/products/ASC.CRM/BackgroundTasks/Properties/launchSettings.json b/products/ASC.CRM/BackgroundTasks/Properties/launchSettings.json new file mode 100644 index 00000000000..cad5cdec51b --- /dev/null +++ b/products/ASC.CRM/BackgroundTasks/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "profiles": { + "Kestrel WebServer": { + "commandName": "Project", + "launchBrowser": false, + "environmentVariables": { + "$STORAGE_ROOT": "../../../Data", + "log__dir": "../../../Logs", + "log__name": "crm", + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_URLS": "http://localhost:5026" + } + }, + "WSL 2 : Ubuntu 20.04": { + "commandName": "WSL2", + "launchBrowser": false, + "environmentVariables": { + "$STORAGE_ROOT": "../../../Data", + "log__dir": "../../../Logs", + "log__name": "crm", + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_URLS": "http://localhost:5026" + }, + "distributionName": "Ubuntu-20.04" + } + } +} \ No newline at end of file diff --git a/products/ASC.CRM/BackgroundTasks/appsettings.json b/products/ASC.CRM/BackgroundTasks/appsettings.json new file mode 100644 index 00000000000..9bf702e3108 --- /dev/null +++ b/products/ASC.CRM/BackgroundTasks/appsettings.json @@ -0,0 +1,3 @@ +{ + "pathToConf": "..\\..\\..\\config" +} diff --git a/products/ASC.CRM/BackgroundTasks/search.json b/products/ASC.CRM/BackgroundTasks/search.json new file mode 100644 index 00000000000..2138b66a234 --- /dev/null +++ b/products/ASC.CRM/BackgroundTasks/search.json @@ -0,0 +1,76 @@ +{ + "components": [ + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerCase, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + }, + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerContact, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + }, + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerContactInfo, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + }, + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerDeal, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + }, + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerEvents, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + }, + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerFieldValue, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + }, + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerInvoice, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + }, + { + "type": "ASC.Web.CRM.Core.Search.FactoryIndexerTask, ASC.CRM", + "services": [ + { + "type": "ASC.ElasticSearch.IFactoryIndexer, ASC.ElasticSearch" + } + ], + "instanceScope": "perlifetimescope" + } + ] +} \ No newline at end of file diff --git a/products/ASC.CRM/Server/Program.cs b/products/ASC.CRM/Server/Program.cs index ff40afee444..8e70bacd1d5 100644 --- a/products/ASC.CRM/Server/Program.cs +++ b/products/ASC.CRM/Server/Program.cs @@ -74,10 +74,6 @@ public static IHostBuilder CreateHostBuilder(string[] args) => { {"pathToConf", path} }); - }) - .ConfigureContainer((context, builder) => - { - builder.Register(context.Configuration, true, false); - });//if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common"))//{// FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider());//}////Register prodjects' calendar events//CalendarManager.Instance.RegistryCalendarProvider(userid =>//{// if (WebItemSecurity.IsAvailableForUser(WebItemManager.CRMProductID, userid))// {// return new List { new CRMCalendar(userid) };// }// return new List();//}); + }); } }