Задача:
Разделение права доступа на записи в справочнике Валют
Вводная:
Есть много офисов компании, например Московскому офису совершенно не интересно каждый раз выбирать валюту UAH, DKK и.т.д. следовательно логично разграничить доступ на валюты

Решение:
1. tbl_Currency -> поставить галочку Is Administrated By Records
2. wnd_CurrencyDictionary
a) Добавить pgAccessDetail
б) wndAccessDetail -> Window = wnd_AccessGridArea
в) Pages -> определить событие PagesOnChangeActivePage

3.wnd_CurrencyDictionaryScript
a) Use Scripts -> scr_WorkspaceUtils
Код самого скрипта нужно поменять следующим образом :

//------------------------------------------------------------------------------
// wnd_CurrencyDictionaryScript
//------------------------------------------------------------------------------

var CurrencyDictionary = new Object();
var BaseWorkspace = new Object();

function InitializeGridData() {
        CurrencyDictionary.CurrencyWindow = wndCurrency.Window;
        CurrencyDictionary.CurrencyWindow.Prepare();   
}

function InitializeCurrencyRateDetail() {
        CurrencyDictionary.CurrencyRateWindow = wndCurrencyRateDetail.Window;
        CurrencyDictionary.CurrencyRateWindow.Prepare();
}

function InitializeGlobalVariables() {
        CurrencyDictionary.CurrencyDataset = GetDatasetFromWindow(
                CurrencyDictionary.CurrencyWindow, DefDatasetLinkName);
        CurrencyDictionary.CurrencyRateDataset = GetDatasetFromWindow(
                CurrencyDictionary.CurrencyRateWindow, DefDatasetLinkName);
}

function InitializeGlobalDatalinks() {
        dlCurrency.Dataset = CurrencyDictionary.CurrencyDataset;
        dlCurrencyRate.Dataset = CurrencyDictionary.CurrencyRateDataset;
}

function OpenCurrencyDataset() {
        CurrencyDictionary.CurrencyDataset.Open();
}

function Initialize(Window) {
        InitializeGridData();
        InitializeCurrencyRateDetail();
        InitializeGlobalVariables();
        InitializeGlobalDatalinks();
        OpenCurrencyDataset();
}

function RefreshCurrencyRate() {
    CurrencyDictionary.CurrencyDataset.Open();
        var CurrencyID = CurrencyDictionary.CurrencyDataset.Values('ID');
        if (CurrencyID == null) {
                return;
        }
        SetAttribute(CurrencyDictionary.CurrencyRateWindow, 'ParentItemID',
                CurrencyID);
        RefreshDetailData(CurrencyDictionary.CurrencyDataset, 'ID',
                CurrencyDictionary.CurrencyRateDataset, 'CurrencyID');
}

// ----------------------------------------------------------------------------
// Event handlers
// ----------------------------------------------------------------------------

function wnd_CurrencyDictionaryOnPrepare(Window) {
        Initialize(Window);
}

function dlCurrencyOnDatasetAfterOpen(Dataset) {
//      RefreshCurrencyRate();
RefreshDetails()
}

function dlCurrencyOnDatasetAfterPositionChange(Dataset) {
//      RefreshCurrencyRate();
RefreshDetails()
}

function dlCurrencyOnDatasetRefreshRecord(Dataset, KeyValue, AddNewRecordOnPage) {
        if (AddNewRecordOnPage) {
//              RefreshCurrencyRate();
        RefreshDetails()
        }
}

function wnd_CurrencyDictionaryOnNotify(ScriptableService, Sender, Message, Data) {
        if (Message == MSG_CLOSE) {
                CloseWindow(Self);
        }
}


function PagesOnChangeActivePage(Pages) {
        RefreshDetails();
}

function RefreshDetails() {
        if (Pages.ActivePage.Name == pgCurrencyRate.Name) {
                RefreshCurrencyRate();
        } else
        if (Pages.ActivePage.Name == pgAccessDetail.Name) {

        //26.06 Create BaseWorkspace
        var Grid = wndCurrency.Window.ComponentsByName('grdData');     
        BaseWorkspace.GridDataset = CurrencyDictionary.CurrencyDataset;
        BaseWorkspace.Grid = Grid

        RefreshAccessDetail(BaseWorkspace, wndAccessDetail, 'tbl_CurrencyRight');
        }
}

