Magento 1.9 observer check if customer has at least order with complete status - magento-1.9

i want to use observer to check if customer has at least one order complete to change order status to processing ( so when customer press on place order then make check if has any order complete then change status from pending to processing )
this is my code but this edit status to previous order not existing order
class ChangeOrder_Observerstatus_Model_Observer {
public function autoOrderevent(Varien_Event_Observer $observer)
{
$order = $observer->getEvent()->getOrder();
$orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$custAdmin = Mage::getSingleton('customer/session')->getCustomer();
$custAdminId = $custAdmin->getId();
$order_collection = Mage::getModel('sales/order')->getCollection()
->addFieldToSelect('*')
->addFieldToFilter('customer_id', $custAdminId)
;
foreach($order_collection as $order)
{
if ($order->getState() == "complete") {
$Is_Complet = true;
}
}
if($Is_Complet)
{
if(!Mage::registry('prevent_observer')):
Mage::register('prevent_observer',true);
$orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
$order->setState(Mage_Sales_Model_Order::STATE_PROCESSING, true, 'Payment Complete.');
$order->save();
endif;
}
}
}

Use event "sales_order_place_after". Compared to other checkout events it fires in any case when order has been placed.
Your described logic has to be implemented in observers method body.

Related

MediaWiki - Hook to edit/alter page title on creation

I'm looking to (programmatically) edit/alter the title of a page when its created and before its saved. I've tried a couple hooks to no avail. I can access the title being saved along with other info which ill be used to alter the title, but can not find the right call to save the altered title.
It is for a private/local lan wiki (currently MediaWiki version 1.38.1 ).
When a new article is created with in a certon category I want to number it with a prefix of #### - based on the number of articles already in the category. At the top of the category page itself I have a <inputbox> which pulls a template that has the wiki syntax for the category in it [[Category:BlaBla]]. When the article is saved I'm doing a check to make sure its a new article and some ofther checks for the info I need, which is working fine, but I can not save the new altered page name.
I've tried the following hooks to no avail.
onMultiContentSave
onArticlePrepareTextForEdit
https://www.mediawiki.org/wiki/Manual:Hooks/MultiContentSave
https://www.mediawiki.org/wiki/Manual:Hooks/ArticlePrepareTextForEdit
Heres acouple snippets ive been testing with, both do as i want, aside from saving the altered page name.
public static function onArticlePrepareTextForEdit( WikiPage $wikiPage, ParserOptions $parserOptions ) {
return;
$exists = $wikiPage->exists();
if ($exists == 1) {
#return true;
}
$getTitle = $wikiPage->getTitle();
# check if title starts with 0000, exit if so, no work needs to be done
if (self::titleCheck($getTitle)) {
#return true;
}
$checkCategories = $wikiPage->getCategories();
$inMalak = false;
foreach ($checkCategories as $value) {
if ($value == "Category:Malak") {
$inMalak = true;
}
}
if ($inMalak == 1) {
$newTitle = self::newTitlePre() . $getTitle;
#$wikiPage->setTitle($newTitle);
print(">" . $newTitle . "<br>");
}
self::pr($newTitle);
}
public static function onMultiContentSave(RenderedRevision $renderedRevision, UserIdentity $user, CommentStoreComment $summary, $flags, Status $hookStatus){
#return;
$revision = $renderedRevision->getRevision();
$getTitle = $revision->getPageAsLinkTarget();
if (self::titleCheck($getTitle)) {
return true;
}
#$titleOBJ = $revision->Title();
$title = $revision->getId();
$parent_id = $revision->getId();
$content = $revision->getContent( SlotRecord::MAIN );
$new_content = $content->getText();
#$test = $revision->ParserOutput();
$parent_id = "";
if ($parent_id == "") {
$pos = strpos($new_content, "[[Category:Malak]]");
if ($pos) {
$newTitle = self::newTitlePre() . $getTitle;
#$wikiPage->setTitle($newTitle);
}
}
self::pr($newTitle);
}
EDIT........
Still have not found the proper way to do this, but came up with a work around (hackery) which works for my needs.
Using the onEditFormPreloadText hook, change the url and added a new parameter ('MalakHere'), edited the 'title' parameter to the altered title, then do a redirect with the new page name. In the hook function there is a check for the 'MalakHere' parameter, if found (only cause of redirect) then it will exit the function so not to create a loop.
public static function onEditFormPreloadText(string &$text, Title &$title ) {
global $wgOut;
if ( isset( $_GET["MalakHere"] ) ) {
return true;
}
$pos = strpos($text, "[[Category:Malak]]");
if ($pos) {
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$urlTitle = urlencode($_GET["title"]);
$newURL = str_replace("title=" . $urlTitle,"MalakHere=yes",$url);
$newTitle = self::newTitlePre() . $title->prefixedText;
$url = $newURL . "&title=" . $newTitle;
return $wgOut->redirect($url);
}
return true;
}
Still have not found the proper way to do this, but came up with a work around (hackery) which works for my needs.
Using the onEditFormPreloadText hook, change the url and added a new parameter ('MalakHere'), edited the 'title' parameter to the altered title, then do a redirect with the new page name. In the hook function there is a check for the 'MalakHere' parameter, if found (only cause of redirect) then it will exit the function so not to create a loop.
public static function onEditFormPreloadText(string &$text, Title &$title ) {
global $wgOut;
if ( isset( $_GET["MalakHere"] ) ) {
return true;
}
$pos = strpos($text, "[[Category:Malak]]");
if ($pos) {
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$urlTitle = urlencode($_GET["title"]);
$newURL = str_replace("title=" . $urlTitle,"MalakHere=yes",$url);
$newTitle = self::newTitlePre() . $title->prefixedText;
$url = $newURL . "&title=" . $newTitle;
return $wgOut->redirect($url);
}
return true;
}

