Hello Everybody,

I want to share what I found here some ideas:

RULE 1: Life’s not fair. Get used to it

You could be the smartest, hardest working most noble person alive and still not get that A. Or promotion. Or the girl, whatever floats your boat. The sooner you stop expecting life to hand you the things you think you “deserve”, the easier it will be to bounce back in those times when life knocks you down and just keeps kicking. You could earn your way to that promotion and still have it snatched from under you – get over it. That doesn’t mean sit back and take it. It means that you need to learn from those ugly situations and better position yourself to reap the benefits of your diligence.

“The world expects you to accomplish something BEFORE you feel good about yourself” … so get on it. Start making something of yourself today. Right now. That idea you’ve been pushing to the back of your mind might be just the thing to propel you to the limelight, so get on it. You only truly fail if you never try.

RULE 3: You will not make six figure salary right after school

“You won’t be a vice president with a car phone until you earn both.” This addresses the entitled behavior that young people display on a daily basis. It’s not a good look for anyone to act like the world should unfurl a red carpet at their feet just because they showed up. You have to work hard for what you get – I’m talking sweat and blood here, and don’t expect anyone’s gratitude for it.

RULE 4: If you think your teacher is tough, wait till you meet your boss

All those deadlines you think are unreasonable at best, those times she locked you out of class because you showed up late? Ten times worse with a boss. Only, instead of chewing you out infront of a classroom, it’s a whole office. Teachers are legally mandated to show some restraint, bosses aren’t. He’ll call you all sorts of names your teacher only dreams of saying to your face, then show you the way to the unemployment line. This isn’t to scare you off of gainful employment, just to encourage you to practice dealing with difficult authority figures, to better prepare you for the future, so you can avoid an emotional outburst at the office.

RULE 5: Flipping buggers is not beneath your dignity

“Your grandparents had a different word for burger flipping – they called it OPPORTUNITY.” So get over yourself and take that job that you think is beneath you. A waiter/waitress position opens up at your favorite restaurant? Swallow your pride and take it. Use that as a stepping stone. The richest men in the world started off as paper boys – remember that.

RULE 6: If you mess up, it’s not your parents fault

“So don’t whine about your mistake – learn from them.” Too many people fall into the trap of claiming “mommy” and “daddy” issues when they mess up. According to Bill Gates, you need to stop spreading the blame around and take responsibility for your failures. Only then do you earn the right to own your successes as well.

RULE 7: Your folks know something you don’t know

“Before you were born, your parents weren’t as boring as they are now. They got that way from paying your bills, cleaning your clothes and listening to you talk about how cool you think you are. So before you save the rainforests from the parasites of your parents’ generation, try delousing the closet in your own room.” Self-explanatory.

RULE 8: Your school may have done away with winners and losers, but life has not

“In some schools, they have abolished failing grades and they’ll give you as many tries as you want to get the right answer. This doesn’t bear the slightest resemblance to ANYTHING in real life.” Only the strong survive. This doesn’t mean that it’s okay to do whatever it takes to come out ahead – the end does not justify the means. It just means that you need to keep the big picture in mind – to remember that while it’s okay to do your best, it’s better to always ensure that you go the extra mile to prove yourself.

RULE 9: Life is not divided into semesters

“You don’t get summer off and very few employers are interested in helping you “find yourself”. Do that on your own time.” This is one thing most students don’t realize. The real world won’t give you time off to recoup your strength. Once life starts it just goes on and on, and on. The sooner you shift your way of thinking from seeing your holiday as time off, but as time to be spent making something worthwhile of yourself, the easier the transition to real life will be.

RULE 10: Television is not real life

“In real life, people actually have to leave the coffee shop and go to jobs.” This applies to more than just an episode of friends. Life seems a lot easier on TV than it is in real life. Sounds like common sense, but you’d be surprised at how many people expect to sleep in every morning and still be able to afford that dream holiday.

RULE 11: Be Nice to Nerds

“Chances are you’ll end up working for one.” Laugh all you want, but he showed that this is a very real possibility. That book worm you keep picking on for choosing the library over a twerk session could end up being your boss in the future, so be nice.

I like those statements.

Hello everybody,

today I want to share trick about renaming item in grid. Suppose you want to use developed by Acumatica data access class of acumatica, which has name BAccount, and you have huge desire to rename it in column from "Account name" to "Employee Name".

