Russian Qt Forum
Апрель 27, 2024, 03:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Возможные варианты архитектуры для системы учета.  (Прочитано 2997 раз)
Alcereo
Гость
« : Май 09, 2016, 15:48 »

    Всем доброго времени суток. Наконец-то дошли руки до сообщества. Надеюсь спровоцировать интерес.)
    Если коротко - некоторое время назад начал писать архитектуру, подразумевающую каркас, который при необходимости расширяется и внедряется согласно бизнес-процессам заказчика. Главная задача - разворачивание системы за "полиномиальное" время, гибкость, бесплатные компоненты. Далее опишу все подробно по блокам: зачем, что и как. Можно знакомится в любом порядке. В конце вопросы, которые хотел бы задать.

     Зачем
Пришел к идее по целой совокупности причин, главные:
  • Обучение новым языкам и технологиям. Пока всерьез не думал о том что будет с коммерческой точки зрения.
  • Иметь в "обойме" решение, которое можно использовать в сфере автоматизации бизнеса. На сколько знаю, в России сейчас эту нишу практически во всем малом бизнесе занимает 1С, которое требует свои лицензии ИТС и прочее. Половина среднего в ситуации доработки своих решений под ту же 1С, небольшая часть под другие системы и малая часть разрабатывает свои вещи. Это все чисто по моим наблюдениям, могу ошибаться. Так вот идея не "написать свою 1С", а сделать то что можно собрать из бесплатных компонент, достаточно быстро, развернуть и расширять.

     Сам занимаюсь автоматизацией бизнеса, разработкой бизнес-процессов, аналитикой, сейчас чаще всего сталкиваться приходится с 1С. С Qt знаком пару лет, постоянно пишу - несколько месяцев. Раньше баловался с микроконтроллерами, потом увидел QML и понеслась)

     Что
    Имея опыт разработки процессов в компании обнаружил, что при желании, практически все процессы низкого уровня, особенно в торговле, рознице и учете решаются с помощью тройки - документ/регистр/справочник. Если бизнес процесс в некоторых случаях усложняется, то приходит в устойчивое состояние довольно быстро и остается неизменным практически до конца. При правильном планировании архитектуры, при описании процесса в виде диаграмм разных нотаций, согласовании, расширение функционала идет в одном направлении и, использование bpm систем в этих процессах не требуется.
    Это конечно не касается вещей более высокой абстракции в организации, где разные департаменты обмениваются документами и т.д. Тут процессы имеют свойство меняться и больше подходят все таки системы документооборота, но тут можно расширить состав объектов: Бизнес-процесс/задача/документ/справочник. На начальном этапе их должно хватить, а далее дело за расширением.
    Чтобы пойти далее взял для себя простую задачку: два документа - чек, инвойс. справочники - номенклатура, склад. регистр - остатков. т.е. Следующая схема:
  • Инвойс (Invoice) - содержит склад, табличная часть в виде: номенклатуры и количества. Делает движения в регистре остатка в плюс.
  • Чек (Receipt) - содержит склад, табличная часть в виде: номенклатуры и количества. Делает движение в регистре остатка в минус.
  • Номенклатура (Nomenclature) и склад (Stock) - простые справочники.
Цель: сделать чтобы можно было с нескольких компьютеров работать с базой, "нормальный" интерфейс, (еще раз) расширяемость, гибкость.

     Как
     И так для начала выбирал СУБД. Долго выбирать не пришлось, остановился на PostgreeSQL. Бесплатен, широкий функционал, комьюнити, кросс-платформенный, думаю в представлении не нуждается.