Нравится

5 комментариев

Мне кажется, как раз не логично решать задачу доступом - если Московскому офису все-таки понадобятся закрытые от них валюты?
Имхо лучше сделать какую-нибудь детальку типа CurrencyInDepartment и фильтровать справочник валют по данным оттуда. Хотя, такая реализация немного сложнее

Дмитрий совсем Вас не понял. Права доступа разделяются на группы All Users -> Moscow -> Managers Moscow, All Users -> Moscow -> Accountant Moscow и.т.д. и как раз на группы и раздаются права.
При таком подходе Московский офис не видит не нужные им валюты, а если например бухгалтеру необходимо видеть что то дополнительно, ему раздаются права доступа (на группу Accountant Moscow)

А то что вы предлагаете очень лихо в силу того что Валюты - это очень базовый справочник

"Яворский Алексей" написал: то что вы предлагаете очень лихо в силу того что Валюты - это очень базовый справочник

С этим не поспоришь, хотя и не "очень"
Разница есть только в том, что в вашем варианте нужен кто-то сверху, кто будет права раздавать, а в моем - пользователи сами смогут этим заниматься

Даже проще можно сделать:
*добавить таблицу CurrencyInUser
*в датасет справочника валют добавить булево поле подзапроса "Показывать мне"

(select 
....
(select ShowForMe from tbl_CurrencyInUser where CurrencyID = tbl_Currency.ID and UserID = :CurrentUserContactID)
....
from tbl_Currency)

*создать логику автозаполнения tbl_CurrencyInUser при создании нового пользователя и валюты
*наложить на датасет валют фильтр where ShowForMe = 1
*для грида справочника отключать фильтр

Алексей, спасибо за пример реализации. Так держать! :)

Показать все комментарии

Вниманию предлагается набор функций для загрузки в Terrasoft 3.X актуального курса доллара к гривне по версии Нацбанка Украины. Можно получать как официальный, так и средневзвешенный рыночный курс.
 Национальный банк Украины

Функция непосредственного получения курса. Если входной параметр true – получает официальный курс, если false или без параметра – средневзвешенный.

Результат - объект с двумя полями. Rate – количество украинских гривен за 1 доллар США (например, 7.993). Date – указанная на сайте дата этого курса. Для официального – следующий рабочий день, для среднего – предыдущий.

