Периодически возникает необходимость создавать маски номеров не стандартного типа (%1), а с использованием нулей в начале (например, 000000%1).

При таком использовании нули будут каждый раз добавляться в левой части не зависимо от количества символов, поэтому вместо маски:

00000010

получиться следующая:

000000010

Есть некоторые варианты решения вопроса, но мы «выкрутились» простым кодом JavaScript:

1. Создали для примера следующую маску:

/system/files/invoicemask_1.png

2. Добавили следующий код для счетов:

         var CurrentNumber = Dataset.Values('InvoiceNumber');
         var CurrentNumberLength = CurrentNumber.length;
         if (CurrentNumberLength > 8) {
                   var NewNumber = CurrentNumber.substring(CurrentNumberLength - 8);
                   Dataset.Values('InvoiceNumber') = NewNumber;
         }

/system/files/invoice_2.png

В результате мы получили нумерацию такого типа:

/system/files/invoicenumber_3.png

Нравится

Поделиться

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

Доброго времени суток всем!
Недавно вот придумал такой еще универсальный вариант:

В сервисе Common\Library\scr_CommonActions приведите функцию
function GenerateSystemNumber(ItemName) к виду:

function GenerateSystemNumber(ItemName) {
	var GeneratedNumber;
	var SystemParameterName = FormatStr('%1Number', ItemName);
	var MaskName = FormatStr('%1Mask', ItemName);
	var SystemNumber =
		GetSystemParameterValueEx(SystemParameterName, true) + 1;		
 
	try {
        var MaskLength = System.GetSystemSettingValue(FormatStr('%1Length', MaskName), false);
 
    	while (SystemNumber.toString().length < MaskLength) {
           SystemNumber = '0'.concat(SystemNumber);
        }
 
    } catch (e) {
    	Log.Write(0, e.message);
	} finally {
        //var MaskLength = null;
    }
 
	SetSystemParameterValue(SystemParameterName, SystemNumber);
	var Mask = GetSystemParameterValueEx(MaskName, false);
	if ((Mask != EmptyStr) && (Mask != undefined) && (Mask != null)) {
		GeneratedNumber = FormatStr(Mask, SystemNumber.toString());
	} else {
		GeneratedNumber = SystemNumber.toString();
	}
	return GeneratedNumber;
}

Теперь, для автоматического заполнения номера записи нулями слева, нужно ввести дополнительный системный параметр под каждый раздел, где это нужно:

<Имя Разделя><Mask>Length

.

Например:
раздел Счета - Invoice
маска счета: InvoiceMask
количество символов номера в номере счета: InvoiceMaskLength

Здравствуйте, Павел!

Есть вопрос: что будет, если в момент времени между выполнением строк

var SystemNumber =
                GetSystemParameterValueEx(SystemParameterName, true) + 1;

и

SetSystemParameterValue(SystemParameterName, SystemNumber);

то же самое проделает скрипт другого пользователя?

Например, если у нас в системе не 10-20 пользователей работают, а 200-500?

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

Если такая ситуация в жизни возможна - приведет только к тому, что в системе появится 2 счета с одинаковыми номерами. Но к ошибке это точно не приведет. Т.к. GetSystemParameterValueEx и SetSystemParameterValue приводят к обращению в СУБД, а она уже управляет очередью запросов.

Поэтому, теориетически, если рассматривать "чистую модель" ситуации, получение одного и того же параметра SystemParameterName возможно. Когда второй пользователь его уже получает пока первый еще не изменил. Но, фактически ситуация настолько маловероятна, если учесть что проме этих двух запросов в БД будет еще с десяток других идти, и все они будут в очередь попадать...

В целом, можно не беспокоиться.

Позволю себе не согласиться...

У нас регулярно происходят подобные ситуации, правда применительно к шагам процесса, а не генерации уникальных номеров. Когда-нибудь думаю дойдут руки поправить.

Этот код не обеспечивает самого главного: последовательной и уникальной генерации номеров.
Принцип "ситуация настолько маловероятна" когда пользователей достаточно много, и сервер БД все таки сервер, а не настольный компьютер, к сожалению, не работает.

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

Добрый день, уважаемые пользователи интернет сообщества Terrasoft!