Первая задача - организация структуры БД. Если кому будет интересно скину диаграмму, сейчас скажу о ключевых моментах.
    Первичные ключи всех таблиц объектов - UUID. Причины в уникальности генерируемого кода, на этот счет в сети полно статей.
    Первая проблема - таблица остатков содержит поля: nomenclature_uid, stock_uid, quantity, date, registrator_uid. Первичный ключ - пара (nomenclature_uid, registrator_uid). Регистратором может быть как уид инвойса так и чека. Есть несколько способов решить неоднозначность, я воспользовался одной из главных "плюшек" РСУБД - наследование. Основная таблица - reg_stockbalance, у нее прописаны вторичные ключи таблиц stock и nomenclature, от нее наследуются две таблицы - reg_stockbalance_invoice, reg_stockbalance_receipt. Мои документы при проведении (posting) отображают свои данные каждый в своей таблице. В каждой из них у них прописаны вторичные ключи на  registrator_uid к своим таблицам документов. Основная таблица не содержит записей, но select * дает движения всех подчиненных таблиц, чтобы понять где чьи движения есть скрытое по умолчанию поле номера таблицы в postgree, его можно соединить с таблицей наименований таблиц.
    Еще одна неоднозначная вещь - табличные части документов. Я решил сделать такой набор: parent_uid, row_number, nomenclature_uid, quantity. Первичный ключ - тройка (parent_uid, row_number). Тут можно сделать по другому и ввести суррогатный ключ, чтобы при обмене данными с другими системами можно было "собрать камни", но пока решил не усложнять.

    Дальше пошли муки бэкенда. Тут сложнее, есть направления. То, что это будет QT сомнений у меня не было, но вопрос языка. Два главных пути - Python с PyQt и C++. Тут выбор такой:
  • Python - Динамическая, сильная, неявная типизация. Для меня - минус для разработки, легко накодить гавежку, которая будет ходить Смеющийся. Просто синтаксис - идеально для бизнес-логики. Интерпритатор - конечно кросс-платформенность без проблем, но производительность - в некоторых тестах до 100 раз медленнее C++, но с другой стороны железо сейчас на машинах делает это все меньше заметным. В итоге: огромный плюс синтаксиса. Два небольших минуса: производительность и типизация.
  • C++ - Статическая, слабая, явная типизация. Мне лично в плане разработки, больше нравится.) Тут, без паттернов не полезешь. Но времени уходит несравнимо больше. Конечно c++11 - auto, templates, и эти QVariant-ы хитрые статичность позволяют обходить, но все же это не считается). Итак писать структуру хорошо, но дойдя до бизнес логики можно простреливать себе колени почти в любой задаче. Плюс производительность, нативность.
   
    Тут вот главные муки выбора, но чтобы не мучиться решил сделать на обоих Смеющийся. Решил, что пока буду делать повылазят нюансы и решу на чем это будет. Забегая вперед, скажу, что на данном этапе я смотрю в сторону C++ и скриптов на QML возможно полностью с бизнес логикой.
  
    Теперь нюансы бэкенда. Сразу скажу, что ориентируюсь именно на архитектуру. На связность классов, на паттерны. Хочу сделать вещь, которую на досуге можно будет допиливать и это не будет терять универсальность. То, что я начал с двух документов и двух справочников это как раз подтверждает. Должно быть так, что если, нужны будут 15 документов, я смогу добавить их в программу за время пропорциональное количеству этих документов.
   Опишу коротко, если будет интерес у людей, опишу подробнее:
   Интерфейсный класс документа - Document - содержит функции сохранения, проведения с реализацией. Так же содержит абстрактные методы, которые переопределяются у потомков. Они возвращают данные которые помогают абстрактному классу документа записывать нужные поля в нужные таблицы СУБД. Т.е. у потомка документа нужно определить его название в СУБД поля (сслыки на другие классы) и показать в одной из функций как эти поля из запроса заполнить и куда сохранить.
   Далее, табличная часть и строка табличной части это два интерфейсных класса, они связаны с главным классом Document. У них так же часть реализации внутри и некоторые абстрактные функции, чтобы заполнили потомки, чтобы в реализации родительского класса все правильно сохранилось. Почему табличная часть в отдельном классе - это чтобы там хранить строки как угодно, но сам класс мог и итераторы и операторы и без наследования контейнеров естественно. Строка в отдельном классе определяет структуру строки и все тоже самое, ну тут вопросов думаю меньше.
   Получается паттерн "Абстрактная фабрика", где Document-DocumentTable-DocumentTableRow три абстрактных класса, которые являются каркасом для документов. Большая часть реализации у них.
   Со справочниками такая же история, разница лишь в том, что у них нет обработчика проведения.
  
    Для фронт энда выбрал паттерн MVP. Объект, документ или справочник имеет свой презентер, который координирует работу  с любым вьювером, нет завязки что это будет, хоть веб страница. Главное условие наследуйся от интерфейсного класса. Презентер не знает о конкретных вьюверах, только о интерфейсе.
    Сначала написал для QWidjets, но чисто для опыта, как и планировал все легко легло на QML, при чем так из питона, так и из C++.

   Сейчас остановился на том, чтобы понять как же все таки оперировать бизнес логикой. Думал над несколькими вариантами:
  • Писать все на питоне
  • Писать на C++, встраивать питон. Как скрипт.
  • Каркас на С++. Питон встраивает с++, а сам рулит процессом.
  • Все на С++. В нужных местах встраивать скрипты.

      Не знаю на сколько хороший вариант со скриптами, но меня покорила тема, что обновлять программу и делать изменения можно на лету, если сами скрипты завернуть в файлы отдельные. На сколько знаю скриптование на Qt делать советуют на QML, остальные вещи типа QT Script объявили устаревшими.

   Итог

    Хотел коротко все описать). В общем хотел услышать конструктивную критику, может вопросы.
    Главное что хотел спросить у знатоков это на сколько аукнется бизнес-логика на JavaScript и что с этим еще можно сделать. Ведь хотелось бы, что бы алгоритмы логики были легко переводимыми, гибкими и легко изменяемыми. Сильно сомневаюсь, что на С++ это делать хорошая идея, идеален для этого Python, но его не хочется встраивать. Может есть какие-то еще пути.
