java.lang.NumberFormatException: For input string: "16000$" in kotlin - android-studio

I want to make display show "16000$" before click increase btn or decrease btn.
when I make code like this error caused by :java.lang.NumberFormatException: For input string: "16000$ . but I should display $. Lets check my code and help me plz.
var productprice = findViewById<TextView>(R.id.productPrice)
productprice.text= intent.getStringExtra("price")+"$"
var price = productPrice.text.toString().toInt()
var inc_val= price
var getPrice = price
decrease.isEnabled=false
increase.setOnClickListener {
increaseInteger()
getPrice+= inc_val
productprice.text=getPrice.toString()+"$"
}
decrease.setOnClickListener {
decreaseInteger()
getPrice -= inc_val
productprice.text=getPrice.toString()+"$"
}

You are trying to parse the string with "$" to int, Hence you are getting NumberFormatException.
Try this instead:
var productprice = findViewById<TextView>(R.id.productPrice)
productprice.text= intent.getStringExtra("price")+"$"
var price = parseInt(intent.getStringExtra("price"))
var inc_val= price
var getPrice = price
decrease.isEnabled=false
increase.setOnClickListener {
increaseInteger()
getPrice+= inc_val
productprice.text=getPrice.toString()+"$"
}
decrease.setOnClickListener {
decreaseInteger()
getPrice -= inc_val
productprice.text=getPrice.toString()+"$"
}

var price = productPrice.text.toString().toInt() - you try to convert "16000$" to Int here. Please get substring here first.
Formally, right code is:
val priceText = productPrice.text.toString()
val price = priceText.substring(0, priceText.length - 1).toInt()
However really I advice you to store value internally. You price is part of model. E.g. you can avoid text parsing and just read value from model. E.g. code will be like this:
var price = intent.getIntExtra("price") // we store int value here, not String
var inc_val= price
decrease.isEnabled=false
displayPrice()
increase.setOnClickListener {
intent.setIntExtra(intent.getIntExtra("price") + inc_val) // read, update, save
displayPrice()
}
decrease.setOnClickListener {
intent.setIntExtra(intent.getIntExtra("price") - inc_val) // read, update, save
displayPrice()
}
/*this function just shows price*/
fun displayPrice() {
val price = intent.getIntExtra("price")
productprice.text= "$price\$"
}

Related

How get Lot/Serial number in Netsuite SuiteScript 2.0 for Inventory Adjustment Transaction?

I'm trying to get the serial numbers from a inventory adjustment in a user event script. The following code works very well for me when the amount to adjust is positive, but not when it is negative.
var invDet = transaction.getSublistSubrecord({sublistId:'inventory',
fieldId:'inventorydetail',
line:x});
for(var y = 0; y = invDet.getLineCount('inventoryassignment'); y++) {
var lotNumber = invDet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'receiptinventorynumber',
line:y});
log.debug('lotNumber', lotNumber);
}
When adjust quantity is negative, receiptinvetorynumber is empty
I have tried using field id equal to 'issueinventorynumber' or 'binnunber' but the returned value is empty.
I found the following comment in a NetsuiteHub forum...
In 2.0 the getValue call returns the internal ID of the serial/lot number and the getText equivalent does not work. Depending on the exact logic you need to execute for the obtained numbers you might need to call a subsequent saved search to obtain the actual serial/lot numbers and not internal IDs (an 'inventorynumber' search will do the trick).
I tried this...
try{
var internalId = invdet.getSublistValue({sublistId:'inventoryassignment',fieldId:'internalid', line:y});
search.create({type:'inventorynumber', filters:[
['internalid', 'is', internalId]
], columns:['inventorynumber']}).run().each(function (result) {
binText = result.getValue('inventorynumber');
log.debug('binText', binText);
});
} catch(e) {
log.debug('Error', e.message);
throw e.message;
}
I am too inexperienced to make this work. I appreciate any help you can give me.
Thanks.
The challenge is that this area of the NetSuite API is not well documented. However, I pushed through it through trial and error and search hours.
var invDet = transaction.getSublistSubrecord({sublistId:'inventory',
fieldId:'inventorydetail',
line:x});
for(var y = 0; y = invDet.getLineCount('inventoryassignment'); y++) {
var Qty = invdet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'quantity',
line:y});
var lotNumber = '';
if(Qty < 0)
{
var ivnNumId = nvdet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'issueinventorynumber',
line:y});
if(ivnNumId !== '')
{
var invNum = record.load({type: 'inventorynumber',id:ivnNumId});
lotNumber = invNum.getValue({fieldId: 'inventorynumber'});
}
}
else
{
lotNumber = invdet.getSublistValue({sublistId:'inventoryassignment',
fieldId:'receiptinventorynumber',
line:y});
}
log.debug('lotNumber', lotNumber);
}
This information was very helpful in ss1.0
I hope it is useful to someone

Fill duedate field based on value of terms field

