How to manage changed items and their previous names in database - sql-server

How does one handle situation when you have sales orders and items tables, and then at one point in time you have to change an item. The change will also show up on sales order that have that item. However, lets say that at the time the sales order was place the information was correct but changed later. I don't want older SOs to change what they show for line items and I don't want to have to make new items because it will confuse me later which item is correct.
I noticed that in OpenERP it does just that, keeps the name of part number and description on sales order even if you changed it after sales order was made.

If you are creating new database restructure your Item table. Create a table (for e.g. ItemHistory). have a ItemID and ItemTypeID and DateCreated Fields on it.
ItemID should be used for orders and ItemTypeID + DateCreated will help you to get the current Item.

Related

Many employees have many courses which have expiry dates

I'm looking for the best way to store this information. Not every course has an expiry date.
The easiest way I've found so far is:
tblEmployee
-----------
ID (pk)
Expiry1
Expiry2
tblCourseCatalog
----------------
CourseID(pk)
Name
For every course in tblCourseCatalog, a new Expiry is created in tblEmployee to match tblCourseCatalog.CourseID.
I tried to have:
tblCourseExpiryDates
--------------------
EmployeeID (pk) 1:1 with tblEmployee.ID
FirstAid
UnderWaterBasketWeaving
Anytime a new course was added to tblCourseCatalog, a new column was added to tblCourseExpiryDates to match. This became tricky when trying to query some info. Does my current way (Expiry in tblEmployee) change things much from having tblCourseExpiryDates? to me, having a Expiry2 column is a waste if tblCourseCatalog.CourseID=2 (UnderWaterBasketWeaving) does not expire.
The standard normalised way to store something like this is to have a table where every row looks at just one course employee combination, holds any data that is specific to just that combination, and is usually called something like EmployeeCourse (or CourseEmployee)
EmployeeID
CourseID
ExpiryDate
You only put records in this table where you actually have a date that is valid. For a course that has no dates, no employee would ever get a record. If a given employee has never done a course, they get not record. If you want to remove a date, you can remove the record, or just remove the date but leave the record (I'd probably remove it). If you want to add a new course, you just put a record into the Course table and you're done - you don't have to change anything else.
When you need to look up the record, you need to join to the table with an outer join, so that you get any records in the main table that have no CourseEmployee record.
The downside of this normalised data is that it does make it harder to get a list of all the expiry dates for an employee in one row of output - this is where pivot tables come in (and I'm not sure how they work in access).
If you want to read more about this, look up database normalisation.

Methods to Populate Database Data for New User Sign Ups

Edit: I revised and deleted to clarify. The analogy goes... Every time I get a new customer, I want to automatically create 100 orders for them because I know all my customers want the same 100 items. But they need to be able to change the quantity after they sign up since they want different quantities. Right now I create 100 orders on the client side by .map()ing through the array of 100 orders and doing createOrder mutations in graphql (apollo), is there a better way to do this?
EDIT 2: I believe doing it on the server side at the database makes more sense. Any other advice appreciated.
Can we have a order and sub order kind of concept introduced in database .
If you know that customer is going to order all 100 items , why not create a parent order id for that customer .
When customer checkouts he would have option to edit the number of items in bag .
After customer orders we can create suborder id kind of thing for each item referring to number of items in each order with other meta details .
This would eventually lead to reduction of time in customer sign up and sub order id could be further delayed . This would also lead to reduction of unused data in case customer does not checkouts . 100 rows would be then reduced to 1 .

Salesforce Report Builder: Sorting by Grouped Total

I have a pretty basic scenario: contacts have orders and orders have order line items. An order has a forumla field on it to calculate the entire cost of the order and that is working fine. I'm trying to create a report that shows each customer name and the summed dollar amounts of all orders for that customer. So I drag the customer name onto the fields area and then add the order total field. I group by the customer full name and then I set the group by on the order total column to sum and this works fine...but then I can't sort by that column. I want to sort by total dollar amount so I can quickly see who is a high buying customer. Is there a way to order a report by a summed field or will I just have to export to Excel and manipulate the data there?
Thanks
Josh
I'm sure that this is possible. I've recreated your scenario with the standard Opportunity object and the Amount field. I have grouped on both Opportunity Name and Amount. Clicking on the down arrow button on the group gives a menu that allows you to change the sort order of the group as shown in this image.
I think the fields in your report should behave in the same way.

Using inheritance to solve a design problem

I need a table that stores items and tracks when an item is...
queued
marked for shipping
shipped
marked for return
returned
The table also needs to tell me how many items a customer...
has received in a month
has at home at this time
I tried using inheritance. I assigned each step a typeId (from 1 to 5, each id representing the current step in the workflow). This approach is not ideal because updating a workflow step erases history.
For example, if an item moves from shipped (typeId 3) to returned (typeId 5) we lose an accurate count for shipped items.
How should I approach this? Also, I prefer to keep the data in one table unless I get a compelling reason not to.
Update
Items are mailed to customers incrementally. There are limits to how many items a customer can receive within a month period, and limits on how many items a customer can have at home at any given time. For this example, let's assume 4 for earlier and 2 for the latter. A customers queue can have any number of items. For this reason, items in the queue need to be ranked so the order of items sent can be according to the customers preference.
Items that have shipped already will need to fall out of ranking (the customer can no longer modify rank after an item is sent).
No inheritance here. Time fields are actually date-time. A row is entered into the Tracking table when a customer adds an item to the queue. Other time columns from TimeMarkedShip to TimeReturned are NULL until the action happens. The TimeQueued is part of the primary key in order to allow a customer to rent an item more than once (sounds like video rentals to me).
To count items that a customer has at home you could use something like
select count(1)
from Tracking
where CustomerID = 1755
and TimeShipped is not NULL
and TimeReturned is NULL ;
Rather than a typeID for the current step, it looks like you need a boolean column for each step. Then when you want to count the "net shipped" items, you can subtract the "returned" items from the "shipped" items.
In addition, if you want to track the history, you could make each of these steps a nullable date field, so that you can see that an item was shipped on 3/5/11 and returned on 4/1/11. This may help if you're using this table in other ways, such as managing your shipping/receiving or billing. A NULL, of course, would indicate that the step has not been performed (yet).

Invoice database design

The invoice database design, might look something like this...
http://www.databaseanswers.org/data_models/invoices_and_payments/index.htm
Now If the user decides to change/revise the product code/description
It will change the previous order and invoice produce code/description :(
What do you do? Copy the product code description to the invoice table instead?
You basically have two options:
either you make your Products table "time-enabled" (also known as "temporal database"), e.g. you keep the "previous" state of your individual product in your table, and you give every entry a ValidFrom / ValidTo pair of dates. That way, if you change your product, you get a new entry, and the previous one remains untouched, referenced from those invoices that used it; only the ValidTo date for the product gets updated
or:
you could copy the products (at least those bits you need for your invoice) to the invoice - that'll make sure you always know what the product looked like when you created the invoice - but this will cause lots of data duplication (not recommended)
See this other Stackoverflow question on temporal databases as another input, and also check out this article on Simple-Talk: Database Design: A Point in Time Architecture

Resources