How do I add another attribute to order_aggregated_created table? - php

I’ve been scratching my head for days on this one. Any help or a push in the right direction would be greatly appreciated.
I’ve extended the sales report under Reports->Sales->Orders and created my own custom filters to filer the report by channels.
Each order has a ‘channel_name’ attribute to identify whether the order came from eBay, Amazon, etc.
Now I cannot for the life of me figure out how sales/order_aggregated_created table that is used to generate the reports is created. Where does the magic happen? I want to add ‘channel_name’ to the order_aggregated_created table to be able to filter by this attribute, but I cannot figure out how to this.
Diagram for order_aggregated_created table with its attributes:
http://www.magento-exchange.com/wp-content/uploads/2010/11/MAGENTO-SALES-ORDER-ER.png
Mage_Sales_Model_Resource_Report_Order_Collection is where the magic starts in retrieving the sales totals, particularly if I understood this correctly inside
protected function _getSelectedColumns(){...}
if (!$this->isTotals()) {
$this->_selectedColumns = array(
'period' => $this->_periodFormat,
'orders_count' => 'SUM(orders_count)',
'total_qty_ordered' => 'SUM(total_qty_ordered)',
'total_qty_invoiced' => 'SUM(total_qty_invoiced)',
'total_income_amount' => 'SUM(total_income_amount)',
'total_revenue_amount' => 'SUM(total_revenue_amount)',
'total_profit_amount' => 'SUM(total_profit_amount)',
'total_invoiced_amount' => 'SUM(total_invoiced_amount)',
'total_canceled_amount' => 'SUM(total_canceled_amount)',
'total_paid_amount' => 'SUM(total_paid_amount)',
'total_refunded_amount' => 'SUM(total_refunded_amount)',
'total_tax_amount' => 'SUM(total_tax_amount)',
'total_tax_amount_actual' => 'SUM(total_tax_amount_actual)',
'total_shipping_amount' => 'SUM(total_shipping_amount)',
'total_shipping_amount_actual' => 'SUM(total_shipping_amount_actual)',
'total_discount_amount' => 'SUM(total_discount_amount)',
'total_discount_amount_actual' => 'SUM(total_discount_amount_actual)',
);
}
If would be awesome if I can just ‘channel_name’ =>$this->_channelName, and be on my merry way.

After a lot and lot of research it turns out that sales/order_aggregated_created table gets generated in here:
Mage_Sales_Model_Resource_Report_Order_Createdat
now I've looked here before seemed like exactly what I needed, but any changes I made would not reflect in Magento reports especially inside the sales/order_aggregated_created table.
I found out that Mage_Sales_Model_Resource_Report_Order_Createdat only gets called when you refresh the statistics inside Reports->Sales->Orders, only then a NEW sales/order_aggregated_created table is generated! So for anyone looking to filter the order sales report by a custom attribute, look inside: /app/code/core/Mage/Sales/Model/Resource/Report/Order/Createat.php

Related

Programmatically adding a WC Booking in the cart fails

