Browse Source

Add logos, etc. to make it work for first version

bernhardbuhl 3 years ago
parent
commit
8affeb406b

+ 75 - 0
README.md

@@ -0,0 +1,75 @@
+# PoLZy Showcase
+
+This is a showcase of PoLZy - the *simple* Policy Lifecycle application for auto and P&C insurance companies.
+
+It includes full test data for policies, fast offer and shows most of the functionalities of user and organization
+management.
+
+In case you want a Demo or discuss, how PoLZy can help your company to attract more new business and reduce overhead 
+costs in administration do contact us now: info@buhl-consulting.com.cy.
+
+# Installation
+
+## From repository:
+
+### Install Showcase-Backend
+* ``git clone https://gogs.earthsquad.global/athos/PoLZy_Showcase``
+* ``cd PoLZy_Showcase``
+* create virtual environment, e.g. like this
+  * ```virtualenv venv```
+  * ```source venv/bin/activate``` (on Mac/Linux) or ```venv/scripts/activate``` (on windows)
+  * ```pip install -r requirements.txt```
+* Start the backend:
+  * ``runbackend.sh`` (on Mac/Linux) or ``runbackend.bat`` (on Windows)
+  
+### Install PoLZy Frontend
+
+You need to have node package manager installed for the frontend to run. Visit
+https://nodejs.org/en/ to install the package for your operating system.
+
+* ``git clone https://gogs.earthsquad.global/athos/PoLZy``
+* ``cd PoLZy/polzy-frontend``
+* ```npm install```
+* ```npm start```
+
+This will open a new browser tab directing you to ``http://localhost:3000``
+
+## Via Docker
+
+TODO
+
+# Usage
+
+Login to http://localhost:3000 and use these usernames to see different layouts and functionalities depending on the
+role and authorization of the user:
+
+* ``admin@polzy.com``: Full administration, also of all organziations and users
+* ``agent@polzy.com``: Opens directly with a Fast offer, ready to calculate
+* ``clerk@polzy.com``: Opens directly in Policy view. No option for calculating fast offers
+
+# Usage of Policy view:
+
+Usually you would connect PoLZy to your policy management system. For the Showcase we simply created a JSON datastore.
+You can see it in ```pms/data/policies.json```. You can try with all policy numbers and see different representations
+of the policy in the UI.
+
+In a real implementation you'd also see different Activities for each policy, depending on the product and current
+state. The logic, which activities are possible (and allowed for the current user) along with the logic, which input
+parameters are needed for an activitiy can be implemented either in PoLZy or in your policy management backend system.
+
+Here some policy numbers for you to try:
+* AS-12345
+* JG-48470
+* GL-21870
+
+# Usage of fast offer view:
+
+When you're logged in with either `admin` or `agent` you can calculate a fast offer. In this example of an auto
+insurance the agent has to provide some technical parameters (which would usually be relevant for the calucation in the
+policy management system). After all required parameters are filled in, the system will automatically calculate the 
+premium.
+
+Once the premium is calculated there's a new activity button in the card to print the pricing information along with
+the technical parameters.
+
+To send the application to underwriters or directly into the policy management system click ``Create Policy``.

+ 0 - 6
antrag.py

@@ -31,15 +31,12 @@ class SampleAntrag(Antrag):
 
         raise Exception(f'No offer available for product {self.product_name}')
 
-
     def get(self):
         #
         # returns antrag instance as json object to front-end 
         #
         return self.instance
 
-        
-
     def get_field_by_name(self, name):
         #
         # find antrag field by name
@@ -71,7 +68,6 @@ class SampleAntrag(Antrag):
             brand_field['inputRange'] = get_auto_brands(vehicle_type)
             if not brand_field['valueChosenOrEntered'] in brand_field['inputRange']:
                 brand_field['valueChosenOrEntered'] = brand_field['inputRange'][0]
- 
 
     def updateFields(self, data):
         #
@@ -90,7 +86,6 @@ class SampleAntrag(Antrag):
 
         self.update_auto_brands()
 
-
     def executeActivity(self, data):
         #
         # executes antrag activity defined in data
@@ -106,5 +101,4 @@ class SampleAntrag(Antrag):
             self.instance['status'] = 'Calculated'
             return self.get()
 
-
         raise Exception(f'Logic for activity {data["activity"]} is not defined')

+ 9 - 6
app.py

@@ -1,6 +1,8 @@
 from polzybackend import create_app
 import os
