You need to sign in to do that
Don't have an account?
cassie
"last Modified by" is always administrator's name
we have customized object "Quote configuration" on Opportunity Page. There is SFDC quote ID (exp SF-11111) generated after one Quote is created, which only get general information about the quote, similar like billing address, customer information, etc. there is one custom link on this quote page to link our external application for real product detail quote configuration. After this real product detail quote is generated, there is corresponding quote ID called EZ-12345 created. there is also "Save" button on our external application which can update the SFDC database. SFDC quote ID SF-11111 and EZ-12345 were insert to quote table in SFDC and opportunity table in SFDC, the issue is the "last modified by" field in Quote table and opportunity table is always using system administrator's name not individual sfdc user name.
anyone knows what caused this issue?
I am guessing that you are using your administrator's login when you update the SF database from your external Application. this is why you get your administrator's name in the Last Modified by field. If you can explain the process in some more detail, then I might be able to help you.
Message Edited by mojeebahmed on 06-13-2007 02:59 PM
{
binding = new sforce.SforceService();
try
{
// binding.SessionHeaderValue = new sforce.SessionHeader();
// binding.SessionHeaderValue.sessionId = Request.QueryString["SessionID"];
// binding.Url = Request.QueryString["SessionURL"] ;
sforce.LoginResult lr = binding.login("qqq@abc.com", "P12345");
//sforce.LoginResult lr = binding.login(username, password);
binding.SessionHeaderValue = new sforce.SessionHeader();
binding.SessionHeaderValue.sessionId = lr.sessionId;
return "OK";
}
catch (Exception ex)
{
return ex.ToString();
}
}
{
private sforce.SforceService binding;
protected System.Web.UI.WebControls.Label Label1;
string qr_str = new string(' ',1);
{
binding = new sforce.SforceService();
try
{
// binding.SessionHeaderValue = new sforce.SessionHeader();
// binding.SessionHeaderValue.sessionId = Request.QueryString["SFSessionID"];
// binding.Url= Request.QueryString["SFSessionURL"];
sforce.LoginResult lr = binding.login("qqq@abc.com", "P12345");
//sforce.LoginResult lr = binding.login(username, password);
binding.Url = lr.serverUrl;
binding.SessionHeaderValue = new sforce.SessionHeader();
binding.SessionHeaderValue.sessionId = lr.sessionId;
{
sforce.Quote__c q = new sforce.Quote__c();
q.Id = Request.QueryString["SFQuoteID"].ToString();
q.Quote_Date__c = DateTime.Now;
q.Quote_Date__cSpecified=true;
q.Quote_Total__c = Convert.ToDouble(Request.QueryString["QuoteTotal"]);
q.Quote_Total__cSpecified=true;
q.EZ_Quote_Quote_Id__c = Request.QueryString["QuoteID"];
sforce.SaveResult[] sr = binding.update(new sforce.sObject[]{q});
}
else //loading quote into opportunity
{
//initializing variables
sforce.QueryResult qr = null;
sforce.sObject[] updateArr = new sforce.sObject[50];
sforce.sObject[] createArr = new sforce.sObject[50];
string[] deleteArr = new String[50];
sforce.Quote__c q = new sforce.Quote__c();
string EzQuoteProductID = new string('c',1);
{
//starting building update array
//1. all other quotes in the opportunity needs to have their forecast flags turned off
qr_str = ("Select Id from Quote__c where Opportunity__c = '" + Request.QueryString["OppID"] + "'" + " and Id <> '" + Request.QueryString["SFQuoteID"]) + "'";
qr= binding.query(qr_str);
for (int j=0; j<qr.size; j++)
{
sforce.Quote__c q2 = (sforce.Quote__c)qr.records[j];
q2.Forecast_Flag__c = false;
q2.Forecast_Flag__cSpecified=true;
updateArr[j+2] = q2;
}
/* for (int i=0;i<sr3.Length;i++)
{
if (sr3[i].success)
{
Label1.Text = "success";
}
else
{
// Iterate through the errors
sforce.Error[] errors = sr3[i].errors;
for (int j=0;j<errors.Length;j++)
{
Label1.Text = (errors[j].message);
}
}
}*/
//4. Products
//
qr_str = ("Select Id from OpportunityLineItem where OpportunityId = '" + Request.QueryString["OppID"] + "'");
qr= binding.query(qr_str);
for (int j=0; j<qr.size; j++)
{
sforce.OpportunityLineItem q3 = (sforce.OpportunityLineItem)qr.records[j];
deleteArr[j] = q3.Id; //retrieve all exisiting products on Opportunity
}
sforce.DeleteResult[] deleteResults = binding.delete(deleteArr); //delete all existing product from Opportunity
//get product info from ezquote
sforce.OpportunityLineItem OI= new SFDC.sforce.OpportunityLineItem();
SqlDataAdapter DataAdapter = (new SqlDataAdapter("select i.SortOrder, q.strPartNo as ProductID, i.strDescription as Descr, q.intQuantity as Quantity, i.Price as ListPrice,case when i.ezcategory=7 then convert(varchar(11),convert(decimal(9,2), round(q.fltListPrice * (1-fltDiscount),2))) else convert(varchar(11),convert(decimal(9,2), round((q.fltListPrice * (1-fltDiscount)*(100-" + Request.QueryString["Disc"] + ")/100),2))) end as UnitPrice,convert(decimal(9,2),round((q.fltListPrice * (1-fltDiscount) * intQuantity),2)) as TotalPrice, i.SFDC_PartID, i.SFDC_PriceBookEntryID from quoteline q, items i where q.strPartNo = i.strPartNo and q.intQuoteid = " + Request.QueryString["QuoteID"] + " order by SortOrder", "server='test'; uid=sa;pwd=12345;database=testquote"));
DataSet Prices = new DataSet();
DataAdapter.Fill (Prices, "QuoteLine");
DataTable pricesTable = Prices.Tables[0];
double QuoteSum = 0;
{
OI= new SFDC.sforce.OpportunityLineItem();
OI.Description= dataRow["Descr"].ToString(); //sfdc product descr, limited to 255
OI.OpportunityId = Request.QueryString["OppID"]; //sfdc Opportunity ID, obtained and saved from NewQuote.aspx
OI.PricebookEntryId = dataRow["SFDC_PriceBookEntryID"].ToString();
OI.Quantity = Convert.ToDouble(dataRow["Quantity"]); //ezquote quantity
OI.QuantitySpecified=true;
OI.UnitPrice = Convert.ToDouble(dataRow["UnitPrice"]); //EzQuote actual line price (might be discount)
OI.UnitPriceSpecified = true;
createArr[k++] = OI; //build an array
//QuoteSum += Convert.ToDouble(dataRow["Quantity"]) * Convert.ToDouble(dataRow["UnitPrice"]);
}
DataAdapter = (new SqlDataAdapter("select fltAmount as UnitPrice, strDescription as Descr from Discounts where intQuoteID=" + Request.QueryString["QuoteID"] + " union select (select sum(fltlistprice*(1-fltdiscount)*intquantity)* subtotals.fltdiscount from quoteline where intquoteid = subtotals.intquoteid and intquoteline between subtotals.intlinestart and subtotals.intlineend), strDescription from subtotals where intquoteid = " + Request.QueryString["QuoteID"], "server='test'; uid=sa;pwd=12345;database=testquote"));
Prices = new DataSet();
DataAdapter.Fill (Prices);
pricesTable = Prices.Tables[0];
foreach (DataRow dataRow in pricesTable.Rows) //loop through each quote line in EzQuote
{
OI= new SFDC.sforce.OpportunityLineItem();
OI.Description= dataRow["Descr"].ToString(); //sfdc product descr, limited to 255
OI.OpportunityId = Request.QueryString["OppID"]; //sfdc Opportunity ID, obtained and saved from NewQuote.aspx
OI.PricebookEntryId = "01u30000000KKHb".ToString();
OI.Quantity = 1; //ezquote quantity
OI.QuantitySpecified=true;
OI.UnitPrice = Convert.ToDouble(dataRow["UnitPrice"])*-1; //EzQuote actual line price (might be discount)
OI.UnitPriceSpecified = true;
createArr[k++] = OI; //build an array
//QuoteSum += Convert.ToDouble(Convert.ToDouble(dataRow["UnitPrice"])*-1);
}
//Label1.Text= Request.QueryString["OppID"];
//create
sforce.SaveResult[] sr4 = binding.create(createArr); //create products on Opportunity
//end of loop
//2. this quote needs to have Quote Date, Quote Total updated and Forecast Flag set to yes
q.Id = Request.QueryString["SFQuoteID"].ToString();
q.Quote_Date__c = DateTime.Now;
q.Quote_Date__cSpecified=true;
q.Quote_Total__c = Convert.ToDouble(Request.QueryString["QuoteTotal"]);
//q.Quote_Total__c = QuoteSum;
q.Quote_Total__cSpecified=true;
q.Forecast_Flag__c=true;
q.Forecast_Flag__cSpecified=true;
q.EZ_Quote_Quote_Id__c =Request.QueryString["QuoteID"];
updateArr[0] = q; //append unto array
sforce.SaveResult[] sr = binding.update(updateArr);
/*for (int i=0;i<sr4.Length;i++)
{
if (sr4[i].success)
{
Label1.Text = (sr4[i].id);
}
else
{
// Iterate through the errors
sforce.Error[] errors = sr4[i].errors;
for (int j=0;j<errors.Length;j++)
{
Label1.Text = (errors[j].message);
}
}
}*/
{Label1.Text=ex.ToString();}
}
I have a few more questions. What is the custom link doing on the quote page? Does it open up some S-Control or it is just a direct link to your external application? And how are you getting the dynamic username and password for the salesforce user?
Have you tried to pass the salesforce user session id from salesforce to your external application? you can get the salesforce user's session id easily and pass it to your external application as an argument and replace the following line:
binding.SessionHeaderValue.sessionId = lr.sessionId;
with this:
binding.SessionHeaderValue.sessionId = Request.QueryString["SFUserSessionID"].ToString();
You can still login with the admin user, just replace the above line and after that every request from your external application will be received by salesforce as if the request is coming from the actual salesforce user and not the admin.
I hope that this will work for you and the last modified by field wil contain the name of the salesforce user and not the admin user.
Let me know what happen after this change.
It depends how you have created the project as there are a few ways to make the changes, if al the project files i.e. aspx and cs files are on your server then you don't need to recompile the files. The server will do it automatically on run time. in other case you have to recompile the files and your project.
So you better recompile the project and rebuild it. I hope this will work. Any ways please let me know what happen.