Is it possible to fill the duedate field based on the terms field? For example, I have a date in the duedate field, but I want to extend it based on the terms field. How can I do it? Through Suitescript or workflow?
The code is incomplete because I don’t know if I’m on the right path.
(NB: It is a user event)
function beforeLoad(context) {
}
function beforeSubmit(context) {
}
function afterSubmit(context) {
var dataEntrega = context.currentRecord
currentRecordRecord.getValue({
fieldId: 'duedate'
})
var dataCondicoes = context.currentRecord
currentRecord.getValue({
fieldId: 'terms'
})
}
return {
beforeLoad: beforeLoad,
beforeSubmit: beforeSubmit,
afterSubmit: afterSubmit
}
Why do you need to script this? I believe the due date is calculated based on the terms out of the box, no need for scripting
The following code should work. Depending on your needs I recommend adding some limitations to when this logic is executed. For example you can only execute based on if the transaction/record mode is create/copy (decide if you want to include edit or not). You can also check the status of the transaction, and only execute if the status is not partially paid/paid in full...
function afterSubmit(context) {
//load record
var curRec = context.newRecord; //can substitute "context.oldRecord", or "currentRecord.get();"
//get current due date
var transDueDate = curRec.getValue({fieldId: 'duedate'});
//get the terms, this will likely come as an internal id. use getText if you want the text.
var transTerms = curRec.getValue({fieldId: 'terms'});
//empty string to hold terms as a number of days
var addtlDays;
//transform the internal id to terms as a number of days
switch (transTerms){
case 1: // Ex: 1 = internal id for term "Net 15"
addtlDays = 15;
break;
case 2: // Ex: 2 = internal id for term "Net 30"
addtlDays = 30;
break;
//add additional case statements as needed
default:
addtlDays = 0;
}
//calculuate the new due date
var d = new Date(transDueDate);
var newDueDate = d.setDate(d.getDate() + addtlDays);
//set the new due date
curRec.setValue({
fieldId: 'duedate',
value: newDueDate,
ignoreFieldChange: true //optional, default is false
});
}

Finding all properties for a schema-less vertex class

I have a class Node extends V. I add instances to Node with some set of document type information provided. I want to query the OrientDB database and return some information from Node; to display this in a formatted way I want a list of all possible field names (in my application, there are currently 115 field names, only one of which is a property used as an index)
To do this in pyorient, the only solution I found so far is (client is the name of the database handle):
count = client.query("SELECT COUNT(*) FROM Node")[0].COUNT
node_records = client.query("SELECT FROM Node LIMIT {0}".format(count))
node_key_list = set([])
for node in node_records:
node_key_list |= node.oRecordData.keys()
I figured that much out pretty much through trial and error. It isn't very efficient or elegant. Surely there must be a way to have the database return a list of all possible fields for a class or any other document-type object. Is there a simple way to do this through either pyorient or the SQL commands?
I tried your case with this dataset:
And this is the structure of my class TestClass:
As you can see from my structure only name, surname and timeStamp have been created in schema-full mode, instead nameSchemaLess1 and nameSchemaLess1 have been inserted into the DB in schema-less mode.
After having done that, you could create a Javascript function in OrientDB Studio or Console (as explained here) and subsequently you can recall it from pyOrient by using a SQL command.
The following posted function retrieves all the fields names of the class TestClass without duplicates:
Javascript function:
var g = orient.getGraph();
var fieldsList = [];
var query = g.command("sql", "SELECT FROM TestClass");
for (var x = 0; x < query.length; x++){
var fields = query[x].getRecord().fieldNames();
for (var y = 0; y < fields.length; y++) {
if (fieldsList == false){
fieldsList.push(fields[y]);
} else {
var fieldFound = false;
for (var z = 0; z < fieldsList.length; z++){
if (fields[y] == fieldsList[z]){
fieldFound = true;
break;
}
}
if (fieldFound != true){
fieldsList.push(fields[y]);
}
}
}
}
return fieldsList;
pyOrient code:
import pyorient
db_name = 'TestDatabaseName'
print("Connecting to the server...")
client = pyorient.OrientDB("localhost", 2424)
session_id = client.connect("root", "root")
print("OK - sessionID: ", session_id, "\n")
if client.db_exists(db_name, pyorient.STORAGE_TYPE_PLOCAL):
client.db_open(db_name, "root", "root")
functionCall = client.command("SELECT myFunction() UNWIND myFunction")
for idx, val in enumerate(functionCall):
print("Field name: " + val.myFunction)
client.db_close()
Output:
Connecting to the server...
OK - sessionID: 54
Field name: name
Field name: surname
Field name: timeStamp
Field name: out_testClassEdge
Field name: nameSchemaLess1
Field name: in_testClassEdge
Field name: nameSchemaLess2
As you can see all of the fields names, both schema-full and schema-less, have been retrieved.
Hope it helps
Luca's answer worked. I modified it to fit my tastes/needs. Posting here to increase the amount of OrientDB documentation on Stack Exchange. I took Luca's answer and translated it to groovy. I also added a parameter to select the class to get fields for and removed the UNWIND in the results. Thank you to Luca for helping me learn.
Groovy code for function getFieldList with 1 parameter (class_name):
g = orient.getGraph()
fieldList = [] as Set
ret = g.command("sql", "SELECT FROM " + class_name)
for (record in ret) {
fieldList.addAll(record.getRecord().fieldNames())
}
return fieldList
For the pyorient part, removing the database connection it looks like this:
node_keys = {}
ret = client.command("SELECT getFieldList({0})".format("'Node'"))
node_keys = ret[0].oRecordData['getFieldList']
Special notice to the class name; in the string passed to client.command(), the parameter must be encased in quotes.

