Override default DateTime 12:00 AM or 12:00PM to current Time? - customization

As in my picture I have DateTime of SLA and Finish Date, and Finish Date is the same value of SLA but it allows user to add or change the DateTime. When I change the DateTime on Finish Date, it got the default value of Time was 12:00 PM or 12:00 AM. Is there any way to change the default time to current time? and will there be any impact if user changes the user locale format?
This is my UsrFinishDate default value:
UsrFinishDate (New Field)
[PXDBDate(PreserveTime = true)]
[PXUIField(DisplayName="Finish Date")]
protected void CRCase_UsrFinishDate_FieldDefaulting(PXCache cache, PXFieldDefaultingEventArgs e)
{
CRCase row = e.Row as CRCase;
CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
if (row == null || row.AssignDate == null) return;
if (row.ClassID != null && row.Severity != null)
{
var severity = (CRClassSeverityTime)PXSelect<CRClassSeverityTime,
Where<CRClassSeverityTime.caseClassID, Equal<Required<CRClassSeverityTime.caseClassID>>,
And<CRClassSeverityTime.severity, Equal<Required<CRClassSeverityTime.severity>>>>>
.Select(Base, row.ClassID, row.Severity);
if (severity != null && severity.TimeReaction != null)
{
e.NewValue = row.SLAETA;
e.Cancel = true;
}
}
if (row.Severity != null && row.ContractID != null)
{
var template = (Contract)PXSelect<Contract, Where<Contract.contractID, Equal<Required<CRCase.contractID>>>>.Select(Base, row.ContractID);
if (template == null) return;
var sla = (ContractSLAMapping)PXSelect<ContractSLAMapping,
Where<ContractSLAMapping.severity, Equal<Required<CRCase.severity>>,
And<ContractSLAMapping.contractID, Equal<Required<CRCase.contractID>>>>>
.Select(Base, row.Severity, template.TemplateID);
if (sla != null && sla.Period != null)
{
e.NewValue = row.SLAETA;
e.Cancel = true;
}
}
}
and this is my other event rowSelected:
protected void CRCase_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
{
var row = e.Row as CRCase;
var oldRow = e.OldRow as CRCase;
CRCaseExt rowExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);
if (row == null || oldRow == null) return;
if (row.OwnerID == null)
{
row.AssignDate = null;
row.SLAETA = null;
rowExt.UsrFinishDate = null;
}
else if (oldRow.OwnerID == null)
{
row.AssignDate = PXTimeZoneInfo.Now;
if (row == null || row.AssignDate == null) return;
if (row.ClassID != null && row.Severity != null)
{
var severity = (CRClassSeverityTime)PXSelect<CRClassSeverityTime,
Where<CRClassSeverityTime.caseClassID, Equal<Required<CRClassSeverityTime.caseClassID>>,
And<CRClassSeverityTime.severity, Equal<Required<CRClassSeverityTime.severity>>>>>.
Select(Base, row.ClassID, row.Severity);
if (severity != null && severity.TimeReaction != null)
{
row.SLAETA = ((DateTime)row.AssignDate).AddMinutes((int)severity.TimeReaction);
rowExt.UsrFinishDate = ((DateTime)row.AssignDate).AddMinutes((int)severity.TimeReaction);
}
}
if (row.Severity != null && row.ContractID != null)
{
var template = (Contract)PXSelect<Contract, Where<Contract.contractID, Equal<Required<CRCase.contractID>>>>.Select(Base, row.ContractID);
if (template == null) return;
var sla = (ContractSLAMapping)PXSelect<ContractSLAMapping,
Where<ContractSLAMapping.severity, Equal<Required<CRCase.severity>>,
And<ContractSLAMapping.contractID, Equal<Required<CRCase.contractID>>>>>.
Select(Base, row.Severity, template.TemplateID);
if (sla != null && sla.Period != null)
{
row.SLAETA = ((DateTime)row.AssignDate).AddMinutes((int)sla.Period);
rowExt.UsrFinishDate = ((DateTime)row.AssignDate).AddMinutes((int)sla.Period);
}
}
}
}

