From 763a8857ad8a0b937f64dc0346431ef5ccb24fd7 Mon Sep 17 00:00:00 2001 From: Juerd Waalboer Date: Thu, 26 Dec 2024 02:21:18 +0100 Subject: [PATCH] Move documentation for revbank.products from plugins/ to lib/ --- README.md | 2 +- lib/RevBank/Products.pod | 156 +++++++++++++++++++++++++++++++++++++++ plugins/products.pod | 152 ++------------------------------------ 3 files changed, 164 insertions(+), 146 deletions(-) create mode 100644 lib/RevBank/Products.pod diff --git a/README.md b/README.md index 23eb650..d131f44 100644 --- a/README.md +++ b/README.md @@ -116,13 +116,13 @@ describe the inner workings in more detail: - [RevBank::FileIO](lib/RevBank/FileIO.pod) - reading and writing files - [RevBank::Global](lib/RevBank/Global.pod) - constants and utility functions - [RevBank::Plugins](lib/RevBank/Plugins.pod) - writing plugins +- [RevBank::Products](lib/RevBank/Products.pod) - revbank.products file format - [RevBank::TextEditor](lib/RevBank/TextEditor.pod) - internal pager and editor - [RevBank::Users](lib/RevBank/Users.pod) - user accounts and special accounts The plugins are mostly undocumented, but some have useful hints in the source files, and some have actual documentation: -- [products](plugins/products.pod) - [statiegeld](plugins/statiegeld.pod) - [statiegeld\_tokens](plugins/statiegeld_tokens.pod) - [vat](plugins/vat.pod) diff --git a/lib/RevBank/Products.pod b/lib/RevBank/Products.pod new file mode 100644 index 0000000..61bfaf5 --- /dev/null +++ b/lib/RevBank/Products.pod @@ -0,0 +1,156 @@ +=head1 NAME + +RevBank::Products - Product list + +=head1 SYNOPISIS + + # Comments are lines that begin with a # character. + # Empty lines are ignored. + + 8710447032756 0.80 "Festini Peer" + 4029764001807,clubmate 1.40 "Club-Mate" +half +pf + pf 0.15@+pfand "Pfand NRW-Flasche" + +half -50% "50% discount \\o/" + 123 0.42 "Hashtag example" #tag #tag2=42 + +=head1 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. + +=head1 CONFIGURATION + +The configuration for this plugin lives in a text file called +C. + +Whitespace at the beginning or end of a line are ignored. Blank lines are +ignored. Comments are lines that start with C<#> and are also ignored. Note +that a whole line is either a comment or a data line; trailing comments are +not supported and C<#> is a valid character in a product description. + +Data lines have whitespace-separated columns: + +=head2 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 C configuration file. However, when a product +id appears multiple times within C, the I one is used. + +Product ids that begin with C<+> can only be used as addons. When entered as +user input, it will be ignored by the C plugin. + +=head2 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 C<@> sign and the name of the +contra account. When no contra account is specified, C<+sales/products> is used. +Internal accounts (that start with C<-> or C<+>) 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 C<+>, asset and expense accounts begin with +C<->. The C<+> accounts typically grow larger over time, while C<-> accounts +typically go negative. In general, you would use a C<+> account in +C. User accounts are liability accounts.) + +=head2 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. + +=head2 Additional fields + +=head3 Addons + +Addons are products that are added as part of the main product. They are +specified after the description, with a C<+> sign that has whitespace before +it, and no whitespace after it. + +When specifying an addon C<+foo>, and no product with the id C<+foo> exists, +the product id C is used instead. The difference is that a product id +C<+foo> can only be used as an addon for another product, while C 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 C; 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. + +=head4 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 I that have I 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 C<+>. + +=head3 Tags + +Additional metadata can be given in additional fields that begin with C<#> and +the name of the tag, optionally followed by C<=> and a value to turn it into a +key/value pair. If no value is specified, a value of C<1> is used. + +The name of a hashtag must contain only C characters. There must +not be whitespace after the C<#> or around the C<=>. + +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, but are currently ignored by upstream +RevBank and its plugins. + +=head3 Other additional fields + +When any field is added after the description, that does not begin with C<+> or +C<#>, 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. diff --git a/plugins/products.pod b/plugins/products.pod index 877fd27..bc7b785 100644 --- a/plugins/products.pod +++ b/plugins/products.pod @@ -2,154 +2,16 @@ products - RevBank plugin for selling products -=head1 SYNOPISIS - - # Comments are lines that begin with a # character. - # Empty lines are ignored. - - 8710447032756 0.80 "Festini Peer" - 4029764001807,clubmate 1.40 "Club-Mate" +half +pf - pf 0.15@+pfand "Pfand NRW-Flasche" - +half -50% "50% discount \\o/" - 123 0.42 "Hashtag example" #tag #tag2=42 - =head1 DESCRIPTION -This plugin turns products from a product list into RevBank commands, +This plugin turns products from the product list into RevBank commands, that add the respective products as Entries to the current Cart. +Note that by design, RevBank does not depend on this plugin or the products +list that is shared between some of the plugins. It is possible to use a +different source of products (e.g. an external database) in addition to, or +instead of, this plugin. + =head1 CONFIGURATION -The configuration for this plugin lives in a text file called -C. - -Whitespace at the beginning or end of a line are ignored. Blank lines are -ignored. Comments are lines that start with C<#> and are also ignored. Note -that a whole line is either a comment or a data line; trailing comments are -not supported and C<#> is a valid character in a product description. - -Data lines have whitespace-separated columns: - -=head2 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 C configuration file. However, when a product -id appears multiple times within C, the I one is used. - -Product ids that begin with C<+> can only be used as addons. When entered as -user input, it will be ignored by the C plugin. - -=head2 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 C<@> sign and the name of the -contra account. When no contra account is specified, C<+sales/products> is used. -Internal accounts (that start with C<-> or C<+>) 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 C<+>, asset and expense accounts begin with -C<->. The C<+> accounts typically grow larger over time, while C<-> accounts -typically go negative. In general, you would use a C<+> account in -C. User accounts are liability accounts.) - -=head2 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. - -=head2 Additional fields - -=head3 Addons - -Addons are products that are added as part of the main product. They are -specified after the description, with a C<+> sign that has whitespace before -it, and no whitespace after it. - -When specifying an addon C<+foo>, and no product with the id C<+foo> exists, -the product id C is used instead. The difference is that a product id -C<+foo> can only be used as an addon for another product, while C 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 C; 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. - -=head4 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 I that have I 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 C<+>. - -=head3 Tags - -Additional metadata can be given in additional fields that begin with C<#> and -the name of the tag, optionally followed by C<=> and a value to turn it into a -key/value pair. If no value is specified, a value of C<1> is used. - -The name of a hashtag must contain only C characters. There must -not be whitespace after the C<#> or around the C<=>. - -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, but are currently ignored by upstream -RevBank and its plugins. - -=head3 Other additional fields - -When any field is added after the description, that does not begin with C<+> or -C<#>, 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. +See the documentation for C (hint: in C).