How To Summarize A Rollup Relationship That Cross References A Custom Object? - salesforce

We are trying to implement a University system for students, faculty, and staff to be able to better manage course registrations as well as other enrollment activities.
Consider the following problem: When a student registers for a course, the course needs to get added to the students bill as a billing line item. The bill needs to have a total price of all the courses that have been registered for that particular student. Note: We've tried to keep the process manual in order to simplify the requirements.
We have identified 4 custom objects and some important fields:
Courses - Course Name:(Primary Key), Course Size:(Number), Course Price:(Currency), Start Date:(Date), End Date:(Date), Students Enrolled:(Rollup Count)
Course Registrations - Course Registration Number:(Primary Key), Course List:(Master-Detail), Student:(Lookup), Course Price:(Formula), Course Credits:(Formula)
Billing Line Item - Billing Line Item Number:(Primary Key), Course Registration:(Master-Detail), Bill:(Master-Detail), Course Price:(Formula)
Bill - Bill Name:(Primary Key), Student:(Lookup)
We know in order to summarize the total of all course prices, we need to make the Billing Line Item the detail object and the Bill the master object. We want to perform a Rollup Summary on all the Billing Line Item prices.
We've also made the Billing Line Item the detail object and the Course Registration a master object. This is because without a Course Registration, there is no need for a Billing Line Item to exist. Also the Course Registration has the Course Price via a formula which needs to be used in order to summarize the total cost of all courses.
I've seen online that you are unable to summarize a cross-reference object. We are getting confused as to how we should summarize all the prices associated with each course. Any help would be greatly appreciated. We can provide screenshots if requested!

I don't think the reference to course price should be a formula. Next year you'll change prices and it'll retroactively screw your past invoices up? (and you wouldn't even have field history tracking on the formula field, only on the Course. So if you don't know where to look it'll be as if it always was this price)
Make it a normal editable Number field (although Currency type would be better) and use workflow / "early" flow / process builder or code to populate the list price on save. You don't lose anything (as you create new line item now you also don't see the price until you save, formula field doesn't show up on "new", right?). This normal field will already be rollup-able but you can spice things up by adding discount % or differentiate between list price, sales price... Look how much stuff is on built-in OpportunityLineItem
If you feel really fancy - you can include something that on change of Course's list price would cascade down to all registrations and billing items where status = Open(?) and update the list price...

Related

Order, OrderItem, Product. Write Product details to OrderItem?

This is not a question about a particular technical issue, more a general question about database design. Nonetheless, the tech stack is: ASP.NET MVC, SQL DB.
I've inherited a system recently which has an Order-->Order Item-->Product concept i.e. an order has many order items and each order item is associated with one product.
The Order Item stores the following when saved to the DB:
OrderID
ProductID
Qty
Unit Cost (written from Product)
Total NET (calculated based on Qty * Unit Cost)
VAT
Total GROSS
The Order Item viewed through the UI looks like this:
Qty | ProdCode | ProdDescription | Unit Cost | Total NET | VAT | Total Gross
Qty, Unit Cost and Totals are all pulled into the UI from the Order Item and the Product Code and Product Description are pulled from the associated Product record.
All seems sensible enough.
So my question revolves around which data should be written from the Product vs which data should be references from the Product. Specifically, the Unit Cost is written from the Product when when the Order Item is created. I assume this is because Product prices change and you don't want this change to apply to old orders. Fine, makes sense.
My question is: should the same logic should also apply to Product
Code and Product Description? And if not, why not?
To my mind, it seems like the Product Code and Description should also be getting written to the Order Item i.e. the Product Code and
Description are as liable to change as the Product Unit Cost. In which
case if you were to go back and look at an old order, the Prod Code
and Description on the order would appear to be different to what was originally ordered, which seems wrong to me.
The developer who built the system is no longer available to discuss his thinking when he designed it.
The system is working fine and there have been no complaints. However that is mainly because there have never been any updates to Prod Codes/Descriptions even though they are available to edit for various users.
I'd be interested to hear people's thoughts on it before I go making wholesale changes, is this a common scenario and am I worrying about nothing?
There are several aspects to take into consideration in such cases.
Let's start with the fact that the orders MUST be immutable.
Since the product code and description are not immutable, it would seem to make sense to keep them in the orders table at a first glance.
However, this may cause a massive amount of duplicated data, for each product in each order.
Another approach is to never keep the product code and description immutable.
One more approach is to enable the administrators edit the product code and description, but instead of updating the row in the products table you simply mark it as history (you will need to add a status column for that, of course) and add a new row with for that product, with the new code and description.
This solution will allow you to keep the integrity of the orders while allowing your administrator users to edit whatever they want, and keep the bare minimum of data, especially if the changes to the product code or descriptions are as sparse as you wrote.