Here is the definition of the field I added to the Case screen, note the PreserveTime = true which I think might be what you are missing.
public class CRCaseExt : PXCacheExtension<PX.Objects.CR.CRCase>
{
#region UsrFinishDate
[PXDBDate(PreserveTime = true)]
[PXUIField(DisplayName = "Finish Date")]
public virtual DateTime? UsrFinishDate { get; set; }
public abstract class usrFinishDate : IBqlField { }
#endregion
}
And here is an easy way to set the current time when the UsrFinishDate value is changed. Don't forget to set the CommitChanges for that field.
protected virtual void CRCase_UsrFinishDate_FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
{
CRCase currentCase = (CRCase)e.Row;
var caseExt = PXCache<CRCase>.GetExtension<CRCaseExt>(currentCase);
if (caseExt == null)
{
return;
}
e.NewValue = new DateTime(caseExt.UsrFinishDate.Value.Year,
caseExt.UsrFinishDate.Value.Month,
caseExt.UsrFinishDate.Value.Day,
DateTime.Now.Hour,
DateTime.Now.Minute,
DateTime.Now.Second);
}

Related

Rapidxml next_sibling not return the next sibling

I want to select the "actual" xml node by attribute.
When I try to iterate trough the nodes, it only return the first one,
but strangely, when I ask the last node, it will return it without any problem. Also, if I search it with name like "actualroot->first_node("roodnode1")" it will found it.
edit:
I checked it just in case and the "actualroot" have parent
Rapidxml version: 1.13
(I tried different version too(1.1), and it had the same result)
The saved xml:
<rootnode Game="gamename">
<rootnode0 table="a" cluster="b" item="c"/>
<rootnode1 table="atest" cluster="btest" item="ctest"/>
<rootnode2 table="1" cluster="2" item="3"/>
</rootnode>
The simplified verion of the code I use:
#include "rapidxml.hpp"
#include "rapidxml_print.hpp"
using namespace std;
using namespace rapidxml;
bool listloaded;
bool actualcontainerloaded;
int rootcounter;
xml_document<> *actuallist;
xml_node<>* actualroot;
xml_node<>* actualcontainer;
std::unordered_map<std::string, xml_document<>*> xmllistmap;
main()
{
listloaded = false;
actualcontainerloaded = false;
rootcounter = 0;
create("tastx")
addcontainer("a","b","c")
addcontainer("atest","btest","ctest")
addcontainer("1","2","3")
setactualcontainer("atest","btest","ctest")
}
bool create(string name)
{
if (isalreadyexist(name)) return false;
//RPXdata oneRPX;
xml_document<> *newlist = new xml_document<>();
xml_node<>* root = newlist->allocate_node(node_element, newlist->allocate_string("rootnode"));
root->append_attribute(newlist->allocate_attribute("Game", newlist->allocate_string("gamename")));
newlist->append_node(root);
newlist->name(name.c_str());
xmllistmap[name] = newlist;
actuallist = newlist;
actualroot = newlist->first_node();
listloaded = true;
return true;
}
bool addcontainer(string table, string cluster, string item)
{
if (listloaded)
{
for (xml_node<> *child = actualroot->first_node(); child; child = actualroot->next_sibling())
{
if (child->first_attribute("table") == NULL) continue;
string tableattr = child->first_attribute("table")->value();
if (tableattr != table) continue;
if (child->first_attribute("cluster") == NULL) continue;
string clusterattr = child->first_attribute("cluster")->value();
if (clusterattr != cluster) continue;
if (child->first_attribute("item") == NULL) continue;
string itemattr = child->first_attribute("item")->value();
if (itemattr == item) continue;
return false;
}
string rootname = "rootnode"+functions.converttostring(rootcounter);
xml_node<>* root = actuallist->allocate_node(node_element, actuallist->allocate_string(rootname.c_str()));
root->append_attribute(actuallist->allocate_attribute("table", actuallist->allocate_string(table.c_str())));
root->append_attribute(actuallist->allocate_attribute("cluster", actuallist->allocate_string(cluster.c_str())));
root->append_attribute(actuallist->allocate_attribute("item", actuallist->allocate_string(item.c_str())));
actualroot->append_node(root);
functions.log("container added:" + table);
rootcounter++;
}
return false;
}
bool setactualcontainer(string table, string cluster, string item)
{
if (listloaded)
{
for (xml_node<> *child = actualroot->first_node(); child; child = actualroot->next_sibling())
{
xml_node<> *lastchild = actualroot->last_node();
string lcname = lastchild->name();
functions.log("last name: " + lcname);
string cname = child->name();
functions.log("cname: " + cname);
functions.log("for step called");
if (child->first_attribute("table") == NULL) continue;
string tableattr = child->first_attribute("table")->value();
string clusterattr = child->first_attribute("cluster")->value();
string itemattr = child->first_attribute("item")->value();
functions.log("actual tableattr:" + tableattr);
if (tableattr == table && clusterattr == cluster && itemattr == item)
{
functions.log("actual continer settd:"+ table);
actualcontainer = child;
actualcontainerloaded = true;
return true;
}
}
}
return false;
}
The result:
23:11:17: container added:a
23:11:17: container added:atest
23:11:17: container added:1
23:11:17: last name: rootnode2
23:11:17: cname: rootnode0
23:11:17: for step called
23:11:17: actual tableattr:a
Just a simple inattention:
The for loop
for (xml_node<> *child = actualroot->first_node(); child; child = actualroot->next_sibling())
actually should looks like this:
for (xml_node<> *child = actualroot->first_node(); child; child = child->next_sibling())

