Core a brief walkthrough through the core concepts behind the systems.

Modularity

This section describes functional modules which group functions. More about them in a less technical manner and more about the functionality itself of the functional modules can be found in the modules section.

This section is NOT about logical modules which group entities, more about those can be found in the entities section

The system is written using a highly modular architecture, as much functionality as possible is implemented in independent and loosely coupled modules. The reason for that is, that any given functionality should be not only easily configurable, but for very specific and custom needs, easily replaced with the help of a new module. This approach helps due to how line of business apps tends to need custom functionalities per organization, as each organization has it's own specific needs.

We can divide the systom in following two main parts:

  • The Backend exposing all the server side functionality through a secure WCF service.
  • The Frontend being a WPF Windows desktop applicaton, allowing user interaction with the system.

let's take a close look at those parts

Backend

The backend is composed of following components

  • The WCF Service which exposes all the backend functionality to the frontend
  • The a7 Kernel assembly, with following responsibilities:
    • Security - making sure that each incoming call and outgoing data conforms the security model and configuration of the system
    • Session handling
    • User authentication
    • Calling server module functions and subscribing event handlers from modules
    • Loading the configuration and exposing it to the modules
    • Wrapping basic CRUD functionalities

    So we could sum it up, that the kernel is responsible for security, server modules and configuration

  • Server Modules called in short SModules. We could say that each and every server functionality is implemented in the SModules, that are just a few sample usages of SModules:
    • Implementation of basic CRUD operations getting and updating data in the database
    • Handling several events in the kernel (like data loaded, record added etc.)
    • Custom functions specific for given module, called Server Module Functions in short SMF
    • Grouping configuration items, so that each entity using the module, has the configuration needed for that module.
Frontend

The frontend, having a similar architecture to the backend, is composed of following components:

  • The Shell WPF Desktop application loading the core, displaying a splash screen for authentication.
  • The a7 Core WPF assembly, with following responsibilities:
    • Security and authentication
    • Loading the configuration
    • Downloading client modules
    • Calling client module functions
    • Composing the UI with WPF controls returned by client module functions
  • Client Modules called in short CModules. Similar to the SModules, here we could say, that each and every client functionality is implemented in CModules, so here we have just a few sample usages of CModules:
    • Custom functions specific for given module, called Client Module Functions in short CMF
    • CMF returning all WPF controls which are composed to the final UI, like workspace, menu bar, navigation bar, details window etc.
    • CMF called when a menu button is clicked
    • Event handlers like record added, notification displayed etc.

Configuration

For the same reason why we decided to make the system as modular as possible, the system is as configurable as possible.

As mentioned above, line of business systems vary from organization to organization because of the specifics of each organization. It's not possible to create a line of business application that would comform even a big part of organizations.

That is why the a7 EBusiness platform focuses heavily on configurability making it easily customizable without the need to code a single line of code. Obviously, not everything is possible to be made based purely on configuration, that's why for edge cases, we can always develop simple modules which will expose any imaginable functionality for the organization.

However, without the need for writing any new module we can:

  • Create new or change existing entities, assign to them existing modules like file module, versioning, statuses etc.
  • Set up the needed fields and validation for them
  • Specify relations and associations between entities
  • Define numeration patterns
  • Create new or change existing data forms by using a simple XML based syntax, which is heavily influenced by the XAML syntax
  • Assign event handlers from existing or new modules to various events in the system.
  • Arrange object modules and boxes in the user interface
  • Defining conditions for a more granular and dedicated security and/or validation logic
  • Define conversion functions, to convert e.g. leads to opportunities to clients, email to complaints to requests to tasks, etc.
  • and many many more...

Searching

Because ebusiness systems usually contain a big amount of data, searching through that data is crucial. Even when the data is optimally distributed between several boxes, at some point at least some boxes will contain a huge amount of data.

The easiest way is the quick search, by simply typing in a single field, the systems searches for the best matches.

When the user wan't to filter data based on a certain set of fields, the column filter is the fastest way to decrease the amount of displayed records.

The most advanced is well.. the advanced filter which allows to build sophisticated filter with a few clicks. The created filters can be as complex as normally they would be created for example in SQL by data engineers.

For example, the below screenshot show a filter, for activities of which Jennifer Mouser, or the Support Team is the owner of, and which are high priority and are regarding the Mennick company.

Additionally, we can configure custom quick filters for entities for which we need a functionality to quickly filter data based on fields specific for the entity, like below for activities based on time, owner and status of the activity


