/// <summary> /// Отправка ответа контрагенту. /// </summary> /// <param name="document">Документ, по которому требуется отправка ответа.</param> /// <param name="documentInfo">Информация о документе, связанная с коммуникацией с контрагентом.</param> /// <param name="addenda">Приложения.</param> public static void SendAnswerToCounterparty(Docflow.IOfficialDocument document, Sungero.Exchange.Structures.Module.SendToCounterpartyInfo documentInfo, List <Docflow.IOfficialDocument> addenda) { var dialog = Dialogs.CreateInputDialog(Resources.SendAnswerToCounterpartyDialogTitle); dialog.HelpCode = Constants.Module.HelpCodes.SendAnswerOnDocument; var positiveResult = Resources.SendCounterpartyPositiveResult; var amendmentResult = Resources.SendCounterpartyNegativeResult; var invoiceAmendmentResult = Resources.SendCounterpartyRejectResult; var allowedResults = new List <string>(); if (documentInfo.CanSendSignAsAnswer) { allowedResults.Add(positiveResult); } if (documentInfo.CanSendInvoiceAmendmentRequestAsAnswer) { allowedResults.Add(invoiceAmendmentResult); } if (documentInfo.CanSendAmendmentRequestAsAnswer) { allowedResults.Add(amendmentResult); } var formParams = ((Domain.Shared.IExtendedEntity)document).Params; var signAndSend = formParams.ContainsKey(Exchange.PublicConstants.Module.DefaultSignResult) && (bool)formParams[Exchange.PublicConstants.Module.DefaultSignResult]; var defaultSignResult = documentInfo.IsSignedByUs || signAndSend == true? allowedResults.FirstOrDefault() : allowedResults.LastOrDefault(); var signResult = dialog.AddSelect(Resources.SendCounterpartyResult, true, defaultSignResult) .From(allowedResults.ToArray()); var counterparty = dialog.AddSelect(Resources.SendCounterpartyReceiver, true, documentInfo.DefaultCounterparty); counterparty.IsEnabled = false; var box = dialog.AddSelect(Resources.SendCounterpartySender, true, documentInfo.DefaultBox); box.IsEnabled = false; var users = new List <Sungero.CoreEntities.IUser>(); if (documentInfo.Certificates.Certificates != null) { users = documentInfo.Certificates.Certificates.Select(c => c.Owner).ToList(); } var signatureOwner = dialog.AddSelect(Docflow.OfficialDocuments.Info.Properties.OurSignatory.LocalizedName, false, users.FirstOrDefault()) .From(users); signatureOwner.IsEnabled = documentInfo.IsSignedByUs; var allowedAddenda = documentInfo.Addenda.Select(a => a.Addendum).ToList(); var defaultSelectedAddenda = addenda.Intersect(allowedAddenda).ToArray(); var selectedAddenda = dialog.AddSelectMany(Resources.SendCounterpartyAddenda, false, defaultSelectedAddenda) .From(allowedAddenda); selectedAddenda.IsEnabled = documentInfo.HasAddendaToSend; var comment = dialog.AddMultilineString(Resources.SendCounterpartyComment, false); comment.IsEnabled = defaultSignResult != positiveResult; var sendButton = dialog.Buttons.AddCustom(Resources.SendCounterpartySendButton); dialog.Buttons.Default = sendButton; dialog.Buttons.AddCancel(); var currentUserSelectedCertificate = Certificates.Null; if (!documentInfo.IsSignedByUs && !documentInfo.Certificates.MyCertificates.Any()) { Dialogs.NotifyMessage(Resources.NotificationNoCertificates); return; } signResult.SetOnValueChanged(x => { if (x.NewValue != x.OldValue) { if (x.NewValue != positiveResult) { signatureOwner.Value = null; signatureOwner.IsEnabled = false; comment.IsEnabled = true; } else { signatureOwner.Value = users.FirstOrDefault(); signatureOwner.IsEnabled = documentInfo.IsSignedByUs; comment.Value = string.Empty; comment.IsEnabled = false; } } }); dialog.SetOnButtonClick(x => { if (x.Button == sendButton && x.IsValid) { var hasExchangeWithCounterparty = counterparty.Value.ExchangeBoxes .Any(c => Equals(c.Box, box.Value) && Equals(c.Status, Parties.CounterpartyExchangeBoxes.Status.Active) && c.IsDefault == true); if (!hasExchangeWithCounterparty) { x.AddError(Exchange.Resources.NoExchangeThroughThisService); return; } if (IsLocked(document, x)) { return; } if (comment.Value != null && comment.Value.Length > 1000) { x.AddError(Exchange.ExchangeDocumentProcessingAssignments.Resources.TextOverlong, comment); return; } if (signResult.Value == Resources.SendCounterpartyPositiveResult) { #region Отправка подписи if (signatureOwner.Value == null && documentInfo.IsSignedByUs && !documentInfo.Certificates.CanSign) { x.AddError(Resources.SendCounterpartyCertificateNotSelected); return; } var noSign = signatureOwner.Value == null; if (noSign) { if (!documentInfo.Certificates.CanSign) { x.AddError(Resources.NotificationNoCertificates); return; } var signDialog = Dialogs.CreateTaskDialog(Resources.SendCounterpartySignAndSendQuestion); var signButtons = signDialog.Buttons.AddCustom(Resources.SendCounterpartySignAndSendButton); signDialog.Buttons.AddCancel(); if (signDialog.Show() == signButtons) { try { if (IsLocked(document, x)) { return; } currentUserSelectedCertificate = GetCurrentUserExchangeCertificate(box.Value, Company.Employees.Current); List <Docflow.IOfficialDocument> lockedDocuments = new List <Docflow.IOfficialDocument>(); foreach (Docflow.IOfficialDocument docAddendum in selectedAddenda.Value) { if (docAddendum.LastVersion != null) { var bodyAddendum = docAddendum.LastVersion.PublicBody; var lockInfoAddendum = Locks.GetLockInfo(bodyAddendum); if (lockInfoAddendum != null) { if (lockInfoAddendum.IsLockedByOther) { x.AddError(lockInfoAddendum.LockedMessage); return; } else if (!lockInfoAddendum.IsLocked) { Locks.TryLock(bodyAddendum); lockedDocuments.Add(docAddendum); } } } } if (currentUserSelectedCertificate == null || !Docflow.PublicFunctions.Module .ApproveWithAddenda(document, selectedAddenda.Value.ToList(), currentUserSelectedCertificate, null, true, true, string.Empty)) { UnlockAddenda(lockedDocuments); x.AddError(Resources.NotificationNoCertificates); return; } UnlockAddenda(lockedDocuments); signatureOwner.Value = Users.Current; documentInfo.Certificates = Functions.Module.Remote.GetDocumentCertificatesToBox(document, box.Value); } catch (Exception ex) { x.AddError(ex.Message); return; } } else { return; } } try { var certificate = signatureOwner.Value == null ? null : documentInfo.Certificates.Certificates.Single(c => Equals(c.Owner, signatureOwner.Value)); var documentsToSend = new List <Docflow.IOfficialDocument>() { document }; documentsToSend.AddRange(selectedAddenda.Value); Functions.Module.Remote.SendAnswers(documentsToSend, counterparty.Value, box.Value, certificate, false); if (Equals(certificate.Owner, Company.Employees.Current)) { Functions.Module.SendDeliveryConfirmation(box.Value, certificate, false); } else { Functions.Module.SendDeliveryConfirmation(box.Value, null, false); } } catch (AppliedCodeException ex) { x.AddError(ex.Message); return; } catch (Exception ex) { Logger.ErrorFormat("Error sending sign: ", ex); x.AddError(Resources.ErrorWhileSendingSignToCounterparty); return; } Dialogs.NotifyMessage(Resources.SendAnswerCounterpartySuccessfully); #endregion } else { #region Отправка отказа в подписании currentUserSelectedCertificate = GetCurrentUserExchangeCertificate(box.Value, Company.Employees.Current); if (currentUserSelectedCertificate != null) { var documents = selectedAddenda.Value.ToList(); documents.Add(document); var error = SendAmendmentRequest(documents, counterparty.Value, comment.Value, false, box.Value, currentUserSelectedCertificate, signResult.Value == invoiceAmendmentResult); Functions.Module.SendDeliveryConfirmation(box.Value, currentUserSelectedCertificate, false); if (!string.IsNullOrWhiteSpace(error)) { x.AddError(error); } else { Dialogs.NotifyMessage(Resources.SendAnswerCounterpartySuccessfully); } } else { x.AddError(Resources.RejectCertificateNotFound); } #endregion } } }); dialog.Show(); }
/// <summary> /// Отправка последней версии документа контрагенту. /// </summary> /// <param name="document">Документ для отправки.</param> /// <param name="documentInfo">Информация о документе, связанная с коммуникацией с контрагентом.</param> /// <param name="service">Сервис обмена.</param> /// <param name="addenda">Приложения.</param> public static void SendDocumentToCounterparty(Docflow.IOfficialDocument document, Sungero.Exchange.Structures.Module.SendToCounterpartyInfo documentInfo, ExchangeCore.IExchangeService service, List <Docflow.IOfficialDocument> addenda) { if (!documentInfo.CanApprove && !documentInfo.HasApprovalSignature) { Dialogs.NotifyMessage(Resources.SendCounterpartyNotApproved); return; } var dialog = Dialogs.CreateInputDialog(Resources.SendCounterpartyDialogTitle); dialog.HelpCode = Constants.Module.HelpCodes.SendDocument; var counterparty = dialog.AddSelect(Resources.SendCounterpartyReceiver, true, documentInfo.DefaultCounterparty) .From(documentInfo.Counterparties) .Where(x => x.Status == CoreEntities.DatabookEntry.Status.Active); var defaultBox = documentInfo.Boxes.FirstOrDefault(x => Equals(x.ExchangeService, service)) ?? documentInfo.DefaultBox; var box = dialog.AddSelect(Resources.SendCounterpartySender, true, defaultBox) .From(documentInfo.Boxes) .Where(x => x.Status == CoreEntities.DatabookEntry.Status.Active); box.IsEnabled = !(Docflow.AccountingDocumentBases.Is(document) && Docflow.AccountingDocumentBases.As(document).IsFormalized == true); var users = documentInfo.Certificates.Certificates.Select(c => c.Owner).ToList(); var signatureOwner = dialog.AddSelect(Docflow.OfficialDocuments.Info.Properties.OurSignatory.LocalizedName, false, users.FirstOrDefault()) .From(users); signatureOwner.IsEnabled = documentInfo.IsSignedByUs; var allowedAddenda = documentInfo.Addenda.Select(a => a.Addendum).ToList(); var defaultSelectedAddenda = addenda.Intersect(allowedAddenda).ToArray(); var selectedAddenda = dialog.AddSelectMany(Resources.SendCounterpartyAddenda, false, defaultSelectedAddenda) .From(allowedAddenda); selectedAddenda.IsEnabled = documentInfo.HasAddendaToSend; var needSign = dialog.AddBoolean(Resources.SendCounterpartyNeedSign, false); if (Docflow.AccountingDocumentBases.Is(document) && Docflow.AccountingDocumentBases.As(document).IsFormalized == true) { var accDocument = Docflow.AccountingDocumentBases.As(document); var isSF = accDocument.FormalizedFunction == Docflow.AccountingDocumentBase.FormalizedFunction.Schf; var isWaybill = FinancialArchive.Waybills.Is(document); var isContractStatement = FinancialArchive.ContractStatements.Is(document); var isUPD = FinancialArchive.UniversalTransferDocuments.Is(document); var isDiadoc = accDocument.BusinessUnitBox.ExchangeService.ExchangeProvider == ExchangeCore.ExchangeService.ExchangeProvider.Diadoc; var isDiadocUPD = isUPD && isDiadoc; var isDiadocContractStatement = isContractStatement && isDiadoc; needSign.Value = isWaybill || isUPD || isContractStatement; needSign.IsEnabled = !(isWaybill || isSF || isDiadocUPD || isDiadocContractStatement); } else { needSign.Value = Docflow.ContractualDocumentBases.Is(document); } var comment = dialog.AddMultilineString(Resources.SendCounterpartyComment, false); var sendButton = dialog.Buttons.AddCustom(Resources.SendCounterpartySendButton); dialog.Buttons.Default = sendButton; dialog.Buttons.AddCancel(); dialog.SetOnRefresh(x => { if (x.IsValid && documentInfo.Certificates.CanSign && signatureOwner.Value == null) { x.AddInformation(Resources.SendCounterpartySignAndSendHint); } if (selectedAddenda.Value != null) { var exchangeDocumentsSize = selectedAddenda.Value.Select(s => s.LastVersion.Body.Size).Sum() + document.LastVersion.Body.Size; if (exchangeDocumentsSize >= Constants.Module.ExchangeDocumentMaxSize) { x.AddError(Resources.AddendaOversized); } } if (counterparty.Value != null) { var boxes = counterparty.Value.ExchangeBoxes.Where(b => b.Box.Status == ExchangeCore.BusinessUnitBox.Status.Active && b.Box.ConnectionStatus == ExchangeCore.BusinessUnitBox.ConnectionStatus.Connected && b.Status == Parties.CounterpartyExchangeBoxes.Status.Active && b.IsDefault == true); if (!boxes.Any()) { x.AddError(Resources.BoxesNotFound); } } }); counterparty.SetOnValueChanged(x => { if (x.NewValue != x.OldValue) { var newCounterpartyList = documentInfo.Counterparties; if (x.NewValue != null) { newCounterpartyList = documentInfo.Counterparties.Where(c => c.Equals(x.NewValue)).ToList(); } documentInfo.Boxes = Functions.Module.Remote.GetConnectedExchangeBoxesToCounterparty(document, newCounterpartyList); box = box.From(documentInfo.Boxes); // Если ящик не был выбран или был выбран ящик, через который нет обмена с выбранным контрагентом, или был выбран ящик, отличный от Synerdocs, // заполнить поле первым подходящим ящиком. if (box.Value == null || !documentInfo.Boxes.Contains(box.Value) || box.Value.ExchangeService.ExchangeProvider != ExchangeCore.ExchangeService.ExchangeProvider.Synerdocs) { box.Value = documentInfo.Boxes.FirstOrDefault(); } } }); box.SetOnValueChanged(x => { if (x.NewValue != x.OldValue) { if (x.NewValue != null) { documentInfo.Certificates = Functions.Module.Remote.GetDocumentCertificatesToBox(document, x.NewValue); documentInfo.IsSignedByUs = documentInfo.Certificates.Certificates.Any(); } else { documentInfo.Certificates = Structures.Module.DocumentCertificatesInfo .Create(new List <ICertificate>(), false, new List <ICertificate>()); documentInfo.IsSignedByUs = false; } users = documentInfo.Certificates.Certificates.Select(c => c.Owner).ToList(); signatureOwner = signatureOwner.From(users); signatureOwner.Value = users.FirstOrDefault(); signatureOwner.IsEnabled = documentInfo.IsSignedByUs; } }); dialog.SetOnButtonClick(x => { if (x.Button == sendButton && x.IsValid) { var hasExchangeWithCounterparty = counterparty.Value.ExchangeBoxes .Any(c => Equals(c.Box, box.Value) && Equals(c.Status, Parties.CounterpartyExchangeBoxes.Status.Active) && c.IsDefault == true); if (!hasExchangeWithCounterparty) { x.AddError(Exchange.Resources.NoExchangeThroughThisService); return; } if (signatureOwner.Value == null && documentInfo.IsSignedByUs && !documentInfo.Certificates.CanSign) { x.AddError(Resources.SendCounterpartyCertificateNotSelected); return; } if (IsLocked(document, x)) { return; } foreach (var addendumDocument in selectedAddenda.Value) { if (IsLocked(addendumDocument, x)) { return; } } if (Functions.ExchangeDocumentInfo.Remote.LastVersionSended(document, box.Value, counterparty.Value)) { x.AddError(Resources.DocumentIsAlreadySentToCounterparty); return; } var noSign = signatureOwner.Value == null; var certificate = documentInfo.Certificates.Certificates.FirstOrDefault(c => Equals(c.Owner, signatureOwner.Value)); ICertificate certificateToRejectFirstVersion = null; if (noSign) { if (!documentInfo.Certificates.CanSign) { if (selectedAddenda.Value.Any()) { x.AddError(Resources.SendCounterpartyWithAddendaWhenDocumentNotSigned); } else { x.AddError(Resources.SendCounterpartyCanNotSign); } return; } var signDialog = Dialogs.CreateTaskDialog(Resources.SendCounterpartySignAndSendQuestion); var signButtons = signDialog.Buttons.AddCustom(Resources.SendCounterpartySignAndSendButton); signDialog.Buttons.AddCancel(); if (signDialog.Show() == signButtons) { try { if (IsLocked(document, x)) { return; } certificate = GetCurrentUserExchangeCertificate(box.Value, Company.Employees.Current); certificateToRejectFirstVersion = certificate; var selectedAddendaList = new List <Docflow.IOfficialDocument>(); if (selectedAddenda.Value != null) { selectedAddendaList = selectedAddenda.Value.ToList(); } if (certificate == null || !Docflow.PublicFunctions.Module .ApproveWithAddenda(document, selectedAddendaList, certificate, null, true, true, string.Empty)) { x.AddError(Resources.SendCounterpartyCanNotSign); return; } } catch (Exception ex) { x.AddError(ex.Message); return; } } else { return; } } try { Functions.Module.Remote.SendDocuments(document, selectedAddenda.Value.ToList(), counterparty.Value, box.Value, certificate, needSign.Value.Value, comment.Value); if (Equals(certificate.Owner, Company.Employees.Current)) { Functions.Module.SendDeliveryConfirmation(box.Value, certificate, false); } else { Functions.Module.SendDeliveryConfirmation(box.Value, null, false); } } catch (AppliedCodeException ex) { x.AddError(ex.Message); return; } catch (Exception ex) { Logger.ErrorFormat("Error sending document: ", ex); x.AddError(Resources.ErrorWhileSendingDocToCounterparty); return; } if (documentInfo.NeedRejectFirstVersion) { if (certificateToRejectFirstVersion == null) { certificateToRejectFirstVersion = GetCurrentUserExchangeCertificate(box.Value, Company.Employees.Current); } TryRejectCounterpartyVersion(document, counterparty.Value, box.Value, certificateToRejectFirstVersion); } var addendaToReject = documentInfo.Addenda .Where(a => a.NeedRejectFirstVersion) .Select(a => a.Addendum) .Where(a => selectedAddenda.Value.Contains(a)) .ToList(); foreach (var addendum in addendaToReject) { if (certificateToRejectFirstVersion == null) { certificateToRejectFirstVersion = GetCurrentUserExchangeCertificate(box.Value, Company.Employees.Current); } TryRejectCounterpartyVersion(addendum, counterparty.Value, box.Value, certificateToRejectFirstVersion); } Dialogs.NotifyMessage(Resources.SendCounterpartySuccessfully); } }); dialog.Show(); }