Why DAC class is not saved in Acumatica? - erp

Let's say I have following code:
DacClass cl = new DacClass();
//init fields of DacClass()
this.Persist();
but when I run this code in any graph, I'm getting different errors. Why?

You can't create DAC item in db in current graph. As mentioned in T200 manual you should create instance of graph and in created instance to call method persist. Another option is to use method PXDataBase.Insert. The first option is preferable for case if you need insertion with graph logic. The second option is preferable for cases if you need perfomance.

Related

Looping through list of objects created by createEntry() and editing their properties before doing submitChange()

Good afternoon fellow developers,
I have come across a scenario where I found myself needing to retrieve the list of pending changes from my model and editing a specific property of those entries before sending them to my back-end.
These are new entities I created using the createEntry() method of the OData model v2. But, at the time of creation of said entities, I do not possess the value I need to add to them yet. This is the list of entities I retrieve by using the getPendingChanges() method on my model:
What I need to do is to loop through each of these newly created entities and set a specific property into them before actually sending them to my back-end with the submitChanges() method. Bare in mind that these are entry objects created by the createEntry() method and exist only in my front-end until I am able to submit them with success.
Any ideas that might point me in the right direction? I look forward to reading from you!
I was able to solve this issue in the following way:
var oPendingChanges = this.model.getPendingChanges();
var aPathsPendingChanges = $.map(oPendingChanges, function(value, index) { return [index];});
aPathsPendingChanges.forEach(sPath => oModel.setProperty("/" + sPath + "/PropertyX","valueFGO"));
The first two instructions retrieve the entire list of pendingChanges objects and then builds an array of paths to each individual entry. I then use that array of paths to loop through my list of pending changes and edit into the property I want in each iteration of the loop. Special thanks to the folks at answers.sap for the guidance!

JShell: Accessing Objects Created by Snippets

I am very confused about something and I would appreciate some insight here.
Say I want to build a GUI that visualizes what is going on inside JShell, i.e. how the, by snippets created objects reference each other and what, by Snippets created objects are contained inside my running instance of JShell. How do I access these objects, and most of all, how do I access how they reference each other?
A concrete example: I create a JShell instance, pass it a few snippets created by the user, which cause the creation of, for example, an ArrayList, a few objects, and add said objects to said ArrayList.
How do I access this ArrayList and the objects contained within it to visualize this in a GUI?
To clarify further:
//say I create a Jshell:
JShell jShell = JShell.create();
//Which then evauletes user code passed from the GUI:
jShell.eval(userCode)
//userCode could be following lines each passed as separate Strings:
“ArrayList<TestObject> allObj = new ArrayList<TestObject>();”
“TestObject tst = new TestObject();”
“TestObject tst2 = new TestObject();”
“allObj.add(tst);”
“allObj.add(tst2);”
How do I access “allObj”?
How do I access “tst” and the object it points to? (the “TestObject”instance that “tst” points to);
I know eval() returns a list of SnippetEvents which contain the changed/added snippets, however, I can’t get my head around how to access the objects created by those snippets.
Assuming your classpath has access to the TestObj you could implement Serializable on that object. Upon completion of the eval run another method automatically that serializes the output. Then you can deserialize that object inside your code.

Access Parse Object ID right after instantiation

I'm creating two PFObjects at the same time that should reference each other's object IDs when they're saved. In the example below, the second object is supposed to save the first object's object ID in an array.
let objectForFirstClass = PFObject(className:"ClassOne")
let objectForSecondClass = PFObject(className: "ClassTwo")
objectForSecondClass.setObject([objectForFirstClass.objectId!], forKey: "classOneObjectArray")
The last line is causing the error because objectForFirstClass.objectId is nil. I'd assume this is because the object hasn't been saved yet. How can I fix this?
You want to save after creating the first object, and in the completion handler, create the second one with a reference to the first one.
You can use saveAllInBackground:block: for this.
Correct, the object id is assigned by the server when saved. I'd be tempted to write some cloud code to do what you want so you can send some details and the cloud code will create and connect the objects, then return both of them to you. You can of course do the same thing locally in your app, there's just more network comms.
You should also consider using pointers or relationships. These are better for querying, though the same save requirements apply before you can set the connections.

Can't access one model's instance variables from another model) (self.ruby)

