Нулевой курс при копировании детали продуктов

Странное поведение системы при копировании продуктов.
Создали Проект, в нем внесли все продукты, затем нажимаем "Действие" - "Создать счет" и соглашаемся, когда нам предлагают скопировать продукты в счет.
Все копируется хорошо, валюта в продукте устанавливается правильно, но курс всегда равен нулю, какую бы валюту мы не ставили. Соответственно, суммы и цена в б.в. все равны нулю. Естественно, из-за этого не работает пересчет суммы счета.
Проверил даты установленных курсов - все нормально, попадаем в срок действия курса.

Версия продукта 3.1.1.6.

Нравится

1 комментарий

Ждал, ждал ответ... В итоге вот, что получилось...

При работе с деталью Продуктов используется общая функция копирования нескольких одинаковых полей из одного датасета в другой. Отсюда и проблема с курсом - в проекте есть поле с валютой, но нет поля с курсом, потому при копировании валюта проставляется, а поле курса остается пустым и заполняется нулевым значением при открытии счета на редактирование.
Вышел из ситуации добавление новой функции, которая после копирования продуток обновляется у всех курс валюты.

В скрипт 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);
}
Показать все комментарии