You can use for such purpose CacheAttached event. In my case following code helped to achieve renaming:

        [PXDBString(60, IsUnicode = true)]
[PXDefault()]
[PXUIField(DisplayName = "Employee Name", Visibility = PXUIVisibility.SelectorVisible)]
[PXFieldDescription]
[PXMassMergableField]
protected virtual void BAccount_AcctName_CacheAttached(PXCache sender)
{
}

Hello everybody,

Today I want to share with you another area. I had small order for MQL4 indicator for round numbers for Metatrader4 or as it is named MT4. The task was to draw lines at screen with some step at any currency pair. In order to implement it I started first of all Googling. Then I found almost implemented indicator at forexfactory just without option for modification steps. After wondering about code purpose of variables I created the following code:

//**************************************************
//*                                                *
//*  Draws horizontal lines at round price levels  *
//*                                                *
//*  Written by: Totoro @ forexfactory.com         *
//*  Modified by Yuriy Zaletskyy                   *
//**************************************************
#property indicator_chart_window
extern double LineSpace     = 1; // 1 unit = 0.01 of basic value (e.g. 1 USD cent)
extern color  LineColor     = Turquoise;
extern int    LineStyle     = 2;
extern string LineStyleInfo = "0=Solid,1=Dash,2=Dot,3=DashDot,4=DashDotDot";
extern string LineText      = "RoundNr ";
extern double stepSize = 0.1;
extern string stepSizeComment = "step size for jpy = 0.1, for others 0.001";
extern int digitsAfterComma = 2;
extern string digitsAfterCommaComment = "2 for jpy and 3 for non jpy pair";

double LineSpaceOld;
double HighScreen;
double Tief;
bool   FirstRun = true;

int deinit()
{
double AbSpace = stepSize*LineSpace;
double HigherScreen    = MathRound(110*HighScreen)/100;
double LowerScreen   = MathRound(80*Tief)/100;
for(double i=0; i<=HigherScreen; i+=AbSpace)
{
if(i<LowerScreen) { continue; }
ObjectDelete(LineText+DoubleToStr(i,digitsAfterComma));
}
return(0);
}

int start()
{
if(FirstRun)
{
HighScreen = NormalizeDouble( High[iHighest(NULL,0,MODE_HIGH,Bars-1,0)], digitsAfterComma );
Tief = NormalizeDouble( Low[iLowest(NULL,0,MODE_LOW,Bars-1,0)], digitsAfterComma );
FirstRun = false;
}
else if(LineSpace != LineSpaceOld)
{
deinit();
HighScreen = NormalizeDouble( High[iHighest(NULL,0,MODE_HIGH,Bars-1,0)], digitsAfterComma );
Tief = NormalizeDouble( Low[iLowest(NULL,0,MODE_LOW,Bars-1,0)], digitsAfterComma );
}
DrawLines();
LineSpaceOld = LineSpace;
return(0);
}

void DrawLines()
{
double AbSpace = stepSize*LineSpace;
double HigherScreen    = MathRound(110*HighScreen)/100;
double LowerScreen   = MathRound(80*Tief)/100;

for(double i=0; i<=HigherScreen; i+=AbSpace)
{
if(i<LowerScreen) { continue; }
string StringNr = DoubleToStr(i,digitsAfterComma); // digits number in object name      if (ObjectFind(LineText+StringNr) != 0) // HLine not in main chartwindow
{
ObjectCreate(LineText+StringNr, OBJ_HLINE, 0, 0, i);
ObjectSet(LineText+StringNr, OBJPROP_STYLE, LineStyle);
ObjectSet(LineText+StringNr, OBJPROP_COLOR, LineColor);
}
{
ObjectSet(LineText+StringNr, OBJPROP_PRICE1, i);
ObjectSet(LineText+StringNr, OBJPROP_STYLE, LineStyle);
ObjectSet(LineText+StringNr, OBJPROP_COLOR, LineColor);
}
}
WindowRedraw();
}


Enjoy.

Few days ago I faced following challenge. SQL profiler gave me ugly SQL, which was unreadable for my eyes.

For example like this:

If you can read it, congratulations, you are genius and I'm envy of you so you can stop reading further. But if you are just programmer as me, then the next step is the following:

1. remove exec sp_executesql

2. In some editor find and replace @P0 with value -2147483647

3. remove tail /* admin@AP.30.40.00 */',N'@P0 int',@P0=-2147483647

