При работе с системой возникла необходимость следующей доработки конфигурации:
При работе с клиентами на основании договора выписываются счета. Большинство из них стандартные и отличаются разве что датой ну и естественно контрагентом, продуктом и тд. Вся необходимая информация заложена в договоре, карточке контрагента, продукте к договору, всё стандартно. Хотелось бы реализовать механизм, когда при выборе соотвествующего действия в разделе договора, на основании всех договоров (естественно отобранных фильтрами по тех или иных критериях) осуществлялось создание счетов. Поля, которые следует изменять (дата, период оплаты и др.) можно вывести в отдельном окне и уже используя ети данные плюс значения из других полей формировать счета.
Получиться создание грубо говоря по "одному клику", что в свою очередь каждый раз будет сохранять время сотрудников (самое важное!), при правильной реализации исключит возникновение бесконечных поисков "кому же я забыл выставить счет" и тд. Такая схема применительна и в других случаях, например, в разделе Документы, когда выписываются акты на те же счета.
Думаю те, кто сталкивался с подобными медитациями в террасофте ("не трогайте меня - я счета выписываю"))) поддержат/дополнят/исправят меня или посоветуют другой механизм реализаци...
Вот такая идея, вернее сказать необходимость в моей ситуации:-)
Дискуссия неизбежна!
Не вижу никаких проблем в реализации подобного функционала. Похожий функционал, например, есть в разделе Контакты, где Вы по одному действию создаете задачу для Контакта. Также похожие действия неоднократно разрабатывались в различных конфигурация. Например, по договору создавались счета, расходные накладные.
"Fishi" написал:Дискуссия неизбежна!
Дискутировать тут особо нечего, нужно закатывать рукава и создавать необходимый функционал.
"Агутин Алексей" написал:Похожий функционал, например, есть в разделе Контакты, где Вы по одному действию создаете задачу для Контакта.
TS X25 3.1.1.26. При выборе нескольких контактов и действии "Создать задачи" соответствующее количество раз открывается карточка редактирования задачи. Я же говорил об открытии карточки один раз и копировании полей в последующие. В данном случае действие для меня совсем не понятное, потому что вместо економии времени на вбивание полей в задачах, економится время разве что на выбор действия "Создать задачу" :confused: Возможно, в дальнейшых
"Агутин Алексей" написал:Также похожие действия неоднократно разрабатывались в различных конфигурация.
Вот потому и пишу, что задача казалось бы не такая уж и нестандартная, но на форуме о реализации что-то найти трудно. Ведь если у кого-то есть рабочая реализация, то не нужно будет изобретать велосипед, а достаточно просто внести изменения для соответствия своей кинфигурации. Не одним же только менеджарам время економить:wink:
В Вашем случаем обычно применяется следующая схема:
1) В раздел Договора добавляется пункт меню "Создать счет".
2) В обработчике события этого пункта меню вызывается окно редактирования Счета с предварительным заполнением полей. Состав и содержание полей для заполнения определяется Вами.
Как добавить пункт меню и показать окно редактирования можно прочитать в
FAQ
Добрый день.
Мы эту проблему решили не много по другому.
Создали Бизнес процесс, который запускается автоматически по одному на каждый счет. (В wa_InvoiceAction добавили параметров, что бы потом клонировать был удобно.) В БП действия следущие: Создается счет, добавляются продукты, ставится задача ответственному отправить счет. После ее завершения через два дня ставится задача другому ответственному отследить приход денег. Если нет, то опять через 2 дня отследить приход.
Все вроде бы довольны :smile:
"Хомутов Кирилл" написал:Добрый день.
Мы эту проблему решили не много по другому.
Создали Бизнес процесс, который запускается автоматически по одному на каждый счет. (В wa_InvoiceAction добавили параметров, что бы потом клонировать был удобно.) В БП действия следущие: Создается счет, добавляются продукты, ставится задача ответственному отправить счет. После ее завершения через два дня ставится задача другому ответственному отследить приход денег. Если нет, то опять через 2 дня отследить приход.
Все вроде бы довольны
upd:(не ту ссылку вставил)
http://community.terrasoft.ua/ideas/4262
Я так и думал, что многие через БП будут реализовывать :)
Хотел поинтересоваться, используете ли Вы при этом планирование, и если да - то как ?
Создали окошко, которое при onPrepare запускает БП, а в onShow закрывает само себя.
На сервере шедулер, там запускается террасофт с параметрами для запуска окна.
Сейчас там таких БП стало много и мы стали объединять окна.
Т.е. одна задача в планировщике запускает окошко, которое стартует серию БП.
Понятно, но хотелось бы реализовать функцмонал без помощи БП, следовательно через действие. И тут сразу возникает несколько вопросов.
Начнем с малого, чисто теоретически. Какой вариант посоветуете выбирать:
1. Действие в разделе Договора->Создать свой счет(станд. карточка счета)->Добавить продукт к счету(карт. продукт в счете)->Автоматически повторить действие для всех договоров.
2. Действие в разделе Договора->Окно редактирования (своя карточка с полями, которые будут вноситься в поля счета и продукта к счету)-> Создание скриптом счета и продукта к нему.
В первом случае необходимо использование TemplateWindow? Если да, то получается много лишних полей, которые могут заполнятся автоматически.
А во втором, если создавать окно, то какой датасет привязать, и можно ли обойтись одним окном?
Как мне думается, оба варианта имеют право на жизнь, оба имеют как преимущества, так и недостатки. Лично я бы склонился скорее ко второму, думаю, первый реализовать будет сложнее. Прокомментирую каждый.
1) упрощает задачу тем, что при подготовке карточек редактирования у Вас уже заполнены поля по умолчанию. Также в scr_DB есть функции, позволяющие скопировать в новый датасет все поля датасета, кроме системных (ID, CreatedOn, CreatedByID и т.д., полный список - в начале этого же скрипта) и вычисляемых. Это функции CopyRowData и CopyFullData. Думаю, основной недостаток - медленная работа (функции каждый раз проходят по всем полям датасета). Нужно также не забывать о полях, которые заполняются автоматически, но разные для каждой записи (например, номер счёта). Впрочем, последнее касается обоих вариантов.
2) в этом случае можно создать окно, наследуя wnd_BaseEdit. Датасет привязывать не нужно. При обработке btnOKOnClick можно выполнять необходимое действие: считывать установленные в окне значения и подставлять их в запросы на вставку в БД. Датасет раздела Договора можно передать в это окно как атрибут, а дальше - как удобнее: создать два сервиса InsertQuery или же использовать Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters). Одного окна вполне достаточно, но в запросах необходимо не забывать и о тех значениях, которые в окне редактирования заполняются автоматически: здесь их нужно включать в параметры.
Понимаю, что данные описания очень поверхностны, но надеюсь, кое-что прояснилось.
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.
Спасибо за разъяснения ,теперь картина еще более прояснилась.
Думаю остановлюсь на втором варианте, но, закономерно возникает несколько вопросов:
1. В созданное окно добавил несколько DateTimeControl, NumericControl и LookupControl. Считывать последние, я так понимаю, нужно из LookupDataset, а вот DateTime и Numeric?
2. Можно ли в обработчике btnOKOnClick использовать function CreateInvoiceByContract() из wnd_ContractsWorkspaceScript? Если так, то вызов CreateNewWindowEdit(Self, 'wnd_InvoiceEdit', DefaultValues, Attributes) будет излишним и что вместо него прописать? И Attributes('IsCreatedByContractID') = ContractDataset.Values('ID') тоже ненужен, посколько там происходит вызов ProcessCopyOfferingDetail, а в данном случае продукт создается заведома известный и только некоторые поля берутся в зависимости от договора и созданной карточки. Но с другой стороны, Счет должен иметь привязку к Договору(или возможно лучше создавать связь самому в скрипте?).
По первому пункту: значение LookupControl'a Вы можете получить так: LookupControlName.LookupDatasetLink.Dataset.Values('ID').
Что касается остальных перечисленных контролов, их значения получить просто: ControlName.Value. У DateTimeControl'ов перед присвоением значения полю датасета полезно проверять свойство DateTimeControlName.IsNull.
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.
Тогда можно в обработке события OnNotify окна анализировать атрибуты объекта Sender:
var ControlText = Sender.Attributes('DisplayFieldValues').CommaText; var KeyValues = Sender.Attributes('KeyValues'); var ParamsArray = new Array(); for (var i = 0; i < KeyValues.Count; i++) { ParamsArray[i] = KeyValues.Items(i); }
Таким образом после выбора значения в окне справочника Вы получаете выбранные ID (KeyValues) и отображаемые значения. Можно записать их в глобальные переменные и использовать в обработке OKOnClick.
Если полей типа "Справочник" несколько, можно в обработке их событий OnPrepareSelectWindow присваивать окну атрибут с названием контрола, а потом в OnNotify его анализировать.
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.
По ходу выполнения возник еще один вопрос. На форуме ответ так и не нашел:
В разделе, например Счета добавил действие. В результате на основании счета создается документ в разделе Документы. Как реализовать автоматическое добавление созданного документа в Подчиненные к выбранному счету?
В Договорах, как я понял, для действия "Создать счет" реализовано передачей атрибута IsCreatedByContractID в CreateNewWindowEdit, или я ошибаюсь?
Если у Вас есть оба ID: счёта и документа, которые записаны в переменные InvoiceID и DocumentID, можно прямо в действии, после создания документа, выполнить следующее:
var Parameters = CreateSPParameters(); CreateSPParameter(Parameters, 'ID', pdtGUID, Connector.GenGUID()); CreateSPParameter(Parameters, 'InvoiceID', pdtGUID, InvoiceID); CreateSPParameter(Parameters, 'DocumentID', pdtGUID, DocumentID); var SQLText = 'insert into tbl_DocumentInDocument (ID, ParentInvoiceID, ChildDocumentID) values (:ID, :InvoiceID, :DocumentID'; Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.
"Лабьяк Олег Игоревич" написал:Если у Вас есть оба ID: счёта и документа, которые записаны в переменные InvoiceID и DocumentID
ID счета есть, а вот документ создается вызовом CreateNewWindowEdit, следовательно нужно как-то после его создания передавать ID, как проще всего реализовать?
Проще всего реализовать через механизм нотификации.
Например, при создании документа в качестве объекта NotifyObject указываете раздел "Договора" с помощью одноимённого атрибута. Дальше, в скрипте раздела договоров при обработке события wnd_ContractsWorkspaceOnNotify анализируете сообщение и объект, отправивший его. Если сообщение равно MSG_OK и название отправителя - wnd_DocumentEdit, выполняете запрос, приведённый выше.
Атрибут IsCreatedByContractID на самом деле используется для копирования продуктов из договора в счёт.
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.
В wnd_InvoicesWorkspaceOnNotify получаю ID счета и созданного документа, но при выполнении запроса появляется ошибка: "Ошибка выполнения метода 'wnd_InvoicesWorkspaceOnNotify'. Object expected «Call Stack»". Возможно нужно дополнительно подключить какой-то скрипт?
И ещё - в предпоследней строчке запроса не должно быть ":DocumentID)';" вместо ":DocumentID';"?;
Да, действительно, я пропустил закрывающуюся скобку...
Если ошибка возникает при выполнении CreateSPParameters или CreateSPParameter, значит, к Вашему скрипту не подключен скрипт scr_DB, либо же в этом скрипте отсутствуют данные функции. Привожу их текст:
function CreateSPParameters() { return System.CreateObject('TSObjectLibrary.Parameters'); } function CreateSPParameter(Parameters, Name, DataType, Value) { var Parameter = Parameters.CreateItem(); Parameter.Name = Name; Parameter.DataType = DataType; Parameter.Value = Value; Parameters.Add(Parameter); return Parameter; }
Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.