Database design for credit based purchases - sql-server

I need an elegant way to implement credit-based purchases for an online store with a small variety of products which can be purchased using virtual credit or real currency. Alternatively, products could only be priced in credits.
Previous work
I have implemented credit-based purchasing before using different product types (eg. Credit, Voucher or Music) with post-order processing to assign purchased credit to users in the form of real currency, which could subsequently be used to discount future orders' charge totals.
This worked fairly well as a makeshift solution, but did not succeed in disconnecting the virtual currency from the real currency, which is what I'd like to do, since spending credits is psychologically easier for customers than spending real currency.
Design
I need guidance on designing the database correctly with support for the simultaneous bulk purchase of credits at a discount along with real currency products. Alternatively, should all products be priced in credits and only credit have a real currency value?
Existing Database Design
Partial Products table:
ProductId
Title
Type
UnitPrice
SalePrice
Partial Orders table:
OrderId
UserId (related to Users table, not shown)
Status
Value
Total
Partial OrderItems table (similar to CartItems table):
OrderItemId
OrderId (related to Orders table)
ProductId (related to Products table)
Quantity
UnitPrice
SalePrice
Prospective UserCredits table:
CreditId
UserId (related to Users table, not shown)
Value (+/- value. Summed over time to determine saldo.)
Date
I'm using ASP.NET MVC and LINQ-to-SQL on a SQL Server database.

You don't pay your suppliers in Credits, so from an internal accounting perspective it would be better to hold only hard cash values (USD, UKP, whatever) against your products.
When displaying to your site's users you need a currency conversion table which translates hard prices into vouchers. Separating the data model from the front end display is a key design strategy. Whether you decide to show both real cash price and virtual credit price or just the credit valuation should have no bearing on how the data is stored in the database.

Talk to your accounting/finance people. Credit, once given, is as real as any money in double accounting, true you are not paying your suppliers in credits, but you are promising to deliver goods for credits that you will have to pay in hard cash. It should all balance at all times, and to see your complete financial position you should be able to get these credits in your balance sheet.
Try to model accounts and transactions, as well, right from the start - it will be easier to connect to finance/accounting software later and it is always good if you can run reports on both sides for purposes of reconciliation.

Related

How do I persist sales price in an orders details table?

I'm writing a simple transactional database to practice my T-SQL skills.
If I sell an umbrella in my sales.orderdetails table and it's getting the current retailprice of that umbrella from the items table and putting it in the invoice, how do I keep from having incorrect historical report data 6 months from now when I jack up the retail price of the umbrella by $10?
How do i store that umbrella sold price in the orderdetails table so it's unaffected by any changes in the items table in the future?
I know you can use an SCD for a datawarehouse for this kind of issue but was wondering how to do it in an OLTP system. Computed persisted column? Can't seem to get that to work in the object explorer when I try to enter the items.retailprice as the computed value for the salesorderdetails.cost column.
The way I have seen this done in the past, without using a technique like SCD, was to have the order detail have the price that was charged and then use a foreign key to another table, possibly products or productprices, that contains the current price.
In a full-on transactional system, you'd want the order detail row to record full retail (MSRP, or what have you), current price (in case you had the item posted at a discount that day), and price charged (in case the customer used a promo/coupon code to reduce the price themselves). Unless you log all three, you're at the mercy of whatever the price changes to tomorrow or next week or next year, which makes for bad analytics.
You probably also want to capture current cost of goods, too, since that's subject to change over time, especially in an average costing scenario. Otherwise, margin calculations will be suspect.
But then, yes, a foreign key or keys to any other descriptive tables for those less ephemeral characteristics of the product.

SQL Server Database Design - Seperate Table for Sale and Purchase

I am building a new business application for my personal business which has close to ~100 transactions of sale and purchase per day. I am thinking of having Separate tables to record the sale and purchase with another linked table for Items that were sold and a seperate linked table with items that were purchased.
Example:
**SaleTable**
InvoiceNo
TotalAmt
**SaleTableDetail**
LinkedInvNo
ProductID
Quantity
Amount
etc.,
would this design be better or would it be more efficient to have one transactiontable with a column stating sale or purchase?
-From an App/Database/Query/Reporting Perspective
An invoice is not the same as a sales order. An invoice is a request for payment. A sales order is an agreement to sell products to a party at a price on a date.
A sales order is almost exactly the same as a purchase order, except you are the customer, and a sales order line item can reference a purchase order line item. You can put them in separate tables, but you should probably use Table Inheritance (CTI, extending from an abstract Order). Putting them in the same table with a "type" column is called Single Table Inheritance and is nice and simple.
Don't store totals in your operational db. You can put them in your analytic db though (warehouse).
You are starting small, thats a quick way to do. But, I am sure, very shortly you will run into differences between sale and purchase transactions, some fields will describe only a sale and some fields that will be applicable only for purchases.
In due course, you may want to keep track of modifications or a modification audit. Then you start having multiple rows for the same transaction with fields indicating obsoletion or you have to move history records to another table.
Also, consider the code-style-overhead in all your queries, you got to mention the Transaction Type as sale or purchase for simple queries.
It would be better to design your database with a model that maps business reality closest. At the highest level, everything may abstract to a "transaction", with date, amount and some kind of tag to indicate amount is paid or received against what context. That shouldn't mean we can have a table with Tag, Date, Amount, PayOrReceive to handle all the diverse transactions.

database normalization of a table

