I am having a DB table that contains orders, of which I need to take a snapshot on certain conditions. The idea behind it is as follows:
An order is opened -> all goods are assigned to the order -> the order is completed and an invoice is generated -> on order cancellation the order is staying open but a 'snapshot' of its last state is saved in DB (this could go for unlimited times, so I need any snapshot to be available, not to overwrite the last one) -> on the event of request of the same order (same client, same goods) the whole cycle repeats again..
So my question goes:
How should one implement it (I do not request code, but approaches and theory of operation)? what could the problems be in this kind of approach ?
PS: I know that this question is tightly related to my own problem, and SO is not about that, but I desperately need help cuz I am really stuck.
Sorry!
you need something to correctly model the order process, you can have a 100 tables model or an elegant 1 single table model...
this database schema should sold your problem (a single table which track the order changes)
create table orderProcessFact
(order_id,
opened_date datetime,
goods_colected_date datetime,
payment_date datetime,
invoice_date datetime,
shipped_date datetime,
canceled_date datetime
);
create table order_items
(
order_id int
item_id int,
quantity int,
price numeric(5,3),
discount ...
)
Related
currently I found myself wondering if this is the right thing to do in this case.
You see I have a database called for example Warehouse
I this database I have two tables:
[the table items is for saving the items of the system add-modify-delete records]
Items (which its columns are )
TAG_ID
P_NUMBER
QUANTITY
TYPE
LOCATION
DESCRIPTION
REASON
USERID
DATE
[the table lastchanges is for saving the items of the system that has been changed]
lastchanges (which its columns are )
ID
TAGID
PNUMBER
USERID
ACTION
DATING
Now I have been asked to add "exactly what has been changed" to the current form, for example if the quantity changed I have to show that before and after in a bootstrap form.
My brain told me to just add all the columns of the table items into lastchanges and save on those columns the data before changing and into items the new modified data, but performance-wise I see this as a bad action and I want your opinion.
If I understand you correctly you need a history of your DB changes.
If thats the point I would recommend you to create a new row for each entry and soft delete the old one. Then nothing gets lost and you can always get differences or older values.
Adding a the field deleted_at, and created_at as dates would do that trick for you. If deleted_at is null its the current entry, if there is a date set you know exactly when it got "overwritten"
I've the following model Order.
Any order can have such status as new, in work, being delivered, on storage, executed, cancelled.
I found the following code in the model:
As for now every order has number what identifies its status.
If I started the project from scratch I would rather create a separate table with the name let's say order_status and insert primary keys from it into Order table.
What approach is more preferred and why?
Thanks
you can take a column named as status and set the number what ever it is like 1,2,3,4,5,this approach is more convenient than creating a new relation ship table because it uses extra join to retrieve status,it will be useful if order have multiple status at the same time otherwise you can update status of that order in same table.
Horrible title I know, I couldn't find a better way to articulate my problem.
I searched through SO without success, but if the answer's already out there, feel free to link it and I will read it thoroughly.
I'm building a book ordering system. People will order books throughout the month, and one large order arrives at the end of every month.
Orders get recorded into an Order table with the following fields:
order_id, book_id, quantity, language, person_ordering, timestamp, month, year
When orders arrive, they are inputted into an Received table with the following fields:
book_id, quantity, language
Now suppose one person orders (2) copies of book 1. And another person orders (3). And another (5). For a grand total of (10).
Then the order arrives and it only has 7 copies.
I'm trying to write a script/function that will find out:
Which persons will receive their copies of the book (it's first come first serve, so the people that ordered it first will have their order fulfilled first.
If a person can only have their order partially fulfilled, to update the Order table (or possible a new Pending Orders table is needed?) to reflect that they have X amount still waiting to be fulfilled. Then the following month, their orders would be fulfilled first, again, based on date ordered.
I thought about pulling the information from the Orders table based on time-stamp of when the order was made and sorting through it, then pulling the information out of the Received table and somehow comparing the two arrays and updating a third array?
Or perhaps there's a simpler solution that I'm missing.
If more information is needed, I will gladly provide.
I've been pulling my hair out over this problem for 2 days straight.
Any help would be appreciated.
Thanks!
To me, it sounds like you could do away with your timestamp, month, and year variables to be replace with a single datetime stamp.
Also, add a column in your Received table for the datetime stamp of collection.
Finally, make another table to keep track of fulfilled orders.
Do a select * on the month needed ordered by the datetime stamp descending for your "orders" data.
In a separate query get your "received" data for programmatic comparison using the correct month.
Put the "received" quantity of each "received" book_id into separate variables (probably a key/value array).
For each "received" book_id, compare and compute the "ordered" quantity needed from each order in a sub-loop, updating the "received" quantity value. At the end of each iteration of your sub-loop, if your "ordered" quantity does not equal 0, then you need to add another entry for the next month with the remaining quantity, also enter all fulfilled orders into your new table.
* You **will not** want to modify any existing records, as you will almost certainly need this untouched in the future.
Clear as mud? :P
* Database tip - Every entry of every record should **always** have a datetime stamp and when possible, a "who did it".
You can try with adding an extra field in Received table.
when the order is coming you can calculate the number of copies that we can provide at that time.
book_id, quantity,qty_available, language
1. B1 2 2 EN
2. B1 3 3 EN
3. B1 5 2 EN
Assuming that the Received table is for current stock, and that orders are only shipped when the entire order can be shipped, here's a suggestion for what you can do:
Add a field to Order for whether the Order has been fulfilled.
Select from Order who have ordered the book, ordered by date. You can limit by quantity of Received.
Start fulfilling the Orders and marking them as such until quantity from Received is reached.
If what is left of Received quantity is not enough to fulfill an Order, leave it and leave the remaining quantity in Received for next time.
Hope it makes sense.
For example, let say a user purchase product called soap with price of 1.50 on 20th sept 2012. This have been recorded on database under purchase table with productID and date.
Let say on 22nd sept 2012, the admin changed the price of soap to 1.20, now the report price is changed because of this.
What is the best approach to make sure that old data of 1.50 is stored for old reports and 1.20 for new reports. Should i insert all data including, product name, product price onto purchase table?
The simple answer to your questions is yes.
When it comes to financial systems, well any systems that may be required to be audited "transactions" should be stored in their entirety in a "document" or "record".
There are other methods such as recording each deletion or modification with "flags" (E.G. current, deleted, modified, etc), "from_date" and "to_date" instead of actually deleting or modifying the data from the database, however this will use more server resources and the programming is significantly more complicated not only in mySQL but PHP also. But it allows you to provide only a relationship between records at the same time.
My suggestion is to keep it simple and store all required data in a single record. You will save time and legally, should the system ever need to be audited you're much safer.
Good luck and I hope it helps!
I don't think it is necessarry to store the product name in the purchase table, but the product price I think that should be stored.
Also if you don't store the product name in the purchase table you should take care about deleting products. Maybe deleting them is not the best idea so you should hide them from the store but not deleting them from db.
I normally store the price for the product on the purchase table with the productID and date, or if you can have multiple items in the cart, you will have a purchase table and a purchase_product table. This was if you ever add coupon codes or anything else like that you will always be able to see what the person paid for the item on that particular purchase.
I've recently been working on a product close to what you described. And I believe your answer relies on the level of complication you are willing to implement your project. The simplest way is to store product information in your invoice record. But this leads to redundancy over the time.
On the other hand you can implement a revision mechanism so you can keep track of your records' changes over the time. This can be easily done by using two ids for your records instead of one. Here's a sample table:
CREATE TABLE IF NOT EXISTS `product` (
`product_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`entity_id` bigint(20) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`price` double NOT NULL DEFAULT '0',
PRIMARY KEY (`product_id`),
KEY `inx_entity_id` (`entity_id`)
) DEFAULT CHARSET=utf8 ;
While product_id is your ordinary auto increment id, the entity_id is a special id which is the same for all the records of the same product. In this design you'll never delete a record, nor update it. You will always just insert into the table and when you need to get the list of products, you'll just have to keep in mind that a group by over the entity_id is in order. The product information can be found in the record with the biggest product_id. Perhaps you may want to create an entity table to keep track of entity_ids.
This design is more complicated than copying products' information to invoice. But it has so many great benefits. Like you can keep track of price changes of a product. Or you can use a foreign key to product_id to point to one specific revision of the product or use the entity_id to indicate a product type instead of some specific revision of it. Of course its complication will cost you but it's you who can tell if it is worth it.
I have a software in PHP and postgres that I use for invoicing. I am running a stock management system that I created. i am trying to create a stock movement page where I can see when a part came in, where it was issued and when and also when it was credited (if it was). I am running 5 tables for the stock. My main one is part2vendor, parts, expenses, wo_parts and int_part_issue. When I receive stock, it goes into the table part2vendor (onhand gets increased by number received). The expense table gets the details of the part number, the supplier invoice and the date received. wo_parts stores the part number issued to a workorder. int_part_issue is when I do a stock adjustment or use a part internally. I am looking to create a PHP table that would list (in date order) the 'paper trail' of a part. I can let you know table names and columns if required. Thanks.
Sounds like you need a simple history table?
Columns
part_history
id
part_id
date_modified (timestamp)
action ( or maybe action_id if you have an actions table)
vendor_id
And when you get a new part, and add it to the parts2vendor table ( i think u said) you would use the inserted part ID (or unique part id ) to add a record rto history
INSERT
(id, part_id, action, vendor_id)
46565, 5757575, "Purchased", 757575
The date will be inserted as a timestamp by postgres
Than for any part yuou can grab history relying on the uniquer id
sort by date_modified DESC.