Magento 1.9.2 order ID duplicate entry if previously canceled - database

I have a very annoying problem with Magento 1.9.2 upgrade (previously was 1.7.0.2)
I get time to time this error message in log file:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'OR1010702' for key 'UNQ_SALES_FLAT_ORDER_INCREMENT_ID', query was: INSERT INTO `sales_flat_order`...
It happens with every payment method, only if customer has already order before and his last order is Canceled or On Hold. It works fine when it's his first order or if previous one is Processing, Complete or Pending.
For exemple, a new customer goes through the checkout process, is redirected on Paypal or other payment solution page. If he uses his credit card correctly, no problem, but if he cancels his payment (the order is created and has status Canceled) he won't be able to process it again. He will stay on Magento checkout page and get javascript prompt error (something like: Payment issue, try latter)
Everything was fine with Magento 1.7 but with 1.9.2 upgrade I don't know what to do get order process working in any case.
If someone has and idea... Thanks very much in advance!

I finally found the answer here: http://blog.adin.pro/2014-12-02/magento-sqlstate23000-integrity-constraint-violation-1062-duplicate-entry-000000254-for-key-unq_sales_flat_order_increment_id/
I had to override /app/code/local/Adin/Sales/Model/Resource/Sales/Quote.php in order to remove (int) in this line: $bind = array(':increment_id' => (int)$orderIncrementId);

Although it's an old answer, I have found a solution which may help someone else in problem.
This problem happens when below conditions met
Customer has canceled previous order
Customer is trying again for a new order (with or without cookies cleared)
Your setup has a custom invoice number which is not int
Why the 3rd point above is bold? Because Magento already has solution to cover the first 2 conditions. Please check function reserveOrderId() in app\code\core\Mage\Sales\Model\Quote.php and function isOrderIncrementIdUsed() in app\code\core\Mage\Sales\Model\Resource\Quote.php.
To cover your custom invoice number which has chars within, you need to change below line
$bind = array(':increment_id' => (int)$orderIncrementId);
with
$bind = array(':increment_id' => $orderIncrementId);
in function isOrderIncrementIdUsed() in app\code\core\Mage\Sales\Model\Resource\Quote.php
note: removal of (int)
I hope you understood the problem now, but to be more precise, Magento tries to parse your invoice number 'OR1010702' into an int, which it can't. So this method returns false and hence no new invoice number is generated. Once you change the code to not parse into int, it is able to assign a new order id and it works fine.
note: You should not touch any file inside core directory, rather copy the file with it's directory structure in app\code\local and do the changes there

Related

Laravel skip and delete records from Database

I'm developing an app which needs to record a list of a users recent video uploads. Importantly it needs to only remember the last two videos associated with the user so I'm trying to find a way to just keep the last two records in a database.
What I've got so far is the below, which creates a new record correctly, however I then want to delete all records that are older than the previous 2, so I've got the below.
The problem is that this seems to delete ALL records even though, by my understanding, the skip should miss out the two most recent records,
private function saveVideoToUserProfile($userId, $thumb ...)
{
RecentVideos::create([
'user_id'=>$userId,
'thumbnail'=>$thumb,
...
]);
RecentVideos::select('id')->where('user_id', $userId)->orderBy('created_at')->skip(2)->delete();
}
Can anyone see what I'm doing wrong?
Limit and offset do not work with delete, so you can do something like this:
$ids = RecentVideos::select('id')->where('user_id', $userId)->orderByDesc('created_at')->skip(2)->take(10000)->pluck('id');
RecentVideos::whereIn('id', $ids)->delete();
First off, skip() does not skip the x number of recent records, but rather the x number of records from the beginning of the result set. So in order to get your desired result, you need to sort the data in the correct order. orderBy() defaults to ordering ascending, but it accepts a second direction argument. Try orderBy('created_at', 'DESC'). (See the docs on orderBy().)
This is how I would recommend writing the query.
RecentVideos::where('user_id', $userId)->orderBy('created_at', 'DESC')->skip(2)->delete();

