The CART system.

In a earlier post I’ve discussed the Items-Transactions-Contracts principle. Today, I am going to expand my views on this topic with the CART system, which is basically a system that can handle items, transactions and contracts.

CART stands for Catalog, Actions, Rules and Templates. And yes, you might already see how ITC fits into CART. The catalog contains all items in your system. The actions are the transactions of your system. The rules are your contracts. And the templates are all the templates you’ve defined for the items, transactions and contracts.

For those who want to look for a matching database model in this system: don’t! There is no model that can handle it all. These are actually four different class models and classes are more than simple database models. They include code that act upon the data. But if you do want to create a data model, just consider this as a system with four different models that are connected to one another. (Maybe three if the templates are only defined by code and metadata.)

When you create a new system, you first have to set up the catalog. Why? Because the catalog is the inventory of everything that you’re going to handle. Next, you set up the actions so you know what you can do with those items. In general, you can just move them around, create new ones or remove existing items. This is all arranged by the actions system. Once you have defined all actions, you start to combine them into rules. If you want to sell an item to a customer, you’re probably end up with several connected transaction. One that sends the item to the customer, one that receives the payment from the customer and maybe one related to VAT that you have to send to the Tax Office. Thus a single sale actually results in several actions. Once you have defined all catalogs, actions and rules, you’ve probably created the templates too. Because every definition of an item, transaction or contract will end up in your template system.

So, let’s consider a simple example to use this principle upon. Let’s organize a garage sale. Say, you have a goal to reach: $500. You want to reach this by selling all your old stuff thus you announce a garage sale. You create a few flyers and you make some cold lemonade so you have some added expenses that you also have to earn back. And to keep track of it all, you want a system to keep track of all the numbers.

First of all, you already have a basic CART system with simple templates for contracts, transactions and items. An item is just a GUID to identify the item. You won’t need anything more. The transaction is a record with a GUID as identification and three other GUID’s for the sender, receiver and the item itself. Sender and receiver can be null. Last, you will need a contract which will also have a GUID as identifier and a link to the transaction templates that it supports. Which also means that you need a way to store templates in some way, but let’s identify them with a single GUID too, plus a unique name and version number. (The version number is required if you’re going to support it and want to alter the system in the future.)

First of all, you define the persons. One is you, the salesperson. One is the customer. Templates for these are simple and more than the basic item plus a name would not be required. You would also create similar item types for the goal you want to reach and the expenses you have. The goal type could have an extra description to explain the goal in more details. Then you will create the type for the items that you’re going to sell. Call them products and give them a name and a short description. Add a monetary field to the record for the default price. You might give discounts but this would be the price you would ask. And maybe even a picture if this is going to be an online garage sale. Since you’re going to give away lemonade and perhaps snacks too, you might also want to create an item type for these, since these will result in added expenses. These too would have a name and a cost price. This all will be your catalog and all these definitions are stored in your templates system. (Which could have any form. A Database model, class definitions, whatever.)

Next, you will fill them with records. Add yourself as salesperson. If your wife and kids are also helping, add them too as sales persons. However, adding more than one salesperson might need an additional shop item, with transactions between shop ans salesperson to move products. Add a single customer record, unless you have a few customers who are special or when you want to keep track of your customers. In that latter case, you would have to add customer records when you sell an item to a new customer.

Add all the things you want to sell to the products. When you’re selling lemonade, make sure you also add “Glass of lemonade” as product! Finally, add the expenses that you’re likely are going to have. Bags of chips or peanuts, bottles of lemonades or whatever else you use to make lemonade, glasses, if you use real glasses to serve your customers because even if they return the glasses, some might break. Or paper cups if you don’t use glasses. Anything that you think is important to keep track of.

Next, the actions with all possible transactions. And suddenly you will realize that I haven’t added “money” as item. Yeah, that’s right. I forgot, so add a new type to the items for money. Simply the ID and the name “Money”. Then add a money record for the currency of your choice. Add multiple records if you want to support multiple currencies, although that would make trading a bit more difficult, since it means that you will have to convert the base prices of the items to the different currencies.

So, let’s define a few transactions. First of all you can have one where the salesperson sends a product to the customer. The customer would then have to send money back to you. The product transaction is simple: salesperson, product, customer. The money transaction is a bit more complex, since it has a customer, money and salesperson field, but also an amount field to specify the exact amount that is paid.

