Suppose I have two objects
1.Account- standard object[it has a field name Status_c which is a picklist having value inprogress and closed]
2.Client_c - custom object[it also have same field name Status__c which is a picklist having value inprogress and closed]
and Client__c has lookup to Account name which means Account has a related list of client object .
My question is :
I want to write a trigger where if I put account status to "closed" I can not put client status to "closed",it should throw an error message on client object or if I put client status to closed I can not put account status to closed vice versa.
Can any one please help me to write a trigger on this??
Conceptually, I think what you are looking to do is set up Validation Rules on both of those objects. Your validation rule on Client_c should be pretty simple: TEXT(Status_c) == 'Closed' && TEXT(Account_c.Status_c) == 'Closed'
The more interesting piece is how you handle making sure none of your related items are Closed when you move the Account to Closed. I tend to prefer creating a field on the Account that keeps track of the status of the related items (checkbox) that basically tells me whether it is valid for me to change my status or not. In this case, the validation rule becomes pretty simple. In order to set that boolean value, I end up using a Trigger on Client__c that basically just grabs all the Accounts when a Client is being modified in the batch (taking into account both inserts, upserts, and deletes):
SELECT Account__c.Id FROM Client__c WHERE Id =: Trigger.new OR Id =: Trigger.old
Then create a Set of all the Account Ids (in this example, named accounts), and run a query to retrieve ALL Clients related to those Ids (in a single query to ensure you don't hit SOQL limits).
SELECT Account__c.Id, Status__c FROM Client__c WHERE Account__c.Id =: accounts
From the results of this, you will iterate over all of the entries, tossing them into a Map keyed by the Account Id where the value is a List of Clients. When you are done, run a query to get all accounts based on the "accounts" list from earlier (which was just a list of strings, not actual Accounts), subsequently iterate over all the Clients associated with that Account, and if a Client is marked as Closed, you will update the metadata of that Account accordingly. If no Clients are closed, the Account will be marked as such. Once you are finished, run an update statement to update the list of Accounts that you have modified.
Related
Hello, I have a problem I created a Registration form and im trying to check if there is any user which have a certain username inside the Firebase Db. I tried to get the reference of all the users.
var users = Database.database().reference("users")
But I don't know how I could check if there is any user with a specified username.
You'll want to use a query for that. Something like:
let query = users.queryOrdered(byChild: "username").equalTo("two")
Then execute the query and check whether the result snapshot exists.
Note though that you won't be able to guarantee uniqueness in this way. If multiple users perform the check at the same time, they may both end up claiming the same user name.
To guarantee a unique user name, you will need to store the user names as the key - as keys are by definition unique within their parent node. For more on this, see some of these top search results and possibly also from here.
I am currently working on an iPad for a restaurant's order management. I am fetching the orders from an API and when there's a new order that order has a bool property isNew which is set to true. I am storing the new orders in a list called pendingOrders. I have created a customEndDrawer that only shows when there's a new order and it lets the user accept or reject the order. But it only works for single order. But I want to implement a system that will keep triggering the customEndDrawer until the pendingOrders list is empty. For example: If there are 2 orders in the pending ordersList the customEndDrawer will show up and let the user accept and reject the order. After users action it will again trigger with the new order details and let user accept or reject that order.
What would be the best solution for implementing this system?
Have you tried a for while loop, whilst your pendingOrders list has items that meet the condition isNew == true? Maybe you can link it to the API stream, so you on each event you trigger the function until each order in your list no longer meets the previously stated condition?
Basically I want the orders to import under Pending Fulfillment only when the selected triggering client field has a value in it (any value). If it is blank I don't want this workflow to run on that SO. I have another workflow in place that affects other orders that are imported through Web Services, so this will be just for specific orders when the Triggering Client Field has a value. I set it up, as you can see in the images attached and no luck!
Parameters: Order Status=Pending Fulfillment (Static value)
Trigger on: After Field Sourcing
Contexts: Web Services
Triggering Client Fields: Custom free form text field that will be
populated with a 4-5 digit number
This looks like it will only work within the UI when someone is entering a sales order - and actually it won't work at all because if that's a free form text field, then it won't trigger the "After Field Sourcing" event. I would make the trigger Before Record Submit, or After Record Submit instead, and then under the "Condition" section, use the visual builder to tell set the criteria to only when Handshake Order ID is not empty. That should do the trick for you.
Please change your workflow action as below
Workflow Action : Import Status
Trigger On : Entry
Condition : {custbody11} is not null
I'm trying to create four distinct queries to a Trac repository from the Mylyn plugin to Eclipse 3.7.1. What I want to do is to divide all tasks into exactly one of the following categories:
My problem: non-resolved tickets assigned to me
Somebody elses problem: non-resolved tickets assigned to somebody else
Nobodys problem (yet): non-resolved, unassigned tickets
No problem: resolved tickets
I have no problem creating the first and the last queries, by simply selecting appropriate status and, in the first case, assignee. But the two in the middle are causing problems:
Somebody elses problem: What I'd like here, is all the tickets that are not in status "closed" and assigned to someone who is not me. I tried the following requirements:
All statuses except "closed"
Owner is not "[my user id]"
But then I get all unassigned tickets as well. I'd lke it to get all tickets that fulfills status != closed && owner != me && owner != '' but it skips the last requirement.
Nobodys problem (yet): Here I'd like all tickets without an assignee, but if I leave the field empty the query creator just ignores it. I'd like status != closed && owner == '', but I only get status != closed.
It seems the problem is including fields in the query with requirements that they are or are not empty, I'm guessing because the form creates the query based on the fields where the user has actually entered some data.
How do I work around this?
One thing we did is to create a user named 'nobody'. 'nobody' is the default owner of all new tickets. To query for unassigned tickets, we simply look for all tickets assigned to 'nobody'. This ended up being easier to script and easier to connect to external tools than using owner==''.
We have a table called Contracts. These contract records are created by users on an external site and must be approved or rejected by staff on an internal site. When a contract is rejected, it's simply deleted from the db. When it's accepted, however, a new record is generated called Contract Acceptance which is written to its own table and is derived from data that exists on the contract.
The problem is that two internal staff members may each end up opening the same contract. The first user accepts and a contract acceptance record is generated. Then, with the same contract record still open on the page, the second user accepts the contract again, creating a duplicate acceptance record.
The quick and dirty way to get past this is to retrieve the contract from the db just before it's accepted, check the status, and produce an error message saying that it's already been accepted. This would probably work for most circumstances, but the users could still click the Accept button at the exact same time and sneak by this validation code.
I've also considered a thread lock deep in the data layer that prevents two threads from entering the same region of code at the same time, but the app exists on two load-balanced servers, so the users could be on separate servers which would render this approach useless.
The only method I can think of would have to exist at the database. Conceptually, I would like to somehow lock the stored procedure or table so that it can't be updated twice at the same time, but perhaps I don't understand Oracle enough here. How do updates work? Are update requests somehow queued up so that they do not occur at the exact same time? If this is so, I could check the status of the record in th SQL and return a value in an out parameter stating it has already been accepted. But if update requests aren't queued then two people could still get into the update sql at the exact same time.
Looking for good suggestions on how to go about this.
First, if there can only be one Contract Acceptance per Contract, then Contract Acceptance should have the Contract ID as its own primary (or unique) key: that will make duplicates impossible.
Second, to prevent the second user from trying to accept the contract while the first user is accepting it, you can make the acceptance process lock the Contract row:
select ...
from Contract
where contract_id = :the_contract
for update nowait;
insert into Contract_Acceptance ...
The second user's attempt to accept will then fail with an exception :
ORA-00054: resource busy and acquire with nowait specified
In general, there are two approaches to the problem
Option 1: Pessimistic Locking
In this scenario, you're pessimistic so you lock the row in the table when you select it. When a user queries the Contracts table, they'd do something like
SELECT *
FROM contracts
WHERE contract_id = <<some contract ID>>
FOR UPDATE NOWAIT;
Whoever selects the record first will lock it. Whoever selects the record second will get an ORA-00054 error that the application will then catch and let them know that another user has already locked the record. When the first user completes their work, they issue their INSERT into the Contract_Acceptance table and commit their transaction. This releases the lock on the row in the Contracts table.
Option 2: Optimistic Locking
In this scenario, you're being optimistic that the two users won't conflict so you don't lock the record initially. Instead, you select the data you need along with a Last_Updated_Timestamp column that you add to the table if it doesn't already exist. Something like
SELECT <<list of columns>>, Last_Updated_Timestamp
FROM Contracts
WHERE contract_id = <<some contract ID>>
When a user accepts the contract, before doing the INSERT into Contract_Acceptance, they issue an UPDATE on Contracts
UPDATE Contracts
SET last_updated_timestamp = systimestamp
WHERE contract_id = <<some contract ID>>
AND last_update_timestamp = <<timestamp from the initial SELECT>>;
The first person to do this update will succeed (the statement will update 1 row). The second person to do this will update 0 rows. The application detects the fact that the update didn't modify any rows and tells the second user that someone else has already processed the row.
In Either Case
In either case, you probably want to add a UNIQUE constraint to the Contract_Acceptance table. This will ensure that there is only one row in the Contract_Acceptance table for any given Contract_ID.
ALTER TABLE Contract_Acceptance
ADD CONSTRAINT unique_contract_id UNIQUE (Contract_ID)
This is a second line of defense that should never be needed but protects you in case the application doesn't implement its logic correctly.