Lightning Experience Specialist - Step 6 - Unable to complete

I am stucked in this challenge and not sure why is it not completing. Please have a look at below details.
Error Message -
Challenge Not yet complete... here's what's wrong: The Fulfillment Cancellation Automation process does not appear to be working properly. Make sure that a cancelled Fulfillment updates the Adventure Package correctly.
My Process builder is as follows:
Object: Fulfillment
Entry Criteria: [Fulfillment__c].Status__c = Cancelled AND [Fulfillment__c].Schedule_Date__c > TODAY()
Immediate Actions:
Based on [Fulfillment__c].Opportunity.OpportunityLineItems
Field Update Filter condition :
Line Item ID equals Formula [FullFillment__c].AdventurePackageId__c
Field to Update :
Sales Price equal to [Fulfillment__c].Deposit__c
I did some finding on web and have changed the below things as well but not working for me.
The Explorer__c field was set to "Required" and "What to do if the lookup record is deleted?" was set to "Don't allow deletion of the lookup record that's part of a lookup relationship.".
I updated the "Required" to false and changed "What to do if the lookup record is deleted?" to "Clear the value of this field. You can't choose this option if you make this field required."
I have unrequired the Explorer__c field on the layout too.
After all the above changes, I am still not able to complete the challenge.
Any help will be really appreciated.
Thanks in advance.
I'm getting this as well, and I think there may well be a bug in their test.
I've manually tested the processes, and it works as described. The Sales Price on the Adventure Package gets updated to the Fulfillment's Deposit amount.
Looking in the debug logs, the query clearly selects 1 record (which is what we'd expect) into a List called fullfillmentList before the code immediately fails an assertion with the message Fulfillment list is empty.
this error is showing because, you might have deactivated the previous process flow i.e Fulfillment Creation, which also should be active for completion of this step in the superbadge

How can I get Watson to recognize two different dates upon user input?

If a user asks the following sentence:
For some reason Watson uses the first date for the both $checkin and $checkout variables even though it detects the second date.
You can refer to the "dialog node" screenshot to see how the nodes are setup.
How can I get Watson to recognize the first date is the checkin date and the second one is the checkout date. Is there a way I could tell Watson after the first date is used if a second one is detected use it to fill the next slot?
I've found something about the #sys-date range_link entity. But the documentation is not detailed.
This is easy to do, but comes with issues you need to be aware of.
Slots allows you to define variables as they are read. For example.
Will generate this:
The issue is that you are assuming that people will ask in the same order that you need the information. If this doesn't happen then this will fail.
You can mitigate this by shaping how the user may ask the question. For example:
"Please let me know where you are leaving and going to"
The person is more likely to respond with the exit date first.
BETA
This is likely to change and doesn't fully work as you expect. You can enable the beta #sys-date in the options. So I wouldn't recommend relying on this until it is final.
You first need to check for range_link. This will tell you if it detected that two dates are connected to each other.
Then you can do the following:
From Date: <? entities['sys-date'].filter("d", "d.role.type == 'date_from'")[0]?.value ?>
To Date: <? entities['sys-date'].filter("d", "d.role.type == 'date_to'")[0]?.value ?>
What this does is find the exact record that has the role of date_from and returns the value. Likewise for date_to.
You end up with something like this.

How to send an Email notification by day end using Rules with all the nodes published that day?

I am trying to achieve email notification . The condition is , it should go by end of the day with the current day published content list.
For the same I have tried couple of things using Rules, but stuck in between.
Any help?
I tried using rules, and I created a rule like so:
Events:
After updating existing content of type(content type name)
Cron maintenance tasks are performed
Condition: Data to compare: [node:field-img-status], Data value: Approve
When I am trying to add second condition to check if the node is published within 24hrs, I am unable to achieve it. When I add strtotime("-1 day"), I get an error like:
Wrong date format. Specify the date in the format 2017-05-10 08:17:18.
I tried date('Y-m-d h:i:s',strtotime("-1 day")) but I did not succeed.
Now I am trying one more method to achieve it using Views Rules which is suggested in this answer to the question about 'How to create a Drupal rule to check (on cron) a date field and if passed set field "status" to "ended"?'.
Below is a blueprint of how I'd get this to work ...
Step 1: Create a single eMail for each node that was published
Create a view (using Views) of all the nodes that were published the last 24 hours. Make sure to include a column in that view for the various data you want to be included about each node in your eMail later on.
Use Rules to create a rule with a Rules Action that consists of a "Rules Loop", in which its "list items" are actually the list of nodes that you want to be included in your eMail later on. To create this Rules Loop, use the Views Rules combined with a Views display type of "Views Rules", for the view that you created. Refer to my answer to "How to pass arguments to a view from Rules?" for way more details on how to use the Views Rules module.
For each list item in the Rules Loop of the previous step, you have access to all data for each column in the View you created. By using these data you could add an additional Rules Action (within the same Rules Loop) to send an appropriate eMail about the node being processed.
Step 2: Group all eMails in a single eMail
Obviously, the previous step creates a single eMail for each node that was published in the last 24 hours. If you only have a few nodes that may not be a real issue to worry about. But if you have dozens (or more?) of such nodes then you might want to consider consolidating all such eMails in a single eMail, which contains (in its eMail body) the complete list of nodes.
A possible solution to implement such consolidation, is similar to what is shown in the Rules example included in my answer to "How to concatenate all token values of a list in a single field within a Rules loop?". In your case, you could make it work like so:
Add some new Rules variable that will be used later on as part of the eMail body, before the start of your loop. Say you name the variable nodes_list_var_for_email_body.
Within your loop, for each iteration, prepend or append the value for each "list item" to that variable nodes_list_var_for_email_body.
Move the Rules Action to send an eMail outside your loop, and after the loop completed. And finetune the details (configuration) of your (new) "send an eMail" Rules Action. When doing so, you'll be able to select the token for nodes_list_var_for_email_body to include anywhere in your eMail body.
Step 3: Schedule the daily execution of your rule
Use the Rules Once per Day to schedule the daily execution of your rule. Refer to my answer to "How to limit the execution of a rule for sending an email to only run once in a day?" for way more details about this module.
VoilĂ , that's it ...
This is how I would achieve this:
Make some view which would list all nodes created today.
Make some end-point (from my module, check out: https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7.x)
It would call this view, and grab that node list (i.e. with views_get_view_result : https://api.drupal.org/api/views/views.module/function/views_get_view_result/7.x-3.x ), loop through the list, compose the email and send it.
Then I would set cron job to call that end-point at end of every day.

Quickly finding the last item in a database Cakephp

I just inherited some cakePHP code and I am not very familiar with it (or any other php/serverside language). I need to set the id of the item I am adding to the database to be the value of the last item plus one, originally I did a call like this:
$id = $this->Project->find('count') + 1;
but this seems to add about 8 seconds to my page loading (which seems weird because the database only has about 400 items) but that is another problem. For now I need a faster way to find the id of the last item in the database, is there a way using find to quickly retrieve the last item in a given table?
That's a very bad approach on setting the id.
You do know that, for example, MySQL supports auto-increment for INT-fields and therefore will set the id automatically for you?
The suggested functions getLastInsertId and getInsertId will only work after an insert and not always.
I also can't understand that your call adds 8 seconds to your siteload. If I do such a call on my table (which also has around 400 records) the call itself only needs a few milliseconds. There is no delay the user would notice.
I think there might be a problem with your database-setup as this seems very unlikely.
Also please have a look if your database supports auto-increment (I can't imagine that's not possible) as this would be the easiest way of adding your wanted functionality.
I would try
$id = $this->Project->getLastInsertID();
$id++;
The method can be found in cake/libs/model/model.php in line 2768
As well as on this SO page
Cheers!
If you are looking for the cakePHP3 solution to this you simply use last().
ie:
use Cake\ORM\TableRegistry;
....
$myrecordstable=Tableregistry::get('Myrecords');
$myrecords=$myrecordstable->find()->last();
$lastId = $myrecords->id;
....

Resources