4. Navigate in your browser to http://www.dpriver.com/pp/sqlformat.htm

5. Copy/Paste in window and choose format mssql

6. Press format SQL.

Compare previous sql with the following:

WHERE  ( apaddress.companyid = 2 )

IMHO the second option is easier to read.

Hello.

Today I want to share some information about Acumatica customization.

Suppose, you want to change your pages not via Acumatica UI, but via Visual Studio. Reasons why you can have such desire can be the following:

1. Visual Studio is faster then Acumatica UI

2. You can put your changes under source control

3. You can easily exchange changes with your co-workers

Let's say you have following situation.

1. You need to make changes to pages ar301000.aspx and  pm301000.aspx and pm304000.aspx.

2. You need to add new page AP508000.aspx.

3. You want to include dll, which is named DS.dll.

In order to do this you'll need the following.

1. Create in your Acumatica instance folder CstPublished

2. Inside created folder create folders pages_ar, pages_pm

3. Copy/Paste into folder pages_ar page ar301000.aspx and into pages_pm pages  pm301000.aspx and pm304000.aspx.

4. Create new page AP508000.aspx in folder AP

6. Create following file: project.xml, with the following records:

<Customization level="0" description="">
<File AppRelativePath="CstPublished\pages_ar\ar301000.aspx" FileID="0849bd3b-c4ce-473e-8c82-c567112aa96b" />
<File AppRelativePath="CstPublished\pages_ar\ar301000.aspx.cs" FileID="302c4089-6046-4a17-8411-1023315f5535" />
<File AppRelativePath="Pages\AP\AP508000.aspx" FileID="b9e88968-7f36-4cfc-9383-caed8363c269" />
<File AppRelativePath="Pages\AP\AP508000.aspx.cs" FileID="a1ce1918-f569-4ced-8a03-b5571dc26abb" />
<File AppRelativePath="CstPublished\pages_pm\pm301000.aspx" FileID="8c174bf0-3143-4a86-83e9-c82704c9297a" />
<File AppRelativePath="CstPublished\pages_pm\pm301000.aspx.cs" FileID="c435350a-89dc-455c-a9cb-6356987b2889" />
<File AppRelativePath="CstPublished\pages_pm\pm304000.aspx" FileID="65b4f056-859f-463c-99cc-32a9cde11c7d" />
<File AppRelativePath="CstPublished\pages_pm\pm304000.aspx.cs" FileID="46b0d39b-ba12-486a-be7f-6058a37cdca1" />
</Customization>

7. Create folder with the following structure:

7.1 Folder CstPublished which has inside of it folders pages_ar and pages_pm. And pages_ar has all ar files, and pages_pm has changes related to pm pages

7.2 Folder Pages, which has inside of it folder AP, and AP inside of it has AP508000.aspx and AP508000.aspx.cs files

7.3 Put into folder file project.xml

Some pitfalls which I faced.

1. xml file should be named project.xml

2. FileId is guid, and each FileID should be unique.

3. All file and folder names shouldn't be capital. Not Pages_pm but pages_pm. And not CstPublished\pages_pm\PM304000.aspx but CstPublished\pages_pm\pm304000.aspx

4. If you find other surprises with customization let me know.

Especially for Tony I made a screenshot of my customization folder.

Today I needed to get all columns of specifict table.

SQL which you can use for this purpose is the following:

SELECT COLUMN_NAME 'All_Columns' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='Specific table'

Hello everybody.

Today I want in short share screen numering in Acumatica.

Let's say we have screen number like this: xx.yy.zz.tt

in that case

yy is screen sequential number

zz is screen type: 10 - setup, 20 - Maintenance, 30 - data entry, 40 - inquiry, 50 - processing, 60 - reports.

tt is sub screen sequential number

Today I want to share with everybody who wants to make unit test of Acumatica how I achieved it.

For unit testing I use NUnit. In order to start my work with Acumatica Unit testing I wrote the following class:

    [TestFixture]
public class CATranEntryExtTest
{
[Test]
public void TestAutonumber()
{
var gr = PXGraph.CreateInstance<CATranEntry>();
}
}

Now with help of Resharper let's start debugging:

And here we go, the first error message:

PX.Data.PXProviderException : Provider cannot be instantiated.

