MySQL and LUA not triggering correctly or code incorrect - mysql

I am struggling to trigger a server event succesfully on my FiveM server. Or maybe it gets triggered but the server event is incorrect. However I do not get any errors and I don't know what to fix...
Server-side
RegisterServerEvent('carwash:pay')
AddEventHandler('carwash:pay', function()
local _source = source
local price = 20
local identifier = GetPlayerIdentifier(_source)
MySQL.Async.fetchAll("SELECT * FROM economy WHERE identifier = #identifier", {
['#identifier'] = identifier
}, function(result)
if result >= 20 then
MySQL.Async.execute('UPDATE economy SET cash = cash - #price WHERE identifier = #identifier',
{ ['#identifier'] = identifier, ['#price'] = price }
)
end
end)
end)
Client-Side
TriggerServerEvent('carwash:pay')

I don't know if you're still working on it or figured it out but for those who have the same problem, I'm gonna answer this.
The problem here is that you are comparing a whole table (SELECT * FROM economy...) to the number 20.
Besides, a "fetchAll" will allways output an array, so, in order to acces the column cash from the table economy, you need to use "result[1].cash".
Then, sometimes the "error" is not a syntaxe one, you need to put some "print()" here and there to understand where it stops, changes or just check if it works.
e.g. :
RegisterServerEvent('carwash:pay')
AddEventHandler('carwash:pay', function()
local _source = source
local price = 20
local identifier = GetPlayerIdentifier(_source)
MySQL.Async.fetchAll("SELECT * FROM economy WHERE identifier = #identifier", {['#identifier'] = identifier},
function(result)
-- CHECK WHAT IT RESULT
print(result)
if result >= 20 then
MySQL.Async.execute('UPDATE economy SET cash = cash - #price WHERE identifier = #identifier', { ['#identifier'] = identifier, ['#price'] = price })
end
end)
end)

Related

Sending info to database and retrieving as well as using for k,v, in pairs() do

Issue i have come across is i have an item, if you use this item it writes to the database with your id and the item name. which is correct and this is what i want to happen, but i want it to first look at the database and see if the item is already there and if so stop the insert.
This is the item.
QBCore.Functions.CreateUseableItem("pumpshotgun_bp", function(source, item)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if Player.Functions.GetItemBySlot(item.slot) ~= nil then
QBCore.Functions.TriggerCallback('sin-crafting:server:getCrafts', src, function(result)
if result ~= nil then
TriggerClientEvent("sin-crafting:client:Update", source, "pumpshotgun_bp")
end
end)
end
end)
after that i query the info to the database
QBCore.Functions.CreateCallback('sin-crafting:server:getCrafts', function(source, cb)
local Player = QBCore.Functions.GetPlayer(source)
local cid = Player.PlayerData.citizenid
local printList = {}
MySQL.query('SELECT * FROM player_crafts WHERE cid = ?', { Player.PlayerData.citizenid }, function(crafts, item)
for k, v in pairs(crafts) do
if v == nil then
end
table.insert(printList,
{
citizenid = v.citizenid,
blueprint = v.blueprint,
}
)
end
cb(json.encode(printList))
end)
end)
and then
the item then triggers this when used and changed info from the item_bp to the actual name for the database
RegisterNetEvent('sin-crafting:client:Update', function(data)
if data == "pumpshotgun_bp" then
TriggerServerEvent('sin-crafting:server:newBlueprint', 'pumpshotgun')
end
end)
Problem now is when i use that item again it will write it again to the database and i dont want that i want instead to set up a notify script that will tell them they have already learned that.
This is the first half of my issue, the second half is pulling the list from the database and and checking it in the script. I really need help as I have been trying to do this for over a week now and cant find a way to do it
This is the config to use for the for k,v in pairs() do, <---which I cant figure out how to do right....
Config.Weapons = {
"pumpshotgun",
"dbshotgun",
"assaultrifle",
"smg",
"combatpistol",
"gusenberg",
"microsmg",
"carbinerifle",
"compactrifle",
"heavypistol",
"machinepistol",
"revolver",
"rifle_silencer",
"pistol_silencer",
"smg_silencer",
"shotgun_silencer",
"weapon_optics",
}

lvl system not working with mysql - Discord Bot

