/// <summary> /// Окончательное согласование накладной. Принимает (при необходимости переустановить учетные цены для строчек расхождений) коллекцию учетных цен. /// </summary> /// <param name="totalApproveSum">Согласованная сумма накладной</param> /// <param name="articleAccountingPriceList">Коллекция учетных цен. Необязательный параметр. При передаче - установи данные цены на строчки с расхождениями.</param> /// <param name="approvementDate">Дата согласования. Необязательный параметр. При передаче - установит дату согласования накладной.</param> public virtual void Approve(decimal totalApproveSum, User approvedBy, DateTime approvementDate, IEnumerable <ArticleAccountingPrice> accountingPrices = null) { CheckPossibilityToApprove(); ValidationUtils.Assert(totalApproveSum >= 0, "Согласованная сумма накладной не может быть меньше 0."); ValidationUtils.CheckDecimalScale(totalApproveSum, 2, "Согласованная сумма накладной должна иметь не более 2 знаков после запятой."); ValidationUtils.Assert(totalApproveSum == ApprovedSumByRows, "Сумма накладной не сходится с суммой по позициям."); ApprovedSum = totalApproveSum; ApprovementDate = approvementDate; ApprovedBy = approvedBy; foreach (var row in Rows.Where(x => x.AreDivergencesAfterReceipt)) { // копируем закупочные цены, указанные при согласовании, в текущие row.PurchaseCost = row.ApprovedPurchaseCost.Value; if (row.PendingCount == 0) { // Доустановим учетные цены для товаров, добавленных при согласовании ValidationUtils.NotNull(accountingPrices, "Невозможно выполнить согласование, так как не удалось получить учетную цену."); var articleAccountingPrice = accountingPrices.FirstOrDefault(x => x.Article == row.Article); ValidationUtils.NotNull(articleAccountingPrice, String.Format("Невозможно выполнить согласование, так как на товар «{0}» не установлена учетная цена.", row.Article.FullName)); row.RecipientArticleAccountingPrice = articleAccountingPrice; } // переводим кол-во по позиции в доступное для резервирования row.AvailableToReserveCount = row.ApprovedCount.Value; } State = ReceiptWaybillState.ApprovedFinallyAfterDivergences; // TODO почему так? Надо как-то передавать сюда обстоятельства и выставлять правильный State }
/// <summary> /// Базовый конструктор для создания приходной накладной /// </summary> /// <param name="number">Номер</param> /// <param name="date">Дата</param> /// <param name="receiptStorage">Место хранения</param> /// <param name="accountOrganization">Собственная организация</param> /// <param name="pendingSum">Ожидаемая сумма накладной</param> /// <param name="pendingDiscountSum">Ожидаемая сумма скидки</param> /// <param name="pendingValueAddedTax">Ожидаемая НДС</param> /// <param name="curator">Куратор</param> private ReceiptWaybill(string number, DateTime date, Storage receiptStorage, AccountOrganization accountOrganization, decimal pendingSum, decimal pendingDiscountSum, ValueAddedTax pendingValueAddedTax, string customsDeclarationNumber, User curator, User createdBy, DateTime creationDate) : base(WaybillType.ReceiptWaybill, number, date, curator, createdBy, creationDate) { ValidationUtils.NotNull(receiptStorage, "Необходимо указать место хранения."); ReceiptStorage = receiptStorage; ValidationUtils.NotNull(accountOrganization, "Необходимо указать организацию."); AccountOrganization = accountOrganization; ValidationUtils.NotNull(pendingValueAddedTax, "Необходимо указать ставку НДС."); PendingValueAddedTax = pendingValueAddedTax; ValidationUtils.CheckDecimalScale(pendingSum, 2, "Общая сумма по накладной должна иметь не более 2 знаков после запятой."); PendingSum = pendingSum; PendingDiscountSum = pendingDiscountSum; State = ReceiptWaybillState.New; if (String.IsNullOrEmpty(customsDeclarationNumber)) { CustomsDeclarationNumber = String.Empty; IsCustomsDeclarationNumberFromReceiptWaybill = false; } else { CustomsDeclarationNumber = customsDeclarationNumber; IsCustomsDeclarationNumberFromReceiptWaybill = true; } ProviderNumber = String.Empty; ProviderInvoiceNumber = String.Empty; CheckPendingDiscountSum(); }
/// <summary> /// Приемка обычной (не связанной с партией заказа) накладной на склад /// </summary> /// <param name="receiptedSum">Общая сумма по накладной</param> public virtual void Receipt(decimal receiptedSum, User receiptedBy, DateTime currentDateTime) { ValidationUtils.Assert(!IsCreatedFromProductionOrderBatch, "Этот метод не подходит для данного типа накладной."); ValidationUtils.Assert(receiptedSum >= 0, "Общая сумма по накладной не может быть меньше 0."); ValidationUtils.CheckDecimalScale(receiptedSum, 2, "Общая сумма по накладной должна иметь не более 2 знаков после запятой."); ValidationUtils.Assert(receiptedSum == Rows.Sum(x => x.ProviderSum), "Общая сумма по накладной не сходится с суммой по позициям."); PerformReceipt(receiptedBy, currentDateTime); }
/// <summary> /// Одновременная установка количеств исходящего товара (проведенного, отгруженного и окончательно перемещенного). /// Если они некорректно заданы, происходит исключение. /// </summary> public virtual void SetOutgoingArticleCount(decimal acceptedCount, decimal shippedCount, decimal finallyMovedCount) { ValidationUtils.Assert(acceptedCount >= 0M && shippedCount >= 0M && finallyMovedCount >= 0M, "Количество проведенного, отгруженного или окончательно перемещенного товара не может быть меньше 0."); ValidationUtils.Assert(shippedCount + finallyMovedCount + acceptedCount <= CurrentCount, "Сумма проведенного, отгруженного и окончательно перемещенного товара не может быть больше текущего количества товара (ожидаемого или принятого)."); ValidationUtils.CheckDecimalScale(acceptedCount, 12, ArticleMeasureUnitScale, "Количество проведенного товара должно иметь соответствующее число знаков до запятой.", "Количество проведенного товара должно иметь соответствующее число знаков после запятой."); ValidationUtils.CheckDecimalScale(shippedCount, 12, ArticleMeasureUnitScale, "Количество отгруженного товара должно иметь соответствующее число знаков до запятой.", "Количество отгруженного товара должно иметь соответствующее число знаков после запятой."); ValidationUtils.CheckDecimalScale(finallyMovedCount, 12, ArticleMeasureUnitScale, "Количество окончательно перемещенного товара должно иметь соответствующее число знаков до запятой.", "Количество окончательно перемещенного товара должно иметь соответствующее число знаков после запятой."); this.acceptedCount = acceptedCount; this.shippedCount = shippedCount; this.finallyMovedCount = finallyMovedCount; this.AvailableToReserveCount = CurrentCount - acceptedCount - shippedCount - finallyMovedCount; }