I am using this code to create an invoice in Magento:
$invoiceId = Mage::getModel('sales/order_invoice_api')->create($order->getIncrementId(), array());
This automatically assigns a number (increment_id) to the invoice, for example 100016050. I want to create an invoice where the increment_id of the invoice = the increment_id of the order.
How can that be done?
Thanks!
This would require coding a complete custom module, so I'll just explain some basics.
In Magento, entities like order, invoice, creditmemo and shipping each have its own and independant number group per store_id.
These number groups can be defined in the table eav_entity_store:
entity_store_id entity_type_id store_id increment_prefix increment_last_id
1 5 1 1 100000000
2 6 1 2 200000000
3 7 1 3 300000000
4 8 1 4 400000000
To know which entity_type_id refers to which entity, check your eav_entity_type table:
entity_type_id entity_type_code entity_model
5 order sales/order
6 invoice sales/order_invoice
7 creditmemo sales/order_creditmemo
8 shipment sales/order_shipment
Note that your entity_type_id's may (or may not) vary from that.
Magento usually increments each of this entities by one, see eav_entity_type.increment_per_store.
This happens the time such entity is created. But, the creation of an order doesn't always mean, that an invoice for it will be created, too. For example the user could cancel the payment while order placing, or the payment will not be authorized by the payment provider, so no invoice would be created.
This may lead to gaps, e.g. order already at 100000005, while invoice still at 200000002.
Your code would need to manage this gap in a way that keeps order and invoice in sync.
To do this, you could create an observer for the sales_order_invoice_save_before event, for example.
app/code/local/Mycompany/Mymodule/etc/config.xml:
<config>
<modules>
<Mycompany_Mymodule>
<version>0.1.0</version>
</Mycompany_Mymodule>
</modules>
<global>
<models>
<mymodule>
<class>Mycompany_Mymodule_Model</class>
</mymodule>
</models>
<events>
<sales_order_invoice_save_before>
<observers>
<myobserver>
<type>singleton</type>
<class>mymodule/observer</class>
<method>salesOrderInvoiceSaveBefore</method>
</myobserver>
</observers>
</sales_order_invoice_save_before>
</events>
</global>
</config>
app/code/local/Mycompany/Mymodule/Model/Observer.php:
class Mycompany_Mymodule_Model_Observer
{
/**
* Hook to observe `sales_order_invoice_save_before` event
*
* #param Varien_Event_Observer $oObserver
*/
public function salesOrderInvoiceSaveBefore($oObserver)
{
$oInvoice = $oObserver->getInvoice();
}
}
Magento passes the invoice object to this observer, before the invoice object is saved. This would allow you to retrieve the related order object (and therefore the order's increment_id) using this invoice object.
Having retrieved the order.increment_id you could search the invoices to find out whether or not an invoice with that order.increment_id already exists.
If it doesn't exist yet, you can assign the value of order.increment_id to invoice.increment_id before leaving the observer and are done.
Please note, that these are only the basics. There are some more pitfalls to it.
For example, multiple and/or duplicate invoices per order cases are not handled yet.
For example, in some countries the fiscal/tax authorities require invoice numbers to be continuously increasing. It must be 1, 2, 3, 4, 5, but 1, 2, 3, 4 is missing, 5 is not acceptable. Using the technique above, such gaps can still happen, because of payment cancellations by the user, etc.
However, this should get you on the right track.
Related
I just have a question regarding how to implement some logic.
Im building a API that allows the client to create orders.
This is solved by a OrderController#create so no problem!
Now, the issue is that an order can have many order-rows, all the relations are set correct but where should i create the order-rows in for the order?
Should the OrderController handle this or should i have a new controller that creates the order-rows for the particular order?
The clients post is sending the following json-data:
{
"status": "paid",
"total_sum": 20,
"payment": "card",
"order_rows": [
{
"id": 12,
},
{
"id":13
}
]
}
I ran into something similar with a project I'm working on now. The best (and long term simplest) solution was definitely to make a whole new model/controller.
*Order
status (should be an int or enum probably)
total (should loop through all order rows and total)
payment (should be an int or enum probably)
has_many order_rows
**OrderRow
belongs_to Order
item_sku
item_name
item_descr
item_cost
etc. etc.
This allows you to easily search for not just items, but orders that include items by name or sku, orders that include items by description.
Your totals are dynamic.
You can retrieve total order numbers or movement numbers on a per item basis.
It is so much easier to create and update orders.
The benefits go on.
It can easily be scoped;
scope :this_orders_rows, -> (order_id) {where(order_id: order_id)}
And it saves you from having to parse through hashes and arrays everytime.
To get technical about it, your order_controller should control ONLY your orders. If you start adding in a heap of other code to read through the arrays its going to get VERY cluttered. It's always better to move that to some other area.
On our product gallery page, I'd really like to query the database to find how many of each product has been purchased, and print that number on the page (for admin users only). I feel like I have all the pieces, I just don't know how to put it together to work.
There is a Products table that is referenced to print out all the products.
There is an LineItems table (Spree::LineItems >> Spree::Orders) where the product can be called/identified by:
#line_items.each do |line_item|
line_item.product.id
end
& this is what defines an order as complete in relation to that line_item:
#line_item.order.state == "complete"
So...I'd like to see if #product.id and #line_item.product.id match (where the #line_item.order.state == "complete") and count how many.
Basically, we iterate each product on the gallery page, so I want to see for each product how many times it appears as a line_item in an order where the order.state is complete
I'm no engineer (as you can obviously tell), but I feel like I'm making this more complicated than it needs to be. Help?
We're using a Postgres database. Thanks in advance!!
That should give you a count of line items associated at the same time with a product with the given id and an order with 'complete' state.
LineItem.joins(:product, :order).where(orders: { state: 'complete' }).where(products: { id: your_product_id }).count
No need to iterate! Just a database query (using ActiveRecord), which also is extremely more efficient than iteration.
I assumed your tables are called orders, products (used in the where clauses) and the associations on the LineItem ActiveRecord object are called order, product (used in the join). Otherwise simply replace those values with the appropriate ones.
I have a model with following columns
Charges Model
Date
fee
discount
Data
1/1/15, 1, 1
1/1/15, 2, 1
2/2/15, 3, 3
I have a few named scopes like this_year
I want to do something like Charges.this_year.summed_up
How do I make a named scope for this.
The returned response then should be:
1/1/15, 3, 2
2/2/15, 3, 3
Assuming you have a model with a date field(eg. published_at) and 2 integer fields(eg. fee, discount). You can use "group" method to run GROUP BY on published_at. Then just use sum method if you want only sum of one fields. If you want more than one field, you have to run a select with SQL SUMs inside, to get multiple column sums. Here is an example.
Charge..group(published_at)
.select("published_at, SUM(fee) AS sum_fee, SUM(discount) AS sum_discount")
.order("published_at")
Note: Summarized fields won't show up in rails console return value prompt. But they are there for you to use.
Depending upon what end result you want, you may want to look at .group(:attribute) rather than .group_by:
Charge.group(:date).each do |charge|
charge.where('date = ?', charge.date).sum(:fee)
charge.where('date = ?', charge.date).sum(:discount)
end
I found this approach easier, especially if setting multiple conditions on the data you want to extract from the table.
In any case, I had an accounting model that presented this kind of issue where I needed credit and debit plus type of payment info on a single table and spent a fruitful few hours learning all about group_by before realizing that .group() offered a simple solution.
I am trying to create an object from several models which I can return using an active record query. The aim being to use the results to create a CSV output file from a subsequent query.
Lets say I have a simple model of items which have a status. The status is held with the ID as you would do in a normalised database. An item would have many statuses and a status would belong to an item (to achieve the relationship).
I've put some data in to illustrate this:
Item (model)
============
id status_id
---------------
1 1
2 2
3 3
Status
============
id title
---------------
1 Available
2 Loaned
3 Missing
Basically I want to be able to return the data as follows in an object:
item_id status_title
--------------------
1 Available
2 Loaned
3 Missing
I know I could achieve this using a "find by sql", however I was hoping this could be returned using active record and relationships.
I've had a look at trying to use delegate but couldn't get that to work (assuming that it would do what I need).
Anyone advise on if this is possible?
You should declare belongs_to association:
class Item
belongs_to :status
end
and use it in AR query:
Item.joins(:status).select('items.id as id, statuses.title as status_title')
I want to build functionality in my Rails application that shows follower trends over time.
Currently, my following methodology involves creating and destroying relationship objects - following creates an object with the IDs of the follower and followed and unfollowing deletes that relationship object.
Since the relationship object is deleted upon an unfollow, it's impossible to go back and look at how many followers existed for a followed at any given time.
To solve this, the best solution I can think of is this:
Instead of deleting a relationship object upon unfollowing, create a new object with a negative value of, say, -1. Following would create an object with a positive value of +1. Therefore, adding up the total values for a given pair would yield whether or not they were currently following (1 or 0), while historical trends could also be calculated by adding up the total following values for a given followed.
My question is: Is this the most elegant solution this problem? Is there an easier way to do it? I realize that it's possible to use cron jobs to output a daily number, but that seems like it would duplicate data. Any other suggestions?
Any help would be greatly appreciated!
I would add an active field then instead of deleting the relationship record I would set the record to inactive. Then you'll have to update all of your user facing queries to reflect active = 1. Then you can use the records with active = 0 for reporting purposes. You can also add a deactivated_at field that stores the date that the record was deactivated.
An example scenario would be user 1 follows user 2, follows user 3, follows user 4, un-follows user 2, re-follows user 2, un-follows user 4.
follower_id followed_id active created_at deactivated_at
1 2 0 9/10/2012 9/13/2012
1 3 1 9/10/2012 NULL
1 4 0 9/10/2012 9/17/2012
1 2 1 9/16/2012 NULL
just use paranoia
https://github.com/radar/paranoia
class Relationship < ActiveRecord::Base
acts_as_paranoid
...
end
(if you have a unique index over the two numeric ID columns, remove it, use a plain index)
Then you can have
def currently_following_count(uid)
Relationship.where(:followed_id => uid).count
end
def historical_following_count(uid)
Relationship.unscoped.where(:followed_id => uid).count
end