Как вы знаете, в системе BPMonline в таких сущностях как счет, документ и пр., существует поле "Номер", которое автоматически (если другой не указан) проставляется как номер предыдущей сущности плюс один. Иногда возникает необходимость добавить префиксы к нумерации, т.е к примеру счета нумеровать как С-1, С-2 и т.д., документы - Д-1, Д-2 и т.д.
Предлагаю Вам простой способ реализации автоматического проставления префиксов к номерам:
для этого Вам необходимо перейти в раздел «Системные настройки» меню [Инструменты] и открыть группу «Автонумерация записей». В этой группе откройте системную настройку «Маска номера инцидента» (документа, счета и т. д.)

1

и измените значение следующим образом:

I: {0} (для инцидента, другие префиксы - для других сущностей).

2

Приятной работы с BPMonline!

Нравится

Поделиться

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

Добрый день!
А как например добавить текущую дату к номеру документа?
Какие-то еще маски кроме {0} целочисленных допускаются?
Или это уже на уровне базы данных нужно делать?
Спасибо

На уровне конфигурации.

Чтобы произвольным образом изменить маску, нужно доработать в схеме «Сгенерировать номер по порядку» функцию «GenerateNumberForSchemaName». Там на вход подаётся название раздела, можно для какого-то одного или для любого раздела заменять определённый макрос на текущую дату.

Если возникают вопросы о конретной реализации, напишите пример формата номера, который хотите получить.

Спасибо, Александр.
Нашел метод GenerateSequenseNumber в схеме «Сгенерировать номер по порядку» в пакете Base 7.5.0
Подскажите еще, как мне его переопределить в своем пакете? Создать свой бизнес-процесс?
Хочу формировать номер заказа в формате YYYY/MM-###

Ниже генерация номера договора (OrderPageV2) в формате Город: кодГорода + Знач.Сис.Настройки + НомерПопорядку(6 знаков) + Знач.Сис.Настройки + КодПродуктаВДоговоре.
Может поможет:

onEntityInitialized: function() {
				this.callParent(arguments);
				if (this.isAddMode() || this.isCopyMode() || this.get("NumberEx") === ""
                        || this.get("NumberEx") === undefined || this.get("NumberEx") === null) {
                    if (this.get("Number") === "") {
                        this.getIncrementCode(function (responce) {
                            this.set("Number", responce);
                        });
                    }
					var owner = this.get("Owner");
					if (!this.Ext.isEmpty(owner)) {
						this.getContactCityCode(owner, function(cityCode) {
							if (this.Ext.isEmpty(cityCode) || this.Ext.isEmpty(cityCode.city)) {
								this.set("Number", "");
								this.set("NumberEx", "");
								this.showMessage("Номер договора не сгенерирован. В карточке ответственного не указан город!");
								return;
							}
							else if (this.Ext.isEmpty(cityCode.code)) {
								this.set("Number", "");
								this.set("NumberEx", "");
								this.showMessage("Номер договора не сгенерирован. Для города ответственного не указан код!");
							} else {
								this.getProductCode(function(productCode) {
									if (this.Ext.isEmpty(productCode) || this.Ext.isEmpty(productCode.product)) {
										this.set("Number", "");
										this.set("NumberEx", "");
										this.showMessage("Номер договора не сгенерирован. В заявке нет продуктов!");
										return;
									} else if (this.Ext.isEmpty(productCode.code)) {
										this.set("Number", "");
										this.set("NumberEx", "");
										this.showMessage("Номер договора не сгенерирован. В продукте заявки не указан код!");
									} else {
										var OrderNumber = this.get("Number");
										while(OrderNumber.length < 6) {
											OrderNumber = "0" + OrderNumber;
										}
										var parentThis = this;
										Terrasoft.SysSettings.querySysSettingsItem("OrderNumberSeparator", function(value) {
											parentThis.set("NumberEx", cityCode.city + ": " + cityCode.code + value +
												OrderNumber + value + productCode.code);
											parentThis.set("Number", cityCode.city + ": " + cityCode.code + value +
												OrderNumber + value + productCode.code);
										});
									}
								});
							}
						});
					}
				}
			}

Спасибо большое!

Каким образом решить проблему с сортировкой по полю номер с использованием маски, т.к. поле "Номер" является текстовым и в следствии этого возникает следующая ситуация:

Вопрос с сортировкой продолжили обсуждать здесь.