Report don't display any data

I'm working on D365FO. I did create a report added a query to dataset that is based on a tmp table.
Now when I try to generate the report I get just the precisiondesign. No data is shown in it. How can I fix this ?
I think this is problem is somewhere outside of my code because I tried to generate a already created report and had the same problem.
[SrsReportParameterAttribute(classStr(ProductionStatusContract))]
class ProductionStatusDP extends SrsReportDataProviderBase
{
ProductionStatusTmp ProductionStatusTmp;
ProdTable prodtable;
SalesTable salestable;
InventDim inventdim;
SalesLine salesline;
public void processReport()
{
ProductionStatusContract contract = this.parmDataContract() as
ProductionStatusContract;
date FromDate;
date ToDate;
boolean DateBetween = false;
if(contract.parmToDate() && contract.parmFromDate())
{
ToDate = contract.parmToDate();
FromDate = contract.parmFromDate();
DateBetween = true;
}
super();
delete_from ProductionStatusTmp;
ProductionStatusTmp.clear();
while select prodtable where prodtable.CollectRefLevel == 0
join inventdim where prodtable.InventDimId == inventdim.inventDimId
join salesline where prodtable.InventRefType == salesline.InventRefType
&& prodtable.InventRefId == salesline.SalesId
&& prodtable.InventRefTransId == salesline.InventTransId
&& prodtable.InventRefType == inventreftype::Sales
{
ProductionStatusTmp.clear();
Info(strFmt("%1", prodtable.ProdId));
ProductionStatusTmp.AcceptedDate = prodtable.CreatedDateTime;
ProductionStatusTmp.ProdWeek = wkOfYr(prodtable.CreatedDateTime) + year(prodtable.CreatedDateTime);
ProductionStatusTmp.ExternalNum = salesline.ExternalItemId;
ProductionStatusTmp.Progress = ((prodtable.qtycalc * 100) / prodtable.QtySched);
ProductionStatusTmp.Quantity = prodtable.QtyCalc;
ProductionStatusTmp.AcceptedBy = prodtable.CreatedBy;
ProductionStatusTmp.ProdItemId = InventDim.InventLocationId;
ProductionStatusTmp.Ware = prodtable.Name;
ProductionStatusTmp.ProductionStatus = prodtable.ProdStatus;
ProductionStatusTmp.Produced = prodtable.QtySched;
ProductionStatusTmp.insert();
}
}
[SrsReportDataSetAttribute(tableStr(ProductionStatusTmp))]
public ProductionStatusTmp getProductionStatusTmp()
{
select ProductionStatusTmp;
return ProductionStatusTmp;
}
}
You will have to verify that your report does indeed display the data you provide.
You can do this by providing fixed static data in your data provider to see if shows up in the SSRS report preview.
See this video for an example to see how.

ServiceStack Ormlite caching entries aren't deleted after expiry