« Последнее редактирование: Май 09, 2016, 15:51 от Alcereo » Записан
PimenS
Крякер
****
Offline Offline

Сообщений: 371


Просмотр профиля
« Ответ #1 : Май 09, 2016, 17:07 »

У самого работает система торговли сети магазинов. Написал ее лет 5 назад, сейчас на очереди 2-я версия.

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

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

Если вы хотите создать что-то типа 1С, то смысла нет. Такие программы без поддержки никогда не дойдут до пользователя.
На голом энтузиазме, можно только повторить судьбу Ананаса.

По структуре.

Цитировать
Это конечно не касается вещей более высокой абстракции в организации, где разные департаменты обмениваются документами и т.д. Тут процессы имеют свойство меняться и больше подходят все таки системы документооборота, но тут можно расширить состав объектов: Бизнес-процесс/задача/документ/справочник. На начальном этапе их должно хватить, а далее дело за расширением.
    Чтобы пойти далее взял для себя простую задачку: два документа - чек, инвойс. справочники - номенклатура, склад. регистр - остатков. т.е. Следующая схема:
Инвойс (Invoice) - содержит склад, табличная часть в виде: номенклатуры и количества. Делает движения в регистре остатка в плюс.
Чек (Receipt) - содержит склад, табличная часть в виде: номенклатуры и количества. Делает движение в регистре остатка в минус.
Номенклатура (Nomenclature) и склад (Stock) - простые справочники.
Цель: сделать чтобы можно было с нескольких компьютеров работать с базой, "нормальный" интерфейс, (еще раз) расширяемость, гибкость.

Ну вряд ли все так просто:

Что вы называете Инвойс (Invoice), я не пойму. Я так понимаю это документ прихода. В него сразу добавляются:
1. Контрагент 2. Цена 3. Сумма 4. НДС/Без НДС 5. ГТД

И это еще не все.

Что такое Чек (Receipt), тоже не понимаю. Если это расходный документ, то какой? Розница? Опт?
Даже если розница, то по любому добавится контрагент и работа с ценами, скидками, долгами, формами оплаты.

Ну и если Склад не сильно сложный справочник, если делать локальную систему, то при работе с несколькими филиалами, сильно разрастается FOREIGN KEY.
Номенклатура так вообще самый сложный справочник. Даже если в него не включать работу с единицами измерений и ГТД и ценообразование вести отдельными регистрами.

Цитировать
Первая задача - организация структуры БД

То что Postgresql это конечно однозначно. И лучше сразу 9.5. Несколько плюшек для более простой работы добавит.
Но некоторые вещи мне непонятны:

Цитировать
Первичный ключ - пара (nomenclature_uid, registrator_uid)

А если у вас в документе больше 1-й строки одиниковой nomenclature_uid?
Ну и по структуре, скомкано пока у вас.

Цитировать
Два главных пути - Python с PyQt и C++. Тут выбор такой:

Мой совет. Выбирайте что-то одно. Проще будет.

Цитировать
Хочу сделать вещь, которую на досуге можно будет допиливать и это не будет терять универсальность. То, что я начал с двух документов и двух справочников это как раз подтверждает. Должно быть так, что если, нужны будут 15 документов, я смогу добавить их в программу за время пропорциональное количеству этих документов.

Скорее всего это путь в никуда. Ничего универсального не получится.

Извиняюсь за сумбур. Я тоже начинал с такими же идеями. Как оказалось, все не так.
Записан
Alcereo
Гость
« Ответ #2 : Май 10, 2016, 04:35 »

Благодарю за отклик.)

По порядку
Цитировать
Ну вряд ли все так просто:

Что вы называете Инвойс (Invoice), я не пойму. Я так понимаю это документ прихода. В него сразу добавляются:
1. Контрагент 2. Цена 3. Сумма 4. НДС/Без НДС 5. ГТД

И это еще не все.

Что такое Чек (Receipt), тоже не понимаю. Если это расходный документ, то какой? Розница? Опт?
Даже если розница, то по любому добавится контрагент и работа с ценами, скидками, долгами, формами оплаты.

