Răsfoiți Sursa

Merge branch 'new_version_open' of blezz-tech/sharix-open-webservice-running into unstable

Editing merge from assist
david berlinskiy 1 lună în urmă
părinte
comite
2af6b549c7
54 a modificat fișierele cu 5446 adăugiri și 599 ștergeri
  1. 1 1
      apiviews/__init__.py
  2. 10 0
      config.py
  3. 1 1
      forms.py
  4. 6 0
      handlers/.gitignore
  5. 72 0
      handlers/BotClass.py
  6. 63 0
      handlers/README.md
  7. 16 0
      handlers/applications.json
  8. 5 0
      handlers/classes/Answer.py
  9. 161 0
      handlers/classes/Order.py
  10. 85 0
      handlers/classes/OrderTicket.py
  11. 8 0
      handlers/classes/Ticket.py
  12. 20 0
      handlers/classes/Ticket_user.py
  13. 8 0
      handlers/config.py
  14. 8 0
      handlers/gen-passwords.py
  15. 15 0
      handlers/gen_users
  16. 9 0
      handlers/gen_web_users.py
  17. 189 0
      handlers/jsonAndRequest.py
  18. 121 0
      handlers/open_accessrequest_accepted.py
  19. 123 0
      handlers/open_accessrequest_pending.py
  20. 50 0
      handlers/open_basic_bot.py
  21. 121 0
      handlers/open_negrequest_accepted.py
  22. 111 0
      handlers/open_negrequest_pending.py
  23. 179 0
      handlers/open_servicerequest_accepted.py
  24. 181 0
      handlers/open_servicerequest_assigned.py
  25. 215 0
      handlers/open_servicerequest_booked.py
  26. 172 0
      handlers/open_servicerequest_booked_v2.py
  27. 136 0
      handlers/open_servicerequest_closed.py
  28. 138 0
      handlers/open_servicerequest_declined.py
  29. 153 0
      handlers/open_servicerequest_done.py
  30. 133 0
      handlers/open_servicerequest_forcemajeure.py
  31. 140 0
      handlers/open_servicerequest_pending.py
  32. 135 0
      handlers/open_servicerequest_preforcemajeure.py
  33. 120 0
      handlers/open_servicerequest_prestart.py
  34. 178 0
      handlers/open_servicerequest_process.py
  35. 130 0
      handlers/open_strequest_assigned.py
  36. 132 0
      handlers/open_strequest_done.py
  37. 131 0
      handlers/open_strequest_dublicate.py
  38. 130 0
      handlers/open_strequest_inprocess.py
  39. 147 0
      handlers/open_strequest_new.py
  40. 147 0
      handlers/open_strequest_reopened.py
  41. 135 0
      handlers/open_strequest_wontfix.py
  42. 125 0
      handlers/open_template_bot.py
  43. 33 0
      handlers/order_functions.py
  44. 7 0
      handlers/requirements.txt
  45. 128 0
      handlers/st_request_assigned.py
  46. 128 0
      handlers/st_request_done.py
  47. 98 0
      handlers/st_request_new.py
  48. 128 0
      handlers/st_request_wontfix.py
  49. 10 0
      handlers/starter.sh
  50. 103 0
      handlers/status_changer.py
  51. 55 0
      handlers/status_handlers.py
  52. 593 593
      license ru.md
  53. 1 1
      models/__init__.py
  54. 2 3
      views.py

+ 1 - 1
apiviews/__init__.py

@@ -1 +1 @@
-from .orders_local import OrdersLocalMVS
+from .orders_local import OrdersLocalMVS

+ 10 - 0
config.py

@@ -0,0 +1,10 @@
+#Подключение к базе данных
+host = "host"
+SSH_H = "46.138.247.90"
+user = "user"
+password = "password"
+port = 334
+db_name = "db_name"
+#Подключение к боту
+jid = "test@msg.sharix-app.org"
+jidpassword = "test1234@"

+ 1 - 1
forms.py

@@ -11,4 +11,4 @@ class OrderRegForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
       super().__init__(*args, **kwargs)
       for field in self.fields.values():
-          field.widget.attrs['class'] = 'form-control'
+          field.widget.attrs['class'] = 'form-control'

+ 6 - 0
handlers/.gitignore

@@ -0,0 +1,6 @@
+__pycache__/
+env/
+config.py
+*bottickets.log
+*.log
+*~

+ 72 - 0
handlers/BotClass.py

@@ -0,0 +1,72 @@
+import sys, xmpp
+from xmpp import cli
+from datetime import datetime
+import json
+
+import jsonAndRequest as jsreq
+
+#Основной класс бота
+class JabberBot: 
+    def __init__(self, jid, password, port):
+        self.jidd = jid
+        jid = xmpp.JID(jid)
+        self.user, self.server, self.password, self.port = jid.getNode(), jid.getDomain(), password, port
+        self.connect()
+        self.auth()
+
+    #Метод проверки подключения к серверу xmpp
+    def connect(self): 
+        self.conn = xmpp.Client(self.server, self.port,debug = [])
+        conn_result = self.conn.connect()
+        if not conn_result:
+            print("Can't connect to server!\n")
+            sys.exit(1)
+    #Метод аутентификации
+    def auth(self): 
+        #по идее, тут может быть актуально также передать информацию относительно порта, например
+        auth_result = self.conn.auth(self.user, self.password)
+        if not auth_result:
+            print (self.user, self.password)
+            print("Can't to authorize!\n")
+            sys.exit(1)
+    #Метод для привязки функций к событиям
+    def register_handler(self, name, handler):
+        self.conn.RegisterHandler(name, handler)
+
+    def step_on(self):
+        try:
+            self.conn.Process(1)    #с какой частотой происходит подключение к серверу, в данном случае каждую секунду
+        except KeyboardInterrupt: return 0
+        return 1
+
+    def bot_log(self, message):
+        #надо строчку лога сделать более информативной
+        logfile = open(datetime.now().strftime('%Y-%m-%d') + "-" + self.user + ".log", "a")
+        logfile.write(message)
+        logfile.close()
+        print (message)
+
+    def send_notification(self, recipient, message):
+        self.conn.send(xmpp.Message(recipient, message))
+        self.bot_log("Message sent successfully"+" "+recipient+" "+message)
+
+    # recipient - это конкретный jid следующего обработчика заявки, ticket - json с заявкой.
+    def proceed_status(self, recipient, ticket):
+        #тут могут быть различные проверки дополнительные, а так вообще эта функция нужна для передачи заявки на обработку следующему
+        jsonTicket = json.dumps(ticket.__dict__)
+        self.conn.send(xmpp.Message(recipient, jsonTicket))
+        self.bot_log("Message sent successfully"+" "+recipient+" "+jsonTicket)
+
+    #сюда можно как параметры передавать переменную для значения Process в вызываемой функции, а также передавать информацию о том, какой из обработчиков ввызывать в бесконечном цикле
+    def start(self, handler, *args):
+        self.conn.sendInitPresence()#статус аккаунта бота (активен или нет)
+        print("Bot started!")
+        while self.step_on():
+            #это вызов конкретной функции для обработки статуса конкретным ботом
+            #handler(args)
+            handler()
+            pass
+    
+    def stop(self):
+        # Disconnect from the Jabber server
+        self.client.disconnect()

+ 63 - 0
handlers/README.md

@@ -0,0 +1,63 @@
+# Open Template Bot
+#### Simple example for processing orders
+
+## Install and run
+
+1. Rename **config_template.py** to **config.py** 
+2. Create env
+```
+python -m venv env #for Windows
+python3 -m venv env #for Linux
+```
+3. Activate env
+```
+.\env\Scripts\activate #Windows
+source env/bin/activate #Linux
+```
+4. Instatt requirements 
+```
+pip3 install -r requirements.txt
+```
+5. Run Bot
+```
+python3 open_template_bot.py
+```
+
+
+## Testing
+https://democonv.sharix-app.org/ - testing client
+
+## Users recommended for testing
+user: test@ej.sharix-app.org
+user: test1@ej.sharix-app.org
+
+## Useful commands for Ejabberctl while testing Bot
+
+```
+ejabberdctl register $username ej $password
+
+ejabberdctl change-password User Host newPassword
+
+ejabberdctl check_account user1 localhost
+
+ejabberdctl unregister badlop3 localhost
+ejabberdctl registered_users localhost
+ejabberdctl help registered_users
+```
+
+# Create MUC room
+```
+ejabberdctl create_room room_name muc_service xmpp_domain
+```
+
+# Destroy MUC room
+```
+#ejabberdctl destroy_room room_name muc_service
+```
+
+# List unused MUC rooms
+```
+ejabberdctl rooms_unused_list xmpp_domain number_of_days
+```
+
+https://docs.ejabberd.im/admin/ejabberdctl/muc-admin/

+ 16 - 0
handlers/applications.json

@@ -0,0 +1,16 @@
+{
+    "applications": [
+        {
+            "id": "1",
+            "desc": "описание 1" 
+        },
+        {
+            "id": "2",
+            "desc": "описание 2" 
+        },
+        {
+            "id": "3",
+            "desc": "описание 3" 
+        }
+    ]
+}

+ 5 - 0
handlers/classes/Answer.py

@@ -0,0 +1,5 @@
+class Answer(object):
+    def __init__(self,order_id,provider,answer):
+        self.order_id = order_id
+        self.provider = provider
+        self.answer = answer

+ 161 - 0
handlers/classes/Order.py

@@ -0,0 +1,161 @@
+class Order(object):
+    def __init__(self, id, ticket, status, title, note, id_metaservice, is_global, is_visible, service, service_type, time_created, time_placed, time_start=None, time_start_predicted=None, time_finish_predicted=None, time_start_real=None, time_finish_real=None, order_place_type=None, order_place_start=None, order_place_start_gps=None, order_place_start_real=None, order_place_start_real_gps=None, order_place_finish_predicted=None, order_place_finish_predicted_gps=None, order_place_finish_real=None, order_place_finish_real_gps=None, predicted_price=None, real_price=None, payment_transaction_id=None, rating_id=None, provider=None, provider_screen_name=None, receiver=None, receiver_screen_name=None, client_id=None, resource_id=None, attempts=None, asap=None, money_limit=None, tasks=None, proceed_before_arrival=False, confirmation=False):
+        self.id = id
+        self.ticket = ticket
+        self.status = status
+        self.title = title
+        self.note = note
+        self.id_metaservice = id_metaservice
+        self.is_global = is_global
+        self.is_visible = is_visible
+        self.service = service
+        self.service_type = service_type
+        self.time_created = time_created
+        self.time_placed = time_placed
+        self.time_start = time_start
+        self.time_start_predicted = time_start_predicted
+        self.time_finish_predicted = time_finish_predicted
+        self.time_start_real = time_start_real
+        self.time_finish_real = time_finish_real
+        self.order_place_type = order_place_type
+        self.order_place_start = order_place_start
+        self.order_place_start_gps = order_place_start_gps
+        self.order_place_start_real = order_place_start_real
+        self.order_place_start_real_gps = order_place_start_real_gps
+        self.order_place_finish_predicted = order_place_finish_predicted
+        self.order_place_finish_predicted_gps = order_place_finish_predicted_gps
+        self.order_place_finish_real = order_place_finish_real
+        self.order_place_finish_real_gps = order_place_finish_real_gps
+        self.predicted_price = predicted_price
+        self.real_price = real_price
+        self.payment_transaction_id = payment_transaction_id
+        self.rating_id = rating_id
+        self.provider = provider
+        self.provider_screen_name = provider_screen_name
+        self.receiver = receiver
+        self.receiver_screen_name = receiver_screen_name
+        self.client_id = client_id
+        self.resource_id = resource_id
+        self.attempts = attempts
+        self.asap = asap
+        self.money_limit = money_limit
+        self.tasks = tasks
+        self.proceed_before_arrival = proceed_before_arrival
+        self.confirmation = confirmation
+
+    def __str__(self):
+        return "{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34}, {35}, {36}, {37}, {38}".format(self.id, self.ticket, self.status, self.title, self.note, self.id_metaservice, self.is_global, self.is_visible, self.service, self.service_type, self.time_created, self.time_placed, self.time_start, self.time_start_predicted, self.time_finish_predicted, self.time_start_real, self.time_finish_real, self.order_place_type, self.order_place_start, self.order_place_start_gps, self.order_place_start_real, self.order_place_start_real_gps, self.order_place_finish_predicted, self.order_place_finish_predicted_gps, self.order_place_finish_real, self.order_place_finish_real_gps, self.predicted_price, self.real_price, self.payment_transaction_id, self.rating_id, self.provider, self.provider_screen_name, self.receiver, self.receiver_screen_name, self.client_id, self.resource_id, self.attempts, self.asap, self.money_limit, self.tasks, self.proceed_before_arrival, self.confirmation)
+
+
+#Тестовый класс User и Address (ВАЖНО!!!) поля классов должны называться также как и поля json объекта
+'''
+#Full json order example
+https://wiki.sharix-app.org/doku.php/open/tech/dev/sharix_open_-_primery_json
+
+{
+
+"ticket": 123,
+"status": 111,
+
+"priority": 1, 
+"title": "123",
+"note": "123",
+"due_date": 2023-05-15T17:16:22.955601Z,
+
+"id_metaservice": 1,
+"is_global": false,
+"is_visible": false,
+"service": 1,
+"service_type": 1,
+
+"status_changed_date": "2023-05-15T17:16:22.955601Z",
+"time_placed": "2023-05-15T16:40:32.179777Z",
+"time_start": "2023-05-15T16:40:32.179777Z",
+"time_start_predicted": "2023-05-15T16:40:32.179777Z",
+"time_finish_predicted": "2023-05-15T16:40:32.179777Z",
+"time_start_real": "2023-05-15T16:40:32.179777Z",
+"time_finish_real": "2023-05-15T16:40:32.179777Z",
+
+"order_place_type": "address",
+"order_place_start": "р-н Беговой",
+"order_place_start_gps": "55.751941, 37.607513",
+"order_place_start_sector": 4,
+"order_place_start_real": "р-н Беговой",
+"order_place_start_real_gps": "55.751941, 37.607513",
+"order_place_finish_predicted": "р-н Мещанский",
+"order_place_finish_predicted_gps": "55.751941, 37.607513",
+"order_place_finish_sector": 4,
+"order_place_finish_real": "р-н Мещанский",
+"order_place_finish_real_gps": "55.751941, 37.607513",
+
+"predicted_price": 1000,
+"real_price": 1001,
+"payment_transaction_id": 1,
+"rating_id": 1,
+
+"provider": 1,
+"provider_screen_name": "Vasya Ispolnitelev",
+"receiver": 1,
+"receiver_screen_name": "Marfa Clientovna",
+"client_id": 1,
+"client_screen_name": "Fedor Client",
+"resource_id": 1,
+"attempts": null
+}
+'''
+#надо адаптировать класс к новому формату JSON
+# class Order(object):
+#     def __init__(self, id,order_synced, ticket, status, title, note, due_date, id_metaservice, is_global, is_visible, service, service_type, status_changed_date,time_created, time_placed, time_start=None, time_start_predicted=None, time_finish_predicted=None, time_start_real=None, time_finish_real=None, order_place_type=None, order_place_start=None, order_place_start_gps=None, order_place_start_real=None, order_place_start_real_gps=None, order_place_finish_predicted=None, order_place_finish_predicted_gps=None, order_place_finish_real=None, order_place_finish_real_gps=None, predicted_price=None, real_price=None, payment_transaction_id=None, rating_id=None, provider=None, provider_screen_name=None, receiver=None, receiver_screen_name=None, client_id=None, resource_id=None, attempts=None, asap=None):
+#         self.order_synced = order_synced
+#         self.id = id
+#         self.ticket = ticket
+#         self.status = status
+
+#         self.title = title
+#         self.note = note
+#         self.due_date = due_date
+
+#         self.id_metaservice = id_metaservice
+#         self.is_global = is_global
+#         self.is_visible = is_visible
+#         self.service = service
+#         self.service_type = service_type
+
+#         self.status_changed_date = status_changed_date
+#         self.time_created = time_created
+#         self.time_placed = time_placed
+#         self.time_start = time_start
+#         self.time_start_predicted = time_start_predicted
+#         self.time_finish_predicted = time_finish_predicted
+#         self.time_start_real = time_start_real
+#         self.time_finish_real = time_finish_real
+
+#         self.order_place_type =order_place_type
+#         self.order_place_start = order_place_start
+#         self.order_place_start_gps = order_place_start_gps
+#         self.order_place_start_real = order_place_start_real
+#         self.order_place_start_real_gps = order_place_start_real_gps
+#         self.order_place_finish_predicted = order_place_finish_predicted
+#         self.order_place_finish_predicted_gps = order_place_finish_predicted_gps
+#         self.order_place_finish_real = order_place_finish_real
+#         self.order_place_finish_real_gps = order_place_finish_real_gps
+
+#         self.predicted_price = predicted_price
+#         self.real_price = real_price
+
+#         self.payment_transaction_id = payment_transaction_id
+#         self.rating_id = rating_id
+
+#         self.provider = provider
+#         self.provider_screen_name = provider_screen_name
+#         self.receiver = receiver
+#         self.receiver_screen_name = receiver_screen_name
+#         self.client_id = client_id
+#         self.resource_id = resource_id
+#         self.attempts = attempts
+#         self.asap = asap
+#         #доделать до конца по аналогии с закоммиченным json
+#     def __str__(self):
+#         return "{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32} , {33} ,{34}".format(self.order_synced, self.id, self.ticket, self.status, self.title, self.note, self.due_date, self.id_metaservice, self.is_global, self.is_visible, self.service, self.service_type, self.status_changed_date, self.time_created,self.time_placed, self.time_start, self.time_start_predicted, self.time_finish_predicted, self.time_start_real, self.time_finish_real, self.order_place_type, self.order_place_start, self.order_place_start_gps, self.order_place_start_real, self.order_place_start_real_gps, self.order_place_finish_predicted, self.order_place_finish_predicted_gps, self.order_place_finish_real, self.order_place_finish_real_gps, self.predicted_price, self.real_price, self.payment_transaction_id, self.rating_id, self.provider, self.provider_screen_name, self.receiver, self.receiver_screen_name, self.client_id, self.resource_id, self.attempts, self.asap)
+
+        #\n добавляете в местах с пустой строкой в шаблоне

+ 85 - 0
handlers/classes/OrderTicket.py

@@ -0,0 +1,85 @@
+class OrderTicket(object):
+  def __init__(self, serviceType, driverSearchEngine, comment, arrivalTime, additionalServices, tasks, spendingLimit, isWithPaymentDocument, id, isProceedBeforeArrival):
+    self.serviceType = serviceType
+    self.driverSearchEngine = driverSearchEngine
+    self.comment = comment
+    self.arrivalTime = arrivalTime
+    self.additionalServices = additionalServices
+    self.tasks = tasks
+    self.spendingLimit = spendingLimit
+    self.isWithPaymentDocument = isWithPaymentDocument
+    self.id = id
+    self.isProceedBeforeArrival = isProceedBeforeArrival
+
+#ticket json example
+'''
+{
+        "id": 2,
+        "status": 111,
+        "created_date": "2023-05-15",
+        "status_changed_date": "2023-05-15T17:16:22.955601Z",
+        "priority": 0,
+        "title": "Test",
+        "note": "{\n    \n    \"ticket\": 1,\n    \"state\": 1,\n    \"id_metaservice\": 1,\n    \"is_global\": false,\n    \"is_visible\": false,\n    \"service\": 1,\n    \"service_type\": 1,\n\n    \"time_placed\": 1}"
+        "due_date": "2023-05-15",
+        "task_list": 10,
+        "created_by": 1,
+        "type": 1,
+        "assigned_to": 1
+}
+'''
+
+
+#ticket minimal example
+'''
+{
+        "id": 2,
+        "status": 111,
+        "created_date": "2023-05-15",
+        "status_changed_date": "2023-05-15T17:16:22.955601Z",
+        "priority": 0,
+        "title": null,
+        "note": null,
+        "due_date": null,
+        "task_list": 10,
+        "created_by": 1,
+        "type": 1,
+        "assigned_to": null
+}
+{
+  "serviceType": 2,
+  "driverSearchEngine": 0,
+  "comment": "Yyyy",
+  "arrivalTime": "2023-12-07T14:39:54Z",
+  "additionalServices": [],
+  "tasks": [
+    {
+      "text": "Eeee",
+      "address": "Jjjj"
+    }
+  ],
+  "spendingLimit": 6668,
+  "isWithPaymentDocument": true,
+  "id": 294830,
+  "isProceedBeforeArrival": true
+}
+
+'''
+
+# class OrderTicketOLD(object):
+#     def __init__(self, id, status, created_date, status_changed_date, priority, title=None, note=None, due_date=None, task_list=None, created_by=None, type=None, assigned_to=None):
+#         self.id = id
+#         self.status = status
+#         self.created_date = created_date
+#         self.status_changed_date = status_changed_date
+#         self.priority = priority
+#         self.title = title
+#         self.note = note
+#         self.due_date = due_date
+#         self.task_list = task_list
+#         self.created_by = created_by
+#         self.type = type
+#         self.assigned_to = assigned_to
+
+#     def  __str__(self):
+#         return "{0}, {1}, {2}, {3}, {4}, {5}, {6},\n{7}, {8}, {9}, {10}, {11}\n".format(self.id, self.status, self.created_date, self.status_changed_date, self.priority, self.title, self.note, self.due_date, self.task_list, self.created_by, self.type, self.assigned_to) 