We are using serviceStack caching with OrmLite Provider (MySql). We noticed that when we create caching keys with expiry dates, the keys don’t get deleted after the expiry date comes. Instead, they get NULL values in the “ExpiryDate” column. Thus, resulting in strange values when we calculate Cache.GetTimeToLive().
Is this a bug in serviceStack or is in our key creating code ? We are using ServiceStack version (4.5.4) and OrmLite version (4.5.4)
IAppSettings appSettings = new AppSettings();
var userConsultsPerHourLimit = appSettings.Get<int>("throttling:consultations:requests:perHourLimit");
var userConsultsPerDayLimit = appSettings.Get<int>("throttling:consultations:requests:perDayLimit");
var userConsultsPerMonthLimit = appSettings.Get<int>("throttling:consultations:requests:perMonthLimit");
var userConsultsMadePerHour = Cache.GetOrCreate<int>(UserConsultPerHourCacheKey, TimeSpan.FromHours(1), () => { return 0; });
var userConsultsMadePerDay = Cache.GetOrCreate<int>(UserConsultPerDayCacheKey, TimeSpan.FromDays(1), () => { return 0; });
var userConsultsMadePerMonth = Cache.GetOrCreate<int>(UserConsultPerMonthCacheKey, (new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1).AddMonths(1).AddDays(-1) - DateTime.UtcNow), () => { return 0; });
string retryAfter = System.Threading.Thread.CurrentThread.CurrentCulture.Name == "ar-SA" ? "يوم" : "day";
bool shouldThrottleRequest = false;
bool didExceedMonthlyLimit = false;
if (userConsultsMadePerHour >= userConsultsPerHourLimit)
{
shouldThrottleRequest = true;
TimeSpan? timeToLive = Cache.GetTimeToLive(UserConsultPerHourCacheKey);
if (timeToLive.HasValue)
retryAfter = Humanizer.TimeSpanHumanizeExtensions.Humanize(timeToLive.Value, 2, System.Threading.Thread.CurrentThread.CurrentUICulture);
}
else if (userConsultsMadePerDay >= userConsultsPerDayLimit)
{
shouldThrottleRequest = true;
TimeSpan? timeToLive = Cache.GetTimeToLive(UserConsultPerDayCacheKey);
if (timeToLive.HasValue)
retryAfter = Humanizer.TimeSpanHumanizeExtensions.Humanize(timeToLive.Value, 2, System.Threading.Thread.CurrentThread.CurrentUICulture);
}
else if (userConsultsMadePerMonth >= userConsultsPerMonthLimit)
{
shouldThrottleRequest = true;
TimeSpan? timeToLive = Cache.GetTimeToLive(UserConsultPerMonthCacheKey);
if (timeToLive.HasValue)
retryAfter = Humanizer.TimeSpanHumanizeExtensions.Humanize(timeToLive.Value, 3, System.Threading.Thread.CurrentThread.CurrentUICulture);
didExceedMonthlyLimit = true;
}
This is working as expected in the latest version of ServiceStack where the row is Deleted after fetching an expired cache entry:
var ormliteCache = Cache as OrmLiteCacheClient;
var key = "int:key";
var value = Cache.GetOrCreate(key, TimeSpan.FromMilliseconds(100), () => 1);
var ttl = Cache.GetTimeToLive(key);
using (var db = ormliteCache.DbFactory.OpenDbConnection())
{
var row = db.SingleById<CacheEntry>(key);
Assert.That(row, Is.Not.Null);
Assert.That(row.ExpiryDate, Is.Not.Null);
}
Assert.That(value, Is.EqualTo(1));
Assert.That(ttl.Value.TotalMilliseconds, Is.GreaterThan(0));
Thread.Sleep(200);
value = Cache.Get<int>(key);
ttl = Cache.GetTimeToLive(key);
Assert.That(value, Is.EqualTo(0));
Assert.That(ttl, Is.Null);
using (var db = ormliteCache.DbFactory.OpenDbConnection())
{
var row = db.SingleById<CacheEntry>(key);
Assert.That(row, Is.Null);
}
We noticed that when we create caching keys with expiry dates, the keys don’t get deleted after the expiry date comes.
The RDBMS doesn't automatically expire Cache Entries by date, but when resolving a Cache Entry the OrmLiteCacheClient will automatically delete expired entries (as can be seen above) so it will never return an expired entry.
Instead, they get NULL values in the “ExpiryDate” column.
This isn't possible. The ExpiryDate is only populated when creating or replacing the existing entry, it's never set to null when it expires. When an entry expires, the entire entry is deleted.
I think we got to the bottom of this .. it was caused by a misuse to the caching APIs from our side .. we found API calls to "Increment" and "Decrement" APIs in different other places causing the keys (those who had exceeded expiry date) to be deleted (by internal call to validate method) and then recreated from scratch (but without expiry date) .. the solution was to call GetOrCreate before calling Increment/Decrement to make sure the key does in fact exist and if it doesn't, recreate it with a fresh expiry date value ..