Ну и если Склад не сильно сложный справочник, если делать локальную систему, то при работе с несколькими филиалами, сильно разрастается FOREIGN KEY.
Номенклатура так вообще самый сложный справочник. Даже если в него не включать работу с единицами измерений и ГТД и ценообразование вести отдельными регистрами.

     С вами абсолютно согласен в том, что структура в конкретной реализации будет не такой простой как я взял для примера. Но факт в том, что, опять же, для каждой конкретной реализации это будут свои справочники и поля в документах. Могут добавиться и серии и ордера для расширенного ведения складского учета и много чего. Все это зависит от учета заказчика и определяется это на этапе анализа бизнес процессов. Поэтому я не рассчитывал сделать готовую приминимую структуру БД. Главное, что даже очень сложный справочник номенклатуры, это просто справочник содержащий в виде реквизитов, или табличных частей другие справочники или может записи в регистрах. Да, структура будет сложной в любом случае, но если у меня есть шаблон - абстрактный класс для создания справочников, есть описание того, что требуется в виде диаграммы классов, то создание этой структуры не должно занять долго времени. В отличии от внешнего вида, где надо будет заморочиться как это все отобразить на форме. Поэтому, вы правы в том, что та простая схема что я взял с двумя документами и двумя справочниками - не применима, её взял чтобы при реализации, при наследовании от абстрактного класса увидеть нюансы той самой реализации и в полевых условиях не тратить на это время.
    Чтобы лучше понять мою мысль можно представить следующее: вы знаете, что у вас появится несколько задач по разработке и внедрению учетной системы. Как будет выглядеть структура в каждом конкретном случае вы не знаете и она может быть разнообразной. У вас есть время подготовиться, и может реализовать какой-то шаблон/каркас. Вот этот каркас и хочу иметь на вооружении.) Поэтому цель: абстрактные классы объектов, паттерны для выхода к фронтенду. От общего к частному, чтобы в уже при конркетной реализации больше времени тратить на структуру справочников и документов, а в эту работу по разработке архитектуры инвестировать время сейчас.) Возможно по вашему это потеря времени, очень интересно узнать на это вашу точку зрения.

Цитировать
Первичный ключ - пара (nomenclature_uid, registrator_uid)

А если у вас в документе больше 1-й строки одиниковой nomenclature_uid?

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

Цитировать
Цитировать
Ну и по структуре, скомкано пока у вас.

    Извиняюсь за изложение, там наверное везде скомкано, просто не хотел поэму разворачивать на несколько листов. Вопросов у меня по структуре СУБД не возникало, но могу выложить для обсуждения.

Цитировать
Мой совет. Выбирайте что-то одно. Проще будет.

    Чем дальше, тем больше начинаю убеждаться, что вы правы.) Но, просто хотел познакомиться с возможностями питона.)

Цитировать
Скорее всего это путь в никуда. Ничего универсального не получится.

    Тут возможно вы не так поняли о какой универсальности идет речь. Я имел в виду не итоговую реализацию, которая подойдет всем, это невозможно. Я имел в виду именно каркас/шаблон который позволит быстрее сделать конкретную реализацию. Наверное даже встает вопрос в том, что должно быть в таком каркасе, чтобы это было так.


    Если позволите, вопрос к вам)
Цитировать
У самого работает система торговли сети магазинов. Написал ее лет 5 назад, сейчас на очереди 2-я версия.
    На каком языке написано? И больше всего интересно на чем писали бизнес логику. Т.е. например когда необходимо документ сохранить и отобразить в базе, все проверки условий. Когда нужно написать АРМ, который собирает данные и может запустить групповое изменение документов. На чем вы это пишете, может есть советы какие-то?
   
Записан
PimenS
Крякер
****
Offline Offline

Сообщений: 371


Просмотр профиля
« Ответ #3 : Май 10, 2016, 08:41 »

Цитировать
На каком языке написано?

Клиентская часть на с++ с Qt. Серверная на SQL, PL/pgSQL.

Цитировать
Т.е. например когда необходимо документ сохранить и отобразить в базе, все проверки условий

Изначально, я старался больше этих функций отдать серверу. Но постепенно пришел к тому, что это сложнее, чем на клиенте. Поэтому ко 2-й версии многое пересмотрел
и сейчас все проверки делает клиент.

Цитировать
который собирает данные и может запустить групповое изменение документов

Т.к. программа у меня узко специализированная ("торговля запасными частями"), то сбор данных не универсальный. Каждый отчет выполняет свои функции.
Групповое изменение считаю не правильным подходом. Поэтому даже не рассматривал такую возможность.
В 1-й версии вообще не делал возможности исправить проведенный документ, и все операции исправлений сделал через сторно.
Но пришел в выводу, что это сложный путь. Во 2-й версии ввел отмену проведения.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.084 секунд. Запросов: 22.