So Im trying to make leveling system in my bot but the problem is that when it reaches enough xp to lvl up it will remove the xp but wont add level. I dont know what is wrong with my code but its not working Im using the same technique for editing xp so it adds them but its not working for lvl so Imagine it like this. User message ---> generates enough xp for lvl up ---> lvls up. But instead of that it remains on level 1 I think I was searching everywhere for answer but found none. My code is here:
let prf = ".";
let messageArray = message.content.split(" ");
if(message.author.bot) return;
con.query(`SELECT * FROM xplvl WHERE id = '${message.author.id}'`, (err, rows) => {
if (err) throw err;
let sql;
if (rows.length < 1){
sql = `INSERT INTO xplvl (id, xp, lvl) VALUES ('${message.author.id}', ${Generatexp()}, ${lvlup()})`
}else{
let xp = rows[0].xp;
let lvl = rows[0].lvl;
let tnlx = 100 * lvl;
let l = 1;
sql = `UPDATE xplvl SET xp = ${xp + Generatexp()} WHERE id = '${message.author.id}'`;
if(xp >= tnlx) {
sql = `UPDATE xplvl SET lvl = ${lvl + l} WHERE id = '${message.author.id}'`;
sql = `UPDATE xplvl SET xp = 0`;
message.channel.send("You leveled up!")
con.query(sql);
return;
}
}
con.query(sql)
})
It's not working because every time you go in to update the level, you are explicitly resetting the experience points back to zero which brings back to level 1 on any subsequent attempts. Then it updates ALL RECORDS back to an xp = 0.
REMOVE your update query resetting the XP = 0.
You are building the sql command to update the level, but never executing it. Then immediately change the sql command to just the xp = 0 (which will do for EVERY record) and thus the level never gets updated.
I also don't think you really mean to reset the xp level and here's why. Your level's appear to be multiple of 100... thus
Level Points
1 100
2 200
3 300
By resetting the xp, getting to level 1 is no problem. Person earned 100 points. Now they are forced back to 0. Now the person has to get 100 points again and it says... ok, you hit level 1 again, back to level 1 and reset to zero. It will never get to 200.

Update planned order - two committed modifications, only one saved

I need to update two information on one object: the quantity (PLAF-gsmng) and refresh the planned order via the module function 'MD_SET_ACTION_PLAF'.
I successfully find a way to update each data separately. But when I execute the both solutions the second modification is not saved on the database.
Do you know how I can change the quantity & set the action on PLAF (Planned order) table ?
Do you know other module function to update only the quantity ?
Maybe a parameter missing ?
It's like if the second object is locked (sm12 empty, no sy-subrc = locked) ... and the modification is not committed.
I tried to:
change the order of the algorithm (refresh and after, change PLAF)
add, remove, move the COMMIT WORK & COMMIT WORK AND WAIT
add DEQUEUE_ALL or DEQUEUE_EMPLAFE
This is the current code:
1) Read the data
lv_plannedorder = '00000000001'
"Read PLAF data
SELECT SINGLE * FROM PLAF INTO ls_plaf WHERE plnum = lv_plannedorder.
2) Update Quantity data
" Standard configuration for FM MD_PLANNED_ORDER_CHANGE
CLEAR ls_610.
ls_610-nodia = 'X'. " No dialog display
ls_610-bapco = space. " BAPI type. Do not use mode 2 -> Action PLAF-MDACC will be autmatically set up to APCH by the FM
ls_610-bapix = 'X'. " Run BAPI
ls_610-unlox = 'X'. " Update PLAF
" Customize values
MOVE p_gsmng TO ls_plaf-gsmng. " Change quantity value
MOVE sy-datlo TO ls_plaf-mdacd. " Change by/datetime, because ls_610-bapco <> 2.
MOVE sy-uzeit TO ls_plaf-mdact.
CALL FUNCTION 'MD_PLANNED_ORDER_CHANGE'
EXPORTING
ecm61o = ls_610
eplaf = ls_plaf
EXCEPTIONS
locked = 1
locking_error = 2
OTHERS = 3.
" Already committed on the module function
" sy-subrc = 0
If I go on the PLAF table, I can see that the quantity is edited. It's working :)
3) Refresh BOM & change Action (MDACC) and others fields
CLEAR ls_imdcd.
ls_imdcd-pafxl = 'X'.
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = lv_plannedorder
iaccto = 'BOME'
iaenkz = 'X'
imdcd = ls_imdcd
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3
OTHERS = 4.
IF sy-subrc = 0.
COMMIT WORK.
ENDIF.
If I go on the table, no modification (only the modif. of the part 2. can be found on it).
Any idea ?
Maybe because the ls_610-bapco = space ?
It should be possible to update planned order quantity with MD_SET_ACTION_PLAF too, at least SAP Help tells us so. Why don't you use it like that?
Its call for changing the quantity should possibly look like this:
DATA: lt_acct LIKE TABLE OF MDACCTO,
ls_acct LIKE LINE OF lt_acct.
ls_acct-accto = 'BOME'.
APPEND lt_acct.
ls_acct-accto = 'CPOD'.
APPEND lt_acct.
is_mdcd-GSMNG = 'value' "updated quantity value
CALL FUNCTION 'MD_SET_ACTION_PLAF'
EXPORTING
iplnum = iv_plnum
iaenkz = 'X'
IVBKZ = 'X'
imdcd = is_mdcd "filled with your BOME-related data + new quantity
TABLES
TMDACCTO = lt_accto
EXCEPTIONS
illegal_interface = 1
system_failure = 2
error_message = 3.
So there is no more need for separate call of MD_PLANNED_ORDER_CHANGE anymore and no more problems with update.
I used word possibly because I didn't find any example of this FM call in the Web (and SAP docu is quite ambiguous), so I propose this solution just as is, without verification.
P.S. Possible actions are listed in T46AS table, and possible impact of imdcd fields on order can be checked in MDAC transaction. It is somewhat GUI equivalent of this FM for single order.