Здравствуйте. Подскажите пожалуйста, а как настроить маску, чтобы нумерация была типа цифры-год. Чтобы каждый год естественно концовка менялась. К примеру, 1885-15
Благодарю

Какая версия используется?

"Зверев Александр" написал:

Какая версия используется?

Здравствуйте, Александр. Используется версия 7.6

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

1. Запустить TSAdmin.exe

2. В дереве сервисов найти сервис таблицы Счета (tbl_Invoice), открыть (\Invoices\General\Main Grid\tbl_Invoice).
3. В Indexes, с помощью контекстного меню добавить индекс, указать ему название, как показано на скриншоте ниже.

4. Установите для поля галочку «Уникальное»

5. Затем добавьте индексное поле

6. И свяжите его с номером счета:

7. Сохраните таблицу:

В результате при дублировании номера счета программа будет уведомлять оператора:

и запрещать сохранять запись:

Нравится

Поделиться

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

Анна, сообщения об ошибке нервируют пользователей. Я бы даже сказала "пугает".
Нельзя ли как-то сделать это предупреждением?

Согласен с Алёной. Такая ошибка слишком жестка для пользователя.
Выходом может быть автоматическое формирования уникального поля и закрытие его редактирования пользователем.

Как вариант, можно в scr_BaseDBEditUtils в функции SaveChangesWithCheck отлавливать сообщение об ошибке и анализировать его (благо имя индекса уникально):

...
catch (e) {
		var Message = e.message;
		if (Message.indexOf('IInvoiceNumber') != -1) {
			Message = "Номер не уникальный!"+'\n'+
				"невозможно сохранить запись";
			System.MessageDialog(Message, mdtInformation, mdbOK, 0);
		} else {
			System.MessageDialog(Message, mdtError, mdbOK, 0);
		}
		Result = false;
	}
...

Здорово :) Пока я думала над решением, Максим меня опередил :)

В принципе, хотела предложить то же самое:

в скрипте scr_BaseDBEditUtils в функции function SaveChangesWithCheck в блоке catch добавить проверку:

if (e.number == -2147418113){
			MessageBox("Невозможно сохранить счет, так как счет с таким номером уже существует! Введите другой номер.");
			Result = false;
		} else

Скрипт в итоге будет выглядеть так:

А программа будет выдавать то сообщение, которое Вы введете в MessageBox:

В любом случае, реализация Максима лучше, поэтому рекомендую использовать ее.

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

Помогите разобраться, были розданы права группам пользователей, а теперь у некоторых групп пользователей при создании нового контрагента не присваивается порядковый номер выдаёт только 0. Права в разделе контрагенты таковы:
В Права доступа к группам таблиц разрешено всё кроме удаления
В Права доступа к полям на раздел контрагент разрешено всё
В правах доступа по умолчанию данной группе пользователей разрешено всё кроме удаления.
Подскажите в чём ошибка?

Нравится

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

Уточните, пожалуйста, каким образом присваивается порядковый номер контрагенту и где хранится последний присвоенный номер.

Присваивается номер следующим кодом:
SetItemSystemNumber('Account', Dataset, 'AccountNumber');

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

Уважаемый Олег, у нас для таблицы tbl_SystemSetting есть только доступ для учетных записей пользователей ,а для групп пользователей нет. Не подскажете где можно найти доступ для групп пользователей?

Этим доступом можно управлять средствами СУБД, которая установлена у Вас на сервере. Если это MS SQL Server, необходимо открыть Enterprise Manager или SQL Server Management Studio (в зависимости от версии MS SQL), найти нужную базу и таблицу в ней, и посмотреть разрешения (Permissions) для этой таблицы в её свойствах. Для других СУБД, таких как Oracle или Firebird, тоже существуют свои инструменты для управления доступом на таблицы. Более подробно на этот вопрос сможет ответить системный администратор Вашей компании. Либо обратитесь в Службу технической поддержки нашей компании, и наши специалисты помогут Вам в телефонном режиме или вышлют необходимые инструкции.

Олег права стоят полные.:sad:

Тогда необходимо анализировать функционал установления номеров контрагента. Прошу Вас направить письменный запрос на адрес Службы поддержки Terrasoft: support@tscrm.com . В теле письма укажите, что запрос связан с данной темой на комьюнити и предоставьте параметры удалённого доступа.

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