Woocommerce select email address destination only for new order notification(admin) through form checkout it's possible? - e-commerce

Scenery: 1 store and 2 locations. I already have select field form (checkout) where the customer select which store is closest to your location, eg: city A or city B.
Now I need that the new order notification (admin) sent ONLY to e-mail the city shop chosen in form.
Seems to me that all this operations occurs near: class-wc-order, class-wc-checkout.php
But I belive that exist that do it only using filters
Any ideas?
Thanks advance.

$_SESSION Vars on WooCommerce work's fine.
Well not the fine way, but also not worst too!
Create a jquery ($.ajax) function to call one php script external file and register the session variable ($_SESSION).
In my case this php is in (eg: public_html/loadvar.php), this file receive $_POST variables through ajax (in my case: when the user select your office location prefered, this value eg: emailA or emailB according office selected (onChange event) )
I used this session variable to store the alternative email addresses. (not admin_email default)
In (class-wc-checkout.php) , retrieve these values (session variable) eg: email1 or email2... previously selected on form checkout, and overriding the "get_option( 'admin_email' )" by the $_SESSION value
Now, users can choice the office that prefer, and only the selected office will receive the quote request
Note: I only can use this session vars on woocommerce configuring wp_unregister_GLOBALS() on wp-includes/load.php or disable it commenting this function.
This worked (not is state-of-art code) maybe dirty code but can't need deep coding, obviously not "strict patch" this will not survive an update
Thats all folks

Related

Prestashop add custom radio button on shipping carriers on front end checkout

I have created one custom module in Prestashop 1.7.8.7 which will add multiple shipping methods (Carrier) and will show shipping cost based on product dimensions and delivery address. So shipping carrier will look something like this on front-end checkout page. https://prnt.sc/E1avDASyJYYW
Now if someone select SameDay Courier Shipping then i need to show two radio button to select which service they want.
It will have two radio options like
Delivery pickup (by default this option will be selected)
Locker pickup
So if someone select Delivery pickup then it will have different shipping cost and if someone select Locker pickup then it will have different shipping cost.
Can anybody help me how can i achieve this functionality.
While digging, i found that we have file called DeliveryOptionsFinder.php and in that file we have one public function called getDeliveryOptions() where we have this line of code
if ($moduleId = Module::getModuleIdByName($carrier['external_module_name'])) {
$carrier['extraContent'] = Hook::exec('displayCarrierExtraContent', ['carrier' => $carrier], $moduleId);
}
}
So if i set is_module to 1 to all my carriers directly from DB then on frontend checkout page, no carriers is being displayed.
Thanks in advance.
I've already done something like this in the last 2 year as prestashop developer.
The truth is that you can't achieve what you want by "respecting" prestashop processes.
Maybe you can hook using a module the hookDisplayCarrierExtraContent($data) and then return the 2 radios if carrier is certain one (use $data).
But you can't handle a form submit or something else, or include it to prestashop checkout data.
But what you can do as workaround, for example, is the following.
In your module, as I said, hook the extra content, render a template with the 2 radios. Hook displayHeader too and use $this->context->controller->addJS() to add your own js if the current controller is the checkout one.
Then in this JS code you can handle the "change" event of the radios and send an ajax request to your module.
You can create inside {your_module}/controllers/front/ a controller called, for example, radio-choose and handle the js ajax request by saving inside your own table the choosen one.
Obviously you can disable the "next" button in checkout untill one of the two radios are selected, or maybe you can just set a radio button as default one to simplify.
For example your table "ps_cart_choosen_radio" could look like this |id_cart|choosen_radio|.
Then you have all the data you needed. When a cart is converted into an order you will have inside Order object (and ps_orders table as well) the id_cart.
Just select / join choosen radio from your own table by using order's id_cart.
"SELECT choosen_radio FROM ps_cart_choosen_radio WHERE id_cart = {$order.id_cart}"
If you need to show data depending on choosen_radio in frontend you can hook everywhere an order is present and select these data. Or maybe you can edit carrier name in ps_orders table by adding a piece of string. Let' say carrier is "express" and customer choosed "24h". You can update that column with carrier name by changing it to "express-24h" so around the whole prestashop ecosystem everybody will see that's a 24h choice.
Remember that the carrier name related to an order is not the carrier name inside the carriers table. So you can edit it without having trouble.
All these problems comes from the "need" to show some nested choices instead of listing all these in the main selections. In that case it would be easy (just create carrier in the prestashop backoffice)