+ 8 - 0
handlers/classes/Ticket.py

@@ -0,0 +1,8 @@
+class Ticket(object):
+    def __init__(self, id,  name, group):
+        self.id = id
+        self.name = name
+        self.group = group
+
+    def  __str__(self):
+        return "{0}, {1}, {2},\n".format(self.id, self.name, self.group)

+ 20 - 0
handlers/classes/Ticket_user.py

@@ -0,0 +1,20 @@
+class Ticket_user(object):
+    def __init__(self, id, status, title, ticket_type, created_at, updated_at, due_date, priority, created_by, assigned_to):
+        self.id = id
+        self.status = status
+        self.title = title
+        self.ticket_type = ticket_type
+        self.created_at = created_at
+        self.updated_at = updated_at
+        self.due_date = due_date
+        self.priority = priority
+        self.created_by = created_by
+        self.assigned_to = assigned_to
+        
+
+    def  __str__(self):
+        return "{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}\n".format(
+        self.id, self.status, self.title, self.ticket_type, self.created_at,
+        self.updated_at, self.due_date, self.priority,
+        self.created_by, self.assigned_to
+    )

+ 8 - 0
handlers/config.py

@@ -0,0 +1,8 @@
+#rename this file to config.py
+BOTLIST=["open_basic_bot",'status_changer','st_request_done','st_request_wontfix','st_request_assigned','st_request_new']
+JSERVER="ej.sharix-app.org"
+PASSWORD="12345"
+PORT=5222
+API_URL = "https://testopen.sharix-app.org/"
+
+

+ 8 - 0
handlers/gen-passwords.py

@@ -0,0 +1,8 @@
+import config
+import hashlib
+
+botlist=config.BOTLIST
+
+for i in range (len(botlist)):
+    print(botlist[i], hashlib.md5((botlist[i]+config.PASSWORD).encode('utf-8')).hexdigest())
+

+ 15 - 0
handlers/gen_users

@@ -0,0 +1,15 @@
+#!/bin/bash
+
+#берем список ботов и паролей к ним и создаем или апдейтим пользователей (если уже созданы) на сервере
+python3 gen-passwords.py | while IFS=' ' read -ra line; do ejabberdctl register ${line[0]} ej.sharix-app.org ${line[1]}; done;
+python3 gen-passwords.py | while IFS=' ' read -ra line; do ejabberdctl change-password ${line[0]} ej.sharix-app.org ${line[1]}; done;
+#ejabberdctl register $username ej $password
+
+#ejabberdctl change-password User Host newPassword
+
+#ejabberdctl check_account user1 localhos
+#
+#ejabberdctl unregister badlop3 localhost
+#ejabberdctl registered_users localhost
+#ejabberdctl help registered_userst
+

+ 9 - 0
handlers/gen_web_users.py

@@ -0,0 +1,9 @@
+import jsonAndRequest as jsreq
+import config
+import hashlib
+
+botlist=config.BOTLIST
+
+for i in range (len(botlist)):
+    print(botlist[i], hashlib.md5((botlist[i]+config.PASSWORD).encode('utf-8')).hexdigest())
+    print (jsreq.createUser(botlist[i],botlist[i],hashlib.md5((botlist[i]+config.PASSWORD).encode('utf-8')).hexdigest(),config.API_URL+"/v1/auth/users/"))

+ 189 - 0
handlers/jsonAndRequest.py

@@ -0,0 +1,189 @@
+import json
+import requests
+import config
+import ast
+
+from classes.Answer import Answer
+from classes.Order import Order
+from classes.OrderTicket import OrderTicket
+from classes.Ticket_user import Ticket_user
+from classes.Ticket import Ticket
+
+
+#Функция преобразования json в объект класса Order
+def jsonToOrder(jsonstring) -> Order:
+    jsonObj = json.loads(jsonstring)
+    print(jsonObj)
+    u = Order(**jsonObj)
+    return u
+
+
+#Функция преобразования json в объект класса OrderTicket
+def jsonToOrderTicket(jsonstring) -> OrderTicket:
+    print (jsonstring)
+    jsonObj = json.loads(jsonstring)
+    print(jsonObj)
+    u = OrderTicket(**jsonObj)
+    return u
+
+
+#Функция обращения к апи и получение токена
+def requestGetToken(login, password, url) -> str:
+    login = "79999999999"
+    password = "12345"
+    # login = "11111111111"
+    # password = "Sharix!"
+    #url = "https://user.sharix-app.org/auth/token/login/"
+    data = {
+        "password":password,
+        "phone_number":login
+    }
+    response = requests.post(url,json=data)
+    result = response.json()
+    return result['auth_token']
+#Функция обращения к апи и получение токена
+
+
+def msg_to_text(jsonstring):
+    jsonObj = json.loads(jsonstring)
+    u = jsonObj 
+    return u
+
+
+def createUser(username, phone, password, url) -> str:
+    data = {
+        "username": username,
+        "phone_number": phone,
+        "password": password
+    } 
+    response = requests.post(url, json=data)
+    result = response.json()
+    return result
+#Функция обращения к апи и получение списка пользователей
+
+
+def requestGetListUser():
+    auth_token=requestGetToken()
+    print(auth_token)
+    headers = {'Authorization': f'Token {auth_token}'}
+    url = 'https://user.sharix-app.org/platform/api/sharix-users/'
+    response = requests.get(url, headers=headers)
+    print(response)
+    print(response.json())
+
+
+# def requestGetList(auth_token, url):
+#     headers = {'Authorization': f'Token {auth_token}'}
+#     response = requests.get(url, headers=headers)
+#     #response = requests.get(config.API_URL+"/dbsynce/api/orders/", headers=headers)
+#     ordertext=response.json()
+#     startlist = []
+    
+#     if not ordertext:
+#         print("Empty array")
+#     else:
+#         for i in ordertext:
+#             print (i, "PROCESSING")
+#             try:
+#                 orderticket = OrderTicket(**i)
+#                 print(i, "ORDER ", orderticket)
+#                 startlist.append(orderticket)
+#             except Exception as ex:
+#                 print(ex)
+#     print (startlist)
+#     return startlist
+
+
+def requestGetList(auth_token, url):
+    headers = {'Authorization': f'Token {auth_token}'}
+    response = requests.get(url, headers=headers)
+    #response = requests.get(config.API_URL+"/dbsynce/api/orders/", headers=headers)
+    ordertext=response.json()
+    startlist = []
+    
+    if not ordertext:
+        print("Empty array")
+    else:
+        for i in ordertext:
+            print (i, "PROCESSING")
+            try:
+                order = Order(**i)
+                print(i, "ORDER ", order)
+                startlist.append(order)
+            except Exception as ex:
+                print(ex)
+    print (startlist)
+    return startlist
+
+
+def requestGetTicket_user(auth_token, url):
+    headers = {'Authorization': f'Token {auth_token}'}
+    response = requests.get(url, headers=headers)
+    
+    #response = requests.get(config.API_URL+"/dbsynce/api/orders/", headers=headers)
+    tickettext=response.json()
+    startlist = []
+    if not tickettext:
+        print("Empty array")
+    else:
+        for i in tickettext:
+            try:
+                ticket = Ticket_user(**i)
+                startlist.append(ticket)
+            except Exception as ex:
+                print(ex)
+    print (startlist)
+    return startlist
+
+
+def requestPatchTicketUser(token,url, data):
+    headers = {'Authorization': f'Token {token}'}
+    response = requests.patch(url, json=data, headers=headers)
+    return response
+
+
+def change_groups(auth_token, url,group):
+    headers = {
+    'Content-Type': 'application/json',
+    'Authorization': f'Token {auth_token}'
+    }
+    response = requests.get(url, headers=headers)
+    user_data = response.json()
+    current_groups = user_data.get('groups', [])
+    updated_groups = list(set([group]+current_groups))
+    data = {'groups': updated_groups}
+    print(data)
+    response = requests.put(url, json=data, headers=headers)
+    print(url)
+    print(user_data)
+    return response
+
+
+def change_status_company(auth_token, url,id_metaservice):
+    headers = {
+    'Content-Type': 'application/json',
+    'Authorization': f'Token {auth_token}'
+    }
+    response = requests.get(url, headers=headers)
+    user_data = response.json()
+    print(user_data)
+    current_metaservice = user_data.get('id_metaservice', [])
+    repsonse = requests.put(config.API_URL+f"dbsynce/api/company/{id_metaservice}", json=data, headers=headers)
+    return response
+
+
+def to_answer(jsonstring):
+    json_answer = json.loads(jsonstring)
+    print(json_answer)
+    u = Answer(**json_answer)
+    return u
+
+
+def change_to_task(localtask,token):
+    headers = {
+        'Authorization': f'Token {token}',
+        'Content-Type': 'application/json'  # Установка заголовка Content-Type
+    }
+    data = json.dumps(localtask.__dict__)
+    response = requests.patch(config.API_URL+f"/dbsynce/api/orders/{localtask.id}/", headers=headers, data=data)
+    return response

+ 121 - 0
handlers/open_accessrequest_accepted.py

@@ -0,0 +1,121 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_accessrequest_accepted"
+
+operating_status=321
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_accessrequest_accepted_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_accessrequest_accepted_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    send_data(localtask)
+
+# Пока не уверен
+def send_data(localtask):
+    # Заглушка отправка данных в БД
+    # ...
+    return True
+
+def open_accessrequest_accepted():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_accessrequest_accepted_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_accessrequest_accepted)
+
+
+

+ 123 - 0
handlers/open_accessrequest_pending.py

@@ -0,0 +1,123 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_accessrequest_pending"
+
+operating_status=320
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_accessrequest_pending_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[1],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ перенаправлен\n")
+
+def open_accessrequest_pending_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    push_notifications(localtask)
+    open_accessrequest_pending_wait(100,localtask)
+
+
+# Пока не уверен
+def push_notifications(localtask):
+    # Отправка уведомлений
+    # ...
+    return True
+
+def open_accessrequest_pending():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_accessrequest_pending_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_accessrequest_pending)
+
+
+

+ 50 - 0
handlers/open_basic_bot.py

@@ -0,0 +1,50 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+botname="open_basic_bot"
+
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test_user@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["another_bot@ej.sharix-app.org"]
+
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    if (str(user).split("/")[0]) in listen_to:
+        if text is not None:
+            msg = jsreq.msg_to_text(text)
+            bot.bot_log(str(datetime.now())+" Сообщение получено\n")
+
+
+def open_basic_bot():      
+    bot.proceed_status(listen_to[0],{'msg':'some_info'})
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Сообщение отправлено\n")
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_basic_bot)
+

+ 121 - 0
handlers/open_negrequest_accepted.py

@@ -0,0 +1,121 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_negrequest_accepted"
+
+operating_status=321
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_negrequest_accepted_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_negrequest_accepted_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    send_data(localtask)
+
+# Пока не уверен
+def send_data(localtask):
+    # Заглушка отправка данных в БД
+    # ...
+    return True
+
+def open_negrequest_accepted():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_negrequest_accepted_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_negrequest_accepted)
+
+
+

+ 111 - 0
handlers/open_negrequest_pending.py

