Google Appmaker createItem failing with could not select element - google-app-maker

I have a temporary table where I let the user copy the record that needs to be edited. Once the edit is complete, I copy it back.
I am getting an error when I am trying to copy the original record to temporary table for editing. Here's the code I am using
console.log('copyOriginalToTemp ' + tempRecord.ID + ' options ' + JSON.stringify(options));
var myCreateDatasource = app.datasources.RadiosTemp.modes.create;
console.log('# of items in myCreateDatasource ' + myCreateDatasource.items.length);
var draft = myCreateDatasource.item;
draft.BatchId = options.BatchId ;
draft.County = tempRecord.County ;
... // lot of assignments
console.log('About to create item ');
myCreateDatasource.createItem(function(createdRecord) {
console.log('Creating the Item ' + createdRecord._key);
app.datasources.RadiosTemp.query.filters.BatchId._equals = options.BatchId;
.....
});
Error message tells me that newly created item cannot be selected but I have no idea why?. If I change the datasource to Manual Save, I get the same error with no key since it is in Manual save mode.

Related

X++ assign Enum Value to a table column

I am trying to pull the Enum chosen from a dialog and assign the label to a table's column.
For example: Dialog opens and allows you to choose from:
Surface
OutOfSpec
Other
These are 0,1,2 respectively.
The user chooses OutOfSpec (the label for this is Out Of Spec), I want to put this enum's Name, or the label, into a table. The column I'm inserting into is set to be a str.
Here's the code I've tried, without success:
SysDictEnum dictEnum = new SysDictEnum(enumNum(SDILF_ScrapReasons));
reason = dialog.addField(enumStr(SDILF_ScrapReasons),"Scrap Reason");
dialog.run();
if (!dialog.closedOk())
{
info(reason.value());
return;
}
ttsBegin;
// For now, this will strip off the order ID from the summary fields.
// No longer removing the Order ID
batchAttr = PdsBatchAttributes::find(itemId, invDim.inventBatchId, "OrderId");
orders = SDILF_BreakdownOrders::find(batchAttr.PdsBatchAttribValue, true);
if (orders)
{
orders.BoxProduced -= 1;
orders.update();
}
// Adding a batch attribute that will include the reason for scrapping
select forUpdate batchAttr;
batchAttr.PdsBatchAttribId = "ScrapReason";
//batchAttr.PdsBatchAttribValue = any2str(dictEnum.index2Value(reason.value()));
batchAttr.PdsBatchAttribValue = enum2str(reason.value());
batchAttr.InventBatchId = invDim.inventBatchId;
batchAttr.ItemId = itemId;
batchAttr.insert();
Obviously this is not the whole code, but it should be enough to give the issue that I'm trying to solve.
I'm sure there is a way to get the int value and use that to assign the label, I've just not been able to figure it out yet.
EDIT
To add some more information about what I am trying to accomplish. We make our finished goods, sometimes they are out of spec or damaged when this happens we then have to scrap that finished good. When we do this we want to keep track of why it is being scrapped, but we don't want just a bunch of random reasons. I used an enum to limit the reasons. When the operator clicks the button to scrap something they will get a dialog screen pop-up that allows them to select a reason for scrapping. The code will then, eventually, put that assigned reason on that finished items batch attributes so that we can track it later in a report and have a list of all the finished goods that were scrapped and why they were scrapped.
I'm not entirely sure of your question, but I think you're just missing one of the index2[...] calls or you're not getting the return value from your dialog correctly. Just create the below as a new job, run it, make a selection of Open Order and click ok.
I don't know the difference between index2Label and index2Name.
static void Job67(Args _args)
{
Dialog dialog = new dialog();
SysDictEnum dictEnum = new SysDictEnum(enumNum(SalesStatus));
DialogField reason;
SalesStatus salesStatusUserSelection;
str label, name, symbol;
int value;
reason = dialog.addField(enumStr(SalesStatus), "SalesStatus");
dialog.run();
if (dialog.closedOk())
{
salesStatusUserSelection = reason.value();
// Label
label = dictEnum.index2Label(salesStatusUserSelection);
// Name
name = dictEnum.index2Name(salesStatusUserSelection);
// Symbol
symbol = dictEnum.index2Symbol(salesStatusUserSelection);
// Value
value = dictEnum.index2Value(salesStatusUserSelection);
info(strFmt("Label: %1; Name: %2; Symbol: %3; Value: %4", label, name, symbol, value));
}
}

AppMaker - Navigate to Last Page on Table

