I'm selling virtual products in my store where my customers buy a subscription for sth. This subscription is valid for 31 days beginning with the day when the order has been completed.
How do I find out the day when the order status had been set to completed?
My Idea was to look for the "updated_at" field of an order but I'm unsure if this is the right way to determine when the order was completed.
$sales_model = Mage::getModel("sales/order");
$all_orders = $sales_model -> getCollection()
->addFieldToFilter('status', 'complete')
->addAttributeToFilter('updated_at', array(
'from' => $one_month_ago,
'to' => date('Y-m-d 24:00:00'),
'date' => true,
)
);
The way I would approach this, is by create a custom module the keep track of the order status using observer
See Magento order status change events
Then log (in a db) the order # and date when the order was complete and expire. This way you could easily run report on when subscription will expire
Customize Magento using Event/Observe
Related
$collection = $this->_itemCollectionFactory->create()->getCollection();
$collection->getSelect()->columns(array('total_orders' => new \Zend_Db_Expr('COUNT(order_id)')))
->columns(array('total_qty' => new \Zend_Db_Expr('ROUND(SUM(qty_ordered))')))
->group('sku');
$collection->getSelect()->limit(3);
$collection->addFieldToFilter('store_id', 2);
Through this code i can get the total quantity and total number of orders of all sales rep. But i need only those total quantity and total orders which were done by the Sales Rep og Logged in Sale Manager.
As you mentioned in your question you only want to get the order info based on a certain sales rep. To do that you need to somehow find a unique identify for the currently logged in sales rep and add a filter for that .
For example:
$collection = $this->_itemCollectionFactory->create()->getCollection();
$collection->getSelect()->columns(array('total_orders' => new \Zend_Db_Expr('COUNT(order_id)')))
->columns(array('total_qty' => new \Zend_Db_Expr('ROUND(SUM(qty_ordered))')))
->group('sku');
$collection->getSelect()->limit(3);
$collection->addFieldToFilter('store_id', 2);
$collection->addFieldToFilter('sales_rep_identifier', $loggedInSalesRepIdentifier);
The label sales_rep_identifier and the value $loggedInSalesRepIdentifier are just examples, you may have to adjust the format in which the data is stored if it doesn't currently have a field to check natively what sales rep did it, and adjust the values there accordingly
If you're using some kind of prebuilt system then maybe there are other labels for the identifier you could use, without more information on the specific database structure it's impossible to answer exactly, but essentially you need to filter by the unique sales rep identifier, and if that doesn't exist now in the database it should somehow but added
I am Trying to get all the invoices in a single API hit.
Because, for every user having 100's of invoices.
It will exceed the API limit (Minute Limit: 60 calls in a rolling 60 second window).
I am trying to store all the invoice id into a single array and from that i will get the details of the user and then i loop the records locally and display it. It's the right way?
invoice_ids = user.estimates.select("invoice_id") || [] xero = Xeroizer::PrivateApplication.new(XERO_CONFIG["key"], XERO_CONFIG["secret"], XERO_CONFIG["path"], :rate_limit_sleep => 5)
invoices = ['795f789b-5958-xxxx-yyyy-48436dbe7757','987g389b-5958-xxxx-yyyy-68636dbe5589']
inv_id = invoice_ids.pluck(:invoice_id)
invoices = xero.Invoice.all(:where => 'InvoiceID==inv_id')
Also, I am getting the following error:
Xeroizer::ApiException (QueryParseException: No property or field 'inv_id' exists in type 'Invoice')
Looks like the problem is that you're not interpolating the inv_ids correctly. You probably need to do something like this:
invoices = xero.Invoice.all(:where => "InvoiceID==\"#{inv_id}\"")
You may have to perform some additional formatting on the inv_id variable to make it a valid Xero string. https://github.com/waynerobinson/xeroizer#retrieving-data
I'm whiling for one of my project to create a subscription system with Laravel Cashier and Stripe.
We will offer one plan to our users : 10€ / month for one location (they can add locations in the system) and for 75 followers.
What I want to do, is to make them pay more for locations : 2.5€ / locations / month for example, so this can be achieve with quantities ? But still, if the basic plan is at 10€ and I put 2 as a quantity, total price will be 20€ ?
Then price will be also based on their followers. 75 are included in the basic price. But then if they want more, they will also have to pay.
Example :
76-150 : + 4.95€ a month
151-250 : + 4.80€ a month etc ...
How can I handle that and make sure the customer will have to pay everything in one shot ?
Thanks in advance !
My advice would be to;
Calculate the total charge in your own logic,
Initiate a 'once-off' payment by first creating a customer object,
Then creating a charge!
Easy as 1,2,3 :D
Here's a tutorial from Stripes documentation on creating payments.
https://stripe.com/docs/charges
If you would like to add the user to a plan (subscription), see the below example (in PHP).
$customer = \Stripe\Customer::create(array(
"source" => $tokenID,
"plan" => $plan,
"email" => $email,
"coupon" => $coupon
));
I would use my front or back end to calculate:
price
discount rate
When the calculation is done, you can create your subscription with the right quantity and price, and discount rate (discount coupon).
$user->newSubscription('main', 'main')
->quantity($quantity)
->withCoupon($coupon)
->create($token, ['email' => $user->email]);
I am working on a donation form for a charity and they have requested a monthly donation plan where the user can choose whatever amount they would like to give.
I know I can make individual plans (i.e. if they said monthly donations of $5, $10, or $20 dollars) I could make three different plans and subscribe users to them. Is there a way to avoid making new plans for every varying subscription amount?
The Stripe documentation recommends using the quantity parameter on the subscription.
https://stripe.com/docs/guides/subscriptions
Varying billing amounts
Some users need full flexibility in computing billing amounts. For
example, you might have a conceptual subscription that has a base cost
of $10 per month, and a $5 per-seat cost each month. We recommend
representing these billing relationships by creating a base plan that
is only $1 per month, or even $0.01 per month. This lets you use
quantity parameter to bill each user very flexibly. In an example
with a $10 base cost and three $5 seats, you could use a $1 per month
base plan, and set quantity=25 to achieve the desired total cost of
$25 for the month.
I don't think you can do it with Stripe.
What you can do is keep using Stripe and dynamically build the subscription plans using Stripe API or move to PayPal and use their Preapproval operation.
https://developer.paypal.com/docs/classic/api/adaptive-payments/Preapproval_API_Operation/
Your question seems self-defeating -- you can't have subscriptions of varying amounts without creating the corresponding plans!
The simplest way to handle recurring donations of varying amounts would be to create one plan per donator. For instance, you could do something like this:
# Create the plan for this donator
plan = Stripe::Plan.create(
:amount => params[:amount],
:currency => 'usd',
:interval => 'month',
:name => 'Donation plan for #{params[:stripeEmail]}',
:id => 'plan_#{params[:stripeEmail]}'
)
# Create the customer object and immediately subscribe them to the plan
customer = Stripe::Customer.create(
:source => params[:stripeToken],
:email => params[:stripeEmail],
:plan => plan.id
)
If you wish to avoid creating unnecessary plans, you could simply check if an appropriate plan already exists. The simplest way to do so would be to use a naming convention that includes the amount. For instance:
plan_id = '#{params[:amount]}_monthly'
begin
# Try to retrieve the plan for this amount, if one already exists
plan = Stripe::Plan.retrieve(plan_id)
rescue Stripe:: InvalidRequestError => e
# No plan found for this amount: create the plan
plan = Stripe::Plan.create(
:amount => params[:amount],
:currency => 'usd',
:interval => 'month',
:name => "$#{'%.02f' % (params[:amount] / 100.0)} / month donation plan",
:id => plan_id
)
# Create the customer object as in the previous example
(Note that in both these examples, I assumed that params[:amount] would be the donation's amount, as an integer in cents.)
I am looking for a way to be able to get approx values of sales volume (basically how much money a store is generating) upon which I would like to base my rough calculations to show user some more data.
(Option A) I know I can directly query the database and then cache the results, but is Magento already doing that & caching it somewhere which I can just use? (Option B), like Magento saves the value of lifetime sales and average sales value somewhere.
Any data like daily/weekly/monthly average of sales or average order amount & daily/weekly/monthly average of orders would suffice here.
If the option A is only way to go here, how should I be querying this data? I have seen examples doing it like the following:
Mage::getResourceModel('sales/order_collection')
Mage::getModel('sales/order')->getCollection()
Which is faster & more lightweight for my needs? And any link where can I actually see detailed or well explained example of using them so that I can understand what parameters are available for querying in each case?
Update: I still don't understand clearly whats the difference between the above 2 methods, but my guess is one is more abstracted than the other & probably uses the other one internally but I am not sure. Anyways, I have this code snippet pulling in the data but I have a problem with filtering the data for a date range:
<?php
require_once 'app/Mage.php';
#umask(0);
Mage::app('default');
$orderTotals = Mage::getModel( 'sales/order' )->getCollection()
->addAttributeToFilter( 'status', Mage_Sales_Model_Order::STATE_COMPLETE )
->addAttributeToFilter( 'status', 'complete' )
//->addAttributeToFilter( 'created_at', array( 'from' => date( 'Y-m-d', strtotime( '-100 days' ) ) ) )
//->addAttributeToFilter( 'created_at', array( 'from' => date( 'Y-m-d', strtotime( '-100 days' ) ), 'to' => date( 'Y-m-d' ) ) )
->addAttributeToSelect( 'grand_total' )
->getColumnValues( 'grand_total' )
;
$totalSum = array_sum( $orderTotals );
$totalSum = Mage::helper( 'core' )->currency( $totalSum, true, false );
echo $totalSum . "\n";
Update:
This code snippet is working now. I had orders in the range but their order status was "processing", so I couldn't see them. I got the snippet from this question.
I am still looking for an explanation to what differs in the above 2 methods and which one is good to use?
In case someone comes here via Google like I did, this question motivated me to make my report page I've been wanting. I typically do not use the built in MVC (more below!) and instead will plop pages in var/export or something. I eventually came up with the below query after going through all the sales_flat_order* and sales_flat_invoice* tables finding a solution which represented the products we sold and shipped.
Sales report for this week:
SELECT sfi.grand_total as 'total',sfii.base_row_total as 'sales', sfii.sku as 'sku', sfii.qty as 'qty', sfo.increment_id as 'order'
FROM sales_flat_invoice_item sfii
LEFT JOIN sales_flat_invoice sfi ON sfii.parent_id = sfi.entity_id
LEFT JOIN sales_flat_order sfo ON sfi.order_id = sfo.entity_id
WHERE sfo.status = 'complete'
AND sfi.updated_at > "2013-06-01"
The date is this past Friday night at midnight. Note: if you add sfi.* to the SELECT you can do the math to double check shipping and taxes against the totals. The problem with sales_flat_order is that table doesn't represent cash in your checking account. We're not on accrual (and probably few small businesses are), so this is better for me understanding cash accounting basis.
For my report script, I also build a table of values and use Google Charts to make it pretty. The below page loads almost instantly:
Edited to add: While creating this above query, I discovered that a previous order querying tool built USING the proper means of collections, etc, misses a vast number of orders without any reason we could uncover. More and more, I'm finding the only way to get a job done correctly is to do it myself -- and do it the hard way.
Did you take a look # Admin -> Report -> Sales
/app/code/core/Mage/Adminhtml/controllers/Report/SalesController.php
/app/code/core/Mage/Adminhtml/Block/Report/Sales/Sales/Grid.php
Collection: 'sales/report_order_collection'
Tables:
sales_bestsellers_aggregated_*
sales_order_aggregated_*
report_viewed_product_*