mesh.delete_face() caused abort()

I have tried to run the code below but got a error when using mesh.delete_face(*it, false);
vector<TriMesh::FaceHandle> terminalFaces;
OpenMesh::FPropHandleT<int> faceType;
OpenMesh::FPropHandleT<bool> faceChecked;
mesh.add_property(faceType, "face-type");
mesh.add_property(faceChecked, "face-checked");
tFillFacesProperty(mesh, faceChecked, false);
tClassifyFaces(mesh, faceType);
terminalFaces = tSplitJointFaces(mesh, faceType);
tClassifyFaces(mesh, faceType);
tAdjustAllVertices(mesh);
for (int i = 0; i < terminalFaces.size(); i++)
{
if (mesh.property(faceType, terminalFaces[i]) != FT_TERMINAL)
continue;
if (mesh.property(faceChecked, terminalFaces[i]))
continue;
vector<TriMesh::VertexHandle> collectedVs;
vector<TriMesh::FaceHandle> collectedFs;
for (TriMesh::FaceVertexIter fvi = mesh.fv_begin(terminalFaces[i]);
fvi != mesh.fv_end(terminalFaces[i]);
++fvi)
{
if (mesh.valence(*fvi) == 2) {
collectedVs.push_back(*fvi);
break;
}
}
assert(collectedVs.size() == 1);
while(1){
bool mustStop = false;
if (collectedFs.empty())
collectedFs.push_back(terminalFaces[i]);
else {
TriMesh::FaceHandle nextFh;
for (TriMesh::FaceFaceIter ffi = mesh.ff_begin(collectedFs.back());
ffi != mesh.ff_end(collectedFs.back());
++ffi)
{
if ((find(collectedFs.begin(), collectedFs.end(), *ffi) == collectedFs.end())
&& mesh.is_valid_handle(*ffi)
&& mesh.property(faceType, *ffi) != FT_NEW)
{
nextFh = *ffi;
break;
}
}
if (mesh.is_valid_handle(nextFh))
collectedFs.push_back(nextFh);
else
mustStop = true;
}
TriMesh::FaceHandle curfh = collectedFs.back();
mesh.property(faceChecked, curfh) = true;
int t = mesh.property(faceType, curfh);
if (t == FT_SLEEVE || t == FT_TERMINAL) {
TriMesh::HalfedgeHandle hh2check;
for (TriMesh::FaceHalfedgeIter fhi = mesh.fh_begin(curfh);
fhi != mesh.fh_end(curfh);
++fhi)
{
TriMesh::FaceHandle oppof = mesh.opposite_face_handle(*fhi);
if (mesh.is_valid_handle(oppof)
&& (find(collectedFs.begin(), collectedFs.end(),oppof) == collectedFs.end()))
{
hh2check = *fhi;
break;
}
}
assert(mesh.is_valid_handle(hh2check) && !mesh.is_boundary(hh2check));
// add new vertices
TriMesh::VertexHandle right, left;
right = mesh.from_vertex_handle(hh2check);
left = mesh.to_vertex_handle(hh2check);
assert(mesh.is_valid_handle(left) && mesh.is_valid_handle(right));
if ((find(collectedVs.begin(), collectedVs.end(), left) == collectedVs.end())
&& mesh.is_valid_handle(left))
collectedVs.insert(collectedVs.begin(), left);
if ((find(collectedVs.begin(), collectedVs.end(), right) == collectedVs.end())
&& mesh.is_valid_handle(right))
collectedVs.push_back(right);
bool inCircle = true;
TriMesh::Point center = (mesh.point(right) + mesh.point(left)) / 2.0;
double diamSq = tSqDist(mesh.point(right), mesh.point(left));
for (int i = 1; i < collectedVs.size() - 1; i++)
{
TriMesh::VertexHandle vh = collectedVs[i];
if (tSqDist(mesh.point(vh), center) * 4 > diamSq) {
inCircle = false;
break;
}
}
if (inCircle && !mustStop) {
continue;
}
else {
OpenMesh::IO::write_mesh(mesh, "outputtr.off");
for (vector<TriMesh::FaceHandle>::iterator it = collectedFs.begin(); it != collectedFs.end(); ++it){
mesh.delete_face(*it, false);
}
I used delete_face() in openmesh to remove one of the faces in mesh.
However, debugging always shows abort() and the error panel just like:
R6010 -abort() has been called
and the breakpoint was triggered by _CrtDbgBreak():
case 1: _CrtDbgBreak(); msgshown = 1;
Maybe the error is caused by a dangling reference/pointer, or an invalidated iterator. How could I fix it?
Just add "mesh.request_face_status();" and solved.

MP3 Tagging ID3v2_3 Id3v2_4

I use the JID3 library which works fine for IDv2_3 but when it is asked to update a tracks tags which are V2_4, it simply wipes the Id3v2_4 tags. How can I test which version of tagging a track has.
Example of setting the ratings and times played in the POPULARIMETER tag
public String setmp3RatingTag(Context context, File SourceFile, String email, int rating, int timesPlayed) throws Exception {
String error = null;
if (timesPlayed < 0) {
timesPlayed = 0;
}
try {
MediaFile MediaFile = new MP3File(SourceFile);
ID3V2_3_0Tag ID3V2_3_0Tag = (org.blinkenlights.jid3.v2.ID3V2_3_0Tag) MediaFile.getID3V2Tag();
POPMID3V2Frame popmid3V2Frame = new POPMID3V2Frame(email, rating, timesPlayed);
popmid3V2Frame.setPopularity(email, rating, timesPlayed);
if (ID3V2_3_0Tag != null) {
frames = ID3V2_3_0Tag.getPOPMFrames();
if (frames != null) {
if (frames.length > 0) {
String emailtouser[]=getmp3Email(SourceFile);
for (int i = 0; i < frames.length; i++) {
if (frames[i] != null) {
ID3V2_3_0Tag.removePOPMFrame(emailtouser[i]);
}
}
}
}
} else {
ID3V2_3_0Tag = new ID3V2_3_0Tag();
}
ID3V2_3_0Tag.addPOPMFrame(popmid3V2Frame);
MediaFile.setID3Tag(ID3V2_3_0Tag);
MediaFile.sync();
} catch (ID3Exception | OutOfMemoryError e) {
e.printStackTrace();
error = e.getMessage();
}
error = finish(context, SourceFile);
return error;
}
For anyone using the jid3 library, I added another method to the class MP3File.java
#Override
public int testforVerion() {
int iMinorVersion=0;
try {
InputStream oSourceIS = new BufferedInputStream(m_oFileSource.getInputStream());
ID3DataInputStream oID3DIS = new ID3DataInputStream(oSourceIS);
try
{
// check if v2 tag is present
byte[] abyCheckTag = new byte[3];
oID3DIS.readFully(abyCheckTag);
if ((abyCheckTag[0] == 'I') && (abyCheckTag[1] == 'D') && (abyCheckTag[2] == '3'))
{
// check which version of v2 tags we have
iMinorVersion = oID3DIS.readUnsignedByte();
}
else
{
return iMinorVersion;
}
}
finally
{
oID3DIS.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return iMinorVersion;
}
simply check for value 3 for ID3V2_3 and 4 for ID3V2_4

Best way to check if one of other objects is true or not

I am looking for best way to implement this scenario:
I have 4 objects that have Boolean member that in the flow of the app sometimes they are set to true and sometimes are set to false depending on conditions;
Then I have final function that gets 1 of this objects and needs to check if in the other 3 objects one of them has the member set to true .
The problem is I know how to do the dirty check , and I am searching for cleaner way here is my code for the final function:
class Obj
{
public :
Obj(int _id) : id(_id)
bool status;
int id // only 4 objects are created 0,1,2,3
}
m_obj0 = new Obj(0) ;
m_obj1 = new Obj(1) ;
m_obj2 = new Obj(2) ;
m_obj3 = new Obj(3) ;
bool check(Obj* obj)
{
if(obj->id == 0)
{
if(m_obj1->status || m_obj2->status || m_obj3->status)
{
return true;
}
return false;
}else if(obj->id == 1)(
if(m_obj0->status || m_obj2->status || m_obj3->status)
{
return true;
}
return false;
}else if(obj->id == 2)(
if(m_obj0->status || m_obj1->status || m_obj3->status)
{
return true;
}
return false;
}else if(obj->id == 3)(
if(m_obj0->status || m_obj1->status || m_obj2->status)
{
return true;
}
return false;
}
is there a shorter and cleaner way to accomplish this check function ?
You can set m_obj as an array. Then use a for loop to check
bool check(Obj* obj)
{
for (int i = 0; i < 4; i ++) {
if (obj->id == i) continue;
if (m_obj[i]->status == true)
return true;
}
return false;
}
Or add them together, then subtract m_obj[obj->id]->status。Check the result is zero or not
bool check(Obj* obj)
{
int result = m_obj[0]->status+m_obj[1]->statusm_obj[2]->status
+m_obj[3]->status-m_obj[obj->id]->status;
return (result!=0);
}

unable to remove range of items in a list

I am setting the items which i want to Remove from list as null and then sorting list through IComparable method CompareTo so that null items would be at the top ... then using RemoveRange function on list but unable to so so ... i see no problem in following code:
try
{
foreach (Invoice item in inv)
{
if (item.qty == 0)
{
item.CustomerName = null;
item.qty = 0;
i++;
}
}
inv.Sort();
inv.RemoveRange(0, i);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
#region IComparable<Invoice> Members
public int CompareTo(Invoice other)
{
return this.CustomerName.CompareTo(other.CustomerName);
}
#endregion
error occurs at inv.RemoveRange(0,i); saying that :Failed to compare two elemets in array
Why is it so??
public int CompareTo(Invoice other)
{
if (other == null || other.CustomerName == null) return 1;
if (this.CustomerName == null) return -1;
return this.CustomerName.CompareTo(other.CustomerName);
}
or
public int CompareTo(Invoice other)
{
//if other Invoide is null, instance is bigger.
if (other == null) return 1;
if (this.CustomerName == null) {
//if both CustomerName are null, instance equals other. Of only instance CustomerName is null, other is bigger.
return other.CustomerName == null ? 0 : -1;
}
//if other.CustomerName is null (and instance.CustomerName is not null), instance is bigger.
if (other.CustomerName == null) return 1;
//both CustomerName are not null, call basic string.CompareTo
return this.CustomerName.CompareTo(other.CustomerName);
}