Associations

Associations between objects are in the system at least as important as the data in the objects itself.

They allow to have a deeper undestanding about the contained data, like for example the associations between a phone call, a task, a project and a client.

Associations are defined by configuration in the system, following association types are available:

  • NxM - many-to-many association, like for example documents and folders, a document can be in many folders, and a folder can have many documents.
  • 1xN - one-to-many association, one parent object, can have many child objects, for example a company can have many contact persons, but a contact person can belong only to one company. Obviously this rule is configurable.
  • Nx1 - many-to-one association, just like the above mentioned, only with reversed child-parent relationship.
  • 1x1 - one-to-one association, a more specific association type between single objects, allows for inheritance-like logic, for example in the ticket sales module, it's a relation between a device object - holding common data between all devices, and a ticket machine object, which holds data which is only specific for ticket machines, and not e.g. for POS.

In the user interface the associations are mostly visualized by:

The datapicker control

Embedded lists in data forms

The relation bar

The relation tree


Aggregation

In the a7 EBusiness Platform we have the concept of summary entities which doesn't have any data on itself, but are used to display aggregation of data from other entities.

Aggregations allows to group data based on dictionary fields (like offer, category, is cancelled etc.) and datetime fields (like sales time, created on etc.), then in such grouped data we can make various calculations on numeric fields (price, sum, count etc.) like calculating the sum, mean, max, min etc. for grouped rows.

Let's for example take a look at a sample set of sales records, where every row is a single ticket sale, with pretty standard fields like offer, unit price, tax etc.

Based on those sales records, we can create a summary entity called sales summary which will allow us, to aggregate the sales data.

We can prepare preconfigured boxes for summary entities, which group the records based on predefined fields, like we can see on below screenshot on the left, there are boxes that group the sales records on the sales date, daily, monthly and yearly.

A not preconfigured box for a summary entitiy, display initially one row, which groups all the records into one group, and display the sum of all numeric records.

At the bottom of the table we can see a summary which summs all the fields in the table.

On summary entities we can apply column and advanced filter to display the aggregated data from a filtered out set of records. More about filters. For example if we wan't to display the sales summary of not cancelled sales records, we can apply a column filter:

As mentioned, we can apply any filter described in the searching paragraph. To see the numbers of the data which we need.

For summary entities we have an additional UI element, which allows us to set up the aggregation. The summary settings allows to select what calculation should be performed for numeric fields, and on which fields we want to group the data.

We can see bellow, that the aggregation settings display all fields, and have different settings for groupable fields, datetime fields and numeric fields.

Above settings together with the filtering options are a powerfull tool to generate various data aggregations and calculations for analysis. The resulting data set can be then saved using my boxes or exported to MS Excel

A example summary, let's say we wan't look at the sales between January 1st 2013 and March 30th 2013, of not cancelled tickets, grouped by device type and month of the sales time. That's how such summary looks like:

To see more details of a row, we can look up the row details by selecting a row:

All the functionality, which fields are visible, which can be grouped, which calculated, what is in the row details visible (which are available after a row is selected), what in the summary at the bottom - basically everything is build based on configuration, the framework takes care of the proper data loading from the database and calculations, no code is needed for any data source.


User Settings

Most of the workspaces give the user the possibility to customize the view of the workspace accordingly to his preferences.

For example he can turn on or off the object preview


Display objects in another view than the standard table view, like for example the cards


or in a calendar if the objects uses the calendar module


In case of the table view, the user can freely arrange the columns he want's to see in the list. The changes if set, can be applied as well for displaying object in the datapicker of that given object type (entity).

Security

Basic rules regarding security in the a7 EBusiness System

  • Security access can be set for a single user, a group or a team.
  • Difference between team and group is, that a group is more static, the defined admin group can set group members of other groups, like for example "IT Department", "Management" etc. Whereas a team is a more dynamic form of of grouping users, teams can be created and managed by specified users. We can for example have a "Project X Team" or a "Customer Y support team" etc.
  • Access to any data in the system needs to be set explicitly. That means, that when for a given user/team/group wasn't any access set for an object, the user/team/group will not have any possibility to access the object. That ensures data safety.
  • Every user can be a member of many groups and/or teams.
  • We can associated any user/group/team with many roles.
  • The efective permission set to a group of objects is the sum of the defined permission set for the user, and for the groups and teams of which the user is a member.

The permission set is defined by the concept of a mask which defines what permissions the role owner has.

