|
Защита от пользовательской глупости | ☑ | ||
---|---|---|---|---|
0
example221
28.02.20
✎
10:13
|
Всем добрый день.
Пишу новый функционал добавления платный ДКП по заказу,впринципе все сделал,но не разу неделал защиту от пользовательской глупости по типу тыкнуть по кнопке 10 раз надо как то через если проверить был ли введен уже дкп и если был то не создавать и выводить сообщение вот сама процедура НомерДоговора = ?(Организация = Справочники.Организации.ОсновнаяОрганизация,"ВПА-",Организация.Префикс+"-") + прав(Номер,5) + "-" + Формат(дата, "ДФ=yy") + " от " + Формат(дата, "ДФ=dd.MM.yyyy"); Запрос = Новый Запрос; запрос.текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | ДоговорыВзаиморасчетов.Ссылка, | ДоговорыВзаиморасчетов.Владелец, | ДоговорыВзаиморасчетов.ВидДоговора |ИЗ | Справочник.ДоговорыВзаиморасчетов КАК ДоговорыВзаиморасчетов |ГДЕ | ДоговорыВзаиморасчетов.Владелец = &контрагент | И ДоговорыВзаиморасчетов.ВидДоговора = &ВидДоговора | И ДоговорыВзаиморасчетов.Организация = &Организация"; Запрос.УстановитьПараметр("контрагент", Контрагент); Запрос.УстановитьПараметр("ВидДоговора",Перечисления.ВидыДоговоров.Продажа); Запрос.УстановитьПараметр("Организация",Организация); РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); Пока Выборка.Следующий() Цикл Договор = Выборка.Ссылка; КонецЦикла; //документРеализацияТоваров_ВИП_Столяров ДокРеализация = Документы.РеализацияТоваров.СоздатьДокумент(); ДокРеализация.Дата = ТекущаяДата(); ДокРеализация.СкладКомпании = СкладКомпании; ДокРеализация.Контрагент = Контрагент; ДокРеализация.ХозОперация = Справочники.ХозОперации.АктОбОказанииУслуг; ДокРеализация.ДоговорВзаиморасчетов = Договор; ДокРеализация.Автор = ПараметрыСеанса.Пользователь; ДокРеализация.Организация = организация; ДокРеализация.ВалютаДокумента = ВалютаДокумента; ДокРеализация.КурсДокумента = КурсДокумента; ДокРеализация.ТипЦен = Справочники.ТипыЦен.ОсновнойТипЦенПродажи; ДокРеализация.ПодразделениеКомпании = ПодразделениеКомпании; ДокРеализация.РегламентированныйУчет = Истина; //ЗаписьДокумента //ДобавлениеНоменклатурыВреализацию_ВИП_Столяров НоваяСтрока = ДокРеализация.Товары.Добавить(); СпрНом = Справочники.Номенклатура.НайтиПоКоду("ЦБАА0003041"); НоваяСтрока.Номенклатура = СпрНом; НоваяСтрока.Коэффициент = 1; НоваяСтрока.Количество = 1; ДокРеализация.ОбработкаРеквизита("Товары.Номенклатура",НоваяСтрока); //НоваяСтрока.Цена = ; //НоваяСтрока.Сумма = НоваяСтрока.Цена*НоваяСтрока.Количество; //НоваяСтрока.СуммаВсего = НоваяСтрока.Сумма*НоваяСтрока.Коэффициент; НоваяСтрока.ЕдиницаИзмерения = СпрНом.ОсновнаяЕдиницаИзмерения; //НоваяСтрока.СтатьяДоходов = Справочники.СтатьиДоходовИРасходов.НайтиПоКоду("ЦБ000270"); НоваяСтрока.СтавкаНДС = Справочники.СтавкиНДС.ОсновнаяСтавкаНДС2019; НоваяСтрока.Содержание = "Платный ДКП договор " + "№" + НомерДоговора; ДокРеализация.ОбработкаРеквизита("Товары.СтавкаНДС",НоваяСтрока); //ПроведениеДокумена Попытка ДокРеализация.Записать(РежимЗаписиДокумента.Проведение); Исключение Попытка ДокРеализация.Записать(РежимЗаписиДокумента.Запись); Сообщить("Документ Реалезации не проведен."); Форма = ДокРеализация.ПолучитьФорму("ФормаДокумента"); Форма.Открыть(); Исключение Сообщить("Документ Реалезации не записан."); Форма = ДокРеализация.ПолучитьФорму("ФормаДокумента"); Форма.Открыть(); КонецПопытки; КонецПопытки; ДокРеализация.Печать("Расходная накладная",1,Ложь,); ДокРеализация.Печать("Расходная накладная",1,Ложь,); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | СчетФактураВыданный.Ссылка |ИЗ | Документ.СчетФактураВыданный КАК СчетФактураВыданный |ГДЕ | СчетФактураВыданный.ДокументыОснования.ДокументОснование = &ДокументОснование"; Запрос.УстановитьПараметр("ДокументОснование", ДокРеализация.Ссылка); РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Объект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект(); Объект.Печать("СчетФактура",1,Ложь,); Объект.Печать("СчетФактура",1,Ложь,); КонецЦикла; //ДокументСчетНаОплату_ВИП_Столяров ДокСчетНаОплату = Документы.СчетНаОплату.СоздатьДокумент(); ДокСчетНаОплату.Дата = ТекущаяДата(); ДокСчетНаОплату.Автор = ПараметрыСеанса.Пользователь; ДокСчетНаОплату.ДоговорВзаиморасчетов = ДокРеализация.ДоговорВзаиморасчетов; ДокСчетНаОплату.КурсДокумента = КурсДокумента; ДокСчетНаОплату.Организация = организация; ДокСчетНаОплату.ДокументОснование = ДокРеализация.Ссылка; ДокСчетНаОплату.ТипЦен = Справочники.ТипыЦен.ОсновнойТипЦенПродажи; ДокСчетНаОплату.ПодразделениеКомпании = ПодразделениеКомпании; ДокСчетНаОплату.ВалютаДокумента = ВалютаДокумента; ДокСчетНаОплату.Контрагент = Контрагент; ДокСчетНаОплату.РасчетныйСчетОрганизации = Организация.ОсновнойБанковскийСчет.Ссылка; ДокСчетНаОплату.ХозОперация = Справочники.ХозОперации.СчетНаОплату; //Добавление номенклатуры ВИП_Столяров НоваяСтрока1 = ДокСчетНаОплату.Товары.Добавить(); НоваяСтрока1.Номенклатура = СпрНом; НоваяСтрока1.Коэффициент = 1; НоваяСтрока1.Количество = 1; НоваяСтрока1.ЕдиницаИзмерения = СпрНом.ОсновнаяЕдиницаИзмерения; ДокСчетНаОплату.ОбработкаРеквизита("Товары.Номенклатура",НоваяСтрока1); //НоваяСтрока1.Цена = 2000; //НоваяСтрока1.Сумма = НоваяСтрока.Цена*НоваяСтрока.Количество; //НоваяСтрока1.СуммаВсего = НоваяСтрока.Сумма*НоваяСтрока.Коэффициент; НоваяСтрока1.СтавкаНДС = Справочники.СтавкиНДС.ОсновнаяСтавкаНДС2019; ДокСчетНаОплату.ОбработкаРеквизита("Товары.СтавкаНДС",НоваяСтрока1); НоваяСтрока1.Комментарий = НоваяСтрока.Содержание; //ЗаписьПроведеие_ВИП_Столяров Попытка ДокСчетНаОплату.Записать(РежимЗаписиДокумента.Запись); Исключение Сообщить("Документ Счет на оплану не Записан."); Форма = ДокСчетНаОплату.ПолучитьФорму("ФормаДокумента"); Форма.Открыть(); КонецПопытки; ДокСчетНаОплату.Печать("Счет на услуги (внешняя)",1,Ложь,); |
|||
1
vicof
28.02.20
✎
10:15
|
Защиты от пользовательской глупости нет. Она всесильна и безгранична.
|
|||
2
unenu
28.02.20
✎
10:16
|
понятный вопрос, блестящий код, логичные выводы - все разумно.
|
|||
3
pechkin
28.02.20
✎
10:16
|
(1) от глупости нет, но защита чтоб глупость не навредила системе - есть
|
|||
4
pechkin
28.02.20
✎
10:17
|
ну и как обычно: сначала ищем - потом обновляем или создаем новый
|
|||
5
example221
28.02.20
✎
10:32
|
Да вопросы не умею еще писать,ну что надо просто проверить были ли созданы это 2 документа только как я не знаю
|
|||
6
D_E_S_131
28.02.20
✎
10:41
|
Что это за нагромождение кода? Где, собственно, сам ДКП? И что это вообще такое "ДКП" и в каком месте он создается (там же по идее и проверять нужно)?
|
|||
7
PR
28.02.20
✎
10:43
|
(0) 42
|
|||
8
Ёпрст
28.02.20
✎
10:44
|
(0) Какую-то хрень, вы, товарищ Столяров понаписали.
|
|||
9
ДенисЧ
28.02.20
✎
10:44
|
От пользовательской глупости хорошо помогает ПКВ.
Или ЗСУ-23-4 |
|||
10
Ёпрст
28.02.20
✎
10:45
|
От так делай всегда и ждёт тебя удача
//Номенклатура.НайтиПоКоду("ЦБАА0003041"); |
|||
11
Ёпрст
28.02.20
✎
10:46
|
А вот кто будет защищать пользователей от дурного кода ?
|
|||
12
Ёпрст
28.02.20
✎
10:48
|
Ну и ..."Счет на оплану не Записан".. Когда пользователь увидит Оплану, с ума сойдёт, наверное, и будет жать на кнопку 10 раз
|
|||
13
example221
28.02.20
✎
10:49
|
(12) axaxaxax
|
|||
14
MyNick
28.02.20
✎
10:52
|
(0) для начала нужно усвоить простую истину.
Если можно по кнопке тыкнуть 10 раз и она при этом создаст 10 ненужных дублей, то это не ПОЛЬЗОВАТЕЛЬСКАЯ ГЛУПОСТЬ, а глупость того, кто это спроектировал и реализовал. |
|||
15
MyNick
28.02.20
✎
10:56
|
...советую забыть про пользовательскую глупость для собственного оправдания плохой реализации функционала.
Подходи к архитектуре так, будто реализуешь алгоритм шахматной партии между двумя компьютерными ботами. Ставь на то, что твои алгоритмы должны при этом выйграть. Нашлась брешь - ты проиграл, ты плохой программист. Разница в том, что в таком случае, ты будешь критично относиться к себе и с уважением к тому, кто будет использовать твой продукт. |
|||
16
VladZ
28.02.20
✎
10:56
|
(14) +500
|
|||
17
Ёпрст
28.02.20
✎
10:57
|
(0) этот код откуда хоть вызывается ?
|
|||
18
example221
28.02.20
✎
11:00
|
Из модуля формы документа (17)
|
|||
19
example221
28.02.20
✎
11:01
|
(17) Есть идея что я могу по строке содержание(коментария) проверить есть ли уже такой комент,и на всякий поверх еще фильтрануть по контрагенту
|
|||
20
nicxxx
28.02.20
✎
11:04
|
(0) Как бы еще от твоей глупости защититься? Глаза ведь режет "но не разу неделал".
|
|||
21
VladZ
28.02.20
✎
11:05
|
Предложения и замечания:
1. Обычно пользователь работает параллельно над несколькими задачами. В таких случаях внимание рассеивается. 2. Как следствие: пользователь должен видеть выполнение программы на каждом этапе. Если документы были сформированы - пользователь должен увидеть, что они сформированы. Если распечатаны - пользователь должен увидеть, что документы распечатаны. Исходя из этих требований и разрабатывай интерфейс. Ситуация, когда пользователь нажал на кнопку и далее не управляет процессом - это хреновая реализация. |
|||
22
example221
28.02.20
✎
11:08
|
(21) Он все видит,если сформировалось то передним выйдет отправка на печать,если нет то сообщение что не записано не проведено
|
|||
23
VladZ
28.02.20
✎
11:18
|
(22) Смоделируй такую ситуацию:
1. Пользователь нажал на кнопку 2. Отвлекся на другую задачу. 3. Вернулся на эту задачу. Как пользователю убедится, что нужные документ он действительно сформировал (и нет необходимости еще раз нажимать на кнопку)? |
|||
24
Ёпрст
28.02.20
✎
11:18
|
(18) И в этой форме документа нет договора, что его искать надо таким диким способом ?
|
|||
25
VladZ
28.02.20
✎
11:19
|
+23 Сядь сам за эту обработку и тыкай кнопку в течении 4х часов.
Расскажешь, потом, что ты думаешь про этот интерфейс. |
|||
26
Михаил Михайлович
28.02.20
✎
11:20
|
(22) каким "передним"? а задним, что?
|
|||
27
example221
28.02.20
✎
11:26
|
(26) а задним опа
|
|||
28
Михаил Михайлович
28.02.20
✎
11:28
|
(27) да тут (0) совсем опа
|
|||
29
example221
28.02.20
✎
11:29
|
(23) так вот я и хочу написать через если,что если создано он не будет формировать
|
|||
30
example221
28.02.20
✎
11:30
|
(25) НомерДоговора = ?(Организация = Справочники.Организации.ОсновнаяОрганизация,"ВПА-",Организация.Префикс+"-") + прав(Номер,5) + "-" + Формат(дата, "ДФ=yy") + " от " + Формат(дата, "ДФ=dd.MM.yyyy");
пСодержание = "Платный ДКП договор " + "№" + НомерДоговора; Запрос2 = Новый Запрос; Запрос2.Текст = "ВЫБРАТЬ | РеализацияТоваровТовары.Содержание |ИЗ | Документ.РеализацияТоваров.Товары КАК РеализацияТоваровТовары |ГДЕ | РеализацияТоваровТовары.Содержание = &Содержание"; Запрос2.установитьПараметр("Содержание",пСодержание); РезЗапроса = Запрос2.Выполнить(); Выборка1 = РезЗапроса.Выбрать(); Пока Выборка1.Следующий() Цикл пПроверка = Выборка1.Содержание; КонецЦикла; Если пПроверка =NULL Тогда Запрос = Новый Запрос; запрос.текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | ДоговорыВзаиморасчетов.Ссылка, | ДоговорыВзаиморасчетов.Владелец, | ДоговорыВзаиморасчетов.ВидДоговора |ИЗ | Справочник.ДоговорыВзаиморасчетов КАК ДоговорыВзаиморасчетов |ГДЕ | ДоговорыВзаиморасчетов.Владелец = &контрагент | И ДоговорыВзаиморасчетов.ВидДоговора = &ВидДоговора | И ДоговорыВзаиморасчетов.Организация = &Организация"; Запрос.УстановитьПараметр("контрагент", Контрагент); Запрос.УстановитьПараметр("ВидДоговора",Перечисления.ВидыДоговоров.Продажа); Запрос.УстановитьПараметр("Организация",Организация); РезультатЗапроса = Запрос.Выполнить(); Выборка = РезультатЗапроса.Выбрать(); Пока Выборка.Следующий() Цикл Договор = Выборка.Ссылка; КонецЦикла; //документРеализацияТоваров_ВИП_Столяров ДокРеализация = Документы.РеализацияТоваров.СоздатьДокумент(); ДокРеализация.Дата = ТекущаяДата(); ДокРеализация.СкладКомпании = СкладКомпании; ДокРеализация.Контрагент = Контрагент; ДокРеализация.ХозОперация = Справочники.ХозОперации.АктОбОказанииУслуг; ДокРеализация.ДоговорВзаиморасчетов = Договор; ДокРеализация.Автор = ПараметрыСеанса.Пользователь; ДокРеализация.Организация = организация; ДокРеализация.ВалютаДокумента = ВалютаДокумента; ДокРеализация.КурсДокумента = КурсДокумента; ДокРеализация.ТипЦен = Справочники.ТипыЦен.ОсновнойТипЦенПродажи; ДокРеализация.ПодразделениеКомпании = ПодразделениеКомпании; ДокРеализация.РегламентированныйУчет = Истина; //ЗаписьДокумента //ДобавлениеНоменклатурыВреализацию_ВИП_Столяров НоваяСтрока = ДокРеализация.Товары.Добавить(); СпрНом = Справочники.Номенклатура.НайтиПоКоду("ЦБАА0003041"); НоваяСтрока.Номенклатура = СпрНом; НоваяСтрока.Коэффициент = 1; НоваяСтрока.Количество = 1; ДокРеализация.ОбработкаРеквизита("Товары.Номенклатура",НоваяСтрока); //НоваяСтрока.Цена = ; //НоваяСтрока.Сумма = НоваяСтрока.Цена*НоваяСтрока.Количество; //НоваяСтрока.СуммаВсего = НоваяСтрока.Сумма*НоваяСтрока.Коэффициент; НоваяСтрока.ЕдиницаИзмерения = СпрНом.ОсновнаяЕдиницаИзмерения; //НоваяСтрока.СтатьяДоходов = Справочники.СтатьиДоходовИРасходов.НайтиПоКоду("ЦБ000270"); НоваяСтрока.СтавкаНДС = Справочники.СтавкиНДС.ОсновнаяСтавкаНДС2019; НоваяСтрока.Содержание = "Платный ДКП договор " + "№" + НомерДоговора; ДокРеализация.ОбработкаРеквизита("Товары.СтавкаНДС",НоваяСтрока); //ПроведениеДокумена Попытка ДокРеализация.Записать(РежимЗаписиДокумента.Проведение); Исключение Попытка ДокРеализация.Записать(РежимЗаписиДокумента.Запись); Сообщить("Документ Реалезации не проведен."); Форма = ДокРеализация.ПолучитьФорму("ФормаДокумента"); Форма.Открыть(); Исключение Сообщить("Документ Реалезации не записан."); Форма = ДокРеализация.ПолучитьФорму("ФормаДокумента"); Форма.Открыть(); КонецПопытки; КонецПопытки; ДокРеализация.Печать("Расходная накладная",1,Ложь,); ДокРеализация.Печать("Расходная накладная",1,Ложь,); Запрос1 = Новый Запрос; Запрос1.Текст = "ВЫБРАТЬ | СчетФактураВыданный.Ссылка |ИЗ | Документ.СчетФактураВыданный КАК СчетФактураВыданный |ГДЕ | СчетФактураВыданный.ДокументыОснования.ДокументОснование = &ДокументОснование"; Запрос.УстановитьПараметр("ДокументОснование", ДокРеализация.Ссылка); РезультатЗапроса = Запрос.Выполнить(); ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать(); Пока ВыборкаДетальныеЗаписи.Следующий() Цикл Объект = ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект(); Объект.Печать("СчетФактура",1,Ложь,); Объект.Печать("СчетФактура",1,Ложь,); КонецЦикла; //ДокументСчетНаОплату_ВИП_Столяров ДокСчетНаОплату = Документы.СчетНаОплату.СоздатьДокумент(); ДокСчетНаОплату.Дата = ТекущаяДата(); ДокСчетНаОплату.Автор = ПараметрыСеанса.Пользователь; ДокСчетНаОплату.ДоговорВзаиморасчетов = ДокРеализация.ДоговорВзаиморасчетов; ДокСчетНаОплату.КурсДокумента = КурсДокумента; ДокСчетНаОплату.Организация = организация; ДокСчетНаОплату.ДокументОснование = ДокРеализация.Ссылка; ДокСчетНаОплату.ТипЦен = Справочники.ТипыЦен.ОсновнойТипЦенПродажи; ДокСчетНаОплату.ПодразделениеКомпании = ПодразделениеКомпании; ДокСчетНаОплату.ВалютаДокумента = ВалютаДокумента; ДокСчетНаОплату.Контрагент = Контрагент; ДокСчетНаОплату.РасчетныйСчетОрганизации = Организация.ОсновнойБанковскийСчет.Ссылка; ДокСчетНаОплату.ХозОперация = Справочники.ХозОперации.СчетНаОплату; //Добавление номенклатуры ВИП_Столяров НоваяСтрока1 = ДокСчетНаОплату.Товары.Добавить(); НоваяСтрока1.Номенклатура = СпрНом; НоваяСтрока1.Коэффициент = 1; НоваяСтрока1.Количество = 1; НоваяСтрока1.ЕдиницаИзмерения = СпрНом.ОсновнаяЕдиницаИзмерения; ДокСчетНаОплату.ОбработкаРеквизита("Товары.Номенклатура",НоваяСтрока1); //НоваяСтрока1.Цена = 2000; //НоваяСтрока1.Сумма = НоваяСтрока.Цена*НоваяСтрока.Количество; //НоваяСтрока1.СуммаВсего = НоваяСтрока.Сумма*НоваяСтрока.Коэффициент; НоваяСтрока1.СтавкаНДС = Справочники.СтавкиНДС.ОсновнаяСтавкаНДС2019; ДокСчетНаОплату.ОбработкаРеквизита("Товары.СтавкаНДС",НоваяСтрока1); НоваяСтрока1.Комментарий = НоваяСтрока.Содержание; //ЗаписьПроведеие_ВИП_Столяров Попытка ДокСчетНаОплату.Записать(РежимЗаписиДокумента.Запись); Исключение Сообщить("Документ Счет на оплану не Записан."); Форма = ДокСчетНаОплату.ПолучитьФорму("ФормаДокумента"); Форма.Открыть(); КонецПопытки; ДокСчетНаОплату.Печать("Счет на услуги (внешняя)",1,Ложь,); Иначе Сообщить("Документы Уже сформированы!!!"); КонецЕсли |
|||
31
example221
28.02.20
✎
11:30
|
к этому эта ветка и создана,кто шарит подскажите пожалуйста
|
|||
32
Ёпрст
28.02.20
✎
11:31
|
(30) стало еще хуже
|
|||
33
Ёпрст
28.02.20
✎
11:32
|
Из формы какого документа идёт вызов того, что в (0) ?
Там есть Договор ? |
|||
34
Ёпрст
28.02.20
✎
11:32
|
На какую дату создаются эти 2 документа ?
|
|||
35
Ёпрст
28.02.20
✎
11:33
|
всегда на текущую ?
|
|||
36
Йохохо
28.02.20
✎
11:34
|
(30) кто ты без Т9? погромизд
|
|||
37
Ёпрст
28.02.20
✎
11:34
|
Справочники.Номенклатура.НайтиПоКоду("ЦБАА0003041"); //это что за номенклатура, если ёё надо по коду искать ?
|
|||
38
example221
28.02.20
✎
11:35
|
(33) на дату проводки заказа на авто/или сдачи его в трейд ин,из формы заказа или поступления идет вызов
это номенклатура платного оформления ДКП |
|||
39
example221
28.02.20
✎
11:35
|
услуга
|
|||
40
example221
28.02.20
✎
11:36
|
(36) :D
|
|||
41
Gbpltw
28.02.20
✎
11:38
|
(32) ну чё начинаешь, нормально же общались)))
(39) а почему не используются общие модули? |
|||
42
Gbpltw
28.02.20
✎
11:39
|
ТЧ Счет можно/нужно заполнять "на основании" РТиУ
|
|||
43
example221
28.02.20
✎
11:48
|
(42) ДокСчетНаОплату.ДокументОснование = ДокРеализация.Ссылка;
в чем проблема то? |
|||
44
example221
28.02.20
✎
11:48
|
Ладно закрыто,пока рофлили вроде дошло и сделал)
|
|||
45
Simod
28.02.20
✎
11:54
|
(0) Неправильно все - как общая концепция формирования пакета документов, так и детали реализации.
Если должен быть сформирован весь пакет документов, особенно на основании друг-друга, то должна использоваться транзакция или иной механизм отмены формирования пакета для обеспечения целостности операции. Здесь, если не создался один документ, то продолжается формирование последующих со ссылкой на предыдущий. - номер договора формируется на основании префикса в коде; - в запросе выбираются лишние данные; - не проверяется заполнение переменных (Организация, контрагент и т.д.), которые критичны для создания документов; - не проверяются результаты выполнения запроса; - печать не созданных документов. Печать может быть опциональной; - поиск по коду и отсутствие проверки результата поиска; и т.д. Ну и общая небрежность самого кода. Даже читать неприятно. |
|||
46
example221
28.02.20
✎
12:29
|
(21) Сделал предложения по контролю)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |