Woocommerce order complete secondary email retrieved from account meta data key value - hook-woocommerce

Scenario: A customer buys any product and upon order completion an additional email gets sent to a stored value in the users meta data.
My meta field is stored in the database as follows:
Table: wp_usermeta
Column: meta_key = iconic-register-email
Column: meta_value = X
I need to retrieve the meta_value based on the meta_key Column iconic-register-email.
My code thus far:
(To be placed in the function.php file of the child theme)
add_filter( 'woocommerce_email_recipient_new_order', 'new_order_conditional_email_recipient', 10, 2 );
function new_order_conditional_email_recipient( $recipient, $order ) {
// Get the order ID (retro compatible)
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
// Get the custom field value (with the right $order_id)
$my_field_name = get_post_meta($order_id, 'my_field_name', true);
if ($my_field_name == "empolyee1#company.com")
$recipient .= ', empolyee1#company.com';
elseif ($my_field_name == "empolyee2#company.com")
$recipient .= ', empolyee2#company.com';
return $recipient;
}
I am not getting any errors but I am also not getting any emails. I tried replacing
$my_field_name = get_post_meta($order_id, 'my_field_name', true);
with
$my_field_name = get_post_meta($order_id, 'iconic-register-email', true);
but that did not work.
In an effort to minimize static coding of each email address to be matched in code below:
if ($my_field_name == "empolyee1#company.com")
is there a way to call the $recipient based off of the meta_value = X

Related

Request.Cookie - Cookie is not sent or not excepted

I'm developing a shopping cart function.
I need product data from the server that used to render the shopping cart page.
Every time the Add-to-cart button is hit, I stringify this array ( using JSON.stringify() ):
var CART = [{productId: 102, quantity: 3} , {productId: 211, quantity: 6}];
I want to get this data using Request.Cookie["shoppingCart"] in my ASP.NET application,
but when I debug It is always null
This is what the browser return when I call document.cookie
"shoppingCart=[{\"productId\":101617121,\"quantity\":2}]"
But when I try to change the value of the cookie to something like: shoppingCart=testresult ,
the Request.Cookie["shoppingCart"] then has value.
Thank you in advance for helping me!
I solved it.
First, I tried to remove some special chars which are: " and , .
And Request.Cookie then had values. So it seems like ASP.NET just doesn't except these characters in cookie value. ( Tell me if I'm wrong please )
My solution was instead of convert JSON string, I used this formular for each product in the shopping cart : var item = `{productId}:{quantity}`; .
For example:
var sampleCookie = "11231:16:15121:8";
Split the string with : char then use a simple code to get the data.
My code for this:
string cookie = Request.Cookies["shoppingCart"];
var cartItems = new List<CartItem>();
if (cookie != null && cookie.Length > 0)
{
string[] values;
values = cookie.Split(':');
int i = 0;
while (i < values.Length)
{
cartItems.Add(new CartItem()
{
ProductId = values[i],
Quantity = Convert.ToInt32(values[i+1])
});
i += 2;
}
}

Cosmos DB stored procedure: I can query the DB, but when I try to upsert I get a 'not same partition' error