I have two models, Draft and Pick. Draft creates an array of available Players in an instance variable named 'available_players'. This is done using the 'before_save' callback. The callback runs the instance method 'start' which in turn runs 'set_active_players'. I've tested all of this in my Draft_spec and I have no problems loading players and having them returned in the available_players array. All my draft specs pass.
The problem is that when I try to access the 'available_players' instance variable from Pick.rb, it returns nil. If I call 'draft.start' (the instance method that should run before Draft.rb saves), I can suddenly access the 'available_players' array... it's like the Draft object is not creating the available_players array even though I have the before_save method in place.
Here is the code that fails inside of Pick.rb:
def available_players_returns_nil
#draft_object.available_players
end
Here is the code that works inside of Pick.rb:
def available_players_working
#draft_object.start
#draft_object.available_players
end
I don't want to have to call start every time I call the method because available_players should not need to reload ALL Players. Please help me access available_players!
Links: failing Pick specs, Pick.rb
EDIT:
I should add that #draft_object is found using
#draft_object = Draft.find(self.draft_id)
For a start, this is wrong:
#draft_object = Draft.find(self.draft_id)
You have an association set up, so use it. You can simply use draft within your Pick object to access the Draft it belongs to. No need to assign it to an instance variable called #draft_object.
Same story with player.
Incidentally, your set_available_players method in Draft is just looping through all of the players and adding them to an instance variable. Why are you doing this? Why don't you simply grab the players directly if you need them in Pick? Like this:
#players = Player.all
Also ... I'm somewhat concerned that pretty much all of your tests are commented out. I hope that's not by design?

Hydrating Database

I am new to learning and understanding how Hydration works, just wanted to point that out first. I'm currently able to Hydrate Select and Insert queries without any problems.
I am currently stuck on trying to Hydrate Update queries now. In my entity I have setup the get/set options for each type of column in my database. I've found that the ObjectProperty() Hydrator works best for my situation too.
However whenever I try to update only a set number of columns and extract via the hydrator I am getting errors because all the other options are not set and are returning null values. I do not need to update everything for a particular row, just a few columns.
For example in my DB Table I may have:
name
phone_number
email_address
But I only need to update the phone_number.
$entity_passport = $this->getEntityPassport();
$entity_passport->setPrimaryPhone('5551239876');
$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
'employeeid' => '1'
));
This returns an error because setName() and setEmailAddress() are not included in this update and the query returns that the values cannot be null. But clearly when you look at the DB Table, there is data already there. The data that is there does not need to be changed either, only in this example does the PrimaryPhone() number.
I've been looking and reading documentation all over the place but I cannot find anything that would explain what I am doing wrong. I should note that I am only using Zend\Db (Not Doctrine).
I'm assuming I've missed something someplace due to my lack of knowledge with this new feature I'm trying to understand.
Perhaps you don't Hydrate Update queries... I'm sort of lost / confused. Any help would be appreciated. Thank you!
I think you're having a fundamental misconception of hydration. A hydrator simply populates an entity object from data (hydrate) and extracts data from an entity object (extract). So there are no separate hydrators for different types of queries.
In your update example you should first retrieve the complete entity object ($entity_passport) and then pass it to the TableGateway's update method. You would retrieve the entity by employeeid, since that's the condition you're using to update. So something like this:
$entity_passport = $passportMapper->findByEmployeeId(1);
$entity_passport->setPrimaryPhone('5551239876');
$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
'employeeid' => $entity_passport->getId()
));
This is assuming you have some sort of mapper layer. Otherwise you could use your passport TableGateway (I assume that's what getTablePassport() returns, no?).
Otherwise, if you think retrieving the object is too much overhead and you just want to run the query you could use just a \Zend\Db\Sql\Sql object, ie:
$sql = new \Zend\Db\Sql\Sql($dbAdapter);
$update = $sql->update('passport')
->set(array('primary_phone' => $entity_passport->getPrimaryPhone()))
->where(array('employeeid' => $employeeId));
Edit:
Maybe it was a mistake to bring up the mapper, because it may cause more confusion. You could simply use your TableGateway to retrieve the entity object and then hydrate the returned row:
$rows = $this->getTablePassport()->select(array('employeeid' => 1));
$entity_passport = $this->getHydrator($rows->current());
[...]
Edit 2:
I checked your gist and I noticed a few things, so here we go:
I see that your getTablePassport indeed does return an object which is a subclass of TableGateway. You have already set up this class for it to use a HydratingResultset. This means you don't need to do any manual hydrating when retrieving objects using the gateway.
You also already implemented a Search method in that same class, so why not just use that? However I would change that method, because right now you're using LIKE for every single column. Not only is it very inefficient, but it will also give you wrong results, for example on the id column.
If you were to fix that method then you can simply call it in the Service object:
$this->getTablePassport->Search(array('employeeid' => 1));
Otherwise you could just implement a separate method in that tablegateway class, such as
public function findByEmployeeId($employeeId)
{
return $tableGateway->select(array('employeeid' => $employeeId));
}
This should already return an array of entities (or one in this specific case). P.S. make sure to debug and check what is actually being returned when you retrieve the entity. So print_r the entity you get back from the PassportTable before trying the update. You first have to make sure the retrieval code works well.

Resources