at PX.Data.PXDatabase.get_Provider() in c:\Builders\4_10-2013_12_16-23_17_15-Full\Scripts\BuildTemp\NetTools\PX.Data\Database\Provider.cs: line 388

at PX.Data.PXDatabase.GetSlot(String key, Type[] tables) in c:\Builders\4_10-2013_12_16-23_17_15-Full\Scripts\BuildTemp\NetTools\PX.Data\Database\Provider.cs: line 802

at PX.Data.PXGraph.a(Type A_0) in c:\Builders\4_10-2013_12_16-23_17_15-Full\Scripts\BuildTemp\NetTools\PX.Data\Graph\Graph.cs: line 2684

at PX.Data.PXGraph.CreateInstance(Type graphType) in c:\Builders\4_10-2013_12_16-23_17_15-Full\Scripts\BuildTemp\NetTools\PX.Data\Graph\Graph.cs: line 112

at PX.Data.PXGraph.CreateInstance() in c:\Builders\4_10-2013_12_16-23_17_15-Full\Scripts\BuildTemp\NetTools\PX.Data\Graph\Graph.cs: line 57

So, it means we need to add some connection string to the site.  How to add it exactly? What proper way? I tried two next options:

1.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<remove name="ProjectX" />
</connectionStrings>
</configuration>

This way also:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionString value="Data Source=DIO222\DIO195;Initial Catalog=Ac20140117;Integrated Security=False;User ID=sa;Password=1234"></connectionString>
</configuration>

and if you suppose, that error message changed, you are wrong. It didn't go away.

you just need this config. That is not necessary to create and use real database. You just need connectionString specified.

In case if with answer you know how to add connectionString to app.config for unit test and it will work, let me congratulate you. For me you are genious. Sadly to admit, I'm not. After a while, I decided to do crazy idea - copy/paste web.config into App.config. Imagine scale of my surprise when I noticed, that error went away!!!!!!

Now I got the next error message:

PX.Data.PXNotLoggedInException : You are not currently logged in.

In order to understand this idea lets go to Login.aspx.cs, maybe we can locate there something. For example method NormalLogin:

    private void NormalLogin(string[] companies)
{
if (companies != null && companies.Length == 1)
{
cmbCompany.Items.Clear();
}

(cmbCompany.SelectedIndex != -1 ? cmbCompany.SelectedItem.Value : PXDatabase.Companies[0]) : loginText;

{
// we will change password during next round-trip

this.Master.Message = string.Empty;
}
else
{
}
}

using (PXLoginScope pxLoginScope = new PXLoginScope(userName, new string[0]))using (PXLoginScope pxLoginScope = new PXLoginScope(userName, new string[0]))

I just think what can mean PXLoginScope. But maybe name is self-explanatory. Some scope where some login considered as working?

Lets write code similar to what reflector showed:

[Test]
public void TestAutonumber()
{
{
var gr = PXGraph.CreateInstance<CATranEntry>();
}
}

and now error message is

PX.Data.PXUndefinedCompanyException : Unable determine proper company id for the request.

At least we can see, that error message changes during our thinking process :).

All other conclusions were built on this code:

        MembershipUser membershipUser = (MembershipUser) null;
