aarong
(Aaron Gulley)
November 5, 2021, 12:25pm
1
Hello everyone
Anyone able to write this code? I want to be able to use null-coalescing but I can’t seem to figure it out!
Here is the code
foreach(var r in ttResults.Where(r => r.Updated()))
{
//Variables
int defaultOpr = (r.JobOper_OprSeq); // Find Operation
string defaultEmp = "99999" ; //Find Employee Number (Epicor Super)
DateTime clockDate = (BpmFunc.Today()); //Today's Date
decimal clockHours = 7.5m; //Clock Hours e.g 7.5 hours.
bool shopFloor = false;
string msg = "";
string expCode = "EXP";
string defaultCompany = (callContextClient.CurrentCompany);
string cMessageText = "";
decimal overQty = (r.JobOper_OverrideQty_c);
decimal compQty = (r.JobOper_QtyCompleted);
decimal estQty = (r.Calculated_cEstimatedQty);
decimal laborQty = estQty ?? new compQty ?? new overQty;
decimal runQty = (r.JobOper_RunQty);
decimal cHours = (r.Calculated_cEstLabourHours);
string labourNote = "Auto Clearing Dirty Jobs";
try
{
using(var laborBO = Ice.Assemblies.ServiceRenderer.GetService<LaborSvcContract>(Db))
{
LaborTableset lds = new LaborTableset();
laborBO.GetNewLaborDtlNoHdr(ref lds, defaultEmp, shopFloor, clockDate, clockHours, clockDate, clockHours);
lds.LaborDtl[0].Company = defaultCompany;
lds.LaborDtl[0].LaborType = "P";
lds.LaborDtl[0].LaborTypePseudo = "P";
lds.LaborDtl[0].JobNum = r.JobOper_JobNum;
lds.LaborDtl[0].LaborNote = labourNote;
lds.LaborDtl[0].ExpenseCode = expCode;
lds.LaborDtl[0].LaborEntryMethod = "Q";
lds.LaborDtl[0].LaborQty = laborQty;
lds.LaborDtl[0].LaborHrs = cHours;
lds.LaborDtl[0].BurdenHrs = cHours;
lds.LaborDtl[0].ClockInDate = clockDate;
lds.LaborDtl[0].ExpenseCode = expCode;
lds.LaborDtl[0].DspClockInTime = "07:30";
lds.LaborDtl[0].DspClockOutTime = "16:00";
lds.LaborDtl[0].ClockinTime = 7.50M;
lds.LaborDtl[0].ClockOutTime = 16.00M;
lds.LaborDtl[0].ActiveTrans = false;
lds.LaborDtl[0].LaborCollection = false;
laborBO.LaborRateCalc(ref lds);
laborBO.DefaultOprSeq(ref lds,defaultOpr, out msg);
laborBO.LaborRateCalc(ref lds);
laborBO.CheckWarnings(ref lds,out msg);
//laborBO.SubmitForApproval(ref lds,false,out msg);
LaborDtlRow ld = lds.LaborDtl.Where(t => t.Added()).FirstOrDefault();
ld["Processed_c"] = r.Calculated_cProcess;
laborBO.Update(ref lds);
ld.RowMod = "U";
laborBO.ValidateChargeRateForTimeType(ref lds, out msg);
laborBO.SubmitForApproval(ref lds, false, out msg);
Db.Validate();
}
}
catch (Exception ex)
{
Ice.Diagnostics.Log.WriteEntry($"EmpID = {defaultEmp}, JobNum = {r.JobOper_JobNum}, Opr = {defaultOpr} Qty = {laborQty} Labour Hours = {cHours} --Error: {ex.Message}", "Dirty Jobs");
}
}
There is one section but I’m getting errors.
decimal laborQty = estQty ?? new compQty ?? new overQty;
The calculation I’m trying to achieve is
If estQty is null then use compQty and if overQty is not null use that over priority)
josecgomez
(Jose C Gomez)
November 5, 2021, 12:41pm
2
remove the word new
new is for instantiating a new object.
Also decimals are not nullable you’d need Decimal for that to work me thinks.
aarong
(Aaron Gulley)
November 5, 2021, 1:11pm
3
What do you mean you need Decimal? How would be written?
josecgomez
(Jose C Gomez)
November 5, 2021, 1:13pm
4
Decimal (capital D) is an object (nullable)
decimal (lower case) is a primitive and not nullable (by standard means)
1 Like
aarong
(Aaron Gulley)
November 5, 2021, 1:22pm
5
josecgomez:
Decimal
Decimal compQty = (r.JobOper_QtyCompleted); //BAQ Data
Decimal estQty = (r.Calculated_cEstimatedQty); //BAQ Data
Decimal estQty = (r.JobOper_OverrideQty_c); //BAQ Data
Decimal laborQty = estQty ?? compQty ?? overQty;
Still gives me
CS0019 Operator '??' cannot be applied to operands of type 'decimal' and 'decimal'
I didn’t realise there was two different.
josecgomez
(Jose C Gomez)
November 5, 2021, 1:25pm
6
Decimals are not likely to be null (ever) don’t use null coalesce for these. Just check if they are zero. The only way those would be null is if your BAQ has a left join from Oper and there is no operation.
1 Like
aarong
(Aaron Gulley)
November 5, 2021, 1:30pm
7
No problem makes a little sense now!
How would you create an over-ride field though? There will be always some sort of value in either one of the two other fields but if a value is added to overQty that would be used. I just don’t know how to write that
josecgomez
(Jose C Gomez)
November 5, 2021, 1:34pm
8
Decimal laborQty = overQty>0?overQty:compQty>0?compQty:estQty;
4 Likes
aarong
(Aaron Gulley)
November 5, 2021, 9:26pm
9
Hi Jose,
I have a question. We have a field OverrideQty_c
on JobOper but the uBAQ custom code is triggered by a boolean (process_c)
changing to true
but I need to recalculate a calculated field on the BAQ before creating the LaborDtl record.
How would you go about doing that? e.g If someone typed 4 in the updateable field in the uBAQ and ticked process the calculated field would remain 0 as it didn’t have the value of OverrideQty
from JobOper as the value was only stored in the ttResults of the uBAQ.
I thought about having a condition if OverrideQty
is greater than zero and process_c is true then update JobOper table with the value of OverrideQty from the BAQ and inform the user to refresh and rerun the uBAQ but there must be a better way than that.
gpayne
(Greg Payne)
November 5, 2021, 10:08pm
10
@aarong The r.JobOper_OverrideQty_c in the update would hold the value that was typed in the baq, not the original value from JobOper.
1 Like
aarong
(Aaron Gulley)
November 6, 2021, 2:43pm
11
Thank you
The calculated field will need to written in custom code to allow it to capture the value from the updated field
aarong
(Aaron Gulley)
November 8, 2021, 8:34am
12
Anyone able to help me write this calculated field in c# for a BPM
Field Name: cEstLabourHours
(CASE
WHEN JobOper.SetupOpr_c = 1 AND JobOper.QtyCompleted = 1 THEN 0
WHEN JobOper.SetupOpr_c = 1 AND JobOper.OverrideQty_c > 0 THEN JobOper.OverrideQty_c * JobOper.EstSetHours
WHEN JobOper.SetupOpr_c = 0 THEN JobOper.ProdStandard * (JobOper.RunQty - JobOper.QtyCompleted) / 60 ELSE 0.00
END)
foreach(var r in ttResults.Where(r => r.Updated()))
{
//Variables
int defaultOpr = (r.JobOper_OprSeq); // Set Operation from BAQ
string defaultEmp = "99999" ; //Hard Coded (Emp Name: Epicor Super)
DateTime clockDate = (BpmFunc.Today()); //Today's Date
decimal clockHours = 7.5m; //Clock Hours e.g 7.5 hours.
bool shopFloor = false;
string msg = "";
string expCode = "EXP"; //Hard Coded
string defaultCompany = (callContextClient.CurrentCompany);
string cMessageText = "";
decimal setHours = (r.JobOper_EstSetHours);
decimal prodHours = (r.JobOper_ProdStandard);
int runQty = (r.JobOper_RunQty);
Decimal compQty = (r.JobOper_QtyCompleted); //BAQ Data
Decimal estQty = (r.Calculated_cEstimatedQty); //BAQ Data
Decimal overQty = (r.JobOper_OverrideQty_c);
bool setupOpr = (r.JobOper_SetupOpr_c);
Decimal laborQty = overQty>0?overQty:compQty>0?compQty:estQty;
decimal runQty = (r.JobOper_RunQty); //BAQ Data
decimal cHours = (r.Calculated_cEstLabourHours); //BAQ Data
string labourNote = "Auto Clearing Dirty Jobs"; //Hard Coded
try
{
using(var laborBO = Ice.Assemblies.ServiceRenderer.GetService<LaborSvcContract>(Db))
{
LaborTableset lds = new LaborTableset();
laborBO.GetNewLaborDtlNoHdr(ref lds, defaultEmp, shopFloor, clockDate, clockHours, clockDate, clockHours);
lds.LaborDtl[0].Company = defaultCompany;
lds.LaborDtl[0].LaborType = "P";
lds.LaborDtl[0].LaborTypePseudo = "P";
lds.LaborDtl[0].JobNum = r.JobOper_JobNum;
lds.LaborDtl[0].LaborNote = labourNote;
lds.LaborDtl[0].ExpenseCode = expCode;
lds.LaborDtl[0].LaborEntryMethod = "Q";
lds.LaborDtl[0].LaborQty = laborQty;
lds.LaborDtl[0].LaborHrs = cHours;
lds.LaborDtl[0].BurdenHrs = cHours;
lds.LaborDtl[0].ClockInDate = clockDate;
lds.LaborDtl[0].ExpenseCode = expCode;
lds.LaborDtl[0].DspClockInTime = "07:30";
lds.LaborDtl[0].DspClockOutTime = "16:00";
lds.LaborDtl[0].ClockinTime = 7.50M;
lds.LaborDtl[0].ClockOutTime = 16.00M;
lds.LaborDtl[0].ActiveTrans = false;
lds.LaborDtl[0].LaborCollection = false;
laborBO.LaborRateCalc(ref lds);
laborBO.DefaultOprSeq(ref lds,defaultOpr, out msg);
laborBO.LaborRateCalc(ref lds);
laborBO.CheckWarnings(ref lds,out msg);
//laborBO.SubmitForApproval(ref lds,false,out msg);
LaborDtlRow ld = lds.LaborDtl.Where(t => t.Added()).FirstOrDefault();
ld["Processed_c"] = r.Calculated_cProcess;
laborBO.Update(ref lds);
ld.RowMod = "U";
laborBO.ValidateChargeRateForTimeType(ref lds, out msg);
laborBO.SubmitForApproval(ref lds, false, out msg);
Db.Validate();
}
}
catch (Exception ex)
{
Ice.Diagnostics.Log.WriteEntry($"EmpID = {defaultEmp}, JobNum = {r.JobOper_JobNum}, Opr = {defaultOpr} Qty = {laborQty} Labour Hours = {cHours} --Error: {ex.Message}", "Dirty Jobs"); //Write to server log file!
}
}
This is the BPM code. I don’t know where to put it and I’ve tried different ways just end up with errors that make no sense!
A.Baeisa
(Al)
November 8, 2021, 9:24am
13
if your second priority -when not null- is estQty over compQty then your line should be:
decimal laborQty = overQty>0?overQty:estQty>0?estQty:compQty;
aarong
(Aaron Gulley)
November 8, 2021, 9:32am
14
Thank you’ve updated it now Still trying to work out this case when now! I love learning C#
A.Baeisa
(Al)
November 8, 2021, 12:28pm
15
Hi @aarong ,
you mean using C# - Ternary Operator ?: short if then else condition, ok, try this :
Decimal cEstLabourHours_recalculated = r.JobOper.SetupOpr_c==1 && r.JobOper.QtyCompleted==1?0:r.JobOper.SetupOpr_c==1&&r.JobOper.OverrideQty_c>0?r.JobOper.OverrideQty_c*r.JobOper.EstSetHours:r.JobOper.SetupOpr_c==0?(r.JobOper.ProdStandard*(r.JobOper.RunQty-r.JobOper.QtyCompleted)/60):0;
1 Like