-#import flask_monitoringdashboard as dashboard
+from clauses import bp
+from logo import bp as logo_bp
+
 
 class Config(object):
 
@@ -18,10 +20,11 @@ class Config(object):
     
     DEBUG = True
 
-
-app = create_app(Config)
+    MEDIA = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'media')
+    LOGO = os.path.join(MEDIA, 'logo')
+    LOGO_URI = 'logo'
 
 
-
-from clauses import bp
-app.register_blueprint(bp)
+app = create_app(Config)
+app.register_blueprint(bp)
+app.register_blueprint(logo_bp)

+ 5 - 0
logo/__init__.py

@@ -0,0 +1,5 @@
+from flask import Blueprint
+
+bp = Blueprint('logo', __name__)
+
+from . import routes

+ 31 - 0
logo/routes.py

@@ -0,0 +1,31 @@
+from flask import jsonify, request, current_app, send_file, abort
+from . import bp
+import os
+
+#
+# Default Logo
+#
+default_logo = {
+    "default": "POLZY_POLZY LIGHT.png",       # login screens
+    "top": "POLZY_POLZY LIGHT.png",         # top bar
+    "policy": "POLZY_LeZySEM LIGHT.png",    # new policy card
+    "antrag": "POLZY_LeZyTOR LIGHT.png",    # new antrag card
+}
+
+
+@bp.route('/logo/<string:filename>')
+@bp.route('/logo/default/<string:target>')
+def logo(filename=None, target=None):
+    current_app.logger.critical(f"Arrived in Logo route")
+    if filename:
+        path_to_file = os.path.join(current_app.config['LOGO'], filename)
+    elif target:
+        path_to_file = os.path.join(current_app.config['LOGO'], str(default_logo.get(target)))
+    else:
+        return abort(403)
+
+    #print(path_to_file)
+    return send_file(
+        path_to_file,
+        attachment_filename=filename,
+    )

BIN
media/logo/LEZYSEM_GREEN.png


BIN
media/logo/LeZySEM Blue.png


BIN
media/logo/LeZySEM Red.png


BIN
media/logo/LeZyTOR Blue.png


BIN
media/logo/LeZyTOR Red.png


BIN
media/logo/POLZY_LeZySEM LIGHT.png


BIN
media/logo/POLZY_LeZyTOR LIGHT.png


BIN
media/logo/POLZY_POLZY DARK.png


BIN
media/logo/POLZY_POLZY LIGHT.png


BIN
media/logo/polzy.png


+ 1 - 0
models/cancel_activity.py

@@ -1,6 +1,7 @@
 from polzybackend import db
 from polzybackend.auth import get_uuid
 from datetime import datetime, date
+import uuid
 
 
 class CancelActivity(db.Model):

+ 10 - 5
pms/__init__.py

@@ -83,7 +83,7 @@ activities = {
                 "inputRange": [
                     "8002 No Payment",
                     "8003 Vacation",
-                    "8005 Other" 
+                    "8005 Other"
                 ],
                 "onlyFromRange": False,
                 "valueChosenOrEntered": "8002 No Payment",
@@ -148,15 +148,16 @@ def get(policy_number, effective_date):
     # load policies
     with open(POLICY_DATASET, 'r') as f:
         policies = json.load(f)
-    
+
     # delay emulation
-    #sleep(DELAY_SECONDS)
+    # sleep(DELAY_SECONDS)
 
     request_number = policy_number.upper().replace('-', '')
     request_date = effective_date.replace('-', '')
     print(f'**** REQUEST POLICY: {request_number} {request_date}')
     for item in policies:
-        if request_number == item['number'].replace('-', '') and request_date == item['effective_date'].replace('-', ''):
+        if request_number == item['number'].replace('-',
+                                                    ''):  # and request_date == item['effective_date'].replace('-', ''):
             # generate clauses
             objects = random_objects()
             item['clauses'] = [{
@@ -164,9 +165,12 @@ def get(policy_number, effective_date):
                 'number': clause,
                 'link': f'{current_app.config["HOST"]}/clauses/{clause}',
                 'description': f'Description of clause {clause}',
-            } for clause in (''.join(random.choice(string.digits) for _ in range(4)) + random.choice(string.ascii_uppercase) for i in range(random.randint(1, 5)))]
+            } for clause in
+                (''.join(random.choice(string.digits) for _ in range(4)) + random.choice(string.ascii_uppercase) for i
+                 in range(random.randint(1, 5)))]
             return item
 
+
 def get_activities(status):
     #
     # returns possible activities based on status