Designing a database for stock control

Having a few issues with my database design. I have designed my system like the following image
As you can see it is a pretty basic system to a point. A user can create a supplier by adding supplier details. A user can then add a product and link it to a supplier. Thats the pretty straight forward bit (I hope!). Now I will attach my database design which should hopefully cover what I have mentioned.
So a supplier can have one contact (person within the suppliers company the user of my system will contact) and a supplier can have one to many products.
He is the part I can't figure out. Twice a week, the user of my system will receive stock from all their suppliers. When they receive this stock, they should go into the update stock screen within the application and input the amount of stock they have received for a certain product. I have added a products_stock table which should hopefully put me on my way to cover this aspect (I think it is missing a lot though).
The last screen however is a display of predicted stock. Lets say for instance on the day my products are delivered, I receive 10 units for Product One. I will then manually count the number of units I have left from the last order for Product One (say 2) and update the stock count for Product One to 12.
This means, that really, I only needed 8 units between the two deliveries for product one. The predicted stock screen is supposed to show the predicted stock levels I should place an order for, for a particular product, over a specified time period. So if 8 units was the average stock sold for product one per week, if I wanted to see how many units I should order for product one for a month, it should display about 32 units.
This is not supposed to be a complex system, it should have this manual aspect to it. I have designed the database up until a point, I was hoping I could get some suggestions regarding the products_stock table and how I can handle stock predictions for a specific period of time (if I maybe need additional tables).
Any advice appreciated.
Thanks
Inventory is more like a view and not a table. Inventory is really a series of movements of goods between locations, as well as periodic counts / adjustments.
Inventory is complex. You should play with some inventory software and read some data modeling books.
Use the concepts of Locations (real and virtual) and Movements (a movement should be its own entity).
Item smashes? Move it from its inventory location to the "damaged" location
Item went missing? Move it from inventory to the "ether" location
Found a random Item? Move it from "ether" to inventory
Sold an Item? Move it from inventory to "sold"
Bought an Item? Move it from purchased to inventory
Some other things to keep in mind:
You could sell something, and it's returned, and you put it back in
inventory
You could buy something, but it ain't right, so you send it
back to the seller
You could sell something that you don't own (on
consignment, or not in inventory yet)
You might have something in
inventory that is not currently for sale.
I won't get into the accounting aspects of inventory :)
One possible approach:
Have a separate "stock item" record for each unit received. When it is sold, record the date of sale in this record.
Then if you want to know how many items were sold in a given time range, just count the records with sold dates in that range, like select count(*) from stock_item where product_id=#product and sold_date between #from and #thru. If you need to keep track of items lost to spoilage, theft, whatever, then you might have a status flag of some kind that says whether it's in stock, sold, destroyed, whatever, and also the date of that status.
If the number of units that pass through is large and there's no other reason to keep individual stock records, you could just have "daily sales" records instead, with a date and number sold that day. Same idea.

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.

db design questions (how to deal with groups of products)