How do I associate a file with a key on google drive?

I'm trying to automate a process at my company where I have to send files to my customers every month.
These files are unique and each customer must receive their own. In addition, I wanted the client to be required to answer an NPS assessment form in order to have access to his file.
Honestly, I don't understand much about programming and I'm just trying to find a solution to do this automatically.
The solution I have in mind today is to use a google forms form and after filling out the form a link would be made available to access a google drive folder (that way the customer would be obliged to answer the form to have access to his file).
In the google drive, each file would be associated with a unique access key (for example, an identification number of that customer, in which he already knows what it is).
Then these customers should insert this key in the google drive folder in order to be able to access their file. That way I would be able to: get all the answers of the evaluation in a single form, make a standard message (or tutorial) available to all customers informing them how to access their file, and give access to the files automatically because the access key would be the same every month.
Sorry for the long text but I tried to describe my problem in the best way. I am accepting any kind of help or guidance. Even where I could get help about it. This automation would be very important to me because in addition to automating a process that costs a lot of time it would give me a very powerful tool to evaluate my services. Thanks in advance to everyone who took the time to read this question.
The best approach in this situation is to start by using Apps Script.
Apps Script is a powerful development platform which can be used to build web apps and specifically for your situation, automate tasks. What makes it special is the fact that it is easy to use and to create applications that integrate with G Suite.
Since you mention that the files are unique for each customer, what you can do is to store these values in a key - value list. However, depending on the number of the customers, you can store these value in a spreadsheet, something similar to this:
Making the files available only after submitting the Google Form mentioned can be done by taking advantage of Apps Script's triggers.
So essentially, you can use an onFormSubmit trigger which will execute every time the above mentioned form is submitted.
Code
You can also add another column in your spreadsheet to mark if the email was sent or not; taking this into account, this is how your spreadsheet will look like:
As for the code, this is just a short snippet which does the following:
opens the spreadsheet and retrieves the values for the File ID, Customer Email and Sent columns as the following arrays ids, emails and sent respectively;
retrieves the needed form and loops through the responses and checks if the last email of the form matches any of the ones from the spreadsheet;
if the conditions check, the file permissions are edited, an email is being sent, and the corresponding row on column C is being set to TRUE;
function editPermissions() {
let form = FormApp.openById('FORM_ID');
let sheet = SpreadsheetApp.openById('SPREADSHEET_ID').getSheetByName('SHEET_NAME');
let responses = form.getResponses();
let emails = sheet.getRange('EMAILS_RANGE').getValues();
let ids = sheet.getRange('IDS_RANGE').getValues();
let sent = sheet.getRange('SENT_RANGE').getValues();
for (let i = responses.length; i > 0; i--) {
let email = responses[i].getRespondentEmail();
for (let j = 0; j < emails.length; j++) {
if (emails[j][0] == email && sent[j][0] == false) {
// edit file permissions
// send email
// mark the associated row on the Sent col with TRUE
}
}
}
}
Trigger
As for making the function above run every time there's a new form submission, you will have to create an onFormSubmit trigger which will trigger the execution of the function.
Reference
Apps Script;
Apps Script Spreadsheet Service;
Apps Script Forms Service;
Apps Script Installable Triggers.

Apex - passing a variable from one page to another

I have a form on one page which prompts a user to enter their email address. When they click "next" I want Apex to redirect the user to a different page which shows them a report which selects the records from the users table where the email address matches the one that they entered.
E.g.
SELECT *
FROM USERS
WHERE EMAIL_ADDRESS = (the email address that they entered on the previous page);
Can someone please explain the easiest way to do this?
I have only in the last 5 seconds heard about 'Apex' Lol ... But I think I found what you need to do.
You need to define a 'Branch' which will allow you to POST to whichever page you need to.
Here's some documentation on 'Branches': http://docs.oracle.com/cd/B32472_01/doc/appdev.300/b32469/pdf_report.htm#BABICIJG
Also this snipet may help:
It's [The 'branch'] in the middle (page processing section) of the
development page at the bottom. The branch will be executed whenever a
post submission occurs but you can put conditions on the branch.
Which I found at: http://dbaforums.org/oracle/index.php?showtopic=8139
The "Next" button should not redirect but should submit. The value of the page item has to be pushed to the session state for it to be available in the (apex) session. On submit you can then define a branch which will take you to the page with your report. Your report can then reference the page item by using bind variable notation in the region source:
SELECT * FROM USERS WHERE EMAIL_ADDRESS = :Px_EMAIL_ADDRESS