@@ -174,6 +178,7 @@ def get_activities(status):
 
     return [activities[_] for _ in activities_by_status[status]]
 
+
 def execute_activity(policy_number, activity):
     #
     # executes activity

+ 2 - 2
pms/data/antrag_activities.json

@@ -2,14 +2,14 @@
   "default": [
     {
       "name": "Berechnen",
-      "description": "Schnellrechner f\u00fcr eingegebene Parameter",
+      "description": "Fast calculation for entered parameters",
       "icon": "calculate.svg",
       "postExecution": "default",
       "fields": []
     },
     {
       "name": "Clone",
-      "description": "Antrag duplizieren",
+      "description": "Copy fast offer",
       "icon": "calculate.svg",
       "postExecution": "default",
       "fields": []

File diff suppressed because it is too large
+ 0 - 1337
pms/data/antrag_sample.json


+ 14 - 28
pms/data/antrags.json

@@ -53,8 +53,8 @@
       {
         "fieldType": 1,
         "name": "Kasko",
-        "brief": "Kasko",
-        "tooltip": "Kasko Insurance",
+        "brief": "Hull",
+        "tooltip": "Hull Insurance",
         "icon": "",
         "fieldDataType": "Flag",
         "inputRange": [],
@@ -128,11 +128,8 @@
         "fieldDataType": "Text",
         "inputRange": [
           "",
-          "Alfa romeo",
-          "Aston martin",
           "Audi",
           "Bentley",
-          "Bmw",
           "Chevrolet",
           "Chrysler",
           "Citroen",
@@ -142,22 +139,17 @@
           "Dodge",
           "Ferrari",
           "Fiat",
-          "Ford (brd)",
-          "Ford (gb)",
           "Honda",
           "Humer",
           "Hyundai",
           "Jaguar",
-          "Jeep",
           "Kia",
           "Lada",
           "Lamborghini",
           "Lancia",
-          "Land rover",
           "Lexus",
           "Maserati",
           "Mazda",
-          "Mcc  (smart)",
           "Mercedes",
           "Mini",
           "Mitsubishi",
@@ -166,18 +158,12 @@
           "Opel",
           "Peugeot",
           "Porsche",
-          "Puch",
-          "Puch mercedes",
-          "Range rover",
           "Renault",
           "Rover",
           "Saab",
           "Seat",
           "Skoda",
           "Smart",
-          "Sonstige",
-          "Ssang yong",
-          "Steyr puch",
           "Subaru",
           "Suzuki",
           "Tesla",
@@ -236,7 +222,7 @@
         "inputRange": [
           "range",
           "1010",
-          "9999"
+          "99999"
         ],
         "onlyFromRange": true,
         "valueChosenOrEntered": "1010",
@@ -474,20 +460,20 @@
       {
         "fieldType": 1,
         "name": "KaskoVariant",
-        "brief": "Kasko Variant",
-        "tooltip": "Select a comprehensive insurance variant",
+        "brief": "Hull Variant",
+        "tooltip": "Select a hull insurance variant",
         "icon": "",
         "fieldDataType": "Text",
         "inputRange": [
-          "Fully comprehensive partial SBH",
-          "Fully comprehensive general SBH",
-          "Partial insurance with partial SBH",
-          "Partial coverage general SBH",
-          "Parking damage partially SBH",
-          "Parking damage general SBH"
+          "Full hull partial Waiver",
+          "Full hull general Waiver",
+          "Partial hull with partial Waiver",
+          "Partial hull general Waiver",
+          "Parking damage partial Waiver",
+          "Parking damage general Waiver"
         ],
         "onlyFromRange": true,
-        "valueChosenOrEntered": "Fully comprehensive general SBH",
+        "valueChosenOrEntered": "Full hull general Waiver",
         "inputTriggers": true,
         "isMandatory": false,
         "errorMessage": "",
@@ -496,8 +482,8 @@
       {
         "fieldType": 1,
         "name": "KaskoSBH",
-        "brief": "Deductible Kasko",
-        "tooltip": "Select which SBH should be apply",
+        "brief": "Deductible Hull",
+        "tooltip": "Select which waiver amount should be apply",
         "icon": "",
         "fieldDataType": "Zahl",
         "inputRange": [

+ 0 - 13
pms/data/auto_brands.json

@@ -1,13 +1,10 @@
 {
   "Car": [
-    "Alfa Romeo",
-    "Aston Martin",
     "Audi",
     "Bentley",
     "BMW",
     "Chevrolet",
     "Chrysler",
-    "Citroen",
     "Dacia",
     "Daewoo",
     "Daihatsu",
@@ -19,16 +16,13 @@
     "Humer",
     "Hyundai",
     "Jaguar",
-    "Jeep",
     "Kia",
     "Lada",
     "Lamborghini",
     "Lancia",
-    "Land rover",
     "Lexus",
     "Maserati",
     "Mazda",
-    "Mcc (smart)",
     "Mercedes",
     "Mini",
     "Mitsubishi",
@@ -37,18 +31,11 @@
     "Opel",
     "Peugeot",
     "Porsche",
-    "Puch",
-    "Puch Mercedes",
-    "Range Rover",
     "Renault",
-    "Rover",
     "Saab",
     "Seat",
     "Skoda",
     "Smart",
-    "Sonstige",
-    "Ssang Yong",
-    "Steyr Puch",
     "Subaru",
     "Suzuki",
     "Tesla",

+ 7 - 0
pms/data/generate_policies.py

@@ -7,6 +7,7 @@ from datetime import date, timedelta
 RECORD_NUMBER = 50
 OBJECTS = None
 
+
 def generate_persons(number):
     print('\nGenerating persons...')
     user_url = f'https://randomuser.me/api/?results={number}&nat=ch,de,dk,es,fi,fr,gb,ie,nl,no,tr'
@@ -66,6 +67,7 @@ def generate_persons(number):
 
     return persons
 
+
 def generate_companies(number):
     print('\nGenerating companies...')
     user_url = f'https://randomuser.me/api/?results={number}'
@@ -106,9 +108,11 @@ def generate_companies(number):
 
     return partners
 
+
 def generate_attributes(name, number):
     return {f'{name} {i+1}': choice(OBJECTS) for i in range(number)}
 
+
 def get_product_line_attributes(name):
     if name == 'Life':
         return generate_attributes('Life Attribute', 3)
@@ -120,6 +124,7 @@ def get_product_line_attributes(name):
         return generate_attributes('Car Attribute', 1)
     return {}
 
+
 def get_object_type_attributes(name):
     if name == 'House':
         return generate_attributes('Hause Attribute', 1)
@@ -133,6 +138,7 @@ def get_object_type_attributes(name):
         return generate_attributes('Forest Attribute', 1)
     return {}
 
+
 def generate_insured_object(person=None):
     if person:
         return {
@@ -157,6 +163,7 @@ def generate_insured_object(person=None):
         'implementation_attributes': generate_attributes('Implementation Attribute', 2),
     }
 
+
 def generate_policies(number):
     persons = generate_persons(number)
     partners = persons + generate_companies(number)

File diff suppressed because it is too large
+ 1 - 1
pms/data/policies.json


+ 1 - 0
pms/fast_offer.py

@@ -1,6 +1,7 @@
 import json
 import os
 
+
 class Products:
 
     @classmethod

+ 0 - 3
policy.py

@@ -2,7 +2,6 @@
 # Sample Policy class definition
 #
 
-
 from polzybackend.mediators import Policy
 import pms
 
@@ -46,7 +45,6 @@ class SamplePolicy(Policy):
             result.update(insured_object['attributes'])
         return result
 
-
     def reshape_data(self, data):
         self.data = {key: data[key] for key in data if not key in ['number', 'premium_payer', 'insured_object']}
         self.data['policy_number'] = data['number']
@@ -54,7 +52,6 @@ class SamplePolicy(Policy):
         self.data['insured_object'] = self.get_insured_object(data['insured_object'])
         self.data['possible_activities'] = pms.get_activities(self.data['status'])
 
-
     def fetch(self):
         # fetch policy data from Policy Management System
         data = pms.get(self.number, self.effective_date)

+ 15 - 0
runbackend.bat

@@ -0,0 +1,15 @@
+pip install -U -r requirements.txt
+
+set LC_ALL=de_DE.utf-8
+set LANG=de_DE.utf-8
+
+set FLASK_APP=app
+set FLASK_ENV=development
+
+flask db init
+flask db migrate
+flask db upgrade
+
+python populate_db.py
+
+flask run

+ 15 - 0
runbackend.sh

@@ -0,0 +1,15 @@
+pip install -U -r requirements.txt
+
+export LC_ALL=de_DE.utf-8
+export LANG=de_DE.utf-8
+
+export FLASK_APP=app
+export FLASK_ENV=development
+
+flask db init
+flask db migrate
+flask db upgrade
+
+python populate_db.py
+
+flask run