Нулевой курс при копировании детали продуктов
Странное поведение системы при копировании продуктов.
Создали Проект, в нем внесли все продукты, затем нажимаем "Действие" - "Создать счет" и соглашаемся, когда нам предлагают скопировать продукты в счет.
Все копируется хорошо, валюта в продукте устанавливается правильно, но курс всегда равен нулю, какую бы валюту мы не ставили. Соответственно, суммы и цена в б.в. все равны нулю. Естественно, из-за этого не работает пересчет суммы счета.
Проверил даты установленных курсов - все нормально, попадаем в срок действия курса.
Версия продукта 3.1.1.6.
Нравится
Ждал, ждал ответ... В итоге вот, что получилось...
При работе с деталью Продуктов используется общая функция копирования нескольких одинаковых полей из одного датасета в другой. Отсюда и проблема с курсом - в проекте есть поле с валютой, но нет поля с курсом, потому при копировании валюта проставляется, а поле курса остается пустым и заполняется нулевым значением при открытии счета на редактирование.
Вышел из ситуации добавление новой функции, которая после копирования продуток обновляется у всех курс валюты.
В скрипт scr_DocumentUtils перед функцией CopyOfferingInItemDetail добавил свою функцию:
function UpdateCurrencyRate(DestinationOfferingInItemDatasetCode, DestinationParentItemIDFieldName, DestinationItemID) { var DDataset = GetSingleItemByCode( DestinationOfferingInItemDatasetCode); ApplyDatasetFilter(DDataset, DestinationParentItemIDFieldName, DestinationItemID, true); DDataset.Open(); var DataField = DDataset.DataFields.ItemsByName('CurrencyID'); var RateDate = ''; switch (DestinationOfferingInItemDatasetCode){ case ('ds_OfferingInInvoice') : RateDate = GetDatasetFieldValueByID('ds_Invoice',DestinationItemID,'InvoiceDate'); break; case ('ds_OfferingInDocument') : RateDate = GetDatasetFieldValueByID('ds_Document',DestinationItemID,'Date'); break; case ('ds_OfferingInContract') : RateDate = GetDatasetFieldValueByID('ds_Contract',DestinationItemID,'StartDate'); break; case ('ds_OfferingInOpportunity') : RateDate = GetDatasetFieldValueByID('ds_Opportunity',DestinationItemID,'EstimatedStartDate'); break; } if (IsEmptyValue(RateDate)) { var Today = GetLocalDate(); RateDate = ExtractDate(Today); }else{ RateDate = ExtractDate(RateDate); } while (!DDataset.IsEOF) { var CurrID = DataField.Value; var Rate = GetRate(CurrID, RateDate, 0, true); DDataset.Edit(); SetFloatDataFieldWithRound(DDataset.DataFields.ItemsByName('Rate'), Rate); DDataset.Post(); DDataset.GotoNext(); } }
В саму функцию CopyOfferingInItemDetail в конце добавил вызов новой функции. В результате функция CopyOfferingInItemDetail приняла следущий вид:
function CopyOfferingInItemDetail(SourceOfferingInItemDatasetCode, DestinationOfferingInItemDatasetCode, SourceParentItemIDFieldName, DestinationParentItemIDFieldName, SourceItemID, DestinationItemID) { var SourceItemName = GetItemNameByParentItemIDFieldName( SourceParentItemIDFieldName); var DestinationItemName = GetItemNameByParentItemIDFieldName( DestinationParentItemIDFieldName); if (SourceItemName == DestinationItemName) { var Message = FormatStr(CopyItemDetailConfirmation, "продукт"); } else { var Message = FormatStr(CopyItemDetailFromItemToItem, "продукт", SourceItemName, DestinationItemName); } var DialogResult = System.MessageDialog(Message, mdtConfirmation, mdbYes + mdbNo, 0); if (DialogResult != wmrYes) { return; } var SourceDataset = GetSingleItemByCode(SourceOfferingInItemDatasetCode, 'OffDetailSource'); SourceDataset.FetchRecordsCount = -1; var DestinationDataset = GetSingleItemByCode( DestinationOfferingInItemDatasetCode, 'OffDetailDestination'); DestinationDataset.FetchRecordsCount = -1; SourceDataset.DisableEvents(); DestinationDataset.DisableEvents(); ApplyDatasetFilter(SourceDataset, SourceParentItemIDFieldName, SourceItemID, true); CopyTreeDetail(SourceDataset, DestinationDataset, SourceParentItemIDFieldName, DestinationParentItemIDFieldName, DestinationItemID); UpdateCurrencyRate(DestinationOfferingInItemDatasetCode, DestinationParentItemIDFieldName, DestinationItemID); }
Решение получилось универсальным и работает при копировании продуктов в счет, документ, договор и проект.
Для себя я сделал еще одну модификацию. Когда на основе проекта создается счет, то его сумма равна нулю, даже если мы туда скопируем продукты. А каждый раз нажимать в меню "Пересчитать сумму" неудобно. Поэтому в скрипт wnd_InvoiceEditScript я добавил перед функцией ProcessCopyOfferingDetail новую функцию:
function SilentRecalcAmount(InvoiceID){ if (IsEmptyGUID(InvoiceID)){ return null; } var BasicTotalAmount = GetDetailSummary('tbl_OfferingInInvoice', 'InvoiceID', InvoiceID, 'BasicTotalAmount', stSum); var InvoiceDataset = GetSingleItemByCode('ds_Invoice'); InvoiceDataset.Open(); var Rate = GetDatasetFieldValueByID('ds_Invoice',InvoiceID,'CurrencyRate'); var Amount = CalcNonBasicSum(BasicTotalAmount, Rate); var UpdateQuery = GetSingleItemByCode('uq_InvoiceAmount', 'InvoiceEdit'); var UpdateFields = new Array('BasicAmount', 'Amount'); var FieldValues = new Array(2); FieldValues[0] = BasicTotalAmount; FieldValues[1] = Amount; UpdateRecordField(UpdateQuery, InvoiceID, UpdateFields, FieldValues, InvoiceDataset); return Amount; }
В саму функцию ProcessCopyOfferingDetail я добавил вызов новой функции, в результате код стал выглядеть вот так:
function ProcessCopyOfferingDetail(Dataset) { var IsCopy = Self.Attributes('IsCopy'); var IsCreatedByDocumentID = Self.Attributes('IsCreatedByDocumentID'); var IsCreatedByContractID = Self.Attributes('IsCreatedByContractID'); var IsCreatedByOpportunityID = Self.Attributes('IsCreatedByOpportunityID'); if (!IsCopy && !IsCreatedByDocumentID && !IsCreatedByContractID && !IsCreatedByOpportunityID) { return; } var DestinationOfferingInItemDatasetCode = 'ds_OfferingInInvoice'; var DestinationParentItemIDFieldName = 'InvoiceID'; var DestinationItemID = Dataset.Values('ID'); if (IsCreatedByDocumentID) { var SourceOfferingInItemDatasetCode = 'ds_OfferingInDocument'; var SourceParentItemIDFieldName = 'DocumentID'; var SourceItemID = IsCreatedByDocumentID; } else if (IsCreatedByContractID) { var SourceOfferingInItemDatasetCode = 'ds_OfferingInContract'; var SourceParentItemIDFieldName = 'ContractID'; var SourceItemID = IsCreatedByContractID; } else if (IsCopy) { var SourceOfferingInItemDatasetCode = 'ds_OfferingInInvoice'; var SourceParentItemIDFieldName = 'InvoiceID'; var SourceItemID = Self.Attributes('SourceRecordID'); } else if (IsCreatedByOpportunityID) { var SourceOfferingInItemDatasetCode = 'ds_OfferingInOpportunity'; var SourceParentItemIDFieldName = 'OpportunityID'; var SourceItemID = IsCreatedByOpportunityID; } else { return; } CopyOfferingInItemDetail(SourceOfferingInItemDatasetCode, DestinationOfferingInItemDatasetCode, SourceParentItemIDFieldName, DestinationParentItemIDFieldName, SourceItemID, DestinationItemID); SilentRecalcAmount(DestinationItemID); }