This document provides an introductory overview of the major modules and scripts in the Freeside system. It is targeted towards the version 4 branch. It is not comprehensive, but is rather designed to help new developers get started. Code snippets are illustrative, and developers should consult the embedded pod documentation for any given module or method before using it.
Code Base Structure
The most essential directories for you to know about:
- perl modules in the FS namespace.
- mason cgi scripts and other files for the main web interface
- standard installed scripts that keep Freeside running
- additional helpful scripts, not automatically installed or integral to functioning
- a separate web interface to allow individual customers to access their accounts
- the "next generation" of the selfservice interface, built in php
- code for the integrated ticket tracking system, mostly third-party but contains some customizations
Typically, a project will involve updating code in FS/FS and httemplate.
Most objects described below use FS::Record as a base. This provides common methods for storing and retrieving records from the database. By convention, modules that create Record-based objects have all-lowercase names, with mixed-case used for mixins and objects that are not stored in the database.
Record objects are not automatically updated in the database when manipulated; for this, the standard methods insert, replace and delete are provided (though they are often overridden by individual modules to perform additional module-specific actions.)
The standard method check is run by insert and replace to validate data before storing it it the database. This is almost always overridden by individual modules according to its specific validation needs. FS::Record provides a variety of common methods for validating individual fields in check (e.g. ut_float to validate a floating-point number, ut_floatn if that field is allowed to be null, etc.)
To retrieve data from the database, functions qsearch (for multiple records) and qsearchs (when you expect only a single record) are provided. These must be imported explicitly from FS::Record into your script. They return appropriately blessed objects in the FS namespace.
People with access to the main web interface are known as Employees (FS::access_user). Each employee can belong to one or more Employee Groups (FS::access_group), which define their access rights to the system and the customers they are allowed to view. Because of the module names, employees are also often just called users.
Access rights are defined in FS::AccessRight and consist of plain english strings describing the right (e.g. 'Edit customer', 'Change customer package', etc.) Appropriate access rights should always be checked in the web interface before any data processing occurs.
Within the web interface, the FS::access_user object for current authenticated employee can be accessed in the variable $FS::CurrentUser::CurrentUser. Access rights can be checked for this object using the access_right method, e.g.
die "access denied" unless $FS::CurrentUser::CurrentUser->access_right('Edit customer');
Ensuring that agents only access their own customers is referred to in the code as "agent virtualization", and for the most part it must be done individually in any qsearch call, with the aid of the FS::access_user method agentnums_sql:
my @cust_main = qsearch( table => 'cust_main', extra_sql => 'WHERE ' . $FS::CurrentUser::CurrentUser->agentnums_sql, );
The SQL code returned by agentnums_sql will check the appropriate employee access rights and the agents associated with the employee group, returning only those records the employee has access to. Additional parameters may need to be passed to agentnums_sql, depending on the circumstaces.
Agents (FS::agent) are resellers in the system. Each agent has many customers, but each customer has one and only one agent. Even if a system is not being used by multiple agents, an initial "Internal" agent is created upon system installation, such that customers will always have an agent.
Configuration for agents occurs under the Companies subheading in the Configuration drop-down menu of the main web interface, though that terminology is not used much beyond that.
An FS::cust_main object represents a customer. For the most part, this will be regular telecom customers. Most actions that can be taken, from ordering a package to generating a bill, occur through FS::cust_main methods. A great number of tables link back to cust_main, and they will be discussed in their own sections below.
There is also a master "System Accounts" customer created upon installation, and individual agents can also have a master customer assigned to them. These are used for things like tracking system wide services such as domains.