How to Get Calendar Event global status?

This is concerning Google script to access Calendar event info
I'm looking for a method to get a Calendar Event global status? like for a Calendar Event with as status of attendess:
10 guests ==> 4 Yes, 3 MayBe, 1 No, 2 Awaiting
I've searched but I find only the way to get the status by guest, then implement a code to count individualy the global status.
Is there a way to get directly the global status?
Thanks in advance.
I happen to have written a function that does this. Here's an example of usage:
var summary = guestSummary(event.getGuestList());
Logger.log(summary);
...
[13-06-26 22:39:58:253 EDT] {respondedMaybe=0.0, awaiting=0.0, additional=0.0, respondedNo=0.0, respondedYes=1.0, invited=1.0}
I elected to use the guest list as a parameter, in order to support both CalendarEvent and CalendarEventSeries.
/**
* Return an object enumerating guest list summary information.
*
* #param {EventGuest[]} guestlist Array of EventGuests.
*
* #returns {object} guest list summary
*/
function guestSummary( guestlist ) {
var invited = guestlist.length;
var respondedYes = 0;
var respondedMaybe = 0;
var respondedNo = 0;
var awaiting = 0;
var additional = 0;
guestlist.forEach( function (guest) {
switch (guest.getGuestStatus()) {
case CalendarApp.GuestStatus.INVITED:
awaiting++;
break;
case CalendarApp.GuestStatus.YES:
respondedYes++;
break;
case CalendarApp.GuestStatus.NO:
respondedNo++;
break;
case CalendarApp.GuestStatus.MAYBE:
respondedMaybe++;
break;
default:
break;
}
additional += guest.getAdditionalGuests();
});
return {
invited : invited,
respondedYes : respondedYes,
respondedMaybe : respondedMaybe,
respondedNo : respondedNo,
awaiting : awaiting,
additional : additional
};
}

Linq-2-Sql code: Does this scale?

I'm just starting to use linq to sql. I'm hoping that someone can verify that linq-2-sql has deferred execution until the foreach loop is executed. Over all, can someone tell me if this code scales. It's a simple get method with a few search parameters. Thanks!
Code:
public static IList<Content> GetContent(int contentTypeID, int feedID, DateTime? date, string text)
{
List<Content> contentList = new List<Content>();
using (DataContext db = new DataContext())
{
var contentTypes = db.ytv_ContentTypes.Where(p => contentTypeID == -1 || p.ContentTypeID == contentTypeID);
var feeds = db.ytv_Feeds.Where(p => p.FeedID == -1 || p.FeedID == feedID);
var targetFeeds = from f in feeds
join c in contentTypes on f.ContentTypeID equals c.ContentTypeID
select new { FeedID = f.FeedID, ContentType = f.ContentTypeID };
var content = from t in targetFeeds
join c in db.ytv_Contents on t.FeedID equals c.FeedID
select new { Content = c, ContentTypeID = t.ContentType };
if (String.IsNullOrEmpty(text))
{
content = content.Where(p => p.Content.Name.Contains(text) || p.Content.Description.Contains(text));
}
if (date != null)
{
DateTime dateTemp = Convert.ToDateTime(date);
content = content.Where(p => p.Content.StartDate <= dateTemp && p.Content.EndDate >= dateTemp);
}
//Execution has been defered to this point, correct?
foreach (var c in content)
{
Content item = new Content()
{
ContentID = c.Content.ContentID,
Name = c.Content.Name,
Description = c.Content.Description,
StartDate = c.Content.StartDate,
EndDate = c.Content.EndDate,
ContentTypeID = c.ContentTypeID,
FeedID = c.Content.FeedID,
PreviewHtml = c.Content.PreviewHTML,
SerializedCustomXMLProperties = c.Content.CustomProperties
};
contentList.Add(item);
}
}
//TODO
return contentList;
}
Depends on what you mean with 'scales'. DB side this code has the potential of causing trouble if you are dealing with large tables; SQL Server's optimizer is really poor at handling the "or" operator in where clause predicates and tend to fall back to table scans if there are multiple of them. I'd go for a couple of .Union calls instead to avoid the possibility that SQL falls back to table scans just because of the ||'s.
If you can share more details about the underlying tables and the data in them, it will be easier to give a more detailed answer...