I would be grateful if somebody could help me to find an elegant solution to this database design problem. There is a company with a lot of different products (P1,P2,P3,P4) and a lot of customers (C1, C2, C3, C4). Now they have a simple database table to deal with orders, something like
20101027 C2 P1 qty status
20101028 C1 P2 qty status
Now I would like to create groups of products ( eg. (P1+P3+p4) and (P2+P3)) that could be purchase together for a reduced price. What is the best way to represent such groups in a database system? Dealing with these groups as individual products doesn't work, because I need the functionality of replacing, adding or removing products from the groups. So I need to keep the currently given table of products.
Thanks for reading. I hope I will get some help.
Add a new table product_group_promotions, with an ID, name and discount price. Then create a table product_group_promotions_products that links products to product group promotions. This will contain a product group ID and a product ID. This way, you can place one product in multiple groups, and let groups contain multiple products (of course).
Jan's answer is correct but incomplete.
You'll also need start and end dates of the promotion. You'll probably want to enter next week promotions so they are ready but not apply them until appropriate.
Discount price may not be enough either. You also will need to get business rules from business people as to how to apply the discount. It could be a percentage or a free item or a fixed amount. If a percentage do you distribute the discount evenly, proportionally, on the cheapest product, the most expensive? If a free item, which one in the set is free. It could also be a fixed amount, $10 off if you buy x, y, and z. Is the discount applied more than once. If someone buys 5x of P2 and P3 do they get the discount on all of them or just the first ones. Is there a limit over a time period. As in the past example, if you don't give me the discount on all 5, I would just fill out 5 orders of 1 each and get the discount you were trying to prevent. If so you'd have to go back through previous purchase by that customer to see if they've received that discount.
You can see how ugly this can get. I would clarify with the business EXACTLY what they plan to use this new feature for and run through these use cases with them.
As Q, asked, if the basket of purchased items is large enough there could be more than one discount possible. Do you have to determine what to give, do you present a list of choices back to the UI... and the recalculate.
This is why I have mercy on department stores who screw this stuff up. It's not simple.
On the surface this is simple sounding but in reality it's very complex.
"Dealing with these groups as individual products doesn't work, because I need the functionality of replacing, adding or removing products from the groups."
Here are several things you need to look at:
Current Inventory vs Past Orders
How do you deal with Price Changes on P1, P2, P3
How do you handle adding a new product or products to an existing group
How do you handle removing a product or products from an existing group
In my opinion you need two sets of tables.
Tables that make up your current inventory
Tables that record what customers purchased (historical data tables)
If you need to reconstruct a customers purchase from six months ago, you can not rely on the current data givin the fact that a grouping may not look the same today as it did six months ago. So, if you do not already have a set of historical data tables for customer records then, I recommend you create them.
With a set of historical data tables that house what was bought by the customer you can pretty much do what every you want to the current invetory data. Change prices, regroup products, make products obsolete, Temporarily suspend a product, etc.

Database design for a small CRM/invoicing system

I'm currently developing a small customer relationship and invoice management system for my client. And I have run into some small issues which I would like do discuss.
What is the best practice around orders, customers and products. Should my client be able to delete orders, customers and products?
Currently I have designed my database around the principle of relationships between order, customer and product like this:
Customer
ID
Name
...
Product
ID
Name
Price
...
Order
ID
CustomerID
OrderDate
...
Order Line
ID
OrderID
ProductID
Like this I can connect all the different tables. But what if my client delete a product, what happens when he later open a order he created months ago which had that item in it. It would be gone, since it has been deleted. Same goes for customer.
Should I just disable the products and customers when the delete button is clicked or what is the best practice?
If I lets say diable a product whenever my client decides to delete it, what happens then if he later tries to add a new product with the same product ID as a disabled product, should I just enable that item again?
Please share your wisdom :D
"If I lets say diable a product whenever my client decides to delete it, what happens then if he later tries to add a new product with the same product ID as a disabled product, should I just enable that item again?"
Depends entirely on your business scenario - what is unique in the way customers maintain it currently? (say manually?) How do they handle when an old product which was earlier discontinued suddenly reappears? (Do they treat it as a new product or start referring to the old product?) I guess there are no right or wrong answers to these questions, it depends on the functionality - it is always advisable to understand the existing processes (minus the software) already followed by the customers and then map them to the software functionality.
For eg. you could always add a 'A product with this code already exists - do you want to use that instead of creating a new one?' kind of a message. Also, the product ids that you use in your tables as foreign keys, and the ones that you use to show the customer, better be different - you dont want to get them mixed up.
Why would you want to be able to delete orders? I would think that such a system would lock orders so that you know you have a good history. Same goes for customers, why delete them? Perhaps a way to "archive" them, having to set some flag, that way they don't show up on customer lists or something.
As for disabling and then entering a new item with the same product ID - I'm not sure why you'd do that either, each product ID is unique for a reason, even if you discontinue a product, it should keep it's product ID so you have a record. But if you must, then you could put a constraint in the business rules, something to the effect of "If there is no product that is active with this product ID then allow it. If we have a product that is active and it has the same product ID, then throw an error." Thus, you only allow for one active product with that product ID - but honestly, I think this would be confusing, and on the back end you'll want to use a unique id that is unchanging for each product to link between tables.
Instead of "deleting" I would add a boolean column for IsActive. That way you won't loose historical data. For instance, if they are able to delete a customer then they won't be able to look at history regarding that customer and it may make looking at statistical data hard or impossible. For the order table you could have a column that represents something like "current", "canceled", "filled" to accomplish the same thing. That column should be a code to a lookup/codetable.

Resources