Странное поведение системы при копировании продуктов.
Создали Проект, в нем внесли все продукты, затем нажимаем "Действие" - "Создать счет" и соглашаемся, когда нам предлагают скопировать продукты в счет.
Все копируется хорошо, валюта в продукте устанавливается правильно, но курс всегда равен нулю, какую бы валюту мы не ставили. Соответственно, суммы и цена в б.в. все равны нулю. Естественно, из-за этого не работает пересчет суммы счета.
Проверил даты установленных курсов - все нормально, попадаем в срок действия курса.
Версия продукта 3.1.1.6.
Нравится
Ждал, ждал ответ... В итоге вот, что получилось...
При работе с деталью Продуктов используется общая функция копирования нескольких одинаковых полей из одного датасета в другой. Отсюда и проблема с курсом - в проекте есть поле с валютой, но нет поля с курсом, потому при копировании валюта проставляется, а поле курса остается пустым и заполняется нулевым значением при открытии счета на редактирование.
Вышел из ситуации добавление новой функции, которая после копирования продуток обновляется у всех курс валюты.
В скрипт scr_DocumentUtils перед функцией CopyOfferingInItemDetail добавил свою функцию:
[javascript]
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();
}
}
[/javascript]
В саму функцию CopyOfferingInItemDetail в конце добавил вызов новой функции. В результате функция CopyOfferingInItemDetail приняла следущий вид:
[javascript]
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);
}
[/javascript]
Решение получилось универсальным и работает при копировании продуктов в счет, документ, договор и проект.
Для себя я сделал еще одну модификацию. Когда на основе проекта создается счет, то его сумма равна нулю, даже если мы туда скопируем продукты. А каждый раз нажимать в меню "Пересчитать сумму" неудобно. Поэтому в скрипт wnd_InvoiceEditScript я добавил перед функцией ProcessCopyOfferingDetail новую функцию:
[javascript]
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;
}
[/javascript]
В саму функцию ProcessCopyOfferingDetail я добавил вызов новой функции, в результате код стал выглядеть вот так:
[javascript]
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);
}
[/javascript]