PHP/MYSQL solution for e-commerce approach - php

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.

Related

Database desing Mysql

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"

update record, or delete and re-insert if the user edits their cart before processing the order

I have a table named orders_products which hold all the products associated with each individual orders. Now, if the customer decides to edit the quantity, the attributes, or simply just remove a product, what would be the easiest way to handle this change in the database?
orders_products
id | quantity | fk_products_id | attributes | price | fk_orders_nr
fk_products_id refers to the actual product id in our products table
attributes is a comma sepparated string with id's refering to our attributes table (attributes can be the angle, lenght, diameter etc. for each product. As in 45 degres, left angeled, 20 cm in length, 43mm in diameter).
fk_orders_nr is the actual order the product belongs to.
Since I have a class that handles this part on the client side. Would it be easier to just DELETE all associated products, based on the order id (fk_orders_nr), and just re-insert and updated the whole set based on what's stored in the class?
Or is there a neat way to handle this directly in MySQL?
I've looked a bit into on duplicate key update, and ignore, but they doesn't seem to fit my needs..
I need to check to see if the actual product id exists, then decide to insert new, or update existing (it could be both the quantity, and/or optional attributes), also the product might be removed if not in the list from the class anymore.
When writing this question. I think deleting the whole set, and reinsert it, might be the easiest way.
This database looks badly designed. Firstly I assume by fk_products_id you mean product_id. You do not need to specify that a column is a foreign key in its name.
Secondly, I would advise you to keep all columns atomic, as in, no multi-values. The attributes column keeping a comma-separated list will give you headaches in the future and it also breaks the FIRST normal form (the most basic one).
Thirdly, you don't need (although it could sometimes be useful) an id as a primary key in your junction table. You can just use a compound primary key from your fk_products_id and fk_orders_nr keys.
When writing this question. I think deleting the whole set, and
reinsert it, might be the easiest way.
Yes, that is the way it's usually done.
But I insist you ignore everything about the current problem you're having and redesign your database from scratch, putting special attention into normalization. These are basic database design standards and they exist for a reason. Hopefully you won't learn about the reason when it's too late.

Best approach to take snapshots of specific data

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 ...
)

Is there a field in the Magento database which holds the date for when an order is shipped?

Is there a field in the Magento database which holds the date for when an order is shipped?
The only date fields I've come across are created_at and updated_at but i don't think that's what i need.
Thanks for any help.
First off, the hierarchy of objects/database tables surrounding orders underwent a major reorganization from EAV style objects to "flat" objects during the 1.4.x branch. This specifics of this answer refer to modern versions of Magento.
When you create a shipment in Magento, you're creating a sales/order_shipment object. These objects are stored in the sales_flat_shipment table. This table has created_at and updated_at columns.
Each of these order shipment objects links to a 1 or many order shipment items objects. These objects are stored in the sales_flat_shipment_item table. Each row in this table represents a shipped line item in the order. This table links back to sales_flat_shipment by its parent_id column, and can be used to ensure a particular product, as well as its quantity, shipped.
Keep in mind that in most large scale e-commerce rollouts, Magento isn't the ultimate "source-of-truth" for what has and hasn't shipped. Every ERP integration I've ever seen is a lump of undocumented custom code that's used to communicate with an oversold bit of warehouse management software. The above data is usually used as a flag to a larger system that an order is ready to ship. Whether it has or not depends entirely on your process.
$shippingDate = Mage::getModel('sales/order_shipment')->getCreatedAt()
Comes from the sales_flat_shipment table in the magento version i'm running.
If you want to display actual shipping date then this date stored in 'sales_flat_shipment_grid' table. You can fetch data from this table using Mage::getResourceModel('sales/order_shipment_grid_collection');.
If you want to check then you can check from shipping grid at 'admin->sales->shipping'.
If this one help full then please up vote. :)

Stock movement in PHP

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.

Categories