function GetUSDRate(IsOfficial) {
        try {
            var Result = new Object();
                var webAddress = 'http://bank.gov.ua/control/uk/index';
                var xmlHttpReq = new ActiveXObject("MSXML2.XMLHTTP.6.0");
                xmlHttpReq.open("GET", webAddress, false);        
            xmlHttpReq.send();
            var HtmlText = xmlHttpReq.responseText.replace(/\s/g, "");
            if (IsOfficial) {
                var BeginText = '100 ДоларівСША';
                var EndText = '100 Євро';
               
                } else {
                        var BeginText = '
грн.за100доларівСША';
                        var EndText =  '
Детальніше...';
                }

                var BeginIndex = HtmlText.indexOf(BeginText)+ BeginText.length;
                var EndIndex = HtmlText.indexOf(EndText);
            var HtmlFragment = HtmlText.substring(BeginIndex, EndIndex);
                var Rate = parseFloat(HtmlFragment);
                if (isNaN(Rate)) {
                        Log.Write(2, 'Ошибка при получении курса Нацбанка');
                        return null;
                }
                Result.Rate = Rate/100;
            if (IsOfficial) {          
                BeginText = 'Офіційнийкурсгривнідоіноземнихвалютз14.00';
                EndText = '';
                } else {
                    BeginText = 'Середньозваженийкурснаміжбанківськомуринку(начасвстановленняофіційногокурсугривні)
';
                    EndText = '

Нравится

Поделиться

4 комментария

Александр, спасибо!
Правильно ли я понимаю, что функция рассчитана на текущую разметку официального сайта НБУ и Вы будете следить за ее изменениями, внося соответствующие правки в свое решение?

Да, так и есть. У НБУ, в отличие от ЦБРФ, нет публичного XML API.
За полгода дизайн сайта НБУ не менялся, пока работает нормально.

Александр! функция перестала работать!

выдает сообщение: "Ошибка при получении курса Нацбанка"

Поправьте скрипт как можно скорее!
Спасибо.

Исправлено.

Показать все комментарии

В примере показано, как выгрузить курсы валют (и сами валюты) на дату.

Я использовал сайт http://cbr.ru (Центральный банк Российской Федерации)

Для использования необходимо:

1. Добавить системный параметр:
CurrencyRatesDictionaryURL
http://www.cbr.ru/scripts/XML_daily_eng.asp?date_req=#DateMacro# - для англоязычной версии
http://www.cbr.ru/scripts/XML_daily.asp?date_req=#DateMacro# - для русскоязной версии

2. В сервис sq_Currency добавить фильтр и парметр ShortName

3. В скрипт scr_CurrencyUtils добавить функцию

        function GetBasicCurrencyCode() {
        if (IsEmptyGUID(CurrencyUtils.BasicCurrencyCode)) {
                CurrencyUtils.BasicCurrencyCode =
                GetDatasetFieldValueFromDatasetByUSI(
                        'ds_Currency', 'IsBase', true, 'ShortName');
        }
        return CurrencyUtils.BasicCurrencyCode;
}

4. Загрузить сервисы из архива и запусть Terrasoft с ключем -wnd=wnd_UploadCurrencyRates

П.С. Курсы валют - с российского сайта, на котором я не нашел кросс-курсов, поэтому, если базовая валюта отличается от рубля - курс получается обычным разделением на курс базовой валюты...

Вроде ничего не забыл...

Нравится

Поделиться

12 комментариев

Добрый день! А для украинского есть что-то подобное?

Не встречал... возможно есть.... платные услуги точно должны быть...

Non noceo.

Вот, нашёл и для нашей страны, т.е. Украины :)
сайт http://ufs.kiev.ua/xml/

+ надо немного модифицировать код функции wnd_UploadCurrencyRatesScript
Просьба к админам приатачить этот код в виде архива как вариант для Украины.

//-----------------------------------------------------------------------------
// wnd_UploadCurrencyRatesScript
//-----------------------------------------------------------------------------
 
var UploadCurrencyRatesObject = new Object();
 
function UploadCurrencyRates(URL) {
	System.BeginProcessing();
	try {
		var XmlDoc = System.CreateObject('Msxml.DOMDocument');
		XmlDoc.async = false;
		if (XmlDoc.load(URL) != true) {
			ShowWarningDialog("The currency rates can't be uploaded from the specified URL");
			return;
		}
		pbUpload.Position = 20;		
		System.ProcessMessages();
		var NodeList = XmlDoc.selectSingleNode('r00t');
		var XmlNode = NodeList.cloneNode(true);
		var RateDate = GetTodayDate().getVarDate();
		NodeList = XmlDoc.selectNodes('*/item');
		var Length = NodeList.length;
		if (Length == 0) {
			return;
		}
		var BasicCurrencyCode = GetBasicCurrencyCode();
		var BasicRate;
		for(var i = 0; i < Length; i++) {
			var Node = NodeList.item(i).cloneNode(true);
			var CurrencyCode = Node.selectSingleNode('title').text;
			if (CurrencyCode == BasicCurrencyCode) {
				BasicRate = parseFloat(Node.selectSingleNode('rate').text);
				if (BasicRate == 0) {
					BasicRate = 1;
				}
				break;
			}
		}
		pbUpload.Position = 25;
		System.ProcessMessages();
		if (IsEmptyValue(BasicRate)) {
			BasicRate = 1;
		}
		for(var i = 0; i < Length; i++) {
			var Node = NodeList.item(i).cloneNode(true);
			var CurrencyCode = Node.selectSingleNode('title').text;
			var CurrencyName = Node.selectSingleNode('description').text;
			var Nominal = parseInt(Node.selectSingleNode('qty').text);
			var Value = parseFloat(Node.selectSingleNode('rate').text);
			if (CurrencyCode != BasicCurrencyCode) {
				UploadCurrencyRate(CurrencyCode, CurrencyName, Nominal,
					Value / BasicRate, RateDate);
			}
			pbUpload.Position = 25 + (i / Length * 75);
			System.ProcessMessages();
		}
	} finally {
		System.EndProcessing();		
	}
}
 
function UploadCurrencyRate(CurrencyCode, CurrencyName, Nominal, Value, RateDate) {
	if (!Assigned(UploadCurrencyRatesObject.CurrencyDataset)) {
		UploadCurrencyRatesObject.CurrencyDataset =
			Services.GetNewItemByUSI('ds_Currency');
	}
 
	var Dataset = UploadCurrencyRatesObject.CurrencyDataset;
	ApplyDatasetFilter(Dataset, 'ShortName', CurrencyCode, true);
	var CurrencyID;
	Dataset.Open();
	try {
		CurrencyID = Dataset.Values('ID');
		if (IsEmptyValue(CurrencyID)) {
			if (edtUploadCurrencies.IsChecked) {
				Dataset.Append();
				CurrencyID = Connector.GenGUID();
				Dataset.Values('ID') = CurrencyID;
				Dataset.Values('Currency') = CurrencyName;
				Dataset.Values('Description') = CurrencyName;
				Dataset.Values('ShortName') = CurrencyCode;
				Dataset.Values('IsBase') = false;
				Dataset.Post();
			} else {
				return;
			}
		}
	} finally {
		Dataset.Close();
	}
	if (!Assigned(UploadCurrencyRatesObject.RatesDataset)) {
		UploadCurrencyRatesObject.RatesDataset =
			Services.GetNewItemByUSI('ds_CurrencyRate');
	}
	Dataset = UploadCurrencyRatesObject.RatesDataset;
	ApplyDatasetFilter(Dataset, 'CurrencyID', CurrencyID, true);
	ApplyDatasetFilter(Dataset, 'RateDate', RateDate, true);
	Dataset.Open();
	try {
		if (Dataset.IsEmptyPage) {
			Dataset.Append();
		} else {
			Dataset.Edit();
		}
		Dataset.Values('StartDate') = RateDate;
		Dataset.Values('DueDate') = RateDate;
		Dataset.Values('Rate') = Value;
		Dataset.Values('For') = Nominal;
		Dataset.Values('CurrencyID') = CurrencyID;
		Dataset.Post();
	} finally {
		Dataset.Close();
	}
}
 
function GetDateInStr(DateValue) {
	var DateObject = new Date(DateValue);
	var Result = '/' + DateObject.getFullYear();
	var Month = DateObject.getMonth();
	Month++;
	if (Month < 10) {
		Month = '0' + Month;
	}
	var Day = DateObject.getDate();
	if (Day < 10) {
		Day = '0' + Day;
	}
	Result = Day + '/' + Month + Result;
	return Result;
}
 
// ----------------------------------------------------------------------------
// Event handlers
// ----------------------------------------------------------------------------
 
function wnd_UploadCurrencyRatesOnPrepare(Window) {
	pbUpload.Position = 0;
	edtRatesDate.Value = GetLocalDate();
}
 
function btnOKOnClick(Control) {
	var URL;
	var Message = "Please, specify the 'CurrencyRatesDictionaryURL' system parameter";
	try {
		URL = 'http://ufs.kiev.ua/xml/nbu_fx.php';
		if (IsEmptyValue(URL)) {
			ShowWarningDialog(Message);
		}
	} catch(e) {
		ShowWarningDialog(Message);
		return;
	}
	var DateValue = edtRatesDate.Value;
	if (IsEmptyValue(DateValue)) {
		DateValue = GetLocalDate();
	}
	if (ShowConfirmationDialog("Do you want to upload currencies from the \n " + 
		URL + '?') != wmrYes) {
	    return;
	} 
	UploadCurrencyRates(URL);
	Self.Close();
	SendNotify(Self, MSG_REFRESHDATA, 0);
}
 
function btnCancelOnClick(Control) {
	Self.Close();
}

Английский вариант для доллара:
ссылка - http://data.newyorkfed.org/markets/fxrates/FXtoXML.cfm?FEXdate=#DateMac…

Контрол edtUploadCurrencies нужно удалить...

//-----------------------------------------------------------------------------
// wnd_UploadCurrencyRatesScript
//-----------------------------------------------------------------------------
 
var UploadCurrencyRatesObject = new Object();
 
function UploadCurrencyRates(URL) {
	System.BeginProcessing();
	try {
		var XmlDoc = System.CreateObject('Msxml.DOMDocument');
		XmlDoc.async = false;
		if (XmlDoc.load(URL) != true) {
			ShowWarningDialog("The currency rates can't be uploaded from the specified URL");
			return;
		}
		pbUpload.Position = 20;		
		System.ProcessMessages();
		var NodeList = XmlDoc.selectSingleNode('UtilityData').selectSingleNode('frbny:DataSet').childNodes;
		var Length = NodeList.length;
		for(var i = 0; i < Length; i++) {
			var Node = NodeList.item(i).cloneNode(true);
			var Unit1 = Node.getAttribute('UNIT');
			var KeyNode = Node.selectSingleNode('frbny:Key');
			var ObsNode = Node.selectSingleNode('frbny:Obs');
			var Unit2 = KeyNode.selectSingleNode('frbny:CURR').text;
			var CurrencyCode = '';
			var Value = parseFloat(ObsNode.selectSingleNode('frbny:OBS_VALUE').text);
			var RateDate = ObsNode.selectSingleNode('frbny:TIME_PERIOD').text;
			var Year = parseInt(RateDate.substr(0, 4));
			var Month = parseInt(RateDate.substr(5, 2));
			var Day = parseInt(RateDate.substr(8, 2));
			RateDate = (new Date(Year, Month, Day)).getVarDate();
			if (Unit1 == 'USD') {
				CurrencyCode = Unit2;
				Value = 1 / Value;
			} else {
				CurrencyCode = Unit1;
			}
			var CurrencyName = '';
			var Nominal = 1;
			UploadCurrencyRate(CurrencyCode, CurrencyName, Nominal,
				Value, RateDate);
			pbUpload.Position = 20 + (i / Length * 70);
			System.ProcessMessages();
		}
	} finally {
		System.EndProcessing();		
	}
}
 
function UploadCurrencyRate(CurrencyCode, CurrencyName, Nominal, Value, RateDate) {
	if (!Assigned(UploadCurrencyRatesObject.CurrencyDataset)) {
		UploadCurrencyRatesObject.CurrencyDataset =
			Services.GetNewItemByUSI('ds_Currency');
	}
	var Dataset = UploadCurrencyRatesObject.CurrencyDataset;
	ApplyDatasetFilter(Dataset, 'ShortName', CurrencyCode, true);
	var CurrencyID;
	Dataset.Open();
	try {
		CurrencyID = Dataset.Values('ID');
		if (IsEmptyValue(CurrencyID)) {
			return;
		}
	} finally {
		Dataset.Close();
	}
	if (!Assigned(UploadCurrencyRatesObject.RatesDataset)) {
		UploadCurrencyRatesObject.RatesDataset =
			Services.GetNewItemByUSI('ds_CurrencyRate');
	}
	Dataset = UploadCurrencyRatesObject.RatesDataset;
	ApplyDatasetFilter(Dataset, 'CurrencyID', CurrencyID, true);
	ApplyDatasetFilter(Dataset, 'RateDate', RateDate, true);
	Dataset.Open();
	try {
		if (Dataset.IsEmptyPage) {
			Dataset.Append();
		} else {
			Dataset.Edit();
		}
		Dataset.Values('StartDate') = RateDate;
		Dataset.Values('DueDate') = RateDate;
		Dataset.Values('Rate') = Value;
		Dataset.Values('For') = Nominal;
		Dataset.Values('CurrencyID') = CurrencyID;
		Dataset.Post();
	} finally {
		Dataset.Close();
	}
}
 
function GetDateInStr(DateValue) {
	var DateObject = new Date(DateValue);
	var Result = '' + DateObject.getFullYear();
	var Month = DateObject.getMonth();
	Month++;
	if (Month < 10) {
		Month = '0' + Month;
	}
	var Day = DateObject.getDate();
	if (Day < 10) {
		Day = '0' + Day;
	}
	Result = Result + '%2D' + Month + '%2D' + Day;
	return Result;
}
 
// ----------------------------------------------------------------------------
// Event handlers
// ----------------------------------------------------------------------------
 
function wnd_UploadCurrencyRatesOnPrepare(Window) {
	pbUpload.Position = 0;
	edtRatesDate.Value = GetLocalDate();
}
 
function btnOKOnClick(Control) {
	var URL;
	var Message = "Please, specify the 'CurrencyRatesDictionaryURL' system parameter";
	try {
		URL = GetSystemParameterValueEx('CurrencyRatesDictionaryURL', true);
		if (IsEmptyValue(URL)) {
			ShowWarningDialog(Message);
		}
	} catch(e) {
		ShowWarningDialog(Message);
		return;
	}
	var DateValue = edtRatesDate.Value;
	if (IsEmptyValue(DateValue)) {
		DateValue = GetLocalDate();
	}
	URL = ReplaceString(URL, '#DateMacro#', GetDateInStr(DateValue));
	if (ShowConfirmationDialog("Do you want to upload currencies from the \n " + 
		URL + '?') != wmrYes) {
	    return;
	}
	UploadCurrencyRates(URL);
	Self.Close();
	SendNotify(Self, MSG_REFRESHDATA, 0);
}
 
function btnCancelOnClick(Control) {
	Self.Close();
}

Non noceo.

может финальный вариант в "примеры решений"?

Это 3 финальных варианта - для рубля, гривны и доллара...

Non noceo.

Здравствуйте!

Загрузила сервисы. В wnd_UploadCurrencyRatesScript используется скрипт scr_SystemSettings, который не нахожу в базе. Как быть?

Подскажите, пожалуйста, еще по следующему пункту

1. Добавить системный параметр:
CurrencyRatesDictionaryURL

Куда его добавлять?

"Шальнева Марина" написал:
В wnd_UploadCurrencyRatesScript используется скрипт scr_SystemSettings, который не нахожу в базе. Как быть?

Видимо, в конфигурации образца 2008 года была, сейчас нет.
Функция GetSystemParameterValueEx сейчас находится в скрипте scr_Utils.


1. Добавить системный параметр:

Речь, похоже, о системных настройках, "Файл"->"Настройки"->"Системные настройки".

Здравствуйте, Марина!

данный скрипт существовал в старых версиях,начиная с 3.3.1 полностью перенесен в базу данных - tbl_SystemSetting

Это - строковая переменная, которая должна содержать адрес, с которого мы загружаем курс.

"Кихтенко Андрей" написал:1. Добавить системный параметр:
CurrencyRatesDictionaryURL
http://www.cbr.ru/scripts/XML_daily_eng.asp?date_req=#DateMacro# - для англоязычной версии
http://www.cbr.ru/scripts/XML_daily.asp?date_req=#DateMacro# - для русскоязной версии

Для нормальной работы скрипта достаточно добавить такой параметр Системные настройки:

systemsetting

Добрый день!

Все подключила, системный параметр указала, при загрузке вываливается ошибка:

'Object 'DataField DueDate' is not assigned'

Марина, данная реализация опубликована для старых версий Terrasoft, поэтому требуется доработка скрипта в связи с изменением структуры БД.

В данном конкретном случае для диагностики сбоя рекомендуем Вам активировать отладчик и выяснить, на какой строке возникает сбой.

Вероятная проблема - в датасете, к которому Вы обращаетесь в скрипте нет поля DueDate, либо датасет пуст.

Также рекомендуем ознакомиться с реализацией получения курсов валют в следующей теме:
http://www.community.terrasoft.ru/blogs/7673

Добрый день!

Получилось выгрузить курсы валют. В датасете действительно не было поля DueDate.

Показать все комментарии