If you want to allow refunds, you would also need transactions for the reverse order. These would be different transaction types. (Then again, you could also delete existing transaction records but then you’ll lose a historic overview.

Next, you will need money transactions to send money from the salesperson to the goal and to send money from the salesperson to the expenses. But expenses and goal have a limit to the amounts they can receive so whatever remains would be profit. Which reminds me, I’ve forgotten to add “Profit” as an item type. Add it, with one profit record.

Did you notice that I did not add an amount field to the goal and the expenses? That’s because we’re going to set these values by transactions! To set up our goal, we need a transaction with the goal as sender, since we want to reduce its amount. When the goal reaches zero, its solved. (Same for expenses.) And it’s a money transaction so the item we’re sending would be money and we need an additional amount field. The target is void, null. We could define an extra item that we’re using to specify the exact destinations that the money is used for, but for our sales system, it’s just not important enough. Remember: we don’t have to include the whole world in our application!

The expenses are a bit similar, although here the sender is a specific expense. And the amount would default to the amount specified by the expense itself. (Unless we got a discount when we buy a new bottle of lemonade, of course.) And again, these amounts are sent to the void, unless you want to keep track of where you’ve bought the stuff.

So now we have transactions for customers making purchases, customers asking for refunds and for maintaining the expenses and keeping track of reaching our goal. And already we see the rules in this all! One rule is for making purchases. A customer buys something so we have two transactions. A product moves to the customer and money to the salesperson. However, we need more transactions, since the money is used to reach our goal! So the purchase rule would need a transaction to send money to the expenses first, because we first need to pay the expenses before we have money available for our goal. Once the expenses reaches zero, we can add money to our goal. When our goal reaches zero, we add money to our profit.

When we allow refunds, we’ll need a refund rule, which would basically do the reverse of a purchase. But refunds will need us to move money away from our profit, goal or even expenses. So when we do a refund, we first lower our profit, making sure we never get a profit below zero. When we have no profits, we will add the refund as an extra expense. Don’t subtract it from our goal but just remember that we can only reach our goal when our goal and our expenses have reached zero. So, basically if we have to do a lot of refunds, we have a lot of expenses, even though we have reached out goal.

And we need a rule for our expenses, which basically means we’re going to the supermarket to buy snacks and lemonade to serve. Since we don’t really care about the supermarket, we’ll just receive lemonade and snacks from the void while sending money to the void. (Actually, we could have replaced our customers by the void too, but it’s better to use customers so we know which transactions are actually sales and refunds, and which ones are just expenses.

So now we have a bunch of contract and transaction templates:

Purchase contract:

  • Salesperson gives the product to customer.
  • Customer gives money to salesperson.
  • Salesperson adds money to expenses.
  • Salesperson adds money to goal.
  • Salesperson adds money to profit.

Refund contract:

  • Customer gives the product to salesperson.
  • Salesperson gives money to customer.
  • Salesperson removes money from profit.
  • Salesperson removes money from expenses.

Expense contract:

  • Salesperson removes expense item. 

Shopping contract:

  • Salesperson removes money from expenses.
  • Salesperson adds Expense items.

Balance contract:

  • Profit moves money to expenses.
  • Profit moves money to goal.
  • Goal moves money to expenses.

Setup contract:

  • Remove money from goal.
  • Remove money from expenses.
  • Add salesperson.
  • Add shop if multiple sales persons are added.
  • Add customer.
  • Add products to salesperson. (Or shop.)
  • Add expense items.

When you use multiple sales persons, you might consider adding transactions to send products from the shop to the salesperson, and back again for the refunds. You can also choose to have products sent directly from the shop to the customer, with the money being paid to the salesperson. You might want to keep track of how much each salesperson makes, otherwise it’s no use to have multiple sales persons. Your salesperson would be the shop. The products transactions between shop and sales persons would be to keep track of who sold which item…

This all defines our CART system for a simple garage sale. We have a bunch of items in our catalog, a bunch of possible actions and six contracts. All of them defined as templates and the contracts will need some code to check for the actual status of our goal, our expenses and even keeping track of our expense items, because when we run out of lemonade, we might need to buy more.

The next step would be to design some data models for the four different systems, to connect them and to finally create a nice user interface for the application. But that’s a nice challenge for my readers. Just keep in mind that you’re supposed to keep things simple.

Before you start selling, you would need to set up the shop, which would need the setup contract to be used.

And at the end of the sale, what you would like to do is to check if your expenses are zero. If they’re below zero, you will need to balance the three accounts. (Expenses, goal and profit.) This requires the balance contract that I’ve added to the list. Basically, your expenses must reach zero, else the whole thing has been a huge loss. Next, your goal needs to be zero, else you haven’t reached your goal. Finally, whatever is in your profit will be your profit of the garage sale, which you might use to celebrate a great action.

Next, if you want to build the thing in some client-server style, the contracts would be the web methods that you will need to create. You will also need a method to give you all the items in your system, which you will need in your client. Your client might want to display each and every purchase and refund so you might want to get all these contracts with related transactions. But you’re probably more interested in the current status so it’s more likely that you just want to see the amounts left in your goal, expenses and profits, and perhaps also for each salesperson. Basically, that would just be a method that would sum up all money transactions related to a specific item. You would send the item ID to the server and it would return an amount back.

First! A new project.

I have been working on a simple project to maintain a lot of data for the game Grepolis which I happen to like. I am just in one world, on the Dutch version, which is called Nu. And while playing this game is fun, I’ve decided to combine this kind of fun with another kind of fun: software development.

As it turns out, Grepolis provides a web API which allows everyone to collect data from every world within the game. So by using this API to import data to my database, and then use this database to feed it to my websites and other application, I can make some good use of this all. And it became quite practical.

But a fun project can grow to something bigger. So I decided to share my code at Google Code but this needs the code to be cleaned up a lot. This is supposed to show the best of my skills and if it looks bad, my skills are bad. I don’t want my skills to be bad. So by sharing the code I also hope to receive some feedback. Feedback is good. It’s nice to hear it looks nice. It’s even nicer when other people will show me the flaws in my work.

For now, the project has one owner, who will do all the hard work. This might change in the future, when the code has matured a lot and enough volunteers are available to help me with the code and the additional content. It doesn’t do much. The web site won’t even compile at this moment because I’ve changed too much in the database and business layers. I will be working on that, but first I need to get the datamodel just right, then make sure I have a working business layer. The most important part of this project isn’t displaying the data, it’s importing the data. And that’s not as easy as it appears.


Since I quit Grepolis a while ago, I also stopped maintaining the code. It has been removed from Google Code and my copy of the code is lost in the catacombs of my enormous backup archive. For those who are still interested, I will try to find a copy of the code to put online.