RevBank::Products
Product list
Synopisis
# Comments are lines that begin with a # character.
# Empty lines are ignored.
8710447032756 0.80 "Festini Peer"
4029764001807,clubmate 1.40 "Club-Mate" +pf +half
pf 0.15@+pfand "Pfand NRW-Flasche" #OPAQUE
+half -50% "50% discount \\o/"
123 0.42 "Hashtag example" #tag #tag2=42
Description
This module implements a products database, based on a text file. It supports additional fees, discounts, compound products, and optional metadata that can be read by plugins.
Functions
read_products
The only function of this module is exported by default. It returns a reference to a hash of products (each represented as a hash), keyed by product id.
The available keys per product are currently not documented; refer to the
Products.pm file after the line that is commented # HERE for a list.
Configuration
The configuration for this plugin lives in a text file called
products.
Whitespace at the beginning or end of a line are ignored. Blank lines are
ignored. Comments are lines that start with # and are also ignored. Note
that a whole line is either a comment or a data line; trailing comments are
not supported and # is a valid character in a product description.
Data lines have whitespace-separated columns:
Product ids
One or more product ids, separated by commas (no whitespace before or after the commas). There is no way to have a comma or whitespace in a product id, but every other printable character is valid.
The first product id on the line is considered canonical, the rest are aliases.
Note: if a product id is the same as another RevBank command (e.g. a username),
the first plugin that accepts the command will "win"; the precedence order is
defined by the plugins configuration file. However, when a product
id appears multiple times within products, the last one is used.
Product ids that begin with + can only be used as addons. When entered as
user input, it will be ignored by the products plugin.
Price
The price of the product. This is the price to be deducted from the user's account when they check out with this product in the cart. When it is a negative number, the user will instead have money added to their account when "buying" this product.
Optionally, the price can be augmented with an @ sign and the name of the
contra account. When no contra account is specified, +sales/products is used.
Internal accounts (that start with - or +) are created automatically. A
regular account can also be used, but has to exist before the product can be
used.
(Note on internal accounts because they aren't documented elsewhere: liability
and revenue accounts begin with +, asset and expense accounts begin with
-. The + accounts typically grow larger over time, while - accounts
typically go negative. In general, you would use a + account in
products. User accounts are liability accounts.)
Description
The description, like other columns, may contain whitespace, but to use whitespace, either the entire field "needs quotes" around it, or the whitespace can be escaped with backslashes.
It is suggested to always use quotes around the description.
Additional fields
Addons
Addons are products that are added as part of the main product. They are
specified after the description, with a + sign that has whitespace before
it, and no whitespace after it.
When specifying an addon +foo, and no product with the id +foo exists,
the product id foo is used instead. The difference is that a product id
+foo can only be used as an addon for another product, while foo can be
used either as an addon or a manually entered as a standalone product.
example_id 2.20 "Example product" +first +second
+first 1.20 "First thing"
second 0.80 "Second thing"
In this example, the final price of the example product will be 4.20. It is not possible to buy the first thing separate, but it is possible to buy the second thing separate.
The addon product must be specified in products; market products
cannot be used as addons.
When a product has addons, it becomes a compound product. This can be used to separate a product into individual counter accounts for bookkeeping purposes, to add a bottle deposit, or to add other additional fees or discounts.
When a compound product has a bare price that isn't 0.00, the bare price is listed as a component named "Product".
A product can have multiple addons. Addon products themselves can also have further addons, but circular recursion is not supported.
Percentage addons
As a special case, an addon's price can be a percentage. In this case, the price is calculated from the sum of the the product components up to that point that have the same contra account as the percentage addon.
So, given the following example,
example_id 0.90 "Example product" +some_fee +discount
+some_fee 0.15@+fees "Some fee; might be a bottle deposit"
+discount -50% "Special offer discount!"
only 0.45 is discounted, because the 0.15 has a different contra account. While complicated, this is probably what you want in most cases. There is currently no way to apply a discount to the product with all of its addons.
A percentage addon must have a product_id that begins with +.
Tags
Additional metadata can be given in additional fields that begin with # and
the name of the tag, optionally followed by = and a value to turn it into a
key/value pair. If no value is specified, a value of 1 is used.
The name of a hashtag must contain only A-Z a-z 0-9 _ characters. There must
not be whitespace after the # or around the =.
Like all the fields, the field can be quoted to contain whitespace. Note, however, that the quotes must be placed around the entire field, not just the value part.
ht1 0.42 "Just one hashtag" #tag
ht2 0.42 "Two hashtags!" #tag #key=value
ht3 0.42 "Surprising syntax" "#x=spaces in value"
Tags can be accessed by custom plugins.
The following tags are used by RevBank itself:
-
#OPAQUEWhen used on an addon, the price of the addon will be excluded when calculating the tag price. The default is to use transparent pricing, i.e. that all additional fees are included in the tag price. In specific cases, such as container deposits, the addon price should not be considered part of the product price, and
#OPAQUEcan be used.Percentage addons (like discounts) on opaque products are not supported and result in a wrong list price. In general, opaque addons need a dedicated contra account.
The tag price is not displayed in the RevBank user interface, but may be used in generated price tags and price listings.
The sum of a product's opaque prices is available via the key
hidden_fees.
By convention, tags that affect internal semantics get uppercase names. It is
suggested that tags used only by plugins get lowercase names.
Other additional fields
When any field is added after the description, that does not begin with + or
#, RevBank currently assumes it's the old syntax (which is not described in
the current version of this document!), and parses it using the old semantics
while showing a warning.
This compatibility feature will be removed from a future version of RevBank.