I understand that stored procedures run in the scope of a single partition key.
It is also possible to do operations that change data, not just read it.
ID must be string, so I must roll my own autoincrementer for a separate property to use in documents.
I am trying to make a simple autoincrement number generator that runs in a single stored procedure.
I am partitioning data mimicking a file tree, using forward slashes to separate+concatenate significant bits that make my partition names. Like so:
/sometype/foo/bar/
/sometype/ids/
The first item is always the document type, and every document type will have a 'ids' sub-partition.
Instead of holding documents, the /sometype/ids/ partition will hold and reserve all numerical ids that have been created for this document type, for autoincrement purposes.
this satisfies uniqueness within a partition, stored procedure execution scope, and unique document count within a document type, which is good for my purposes.
I got stumped in a stored procedure where I want to get a specified id, or create it if it does not exist.
I can query my partition with the stored procedure, but the upsert throws an error, using the same partition key.
I designed my database with "pkey" as the name of the property that will holds my partition keys.
Here is the code:
//this stored procedure is always called from a partition of type /<sometype>/ids/ , where <sometype> os one of my document types.
//the /sometype/ids/ is a partition to reserve unique numerical ids, as Cosmos DB does not have a numerical increment out of the box, I am creating a facility for that.
//the actual documents of /sometype/ will be subpartitioned as well for performance.
function getId(opkey, n, id) {
// gets the requested number if available, or next one.
//opkey: string - a partition key of cosmos db of the object that is going to consume the generated ID, if known. must start with /<sometype>/ which is the same that is being used to call this SP
//n: integer - a numerical number for the autoincrement
//id = '' : string - a uuid of the document that is using this id, if known
if (opkey === undefined) throw new Error('opkey cannot be null. must be a string. must be a valid partition key on Cosmos DB.');
n = (n === undefined || n === null)?0:n;
id = (id === undefined || id === null)?'':id;
var collection = getContext().getCollection();
//make opkey parameter into an array
var split_pkey = opkey.split('/');
//recreate the pkey /<sometype>/ids/ because I can't find a reference to this string inside the context.
var idpkey = '/'+split_pkey[1]+'/ids/';
//first query as SQL
//get highest numerical value.
var q = 'SELECT TOP 1 * FROM c \
WHERE c.pkey = \''+idpkey+'\' ORDER BY c.n desc';
//helper function to create uuids. can I ditch it?
function CreateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
// Query documents and take 1st item.
var isAccepted = collection.queryDocuments(
collection.getSelfLink(),
q
,
function (firstError, feed, options) {
if (firstError) throw "firstError:"+firstError;
//console.log(collection.options.);
console.log(idpkey+', '+n+', '+id+"-");
var maxn = 0;
// take 1st element from feed
if (!feed || !feed.length) {
//var response = getContext().getResponse();
//response.setBody(null);
}
else {
maxn = feed[0].n;
//var response = getContext().getResponse();
//var body = { original: '', document: '', feed: feed[0] };
//response.setBody(JSON.stringify(body));
}
console.log(maxn);
//query for existing numerical value
q = 'SELECT TOP 1 * FROM c \
WHERE c.pkey = \''+idpkey+'\' \
AND \
c.number = '+n+' \
OR \
c.id = \''+id+'\'';
var isAccepted2 = collection.queryDocuments(
collection.getSelfLink(),
q
,
function (secondFetchError, feed2, options2) {
if (secondFetchError) throw "second error:"+secondFetchError;
//if no numerical value found, create a new (autoincrement)
if (!feed || !feed.length) {
console.log("|"+idpkey);
var uuid = CreateUUID();
var newid = {
id:uuid,
pkey:idpkey,
doc_pkey:opkey,
n:maxn+1
};
//here I used the javascript query api
//it throws an error claiming the primary key is different and I don't know why, I am using idpkey all the time
var isAccepted3 = collection.upsertDocument(
collection.getSelfLink(),
newid
,
function (upsertError,feed3,options3){
if (upsertError) throw "upsert error:"+upsertError;
//if (upsertError) console.log("upsert error:|"+idpkey+"|");
//var response = getContext().getResponse();
//response.setBody(feed[0]);
});
if (!isAccepted3) throw new Error('The third query was not accepted by the server.');
console.log(" - "+uuid);
}
else {
//if id found, return it
//maxn = feed[0].n;
var response = getContext().getResponse();
response.setBody(feed[0]);
//var body = { original: '', document: '', feed: feed[0] };
//response.setBody(JSON.stringify(body));
}
});
if (!isAccepted2) throw new Error('The second query was not accepted by the server.');
});
if (!isAccepted) throw new Error('The query was not accepted by the server.');
}
The error message is :
"Requests originating from scripts cannot reference partition keys other than the one for which client request was submitted."
I don't understand why it thinks it is in error, as I am using the variable idpkey in all queries to hold the correct pkey.
Talk about brain fart!
I was violating my own rules because I was misspelling the partition name in the request, making the first part of the partition key /sometype/ different from the parameter sent, causing a mismatch between the execution scope's partition key and the idpkey variable, resulting in the error.

priority-web-sdk: fieldUpdate for choose field failed