There are three types of masks:

  • Entity mask - defining access to objects of a given entity
  • Relation masks - defining access to object in context of a given relation
  • Field masks - defining access to fields in objects

The entity and relation masks are a group of permissions either for whole entities, or for entities in context of a relation.

Each permission definition is based on two properties:

  • Permision type - the operation type that the permission allows/denies, like accessing, editing, adding etc.
  • Permision scope - which objects are the permission is regarding to, e.g. to all obejcts, only objects with certain category etc.
Permission type

We have following permission types available in the system for entity and relation masks:

  • Access, Add, Edit, Delete, Publish
  • Associate new child objects
  • Associate to new parent objects
Permission scope

And we have following permission scopes available to configure the security in the system:

  • All - all objects of given entity or relation are within that scope
  • Explicit - only objects where a user with "publish" permission has the object explicitly made available for the user that has this permission scope
  • Filtered - only objects that fulfill a defined filter (the advanced filter can be used to define this filter)
  • Explicit and filtered - only objects that where "publised" to the user/team/group, but also fulfill a defined filter
  • Inherited - only object displayed in context of a parent record - the permission will be inherited from the parent object

If a user/group/team has several roles with mixed scopes, the scopes are summed.

For example if in one role the user can only access documents that were explicitly made available for him, but in another role he has access to all documents of the category "Specsheets", he will see all documents with "Specsheets" category, as well documents that were explicitly made available for him, even if those are of different category.


Entity mask

The entity mask is defining the scope for each type of permissions for a given entity.

Let show a sample entity mask with following permissions:

  • Access to all documents, but permission to add new documents only with the category "contract".
  • Access only to folders that where explicitly made available for the user, and attaching documents to folders - but only to those which were created by the user.

The entity mask definition would look like this:

And below we can see the defined filters for types with the scope filtered, as we can see the advanced filter control is used, with which it's easy to build sophisticated filtering rules.

Sample of a more sophisticated entity mask:


Relation mask

The relation mask is a specific variation of the entity mask, additionally to the permission scopes and types available in the entity masks, it definition is based on a given relation for which the mask is used.

Each relation between two objects is defined in the system and has it's own id, e.g. the folder-document relation, or the company-contact person relation.

So relation masks are used to determine permissions to objects in context of the defined relation.

A example of a defined relation mask with following permissions:

  • Access to all contact persons, but only to those that are related to companies with the category "Partner"
  • Permission to add new contact persons, but only under above mentioned companies, and with selected country "Poland"

And that are the filters used for the permissions with scope "filtered":


Field mask

The system has also the logic for a more granular security management, by managing the permissions not only to entities, objects and relations, but also to single fields.

In contract to the object level of permissions, where we must explicitly set the access, in case of fields, it's the other way around - by default, if the user has access permission to a entity, he will have access permission to all the fields of the entity, and if the user has edit permission to a entity, he will have write permissoins to all the fields of that entity.

However, with the help of the field masks, we can explicitly deny access and or write permissions to a given field.

If the user has a role which denies access to a field, he will not see and/or will not be able to edit the value of that field.


Explicit permission scope - details
  • When the user/group/team has a given permission type to an entity/relation set to the "explicit" scope. Then it means that the user/group/team doesn't have the given permission type until somebody with the "publish" permission type doesn't explicitly give the permission for a single record for this user/group/team.
  • By default, when a record is created, the creator of the record gets full permission to that record. (This behavior is configurable)
  • It's for example possible to configure the security that way, that when a user creates an object, it has full permissions to it, and all member of a group of which the user is a member of, get a read-only access to the created record (if they don't have higher level permissions based on other roles)

Permissions to a record can be managed in following dialog:

If a user doesn't have the "publish" permission for this object, this dialog will be read-only for him, so that he can see, for whom there were granted permissions.

If the user has the "publish" permission, with this dialog he can make the object available for selected users/groups/teams.


JobServer

The job server service is designed to perform in the background time consuming tasks during set up intervals.

It can be things like email synchronization, thumbnail generation of documents, converting documents to PDF format, and many more.

The job server is just as the whole system based on modules and configuration. Tasks that are performed by the job server are implemented in independent modules, basically the tasks are server module functions (SMF) implemented in server modules (SModules), more about modules in the modularity section.

Which server module functions should be performed by which job server, and in what time intervals, can be freely configured without any code changes.

On the right we can see the job server monitor, a seperate application which displays information about the running tasks. The functions implemented in the modules can also define what should be displayed by the job server monitor.