I am facing a problem to add such a product to the cart.
I manage to create the booking with:
$new_booking = get_wc_booking ($new_booking_data);
$new_booking -> create ($status);
But then I tried to apply these different methods without success:
add_cart_item_data ($cart_item_meta, $product_id); // error 500
or
$ new_booking_object -> add_cart_item ($cart_item_meta); // error 500
The $cart_item_meta object I create is like the following (some keys are duplicative, like for example start and start_date, because I observed in the code that both names are used, and I wanted to be sure to send at least the correct one ;-) ). BTW, by comparing with standard bookings created via the plugin form, I can be sure that the values I set in the array have the correct format.
$cart_item_meta = array(
'all_day' => false,
'cost' => $price,
'customer_id' => 1,
'user_id' => 1,
'date_created' => '',
'date_modified' => '',
'end' => $endDate,
'end_date' => $endDate,
'google_calendar_event_id' => 0,
'order_id' => $order->get_id(),
'order_item_id' => 0,
'parent_id' => 0,
'person_counts' => array($addPaxId => $pax),
'persons' => array($addPaxId => $pax),
'product_id' => $prodId,
'resource_id' => $resourceId,
'start' => $startDate,
'start_date' => $startDate,
'status' => 'in-cart',
'local_timezone' => 'Europe/Brussels',
);
I do get a record in the "posts" table, with the same specifics as a normal booking created by the normal way. In particular, I get post_type = wc_booking, and post_status = in-cart. But the cart remains empty.
I have compared all the entries in the database, and I can't see what is missing. But I'm definitely missing some of the understanding of the mechanics of WooCommerce ...
Does someone can help me to find a way to pass the final step: putting the created booking in the cart ? Thanks!
Well, maybe someone will be interested to know how I worked around, as so far I couldn't find a complete programming solution.
The products I want to book programmatically and add to the cart are existing products in my WooCommerce store. My purpose is just to use my own form to allow the customer to better understand what he books (I'm managing a flight simulators center with several machines), and the native WC Bookings form is not clear enough for me, and moreover it is really heavy and slow.
So after gathering customers info with my own form (simulator, duration, participants, timeslot), my problem was to put all this in the cart. I could achieve to create the relevant booking in the database, but not add it to the cart.
I observed that when you book via the standard form, you send a POST to the server on the same product page, including the following parameters (random data for example):
wc_bookings_field_persons_xxxx => 2 // 'xxxx' is the ID of the related 'bookable_person' in 'posts'
wc_bookings_field_start_date_month => 11 // November (sample)
wc_bookings_field_start_date_day => 26 // the 26th (sample)
wc_bookings_field_start_date_year => 2021 // Year (sample)
wc_bookings_field_start_date_time => 2021-11-26T15:00:00+0100
wc_bookings_field_start_date_local_timezone => Europe/Brussels
add-to-cart => 1147 // the product ID in 'posts'
So the simplest solution is to create a POST call (via form + button or button + ajax), setting the action/ajax url to the related product after filling the fields here above with the custom form...
EDIT: while I was thinking this was the solution, I discovered that it worked only when another tab in my browser previously 'opened the door' by adding the same product in the standard way. But when this tab is closed (or timeout), the above method fails and just open the product page. The 302 redirect that was operating stops to work for un unknown reason, and we get the standard 200 straight forward. No Cart.
So the question is still pending.

Google Calendar API always Paginates Event List

Summary:
Google_Service_Calendar seems to be "force-paginating" results of $service->events->listEvents();
Background:
google calendar API v3,
using php client library
We are developing a mechanism to sync our internal calendar with a user's google calendar.
Please note I will refer below to $x, which represents google's default limit on the number of events, similar to $options['maxResults']; The default value is 250, but it should not matter: we have tested the below with and without explicitly defined request parameters such as 'maxResults', 'timeMin', and 'timeMax' - the problem occurs in all cases.
Another relevant test we did: export this calendar to foobar.ics, created a new gmail user form scratch, import foobar.ics to newuser#gmail.com. DOES NOT REPLICATE THIS ISSUE. We have reviewed/reset various options in the subject calendar (sharing, etc) but cannot find any setting that has any effect.
The Problem:
Normally, when we call this:
$calendar='primary';
$optParams=array();
$events = $this->service->events->listEvents($calendar, $optParams);
$events comes back as a Google_Service_Calendar_Events object, containing $n "items". IF there are more than $x items, the results could be paginated, but the vanilla response (for a 'normal', result set with ( count($items) < $x ) ) is a single object, and $events->nextPageToken should be empty.
One account we are working with (of course, the boss's personal account) does not behave this way. The result of:
$events = $this->service->events->listEvents('primary', []);
is a Google_Service_Calendar_Events object like this:
Google_Service_Calendar_Events Object
(
[accessRole] => owner
[defaultRemindersType:protected] => Google_Service_Calendar_EventReminder
[defaultRemindersDataType:protected] => array
[description] =>
[etag] => "-kakMffdIzB99fTAlD9HooLp8eo/WiDS9OZS7i25CVZYoK2ZLLwG7bM"
[itemsType:protected] => Google_Service_Calendar_Event
[itemsDataType:protected] => array
[kind] => calendar#events
[nextPageToken] => CigKGmw5dGh1Mms4aWliMDNhanRvcWFzY3Y1ZGkwGAEggICA6-L3lrgUGg0IABIAGLig_Zfi278C
[nextSyncToken] =>
[summary] => example#mydomain.com
[timeZone] => America/New_York
[updated] => 2014-07-23T15:38:50.195Z
[collection_key:protected] => items
[modelData:protected] => Array
(
[defaultReminders] => Array
(
[0] => Array
(
[method] => popup
[minutes] => 30
)
)
[items] => Array
(
)
)
[processed:protected] => Array
(
)
)
Notice that $event['items'] is empty, and nextPageToken is not null. If we then do a paginated request like this:
while (true) {
$pageToken = $events->getNextPageToken();
if ($pageToken) {
$optParams = array('pageToken' => $pageToken);
$events = $this->service->events->listEvents($calendar, $optParams);
if(count($events) > 0){
h2("Google Service returned total of ".count($events)." events.");
}
} else {
break;
}
}
The next result set gives us the events. In other words, the google service seems to be paginating the initial results, despite the fact that we are certain the result is less than $x.
To be clear, if we have 5 events on our calendar, we expect 1 result with 5 items. Instead, we get 1 result with 0 items, but the first result of the 'nextPageToken' logic gives us the desired 5 items.
Solution Ideas?:
A. handle paginated results, and/or "Incremental Syncronization'. These are on our list of features to implement, but we consider these to be more 'optimization' than 'necessity'. In other words, I understand that handling/sending nextSyncToken and nextPageToken are OPTIONAL- thus the issue we are having should not depend on our client code doing this.
B. use a different, non-primary calendar for this user. we think this particular primary calendar may corrupt or somehow cached on google's side: to be fair, we did at one point accidentally insert a bunch of junk events on this calendar to the point that google put us in read-only mode as described here: https://support.google.com/a/answer/2905486?hl=en but we understand that was a temporary result of clunky testing.... In other words, we know we HAD screwed this calendar up badly, but this morning we deleted ALL events, added a single test event, and got the same result as above FOR THIS CALENDAR. Cannot replicate for any other user.... including a brand new gmail user.
C. delete the 'primary' calendar, create a new one. Unfortunately, we understand it is not possible to delete the primary CALENDAR, only to delete the CALENDAR EVENTS.
D. make the boss open a brand new google account
Any other suggestions? We are proceeding with A, but even that is a band-aid to the problem, and does not answer WHY is this happening? How can we avoid it in the future? (Please don't say "D")
Thanks in advance for any advice or input!
There is a maximum page size, if you don't specify one yourself there is an implicit one (https://developers.google.com/google-apps/calendar/v3/pagination). Given this it's necessary to implement pagination for your app to work correctly.
As you noticed, a page does not always contain the maximum number of results so pagination is important even if the number of events does not exceed the page size. Just keep following the page tokens and it will eventually give you all the results (there will be a page with no nextPageToken)
TL;DR A :)

Fuelphp related limit

I am currenty working on a story board, and i upload images there telling a story.
So the problem is i just want to limit the related query.
The story board has a has_manyrelation for images. and on the list where the story boards appear i just only want to show the first image, and when someone clicks it it will show all, the show all is fine, but i can limit just the related images in my view.
And im totally confused with it because i read lot of infos about it in the forum, tried may variations, the limit is just ignored, or i get errors
so here is my code
controller
$stories = Model_Storyboard::find('all', array('related' => array('storyboardimage')));
$this->template->title = "Sotry Board | " . Config::get('site_name');
$this->template->content = View::forge('storyboard/index', array('stories' => $stories));
So how can i limit the storyboardimage to show the first image for each storyboard?
Sorry if im askin to much, but i would be really happy if someone could give me a working example beacuse i tried lots of variations and nothing works...
You can add criteria onto the relations, i.e. where, order_by, limit etc.
For example (note this is untested)
$stories = Model_Storyboard::find('all', array(
'related' => array(
'storyboardimage' => array(
'limit' => 1,
'order_by' => array(
'field_indicative_of_first_image' => 'desc'
),
)
)
));
In the example above I've added in field_indicative_of_first_image which simply means replace this with a column which you can use to get the first image. This might be for example a created_at column or a weight or sort_order column. Without knowing your database schema, I can't tell you which you'd need.

Trying to add records to a table with MYSQL and php, with a forced unique identifier

I am trying to modify a script that was developed to import article records from a Joomla (1.5.x) database into a Wordpress 3.2.1 table for posts. It is a script that migrates content from Joomla to Wordpress.
The issue I had with the script is that it did not maintain the unique identifier ('id' in Joomla, and 'ID' in Wordpress). Based on my understanding, this makes it a lot more complicated (much more work) to deal with redirecting all the Joomla permalinks over to the new (and obviously different) Wordpress permalinks. If the ID was the same in WP as it was in Joomla then some basic rewrite rules in htaccess would be enough to perform the redirections.
So I want to see if I can modify the code to force the ID rather than it being generated in consecutive order as records are inserted into the table.
The script I am modifying is available here: http://wordpress.org/extend/plugins/joomla-to-wordpress-migrator/
The file in question is called: joomla2wp-mig.php
The array is being created at around line 1049 and 1081.
At line 1049 it is:
$wp_posts[] = array(
'ID' => $R->id, //I ADDED THIS IN
'post_author' => $user_id,
'post_category' => array($wp_cat_id),
'post_content' => $post_content,
'post_date' => $R->created,
'post_date_gmt' => $R->created,
'post_modified' => $R->modified,
'post_modified_gmt' => $R->modified,
'post_title' => $R->title,
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_name' => $R->alias,
'tags_input' => $R->metakey,
'post_type' => 'post'
);
And at line 1081 it is:
$array = array(
"ID" => $item['ID'], //I ADDED THIS IN
"post_author" => $user_id,
"post_parent" => intval($wp_cat_id),
"post_content" => $item['post_content'],
"post_date" => $item['post_date'],
"post_date_gmt" => $item['post_date_gmt'],
"post_modified" => $item['post_modified'],
"post_modified_gmt" => $item['post_modified_gmt'],
"post_title" => $item['post_title'],
"post_status" => $item['post_status'],
"comment_status" => $item['comment_status'],
"ping_status" => $item['ping_status'],
"post_name" => $item['post_name'],
"post_type" => $item['post_type']
);
I have commented the ID line which I have added into the top of each of these bits of array code.
The INSERT command is being implimented around line 1097
The INSERT command is put together like this:
$insert_sql = "INSERT INTO " . $j2wp_wp_tb_prefix . "posts" . " set ";
$inserted = 0;
foreach ($array as $k => $v)
{
if($k AND $v)
{
if($inserted > 0)
$insert_sql .= ",";
$insert_sql .= " ".$k." = '".mysql_escape_string(str_replace("`","",$v))."'";
++$inserted;
}
}
$sql_query[] = $insert_sql;
}
It uses the MYSQL function INSERT INTO... SET (as opposed to INSERT INTO... VALUE)
The challenge I have is this:
The array did not include the ID, so I have added this in.
Having made this change, when I run the script it will appear (at the Wordpress UI end) to run fine, but no records are inserted, even though it says it was successful.
I found I could get around that issue by setting up a fresh wp_posts table with X number of blank records. Let's say I am importing 100 articles, then I would put 100 records into the table, and they would have ID 1 to 100. When I run my modified code it will happily update and populate these existing records. What I don't understand is why it will not create new records when I force the unique identifier (ID) to what I want it as.
I am wondering if I need to use the INSERT INTO... VALUE command instead of INSERT INTO... SET
I was going to test that out, but to be honest I am not a programmer and am just winging it as I go along. So I had not idea how to rewrite the PHP in order to impliment the structure required for the VALUE command in place of SET.
Any help or suggestions would be greatly appreciate.
I gather I have to rewrite the last bit of code I provded above.
There is some discussion on this matter at the wordpress support forums. One user (spiff06) very kindly helped troubleshoot the issue with me. We came unstuck around getting the code to insert new records with a forced identifier, and I went with what we referred to as the "messy" option (which is the method I mentioned above... setting up a table with the required number of blank records).
Even though I've used that "messy" method for my own site, it is my wish to make this process work cleanly for other users who are on Joomla 1.5.x and are switching to WP instead of upgrading to a newer Joomla release (which is a big process, so many are just jumping ot WP, like me).
With much thanks...
Jonathan
You can try the following:
Change the structure of the imported mysql table (post#wordpress). Change the id field so it is not anymore an autoincrement field. Let it being just an integer field.
Import the values. This way you can put any values in the field ID without limitations at all.
After the importation change again the structure of the table to set the ID field to be again an autoincrement field.
I never found a truly automated / scripted way of doing this. I ended up doing a workaround:
For now I've imported all my posts the "messy" way, by prepopulating the table.
THE WORKSROUND METHOD
Prepopulate the wp_posts table in the WP database with as many records as you require (look in Joomla to see how many records you have). I had 398, so I added 398 records to wp_posts.
HOW? I did it by exporting the emtpy wp_posts table to a .csv file. I then opened this in Excel (Numbers, or OpenOffice would also do). In the spreadsheet application it was easy to autofill 1 to 398 in the ID column.
I then reimported that .csv file into wp_posts. This gave me a wp_posts with 398 record rows with 1 to 398 in the ID field.
I then ran version 1.5.4 of Mambo/Joomla to WordPress migrator, which can be installed from within WordPress.
End result?
All posts have the same ID as the original Joomla articles.

SugarCRM - How to set the default homepage for all users

I am using SugarCRM Version 5.2.0k (Build 5837). I would like to be able to set a default home page (with dashlets I've created myself) that will be the same for all users, can anyone advice on best way to do this?
Thanks in advance for your help
I'd like to know how to do this too... see here for some ideas, but it's clear that it's not a supported feature.
I wonder if you can write a module that installs a hook for post user creation (assuming that this hook is provided) and then populate the appropriate part of the user preferences table when the hook is invoked. Of course, your module will probably break with each upgrade of SurgarCRM, so this might be more trouble than it i worth.
Edit:
I had a look at the Dash Manager module that is referenced in the thread I linked to above. It's approach is to copy the preferences of the admin user to all other users when the administrator clicks a link in the admin page. So, the admin user is used as a sort of template for other users. Rudimentary solution, but not a bad start - using a template user and treating the preferences (as stored in the DB table) as opaque seems like the way to go.
It's quite easy to do it.
I have done it in SugarCRM 6.5.23.
Here I have mentioned steps to do it:
Just copy sugarcrm_root/modules/Home/index.php and paste it in SugarCRM_root/custom/modules/Home/index.php.
Now you can customize it's behavior as you want.
You can remove default dashlets and add your own dashlets by creating one file at SugarCRM_root/custom/modules/Home/dashlets.php and add this code in it:
<?php
unset($defaultDashlets);
$defaultDashlets = array(
'CustomDashlet' => 'ModuleName',
'UpcomingAppointmentsDashlet' => 'Meetings', //Example
);
Once you do this thing still you have 3 dashlets left in your hook code you can remove it if it's needed code for that hook is like this:
$dashlets[create_guid()] = array(
'className' => 'iFrameDashlet',
'module' => 'Home',
'forceColumn' => 0,
'fileLocation' => $dashletsFiles['iFrameDashlet']['file'],
'options' => array('titleLabel' => 'LBL_DASHLET_DISCOVER_SUGAR_PRO',
'url' => '...',
'height' => 315,
));
Hope this will help you. :)

Categories