@@ -0,0 +1,111 @@
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+#В этом файле содержится только то, что запускает конкретный обработчик
+
+# botname="open_strequest_assigned"
+botname="open_negrequest_pending"
+operating_status=420
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+#раскомментировать, когда перейдем на разные пароли
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["open_negrequest_pending@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["open_negrequest_pending@ej.sharix-app.org", "open_negrequest_declined@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    #user = mess.getNode()#только jid 
+   
+   #нужна проверка, данный обработчик вообще должен от данного отправителя получать сообщения или нет. Подсказка ниже
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+#TODO - для обработчиков Ticket скорее надо будет функции вынести в отдельную библиотеку, они типовые же
+def pending_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает пользовательской реакции\n")
+    time.sleep(period)
+    
+    #ВАЖНО! НАДО ВСТАВИТЬ ИЗМЕНЕНИЕ СТАТУСА ЧЕРЕЗ API
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[1],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отклонен\n")
+
+def open_negrequest_pending():
+    #print("Тут описывается работа со списком задач в данном статусе")
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        
+        #если боту почему-то пришла не его заявка - это явно ошибка движения процессов и отдаем в форсмажор - этот обработчик указывать стоит всегда последним
+        #if (localtask.status!=operating_status):
+        #    bot.proceed_status(proceed_to[-1],localtask)
+        #    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+        #    continue
+
+        #TODO: send_notifications - изучить как в комнату
+
+        #ЖДАТЬ НАДО ПОДОЛЬШЕ
+        t1=threading.Thread(target=pending_wait, args=(100,localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        #bot.proceed_status(proceed_to[0],localtask)
+        #print("Заказ возвращен в очередь\n")
+        #print (tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо понять, по такому ли запросу разумно делать фильтр - или поменять порядок
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?status=210&list_id=10")
+print (len(tasklist))
+
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_negrequest_pending)
+
+
+

+ 179 - 0
handlers/open_servicerequest_accepted.py

@@ -0,0 +1,179 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_accepted"
+
+operating_status='221'
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["open_servicerequest_assigned@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname,"open_servicerequest_process@ej.sharix-app.org", "open_servicerequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+def log_handler():
+    while True:
+        with open(f'{botname}.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
+        time.sleep(3600)
+
+
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    if (str(user).split("/")[0]) in listen_to:
+        if text is not None:
+            orderObj = jsreq.jsonToOrder(text)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_accepted_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_accepted_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    
+    # order = jsreq.jsonToOrder(localtask)
+    localtask.status='231'
+    jsreq.change_to_task(localtask,token)
+    bot.proceed_status(proceed_to[1],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    # if order.time_start_predicted < 100:
+    #     # Заглушка. Проверка может ли заказ быть переназначен
+    #     if True:
+    #         # Заглушка. Сбросить пометку предзаказа
+    #         # ...
+
+
+    #         bot.proceed_status(proceed_to[1],localtask)
+    #         bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    #     else:
+    #         bot.proceed_status(proceed_to[2],localtask)
+    #         bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    # else:
+    #     # Заглушка. Обработана заявка на устанавление взаимоотношений?
+    #     if True:
+    #         # Заглушка. Взаимоотношения установлены ?
+    #         if True:
+    #             # Заглушка. Отобразить в предварительных заказах исполнителям.
+    #             send_message()
+    #             # Заглушка. Исполнитель откликнулся на заказ?
+    #             if True:
+    #                 # У пользователя стоит ручной выбор из нескольких исполнителей?
+    #                 if True:
+    #                     # Заглушка создать дочернюю локальную заявку с информацией от исполнителя
+    #                     create_ticket()
+    #                     # Заглушка отобразить в предварительных клиенту
+    #                     send_message()
+
+    #                     # Заглушка. Клиент выбрал конкретную заявку?
+    #                     if True:
+    #                         # Заглушка. обновление локальной копии. Замена основной
+    #                         pass
+    #                     else:
+    #                         bot.proceed_status(proceed_to[3],localtask)
+    #                         bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    #                 else:
+    #                     bot.proceed_status(proceed_to[3],localtask)
+    #                     bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    #             else:
+    #                 #Заглушка. Заказ ждет очередную итерацию обработки списка
+    #                 open_servicerequest_accepted_process(localtask)
+    #         else:
+    #             bot.proceed_status(proceed_to[1],localtask)
+    #             bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    #     else:
+    #         #Заглушка. Заказ ждет очередную итерацию обработки списка
+    #         open_servicerequest_accepted_process(localtask)
+    #         pass
+    
+
+
+def send_message():
+    pass
+
+def create_ticket():
+    pass
+
+def open_servicerequest_accepted():
+    log_thread = threading.Thread(target=log_handler)
+    log_thread.daemon = True 
+    log_thread.start()
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            localtask.status=239
+            jsreq.change_to_task(localtask,token)
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+        elif True:
+            t1=threading.Thread(target=open_servicerequest_accepted_process, args=([localtask]))
+            t1.start()
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        
+
+        # #если никакие обработчики не подошли - отправляем обратно в очередь
+        # bot.proceed_status(proceed_to[0],localtask)
+        # print("Заказ возвращен в очередь\n")
+        # print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/")
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_accepted)

+ 181 - 0
handlers/open_servicerequest_assigned.py

@@ -0,0 +1,181 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+import asyncio
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_assigned"
+
+operating_status='212'
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+drivers = ["799999999998@ej.sharix-app.org"]
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["open_servicerequest_booked@ej.sharix-app.org","open_servicerequest_pending@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_servicerequest_accepted@ej.sharix-app.org", "open_servicerequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+def log_handler():
+    while True:
+        with open(f'{botname}.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
+        time.sleep(3600)
+
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    if (str(user).split("/")[0]) in listen_to:
+        print('order_handler')
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrder(text)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+        
+            
+def open_servicerequest_assigned_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def wait_for_answer(localtask):
+    order = localtask
+    driver = drivers[0]
+    send_message(order,driver)
+ # Здесь можно реализовать логику выбора водителя
+    while True:
+        start_time = time.time()
+        if time.time()+400 - start_time > 300: ##Логика временная
+            if len(answers) > 0:
+                answer = answers.pop(0)
+                if answer.answer == 'ACCEPT':
+                    localtask.status='221'
+                    jsreq.change_to_task(localtask,token)    
+                    bot.proceed_status(proceed_to[1], localtask)
+                    bot.bot_log(botname + " " + str(datetime.now()) + f" Заказ отправлен на {proceed_to[1]}\n")
+                elif answer.answer == 'DECLINE':
+                    localtask.status='229'
+                    localtask.provider=None
+                    jsreq.change_to_task(localtask,token)
+                    bot.proceed_status(proceed_to[2], localtask)
+                    bot.bot_log(botname + " " + str(datetime.now()) + f" Заказ отправлен на {proceed_to[2]}\n")
+                else:
+                    bot.bot_log(botname + " " + str(datetime.now()) + f"Ошибка ответа\n")
+                break
+            else:
+                print("Ожидание ответа...")
+                time.sleep(3)
+        else:
+            localtask.status='229'
+            localtask.provider=None
+            jsreq.change_to_task(localtask,token)
+            bot.proceed_status(proceed_to[2], localtask)
+            bot.bot_log(botname + " " + str(datetime.now()) + f" Заказ отправлен на {proceed_to[2]}\n")
+            break
+            
+
+def open_servicerequest_assigned_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    order = localtask
+    if order.provider!=None:
+        wait_thread = threading.Thread(target=wait_for_answer, args=(localtask,))
+        wait_thread.start()
+
+
+def message_answer(conn, mess):       
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    if (str(user).split("/")[0]) in drivers:
+        print ('answer_handler')
+        if text is not None:
+            answerObj = jsreq.to_answer(text)
+            answers.append(answerObj)
+            bot.bot_log(str(datetime.now())+" Поступивший ответ успешно добавлен в очередь обработки\n")
+            
+    
+def send_message(order,driver):
+    order=json.dumps(order.__dict__)
+    bot.send_notification(driver,order)   
+
+
+def open_servicerequest_assigned():
+    log_thread = threading.Thread(target=log_handler)
+    log_thread.daemon = True 
+    log_thread.start()
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        if (localtask.status!=operating_status):
+            localtask.status='239'
+            jsreq.change_to_task(localtask,token)
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+        else:
+            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+            t1=threading.Thread(target=open_servicerequest_assigned_process, args=([localtask]))
+            t1.start()
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        # t1=threading.Thread(target=open_servicerequest_assigned_process, args=(localtask))
+        # t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        # bot.proceed_status(proceed_to[0],localtask)
+        # print("Заказ возвращен в очередь\n")
+        # print(tasklist)
+
+#Авторизация и запуск бота
+
+answers = []
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/")
+
+
+bot = JabberBot(JID, PASSWORD, PORT)
+bot.register_handler('message', message_handler)
+bot.register_handler('message', message_answer)
+bot.start(open_servicerequest_assigned)
+
+
+#Добавить функцию поток для ожидания получения заказа.

+ 215 - 0
handlers/open_servicerequest_booked.py

@@ -0,0 +1,215 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+def log_handler():
+    while True:
+        with open('log.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - Function is still running...\n")
+        time.sleep(3600)
+botname="open_servicerequest_booked"
+
+operating_status='211'
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["799999999990@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["open_servicerequest_assigned@ej.sharix-app.org","open_servicerequest_pending@ej.sharix-app.org",  "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+def log_handler():
+    while True:
+        with open(f'{botname}.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
+        time.sleep(3600)
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    if (str(user).split("/")[0]) in listen_to:
+        # print (str(user).split("/")[0])
+        if text is not None:
+            try :
+                orderObj = jsreq.jsonToOrder(text)
+                tasklist.append(orderObj)
+                bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+            except:
+                bot.proceed_status(proceed_to[-1], text)
+                bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на assigned\n")
+            
+            
+
+def open_servicerequest_booked_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_servicerequest_booked_process(localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ в обработчике\n")
+    
+    if not localtask.provider:
+        answer,provider,service = set_provider(localtask.id)
+        # localtask.service =service.id
+        localtask.service = service['id']
+        if set_provider(localtask.id):
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Водитель успешно установлен\n")
+        else:
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"'Ошибка водитель не был установлен'\n")
+        localtask.provider = provider
+    current_time = datetime.now()
+    
+    # if localtask.asap or (current_time - datetime.fromisoformat(localtask.time_start_predicted) < timedelta(hours=3)):
+    if localtask.asap:
+        localtask.status = '212'
+        print(jsreq.change_to_task(localtask,token))
+        bot.proceed_status(proceed_to[0], localtask)
+        bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на assigned\n")
+    else:
+        localtask.status = '220'
+        print(jsreq.change_to_task(localtask,token))
+        bot.proceed_status(proceed_to[1], localtask)
+        bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на pending\n")
+        
+        # Проверка срочности заказа
+        # if order.asap:
+        #     #Заглушка назначение исполнителя системой
+        #     if set_provider(order.ticket, order.provider) == "success":
+        #         bot.proceed_status(proceed_to[0], localtask)
+        #     else:
+        #         bot.bot_log(botname+" "+str(datetime.now())+" "+"Ошибка назначения исполнителя\n")
+        # else:
+        #         localtask.status = 220
+        #         bot.proceed_status(proceed_to[0], localtask)
+        #         print(localtask)
+        # bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан и отправлен на assigned\n")
+        # Проверка срочности заказа
+        
+def get_balance(client):
+    headers = {'Authorization': f'Token {token}'}
+    # Передаем id пользователя и получаем его баланс
+    response = requests.get(config.API_URL+f"/api/example/{client}", headers=headers)
+    print(response.json())
+    ordertext=response.json()
+    
+    if not ordertext:
+        print("Empty array")
+    else:
+        print(ordertext[0], "PROCESSING")
+        try:
+            balance = ordertext[0].get('balance')
+            return balance
+        except Exception as ex:
+            print(ex)
+            
+#set provider?
+def choose_provider(auth_token,geo):
+    providers=requests.get(config.API_URL+"/dbsynce/api/provider/",headers=auth_token)
+    provider=providers.json()[0]['id']
+    return provider
+    
+def set_provider(localtask_id):
+    token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+    headers = {'Authorization': f'Token {token}'}
+    provider = choose_provider(headers,'geoposition')
+    service = requests.get(config.API_URL+f"/dbsynce/api/service/?id_provider={provider}", headers=headers)
+    service=service.json()[0]
+    data = {'provider':int(provider)}
+    # print(data)
+    # print(str(config.API_URL+f"/dbsynce/api/orders/{localtask_id}/"))
+    response = requests.patch(config.API_URL+f"/dbsynce/api/orders/{localtask_id}/", headers=headers, json=data)
+    return response ,provider , service
+
+    
+    # if not ordertext:
+    #     print("Empty array")
+    # else:
+    #     print(ordertext[0], "PROCESSING")
+    #     try:
+    #         message = ordertext[0].get('message')
+    #         return message
+    #     except Exception as ex:
+    #         print(ex)
+
+def open_servicerequest_booked():
+    log_thread = threading.Thread(target=log_handler)
+    log_thread.daemon = True 
+    log_thread.start()
+    
+    
+    
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        if (str(localtask.status)!=str(operating_status)):
+            # bot.proceed_status(proceed_to[-1],localtask) #временная проверка отправки
+            print(localtask)
+            localtask.status='239'
+            jsreq.change_to_task(localtask,token)
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+        else:
+            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+            t1=threading.Thread(target=open_servicerequest_booked_process, args=([localtask]))
+            t1.start()
+        # elif (localtask.provider==T):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+        
+        
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        # bot.proceed_status(proceed_to[0],localtask)
+        # print("Заказ возвращен в очередь\n")
+        # print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+# #надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+# #ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/") ###Должна быть проверка между двумя
+
+# # print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_booked)
+
+# print(set_provider('localtask'))

+ 172 - 0
handlers/open_servicerequest_booked_v2.py

@@ -0,0 +1,172 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_booked"
+
+operating_status=211
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["9090@ej.sharix-app.org","test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org","799999999990@ej.shaix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["open_servicerequest_assigned@ej.sharix-app.org", "open_servicerequest_pending@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    print(text)
+    print(user)
+    print(f'This is text{text} and this is\n\n{user}')
+    # print (str(user).split("/")[0])
+    # print('good')
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+        
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_booked_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_servicerequest_booked_process(localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+    #Пока заглушка
+    balance = get_balance(order.client_id)
+
+    
+    price = order.real_price
+
+    if balance > price:
+        #Заказ на основного водителя?
+        if order.provider:
+            bot.proceed_status(proceed_to[1], localtask)
+            bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан\n")
+        else:
+            # Проверка срочности заказа
+            if order.asap:
+                #Заглушка назначение исполнителя системой
+                if set_provider(order.ticket, order.provider) == "success":
+                    bot.proceed_status(proceed_to[0], localtask)
+                else:
+                    bot.bot_log(botname+" "+str(datetime.now())+" "+"Ошибка назначения исполнителя\n")
+            else:
+                bot.proceed_status(proceed_to[1], localtask)
+            
+            bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ успешно обработан\n")
+    else:
+        # Заглушка получения оплаты от клиента
+        pass
+
+def get_balance(client):
+    headers = {'Authorization': f'Token {token}'}
+    # Передаем id пользователя и получаем его баланс
+    response = requests.get(config.API_URL+f"/api/example/{client}", headers=headers)
+    print(response.json())
+    ordertext=response.json()
+    
+    if not ordertext:
+        print("Empty array")
+    else:
+        print(ordertext[0], "PROCESSING")
+        try:
+            balance = ordertext[0].get('balance')
+            return balance
+        except Exception as ex:
+            print(ex)
+
+def set_provider(ticket, provider):
+    headers = {'Authorization': f'Token {token}'}
+    data = {'ticket': ticket,
+            'provider': provider}
+    response = requests.post(config.API_URL+f"/api/example/set-provider", headers=headers, data=data)
+    print(response.json())
+    ordertext=response.json()
+    
+    if not ordertext:
+        print("Empty array")
+    else:
+        print(ordertext[0], "PROCESSING")
+        try:
+            message = ordertext[0].get('message')
+            return message
+        except Exception as ex:
+            print(ex)
+
+def open_servicerequest_booked():
+    # while (len(tasklist)):
+    #     localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            # continue
+
+        t1=threading.Thread(target=open_servicerequest_booked_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/base/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/webservice/api/webservice/")
+
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_booked)
+
+
+

+ 136 - 0
handlers/open_servicerequest_closed.py

@@ -0,0 +1,136 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+
+global tasklist
+
+
+
+botname="open_servicerequest_booked"
+##############################
+# operating_status='211'
+# JID=botname+"@"+config.JSERVER
+# PORT=config.PORT
+
+# PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+
+
+
+###################
+botname="open_servicerequest_closed"
+
+operating_status=239
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+headers = {'Authorization': f'Token {token}'}
+
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["799999999990@ej.sharix-app.org","test@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_new@ej.sharix-app.org", "open_servicerequest_closed@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+def log_handler():
+    while True:
+        with open(f'{botname}.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
+        time.sleep(3600)
+
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    if (str(user).split("/")[0]) in listen_to:
+        if text is not None:
+            orderObj = jsreq.jsonToOrder(text)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_closed_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_closed_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    response = requests.delete(config.API_URL+f"/dbsynce/api/orders/{localtask.id}/",headers=headers)
+    text = (config.API_URL+f"dbsynce/api/orders/{localtask.id}/")
+    if response:      
+        bot.proceed_status(proceed_to[2],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ удален\n")
+    else:
+        bot.proceed_status(proceed_to[-1],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+
+
+
+def open_servicerequest_closed():
+    log_thread = threading.Thread(target=log_handler)
+    log_thread.daemon = True 
+    log_thread.start()
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        # if (localtask.status!=operating_status):
+        #     bot.proceed_status(proceed_to[-1],localtask)
+        #     bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+        #     continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        if (localtask.status in ("239","211","212","220","221","222","231","238","229")):
+            t1=threading.Thread(target=open_servicerequest_closed_process, args=([localtask]))
+            t1.start()
+
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/")
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_closed)

+ 138 - 0
handlers/open_servicerequest_declined.py

@@ -0,0 +1,138 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_declined"
+
+operating_status=229
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+users = ["799999999990@ej.sharix-app.org"]
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "799999999990@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_servicerequest_cancelled@ej.sharix-app.org", "open_servicerequest_booked@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+def log_handler():
+    while True:
+        with open(f'{botname}.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
+        time.sleep(3600)
+
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrder(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_declined_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_declined_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    
+    order = jsreq.jsonToOrder(localtask)
+
+    # Заглушка с счетчиком
+
+    # Заказ может быть выполнен другим
+    if True:
+        bot.proceed_status(proceed_to[1],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    else: 
+        # Заглушка. Сброс пометки что заказ на основного водителя
+        bot.proceed_status(proceed_to[2],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+
+def send_message():
+    pass
+
+def create_ticket():
+    pass
+
+def open_servicerequest_declined():
+    log_thread = threading.Thread(target=log_handler)
+    log_thread.daemon = True 
+    log_thread.start()
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_servicerequest_declined_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_declined)

+ 153 - 0
handlers/open_servicerequest_done.py

@@ -0,0 +1,153 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_done"
+
+operating_status='241'
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+users = ["799999999990@ej.sharix-app.org"]
+
+drivers = ["799999999998@ej.sharix-app.org"]
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["open_servicerequest_process@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_new@ej.sharix-app.org", "open_servicerequest_closed@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+statuses = ['DONE', 'WONTFIX', 'DUBLICATE']
+
+
+
+def log_handler():
+    while True:
+        with open(f'{botname}.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
+        time.sleep(3600)
+
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrder(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_done_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_done_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    
+    order = jsreq.jsonToOrder(localtask)
+    status = order.status
+
+    # Заглушка + Оплата
+    create_ticket(localtask)
+    # отправка формы
+    send_message()
+    
+    # Заглушка с таймером
+
+    
+    bot.proceed_status(proceed_to[2],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+
+        
+    
+# Заглушка
+def send_message(localtask):
+    pass
+
+
+def create_ticket(localtask):
+    bot.proceed_status(proceed_to[1],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    pass
+
+def open_servicerequest_done():
+    log_thread = threading.Thread(target=log_handler)
+    log_thread.daemon = True 
+    log_thread.start()
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_servicerequest_done_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_done)

+ 133 - 0
handlers/open_servicerequest_forcemajeure.py

@@ -0,0 +1,133 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_forcemajeure"
+
+operating_status=239
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_new@ej.sharix-app.org", "open_servicerequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+statuses = ['DONE', 'WONTFIX', 'DUBLICATE']
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_forcemajeure_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_forcemajeure_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    
+    order = jsreq.jsonToOrder(localtask)
+    status = order.status
+
+    # Заглушка
+    create_ticket(localtask)
+    # ???
+    if order.status in statuses:
+        order.status = status
+    else:
+        bot.proceed_status(proceed_to[0],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+        
+    
+    
+
+
+def create_ticket(localtask):
+    bot.proceed_status(proceed_to[1],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    pass
+
+def open_servicerequest_forcemajeure():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_servicerequest_forcemajeure_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_forcemajeure)

+ 140 - 0
handlers/open_servicerequest_pending.py

@@ -0,0 +1,140 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_pending"
+
+operating_status='220'
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["open_servicerequest_booked@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_servicerequest_assigned@ej.sharix-app.org",  "open_servicerequest_forcemajeure@ej.sharix-app.org","799999999998@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    # print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        # print(text)
+        # print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrder(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_pending_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_pending_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    
+    order = jsreq.jsonToOrder(localtask)
+
+    # Заглушка. Может ли что-то пойти не так
+    if True:
+        if order.time_start_predicted < time.time():
+            bot.proceed_status(proceed_to[0],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+            return
+        # Заглушка активная ли стадия заказа
+        elif order.status == "active":
+            localtask.status=212
+            jsreq.change_to_task(localtask,token)
+            bot.proceed_status(proceed_to[1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+        # else:
+        #     bot.proceed_status(proceed_to[2],localtask)
+        #     bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+        #     # Заглушка на получение ответа
+        #     pass
+    # else:
+    #     bot.proceed_status(proceed_to[1],localtask)
+    #     bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+
+
+def send_message():
+    pass
+
+def open_servicerequest_pending():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        # print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            localtask.status=239
+            jsreq.change_to_task(localtask,token)
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_servicerequest_pending_process, args=([localtask]))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        # print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/")
+# print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_pending)
+
+#Получение сообщения от водителя

+ 135 - 0
handlers/open_servicerequest_preforcemajeure.py

@@ -0,0 +1,135 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_preforcemajeure"
+
+operating_status=239
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_new@ej.sharix-app.org", "open_servicerequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+statuses = ['DONE', 'WONTFIX', 'DUBLICATE']
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_preforcemajeure_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_preforcemajeure_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    
+    order = jsreq.jsonToOrder(localtask)
+    status = order.status
+
+    # Заглушка
+    create_ticket(localtask)
+    # ???
+    if order.status in statuses:
+        order.status = status
+    else:
+        
+        # Заглушка с таймером
+        bot.proceed_status(proceed_to[0],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+        
+    
+    
+
+
+def create_ticket(localtask):
+    bot.proceed_status(proceed_to[1],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    pass
+
+def open_servicerequest_preforcemajeure():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_servicerequest_preforcemajeure_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_preforcemajeure)

+ 120 - 0
handlers/open_servicerequest_prestart.py

@@ -0,0 +1,120 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_prestart"
+
+operating_status=222
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_servicerequest_preforcemajeure@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_prestart_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def open_servicerequest_prestart_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    
+    order = jsreq.jsonToOrder(localtask)
+
+    if order.asap:
+        bot.proceed_status(proceed_to[1],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    else:
+        bot.proceed_status(proceed_to[0],localtask)
+        bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    
+
+def open_servicerequest_prestart():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_servicerequest_prestart_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_prestart)

+ 178 - 0
handlers/open_servicerequest_process.py

@@ -0,0 +1,178 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_servicerequest_process"
+
+operating_status='231'
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+
+drivers = ["799999999998@ej.sharix-app.org"]
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["open_servicerequest_accepted@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname,"open_servicerequest_done@ej.sharix-app.org", "open_servicerequest_preforcemajeure@ej.sharix-app.org", "open_servicerequest_declined@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+
+def log_handler():
+    while True:
+        with open(f'{botname}.txt', 'a') as log_file:
+            log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {botname} is still running...\n")
+        time.sleep(3600)
+
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    if (str(user).split("/")[0]) in listen_to:
+        if text is not None:
+            orderObj = jsreq.jsonToOrder(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+
+def message_answer(conn, mess):       
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    if (str(user).split("/")[0]) in drivers:
+        print ('answer_handler')
+        if text is not None:
+            answerObj = jsreq.to_answer(text)
+            answers.append(answerObj)
+            bot.bot_log(str(datetime.now())+" Поступивший ответ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_process_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+
+def wait_for_answer(localtask):
+    order = localtask
+    # Здесь можно реализовать логику выбора водителя
+    while True:
+        if len(answers) > 0:
+            answer = answers.pop(0)
+            if answer.answer == 'Complete':
+                localtask.status='241'
+                jsreq.change_to_task(localtask,token)    
+                bot.proceed_status(proceed_to[1], localtask)
+                bot.bot_log(botname + " " + str(datetime.now()) + f" Заказ отправлен на {proceed_to[1]}\n")
+            break
+        else:
+            print("Ожидание ответа...")
+            time.sleep(30)
+
+def open_servicerequest_assigned_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    order = localtask
+    if order.provider!=None:
+        wait_thread = threading.Thread(target=wait_for_answer, args=(localtask,))
+        wait_thread.start()
+        
+def open_servicerequest_process_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+    order = localtask
+    wait_thread = threading.Thread(target=wait_for_answer, args=(localtask,))#ожидание выполнения заказа
+    wait_thread.start()
+
+    # Заглушка проверка баланса
+    # if check_balance() >= order.real_price:
+    # if True:
+    #     # Заглушка. Расчетное время прибытия на следующую точку превышаетзапланированное на Х
+    #     if True:
+    #         bot.proceed_status(proceed_to[1],localtask)
+    #         bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+    #     else:
+    #         bot.proceed_status(proceed_to[0],localtask)
+    #         bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и отправлен в очередь\n")
+    # else:
+    #     # Оплата
+
+    #     bot.proceed_status(proceed_to[1],localtask)
+    #     bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен\n")
+        
+    #     pass
+
+
+def check_balance():
+    pass
+
+def open_servicerequest_process():
+    log_thread = threading.Thread(target=log_handler)
+    log_thread.daemon = True 
+    log_thread.start()
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        if (localtask.status!=operating_status):
+            localtask.status='239'
+            jsreq.change_to_task(localtask,token)
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_servicerequest_process_process, args=[localtask])
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        # bot.proceed_status(proceed_to[0],localtask)
+        # print("Заказ возвращен в очередь\n")
+        # print(tasklist)
+
+#Авторизация и запуск бота
+
+answers = []
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"my/api/v1/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist_dbsynce=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/")
+
+
+bot = JabberBot(JID, PASSWORD, PORT)
+bot.register_handler('message', message_handler)
+bot.register_handler('message', message_answer)
+bot.start(open_servicerequest_process)

+ 130 - 0
handlers/open_strequest_assigned.py

@@ -0,0 +1,130 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_strequest_assigned"
+
+operating_status=121
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_wontfix@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_strequest_assigned_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_strequest_assigned_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+
+    # Проверяем наличие маркера обработчика
+    if order.marker:
+        # Вызываем алгоритм обработки в соответствии с маркером
+        process_with_handler(order)
+    else:
+        #Заглушка Если таймер неактивен, отправляем в st_request_wontfix
+        if True:
+            bot.proceed_status(proceed_to[1],localtask)
+
+# Пока не уверен
+def process_with_handler(order):
+    # Алгоритм назначения исполнителя
+    # ...
+    return True
+
+def open_strequest_assigned():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_strequest_assigned_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_strequest_assigned)
+
+
+

+ 132 - 0
handlers/open_strequest_done.py

@@ -0,0 +1,132 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_strequest_done"
+
+operating_status=149
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_closed@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_strequest_done_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_strequest_done_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+    idle_value = idle_value - 1
+
+    if idle_value < 1:
+        bot.proceed_status(proceed_to[1],localtask)
+    else:
+        push_notifications(order)
+        open_strequest_done_wait(100,localtask)
+    # Затычка
+    if True:
+        open_strequest_done_process(localtask)
+
+
+# Пока не уверен
+def push_notifications(order):
+    # Отправка уведомлений
+    # ...
+    return True
+
+def open_strequest_done():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_strequest_done_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_strequest_done)
+
+
+

+ 131 - 0
handlers/open_strequest_dublicate.py

@@ -0,0 +1,131 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_strequest_dublicate"
+
+operating_status=149
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_closed@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_strequest_dublicate_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_strequest_dublicate_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+    idle_value = idle_value - 1
+
+    if idle_value < 1:
+        bot.proceed_status(proceed_to[1],localtask)
+    else:
+        push_notifications(order)
+        open_strequest_dublicate_wait(100,localtask)
+    # Затычка
+    if True:
+        open_strequest_dublicate_process(localtask)
+
+# Пока не уверен
+def push_notifications(order):
+    # Отправка уведомлений
+    # ...
+    return True
+
+def open_strequest_dublicate():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_strequest_dublicate_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_strequest_dublicate)
+
+
+

+ 130 - 0
handlers/open_strequest_inprocess.py

@@ -0,0 +1,130 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_strequest_inprocess"
+
+operating_status=131
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_wontfix@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_strequest_inprocess_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_strequest_inprocess_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+
+    # Проверяем наличие маркера обработчика
+    if order.marker:
+        # Вызываем алгоритм обработки в соответствии с маркером
+        process_with_handler(order)
+    else:
+        #Заглушка Если таймер неактивен, отправляем в st_request_wontfix
+        if True:
+            bot.proceed_status(proceed_to[1],localtask)
+
+# Пока не уверен
+def process_with_handler(order):
+    # Алгоритм назначения исполнителя
+    # ...
+    return True
+
+def open_strequest_inprocess():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_strequest_inprocess_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_strequest_inprocess)
+
+
+

+ 147 - 0
handlers/open_strequest_new.py

@@ -0,0 +1,147 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_strequest_new"
+
+operating_status=111
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_assigned@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_servicerequest_booked_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_stequest_new_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+
+    if order.provider:
+        st_request_assigned(order)
+    else:
+        # Что такое маркер обработчика?
+        if not order.marker:
+            add_marker(order)
+            assign_executor(localtask)
+        
+        if assign_executor(order):
+            st_request_assigned(localtask)
+        else:
+            # Проверка таймера
+            if True:
+                if assign_executor(order):
+                    st_request_assigned(localtask)
+            else:
+                add_marker(order)
+                assign_executor(order)
+
+def st_request_assigned(localtask):
+    bot.proceed_status(proceed_to[1],localtask)
+
+# Пока не уверен
+def assign_executor(order):
+    # Алгоритм назначения исполнителя
+    # ...
+    return True
+
+def add_marker(order):
+    # 
+    pass
+
+def open_servicerequest_booked():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_stequest_new_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_servicerequest_booked)
+
+
+

+ 147 - 0
handlers/open_strequest_reopened.py

@@ -0,0 +1,147 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_strequest_reopened"
+
+operating_status=110
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_assigned@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_stequest_reopened_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_stequest_reopened_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+
+    if order.provider:
+        st_request_assigned(order)
+    else:
+        # Что такое маркер обработчика?
+        if not order.marker:
+            add_marker(order)
+            assign_executor(localtask)
+        
+        if assign_executor(order):
+            st_request_assigned(localtask)
+        else:
+            # Проверка таймера
+            if True:
+                if assign_executor(order):
+                    st_request_assigned(localtask)
+            else:
+                add_marker(order)
+                assign_executor(order)
+
+def st_request_assigned(localtask):
+    bot.proceed_status(proceed_to[1],localtask)
+
+# Пока не уверен
+def assign_executor(order):
+    # Алгоритм назначения исполнителя
+    # ...
+    return True
+
+def add_marker(order):
+    # 
+    pass
+
+def open_stequest_reopened():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_stequest_reopened_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_stequest_reopened)
+
+
+

+ 135 - 0
handlers/open_strequest_wontfix.py

@@ -0,0 +1,135 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="open_strequest_wontfix"
+
+operating_status=149
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+print(JID, PASSWORD)
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=[botname, "open_strequest_closed@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_strequest_wontfix_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_strequest_wontfix_process(localtask):
+    bot.bot_log(botname + " " + str(datetime.now()) + " " + "Заказ в обработчике\n")
+
+    order = jsreq.jsonToOrder(localtask)
+    idle_value = idle_value - 1
+
+    if idle_value < 1:
+        st_request_wontfix(localtask)
+    else:
+        push_notifications(order)
+        open_strequest_wontfix_wait(100,localtask)
+    # Затычка
+    if True:
+        open_strequest_wontfix_process(localtask)
+
+
+def st_request_wontfix(localtask):
+    bot.proceed_status(proceed_to[1],localtask)
+
+# Пока не уверен
+def push_notifications(order):
+    # Отправка уведомлений
+    # ...
+    return True
+
+def open_strequest_wontfix():
+    while (len(tasklist)):
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        print("EACH TASKLIST", tasklist)
+
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        # if (localtask.title!="10"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_wait, args=(5,localtask))
+        #     t1.start()
+
+        # if (localtask.title=="101"):
+        #     t1=threading.Thread(target=open_servicerequest_booked_process, args=(10,localtask))
+        #     t1.start()
+
+        t1=threading.Thread(target=open_strequest_wontfix_process, args=(localtask))
+        t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print(tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/auth/token/login/")
+
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/tickets/api/tickets/?list_id=10")
+print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_strequest_wontfix)
+
+
+

+ 125 - 0
handlers/open_template_bot.py

@@ -0,0 +1,125 @@
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+#В этом файле содержится только то, что запускает конкретный обработчик
+
+# botname="open_strequest_assigned"
+botname="open_template_bot"
+operating_status=210
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+#раскомментировать, когда перейдем на разные пароли
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["test@ej.sharix-app.org", "open_template_bot@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["open_template_bot@ej.sharix-app.org", "test@ej.sharix-app.org", "test1@ej.sharix-app.org", "open_servicerequest_forcemajeure@ej.sharix-app.org"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+def message_handler(conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+    #user = mess.getNode()#только jid 
+   
+   #нужна проверка, данный обработчик вообще должен от данного отправителя получать сообщения или нет. Подсказка ниже
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def open_bot_template_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает\n")
+    time.sleep(period)
+    
+    #ВАЖНО! Надо скорее всего через API редактировать заказ, иначе возможна потеря данных
+    localtask.title=localtask.title+"1"
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ подождал и возвращен в очередь\n")
+
+def open_bot_template_process(localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ в обработчике\n")
+    
+    #ВАЖНО! Надо через API редактировать заказ, иначе возможна потеря данных
+    #localtask.title +=1
+
+    bot.proceed_status(proceed_to[1],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ успешно обработан\n")
+
+
+def open_bot_template():
+    #print("Тут описывается работа со списком задач в данном статусе")
+    while (len(tasklist)):
+    #for i in range(len(tasklist)):
+        #проверяем элемент tasklist[i]
+        #print (i, len(tasklist))
+        localtask=tasklist.pop(0)
+        bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Заказ в очереди на обработке\n")
+        #bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " " + str(i) + " " + "Заказ в очереди на обработке\n")
+        #print ("EACH TASKLIST", tasklist[i])
+        #localtask=tasklist.pop(i)
+        
+        #если боту почему-то пришла не его заявка - это явно ошибка движения процессов и отдаем в форсмажор - этот обработчик указывать стоит всегда последним
+        if (localtask.status!=operating_status):
+            bot.proceed_status(proceed_to[-1],localtask)
+            bot.bot_log(botname+" "+str(datetime.now())+" "+"Заказ не по адресу, перенаправляем на форсмажор\n")
+            continue
+
+        if (localtask.title!="10"):
+            t1=threading.Thread(target=open_bot_template_wait, args=(5,localtask))
+            t1.start()
+
+        if (localtask.title=="101"):
+            t1=threading.Thread(target=open_bot_template_process, args=(10,localtask))
+            t1.start()
+
+        #если никакие обработчики не подошли - отправляем обратно в очередь
+        bot.proceed_status(proceed_to[0],localtask)
+        print("Заказ возвращен в очередь\n")
+        print (tasklist)
+
+#Авторизация и запуск бота
+
+#пустой список заказов
+tasklist = []
+
+#надо инициализировать tasklist при запуске из API
+token = jsreq.requestGetToken(botname, PASSWORD, config.API_URL+"/base/auth/token/login/")
+#ВАЖНО! Надо еще фильтровать список по статусу обработки заявки
+tasklist=jsreq.requestGetList(token, config.API_URL+"/webservice/api/webservice/")
+
+print(JID, PASSWORD, PORT)
+bot = JabberBot(JID, PASSWORD, PORT)
+
+bot.register_handler('message', message_handler)
+bot.start(open_bot_template)
+
+
+

+ 33 - 0
handlers/order_functions.py

@@ -0,0 +1,33 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+
+def send_message(order):
+    task_apply = {
+        'driver_id':None,
+        'apply':False,
+        'task_id':order.id
+    }
+    print(order.id)
+    
+    bot.proceed_status('driver_jabber',task_apply)
+    
+def find_jabber_acc():
+    pass
+#поиск пользователя в джаббер для далнейшей отправки
+    

+ 7 - 0
handlers/requirements.txt

@@ -0,0 +1,7 @@
+certifi==2022.12.7
+charset-normalizer==3.1.0
+idna==3.4
+requests==2.29.0
+six==1.16.0
+urllib3==1.26.15
+xmpppy==0.7.1

+ 128 - 0
handlers/st_request_assigned.py

@@ -0,0 +1,128 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="status_changer"
+
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["status_changer@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["numbers"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+# def message_handler(conn, mess):
+#     text = mess.getBody()#текст сообщения боту
+#     user = mess.getFrom()#отправитель сообщения
+#     if (str(user).split("/")[0]) in listen_to:
+#         # print (str(user).split("/")[0])
+#         if text is not None:
+#             orderObj = jsreq.jsonToOrder(text)
+#             tasklist.append(orderObj)
+#             bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def status_changer_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет ожидает\n")
+    time.sleep(period)
+
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет подождал и возвращен в очередь\n")
+
+def status_changer_process(ticket):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет в обработчике\n")
+    tickets_new=jsreq.requestGetTicket_user(token, config.API_URL+f"tickets/api/ticket_list/{ticket.id}")
+    # if ticket.id == 2103:
+    #     for ticket_new in tickets_new:
+    #         metaservice_admin(ticket_new,ticket.group)
+    if ticket.id == 2101:
+        for ticket_new in tickets_new:
+            company_status(ticket_new)
+    elif ticket.id == 2102:
+        for ticket_new in tickets_new:
+            company_status(ticket_new,ticket.group)
+    elif ticket.id =='':
+        print('should be soon')#дополнить по всем айди тикетов
+    # if ticket_new != []:
+    #     print(ticket_new)
+    #api/v1/platform/sharix-users/1/
+    
+    # bot.proceed_status(proceed_to[1], localtask)
+    # bot.bot_log(botname + " " + str(datetime.now()) + " " + "Тикет успешно обработан и отправлен на pending\n")
+
+
+def company_status(ticket_new):
+    if ticket_new.status == 141:#нужны доп проверки
+        answer=jsreq.change_status_company(token, config.API_URL+f"dbsynce/api/client/{ticket_new.created_by}/")
+        if answer!=200:
+            print(f'Ошибка{answer}')
+    else:   
+        print('Статус не ACCESS')
+
+# def company_status(ticket_new):
+#     if ticket_new.status == 141:#нужны доп проверки
+#         answer=jsreq.change_status_company(token, config.API_URL+f"dbsynce/api/client/{ticket_new.created_by}/",ticket_new.created_by)
+#         if answer!=200:
+#             print(f'Ошибка{answer}')
+#     else:   
+#         print('Статус не ACCESS')
+
+
+def metaservice_admin(ticket_new,group):
+    if ticket_new.status == 141:#нужны доп проверки
+        answer=jsreq.change_groups(token, config.API_URL+f"api/v1/platform/sharix-users/{ticket_new.created_by}/",group)
+        if answer!=200:
+            print(f'Ошибка{answer}')
+    else:   
+        print('Статус не ACCESS')
+
+
+def status_changer():
+    while True:
+        ticketlist=jsreq.requestGetList(token, config.API_URL+"tickets/api/ticket_list/")
+        for ticket in ticketlist:
+            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Тикет в очереди на обработке\n")
+            t1 = threading.Thread(target=status_changer_process, args=(ticket,))
+            t1.start()
+            t1.join()  # Ожидаем завершения обработки тикета
+        time.sleep(300)  # Обновляем ticketlist каждые 5 минут
+
+
+#Авторизация и запуск бота
+
+#пустой список
+ticketlist = []
+
+token = jsreq.requestGetToken(config.API_URL+"api/v1/auth/token/login/")
+# ticketlist=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/") ###Должна быть проверка между двумя
+
+# # print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+
+
+bot.start(status_changer)
+

+ 128 - 0
handlers/st_request_done.py

@@ -0,0 +1,128 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="status_changer"
+
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["status_changer@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["numbers"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+# def message_handler(conn, mess):
+#     text = mess.getBody()#текст сообщения боту
+#     user = mess.getFrom()#отправитель сообщения
+#     if (str(user).split("/")[0]) in listen_to:
+#         # print (str(user).split("/")[0])
+#         if text is not None:
+#             orderObj = jsreq.jsonToOrder(text)
+#             tasklist.append(orderObj)
+#             bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def status_changer_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет ожидает\n")
+    time.sleep(period)
+
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет подождал и возвращен в очередь\n")
+
+def status_changer_process(ticket):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет в обработчике\n")
+    tickets_new=jsreq.requestGetTicket_user(token, config.API_URL+f"tickets/api/ticket_list/{ticket.id}")
+    # if ticket.id == 2103:
+    #     for ticket_new in tickets_new:
+    #         metaservice_admin(ticket_new,ticket.group)
+    if ticket.id == 2101:
+        for ticket_new in tickets_new:
+            company_status(ticket_new)
+    elif ticket.id == 2102:
+        for ticket_new in tickets_new:
+            company_status(ticket_new,ticket.group)
+    elif ticket.id =='':
+        print('should be soon')#дополнить по всем айди тикетов
+    # if ticket_new != []:
+    #     print(ticket_new)
+    #api/v1/platform/sharix-users/1/
+    
+    # bot.proceed_status(proceed_to[1], localtask)
+    # bot.bot_log(botname + " " + str(datetime.now()) + " " + "Тикет успешно обработан и отправлен на pending\n")
+
+
+def company_status(ticket_new):
+    if ticket_new.status == 141:#нужны доп проверки
+        answer=jsreq.change_status_company(token, config.API_URL+f"dbsynce/api/client/{ticket_new.created_by}/")
+        if answer!=200:
+            print(f'Ошибка{answer}')
+    else:   
+        print('Статус не ACCESS')
+
+# def company_status(ticket_new):
+#     if ticket_new.status == 141:#нужны доп проверки
+#         answer=jsreq.change_status_company(token, config.API_URL+f"dbsynce/api/client/{ticket_new.created_by}/",ticket_new.created_by)
+#         if answer!=200:
+#             print(f'Ошибка{answer}')
+#     else:   
+#         print('Статус не ACCESS')
+
+
+def metaservice_admin(ticket_new,group):
+    if ticket_new.status == 141:#нужны доп проверки
+        answer=jsreq.change_groups(token, config.API_URL+f"api/v1/platform/sharix-users/{ticket_new.created_by}/",group)
+        if answer!=200:
+            print(f'Ошибка{answer}')
+    else:   
+        print('Статус не ACCESS')
+
+
+def status_changer():
+    while True:
+        ticketlist=jsreq.requestGetList(token, config.API_URL+"tickets/api/ticket_list/")
+        for ticket in ticketlist:
+            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Тикет в очереди на обработке\n")
+            t1 = threading.Thread(target=status_changer_process, args=(ticket,))
+            t1.start()
+            t1.join()  # Ожидаем завершения обработки тикета
+        time.sleep(300)  # Обновляем ticketlist каждые 5 минут
+
+
+#Авторизация и запуск бота
+
+#пустой список
+ticketlist = []
+
+token = jsreq.requestGetToken(config.API_URL+"api/v1/auth/token/login/")
+# ticketlist=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/") ###Должна быть проверка между двумя
+
+# # print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+
+
+bot.start(status_changer)
+

+ 98 - 0
handlers/st_request_new.py

@@ -0,0 +1,98 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="st_request_new"
+
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["st_request_new@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["numbers"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+# def message_handler(conn, mess):
+#     text = mess.getBody()#текст сообщения боту
+#     user = mess.getFrom()#отправитель сообщения
+#     if (str(user).split("/")[0]) in listen_to:
+#         # print (str(user).split("/")[0])
+#         if text is not None:
+#             orderObj = jsreq.jsonToOrder(text)
+#             tasklist.append(orderObj)
+#             bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+
+
+def status_new_process(ticket):
+    
+    tickets_new=jsreq.requestGetTicket_user(token, config.API_URL+f"tickets/api/ticket_list/{ticket.id}")
+    for ticket_new in tickets_new:
+        send_to_user(ticket_new)
+
+
+def send_to_user(ticket_new):
+    user = jsreq.requestGetListUser(token)
+    print(user.json()[0]['id'])
+    headers = {'Authorization': f'Token {token}'}
+    url =  config.API_URL+f"tickets/api/ticket_list/{ticket_new.id}"
+    if ticket_new.assigned_to == None:
+        ticket_new.assigned_to = user.json()[0]['id']
+        user = 'test@ej.sharix-app.org' 
+        print({'id':ticket_new.id, 'assigned_to' :ticket_new.assigned_to })
+        response = requests.put(url, json={'id':ticket_new.id, 'assigned_to' :ticket_new.assigned_to }, headers=headers)
+        print(response)
+        if response:
+            bot.send_notification(user,ticket_new)   
+
+
+
+def status_new():
+    while True:
+        ticketlist=jsreq.requestGetList(token, config.API_URL+"tickets/api/ticket_list/")
+        for ticket in ticketlist:
+            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Тикет отправлен в очередь на обработку\n")
+            t1 = threading.Thread(target=status_new_process, args=(ticket,))
+            t1.start()
+            t1.join()  # Ожидаем завершения обработки тикета
+        time.sleep(300)  # Обновляем ticketlist каждые 5 минут
+
+
+#Авторизация и запуск бота
+
+#пустой список
+ticketlist = []
+
+token = jsreq.requestGetToken(config.API_URL+"api/v1/auth/token/login/")
+# ticketlist=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/") ###Должна быть проверка между двумя
+
+# # print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+
+
+bot.start(status_new)
+

+ 128 - 0
handlers/st_request_wontfix.py

@@ -0,0 +1,128 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="st_request_wontfix"
+
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["st_request_wontfix@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["numbers"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+# def message_handler(conn, mess):
+#     text = mess.getBody()#текст сообщения боту
+#     user = mess.getFrom()#отправитель сообщения
+#     if (str(user).split("/")[0]) in listen_to:
+#         # print (str(user).split("/")[0])
+#         if text is not None:
+#             orderObj = jsreq.jsonToOrder(text)
+#             tasklist.append(orderObj)
+#             bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def status_changer_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет ожидает\n")
+    time.sleep(period)
+
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет подождал и возвращен в очередь\n")
+
+def status_changer_process(ticket):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет в обработчике\n")
+    tickets_new=jsreq.requestGetTicket_user(token, config.API_URL+f"tickets/api/ticket_list/{ticket.id}")
+    # if ticket.id == 2103:
+    #     for ticket_new in tickets_new:
+    #         metaservice_admin(ticket_new,ticket.group)
+    if ticket.id == 2101:
+        for ticket_new in tickets_new:
+            company_status(ticket_new)
+    elif ticket.id == 2102:
+        for ticket_new in tickets_new:
+            company_status(ticket_new,ticket.group)
+    elif ticket.id =='':
+        print('should be soon')#дополнить по всем айди тикетов
+    # if ticket_new != []:
+    #     print(ticket_new)
+    #api/v1/platform/sharix-users/1/
+    
+    # bot.proceed_status(proceed_to[1], localtask)
+    # bot.bot_log(botname + " " + str(datetime.now()) + " " + "Тикет успешно обработан и отправлен на pending\n")
+
+
+def company_status(ticket_new):
+    if ticket_new.status == 141:#нужны доп проверки
+        answer=jsreq.change_status_company(token, config.API_URL+f"dbsynce/api/client/{ticket_new.created_by}/")
+        if answer!=200:
+            print(f'Ошибка{answer}')
+    else:   
+        print('Статус не ACCESS')
+
+# def company_status(ticket_new):
+#     if ticket_new.status == 141:#нужны доп проверки
+#         answer=jsreq.change_status_company(token, config.API_URL+f"dbsynce/api/client/{ticket_new.created_by}/",ticket_new.created_by)
+#         if answer!=200:
+#             print(f'Ошибка{answer}')
+#     else:   
+#         print('Статус не ACCESS')
+
+
+def metaservice_admin(ticket_new,group):
+    if ticket_new.status == 141:#нужны доп проверки
+        answer=jsreq.change_groups(token, config.API_URL+f"api/v1/platform/sharix-users/{ticket_new.created_by}/",group)
+        if answer!=200:
+            print(f'Ошибка{answer}')
+    else:   
+        print('Статус не ACCESS')
+
+
+def status_changer():
+    while True:
+        ticketlist=jsreq.requestGetList(token, config.API_URL+"tickets/api/ticket_list/")
+        for ticket in ticketlist:
+            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Тикет в очереди на обработке\n")
+            t1 = threading.Thread(target=status_changer_process, args=(ticket,))
+            t1.start()
+            t1.join()  # Ожидаем завершения обработки тикета
+        time.sleep(300)  # Обновляем ticketlist каждые 5 минут
+
+
+#Авторизация и запуск бота
+
+#пустой список
+ticketlist = []
+
+token = jsreq.requestGetToken(config.API_URL+"api/v1/auth/token/login/")
+# ticketlist=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/") ###Должна быть проверка между двумя
+
+# # print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+
+
+bot.start(status_changer)
+

+ 10 - 0
handlers/starter.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+python3 open_servicerequest_booked.py
+python3 open_servicerequest_assigned.py
+python3 open_servicerequest_pending.py
+python3 open_servicerequest_accepted.py
+python3 open_servicerequest_process.py
+python3 open_servicerequest_done.py
+
+

+ 103 - 0
handlers/status_changer.py

@@ -0,0 +1,103 @@
+import requests
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+import hashlib
+from datetime import datetime
+
+import time
+import threading
+
+#test
+import jsonAndRequest as jsreq
+
+global tasklist
+
+botname="status_changer"
+
+JID=botname+"@"+config.JSERVER
+PORT=config.PORT
+
+PASSWORD=hashlib.md5((botname+config.PASSWORD).encode('utf-8')).hexdigest()
+
+
+#таким образом хранится список jid, от которых можно получать сообщения этому боту
+listen_to=["status_changer@ej.sharix-app.org"]
+
+#тут хранится список jid, кому бот может отправлять сообщения в результате обработки заявки
+proceed_to=["numbers"]
+
+#максимальное значение попыток обработать заказ
+idle_value=10
+
+# обработчик входящих сообщений
+# def message_handler(conn, mess):
+#     text = mess.getBody()#текст сообщения боту
+#     user = mess.getFrom()#отправитель сообщения
+#     if (str(user).split("/")[0]) in listen_to:
+#         # print (str(user).split("/")[0])
+#         if text is not None:
+#             orderObj = jsreq.jsonToOrder(text)
+#             tasklist.append(orderObj)
+#             bot.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+def status_changer_wait(period,localtask):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет ожидает\n")
+    time.sleep(period)
+
+    bot.proceed_status(proceed_to[0],localtask)
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет подождал и возвращен в очередь\n")
+
+def status_changer_process(ticket):
+    bot.bot_log(botname+" "+str(datetime.now())+" "+"Тикет в обработчике\n")
+    tickets_new=jsreq.requestGetTicket_user(token, config.API_URL+f"tickets/api/ticket_list/{ticket.id}")
+    if ticket.id == 2103:
+        for ticket_new in tickets_new:
+            metaservice_admin(ticket_new,ticket.group)
+    elif ticket.id =='':
+        print('should be soon')#дополнить по всем айди тикетов
+    # if ticket_new != []:
+    #     print(ticket_new)
+    #api/v1/platform/sharix-users/1/
+    
+    # bot.proceed_status(proceed_to[1], localtask)
+    # bot.bot_log(botname + " " + str(datetime.now()) + " " + "Тикет успешно обработан и отправлен на pending\n")
+
+def metaservice_admin(ticket_new,group):
+    if ticket_new.status == 141:#нужны доп проверки
+        answer=jsreq.change_groups(token, config.API_URL+f"api/v1/platform/sharix-users/{ticket_new.created_by}/",group)
+        if answer!=200:
+            print(f'Ошибка{answer}')
+    else:
+        print('Статус не ACCESS')
+
+def status_changer():
+    while True:
+        ticketlist=jsreq.requestGetList(token, config.API_URL+"tickets/api/ticket_list/")
+        for ticket in ticketlist:
+            bot.bot_log(botname + " " + datetime.now().strftime('%Y-%m-%d') + " "+ "Тикет в очереди на обработке\n")
+            t1 = threading.Thread(target=status_changer_process, args=(ticket,))
+            t1.start()
+            t1.join()  # Ожидаем завершения обработки тикета
+        time.sleep(300)  # Обновляем ticketlist каждые 5 минут
+
+
+#Авторизация и запуск бота
+
+#пустой список
+ticketlist = []
+
+token = jsreq.requestGetToken(config.API_URL+"api/v1/auth/token/login/")
+# ticketlist=jsreq.requestGetList(token, config.API_URL+"/dbsynce/api/orders/") ###Должна быть проверка между двумя
+
+# # print (len(tasklist))
+
+bot = JabberBot(JID, PASSWORD, PORT)
+
+
+
+bot.start(status_changer)
+

+ 55 - 0
handlers/status_handlers.py

@@ -0,0 +1,55 @@
+import xmpp
+from xmpp import cli
+import config
+from BotClass import JabberBot
+import json
+#раскомментировать, когда перейдем на разные пароли
+from datetime import datetime
+
+import time
+
+#test
+import jsonAndRequest as jsreq
+
+
+
+def proceed_status(self, recipient, ticket):
+        #тут могут быть различные проверки дополнительные, а так вообще эта функция нужна для передачи заявки на обработку следующему
+        jsonTicket = json.dumps(ticket.__dict__)
+        self.conn.send(xmpp.Message(recipient, jsonTicket))
+        self.bot_log("Message sent successfully"+" "+recipient+" "+jsonTicket)
+
+# обработчик входящих сообщений
+def message_handler(self, conn, mess):
+    text = mess.getBody()#текст сообщения боту
+    user = mess.getFrom()#отправитель сообщения
+   
+    #проверка на возможность получения сообщений от данного обработчика
+    print (str(user).split("/")[0])
+    if (str(user).split("/")[0]) in listen_to:
+        print(text)
+        print(mess)
+
+        if text is not None:
+            orderObj = jsreq.jsonToOrderTicket(text)
+            print (orderObj)
+            tasklist.append(orderObj)
+            self.bot_log(str(datetime.now())+" Поступивший заказ успешно добавлен в очередь обработки\n")
+
+#TODO - для обработчиков Ticket скорее надо будет функции вынести в отдельную библиотеку, они типовые же
+def pending_wait(self, period, localtask, proceed_to):
+    self.bot_log(botname+" "+str(datetime.now())+" "+"Заказ ожидает пользовательской реакции\n")
+    time.sleep(period)
+    
+    #ВАЖНО! НАДО ВСТАВИТЬ ИЗМЕНЕНИЕ СТАТУСА ЧЕРЕЗ API
+
+    #обязательно данный обработчик должен заканчиваться передачей заказа куда-то на обработку дальше - обратно или другому, иначе оно потеряется
+    self.proceed_status(proceed_to,localtask)
+    self.bot_log(botname+" "+str(datetime.now())+" "+"Заказ отправлен в очередь "+proceed_to+"\n")
+
+def order_close(self, localtask):
+
+    #тут надо вызов API с удалением
+    self.bot_log(botname+" "+str(datetime.now())+" "+"Заказ удален\n")
+
+

+ 593 - 593
license ru.md

@@ -1,594 +1,594 @@
-This is an unofficial translation of the GNU General Public License into Russian
-language. It was not published by the Free Software Foundation, and does not
-legally state the distribution terms for software that uses the GNU GPL—only the
-original English text of the GNU GPL does that. However, we hope that this
-translation will help language speakers understand the GNU GPL better.
-You may publish this translation, modified or unmodified, only under the terms
-at http://www.gnu.org/licenses/translations.html.
-Это неофициальный перевод GNU General Public License на русский язык. Он был
-опубликован не Фондом свободного программного обеспечения и не содержит условий
-распространения программ, которые используют GNU GPL -- для этого пригоден
-только ее исходный английский текст. Тем не менее мы надеемся, что этот перевод
-поможет лучше понять ее текст.
-Вы можете распространять перевод, с изменениями или без, только с соблюдением
-условий, описанных по адресу: http://www.gnu.org/licenses/translations.html.
-Генеральная публичная лицензия GNU. Редакция 3,
-29 июня 2007 г.
-Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>. Перевод:
-Павел Протасов <pvphome@gmail.com>, 2016 г. Разрешается свободно копировать и
-распространять текст настоящей Лицензии, запрещается вносить в него изменения.
-Введение
-Генеральная публичная лицензия GNU (GNU GPL) -- свободная лицензия для
-программного обеспечения и произведений других видов, разрешающая свободное
-создание производных произведений, используемых на условиях GNU GPL.
-Лицензии на большинство программ и других прикладных работ составлены так, чтобы
-лишить Вас права распространять и изменять такие произведения. В
-противоположность этому, Генеральная публичная лицензия GNU предназначена для
-того, чтобы предоставить Вам право распространять и изменять все версии
-программы, чтобы она оставалась свободным программным обеспечением для всех
-пользователей. Мы, Фонд свободного программного обеспечения, используем
-Генеральную публичную лицензию GNU для большей части нашего программного
-обеспечения; это относится и к другим произведениям, авторы которых сделали то
-же самое. Вы также можете применить ее к своим программам.
-Когда мы говорим о свободном программном обеспечении, мы имеем в виду свободу
-использования, а не бесплатность. Наши Генеральные публичные лицензии составлены
-для того, чтобы убедиться, что у Вас есть право распространять копии свободного
-ПО (и взимать плату за них, если Вы хотите), что Вы получаете исходные тексты
-или можете получить их, если захотите, что Вы можете изменять программное
-обеспечение или использовать его части в новых свободных программах, и Вы знаете
-о своем праве делать все это.
-Чтобы защитить Ваши права, нам нужно запретить другим отрицать их или просить
-Вас отказаться от них. Таким образом, если Вы распространяете копии программного
-обеспечения или изменяете его, у Вас появляются определенные обязанности: Вы
-должны уважать свободу других.
-Например, если Вы распространяете копии такой программы, будь то бесплатно или
-за вознаграждение, Вы должны передать получателям те же права, которые получили.
-Вы должны убедиться, что они также получили или могут получить исходный текст.
-Также Вы должны ознакомить их с этими условиями, чтобы они знали свои права.
-Разработчики, использующие GNU GPL, защищают Ваши права при помощи следующих
-мер: (1) закрепляют авторское право на программное обеспечение, и (2) предлагают
-Вам принять условия настоящей Лицензии, закрепляющей Ваше право на создание
-копий, распространение и (или) внесение изменений в программное обеспечение.
-Для защиты разработчиков и авторов GPL в явной форме говорит об отсутствии
-гарантий на свободное программное обеспечение. В интересах и пользователей и
-авторов GPL требует, чтобы к измененным версиям прилагалось описание изменений,
-так чтобы связанные с ними проблемы не могли быть ошибочно приписаны авторам
-предыдущих версий.
-Некоторые устройства спроектированы так, чтобы запретить пользователям установку
-или запуск на них измененных версий программного обеспечения, разрешив это
-только производителю. Это в корне несовместимо с целью защиты права
-пользователей на изменение программного обеспечения. Как правило, такие
-злоупотребления происходят в области потребительских продуктов, то есть там, где
-это особенно неприемлемо. Поэтому мы разработали эту редакцию GPL, чтобы пресечь
-подобную практику в этой сфере. Если подобные проблемы возникнут в других
-сферах, мы готовы расширить эти положения на них в будущих редакциях GPL,
-настолько, насколько это нужно для того, чтобы защитить свободу пользователей.
-И наконец, каждой программе постоянно угрожают патенты на программное
-обеспечение. Государства не должны допускать ограничения патентами разработки и
-использования программного обеспечения на компьютерах общего назначения, однако,
-поскольку они это допускают, мы хотели бы избежать еще одной опасности,
-состоящей в том, что в результате патентования решений, используемых в свободной
-программе, она перестанет удовлетворять критериям свободного программного
-обеспечения. Чтобы предотвратить это, GPL гарантирует, что патентование не может
-быть использовано для того, чтобы сделать программу несвободной.
-Детальные определения используемых терминов и описание условий копирования,
-распространения и внесения изменений приведены ниже.
-ТЕРМИНЫ И УСЛОВИЯ
-0. Определения
-"Настоящая Лицензия" -- редакция 3 Генеральной публичной лицензии GNU.
-Под "Авторским правом" также понимаются законы, сходные с авторско-правовыми,
-которые применяются к другим видам работ, например, к топологиям микросхем.
-Термином "Программа" обозначается любое охраноспособное произведение,
-используемое в соответствии с настоящей Лицензией. Лицензиат именуется "Вы".
-"Лицензиаты" и "получатели" могут быть как физическими лицами, так и
-организациями.
-"Внесение изменений" в произведение означает копирование или адаптацию
-произведения целиком или в части, способом, требующим разрешения
-правообладателя, за исключением изготовления его точной копии. Получившееся в
-результате произведение называется "измененной версией" предыдущего произведения
-или произведением, "основанным на" более ранней работе.
-Термином "Лицензионное произведение" обозначается неизмененная Программа или
-произведение, основанное на Программе.
-"Распространение" произведения означает совершение с ним действий, которые при
-отсутствии разрешения сделают Вас прямо или косвенно ответственным за нарушение
-действующего закона об авторском праве, за исключением запуска на компьютере или
-изменения копии, созданной в личных целях. Распространение включает в себя
-копирование, раздачу копий (с изменениями или без них), доведение до всеобщего
-сведения, а в некоторых странах -- и другие действия.
-"Передача" произведения означает любой вид распространения, который позволяет
-другим лицам создавать или получать копии произведения. Обычное взаимодействие с
-пользователем через компьютерную сеть без создания копии передачей не является.
-В диалоговом режиме пользователю должна быть показана "Информация об авторском
-праве", достаточная для того, чтобы (1) обеспечить отображение соответствующего
-уведомления об авторских правах и (2) сообщить пользователю о том, что ему не
-предоставляется никакой гарантии на произведение (за исключением фактически
-предоставленных гарантий), о том, что лицензиаты могут передавать произведение
-на условиях, описанных в настоящей Лицензии, а также о том, как ознакомиться с
-текстом настоящей Лицензии. Если интерфейс предоставляет собой список
-пользовательских команд или настроек, наподобие меню, это требование считается
-выполненным при наличии явно выделенного пункта в таком меню.
-1. Исходный текст
-Под "Исходным текстом" понимается произведение в форме, которая более всего
-подходит для внесения в него изменений. "Объектным кодом" называется
-произведение в любой иной форме.
-"Стандартный интерфейс" -- интерфейс, который либо является общепринятым
-стандартом, введенным общепризнанным органом по стандартизации, либо, в случае
-интерфейсов, характерных для конкретного языка программирования -- тот, который
-широко используется разработчиками, пишущими программы на этом языке.
-"Системные библиотеки" исполняемого произведения включают в себя то, что не
-относится к произведению в целом и при этом (a) входит в обычный комплект
-Основного компонента, но при этом не является его частью и (b) служит только для
-обеспечения работы с этим Основным компонентом или реализации Стандартного
-интерфейса, для которого существует общедоступная реализация, опубликованная в
-виде исходного текста. "Основным компонентом" в данном контексте назван главный
-существенный компонент (ядро, оконная система и т.д.) определенной операционной
-системы (если она используется), под управлением которой функционирует
-исполняемое произведение, либо компилятор, используемый для создания
-произведения или интерпретатор объектного кода, используемый для его запуска.
-"Полный исходный текст" для произведения в форме объектного кода -- весь
-исходный текст, необходимый для создания, установки и (для исполняемого
-произведения) функционирования объектного кода, а также модификации
-произведения, включая сценарии, контролирующие эти действия. Однако он не
-включает в себя Системные библиотеки, необходимые для функционирования
-произведения, инструменты общего назначения или общедоступные свободные
-программы, которые используются в неизменном виде для выполнения этих действий,
-но не являются частью произведения. Полный исходный текст включает в себя,
-например, файлы описания интерфейса, прилагаемые к файлам исходного текста
-произведения, а также исходные тексты общих библиотек и динамически связанных
-подпрограмм, которые требуются для функционирования произведения, например для
-прямой передачи данных или передачи управления потоками между этими
-подпрограммами и другими частями произведения.
-Полный исходный текст не включает в себя то, что пользователи могут получить
-автоматически из других частей Полного исходного текста.
-Полным исходным текстом для произведения в форме исходных текстов является само
-это произведение.
-2. Основные права
-Все права, предоставленные на основании настоящей Лицензии, действуют в течение
-срока действия авторских прав на Программу и не могут быть отозваны при условии,
-что сформулированные в ней условия соблюдены. Настоящая Лицензия однозначно
-подтверждает Ваши неограниченные права на запуск неизмененной Программы.
-Результаты функционирования Лицензионного произведения распространяются на
-условиях настоящей Лицензии в случае, если они, учитывая их содержание, являются
-частью Лицензионного произведения. Настоящая Лицензия подтверждает Ваши права на
-свободное использование произведения или другие аналогичные полномочия,
-предусмотренные действующим законодательством об авторском праве.
-Если Вы не осуществляете обычную передачу Лицензионного произведения, то можете
-как угодно создавать, запускать и распространять его копии до тех пор, пока
-Лицензия сохраняет силу. Вы можете передавать Лицензионные произведения третьим
-лицам исключительно для того, чтобы они внесли в них изменения для Вас или
-предоставили Вам возможность их запуска, при условии, что Вы соглашаетесь с
-условиями настоящей Лицензии при передаче всех материалов, авторскими правами на
-которые Вы не обладаете. Лица, создающие или запускающие Лицензионные
-произведения для Вас, должны делать это исключительно от Вашего имени, под Вашим
-руководством и контролем, на условиях, которые запрещают им создание без Вашей
-санкции каких-либо копий материалов, на которые Вы обладаете авторским правом.
-Любая другая передача разрешается исключительно при соблюдении описанных ниже
-условий. Сублицензирование не допускается; раздел 10 делает его не нужным.
-3. Защита прав пользователей от законов, запрещающих обход
-технических средств
-Ни одно Лицензионное произведение не должно считаться содержащим эффективные
-технические средства, удовлетворяющие требованиям любого действующего закона,
-принятого во исполнение обязательств, предусмотренных статьей 11 Договора ВОИС
-по авторскому праву от 20 декабря 1996 года или аналогичных законов, запрещающих
-или ограничивающих обход таких технических средств.
-При передаче Лицензионного произведения Вы отказываетесь от всех предоставляемых
-законом полномочий по запрету обхода технических средств, используемых авторами
-в связи с осуществлением их прав, признавая, что такой обход находится в рамках
-осуществления прав на использование Лицензионного произведения, предоставленных
-настоящей Лицензией; также Вы отказываетесь от любых попыток ограничить
-функционирование произведения или внесение в него изменений, направленных на
-реализацию предоставленных Вам законом прав на запрет пользователю обхода
-технических средств.
-4. Передача не измененных копий
-Вы можете передавать точные копии исходных текстов Программы в том виде, в
-котором Вы их получили, на любом носителе, при условии, что Вы прилагаете к
-каждой копии соответствующее уведомление об авторских правах способом,
-обеспечивающим ознакомление с ним пользователя; сохраняете все уведомления о
-том, что к тексту применима настоящая Лицензия и любые ограничения, добавленные
-в соответствии с разделом 7; сохраняете все уведомления об отсутствии каких-либо
-гарантий; предоставляете всем получателям вместе с Программой копию настоящей
-Лицензии.
-Вы можете установить любую цену за каждую копию, которую Вы передаете, или
-распространять копии бесплатно; также Вы можете предложить поддержку или
-гарантию за отдельную плату.
-5. Передача измененных исходных текстов
-Вы можете передавать исходный текст произведения, основанного на Программе, или
-изменений, необходимых для того, чтобы получить его из Программы, на условиях,
-описанных в разделе 4, при соблюдении следующих условий:
-а) Произведение должно содержать уведомления о произведенных Вами изменениях с
-указанием их даты, сделанные способом, обеспечивающим ознакомление с ними
-пользователя.
-b) Произведение должно содержать уведомление о том, что оно распространяется на
-условиях настоящей Лицензии, а также об условиях, добавленных в соответствии с
-разделом 7, сделанное способом, обеспечивающим ознакомление с ним пользователя.
-Данное требование имеет приоритет над требованиями раздела 4 "оставлять
-нетронутыми все уведомления".
-c) Вы должны передать на условиях настоящей Лицензии всю работу целиком любому
-лицу, которое приобретает копию. Таким образом, настоящая Лицензия вместе с
-любыми применимыми условиями раздела 7 будет применяться к произведению в целом
-и всем его частям, независимо от их комплектности. Настоящая Лицензия не дает
-права на лицензирование произведения на любых других условиях, но это не лишает
-законной силы такое разрешение, если Вы получили его отдельно.
-d) Если произведение имеет интерактивные пользовательские интерфейсы, каждый из
-них должен отображать Информацию об авторском праве; однако, если Программа
-имеет пользовательские интерфейсы, которые не отображают информацию об авторском
-праве, от Вашего произведения этого также не требуется.
-Включение Лицензионного произведения в подборку на разделе хранения данных или
-на носителе, на котором распространяется произведение, вместе с другими
-отдельными самостоятельными произведениями, которые по своей природе не являются
-переработкой Лицензионного произведения и не объединены с ним, например, в
-программный комплекс, называется "набором", если авторские права на подборку не
-используются для ограничения доступа к ней или законных прав ее пользователей
-сверх того, что предусматривают лицензии на отдельные произведения. Включение
-Лицензионного произведения в набор не влечет применения положений настоящей
-Лицензии к остальным его частям.
-6. Передача произведения в формах, не относящихся к исходному
-тексту
-Вы можете передавать Лицензионное произведение в виде объектного кода в
-соответствии с положениями разделов 4 и 5, при условии, что Вы также передаете
-машиночитаемый Полный исходный текст в соответствии с условиями настоящей
-Лицензии, одним из следующих способов:
-a) Передавая объектный код или содержащий его материальный продукт (включая
-носитель, на котором распространяется произведение), с приложением Полного
-исходного текста на материальном носителе, обычно используемом для обмена
-программным обеспечением.
-b) Передавая объектный код или содержащий его материальный продукт (включая
-носитель, на котором распространяется произведение), с письменным предложением,
-действительным в течение не менее трех лет либо до тех пор, пока Вы
-предоставляете запасные части или поддержку для данного продукта, о передаче
-любому обладателю объектного кода (1) копии Полного исходного текста для всего
-программного обеспечения, содержащегося в продукте, на которое распространяется
-действие настоящей Лицензии, на физическом носителе, обычно используемом для
-обмена программным обеспечением, по цене, не превышающей разумных затрат на
-передачу копии, или (2) доступа к Полному исходному тексту с возможностью его
-копирования с сетевого сервера без взимания платы.
-c) Передавая отдельные копии объектного кода с письменной копией предложения о
-предоставлении Полного исходного текста. Этот вариант допускается только в
-отдельных случаях при распространении без извлечения прибыли, и только если Вы
-получили объектный код с таким предложением в соответствии с пунктом 6b.
-d) Передавая объектный код посредством предоставления доступа к нему по
-определенному адресу (бесплатно или за дополнительную плату), и предлагая
-эквивалентный доступ к Полному исходному тексту таким же способом по тому же
-адресу без какой-либо дополнительной оплаты. От Вас не требуется принуждать
-получателей копировать Полный исходный текст вместе с объектным кодом. Если
-объектный код размещен на сетевом сервере, Полный исходный текст может
-находиться на другом сервере (управляемом Вами или третьим лицом), который
-предоставляет аналогичную возможность копирования; при этом Вы должны четко
-указать рядом с объектным кодом способ получения Полного исходного текста.
-Независимо от того, на каком сервере расположен Полный исходный текст, Вы
-обязаны убедиться в том, что он будет распространяться в течение времени,
-необходимого для соблюдения этих требований.
-e) Передавая объектный код с использованием одноранговой (пиринговой) сети, при
-условии информирования других пользователей сети о том, где можно бесплатно
-получить объектный код и Полный исходный текст произведения способом, описанным
-в пункте 6d.
-Не нужно включать в передаваемый объектный код его отделимые части, исходные
-тексты которых не входят в состав Полного исходного текста, такие как Системные
-библиотеки.
-"Потребительский товар" это либо (1) "товар, предназначенный для личных нужд",
-под которым понимается любое материальное личное имущество, которое обычно
-используется для личных, семейных или домашних целей, или (2) что-либо
-спроектированное или продающееся для использования в жилище. При определении
-того, предназначен ли товар для личных нужд, сомнения должны толковаться в
-пользу положительного ответа на этот вопрос. Применительно к конкретному товару,
-используемому конкретным пользователем, под выражением "обычно используется"
-имеется в виду способ, которым данный вид товаров преимущественно или как
-правило используется, независимо от статуса конкретного пользователя или
-способа, которым конкретный пользователь использует, предполагает или будет
-использовать товар. Товар относится к предназначенным для личных нужд независимо
-от того, насколько часто он используется в коммерческой деятельности,
-промышленности или иной сфере, не относящейся к личным нуждам, за исключением
-случая, когда использование в этой сфере представляет собой единственный
-основной способ использования такого товара.
-"Информация, необходимая для установки" Потребительского товара -- любые методы,
-процедуры, сведения, необходимые для авторизации, или другая информация,
-необходимая для установки и запуска в Потребительском товаре измененных версий
-Лицензионного произведения, полученных при изменении Полного исходного текста.
-Данная информация должна быть достаточной для того, чтобы обеспечить возможность
-внесения в исходный текст изменений, не приводящих к ограничению или нарушению
-его дальнейшей работоспособности.
-Если вместе с Потребительским товаром или специально для использования в нем Вы
-передаете произведение в виде объектного кода на условиях, описанных в данном
-разделе, и такая передача является частью сделки, по которой право владения и
-пользования Потребительским товаром переходит к получателю пожизненно или на
-определенный срок (независимо от признаков сделки), Полный исходный текст,
-передаваемый согласно данному разделу, должен сопровождаться Информацией,
-необходимой для установки. Но это требование не применяется, если ни Вы, ни
-какое-либо третье лицо не сохраняет за собой возможности установки измененного
-объектного кода на Потребительский товар (например, произведение было
-установлено в постоянную память).
-Требование о предоставлении Информации, необходимой для установки, не включает в
-себя требование продолжения оказания услуг по поддержке, предоставления гарантии
-или обновлений для произведения, которое было изменено или установлено
-получателем, либо для Потребительского товара, в котором оно было изменено или
-на который оно было установлено. В доступе к сети может быть отказано, если само
-внесение изменений существенно и негативно влияет на работу сети, нарушает
-правила обмена данными или не поддерживает протоколы для обмена данными по сети.
-Передаваемый в соответствии с данным разделом Полный исходный текст и
-предоставленная Информация, необходимая для установки, должны быть записаны в
-формате, который имеет общедоступное описание (и общедоступную реализацию,
-опубликованную в форме исходного текста) и не должны требовать никаких
-специальных паролей или ключей для распаковки, чтения или копирования.
-7. Дополнительные условия
-"Дополнительными разрешениями" называются условия, которые дополняют условия
-настоящей Лицензии, вводя исключения из одного или нескольких ее положений.
-Дополнительные разрешения, которые применимы ко всей Программе, должны
-рассматриваться как часть настоящей Лицензии, в той степени, в которой они
-соответствуют действующему законодательству. Если дополнительные разрешения
-применяются только к части Программы, эта часть может быть использована отдельно
-на измененных условиях, но вся Программа продолжает использоваться на условиях
-настоящей Лицензии без учета дополнительных разрешений.
-Когда Вы передаете копию Лицензионного произведения, Вы можете по своему
-усмотрению исключить любые дополнительные разрешения, примененные к этой копии
-или к любой ее части. (Для дополнительных разрешений может быть заявлено
-требование об их удалении в определенных случаях, когда Вы вносите изменения в
-произведение.) Вы можете добавлять дополнительные разрешения к добавленным Вами
-в Лицензионное произведение материалам, на которые Вы обладаете авторскими
-правами или правом выдачи соответствующего разрешения.
-Независимо от любых других положений настоящей Лицензии, Вы можете дополнить ее
-положения следующими условиями, относящимися к материалу, добавленному к
-Лицензионному произведению (если это разрешено обладателями авторских прав на
-материал):
-a) отказом от гарантий или ограничением ответственности, отличающимися от тех,
-что описаны в разделах 15 и 16 настоящей Лицензии; либо
-b) требованием сохранения соответствующей информации о правах или об авторстве
-материала, или включения ее в Информацию об авторском праве, отображаемую
-содержащим его произведением; либо
-c) запретом на искажение информации об источнике происхождения материала или
-требованием того, чтобы измененные версии такого материала содержали корректную
-отметку об отличиях от исходной версии; либо
-d) ограничением использования в целях рекламы имен лицензиаров или авторов
-материала; либо
-e) отказом от предоставления прав на использование в качестве товарных знаков
-некоторых торговых наименований, товарных знаков или знаков обслуживания; либо
-f) требованием от каждого, кто по договору передает материал (или его измененные
-версии), предоставления компенсации лицензиарам и авторам материала в виде
-принятия на себя любой ответственности, которую этот договор налагает на
-лицензиаров и авторов.
-Все остальные ограничивающие дополнительные условия считаются "дополнительными
-запретами" по смыслу раздела 10. Если программа, которую Вы получили, или любая
-ее часть содержит уведомление о том, что наряду с настоящей Лицензией ее
-использование регулируется условием, относящимся к дополнительным запретам, Вы
-можете удалить такое условие. Если лицензия содержит дополнительный запрет, но
-допускает лицензирование на измененных условиях или передачу в соответствии с
-настоящей Лицензией, Вы можете добавить к Лицензионному произведению материал,
-используемый на условиях такой лицензии, в том случае, если дополнительный
-запрет не сохраняется при таком изменении условий лицензии или передаче.
-Если Вы добавляете условия для использования Лицензионного произведения в
-соответствии с настоящим разделом, Вы должны поместить в соответствующих файлах
-исходного текста уведомление о том, что к этим файлам применяются дополнительные
-условия, или указание на то, как ознакомиться с соответствующими условиями.
-Дополнительные разрешающие или ограничивающие условия могут быть сформулированы
-в виде отдельной лицензии или зафиксированы как исключения; вышеуказанные
-требования применяются в любом случае.
-8. Прекращение действия
-Вы не можете распространять Лицензионное произведение или вносить в него
-изменения на условиях, отличающихся от явно оговоренных в настоящей Лицензии.
-Любая попытка распространения или внесения изменений на иных условиях является
-ничтожной и автоматически прекращает Ваши права, полученные по настоящей
-Лицензии (включая лицензию на любые патенты, предоставленные согласно третьему
-пункту раздела 11).
-Тем не менее если Вы прекращаете нарушение настоящей Лицензии, Ваши права,
-полученные от конкретного правообладателя, восстанавливаются (а) временно, до
-тех пор пока правообладатель явно и окончательно не прекратит действие Ваших
-прав, и (б) навсегда, если правообладатель не уведомит Вас о нарушении с помощью
-надлежащих средств в течение 60 дней после прекращения нарушений.
-Кроме того, Ваши права, полученные от конкретного правообладателя,
-восстанавливаются навсегда, если правообладатель впервые любым подходящим
-способом уведомляет Вас о нарушении настоящей Лицензии на свое произведение (для
-любого произведения) и Вы устраняете нарушение в течение 30 дней после получения
-уведомления.
-Прекращение Ваших прав, описанное в настоящем разделе, не прекращает действие
-лицензий лиц, которые получили от Вас копии произведения или права,
-предоставляемые настоящей Лицензией. Если Ваши права были прекращены навсегда и
-не восстановлены, Вы не можете вновь получить право на тот же материал на
-условиях, описанных в разделе 10.
-9. Акцепт не требуется для получения копий
-Вы не обязаны принимать условия настоящей Лицензии для того, чтобы получить или
-запустить копию Программы. Случайное распространение Лицензионного произведения,
-происходящее вследствие использования для получения его копии передачи по
-одноранговой (пиринговой) сети, также не требует принятия этих условий. Тем не
-менее только настоящая Лицензия дает Вам право распространять или изменять любое
-Лицензионное произведение. Если Вы не приняли условия настоящей Лицензии, такие
-действия будут нарушением авторского права. Поэтому изменяя или распространяя
-Лицензионное произведение, Вы выражаете согласие с условиями настоящей Лицензии.
-10. Автоматическое получение прав последующими получателями
-Каждый раз, когда Вы передаете Лицензионное произведение, получатель
-автоматически получает от его лицензиара право запускать, изменять и
-распространять это произведение при условии соблюдения настоящей Лицензии. Вы не
-несете ответственности за соблюдение третьими лицами условий настоящей Лицензии.
-"Реорганизацией" называются действия, в результате которых передается управление
-организацией или значительная часть ее активов, а также происходит разделение
-или слияние организаций. Если распространение Лицензионного произведения
-является результатом реорганизации, каждая из сторон сделки, получающая копию
-произведения, также получает все права на произведение, которые предшествующее
-юридическое лицо имело или могло предоставить согласно предыдущему абзацу, а
-также право на владение Полным исходным текстом произведения от предшественника,
-осуществляемое в его интересах, если предшественник владеет им или может
-получить его при разумных усилиях.
-Вы не можете налагать каких-либо дополнительных ограничений на осуществление
-прав, предоставленных или подтвержденных в соответствии с настоящей Лицензией.
-Например, Вы не можете ставить осуществление прав, предоставленных по настоящей
-Лицензии, в зависимость от оплаты отчислений, роялти или других сборов; также Вы
-не можете инициировать судебный процесс (включая встречный иск или заявление
-встречного требования в судебном процессе) о нарушении любых патентных прав при
-создании, использовании, продаже, предложении продажи, импорте Программы или
-любой ее части.
-11. Патенты
-"Инвестором" называется правообладатель, разрешающий использование Программы
-либо произведения, на котором основана Программа, на условиях настоящей
-Лицензии. Произведение, лицензированное таким образом, называется "версией со
-вкладом" инвестора.
-"Неотъемлемые патентные претензии" инвестора -- все патентные права,
-принадлежащие инвестору или контролируемые им в настоящее время либо
-приобретенные в будущем, которые могут быть нарушены созданием, использованием
-или продажей версии со вкладом, допускаемыми настоящей Лицензией; они не
-включают в себя права, которые будут нарушены исключительно вследствие будущих
-изменений версии со вкладом. Для целей данного определения под "контролем"
-понимается право выдавать патентные сублицензии способами, не нарушающими
-требований настоящей Лицензии.
-Каждый инвестор предоставляет Вам неисключительную безвозмездную лицензию на
-патент, действующую во всем мире, соответствующую неотъемлемым патентным
-претензиям инвестора, на создание, использование, продажу, предложение для
-продажи, импорт, а также запуск, внесение изменений и распространение всего, что
-входит в состав версии со вкладом.
-В следующих трех абзацах "лицензией на патент" называется любое явно выраженное
-вовне согласие или обязательство не применять патент (например, выдача
-разрешения на использование запатентованного объекта или обещание не подавать в
-суд за нарушение патента). "Выдать" кому-то такую лицензию на патент означает
-заключить такое соглашение или обязаться не применять патент против него.
-Если Вы передаете Лицензионное произведение, сознательно основываясь на лицензии
-на патент, в то время как Полный исходный текст произведения невозможно
-бесплатно скопировать с общедоступного сервера или другим не вызывающим
-затруднений способом, Вы должны либо (1) обеспечить возможность такого доступа к
-Полному исходному тексту, либо (2) отказаться от прав, предоставленных по
-лицензии на патент для данного произведения, либо (3) принять меры по передаче
-лицензии на патент последующим получателям произведения, в соответствии с
-требованиями настоящей Лицензии. "Сознательно основываясь" означает, что Вы
-знаете, что при отсутствии лицензии на патент передача Вами Лицензионного
-произведения в определенной стране или использование получателем переданного ему
-Вами Лицензионного произведения в этой стране нарушит один или несколько
-определенных патентов этой страны, срок действия которых не истек.
-Если в соответствии или в связи с единичной сделкой либо соглашением Вы
-передаете или делаете заказ на распространение Лицензионного произведения и
-предоставляете определенным лицам, получающим Лицензионное произведение,
-лицензию на патент, разрешающую им использовать, распространять, вносить
-изменения или передавать конкретные экземпляры Лицензионного произведения, то
-права, которые Вы предоставляете по лицензии на патент, автоматически переходят
-ко всем получателям Лицензионного произведения и произведений, созданных на его
-основе.
-Патентная лицензия называется "дискриминирующей", если она не покрывает,
-запрещает осуществление или содержит в качестве условия отказ от применения
-одного или нескольких прав, предоставленных настоящей Лицензией. Вы не можете
-передавать Лицензионное произведение, если Вы являетесь участником договора с
-третьим лицом, осуществляющим распространение программного обеспечения, в
-соответствии с которым Вы делаете в пользу третьего лица выплаты, размер которых
-зависит от масштабов Вашей деятельности по передаче произведения, и в
-соответствии с которым любое третье лицо, получающее от Вас Лицензионное
-произведение, делает это на условиях дискриминирующей патентной лицензии (а)
-которая зависит от количества копий Лицензионного произведения, переданных Вами
-(или копий, сделанных с этих копий), или (b) которая используется
-преимущественно в конкретных товарах или подборках, содержащих Лицензионное
-произведение, или в связи с ними, в том случае, если Вы заключили данный договор
-или получили лицензию на патент после 28 марта 2007 года.
-Ничто в настоящей Лицензии не должно толковаться как исключение или ограничение
-любого предполагаемого права или других способов противодействия нарушениям,
-которые во всем остальном могут быть доступны для Вас в соответствии с
-применимым патентным правом.
-12. Запрет отказывать в свободе другим
-Если на Вас наложены обязанности (будь то по решению суда, договору или иным
-способом), которые противоречат условиям настоящей Лицензии, это не освобождает
-Вас от соблюдения ее условий. Если Вы не можете передать Лицензионное
-произведение так, чтобы одновременно выполнять Ваши обязательства по настоящей
-Лицензии и любые другие относящиеся к делу обязательства, то Вы не можете
-передавать его вообще. Например, если Вы согласны с условием, обязывающими Вас
-производить сбор отчислений за дальнейшую передачу от тех, кому Вы передаете
-Программу, то для того, чтобы соблюсти это условие и выполнить требования
-настоящей Лицензии, Вы должны полностью воздержаться от передачи Программы.
-13. Использование вместе с Генеральной публичной лицензией
-GNU Affero
-Независимо от любых других положений настоящей Лицензии, Вам разрешается
-связывать или соединять любое Лицензионное произведение в единое составное
-произведение с произведением, лицензированным на условиях редакции 3 Генеральной
-публичной лицензии GNU Affero, а также передавать получившееся произведение.
-Условия данной Лицензии продолжат применяться к той части, которая представляет
-собой Лицензионное произведение, но при взаимодействии через сеть к комбинации
-как таковой будут применяться особые требования, содержащиеся в разделе 13
-Генеральной публичной лицензии GNU Affero.
-14. Пересмотренные редакции настоящей Лицензии
-Фонд свободного программного обеспечения время от времени может публиковать
-пересмотренные и (или) новые редакции Генеральной публичной лицензии GNU. Они
-будут аналогичны по смыслу настоящей редакции, но могут отличаться от нее в
-деталях, направленных на решение новых проблем или регулирование новых
-отношений.
-Каждой редакции присваивается собственный номер. Если для Программы указано, что
-к ней применима определенная редакция Генеральной публичной лицензии GNU "или
-любая более поздняя редакция", у Вас есть возможность использовать термины и
-условия, содержащиеся в редакции с указанным номером или любой более поздней
-редакции, опубликованной Фондом свободного программного обеспечения. Если для
-Программы не указан номер редакции Генеральной публичной лицензии GNU, Вы можете
-выбрать любую редакцию, опубликованную Фондом свободного программного
-обеспечения.
-Если Вы получили Программу, содержащую указание на то, что доверенное лицо
-правообладателя может выбирать, какую из будущих версий Генеральной публичной
-лицензии GNU использовать, то публичное заявление этого лица о принятии любой
-версии позволяет Вам выбрать эту версию для применения ее условий к Программе.
-Более поздние редакции Лицензии могут дать Вам дополнительные или принципиально
-иные права. Тем не менее в результате Вашего выбора более поздней редакции на
-автора или правообладателя не возлагается никаких дополнительных обязанностей.
-15. Отказ от гарантий
-НА ПРОГРАММУ НЕ ПРЕДОСТАВЛЯЕТСЯ НИКАКИХ ГАРАНТИЙ ЗА ИСКЛЮЧЕНИЕМ ПРЕДУСМОТРЕННЫХ
-ДЕЙСТВУЮЩИМ ЗАКОНОДАТЕЛЬСТВОМ. ЕСЛИ ИНОЕ НЕ УКАЗАНО В ПИСЬМЕННОЙ ФОРМЕ,
-ПРАВООБЛАДАТЕЛИ И (ИЛИ) ТРЕТЬИ ЛИЦА ПРЕДОСТАВЛЯЮТ ПРОГРАММУ "КАК ЕСТЬ", БЕЗ
-КАКИХ-ЛИБО ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ, ВКЛЮЧАЯ ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ
-КОНКРЕТНЫХ ЦЕЛЕЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ВЕСЬ РИСК, СВЯЗАННЫЙ С КАЧЕСТВОМ И
-ПРОИЗВОДИТЕЛЬНОСТЬЮ ПРОГРАММЫ, ВОЗЛАГАЕТСЯ НА ВАС. ЕСЛИ В ПРОГРАММЕ БУДУТ
-ВЫЯВЛЕНЫ НЕДОСТАТКИ, ВЫ ПРИНИМАЕТЕ НА СЕБЯ СТОИМОСТЬ ВСЕГО НЕОБХОДИМОГО
-ОБСЛУЖИВАНИЯ, РЕМОНТА ИЛИ ИСПРАВЛЕНИЯ.
-16. Ограничение ответственности
-Если иное не предусмотрено действующим законодательством или соглашением сторон,
-заключенным в письменной форме, правообладатель или иное лицо, которое вносит
-изменения в Программу и (или) передает ее на условиях, сформулированных выше, не
-может нести ответственность перед Вами за причиненный ущерб, включая ущерб
-общего либо конкретного характера, причиненный случайно или являющийся
-следствием использования программы либо невозможности ее использования (в том
-числе за уничтожение или модификацию информации, либо убытки, понесенные Вами
-или третьими лицами, либо сбои Программы при взаимодействии с другим программным
-обеспечением), в том числе и в случаях, когда правообладатель или третье лицо
-предупреждены о возможности причинения таких убытков.
-17. Толкование разделов 15 и 16
-Если отказ от гарантии и ограничение ответственности, представленные выше, по
-закону не могут быть применены в соответствии с их условиями, суды,
-рассматривающие спор, должны применить действующий закон, который в наибольшей
-степени предусматривает абсолютный отказ от всей гражданской ответственности в
-связи с Программой, за исключением случаев, когда гарантия или принятие на себя
-ответственности за копию программы предоставляется за плату.
-КОНЕЦ ОПРЕДЕЛЕНИЙ И УСЛОВИЙ
-Порядок применения условий Лицензии к Вашим программам
-Если Вы разрабатываете новую программу и хотите, чтобы ее использование принесло
-максимальную пользу обществу, наилучший способ достичь этого -- сделать ее
-свободной, чтобы все могли распространять и изменять ее на условиях настоящей
-Лицензии.
-Для этого сделайте так, чтобы программа содержала в себе описанные ниже
-уведомления. Самым надежным способом это сделать является включение их в начало
-каждого файла исходного текста, чтобы наиболее эффективным образом сообщить об
-отсутствии гарантий; каждый файл должен иметь по меньшей мере одну строку с
-оповещением об авторских правах и указанием на то, где находится полный текст
-уведомлений.
-<Строка с названием Программы и информацией о ее назначении.> Copyright © <год
-выпуска программы в свет> <имя автора> Эта программа является свободным
-программным обеспечением: Вы можете распространять ее и (или) изменять, соблюдая
-условия Генеральной публичной лицензии GNU, опубликованной Фондом свободного
-программного обеспечения; либо редакции 3 Лицензии, либо (на Ваше усмотрение)
-любой редакции, выпущенной позже.
-Эта программа распространяется в расчете на то, что она окажется полезной, но
-БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая подразумеваемую гарантию КАЧЕСТВА либо
-ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Генеральной публичной
-лицензией GNU для получения более подробной информации.
-Вы должны были получить копию Генеральной публичной лицензии GNU вместе с этой
-программой. Если Вы ее не получили, то перейдите по адресу:
-<http://www.gnu.org/licenses/>.
-Также добавьте информацию о том, как связаться с Вами посредством электронной
-или обычной почты.
-Если программа работает в диалоговом режиме, сделайте так, чтобы в начале такого
-режима работы она выводила короткое сообщение, подобное приведенному ниже:
-<Программа> Copyright (C) <год> <имя автора> Эта программа поставляется БЕЗ
-КАКИХ-ЛИБО ГАРАНТИЙ; для подробной информации введите "show w". Это свободное
-программное обеспечение, Вы можете распространять его при соблюдении
-определенных условий; для подробной информации введите "show c".
-Гипотетические команды "show w" и "show c" должны показывать соответствующие
-части Генеральной публичной лицензии.
-Конечно, команды Вашей программы могут быть другими; в случае применения
-графического интерфейса пользователя Вы можете использовать окно "О программе".
-Вы также должны получить от своего работодателя (если Вы работаете
-программистом) или, при необходимости, учебного заведения, письменный отказ от
-исключительных прав на Программу, если это необходимо. Для получения
-дополнительной информации об этом, а также о применении и соблюдении условий GNU
-GPL, см <http://www.gnu.org/licenses/>.
-Генеральная публичная лицензия GNU не разрешает включать Вашу программу в
-программы, свободное использование которых не разрешено. Если Ваша программа
-является библиотекой подпрограмм, Вы можете посчитать более полезным дать
-разрешение программам, свободное использование которых не разрешено, связываться
-с Вашей библиотекой. Если Вы хотите сделать это, используйте Малую генеральную
-публичную лицензию GNU вместо настоящей Лицензии. Но сначала прочитайте
+This is an unofficial translation of the GNU General Public License into Russian
+language. It was not published by the Free Software Foundation, and does not
+legally state the distribution terms for software that uses the GNU GPL—only the
+original English text of the GNU GPL does that. However, we hope that this
+translation will help language speakers understand the GNU GPL better.
+You may publish this translation, modified or unmodified, only under the terms
+at http://www.gnu.org/licenses/translations.html.
+Это неофициальный перевод GNU General Public License на русский язык. Он был
+опубликован не Фондом свободного программного обеспечения и не содержит условий
+распространения программ, которые используют GNU GPL -- для этого пригоден
+только ее исходный английский текст. Тем не менее мы надеемся, что этот перевод
+поможет лучше понять ее текст.
+Вы можете распространять перевод, с изменениями или без, только с соблюдением
+условий, описанных по адресу: http://www.gnu.org/licenses/translations.html.
+Генеральная публичная лицензия GNU. Редакция 3,
+29 июня 2007 г.
+Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>. Перевод:
+Павел Протасов <pvphome@gmail.com>, 2016 г. Разрешается свободно копировать и
+распространять текст настоящей Лицензии, запрещается вносить в него изменения.
+Введение
+Генеральная публичная лицензия GNU (GNU GPL) -- свободная лицензия для
+программного обеспечения и произведений других видов, разрешающая свободное
+создание производных произведений, используемых на условиях GNU GPL.
+Лицензии на большинство программ и других прикладных работ составлены так, чтобы
+лишить Вас права распространять и изменять такие произведения. В
+противоположность этому, Генеральная публичная лицензия GNU предназначена для
+того, чтобы предоставить Вам право распространять и изменять все версии
+программы, чтобы она оставалась свободным программным обеспечением для всех
+пользователей. Мы, Фонд свободного программного обеспечения, используем
+Генеральную публичную лицензию GNU для большей части нашего программного
+обеспечения; это относится и к другим произведениям, авторы которых сделали то
+же самое. Вы также можете применить ее к своим программам.
+Когда мы говорим о свободном программном обеспечении, мы имеем в виду свободу
+использования, а не бесплатность. Наши Генеральные публичные лицензии составлены
+для того, чтобы убедиться, что у Вас есть право распространять копии свободного
+ПО (и взимать плату за них, если Вы хотите), что Вы получаете исходные тексты
+или можете получить их, если захотите, что Вы можете изменять программное
+обеспечение или использовать его части в новых свободных программах, и Вы знаете
+о своем праве делать все это.
+Чтобы защитить Ваши права, нам нужно запретить другим отрицать их или просить
+Вас отказаться от них. Таким образом, если Вы распространяете копии программного
+обеспечения или изменяете его, у Вас появляются определенные обязанности: Вы
+должны уважать свободу других.
+Например, если Вы распространяете копии такой программы, будь то бесплатно или
+за вознаграждение, Вы должны передать получателям те же права, которые получили.
+Вы должны убедиться, что они также получили или могут получить исходный текст.
+Также Вы должны ознакомить их с этими условиями, чтобы они знали свои права.
+Разработчики, использующие GNU GPL, защищают Ваши права при помощи следующих
+мер: (1) закрепляют авторское право на программное обеспечение, и (2) предлагают
+Вам принять условия настоящей Лицензии, закрепляющей Ваше право на создание
+копий, распространение и (или) внесение изменений в программное обеспечение.
+Для защиты разработчиков и авторов GPL в явной форме говорит об отсутствии
+гарантий на свободное программное обеспечение. В интересах и пользователей и
+авторов GPL требует, чтобы к измененным версиям прилагалось описание изменений,
+так чтобы связанные с ними проблемы не могли быть ошибочно приписаны авторам
+предыдущих версий.
+Некоторые устройства спроектированы так, чтобы запретить пользователям установку
+или запуск на них измененных версий программного обеспечения, разрешив это
+только производителю. Это в корне несовместимо с целью защиты права
+пользователей на изменение программного обеспечения. Как правило, такие
+злоупотребления происходят в области потребительских продуктов, то есть там, где
+это особенно неприемлемо. Поэтому мы разработали эту редакцию GPL, чтобы пресечь
+подобную практику в этой сфере. Если подобные проблемы возникнут в других
+сферах, мы готовы расширить эти положения на них в будущих редакциях GPL,
+настолько, насколько это нужно для того, чтобы защитить свободу пользователей.
+И наконец, каждой программе постоянно угрожают патенты на программное
+обеспечение. Государства не должны допускать ограничения патентами разработки и
+использования программного обеспечения на компьютерах общего назначения, однако,
+поскольку они это допускают, мы хотели бы избежать еще одной опасности,
+состоящей в том, что в результате патентования решений, используемых в свободной
+программе, она перестанет удовлетворять критериям свободного программного
+обеспечения. Чтобы предотвратить это, GPL гарантирует, что патентование не может
+быть использовано для того, чтобы сделать программу несвободной.
+Детальные определения используемых терминов и описание условий копирования,
+распространения и внесения изменений приведены ниже.
+ТЕРМИНЫ И УСЛОВИЯ
+0. Определения
+"Настоящая Лицензия" -- редакция 3 Генеральной публичной лицензии GNU.
+Под "Авторским правом" также понимаются законы, сходные с авторско-правовыми,
+которые применяются к другим видам работ, например, к топологиям микросхем.
+Термином "Программа" обозначается любое охраноспособное произведение,
+используемое в соответствии с настоящей Лицензией. Лицензиат именуется "Вы".
+"Лицензиаты" и "получатели" могут быть как физическими лицами, так и
+организациями.
+"Внесение изменений" в произведение означает копирование или адаптацию
+произведения целиком или в части, способом, требующим разрешения
+правообладателя, за исключением изготовления его точной копии. Получившееся в
+результате произведение называется "измененной версией" предыдущего произведения
+или произведением, "основанным на" более ранней работе.
+Термином "Лицензионное произведение" обозначается неизмененная Программа или
+произведение, основанное на Программе.
+"Распространение" произведения означает совершение с ним действий, которые при
+отсутствии разрешения сделают Вас прямо или косвенно ответственным за нарушение
+действующего закона об авторском праве, за исключением запуска на компьютере или
+изменения копии, созданной в личных целях. Распространение включает в себя
+копирование, раздачу копий (с изменениями или без них), доведение до всеобщего
+сведения, а в некоторых странах -- и другие действия.
+"Передача" произведения означает любой вид распространения, который позволяет
+другим лицам создавать или получать копии произведения. Обычное взаимодействие с
+пользователем через компьютерную сеть без создания копии передачей не является.
+В диалоговом режиме пользователю должна быть показана "Информация об авторском
+праве", достаточная для того, чтобы (1) обеспечить отображение соответствующего
+уведомления об авторских правах и (2) сообщить пользователю о том, что ему не
+предоставляется никакой гарантии на произведение (за исключением фактически
+предоставленных гарантий), о том, что лицензиаты могут передавать произведение
+на условиях, описанных в настоящей Лицензии, а также о том, как ознакомиться с
+текстом настоящей Лицензии. Если интерфейс предоставляет собой список
+пользовательских команд или настроек, наподобие меню, это требование считается
+выполненным при наличии явно выделенного пункта в таком меню.
+1. Исходный текст
+Под "Исходным текстом" понимается произведение в форме, которая более всего
+подходит для внесения в него изменений. "Объектным кодом" называется
+произведение в любой иной форме.
+"Стандартный интерфейс" -- интерфейс, который либо является общепринятым
+стандартом, введенным общепризнанным органом по стандартизации, либо, в случае
+интерфейсов, характерных для конкретного языка программирования -- тот, который
+широко используется разработчиками, пишущими программы на этом языке.
+"Системные библиотеки" исполняемого произведения включают в себя то, что не
+относится к произведению в целом и при этом (a) входит в обычный комплект
+Основного компонента, но при этом не является его частью и (b) служит только для
+обеспечения работы с этим Основным компонентом или реализации Стандартного
+интерфейса, для которого существует общедоступная реализация, опубликованная в
+виде исходного текста. "Основным компонентом" в данном контексте назван главный
+существенный компонент (ядро, оконная система и т.д.) определенной операционной
+системы (если она используется), под управлением которой функционирует
+исполняемое произведение, либо компилятор, используемый для создания
+произведения или интерпретатор объектного кода, используемый для его запуска.
+"Полный исходный текст" для произведения в форме объектного кода -- весь
+исходный текст, необходимый для создания, установки и (для исполняемого
+произведения) функционирования объектного кода, а также модификации
+произведения, включая сценарии, контролирующие эти действия. Однако он не
+включает в себя Системные библиотеки, необходимые для функционирования
+произведения, инструменты общего назначения или общедоступные свободные
+программы, которые используются в неизменном виде для выполнения этих действий,
+но не являются частью произведения. Полный исходный текст включает в себя,
+например, файлы описания интерфейса, прилагаемые к файлам исходного текста
+произведения, а также исходные тексты общих библиотек и динамически связанных
+подпрограмм, которые требуются для функционирования произведения, например для
+прямой передачи данных или передачи управления потоками между этими
+подпрограммами и другими частями произведения.
+Полный исходный текст не включает в себя то, что пользователи могут получить
+автоматически из других частей Полного исходного текста.
+Полным исходным текстом для произведения в форме исходных текстов является само
+это произведение.
+2. Основные права
+Все права, предоставленные на основании настоящей Лицензии, действуют в течение
+срока действия авторских прав на Программу и не могут быть отозваны при условии,
+что сформулированные в ней условия соблюдены. Настоящая Лицензия однозначно
+подтверждает Ваши неограниченные права на запуск неизмененной Программы.
+Результаты функционирования Лицензионного произведения распространяются на
+условиях настоящей Лицензии в случае, если они, учитывая их содержание, являются
+частью Лицензионного произведения. Настоящая Лицензия подтверждает Ваши права на
+свободное использование произведения или другие аналогичные полномочия,
+предусмотренные действующим законодательством об авторском праве.
+Если Вы не осуществляете обычную передачу Лицензионного произведения, то можете
+как угодно создавать, запускать и распространять его копии до тех пор, пока
+Лицензия сохраняет силу. Вы можете передавать Лицензионные произведения третьим
+лицам исключительно для того, чтобы они внесли в них изменения для Вас или
+предоставили Вам возможность их запуска, при условии, что Вы соглашаетесь с
+условиями настоящей Лицензии при передаче всех материалов, авторскими правами на
+которые Вы не обладаете. Лица, создающие или запускающие Лицензионные
+произведения для Вас, должны делать это исключительно от Вашего имени, под Вашим
+руководством и контролем, на условиях, которые запрещают им создание без Вашей
+санкции каких-либо копий материалов, на которые Вы обладаете авторским правом.
+Любая другая передача разрешается исключительно при соблюдении описанных ниже
+условий. Сублицензирование не допускается; раздел 10 делает его не нужным.
+3. Защита прав пользователей от законов, запрещающих обход
+технических средств
+Ни одно Лицензионное произведение не должно считаться содержащим эффективные
+технические средства, удовлетворяющие требованиям любого действующего закона,
+принятого во исполнение обязательств, предусмотренных статьей 11 Договора ВОИС
+по авторскому праву от 20 декабря 1996 года или аналогичных законов, запрещающих
+или ограничивающих обход таких технических средств.
+При передаче Лицензионного произведения Вы отказываетесь от всех предоставляемых
+законом полномочий по запрету обхода технических средств, используемых авторами
+в связи с осуществлением их прав, признавая, что такой обход находится в рамках
+осуществления прав на использование Лицензионного произведения, предоставленных
+настоящей Лицензией; также Вы отказываетесь от любых попыток ограничить
+функционирование произведения или внесение в него изменений, направленных на
+реализацию предоставленных Вам законом прав на запрет пользователю обхода
+технических средств.
+4. Передача не измененных копий
+Вы можете передавать точные копии исходных текстов Программы в том виде, в
+котором Вы их получили, на любом носителе, при условии, что Вы прилагаете к
+каждой копии соответствующее уведомление об авторских правах способом,
+обеспечивающим ознакомление с ним пользователя; сохраняете все уведомления о
+том, что к тексту применима настоящая Лицензия и любые ограничения, добавленные
+в соответствии с разделом 7; сохраняете все уведомления об отсутствии каких-либо
+гарантий; предоставляете всем получателям вместе с Программой копию настоящей
+Лицензии.
+Вы можете установить любую цену за каждую копию, которую Вы передаете, или
+распространять копии бесплатно; также Вы можете предложить поддержку или
+гарантию за отдельную плату.
+5. Передача измененных исходных текстов
+Вы можете передавать исходный текст произведения, основанного на Программе, или
+изменений, необходимых для того, чтобы получить его из Программы, на условиях,
+описанных в разделе 4, при соблюдении следующих условий:
+а) Произведение должно содержать уведомления о произведенных Вами изменениях с
+указанием их даты, сделанные способом, обеспечивающим ознакомление с ними
+пользователя.
+b) Произведение должно содержать уведомление о том, что оно распространяется на
+условиях настоящей Лицензии, а также об условиях, добавленных в соответствии с
+разделом 7, сделанное способом, обеспечивающим ознакомление с ним пользователя.
+Данное требование имеет приоритет над требованиями раздела 4 "оставлять
+нетронутыми все уведомления".
+c) Вы должны передать на условиях настоящей Лицензии всю работу целиком любому
+лицу, которое приобретает копию. Таким образом, настоящая Лицензия вместе с
+любыми применимыми условиями раздела 7 будет применяться к произведению в целом
+и всем его частям, независимо от их комплектности. Настоящая Лицензия не дает
+права на лицензирование произведения на любых других условиях, но это не лишает
+законной силы такое разрешение, если Вы получили его отдельно.
+d) Если произведение имеет интерактивные пользовательские интерфейсы, каждый из
+них должен отображать Информацию об авторском праве; однако, если Программа
+имеет пользовательские интерфейсы, которые не отображают информацию об авторском
+праве, от Вашего произведения этого также не требуется.
+Включение Лицензионного произведения в подборку на разделе хранения данных или
+на носителе, на котором распространяется произведение, вместе с другими
+отдельными самостоятельными произведениями, которые по своей природе не являются
+переработкой Лицензионного произведения и не объединены с ним, например, в
+программный комплекс, называется "набором", если авторские права на подборку не
+используются для ограничения доступа к ней или законных прав ее пользователей
+сверх того, что предусматривают лицензии на отдельные произведения. Включение
+Лицензионного произведения в набор не влечет применения положений настоящей
+Лицензии к остальным его частям.
+6. Передача произведения в формах, не относящихся к исходному
+тексту
+Вы можете передавать Лицензионное произведение в виде объектного кода в
+соответствии с положениями разделов 4 и 5, при условии, что Вы также передаете
+машиночитаемый Полный исходный текст в соответствии с условиями настоящей
+Лицензии, одним из следующих способов:
+a) Передавая объектный код или содержащий его материальный продукт (включая
+носитель, на котором распространяется произведение), с приложением Полного
+исходного текста на материальном носителе, обычно используемом для обмена
+программным обеспечением.
+b) Передавая объектный код или содержащий его материальный продукт (включая
+носитель, на котором распространяется произведение), с письменным предложением,
+действительным в течение не менее трех лет либо до тех пор, пока Вы
+предоставляете запасные части или поддержку для данного продукта, о передаче
+любому обладателю объектного кода (1) копии Полного исходного текста для всего
+программного обеспечения, содержащегося в продукте, на которое распространяется
+действие настоящей Лицензии, на физическом носителе, обычно используемом для
+обмена программным обеспечением, по цене, не превышающей разумных затрат на
+передачу копии, или (2) доступа к Полному исходному тексту с возможностью его
+копирования с сетевого сервера без взимания платы.
+c) Передавая отдельные копии объектного кода с письменной копией предложения о
+предоставлении Полного исходного текста. Этот вариант допускается только в
+отдельных случаях при распространении без извлечения прибыли, и только если Вы
+получили объектный код с таким предложением в соответствии с пунктом 6b.
+d) Передавая объектный код посредством предоставления доступа к нему по
+определенному адресу (бесплатно или за дополнительную плату), и предлагая
+эквивалентный доступ к Полному исходному тексту таким же способом по тому же
+адресу без какой-либо дополнительной оплаты. От Вас не требуется принуждать
+получателей копировать Полный исходный текст вместе с объектным кодом. Если
+объектный код размещен на сетевом сервере, Полный исходный текст может
+находиться на другом сервере (управляемом Вами или третьим лицом), который
+предоставляет аналогичную возможность копирования; при этом Вы должны четко
+указать рядом с объектным кодом способ получения Полного исходного текста.
+Независимо от того, на каком сервере расположен Полный исходный текст, Вы
+обязаны убедиться в том, что он будет распространяться в течение времени,
+необходимого для соблюдения этих требований.
+e) Передавая объектный код с использованием одноранговой (пиринговой) сети, при
+условии информирования других пользователей сети о том, где можно бесплатно
+получить объектный код и Полный исходный текст произведения способом, описанным
+в пункте 6d.
+Не нужно включать в передаваемый объектный код его отделимые части, исходные
+тексты которых не входят в состав Полного исходного текста, такие как Системные
+библиотеки.
+"Потребительский товар" это либо (1) "товар, предназначенный для личных нужд",
+под которым понимается любое материальное личное имущество, которое обычно
+используется для личных, семейных или домашних целей, или (2) что-либо
+спроектированное или продающееся для использования в жилище. При определении
+того, предназначен ли товар для личных нужд, сомнения должны толковаться в
+пользу положительного ответа на этот вопрос. Применительно к конкретному товару,
+используемому конкретным пользователем, под выражением "обычно используется"
+имеется в виду способ, которым данный вид товаров преимущественно или как
+правило используется, независимо от статуса конкретного пользователя или
+способа, которым конкретный пользователь использует, предполагает или будет
+использовать товар. Товар относится к предназначенным для личных нужд независимо
+от того, насколько часто он используется в коммерческой деятельности,
+промышленности или иной сфере, не относящейся к личным нуждам, за исключением
+случая, когда использование в этой сфере представляет собой единственный
+основной способ использования такого товара.
+"Информация, необходимая для установки" Потребительского товара -- любые методы,
+процедуры, сведения, необходимые для авторизации, или другая информация,
+необходимая для установки и запуска в Потребительском товаре измененных версий
+Лицензионного произведения, полученных при изменении Полного исходного текста.
+Данная информация должна быть достаточной для того, чтобы обеспечить возможность
+внесения в исходный текст изменений, не приводящих к ограничению или нарушению
+его дальнейшей работоспособности.
+Если вместе с Потребительским товаром или специально для использования в нем Вы
+передаете произведение в виде объектного кода на условиях, описанных в данном
+разделе, и такая передача является частью сделки, по которой право владения и
+пользования Потребительским товаром переходит к получателю пожизненно или на
+определенный срок (независимо от признаков сделки), Полный исходный текст,
+передаваемый согласно данному разделу, должен сопровождаться Информацией,
+необходимой для установки. Но это требование не применяется, если ни Вы, ни
+какое-либо третье лицо не сохраняет за собой возможности установки измененного
+объектного кода на Потребительский товар (например, произведение было
+установлено в постоянную память).
+Требование о предоставлении Информации, необходимой для установки, не включает в
+себя требование продолжения оказания услуг по поддержке, предоставления гарантии
+или обновлений для произведения, которое было изменено или установлено
+получателем, либо для Потребительского товара, в котором оно было изменено или
+на который оно было установлено. В доступе к сети может быть отказано, если само
+внесение изменений существенно и негативно влияет на работу сети, нарушает
+правила обмена данными или не поддерживает протоколы для обмена данными по сети.
+Передаваемый в соответствии с данным разделом Полный исходный текст и
+предоставленная Информация, необходимая для установки, должны быть записаны в
+формате, который имеет общедоступное описание (и общедоступную реализацию,
+опубликованную в форме исходного текста) и не должны требовать никаких
+специальных паролей или ключей для распаковки, чтения или копирования.
+7. Дополнительные условия
+"Дополнительными разрешениями" называются условия, которые дополняют условия
+настоящей Лицензии, вводя исключения из одного или нескольких ее положений.
+Дополнительные разрешения, которые применимы ко всей Программе, должны
+рассматриваться как часть настоящей Лицензии, в той степени, в которой они
+соответствуют действующему законодательству. Если дополнительные разрешения
+применяются только к части Программы, эта часть может быть использована отдельно
+на измененных условиях, но вся Программа продолжает использоваться на условиях
+настоящей Лицензии без учета дополнительных разрешений.
+Когда Вы передаете копию Лицензионного произведения, Вы можете по своему
+усмотрению исключить любые дополнительные разрешения, примененные к этой копии
+или к любой ее части. (Для дополнительных разрешений может быть заявлено
+требование об их удалении в определенных случаях, когда Вы вносите изменения в
+произведение.) Вы можете добавлять дополнительные разрешения к добавленным Вами
+в Лицензионное произведение материалам, на которые Вы обладаете авторскими
+правами или правом выдачи соответствующего разрешения.
+Независимо от любых других положений настоящей Лицензии, Вы можете дополнить ее
+положения следующими условиями, относящимися к материалу, добавленному к
+Лицензионному произведению (если это разрешено обладателями авторских прав на
+материал):
+a) отказом от гарантий или ограничением ответственности, отличающимися от тех,
+что описаны в разделах 15 и 16 настоящей Лицензии; либо
+b) требованием сохранения соответствующей информации о правах или об авторстве
+материала, или включения ее в Информацию об авторском праве, отображаемую
+содержащим его произведением; либо
+c) запретом на искажение информации об источнике происхождения материала или
+требованием того, чтобы измененные версии такого материала содержали корректную
+отметку об отличиях от исходной версии; либо
+d) ограничением использования в целях рекламы имен лицензиаров или авторов
+материала; либо
+e) отказом от предоставления прав на использование в качестве товарных знаков
+некоторых торговых наименований, товарных знаков или знаков обслуживания; либо
+f) требованием от каждого, кто по договору передает материал (или его измененные
+версии), предоставления компенсации лицензиарам и авторам материала в виде
+принятия на себя любой ответственности, которую этот договор налагает на
+лицензиаров и авторов.
+Все остальные ограничивающие дополнительные условия считаются "дополнительными
+запретами" по смыслу раздела 10. Если программа, которую Вы получили, или любая
+ее часть содержит уведомление о том, что наряду с настоящей Лицензией ее
+использование регулируется условием, относящимся к дополнительным запретам, Вы
+можете удалить такое условие. Если лицензия содержит дополнительный запрет, но
+допускает лицензирование на измененных условиях или передачу в соответствии с
+настоящей Лицензией, Вы можете добавить к Лицензионному произведению материал,
+используемый на условиях такой лицензии, в том случае, если дополнительный
+запрет не сохраняется при таком изменении условий лицензии или передаче.
+Если Вы добавляете условия для использования Лицензионного произведения в
+соответствии с настоящим разделом, Вы должны поместить в соответствующих файлах
+исходного текста уведомление о том, что к этим файлам применяются дополнительные
+условия, или указание на то, как ознакомиться с соответствующими условиями.
+Дополнительные разрешающие или ограничивающие условия могут быть сформулированы
+в виде отдельной лицензии или зафиксированы как исключения; вышеуказанные
+требования применяются в любом случае.
+8. Прекращение действия
+Вы не можете распространять Лицензионное произведение или вносить в него
+изменения на условиях, отличающихся от явно оговоренных в настоящей Лицензии.
+Любая попытка распространения или внесения изменений на иных условиях является
+ничтожной и автоматически прекращает Ваши права, полученные по настоящей
+Лицензии (включая лицензию на любые патенты, предоставленные согласно третьему
+пункту раздела 11).
+Тем не менее если Вы прекращаете нарушение настоящей Лицензии, Ваши права,
+полученные от конкретного правообладателя, восстанавливаются (а) временно, до
+тех пор пока правообладатель явно и окончательно не прекратит действие Ваших
+прав, и (б) навсегда, если правообладатель не уведомит Вас о нарушении с помощью
+надлежащих средств в течение 60 дней после прекращения нарушений.
+Кроме того, Ваши права, полученные от конкретного правообладателя,
+восстанавливаются навсегда, если правообладатель впервые любым подходящим
+способом уведомляет Вас о нарушении настоящей Лицензии на свое произведение (для
+любого произведения) и Вы устраняете нарушение в течение 30 дней после получения
+уведомления.
+Прекращение Ваших прав, описанное в настоящем разделе, не прекращает действие
+лицензий лиц, которые получили от Вас копии произведения или права,
+предоставляемые настоящей Лицензией. Если Ваши права были прекращены навсегда и
+не восстановлены, Вы не можете вновь получить право на тот же материал на
+условиях, описанных в разделе 10.
+9. Акцепт не требуется для получения копий
+Вы не обязаны принимать условия настоящей Лицензии для того, чтобы получить или
+запустить копию Программы. Случайное распространение Лицензионного произведения,
+происходящее вследствие использования для получения его копии передачи по
+одноранговой (пиринговой) сети, также не требует принятия этих условий. Тем не
+менее только настоящая Лицензия дает Вам право распространять или изменять любое
+Лицензионное произведение. Если Вы не приняли условия настоящей Лицензии, такие
+действия будут нарушением авторского права. Поэтому изменяя или распространяя
+Лицензионное произведение, Вы выражаете согласие с условиями настоящей Лицензии.
+10. Автоматическое получение прав последующими получателями
+Каждый раз, когда Вы передаете Лицензионное произведение, получатель
+автоматически получает от его лицензиара право запускать, изменять и
+распространять это произведение при условии соблюдения настоящей Лицензии. Вы не
+несете ответственности за соблюдение третьими лицами условий настоящей Лицензии.
+"Реорганизацией" называются действия, в результате которых передается управление
+организацией или значительная часть ее активов, а также происходит разделение
+или слияние организаций. Если распространение Лицензионного произведения
+является результатом реорганизации, каждая из сторон сделки, получающая копию
+произведения, также получает все права на произведение, которые предшествующее
+юридическое лицо имело или могло предоставить согласно предыдущему абзацу, а
+также право на владение Полным исходным текстом произведения от предшественника,
+осуществляемое в его интересах, если предшественник владеет им или может
+получить его при разумных усилиях.
+Вы не можете налагать каких-либо дополнительных ограничений на осуществление
+прав, предоставленных или подтвержденных в соответствии с настоящей Лицензией.
+Например, Вы не можете ставить осуществление прав, предоставленных по настоящей
+Лицензии, в зависимость от оплаты отчислений, роялти или других сборов; также Вы
+не можете инициировать судебный процесс (включая встречный иск или заявление
+встречного требования в судебном процессе) о нарушении любых патентных прав при
+создании, использовании, продаже, предложении продажи, импорте Программы или
+любой ее части.
+11. Патенты
+"Инвестором" называется правообладатель, разрешающий использование Программы
+либо произведения, на котором основана Программа, на условиях настоящей
+Лицензии. Произведение, лицензированное таким образом, называется "версией со
+вкладом" инвестора.
+"Неотъемлемые патентные претензии" инвестора -- все патентные права,
+принадлежащие инвестору или контролируемые им в настоящее время либо
+приобретенные в будущем, которые могут быть нарушены созданием, использованием
+или продажей версии со вкладом, допускаемыми настоящей Лицензией; они не
+включают в себя права, которые будут нарушены исключительно вследствие будущих
+изменений версии со вкладом. Для целей данного определения под "контролем"
+понимается право выдавать патентные сублицензии способами, не нарушающими
+требований настоящей Лицензии.
+Каждый инвестор предоставляет Вам неисключительную безвозмездную лицензию на
+патент, действующую во всем мире, соответствующую неотъемлемым патентным
+претензиям инвестора, на создание, использование, продажу, предложение для
+продажи, импорт, а также запуск, внесение изменений и распространение всего, что
+входит в состав версии со вкладом.
+В следующих трех абзацах "лицензией на патент" называется любое явно выраженное
+вовне согласие или обязательство не применять патент (например, выдача
+разрешения на использование запатентованного объекта или обещание не подавать в
+суд за нарушение патента). "Выдать" кому-то такую лицензию на патент означает
+заключить такое соглашение или обязаться не применять патент против него.
+Если Вы передаете Лицензионное произведение, сознательно основываясь на лицензии
+на патент, в то время как Полный исходный текст произведения невозможно
+бесплатно скопировать с общедоступного сервера или другим не вызывающим
+затруднений способом, Вы должны либо (1) обеспечить возможность такого доступа к
+Полному исходному тексту, либо (2) отказаться от прав, предоставленных по
+лицензии на патент для данного произведения, либо (3) принять меры по передаче
+лицензии на патент последующим получателям произведения, в соответствии с
+требованиями настоящей Лицензии. "Сознательно основываясь" означает, что Вы
+знаете, что при отсутствии лицензии на патент передача Вами Лицензионного
+произведения в определенной стране или использование получателем переданного ему
+Вами Лицензионного произведения в этой стране нарушит один или несколько
+определенных патентов этой страны, срок действия которых не истек.
+Если в соответствии или в связи с единичной сделкой либо соглашением Вы
+передаете или делаете заказ на распространение Лицензионного произведения и
+предоставляете определенным лицам, получающим Лицензионное произведение,
+лицензию на патент, разрешающую им использовать, распространять, вносить
+изменения или передавать конкретные экземпляры Лицензионного произведения, то
+права, которые Вы предоставляете по лицензии на патент, автоматически переходят
+ко всем получателям Лицензионного произведения и произведений, созданных на его
+основе.
+Патентная лицензия называется "дискриминирующей", если она не покрывает,
+запрещает осуществление или содержит в качестве условия отказ от применения
+одного или нескольких прав, предоставленных настоящей Лицензией. Вы не можете
+передавать Лицензионное произведение, если Вы являетесь участником договора с
+третьим лицом, осуществляющим распространение программного обеспечения, в
+соответствии с которым Вы делаете в пользу третьего лица выплаты, размер которых
+зависит от масштабов Вашей деятельности по передаче произведения, и в
+соответствии с которым любое третье лицо, получающее от Вас Лицензионное
+произведение, делает это на условиях дискриминирующей патентной лицензии (а)
+которая зависит от количества копий Лицензионного произведения, переданных Вами
+(или копий, сделанных с этих копий), или (b) которая используется
+преимущественно в конкретных товарах или подборках, содержащих Лицензионное
+произведение, или в связи с ними, в том случае, если Вы заключили данный договор
+или получили лицензию на патент после 28 марта 2007 года.
+Ничто в настоящей Лицензии не должно толковаться как исключение или ограничение
+любого предполагаемого права или других способов противодействия нарушениям,
+которые во всем остальном могут быть доступны для Вас в соответствии с
+применимым патентным правом.
+12. Запрет отказывать в свободе другим
+Если на Вас наложены обязанности (будь то по решению суда, договору или иным
+способом), которые противоречат условиям настоящей Лицензии, это не освобождает
+Вас от соблюдения ее условий. Если Вы не можете передать Лицензионное
+произведение так, чтобы одновременно выполнять Ваши обязательства по настоящей
+Лицензии и любые другие относящиеся к делу обязательства, то Вы не можете
+передавать его вообще. Например, если Вы согласны с условием, обязывающими Вас
+производить сбор отчислений за дальнейшую передачу от тех, кому Вы передаете
+Программу, то для того, чтобы соблюсти это условие и выполнить требования
+настоящей Лицензии, Вы должны полностью воздержаться от передачи Программы.
+13. Использование вместе с Генеральной публичной лицензией
+GNU Affero
+Независимо от любых других положений настоящей Лицензии, Вам разрешается
+связывать или соединять любое Лицензионное произведение в единое составное
+произведение с произведением, лицензированным на условиях редакции 3 Генеральной
+публичной лицензии GNU Affero, а также передавать получившееся произведение.
+Условия данной Лицензии продолжат применяться к той части, которая представляет
+собой Лицензионное произведение, но при взаимодействии через сеть к комбинации
+как таковой будут применяться особые требования, содержащиеся в разделе 13
+Генеральной публичной лицензии GNU Affero.
+14. Пересмотренные редакции настоящей Лицензии
+Фонд свободного программного обеспечения время от времени может публиковать
+пересмотренные и (или) новые редакции Генеральной публичной лицензии GNU. Они
+будут аналогичны по смыслу настоящей редакции, но могут отличаться от нее в
+деталях, направленных на решение новых проблем или регулирование новых
+отношений.
+Каждой редакции присваивается собственный номер. Если для Программы указано, что
+к ней применима определенная редакция Генеральной публичной лицензии GNU "или
+любая более поздняя редакция", у Вас есть возможность использовать термины и
+условия, содержащиеся в редакции с указанным номером или любой более поздней
+редакции, опубликованной Фондом свободного программного обеспечения. Если для
+Программы не указан номер редакции Генеральной публичной лицензии GNU, Вы можете
+выбрать любую редакцию, опубликованную Фондом свободного программного
+обеспечения.
+Если Вы получили Программу, содержащую указание на то, что доверенное лицо
+правообладателя может выбирать, какую из будущих версий Генеральной публичной
+лицензии GNU использовать, то публичное заявление этого лица о принятии любой
+версии позволяет Вам выбрать эту версию для применения ее условий к Программе.
+Более поздние редакции Лицензии могут дать Вам дополнительные или принципиально
+иные права. Тем не менее в результате Вашего выбора более поздней редакции на
+автора или правообладателя не возлагается никаких дополнительных обязанностей.
+15. Отказ от гарантий
+НА ПРОГРАММУ НЕ ПРЕДОСТАВЛЯЕТСЯ НИКАКИХ ГАРАНТИЙ ЗА ИСКЛЮЧЕНИЕМ ПРЕДУСМОТРЕННЫХ
+ДЕЙСТВУЮЩИМ ЗАКОНОДАТЕЛЬСТВОМ. ЕСЛИ ИНОЕ НЕ УКАЗАНО В ПИСЬМЕННОЙ ФОРМЕ,
+ПРАВООБЛАДАТЕЛИ И (ИЛИ) ТРЕТЬИ ЛИЦА ПРЕДОСТАВЛЯЮТ ПРОГРАММУ "КАК ЕСТЬ", БЕЗ
+КАКИХ-ЛИБО ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ ГАРАНТИЙ, ВКЛЮЧАЯ ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ
+КОНКРЕТНЫХ ЦЕЛЕЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ВЕСЬ РИСК, СВЯЗАННЫЙ С КАЧЕСТВОМ И
+ПРОИЗВОДИТЕЛЬНОСТЬЮ ПРОГРАММЫ, ВОЗЛАГАЕТСЯ НА ВАС. ЕСЛИ В ПРОГРАММЕ БУДУТ
+ВЫЯВЛЕНЫ НЕДОСТАТКИ, ВЫ ПРИНИМАЕТЕ НА СЕБЯ СТОИМОСТЬ ВСЕГО НЕОБХОДИМОГО
+ОБСЛУЖИВАНИЯ, РЕМОНТА ИЛИ ИСПРАВЛЕНИЯ.
+16. Ограничение ответственности
+Если иное не предусмотрено действующим законодательством или соглашением сторон,
+заключенным в письменной форме, правообладатель или иное лицо, которое вносит
+изменения в Программу и (или) передает ее на условиях, сформулированных выше, не
+может нести ответственность перед Вами за причиненный ущерб, включая ущерб
+общего либо конкретного характера, причиненный случайно или являющийся
+следствием использования программы либо невозможности ее использования (в том
+числе за уничтожение или модификацию информации, либо убытки, понесенные Вами
+или третьими лицами, либо сбои Программы при взаимодействии с другим программным
+обеспечением), в том числе и в случаях, когда правообладатель или третье лицо
+предупреждены о возможности причинения таких убытков.
+17. Толкование разделов 15 и 16
+Если отказ от гарантии и ограничение ответственности, представленные выше, по
+закону не могут быть применены в соответствии с их условиями, суды,
+рассматривающие спор, должны применить действующий закон, который в наибольшей
+степени предусматривает абсолютный отказ от всей гражданской ответственности в
+связи с Программой, за исключением случаев, когда гарантия или принятие на себя
+ответственности за копию программы предоставляется за плату.
+КОНЕЦ ОПРЕДЕЛЕНИЙ И УСЛОВИЙ
+Порядок применения условий Лицензии к Вашим программам
+Если Вы разрабатываете новую программу и хотите, чтобы ее использование принесло
+максимальную пользу обществу, наилучший способ достичь этого -- сделать ее
+свободной, чтобы все могли распространять и изменять ее на условиях настоящей
+Лицензии.
+Для этого сделайте так, чтобы программа содержала в себе описанные ниже
+уведомления. Самым надежным способом это сделать является включение их в начало
+каждого файла исходного текста, чтобы наиболее эффективным образом сообщить об
+отсутствии гарантий; каждый файл должен иметь по меньшей мере одну строку с
+оповещением об авторских правах и указанием на то, где находится полный текст
+уведомлений.
+<Строка с названием Программы и информацией о ее назначении.> Copyright © <год
+выпуска программы в свет> <имя автора> Эта программа является свободным
+программным обеспечением: Вы можете распространять ее и (или) изменять, соблюдая
+условия Генеральной публичной лицензии GNU, опубликованной Фондом свободного
+программного обеспечения; либо редакции 3 Лицензии, либо (на Ваше усмотрение)
+любой редакции, выпущенной позже.
+Эта программа распространяется в расчете на то, что она окажется полезной, но
+БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, включая подразумеваемую гарантию КАЧЕСТВА либо
+ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Ознакомьтесь с Генеральной публичной
+лицензией GNU для получения более подробной информации.
+Вы должны были получить копию Генеральной публичной лицензии GNU вместе с этой
+программой. Если Вы ее не получили, то перейдите по адресу:
+<http://www.gnu.org/licenses/>.
+Также добавьте информацию о том, как связаться с Вами посредством электронной
+или обычной почты.
+Если программа работает в диалоговом режиме, сделайте так, чтобы в начале такого
+режима работы она выводила короткое сообщение, подобное приведенному ниже:
+<Программа> Copyright (C) <год> <имя автора> Эта программа поставляется БЕЗ
+КАКИХ-ЛИБО ГАРАНТИЙ; для подробной информации введите "show w". Это свободное
+программное обеспечение, Вы можете распространять его при соблюдении
+определенных условий; для подробной информации введите "show c".
+Гипотетические команды "show w" и "show c" должны показывать соответствующие
+части Генеральной публичной лицензии.
+Конечно, команды Вашей программы могут быть другими; в случае применения
+графического интерфейса пользователя Вы можете использовать окно "О программе".
+Вы также должны получить от своего работодателя (если Вы работаете
+программистом) или, при необходимости, учебного заведения, письменный отказ от
+исключительных прав на Программу, если это необходимо. Для получения
+дополнительной информации об этом, а также о применении и соблюдении условий GNU
+GPL, см <http://www.gnu.org/licenses/>.
+Генеральная публичная лицензия GNU не разрешает включать Вашу программу в
+программы, свободное использование которых не разрешено. Если Ваша программа
+является библиотекой подпрограмм, Вы можете посчитать более полезным дать
+разрешение программам, свободное использование которых не разрешено, связываться
+с Вашей библиотекой. Если Вы хотите сделать это, используйте Малую генеральную
+публичную лицензию GNU вместо настоящей Лицензии. Но сначала прочитайте
 пожалуйста: <http://www.gnu.org/philosophy/why-not-lgpl.html>. 

+ 1 - 1
models/__init__.py

@@ -1 +1 @@
-from .webservice_running import OrdersLocal
+from .webservice_running import OrdersLocal

+ 2 - 3
views.py

@@ -3,9 +3,8 @@ import requests
 from django.http import HttpResponse
 from webservice_running.apps import api
 from core.settings import API_URL
-from webservice_running.forms import OrderRegForm
-from django.shortcuts import render
-
+from webservice_running.forms import OrderRegForm, RegisterUserForm
+from django.shortcuts import redirect, render
 
 def order_reg(request):
     if request.method == 'POST':