entertaining-crib v8.0.1
Overview
We build a pipeline
raw-cdr | rating | aggregation | invoicingratingtranslates CDR-by-CDR, applying two rating tables, one for clients, one for carriers;aggregationmanages billing periods and applies contract elements (e.g. limits per billing period); only applied to clients;invoicingis out-of-scope.
For each call we create:
- a
traceCDR, used for troubleshooting; - two rated CDRs:
- one for "client" invoicing;
- one for "carrier" invoicing.
- an invoicing CDR.
Since LCR routing is now donne client-side, CDR generation will also happen client-side.
Project Plan
Rating
Generate rated CDRs from call data. Projet entertaining-crib
Aggregation
Projet astonishing-competition
Mapping a CDR to a rating table
We add two fields, timezone and rating, in all endpoint records:
{
"type": "endpoint"
"timezone": "{timezone}",
"rating": {
"{start-date}": {
"table": "{tarif}"
"plan": "{forfait}"
},
"{start-date}": {
"table": "{tarif}"
"plan": "{forfait}"
}
},
}{timezone}: billing timezone{start-date}:YYYY-MM-DD(sorted alpha-numerically){tarif}: used in rating{plan}: used in aggregation
Rating tables
Naming conventions
Each rating table is identified by its name. Example conventions might be:
{tarif}={client|carrier}-{start}{client|carrier}={client}|{carrier}{client}= name of client tariff{carrier}= name of carrier tariff{start}= start of applicability (YYYYMMDD, ISO8601)
Each rating table is created once and for all, and never modified.
Each rating table is stored in a CouchDB database called rates-{tarif}.
Each rating table contains records as defined in the following sections.
Configuration
One single record per rating database:
{
"_id": "configuration"
, "name": {
"en-US": "Tariff unlimited-special, starting October 12, 2015
"fr-FR": "Tarif illimité spécial, au 12 octobre 2015"
}
, "currency": "EUR"
, "divider": 1000
, "per": 60
, "ready": false
}divider: divider used on tariffs. In this example, values are computed in thousandth of Euros.per: duration used for tariffs, defaults to 60 meaning all prices are expressed as "per minute" (even though computations use thetimeparameters, for example "per second starting with the first second").currency: invoicing currencyname: names of the rating table in different locales.ready: if false, the rating table can still be edited, but not used as a tariff; if true, the rating table can no longer be edited, but it may be used as a tariff.
The configuration record is copied in the rated CDR in the field configuration.
Prefixes
There are two ways to provide rating data for a given prefix:
Mapping prefix → destination, to send multiple prefixes into a common
destinationrecord (see below):{ "_id": "prefix:336" , "type": "prefix" , "prefix": "336" , "destination": "fr-mobile" }Storing rating data directly inside the prefix record, for example for individual numbers with dedicated costs:
{ "_id": "prefix:3303614" , "type": "prefix" , "prefix": "3303614" , "description": { "fr-FR": "RSVA 3614" } , "country": "fr" , "fixed": false , "mobile": false # etc. see https://gitlab.k-net.fr/shimaore/numbering-plans for appropriate fields , "initial": { "duration": 60 , "cost": 2000 } , "subsequent": { "duration": 10 "cost": 345 } }Notes:
durationis expressed in seconds,costis expressed incurrency*divider.In this example, costs is 2€ at connection time for the first minute, plus 0.345€/minute billed by 10s increments.
Destination
The destination records are used to ease translation.
{
"_id": "destination:fr-mobile"
, "type": "destination"
, "destination": "fr-mobile"
, "description": {
"fr-FR": "Mobile France"
}
, "mobile": true
, "country": "fr"
, "initial": {
"duration": 0
, "cost": 0
}
, "subsequent": {
"duration": 1
"cost": 12
}
}Notes: duration is expressed in seconds, cost is expressed in currency*divider.
In this example, there are no connection costs, cost are 0.012€/minute rated per second starting with the first second of the call.
What does the rating code do?
The code will output rated records, with the indicated rates applied onto the record.
The records are generated in the middleware of the earthy-slave project, which uses the code in entertaining-crib to build the CDRs.
Time of rating
Rating is based on the tarif applicable at the time the call is connected, in the selected timezone.
Rated amount
Pseudo-code:
# assuming call was answered
call_duration = ...
if call_duration <= initial.duration
amount = initial.cost
else
# periods of s.duration duration
periods = Math.ceil (call_duration-initial.duration)/subsequent.duration
amount = initial.cost + (subsequent.cost/tarif.per) * (periods*subsequent.duration)
# roundup to the higher integer
integer_amount = Math.ceil amount
# this is the actual value (expressed in tarif.currency)
actual_amount = integer_amount / tarif.dividerContents
Format of a rated CDR:
{
"_id": "{billable-number}-{connect-stamp}-{remote-number}-{duration}"
"source": "{CDR source table/DB}"
"source_id": "{reference of the record in the source table/DB}"
"rating": `rating` record for the date of the call
"rating_table": full (CouchDB database) name of the rating table used
"rating_data": {
initial: {
cost:
duration:
}
subsequent: {
cost:
duration:
}
# and other data found in the `destination` record
}
"billable_number": CCNQ E.164 billable number (`33972222713`)
"connect_stamp": ISO8601 connect stamp in local timezone
"timezone":
"remote_number":
"duration":
"period"
"prefix" (object, from database)
"destination" (object, from database, if applicable)
"configuration" (object, from database)
"periods"
"amount"
"integer_amount"
"actual_amount"
}Source code
Projects entertaining-crib (rating algorithm) and earthy-slave (FreeSwitch middleware).
What does the aggregation code
The aggregation code in astonishing-competition uses the database-driven flat-ornament code execution module to convert a rated CDR into an invoicing CDR.
Target database
Note that the storing code is located in module astonishing-competition, not in the rating modules.
{period}name is algorithmic; by default =YYYY-MMbased on local time
Carrier-side: cdr-{carrier}-{period}
Client-side: cdr-{client}-{period}
Source
Projet astonishing-competition.
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago