I am using a JavaScript to dynamically output a specific default text to the additional comments box in Bugzilla, based on the bug status which is selected from the drop down menu. I have tried using 'bug.bug_status' but this only changes on the submission of the page. The variable I have found which populates the drop down menu is 'bug_status.name' but when I try use this variable, it does not seem to be recognised. Has anyone any suggestions what may be causing the problem? Has anyone tried this before?
The following code has been placed at the start of the knob.html.tmpl file.
[% PROCESS global/variables.none.tmpl %]
[% # Output a specific default content in the comments box depending on bug status. %]
<script type="text/javascript">
<!--
var messages = ['Message 0', 'Message 1', 'Message 2', 'Message 3', 'Message 4', 'Message 5', 'Message 6'];
function changetext(selectObj){
var textAreaElement = document.getElementsByName("comment")[0];
[% IF (bug_status.name == "ASSIGNED") %]
textAreaElement.value = messages[4];
[% ELSIF(bug_status.name == "RESOLVED") %]
textAreaElement.value = messages[5];
[% ELSE %]
var variable1 = 0;
variable1 = bug_status.name
textAreaElement.value = variable1;
[% END %]
Based on your other question, it seems that you want this to change on the client side as the user is selecting a new status. However, the code that you have written in this question will change on the server side before the client sees it. Your if/else tree needs to be written in javascript instead of in Template Toolkit.
So, something like this:
function changetext(selectObj){
var textAreaElement = document.getElementsByName("comment")[0];
var currentStatus = document.getElementById("bug_status").value;
if (currentStatus == "ASSIGNED") {
textAreaElement.value = messages[4];
} else if (currentStatus == "RESOLVED") {
textAreaElement.value = messages[5];
} else {
textAreaElement.value = currentStatus;
}
}
Related
I have various streams but some of the streams are becoming stale. To avoid them becoming stale, I want to put some process in place which can read the 'show stream' property 'stale after', if it is only 1 day left, run a process to refresh the stream.
To achieve your goal you have to capture the output of SHOW STREAMS https://docs.snowflake.com/en/sql-reference/sql/show-streams.html. You can start building a stored procedure that runs it and returns its output as a resultset using TABLE(RESULT_SCAN(LAST_QUERY_ID())) similar to the following one, which could be enriched by a parameter for the time window you want to check (your "1 day left) and a subsequent CREATE OR REPLACE STREAM.
Please note this is not a full solution to your problem but only half of it as it does not include the action required to re-create the stale streams.
CREATE OR REPLACE PROCEDURE sp_show_stream_stale()
RETURNS VARIANT NOT NULL
LANGUAGE Javascript
EXECUTE AS Caller
AS
$$
var sql_command0 = snowflake.createStatement({ sqlText:`show streams in database`});
var sql_command1 = snowflake.createStatement({ sqlText:`SELECT "created_on"
, "name"
, "database_name"
, "schema_name"
, "owner"
, "comment"
, "table_name"
, "type"
, "stale"
, "mode"
, "stale_after"
FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))`});
try {
sql_command0.execute();
var db = sql_command1.execute();
var json_rows = {};
var array_of_rows = [];
var COLUMNS = ["created_on","name","database_name","schema_name","owner", "comment", "table_name", "type", "stale", "mode", "stale_after"];
var row_num = 1;
while (db.next()) {
json_rows = {};
for (var col_num = 0; col_num < COLUMNS.length; col_num = col_num + 1) {
var col_name = COLUMNS[col_num];
json_rows[col_name] = db.getColumnValue(col_num + 1);
}
array_of_rows.push(json_rows);
++row_num;
}
return array_of_rows;
}
catch (err) {
return "Failed: " + err;
}
$$;
As the resultset is a single JSON, you can run the stored procedure and soon after the following SELECT statement to get the resultset in tabular format.
CALL sp_show_stream_stale();
SELECT value:created_on::datetime as "created_on",
value:name::string as "name",
value:database_name::string as "database_name",
value:schema_name::string as "schema_name",
value:owner::string as "owner",
value:comment::string as "comment",
value:table_name::string as "table_name",
value:type::string as "type",
value:stale::string as "stale",
value:mode::string as "mode",
value:stale_after::datetime as "stale_after"
FROM (SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())))
, LATERAL FLATTEN(Input => sp_show_stream_stale)
WHERE DATEDIFF(Day, current_timestamp, value:stale_after::datetime) <= 1 ;
Below code works fine when updating/inserting on Visual Force Page one record at a time, receive error 'Insert failed....INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call' when using data loader (error pointing to code, 'insert amcRecord'). Would anyone know how to fix?
trigger Status on Cl__c (after insert, after update)
{
List<AMC__c> amcRecord = new List<AMC__c>();
for (Cl__c cls: Trigger.new )
{
Cl__c oldcls = Trigger.oldMap.get(cls.Id);
if (cls.Status__c == 'Completed' && (oldcls.Status__c != 'Completed' ))
{
AMC__c newAMC = new AMC__c();
newAMC.Cl__c = cls.ID;
newAMC.Default__c = true;
amcRecord.add(newAMC);
insert amcRecord;
}
}
}
amcRecord is a list, not a single item, but you're calling insert for every item in the request [which would only be 1 for the UI, but upto 200 with the data loader. You need to move the insert amcRecord line to after the for (... Trigger.new) loop has finished, so that its only called once, e.g.
trigger Status on Cl__c (after insert, after update)
{
List<AMC__c> amcRecord = new List<AMC__c>();
for (Cl__c cls: Trigger.new )
{
Cl__c oldcls = Trigger.oldMap.get(cls.Id);
if (cls.Status__c == 'Completed' && (oldcls.Status__c != 'Completed' ))
{
AMC__c newAMC = new AMC__c();
newAMC.Cl__c = cls.ID;
newAMC.Default__c = true;
amcRecord.add(newAMC);
}
}
insert amcRecord;
}
You shouldn't be performing DML inside a loop.This exception comes if you try to insert already inserted record.
Account a =new Account();
a.name='Hello';
insert a;
insert a;
Changed
insert amcRecord;
to
upsert amcRecord;
It seems to be working now.
I have a paypal form which is submitted and working, this is part of the ipn, which means I can not see the error reporting on page which means I am a little blind on what is the issue.
Everything looks fine I think.
Here is the code:
$newcustom = rtrim($_POST['custom'], ',');
$buyingarray = explode('~', $newcustom);
$name = $buyingarray[1];
$phone = $buyingarray[2];
$email = $buyingarray[3];
$comments = $buyingarray[4];
$date = $buyingarray[5];
$time = explode(",",$tt[6]);
$person = explode(",",$tt[7]);
$orderID = $tt[0];
$booking_date = strtotime($date);
$nowitsdate = date('Y-m-d G:i:s', strtotime("now"));
$addreservation = $pdo->prepare("INSERT INTO reservations (id, dateCreated, name, email, phone, comments, status, eventID, voucherCode, voucherplace, OrderID) VALUES ('', :dateCreated, :name, :email, :phone, :comments, 1, NULL, '', 'PayPal Purchase', :OrderID)");
$addreservation->execute(array(':dateCreated' => $nowitsdate,':name' => $name,':email' => $email,':phone' => $phone,':comments' => $comments,':OrderID' => $orderID));
$addreservation_num = $addreservation->rowCount();
if($addreservation_num == 0){ $inserterror = $pdo->query("INSERT INTO testipn (id, testing, testing2) VALUES ('','Input into reservations died','')"); exit();}
Now I know that everything is ok with the details coming in as I have input each of the variables into the testipn row which is telling me if an error occurred when the ipn is being used.
As far as I can see everything looks fine yet it still is not finding the problem.
Now the only thing I can think it can be is the NULL within the eventID, maybe that is causing an issue?
If a ID is not present which it wont be within this table, then it needs to be NULL.
The rows effected is 0 which means my error row in the database says: Input into reservations died
Thanks for any input into finding a solution :)
I don't know how to explain this but I'll try hard. I have code that sends a friend request to another user of a site I'm developing. and there are two email fields for that which is the req_email (for the requestor) and the resp_email (for the responder). the code I currently have displays friends of the sender field alone. But sometimes the sender can also be a responder since others may send him requests.
SELECT CASE WHEN status = 'Yes' THEN 'Friends'
ELSE CASE WHEN status = 'No' THEN 'Request Sent'
ELSE CASE WHEN status IS NULL THEN 'Send Request' END
END
END AS Answer,
*
FROM dbo.profile p
LEFT JOIN friends f On p.email = f.[resp_email] AND f.[req_email] = MMColParam
WHERE fname LIKE %varsearch%
AND email NOT LIKE MMColParam2
ORDER BY fname ASC
Now my issue is how to combine both the sender_email and the responder email as one so the results are returned in one instance
Your query is wrong. please check following query:
SELECT CASE WHEN status = 'Yes' THEN 'Friends'
WHEN status = 'No' THEN 'Request Sent'
WHEN status IS NULL THEN 'Send Request'
END AS Answer,
*
FROM dbo.profile p
LEFT JOIN friends f On p.email = f.[resp_email] AND f.[req_email] = MMColParam
WHERE fname LIKE '%varsearch%'
AND email NOT LIKE 'MMColParam2'
ORDER BY fname ASC
I'm relatively new to Apex, but I have a question about a batch job that I am creating. I am trying to insert AccountTeamMember records based on my company's territory alignment. The code seems to be working fine, but with one flaw: it is only inserting 100 AccountTeamMember records per user (it should be closer to 400, as that is how many I have loaded in my dev sandbox). Does anyone know what I can do to get an AccountTeamMember record inserted for all accounts per user, rather than 100 of the ~400? Is it something to do with the query including parent-child relationships and governor limits since it is such an even number (100)?
Here is the relevant code:
//list to hold new account teams
List<AccountTeamMember> acctMembers = new List<AccountTeamMember>();
//list to hold new account sharing rules
List<AccountShare> acctSharingRules = new List<AccountShare>();
global Database.querylocator start(Database.BatchableContext BC){
String query = 'SELECT (SELECT User__c FROM Territory_Users__r), (SELECT Account__c FROM Territory_Accounts__r) FROM Territory_Master__c';
return Database.getQueryLocator(query);}
global void execute(Database.BatchableContext BC, List<sObject> scope){
for (sObject s : scope) {
Territory_Master__c tm = (Territory_Master__c) s;
Territory_User__c[] userList = tm.getSObjects('Territory_Users__r');
Territory_Account__c[] accountList = tm.getSObjects('Territory_Accounts__r');
if (userList != null && accountList != null){
for(Territory_User__c uu : userList){
for(Territory_Account__c aa: accountList){
AccountTeamMember addRecord = new AccountTeamMember();
addRecord.AccountId = aa.Account__c;
addRecord.TeamMemberRole = 'Sales Rep';
addRecord.UserId = uu.User__c;
acctMembers.add(addRecord);
AccountShare addSharing = new AccountShare();
addSharing.AccountId = aa.Account__c;
addSharing.OpportunityAccessLevel = 'Read';
addSharing.CaseAccessLevel = 'Read';
addSharing.AccountAccessLevel = 'Edit';
addSharing.UserOrGroupId = uu.User__c;
acctSharingRules.add(addSharing);
}
}
}
}
//DML
if(acctMembers.size() > 0){
insert acctMembers;
}
if(acctSharingRules.size() > 0){
insert acctSharingRules;
}
}
Thanks,
Trey
FYI: This is the final result based on the answer to the question:
global Database.querylocator start(Database.BatchableContext BC){
String query = 'SELECT Id FROM Territory_Master__c';
return Database.getQueryLocator(query);}
global void execute(Database.BatchableContext BC, List<sObject> scope){
for(sObject s : scope){
Territory_Master__c tm = (Territory_Master__c) s;
List<Territory_User__c> userList = [SELECT User__c FROM Territory_User__c WHERE Territory_Master__c = :tm.Id];
List<Territory_Account__c> accountList = [SELECT Account__c FROM Territory_Account__c WHERE Territory_Master__c = :tm.Id];
if (userList != null && accountList != null){
for(Territory_User__c uu : userList){
for(Territory_Account__c aa: accountList){
AccountTeamMember addRecord = new AccountTeamMember();
addRecord.AccountId = aa.Account__c;
addRecord.TeamMemberRole = 'Sales Rep';
addRecord.UserId = uu.User__c;
acctMembers.add(addRecord);
acctSharingRules.add(new AccountShare(
AccountId = aa.Account__c,
OpportunityAccessLevel = 'Read',
CaseAccessLevel = 'Read',
AccountAccessLevel = 'Edit',
UserOrGroupId = uu.User__c)
);
}
}
}
}
//DML
if(acctMembers.size() > 0){
insert acctMembers;
}
if(acctSharingRules.size() > 0){
insert acctSharingRules;
}
}
I suspect that your subqueries got limited and it's your job to make sure you've finished with this record before moving on to the next one.
http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_soql_relationships.htm
Subquery results are like regular query results in that you might need
to use queryMore() to retrieve all the records if there are many
children. For example, if you issue a query on accounts that includes
a subquery, your client application must handle results from the
subquery as well
(the example is for Java calling Salesforce so don't copy-paste the code, try to understand the concept. As far as I know Apex doesn't have this queryMore method, it's for integrations only)
Option 1
Funny enough, it should in theory work if you'd change the for loops to this:
for(Territory_User__c uu : tm.getSObjects('Territory_Users__r')){
for(Territory_Account__c aa: tm.getSObjects('Territory_Accounts__r'))
That's because for loops written in that way should automatically call their internal queryMore().
If it won't work (I haven't tested it), you'll have to make a bit more complex changes.
Option 2
Remove the subqueries from the main query, you'll have to put them in the execute(). Something like this:
for(sObject s : scope){
Territory_Master__c tm = (Territory_Master__c) s;
for(Territory_User__c uu : [SELECT User__c FROM Territory_User__c WHERE Territory_Master__c = :tm.Id]){
for(Territory_Account__c aa: [SELECT Account__c FROM Territory_Account__c WHERE Territory_Master__c = :tm.Id]){
acctMembers.add(new AccountTeamMember(
AccountId = aa.Account__c,
TeamMemberRole = 'Sales Rep',
UserId = uu.User__c)
);
acctSharingRules.add(new AccountShare(
AccountId = aa.Account__c,
OpportunityAccessLevel = 'Read',
CaseAccessLevel = 'Read',
AccountAccessLevel = 'Edit',
UserOrGroupId = uu.User__c)
);
}
}
}
Side notes
Is there a chance you'll hit a limit of 50K rows retrieved across all objects (Territory Master/User/Account? If that's the case you might have to limit the scope of your batch job (optional second parameter passed to the Database.executeBatch()).
This trick can make your script execute bit faster and use less statements (so you won't hit another governor limit):
acctSharingRules.add(new AccountShare(
AccountId = aa.Account__c,
OpportunityAccessLevel = 'Read',
CaseAccessLevel = 'Read',
AccountAccessLevel = 'Edit',
UserOrGroupId = uu.User__c)
);
There's nothing obviously wrong with your code there, so if I were you I'd try to narrow down the cause of the problem. The source of the problem is going to be one of:
Your query is only returning 100 items in accountList or userList or both
The insert can only handle 100 items at a time and is silently failing to insert the rest
The insert is failing for the items after 100
If you haven't already done so, you should familiarize yourself with using Debug Logs in Salesforce.com (Setup | Monitoring | Debug Logs). Turn them on, then run this code with some System.debug calls in there to figure out:
How many items are in userList and accountList?
If it's more than 100, when you go to insert the share rows, are some of those inserts failing? If you use Database.insert() instead of just the insert statement then you'll get a SaveResult[] back that will tell you for each row you attempted to insert whether it was successful or errored out.
So I can't say off the top of my head why this is failing, and I don't see any particular limit that should apply here, but the above should help you debug it at least.