My form contains a field with drop down values (the values came from the choose function) and when I am trying to update the field (with fieldUpdate) in the second time I always get the following error: "A record with the same value already exists in the screen", What is the correct order of actions that need to be done in order to achieve the right behaviour?
This is my attempt to achieve that:
await actions.loginTest();
const form = await actions.priority.formStart(this.formName,
this.onShowMessgeFunc, this.onUpdateFieldsFunc);
_formInstance = form;
const rows = await form.getRows(1);
console.log("parent form rows", rows);
await _formInstance.setActiveRow(1);
form.choose("CUSTNAME", '').then(options => {
let custOptions = options.SearchLine.map(x => {return {label:x.retval + " -
" + x.string1, value: x.retval }});
}).catch((err) => {
console.log("CHOOSE ERROR", err);
})
When I select a value from the drop-down, those are my actions:
await _formInstance.fieldUpdate("CUSTNAME", data.value);
await _formInstance.saveRow(1);
const rows = await _formInstance.getRows(1);
console.log("rows", rows);
In the first time it work's great, but when I select a different value for the second time I get an error that say that this value already exists (it's like it think that I am trying to update the value but I don't, I just want to get the values of other fields that return as a result of the field trigger when I leave the field in Priority). I don't have any purpose to change values, just getting information on other fields and data from sub-forms.
I don't have any purpose to change values, just getting information on other fields and data from sub-forms.
In order to achieve your purpose you could choose one of the following flows, that should work:
Recommended: Use getRows() after you have setSearchFilter() in order to retrieve the row you're interested in including its fields. Then easily setActiveRow() with its index to startSubForm(). You could always use clearRows() to clear the current rows and retrieve others.
Example:
const form = await actions.priority.formStart(this.formName,
this.onShowMessgeFunc, this.onUpdateFieldsFunc);
const filter = {
QueryValues:
[{
field: 'CUSTNAME',
fromval: value,
op: '='
}]
}
await form.setSearchFilter(filter)
const rows = await form.getRows(1);
console.log("parent form rows", rows);
await form.setActiveRow(1);
await form.startSubForm(1);
Perform the 'update' on a newRow() without calling getRows(). Then saveRow() and startSubForm() to get the information you need. Do this for each record you trying to retrieve its data.
Explanation: When calling getRows() you retrieve some rows. Then you cannot update a key field with a value that already exists in the retrieved rows otherwise you get that error.

'System.Data.Entity.Core.EntityCommandExecutionException' occurred in EntityFramework.SqlServer.dll but was not handled in user code

I did raw SQL query below to select only certain fields from a table.
{
List<CustEmpVM> CustomerVMlist = new List<CustEmpVM>();
var cid = db.Customers.SqlQuery("select SchedDate from Customer where CustID = '#id'").ToList<Customer>();
}
But i keep getting the error of:
System.Data.Entity.Core.EntityCommandExecutionException occurred in EntityFramework.SqlServer.dll but was not handled in user code
Additional information: The data reader is incompatible with the specified ALFHomeMovers.Customer. A member of the type, CustID, does not have a corresponding column in the data reader with the same name.
The exception message is pretty straightforward: the query expected to return full entity of Customer table but only SchedDate column returned, hence EF cannot done mapping other omitted columns including CustID.
Assuming Customers is a DbSet<Customer>, try return all fields from Customer instead:
// don't forget to include SqlParameter
var cid = db.Customers.SqlQuery("SELECT * FROM Customer WHERE CustID = #id",
new SqlParameter("id", "[customer_id]")).ToList();
If you want just returning SchedDate column, materialize query results and use Select afterwards:
var cid = db.Customers.SqlQuery("SELECT * FROM Customer WHERE CustID = #id",
new SqlParameter("id", "[customer_id]"))
.AsEnumerable().Select(x => x.SchedDate).ToList();
NB: I think you can construct LINQ based from the SELECT query above:
var cid = (from c in db.Customers
where c.CustID == "[customer_id]"
select c.SchedDate).ToList();
Similar issue:
The data reader is incompatible with the specified Entity Framework
Use below query instead of raw query:
{
List<CustEmpVM> CustomerVMlist = new List<CustEmpVM>();
var cid = db.Customers.Where(w=>w.Id == YOURCUSTOMERID).Select(s=>new Customer{SchedDate = s.SchedDate }).ToList();
}
It will give compile time error rather than run time error.

How can I update table in Entity framework?

I am calling a web service from my MVC project and if it is successful then it returns process complete. This result, I am storing in variable called y.
var y = Here pass required parameters and if it is successfull store result in y
when I put breakpoint here and if process complete, I can see result in var y.
So if process complete I need to update my table. For this can I do like this ?
if( y = "Process complete")
{
update table code here
}
and I don't know how to update table in Entity Framework. Here I need to update table called table1 and set column2 = 1, column 3 = value of column 4 where column 1 = value of column 1.
What I know for this is :
UPDATE tableName
SET column2 = 1, column3 = context.FirstOrDefault().column4
WHERE column1 = context.FirstOrDefault(). column1
Update :
Hi i got to know how to write code to update table.But when i put break-point and come to savechanges method i am getting Property export is part of the objects key information and cannot be modified error.
This is the code i am using to update my table :
var rec = (from s in geton.table_1
where s.on_id == geton.table_1.FirstOrDefault().on_id
select s).FirstOrDefault();
rec.export = 1;
rec.on_date = geton.table_1.FirstOrDefault().on_date;
geton.SaveChanges();
A new entity can be added to the context by calling the Add method on DbSet. This puts the entity into the Added state, meaning that it will be inserted into the database the next time that SaveChanges is called.
For example:
using (var context = new YourContext())
{
var record = new TypeName { PropertyName = "Value" };
context.EntityName.Add(record );
context.SaveChanges();
}
For More Info :
http://msdn.microsoft.com/en-us/library/bb336792.aspx
http://msdn.microsoft.com/en-us/data/jj592676.aspx
http://www.entityframeworktutorial.net/significance-of-savechanges.aspx
Hi i got to know how to write code to update table.But when i put break-point and come to savechanges method i am getting Property export is part of the objects key information and cannot be modified error.
That sounds more like a Key error. Are you sure you have put a primary key on that table?
If not then EF just uses the whole table as the key essentially

Resources