moment.js reverse .fromNow()

So i'm working with moment.js.
I see you can translate a date into a human-friendly format using moment().fromNow();
Is there a way to do the opposite?
For example, I want to turn this --> "2 weeks ago" into a normal date format or UNIX timestamp.
I sifted through the documentation but couldnt find anything. Any direction would help, thanks.
Depending on how complicated/different the input strings can be, you could do this:
//parse out the number and the duration
var inputString = "2 weeks ago";
var myRegExp = /^(\d+)\s(\w+)\sago$/;
var results = myRegExp.exec(inputString);
var num = results[1];
var duration = results[2];
moment().subtract(duration,num).toString() //or whatever format you prefer
Note this will work for input strings of the format "number duration ago".
Hope that helps!
In some cases .fromNow() returns string like "30+ days ago". The regex provided in above solution doesn't handle to parse that properly.
Here's the updated regex to handle that case:
var myRegExp = /^(\d+)\+?\s(\w+)\sago$/;
Here is the method that I used to reverse it for the current moment.js locale. I tested it on a few locales and it should work for every locale but it might not.
Change the last two .toString() functions to .valueOf() to get numerical values.
Moment actually doesn't have the week name data for all languages right now, so the function will assume that the string is a week if it could not find the value.
Some languages use translation functions instead of having built in values so the script will not work on those either! If you manually specify your language data then it should work.
//test en locale
moment.locale("en");
console.log(reversefromNow("5 days ago"));
console.log(reversefromNow("in 5 days"));
//test ja locale
moment.locale("ja");
console.log(reversefromNow("5 日前"));
console.log(reversefromNow("5 日後"));
function reversefromNow(input) {
let relativeLocale = JSON.parse(JSON.stringify(moment.localeData()._relativeTime));
let pastfutureObject = {
future: relativeLocale.future,
past: relativeLocale.past
};
delete relativeLocale.future;
delete relativeLocale.past;
//detect if past or future
let pastfuture;
for (const [key, value] of Object.entries(pastfutureObject)) {
if (input.indexOf(value.replace("%s", "")) != -1) {
pastfuture = key;
}
}
//detect the time unit
let unitkey;
for (const [key, value] of Object.entries(relativeLocale)) {
if (input.indexOf(value.replace("%d", "")) != -1) {
unitkey = key.charAt(0);
}
}
//if its not in the data, then assume that it is a week
if (unitkey == null) {
unitkey = "w";
}
const units = {
M: "month",
d: "day",
h: "hour",
m: "minute",
s: "second",
w: "week",
y: "year"
};
//Detect number value
const regex = /(\d+)/g;
let numbervalue = input.match(regex) || [1];
//Add if future, subtract if past
if (pastfuture == "past") {
return moment().subtract(numbervalue, units[unitkey]).valueOf();
} else {
return moment().add(numbervalue, units[unitkey]).valueOf();
}
}

How to get the attribute value of xml using LINQ to XML?

I have the following xml schema.
<Rooms>
<Room RoomNumber="room1" EMAIL="ssds#dsfd.com" dsfdd=""/>
<Room RoomNumber="room2" EMAIL="ssds#sdd.com" dsfdd=""/>
</Rooms>
I have to return Email address based on the input(input to program is room number).
How i can achieve this using LINQ to XML?
Try this:
var xml = XElement.Parse("<Rooms>"+
"<Room RoomNumber=\"room1\" EMAIL=\"ssds#dsfd.com\" dsfdd=\"\"/>"+
"<Room RoomNumber=\"room2\" EMAIL=\"ssds#sdd.com\" dsfdd=\"\"/>"+
"</Rooms>");
string room = "room1"; //input
var email = xml.Elements("Room")
.Where(c => c.Attribute("RoomNumber").Value == room)
.Select(c => c.Attribute("EMAIL").Value).FirstOrDefault();
var doc = XDocument.Load(myXmlFilePath);
// or doc = XDocument.Parse(myXmlString);
string roomNumber = "room1";
var emailQuery = from room in doc.Root.Elements("Room")
where (string)room.Attribute("RoomNumber") == roomNumber
select (string)room.Attribute("EMAIL");
Then, with a query like that you can get results:
// if there is always only one <Room> with given roomNumber
var email = emailQuery.First();
// otherwise
var emails = emailQuery.ToList();

Resources