Keeping track of user ID with custom authentication

I am currently making an app on apex.oracle.com, and I've been trying to solve this for a couple hours now, but I have no idea how to.
Alright, so basically my application has custom authentication based on a user table I created inside of my application. Therefore, it seems to render useless most APEX_UTIL functions to retrieve info on the current user. The issue is, I am trying to find a way to store the user's numeric ID from my table in the session, so I could retrieve it directly in the queries throughout my application, in order to do something like WHERE id = :MEMBER_ID instead of WHERE UPPER(username) = UPPER(:APP_USER).
Now, the way I attempted to do this is by creating a Post Authentication procedure that retrieves the user ID based on the username, and stores that value in the session using APEX_UTIL.SET_SESSION_STATE( p_name => 'MEMBER_ID', p_value => member_id ). However, it seems that SET_SESSION_STATE is unable to create custom session values or something, returning an ERR-1002 every time I use a value name that isn't specifically mentioned in the documentation.
I am a total newbie to APEX so I am probably unaware of something, however I have done many searches, but I could not find anything specifically related to my issue.
Thanks a lot if you can help.
You're trying to store a value into an item, whether page or application level. This requires that the item with that name exists in one of those scopes. So, do you have an item somewhere that is called MEMBER_ID?
I'd suggest you create one in the application scope. Go through Shared Components > Application items. Once created, you should be able to assign a value either through apex_util.set_session_state or with bind variable syntax eg :MEMBER_ID := somevariable;
There are a number of ways you can do this. Some have already been suggested in other answers.
Application Item (as per Tom's answer)
PL/SQL package global (as per hol's answer) - although you'd have to reset it for each call (e.g. by adding code to the application's Security Attribute Initialization PL/SQL Code and clearing it by adding code to Cleanup PL/SQL Code).
Globally Accessible Context - this method, while a little more complex, has some benefits especially for security and debugging. I've described it here: http://jeffkemponoracle.com/2013/02/28/apex-and-application-contexts/, but basically:
Create a globally accessible context:
CREATE OR REPLACE CONTEXT MY_CONTEXT USING MY_PACKAGE ACCESSED GLOBALLY;
In the post-authentication procedure (in the database package MY_PACKAGE), you can store the data you wish to keep track of, e.g.
DBMS_SESSION.set_context
(namespace => 'MY_CONTEXT'
,attribute => 'MEMBER_ID'
,value => '12345whatever'
,client_id => v('APP_USER') || ':' || v('APP_SESSION'));
(note the caveats in my blog article and the subsequent comments from others about CLIENT_IDENTIFIER not being reliably set at the post-auth stage)
In your views, code, etc. you can access the MEMBER_ID by simply referring to SYS_CONTEXT('MY_CONTEXT','MEMBER_ID').

MVC user's full name in Url, how to handle duplicates

I want to setup the following url in my MVC4 website, using the user's full name in the url:
http://www.myapp.com/profile/steve-jones
I have setup the following route in Global.asax:
routeCollection.MapRoute(
"profile", "profile/{userName}",
new { controller = "myController", action = "profile", userName = string.Empty
});
And I can take the parameter 'steve-jones' and match it to a user with matching name. My only problem though is, what if there is more than one 'Steve Jones', how can I handle this?
Does anyone know of a workaround/solution to this so that I can use a user's full name as part of the url and still be able to retrieve the correct user in the controller method?
Am I forced into including the user's id with the url (something that I do not want to appear)?
The usual way of handling this is by appending a number when creating the profiles. So if "steve-jones" is already a name in the database, then make the user's display name "steve-jones2". You basically have to insist that all profile urls are unique, which includes updating any existing database and account creation code.
Alternatively (and/or additionally), if two same names are found then have the script reroute to a disambiguation page where the user is presented with links and snippet of profile info of the many existing Steve Joneseses so they can go to the full correct profile.
Another way of handling it is by giving all user profiles an additional numeric code on the end. At my university all logins are based on name, so they give everyone pseudo-random 3-digit extensions so that they are safe as long as they don't get 1000 people with the exact same names :)
Some people might be happier being steve-jones-342 if there is no steve-jones or steve-jones1, if you're concerned.