Scenario:
I have a calculated SQL that returns 100 results.
Added a table (from this calculated SQL) and limited the size of the page by 25 results.
This will generate 4 pages.
Pager form AppMaker works well (navigates between pages) but i need a button that navigates directly from page 1 to the page 4.
is this possible?
Anyone got a solution for this?
Regards
If you need to know how many entries your table has (in your case it's seems fixed to 100, but maybe it could grow), you can still do what you want:
E.g. say your table on YOURPAGE depends on a datasource called Customers.
Create a new Data item called CustomerCount, with just one field, called Count (integer).
Its data source would be a sql query script:
Select count(CustomerName) as Count from Customers
on the page you are having the table on, add a custom property (say called
Count of type integer)
In the page attach event, set the property asynchronously with this custom action:
app.datasources.CustomerCount.load(function() {
app.pages.YOURPAGE.properties.Count = app.datasources.CustomerCount.count;
app.datasources.Customers.query.pageIndex = #properties.Count / 25;
app.datasources.Customers.datasource.load();
});
I tried similar things successfully in the past.
Found a solution for this:
ServerScript:
function CandidateCountRows() {
var query = app.models.candidate.newQuery();
var records = query.run();
console.log("Number of records: " + records.length);
return records.length;
}
in the button code:
var psize = widget.datasource.query.pageSize;
var pidx = widget.datasource.query.pageIndex;
var posicao = psize * pidx;
var nreg = posicao;
google.script.run.withSuccessHandler(function(Xresult) {
nreg = Xresult;
console.log('position: ' + posicao);
console.log('nreg: ' + nreg);
console.log('psize: ' + psize);
console.log('pidx: ' + pidx);
var i;
for (i = pidx; i < (nreg/psize); i++) {
widget.datasource.nextPage();
}
widget.datasource.selectIndex(1);
}).CandidateCountRows();
This will allow to navigate to last page.
If you know for a fact that your query always returns 100 records and that your page size will always be 25 records then the simplest approach is to make sure your button is tied to the same datasource and attach the following onClick event:
widget.datasource.query.pageIndex = 4;
widget.datasource.load();

Show Log of a file in jgit when committng it as a BLOB

Implemented the above logic to create a new commit (with no parents) that contains only my file. Commits are fast in the repository as compared to CommitCommand commit = git.commit();
But I am not able to get the Logs of a particular file , the number of times it has been updated/revised , and every time i go for Constants.HEAD , I am getting null.
Any help will be of great advantage.
Git git = jGitUtil.openRepo();
Repository repository = git.getRepository();
ObjectInserter repoInserter = repository.newObjectInserter();
ObjectId commitId = null;
try
{
byte[] fileBytes= FileUtils.readFileToByteArray(sourceFile);
// Add a blob to the repository
ObjectId blobId = repoInserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, fileBytes);
// Create a tree that contains the blob as file "hello.txt"
TreeFormatter treeFormatter = new TreeFormatter();
treeFormatter.append(actualFileName, FileMode.REGULAR_FILE, blobId);
ObjectId treeId = treeFormatter.insertTo(repoInserter);
System.out.println("File comment : " + relativePath + PortalConstants.FILESEPARATOR + actualFileName + PortalConstants.EP_DELIMETER + userComments);
// Create a commit that contains this tree
CommitBuilder commit = new CommitBuilder();
PersonIdent ident = new PersonIdent(user.getFirstName(), user.getUserId());
commit.setCommitter(ident);
commit.setAuthor(ident);
commit.setMessage(relativePath + PortalConstants.FILESEPARATOR + actualFileName + PortalConstants.EP_DELIMETER + userComments);
commit.setTreeId(treeId);
commitId = repoInserter.insert(commit);
System.out.println(" commitId : " + commitId.getName());
repoInserter.flush();
System.out.println("Flush Done");
}catch(IOException ioe){
log.logError(StackTraceUtil.getStackTrace(ioe));
System.out.println(StackTraceUtil.getStackTrace(ioe));
}
finally
{
repoInserter.release();
}
return commitId.getName();
}
I would probably use Add File and Commit File porcelain commands instead of trying to implement it myself. Then retrieving the log should be possible via something like this:
Iterable<RevCommit> logs = new Git(repository).log()
.all()
.call();
for(RevCommit rev : logs) {
System.out.println("Commit: " + rev + " " + rev.getName() + " " + rev.getId().getName());
}
Where you can retrieve the additional information based on the commit-id.
I have now also added this as new snippet Show Log
Note that if you are creating a commit with no parents, you are saying that there is no history. Therefore you won't be able to see any other changes from that history because it doesn't exist.
You probably should use a commit with the parent of the current position of the branch so that you'll be able to get more information.

Linq to dataset, Query optimization