try
{
{
if (membershipUser != null)
{
{
if (rolesForUser == null || rolesForUser.Length == 0)
throw new PXException("You are not allowed to login to the company {0}.", new object[1]
{
});
throw new PXException("You are not allowed to login to the company {0}.", new object[1]
{
});
}
return false;
PXSessionContextFactory.AuthenticateRequest();
return true;
}

The function which has name a if to trust to reflector just updates some info in audit journal, and updates some info in db, which IMHO is not usable for unit test.

So, code, which I use now for initiating Unit test now looks like this:

    [TestFixture]
public class CATranEntryExtTest
{
[Test]
public void TestAutonumber()
{
string userName = "some user name in db";
{
var membershipUser = (MembershipUser) null;

if (membershipUser != null)
{
{
if (rolesForUser == null || rolesForUser.Length == 0)
throw new PXException("You are not allowed to login to the company {0}.", new object[1]
{
});
else if (
!Enumerable.Contains<string>((IEnumerable<string>) PXDatabase.AvailableCompanies,
throw new PXException("You are not allowed to login to the company {0}.", new object[1]
{
});
}
var gr = PXGraph.CreateInstance<CATranEntry>();
}
}
}
}

At the end of execution gr looks like this:

Lets continue our way of unit testing for creating instance of our extension. This can be achieved via following way:

var accountsManager = gr.GetExtension<CATranEntryExt>();

Screenshot shows that we created instance of extension successfully:

Now I can test methods, which are inside of the extension CATranEntryExt.

I think it's enough for this article. If you have any comments, requests, wishes, critics, you are wormly welcome to express them.

Hello,

this post is dedicated to understanding how security in Acumatica works. If to be precisive security of accounts.

Let's say you need in some way filter accounts for some user according to configuration at row level security screen ( GL104000 ).

In my case I had following records in database which correspondent to the following numbers:

Relation group mask : 16; 0; 0; 0

User group mask: 159; 96; 0; 0

Account group mask: 16; 0; 0; 0

How to join them? They are joined not by separated table, which has relations between groups and accounts or groups and users, but with usage of bit mask. It's very effective way to join and is much faster then holding adta in db. But the most complicated from viewpoint of understanding. Lets convert already mentioned numbers into bit masks:

00010000; 00000000; 00000000; 00000000

10011111; 11000000; 00000000; 00000000

00010000; 00000000; 00000000; 00000000

From the bit mask you can notice that there is common bit between first byte in Account group mask and User group mask. Also there is common bit between "User group mask" and Relation group mask which means that user belongs to the group, and account belongs to the group. In order to work with them I wrote the following code:

 public List<Account> GetAvailableCashAccounts()
{
var result = new List<Account>();
var userID = PXAccess.GetUserID();
var user = GetUsers().First(u => u.PKID == userID);
var allAccounts = GetAccounts();
var groups = GetGroups();
foreach (var account in allAccounts)
{
foreach (var relationGroup in groups)
{
for (var i = 0; i < relationGroup.GroupMask.Length && i < account.GroupMask.Length; i++)
{
if ((account.GroupMask[i] & user.GroupMask[i]) == 0 || result.Find(a => a.AccountCD.Equals(account.AccountCD)) != null) continue;
}
}
}
return result;
}

In one of my previous posts I described how to add autonumbering to acumatica. Described method will work pretty well, if you don't have any pop-ups which also need to have autonumbering. In case if you have such pop-ups, then it is different story.

My next assignment on the job was to add autonumbering to the screen "Fund Transfers" which is marked as "CA301000" to the field Document ref at three places:

There is a saying, that one image is better then thousands of words :).

Here is example of my code for OutExtRefNbr:

        protected void CATransfer_OutExtRefNbr_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
var row = e.Row as CATransfer;
if (row == null)
return;
var refNbr = "001224";
e.NewValue = refNbr;
}

If you have a question why on earth code below needed:

var row = e.Row as "Class for which we will provide extension";

if( row == null )

return;

the answer is simple: because Acumatica for some unknown reason calls method FieldDefaulting and for mysterious reason passes into e.Row null. If you have any idea why, you are welcome to share them. I don't have and just used workaround ( don't say it to my boss ).

The second part of my task was to add some value to pop-up window. That can be done via the following template:

public class "Class Extention name" : PXGraphExtension<"Class for which we will provide extension">

{

protected void "Class for which we will provide extension"_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)

{

Base.AddFilter.Current."Field in pop-up" = "some default value";

}

"Field in pop-up" you can find also in Design mode of Acumatica forms.

Here is fragment of my source code for changes:

protected void CATransfer_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
}

In case if you have any comments, ideas don't hesitate to share them via comments line.

There is a saying, that one image is better then thousands of words :).

Here is example of my code for OutExtRefNbr:

        protected void CATransfer_OutExtRefNbr_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
var row = e.Row as CATransfer;
if (row == null)
return;
var refNbr = "001224";
e.NewValue = refNbr;
}

If you have a question why on earth code below needed:

var row = e.Row as "Class for which we will provide extension";

if( row == null )

return;

the answer is simple: because Acumatica for some unknown reason calls method FieldDefaulting and for mysterious reason passes into e.Row null. If you have any idea why, you are welcome to share them. I don't have and just used workaround ( don't say it to my boss ).

The second part of my task was to add some value to pop-up window. That can be done via the following template:

public class "Class Extention name" : PXGraphExtension<"Class for which we will provide extension">

{

protected void "Class for which we will provide extension"_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
{
Base.AddFilter.Current."Field in pop-up" = "some default value";
}
protected void CATransfer_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
}