Let's consider I have the following not normalized table
1) warehouse
id
item_id
residual
purchase cost
sale cost
Currency
I tried to normalize this and I obtained this tables:
1) warehouse table
id
product_id
residual
cost_id
2) costs table
id
purchase cost
sale cost
Currency
Does that comply with database normal forms?
Thanks much in advance!!!
This should be a comment, but it's too verbose.
There's not enough information to provide an answer - we have to infer structure from context - and the context is confusing. Your initial record looks like a description of a product to be bought and sold - but you've named it as warehouse - which is a place for storing products. I've no idea what you mean by residual. Do you have multiple purchase costs for a specific product? If so how are they differentiated. Similar for sale cost. If ther are multiple costs involved why is the selling price tied to the purchase cost?
I don't know what "residual" means in this context. But just ignoring that ...
I doubt that there's anything to be gained by breaking cost out into a separate table. Let's say we have two products, "toaster model 14" and "men's shirt style X7". Both have a cost of $12. So you create a cost record for $12, and point both records to this. Then you realize that you made a mistake and the toaster really cost $13. So you update the cost record. But that will then update the cost for the shirt also, which is almost surely wrong. Having a separate cost table would mean that you would always create a new cost record every time you created a stock record. Nothing is gained.
The fields you have listed look to me like they all belong in one table. You'd also need an item table that would have data like the description, maybe manufacturer, product specs, etc.
Your warehouse table appears to really be a stocked item table, as it lists items and not warehouses, but whatever. I suspect it also needs some sort of serial number, or how will you link a given physical item in the warehouse to the corresponding record?
If by "sale cost" you mean the price that you will charge to the customer when you sell it, I doubt this belongs in the warehouse table. When a customer buys a product, do you tell him, "I can sell you the one that's in bin 40 in the warehouse for $20 or the one that's in bin 42 for $22. Which do you want?" Probably not. I suspect you charge the same price regardless of which particular unit the customer gets. The fact that the price you have to pay to your supplier went up between when you bought the first one and when you bought the second one normally does not mean that you will charge your customer a different price. You may raise the price, but you will have one price regardless of which unit is sold. Therefore, the selling price goes in the item table, not the warehouse table. If "sale cost" is something else, maybe this whole paragraph is irrelevant.

what are the differences between inventory and products in a POS system?

I'm trying to make the database system point of sale, however I am confused between the entity and product inventory entity. What are the differences between product and inventory?
I know that the inventory should control the amount of product available .... but i have all that in products.
product code
name
description
cost
unit price
Subcategory code
brand code
amount available
Minimum quantity for rehearing
state
tax code
weight
amount wholesales
wholesales price
perishable
due date
creation date
upgrade date
what i should have in inventory? I have researched and according to what I read I need to have the product, the description, the quantity, purchase price, sale price, profit or gain and date of the transactions. But almost everything is in the Products table, what should I do?
A Product is an abstract Good or Service. A Good is the specification of an Asset.
Example "2014 Mazda 3" is a good. A "2014 Mazda 3 with VIN 12345" is an Asset.
A Catalog is the list of products that you want to sell. They don't need to exist yet, or you could be selling them for someone else.
Items Held For Sale are assets that you keep around to sell. These could be consigned (owned by someone else).
Inventory is an accounting concept. It is the dollar value of the items held for sale that you own, plus inbound and outbound goods that you're responsible for, plus any costs associated with holding that inventory.
You can track the value of inventory in a variety of ways such as FIFO and LIFO
I think you can store the inventory in the products table. There will certainly be transaction tables for purchases for the products and sales and even adjusting records (when items get count and the number differs from what's stored in the database), but you can easily work with the stock stored in the production table itself, thus not having to scan the whole database and sum up all purchases and sales and corrections every time (and never being able to delete old transaction data from the database, as that would invalidate the calculations).
However there are reasons to have stock stored in an inventory table instead. For instance if you want to store different statusses, e.g. you have 100 pieces in store plus twenty just arrived and still unchecked. Or you have a store with goods plus a warehouse housing additional stock. Or you have charges (different model numbers for example for a slightly altered product) which you offer as the same product, but still want to know how many old and how many new ones are in stock. And so on.
So make your mind up, if you want to store additional data with product stock, which would result in an 1:n relation instead of 1:1 which you have now.

Same Fact Table Column; Records with Multiple Reasons

I am in a situation similar to the one below:
Think for instance we need to store customer sales in a fact table (under a data warehouse built with dimensional modelling). I have sales, discounts related to the sale, sales returns and cancellations to be stored.
Do you think it would be advisable to store sales for a day to a customer in a particular product (when the day is the grain) as a positive value while the returns and discounts are stored as minuses?
Also if a discount is enforced to a customer at a level other than the product (for instance brand), do you think it is alright to persist it with a key particularly assigned to the brand (product is the grain) while the product column being given an N/A, for the particular record?
Thanks in advance.
If your sales are considered a good thing (I'm assuming they are) then recording sales as positive numbers makes perfect sense. Any transaction that reduces sales (i.e. discounts and returns) should therefore be recorded as negative numbers. This will make reporting your sales very natural.
If you have diffent dimensions that might account for a record, you should populate the dimensions that make sense. So yes, attribute a discount to a brand rather than a product if that is what happened in your business transaction. This way your reporting will be able to look at all discounts, at discounts for particular products and discounts for entire brands. If your fact table shows the most direct "cause" of the discount (product or brand) then your reports will be more useful than if you link the fact to brand through a relationship to product.

Resources