I have following linq queries:
var itembind = (from q in dsSerach.Tables[0].AsEnumerable()
select new
{
PatternID = q.Field<int>("PatternID"),
PatternName = q.Field<string>("PatternName") + " " + q.Field<string>("ColorID") + q.Field<string>("BookID"),
ColorID = q.Field<string>("ColorID"),
BookID = q.Field<string>("BookID"),
CoverImage = (from img1 in objJFEntities.ProductImages.ToList()
where img1.PatternName.ToLower() == q.Field<string>("PatternName").ToLower()
select new CoverImage
{
URL = "Images/MediumPatternImages/" +
q.Field<string>("PatternName") + "_" + q.Field<string>("ColorID") + q.Field<string>("BookID") + q.Field<string>("ImageExtension"),
ID = q.Field<int>("ProductImageID")
}).FirstOrDefault(),
TotalCount = q.Field<int>("TotalCount")
}).Distinct();
var patterns = (from r in itembind
group r by new { r.PatternID, r.ColorID } into g
select new SearchPattern
{
PatternID = g.Key.PatternID,
PatternName = string.Join(",", g.OrderBy(s => s.ColorID).OrderBy(s => s.BookID)
.Select(s => String.Format("<a href='{0:s}' title='{1:s}'>{2:s}</a><br />",
new object[] { String.Format("Product.aspx?ID={0}&img={1}", g.Key.PatternID, s.CoverImage.ID), s.PatternName, s.PatternName })).FirstOrDefault()),
CoverImage = g.Count() > 1 ? (from img1 in objJFEntities.ProductImages.ToList()
where img1.ProductImageID == g.Select(i => i.CoverImage.ID).FirstOrDefault() && img1.ColorID.ToString() == g.Key.ColorID
select new CoverImage
{
URL = "Images/MediumPatternImages/" +
img1.PatternName + "_" + img1.ColorID + img1.BookID + img1.ImageExtension,
ID = img1.ProductImageID
}).FirstOrDefault() : g.Select(i => i.CoverImage).FirstOrDefault()
}).ToList();
these queries are taking more then 1 minute to execute for the 1000 records only.
The dsSearch is a dataset filled with records returned from my procedure in SQL.
Am using entity framework. The site is deployed with IIS7.0. The SQL server 2008 is in use.
I got "Error Message:Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding." ,
"Cannot open database "DB" requested by the login. The login failed." & "The underlying provider failed on Open." kind of error very frequently site.
Please tell me how to optimize such a query.
EDIT:
Here is the procedure
http://pastie.org/7160934
In the first query you are doing a objJFEntities.ProductImages.ToList() , with the ToList() call you are fetching every entry from the database, and later filter the results in memory.
Rolfvm is correct in pointing out that objJFEntities.ProductImages causes the problem, but the analysis is a bit different. You fetch the entire ProductImages table into memory for each iteration of the query when you enumerate over it. So one optimization would be to fetch the images first in a collection and use that collection in the query statement
var localImages = objJFEntities.ProductImages.ToList();
...
CoverImage = (from img1 in localImages....
But then, your query seems to do far too much. You build the first part itembind without executing it. Then you build the second part (var patterns = (from r in itembind) and execute it by ToList(). But in the second part you never use the CoverImage from the first part. So creating these is a waste of resources. (Or you skimmed the code, hiding another use of the first part).

firefox extension SQLite saving and getting

Ok now for the juicy stuff. All attempts failed to save my string so far.
Here is the code for saving it in sqllite in firefox extension:
var file = Components.classes["#mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsIFile);
file.append("my_db_file_name.sqlite");
var storageService = Components.classes["#mozilla.org/storage/service;1"]
.getService(Components.interfaces.mozIStorageService);
var mDBConn = storageService.openDatabase(file);
mDBConn.execute("CREATE TABLE IF NOT EXISTS log_det (id INTEGER PRIMARY KEY AUTOINCREMENT, acc STRING)");
mDBConn.execute("INSERT INTO log_det (acc) VALUES(" + window['gluistr']+ ")");
mDBConn.drop();
And the code for retrieving the value:
var file = Components.classes["#mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties)
.get("ProfD", Components.interfaces.nsIFile);
file.append("my_db_file_name.sqlite");
var storageService = Components.classes["#mozilla.org/storage/service;1"]
.getService(Components.interfaces.mozIStorageService);
var mDBConn = storageService.openDatabase(file);
var res = mDBConn.execute("SELECT * FROM log_det");
mDBConn.drop();
Is not working. Anybody knows why? Is "execute" ok or do I need "createStatement" or "executeSimpleSQL". I am confused.
Use executeSimpleSQL.
openDatabase returns a mozIStorageConnection instance, which does not have any method named execute. You can use executeSimpleSQL any time you want to execute a SQL statement without bound parameters (which is what you're doing).
You were probably thinking of mozIStorageStatement's execute method. executeSimpleSQL is not sufficient when bound parameters are necessary. Instead, you need to create a statement, bind any parameters, and then execute it:
var statement = mDBConn.createStatement(
"SELECT * FROM log_det WHERE column_name = :parameter");
statement.bindStringParameter(0, "value");
statement.execute();
statement.reset();
Also note that mozIStorageConnection does not have any method named drop. Maybe you meant to write mDBConn.close()?
All of this is covered here:
https://developer.mozilla.org/en/storage

Resources