Getting issues when SQL is trying to write to table. Value Larger than Specific Precision

So I work for a retail company and was involved in looking at an incident where I systemically had to 'load' some stock onto a trailer, to be dispatched to a store.
So I have an issue with some code which executed, the process is trying to do the following to a SQL table;
UPDATE RESV_LOCN_HDR SET RESV_LOCN_HDR.USER_ID = :1, RESV_LOCN_HDR.CURR_WT = :2, RESV_LOCN_HDR.CURR_VOL = :3, RESV_LOCN_HDR.CURR_UOM_QTY = :4, RESV_LOCN_HDR.MOD_DATE_TIME = :5 WHERE ( RESV_LOCN_HDR.LOCN_ID = :6 )
The input variables for reference are;
input variables
1: Address(309adbdc) Length(0) Type(8) "RFUSER" - Indicator # 309ad7d4 = 0
2: Address(309ae02c) Length(0) Type(4) "11047.4" - Indicator # 309ad9b8 = 0
3: Address(309ae1ac) Length(0) Type(4) "-1.01e+09" - Indicator # 309ada3c = 0
4: Address(309ae32c) Length(0) Type(4) "-57" - Indicator # 309adac0 = 0
5: Address(309ae55c) Length(0) Type(7) "10/27/2016 2:57:50 PM" - Indicator # 309adb70 = 0
6: Address(309ade0c) Length(0) Type(8) "600062508" - Indicator # 309ad8d0 = 0
The columns I am writing to (USER_ID, CURR_WT, CURR_VOL, CURR_UOM_QTY, MOD_DATE_TIME, LOCN_ID all have the following data types;
USER_ID = VARCHAR2(15 CHAR)
CURR_WT, CURR_VOL = NUMBER(13,4)
CURR_UOM_QTY = NUMBER(9,2)
MOD_DATE_TIME = DATE
LOCN_ID = VARCHAR2(10 CHAR)
From my understanding (and I'm sure you'll all see the above as well, all the column data types are met apart from 3: CURR_UOM_QTY is trying to write -1.01e+09, now is it just me or is this the reason why the error is being returned? Is it not that the above data is a macro? or something similar?
Just not seen SQL try to write 1.01e+09 before, as it should only be writing numerical data, not a mixture.
Using oracle 11g.
Yes, the value of -1.01e+09 is why you are getting an error since your decimal precision is 4 and that value has many more decimals. It does not automatically round to four decimal places.

Include nested entity details but don't group by then when grouping by other fields

I working with Database first C# MVC, EF6, LINQ and JSon to try and pass data to both Highcharts and Google Maps for some of my reporting.
If I could add an image I would show you the relevant portion of my model, but sadly I need more reputation to do that...
The portion of the Entity Model I'm concentrating on right now is based on a central Docket that contains a BuildingCode as part of a one-to-many relationship to a building with and address and further relationship to the buildings polygons (for mapping). Dockets are also classified by one or more DocketTypes and thus there is a many-to-many relationship between Dockets and DocketTypes, which is not directly exposed to through the EF.
As an example a Docket which represents an investigation, could be related to the theft of a mobile phone in building A located on Campus X, not only was the cellphone stolen but the assailant also assaulted the victim in order to steal the mobile phone. So there are 2 DocketTypes here 1. Theft of mobile phone and 2. assault. Note: this is fictitious and for illustration purposes only .
One of my fundamental reports requires that I count how many docketTypes affect each building and each campus in a given period. When I display this I also need to show what the DocketTypes are.
I have no end of nightmare trying to find a way to get this right, I keep running into circular reference errors and needing to use explicit conversions when trying to model the data with LINQ so that I can pass a single nested object through JSON to the client side where displaying will occur.
In the below code I am told I need an Explicit conversion:
Cannot implicitly convert type 'Campus_Investigator.ViewModels.DocketTypeViewModel' to 'System.Collections.Generic.IEnumerable<Campus_Investigator.ViewModels.DocketTypeViewModel>'. An explicit conversion exists (are you missing a cast?)
var currentDocketQuery = from d in db.Dockets
from dt in d.DocketTypes
from bp in d.BuildingDetail.BuildingPolygons
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
select new CampusBuildingDocketTypeViewModel()
{
BuildingCode = d.BuildingDetail.BuildingCode,
BuildingName = d.BuildingDetail.BuildingName,
//BuildingPolygons = d.BuildingDetail.BuildingPolygons,
DocketTypes = new DocketTypeViewModel()
{
Category = dt.Category,
SubCategory = dt.SubCategory,
ShortDescription = dt.ShortDescription
}
};
I appreciate any ideas on how I can explicitly convert this or is that a better method I can use and avoid the circular reference error?
You included some redundant part in your query (which performs some inner join). The from bp in d.BuildingDetail.BuildingPolygons is joined in but then is not shown in the result. So it totally does not make sense. There may be duplicated elements in the result due to that. The from dt in d.DocketTypes is wrong joined in, although you need it in the result but because the DocketTypes is output per d in db.Dockets, so it's just simply queried like this:
var currentDocketQuery = from d in db.Dockets
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
select new CampusBuildingDocketTypeViewModel()
{
BuildingCode = d.BuildingDetail.BuildingCode,
BuildingName = d.BuildingDetail.BuildingName,
//BuildingPolygons = d.BuildingDetail.BuildingPolygons,
DocketTypes = d.DocketTypes
};
In fact I can see the commented line //BuildingPolygons = d.BuildingDetail.BuildingPolygons, so if you want to include that, it should also work.
If the DocketTypes has different type of d.DocketTypes, then you need a simple projection like this:
var currentDocketQuery = from d in db.Dockets
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
select new CampusBuildingDocketTypeViewModel()
{
BuildingCode = d.BuildingDetail.BuildingCode,
BuildingName = d.BuildingDetail.BuildingName,
//BuildingPolygons = d.BuildingDetail.BuildingPolygons,
DocketTypes = d.DocketTypes.Select(e => new DocketTypeViewModel()
{
Category = e.Category,
SubCategory = e.SubCategory,
ShortDescription = e.ShortDescription
})
};
I managed to solve this one by using the below. The major hassle with this is the circular referencing that exists in the model. When JSON serializes these, everything falls apart so it takes a lot of transforming to make sure that I only extract what I need. In this case grouped campus and building data (below includes the polygons which where only half commented out in the above) and then the include the detail of the DocketTypes that occurred at each building.
var datetime = DateTime.Now.AddDays(-30);
var campusDocket = from d in db.Dockets
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
group d by new { d.BuildingDetail.CampusName, d.BuildingDetail.BuildingCode, d.BuildingDetail.BuildingName } into groupdata
select new CampusBuildingDocketTypeViewModel
{
BuildingCode = groupdata.Key.BuildingCode,
BuildingName = groupdata.Key.BuildingName,
CampusName = groupdata.Key.CampusName,
Count = groupdata.Count(),
BuildingPolygons = from bp in db.BuildingPolygons
where bp.BuildingCode == groupdata.Key.BuildingCode
select new BuildingPolygonViewModel
{
Accuracy = bp.Accuracy,
BuildingCode = bp.BuildingCode,
PolygonOrder = bp.PolygonOrder,
Latitude = bp.Latitude,
Longitude = bp.Longitude
},
DocketTypes = from doc in db.Dockets
from dt in doc.DocketTypes
where doc.OccurrenceStartDate >= datetime && doc.BuildingCode == groupdata.Key.BuildingCode
select new DocketTypeViewModel
{
Category = dt.Category,
SubCategory = dt.SubCategory,
ShortDescription = dt.ShortDescription
}
};
The Answer again is ViewModels. I'm finding ViewModels seem to solve a lot of problems...