Comments Todo And Hack In C#

 

Hello everybody,

today I want to leave one more note, which you can use for boosting your productivity.

Imagine following scenario. On the meeting with customer you've got some list of to do points. You have them on your email. You've made some research, and found that you need to make changes to 5 C# files. How not to forget about all of those files?

On rescue comes two comments in C#:

  1. TODO
  2. HACK

Leave those comments in your 5 files -> save all files -> Open Task List, and you'll see something like this:

As you can see from presented screenshot, after you leave TODO or HACK comments in 5 C# files, you'll be in perfect position of usage of code.

What is even more interesting, with help of double click you can navigate to exact comment location.

 

How To Imitate Click On Confirm Shipment In Acumatica

 

Hello everybody,

Today I want to describe how to imiate click on menu item "Confirm shipment" in Acumatica. 

Probably your first guess will be just call method ConfirmShiment of graph SOShipmentEntry. But for now Acumatica team has another advice in order to call this action. Instead of calling method ConfirmShipment you'll need to have a bit more steps.

Code sample below demonstrates those necessary steps:

SOShipmentEntry shipmentGraph = PXGraph.CreateInstance<SOShipmentEntry>(); //Create instance of Graph
PXAutomation.CompleteSimple(shipmentGraph.Document.View);
PXAdapter adapter2 = new PXAdapter(new DummyView(shipmentGraph, shipmentGraph.Document.View.BqlSelect,
						 new List<object> { shipmentGraph.Document.Current }));
adapter2.Menu = SOShipmentEntryActionsAttribute.Messages.ConfirmShipment;
adapter2.Arguments = new Dictionary<stringobject>
{
		{"actionID"SOShipmentEntryActionsAttribute.ConfirmShipment}
};
adapter2.Searches = new object[]{shipmentGraph.Document.Current.ShipmentNbr};
adapter2.SortColumns = new[] { "ShipmentNbr"};
soShipmentGraph.action.PressButton(adapter2);
TimeSpan timespan;
Exception ex;
while (PXLongOperation.GetStatus(shipmentGraph.UID, out timespanout ex) == PXLongRunStatus.InProcess)
{ }
//Here you'll have your shipment confirmed

And DummyView looks like this:

public class DummyView : PXView
    {
        List<object> _Records;
        internal DummyView(PXGraph graphBqlCommand commandList<objectrecords)  : base(graphtruecommand)
        {
            _Records = records;
        }
        public override List<objectSelect(object[] currentsobject[] parametersobject[] searchesstring[] sortcolumns
bool[] descendingsPXFilterRow[] filtersref int startRowint maximumRowsref int totalRows)         {             return _Records;         }     }

If you wonder, why calling ConfirmShipment is not enough, answer is this: ConfirmShipment cal will confirm shipment, but it will not execute Automation Steps. Thats why all of mentioned steps are needed. Otherwise, you'll make long research on question, why something doesn't work in the same way, as it works in UI, but doesn't work from my code.

 

Pagination In Custom Inquiry

 

Hello everybody,

today I want to share with everybody, and with myself code fragment, that allows to achieve pagination in custom inquiry pages. 

Take a look on the code below:

  public class YourGraphInquiry : PXGraph<YourGraphInquiry>
  {
    public PXCancel<YourDACFilter> Cancel;
        public PXFilter<YourDACFilter> Filter;
 
        [PXFilterable]
        public PXSelect<YourDACDetails,
            Where2<
                Where<YourDACDetails.SomeidEqual<Current<YourDACFilter.SomeID>>, 
                    Or<Current<YourDACFilter.SomeID>, IsNull>>,
                And<
                    Where<YourDACDetails.SomepartidEqual<Current<YourDACFilter.SomePartId>>, 
                        Or<Current<YourDACFilter.SomePartId>, IsNull>>>>> Details;
 
        public virtual IEnumerable details()
        {
            PXView cmd = new PXView(thistrue, Details.View.BqlSelect);
            var currentFilter = Filter.Current;
 
            var s = (currentFilter.PageNbr ?? 0) * (currentFilter.PageSize ?? 0);
            int startRow = s > 0 ? s : PXView.StartRow;
            int totalRows = 0;
            int maxRows = (currentFilter.PageSize ?? 0) == 0 ? PXView.MaximumRows : currentFilter.PageSize ?? 0;
            foreach (var result in cmd.Select(new[] { currentFilter }, nullPXView.Searches,
                PXView.SortColumns, PXView.Descendings, PXView.Filters, ref startRowmaxRowsref totalRows))
            {
                yield return result;
            }
            startRow = 0;
        }
        public YourGraphInquiry ()
        {
            Details.Cache.AllowInsert = false;
            Details.Cache.AllowDelete = false;
            Details.Cache.AllowUpdate = false;
        }
 
       
  }
    
    [System.SerializableAttribute()]
    public class YourDACFilter : PX.Data.IBqlTable
    {
 
        #region SomeID
        public abstract class SomeID : BqlInt.Field<SomeID>
        {
        }
 
        protected int? _SomeID;
 
        [PXDBInt()]
        [PXDefault()]
        [PXUIField(DisplayName = "Some", Visibility = PXUIVisibility.Visible)]
        [PXSelector(typeof(Search<CWSome.SomeID>),   new Type[]{ typeof(MVP.CWSome.SomeCD), typeof(MVP.CWSome.description), typeof(MVP.CWSome.SomeCD) }, SubstituteKey = typeof(MVP.CWSome.SomeCD))]
        public virtual int? SomeID
        {
            get { return this._SomeID; }
            set { this._SomeID = value; }
        }
 
        #endregion SomeID
 
        #region SomePartId
 
        public abstract class SomePartId : BqlInt.Field<SomePartId>
        {
        }
 
        protected int? _SomePartId;
 
        [PXDBInt()]
        [PXDefault()]
        [PXUIField(DisplayName = "Some Part", Visibility = PXUIVisibility.Visible)]
        [PXSelector(typeof(Search<CWSomePart.SomePartIdWhere<CWSomePart.SomeIDEqual<Current<YourDACFilter.SomeID>>>>), 
                    new Type[] { typeof(CWSomePart.SomePartCD), typeof(CWSomePart.SomePartFullCD) }, SubstituteKey = typeof(CWSomePart.SomePartCD))]
        public virtual int? SomePartId
        {
            get { return this._SomePartId; }
            set { this._SomePartId = value; }
        }
        #endregion SomePartId
 
        #region Page number
        public abstract class pageNbr : BqlInt.Field<pageNbr> { }
        [PXInt]
        [PXUIField(DisplayName = "Page Number")]
        [PXDefault(0)]
        public virtual int? PageNbr { getset; }
 
        #endregion Page number
 
        #region page size
 
        public abstract class pageSize : BqlInt.Field<pageSize> { }
        [PXInt]
        [PXUIField(DisplayName = "Page Size")]
        [PXDefault(3)]
        public virtual int? PageSize { getset; }
 
        #endregion page size
    }
}

 

Presented code has few important features:

  1. With this code you can achieve fragmentation of reading of your data. 
  2. In order to avoid returning everything, used structure of yield return. It's efficient because allows to return not all array, but elements of array one by one
  3. In the end of details method, you can see startRow = 0. If you wonder why, reason is simple, after all elements in db will be executed, that line of code will reset reading of pages to the begining. 
  4. cmd.Select allows you to read chunk of data from db, in a very similar manner to SelectWindowed. If you check generated sql, you'll see staff like this:

SELECT TOP (3) [YourDACDetails].[Column1], [YourDACDetails].[Column2], .....

5. But for second and other pages, generated sql will not be very efficient, but on UI Side you'll not notice it. For example, when I've set Page number = 3, and page size = 5, I've got following sql:

exec sp_executesql N'SELECT TOP (20) [YourDACDetails].[Column1], [YourDACDetails].[Column2], ..... which leads to a conclusion, that Acumatica framework on later stage just throws out redundant values.

Summary

After all of those details description you may wonder, what can be the case, when you may need pagination for custom inquiry. And the main scenario, where such pagination may be useful is web services synchronization. If you want to achieve pagination for some of your data, then simplest way would be usage of mentioned pattern.

 

Database Of Acumatica Is In Recovery Pending Condition

 

Hello everybody,

recently I've got interesting situation, when my database for Acumatica developed turned to be in Pending condtion. In order to deal with it, I've executed following SQL:

 

ALTER DATABASE YourDatabase SET EMERGENCY;
GO
ALTER DATABASE YourDatabase set single_user
GO
DBCC CHECKDB (YourDatabase, REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;
GO
ALTER DATABASE YourDatabase set multi_user
GO

 

and my database turned back to normal.

Update on 10/08/2019

declare @dbName nvarchar(50);
set @dbName = 'yourDatabase';
 
exec( 'ALTER DATABASE' +@dbName  + ' SET EMERGENCY;')
 
exec ('ALTER DATABASE ' + @dbName + '  set single_user')
 
exec ('DBCC CHECKDB (' + @dbName + ' , REPAIR_ALLOW_DATA_LOSS) WITH ALL_ERRORMSGS;')
 
exec ('ALTER DATABASE ' + @dbName +' set multi_user');

I've modified script to a bit another

 

Three States Of Fields In Acumatica

 

Hello everybody,

today I want to write a short note on three states of fields existing in Acumatica:

  1. Exists but is empty
  2. Exist and have value
  3. Has null

If to speak about string, it can exist like this:

  1.  
  2. Some value
  3.  

Do you see difference between 1 and 3? Not easy. As usually developers of C#, show this difference like this:

  1. ""
  2. "Some Value"
  3. null

And following screenshot with explanation shows how it works in case of SOAP contracts:

 so, while you make integration, keep that in mind

New Functions For Redirect In Acumatica

 

Hello everybody,

today I want to say few words about new functions for redirect in Acumatica, and particularly about class PXRedirectHelper. 

Classical approach from T200/T300 manual may look like this:

var currentCse = Cases.Current;
if(currentCse == null)
	return;
 
 
var graph = PXGraph.CreateInstance<CRCaseMaint>();
graph.Case.Current = graph.Case.Search<CRCase.caseCD>(currentCse.CaseCD);
if (graph.Case.Current != null)
{
	throw new PXRedirectRequiredException(graphtrue"Case details");
}

But with new function all of those lines can be simplified to this:

PXRedirectHelper.TryRedirect(Cases.Cache, Cases.Current, "Edit case"PXRedirectHelper.WindowMode.NewWindow);

With that approach you'll get the same result, but just in one line of code. 

Simplest Caching Explanation

Hello everybody,

today I want to give one more explanation of how to use caching and slots for caching purposes. Also there are plenty of articles on the subject,  I want to give one more with simplest recipe. So, if you need to cache something, you'll need to follow this procedure:

  1. declare you class as something that inherits IPrefetchable
  2. Create some placeholder in your class for storing items in the cache
  3. Implement Prefetch
  4. Implement GetSlot

 

Take a look on the code below, how it can be done:

public class ArTranFetcher : IPrefetchable
{
	private List<ARTran> _arTranList = new List<ARTran>();
 
	public void Prefetch()
	{
		_configurableList = new List<ARTran>();
 
		var dbRecords = PXDatabase.Select<ARTran>();
		foreach (var csAttributeDetailConfigurable in dbRecords)
		{
			_arTranList.Add(csAttributeDetailConfigurable);
		}
	}
 
	public static List<ARTran> GetARTrans()
	{
		var def = GetSlot();
		return def._arTranList;
	}
		
	private static ArTranFetcher GetSlot()
	{
		return PXDatabase.GetSlot<ArTranFetcher>("ARtranFetcherSlot"typeof(ARTran));
	}
 
}

 

few more explanations on presented code.

  1. Placeholder will be _arTranList 
  2. GetSlot will be monitoring database ARTran ( because of typeof(ARTran) statement ). So each time ARTRan will be updated, GetSlot will be executed automatically via framework.
  3. In your code you can get cached valus via following line of code: var arTrans = ArTranFetcher.GetARTrans();

 

with usage of such tricks, you can optimize plenty of staff. The only warning would be don't cache ARTran, as it will swallow up all memory of your server.

 

 

Four Types Of Programmers

Hi.

It is first time I write on topic of management and recruitment. Question is about one way of classifying your programmers, who work with you now or will come in a future. My main thesis is: all developers, roughly speaking, are divided into 4 large types and each of these types has its own application area.
Attempting to send the wrong type to solve inappropriate tasks leads to a failure ( inefficient work, or the employee leaves the team ). If you want to know why, you are welcome. Get ready, we have a lot of information. Basicallly what I say is my perception of world of programmers.

It is important to understand that there are no "bad" types. If any of the types you think is bad, then you just do not know how to use it. Remember: for each task should be a suitable tool. I will talk about all 4 types in the form of cards, giving a brief description, indicating the background, goals and motivations, as well as talking about strong qualities and weaknesses.
Especially it is necessary to pay attention to the background, as specific type of people grows out of their background. We begin with something what is easier.

Linear programmer

The main ingredient of IT industry. On such people, as it is said, the world holds. He's a ``hamster``. He is also a “rower on the gallery”, but I prefer to avoid such shortcuts, so simply “linear programmer”. He cannot do something outstanding, does not write his compilers and DBMS. Well, the maximum – he will make a couple of tools to make life easier for himself, otherwise - just solves working tasks. He rarely changes jobs, persistent. His attitude to his work is realistic and without much enthusiasm. He is moderately lazy, disciplined (but there are exceptions), however, without proper management quickly becoming "too relaxed" and loses focus. You can manage such people by standard methods - described for example in the book of J. Rainwater - ``How to graze cats``. Qualifications can vary and are determined solely by experience and the number of projects in which the linear programmer has participated. Sometimes qualified linear programmers take a low rank managerial position - they are named `` team lead`` and this is a situation, where the above mentioned book becomes for them useful. But the most important feature of a linear programmer is a very frequent lack of desire to develop and to experiment. He will perfectly solve even a very tedious task that you will offer him, if it is not too complicated. He will choose the quickest and most straightforward tool he knows. Personal development for these people is sporadic in nature and basically goes not forward but `` to the sides``: to explore a new framework or a new tool that will help to solve everyday work tasks better. Or "the customer came, who uses such a thing - well, never mind, we will sort it out." It is noteworthy, that the knowledge, obtained as a result of the sporadic development of individual linear programmers is precisely the experience of an outsourcing company. But, a linear programmer mostly often does not have an intention ``to move mountains`` and deeply explore the world. For example, he is simply not interested in learning a new, HYIP programming language. He will learn only if the new language helps in solving everyday tasks. If to take more serious step - to develop your own language – no way. And this is normal. The most bad thing is when linear programmers becoming ``frozen`` in their development when they stay in one place for a long period of time. For example, if you have a person who has been consistently engaged in conceptually the same projects for 3-5 years, then it is very unlikely that he will change the type and will develop professionally. But taking into consideration the background before this empirical term, everything is possible.
Background: different. People can become "linear programmers" when they have completed online courses, university graduates, some participants of competitions, former technical scientists, and even people from conceptually different professions ( there are cases when truck drivers became PHP developers ). It is important to understand that a linear programmer is a background by itself and step for a jump to another type. But! Whether a person jumps or not, depends primarily on his personal desires, and not on his skills. The presence of one or another background determines only the direction of a potential jump, but not its probability! But the probability of a jump over time decreases rapidly. However, if you need a faithful employee for a long-term contract - learn to identify those, who want to "jump" in advance. If he will run away from the project - it will be unpleasant.
Attitudes: stability, average but 2-times-a-month-stable wages, peace and personal relationships in a team, fixed normal working hours, office bonuses such as a billiard room, fruits on weekends, travel expenses or the gym, medical insurance and (perhaps tedious, but) not hard work.
Strong qualities: perseverance, responsibility, interpersonal skills (fifty-fifty), complete controllability, calm behavior in stressful for a project situations.
Weak qualities: complex and / or non-standard tasks, abstractions, behavior in stressful for the company situations, again- bad quality code.
Interview: important to pay attention to such qualities: perseverance, discipline, communication skills, aspirations, that's all. It also makes sense to talk about previous experience and to look at CV. Give him a standard test task such as: "write chat on web sockets" and look at the deadlines, accuracy of the task and the adequacy of selected tools. It is good to give technical questions on the knowledge of languages, protocols, patterns and standard libraries. If the applicant already has experience specifically with your set of frameworks, it’s a plus, but if not, it doesn't matter. If everything else is in order – he will manage. It’s his job.
What you shouldn’t ask: don’t ask why hatches are round (don’t ask it anybody at all), don’t ask him to slew round a red and black tree on a board, using a marker, estimate the complexity of the algorithm, perform topological sorting or design a high-load system. A linear programmer does not feel good with such things, rather wants to run away.

Rock star (Software Scientist)

They are concentrated researchers and look like classical scientists, but only from IT. They are interested in algorithms, theoretical studies, conceptually new directions in the industry, but above all - they are interested in experimenting. In fact, they are hired for the sake of these experiments. They are willing to spend hours, digging through complex things and solving problems that other people don’t even understand. They are experts in complex tasks. They know exactly when q-sort should be replaced with heap sort and how they differ, or maybe what clustering algorithms are suitable for analyzing the flow of stock quotes, and others, to know what optimizations are used inside g ++ and how they help to live. A team of such people, for example, is able to develop a new programming language and compiler for it, or significantly improve any existing system. They are also often predisposed to functional programming. I do not hint at anything - just a statistical regularity. By the way, rock stars can make a bad code (especially at the stage of prototyping ideas), but in general, they do not allow bad code in the final versions of the things they develop, they try to do everything nicely, with comments and convenient software interfaces. But. As always, there is a "but" which spoils everything. It is important to understand that these people will not solve your tasks, even under any circumstances. It means that rock stars will solve those problems which are interesting to them and if you pay money. ( Even more - big money). And there is no guarantee that you will have some kind of result. The fact that your tasks are interesting for rock star is a very big luck and a happy coincidence, no more. But if tomorrow a rock star will come up with an idea to improve GHC, instead of improving your build of MySQL, then you will have a limited amount of time to dismiss him quickly and decisively. When you will try to force him to return to his tasks, you will receive, depending on your emotions, behaviour and your soft skills, or conflicts or silent failure of keeping deadlines. But it happens rarely and situation develops gradually, when peoples become so disappointed. But there is a reverse situation what happens quite often. If you transfer a rock star from improving your build of MySQL to improving GHC, against his will, it leads to similar consequences. This situation leads to conclusion that a rock star totally unacceptable for an outsource.
That is why rock stars feel best in grocery companies ( for example, JetBrains ), where they are given complete freedom within a single product and stability without a sudden change of tasks ( except through dismissal ). In such conditions people get the opportunity to do the tasks that they are interested in and possibility for self-realization,when no one annoy them. If it is happened for them to make a good product - it goes to release. If not-nobody cares. In such conditions rock stars feel good, keep their work positions and stay a very long time (up to a dozen years). In this situation management should provide light and unobtrusive control in order that the rock stars do not move away and do not involved into unpromising experiments, and in a very polite manner to inform person that this or that interesting for him is not needed for company. There is another great example of working with rock star - this is Google, where the rock star has the opportunity to do what he wants. Google feeds them, waters them, dresses them and protects them from external threats. In return, everything that a rock star is inventing will be owned and promoted by Google, turning into its products. Fair enough. Such prospective investments in a certain company.
Background: college or another good school, higher education in a good university on IT-specialty or mathematics. He is an excellent or at least good student. Probably involved in serious research activities ( scientific publications as a plus ) and / or programming at competitions right from school.

Attitudes: appreciates peace ( while solving the problem ), free irregular schedule with the possibility of remote work, adequacy of management, the ability to work with other rock stars, complex, interesting and non-standard tasks, stable funding. Office bonuses he takes for granted or ignores completely.

Strong qualities: complicated tasks, research activities, often design.

Weak qualities: there are often problems in communication; there is no resistance to stress. Instability in a company or with a project makes a rock stars feel scared and rigidly set deadlines turn them into stress. They possess inability to switch attention from one subject to another when it’s needed, but only if they wish. Despite all their creativity, they are not independent outside their tasks.

Interview: algorithms and data structures, complexity assessment, tasks from competitions - all are your reliable friends. It is possible to slew round the tree on the board (but why?) - but it is much better to give a simple math task. The main thing is not to hurry him up: let the person think as much as he needs. Also very good are creative tasks, the tasks for understanding ( well, just not about the hatches! ) and the design problems in the format of "let's reason" and "propose a solution". Look at education and publications in a CV. Ask him about participation in competitions, scientific conferences or about the topic of his diploma.
If he explaining you all this with enthusiasm, - you have found what you need. It is also worth making sure that the applicant knows perfectly any programming language (any), otherwise it is not very clear how he will implement his experiments.

What you should not ask: do not ask stupid questions. Stupid questions include: details of the implementation of something like "what does the Content-Length HTTP header do?", Questions about communication skills and other person’s behaviour (yes, rock stars may have an absolutely ugly character - but what can you do, this is the price you pay for them).
And even more - do not mention and even think to check stress resistance. Punctuality check only at the level of "does not disappear for a week- that is fine."

Rustler (Software Engineer)

 

He is a rare personality. Rustler sometimes called "result oriented". His attitude is- "anything you want, but for your money." A kind of linear programmer who unexpectedly ( and in fact - predictably ) got autonomy, self-motivated, and began to grow in a direction, where he sees a benefit. This is not a rock star, because he is not interested in deep and abstract tasks. He is interested in working tools that bring real, tangible benefits that you can touch by hands right here and right now ( often - in the form of banknotes in a pocket, but more about that later). If there is no working tool, the rustler will make it for himself.
He is very fond of concreteness in setting tasks, in technologies and - most importantly - in communication. They are also said to be "strict but fair". Communication skills are good. Politicaly correct, friendly, not difficult character, although it can be rude and prone to boring formalities. He is a rustler not from a good life, therefore he quickly deals with rude and silent people. If you are rude - you will spoil your reputation, if silent - you will not receive orders. If you don’t avoid and resolve conflicts and look for troubles - you will stay without money. He is materialistic and works with the tasks that objective reality sets for him. If he does not understand something, he asks and seeks a concrete answer. His bread is a carefully selected or hand-developed toolkit, experience, ability to understand every nasty thing in an acceptable time frame and to work quickly and with a quality. He searches for the toolkit on his own or after consulting with other rustlers - and don’t even think to give him advice at this moment. He is responsible. A good rustler does not break deadlines and provides a working and supported product. He looks at the bed code as one of the tools. He may take a technical debt, if it is appropriate and useful in a particular situation, depends of the specifics of the project. He has knowledge about a management and often understands it more than his boss. As a result of this, he can recommend ad-hoc management solutions. His professional flaw is an inattention to trifles, but this is also possible to treat.
Cool description – isn’t it? But there are two tricks here also. The first is that the rustler does not tolerate any superiors, especially if he is less skilled than the rustler himself. This is largely due to the good awareness of management methods. And also by the fact that the rustler himself perfectly understands how to make money in IT-industry. As a result – he doesn’t obey orders. A Rustler collaborates under contracts. Any attempt to force him to do anything outside the contract ( if not formally signed - then at least verbally agreed ) - leads to a polite refusal (at least) or to the termination of the contract ( in a worst case ).
If the rustler did not promise to send you daily reports - he will not do this. If he didn’t agree to spend 8 hours a day for you ( if there are deadlines for the assignment ), then he will not do this. If he did not promise to make edits for the project - well, you understand. However, if you buy a certain amount of time from the rustler ( without specific deadlines and specific tasks ), he will be happy to listen to your moaning, vague requirements, to take part in any stupid corporate meeting – no problem! You already paid for it. Anything you want if you pay money.
The second trick relates to his attitude towards money. The businessman is not subject to intangible motivation. For your offers: "company will pay you a gym, lunches and cats on Fridays" he likely will answer: "please, give me money". And the rustler loves a lot of money. And not just a lot, but a great amount. Yes, he has no big concern to the instability of payments, for working overtime and for payment for the result, but this payment must be large.
Long-term contracts for small monthly salary are not interesting for him- only for big money. As a result, the rustler often changes his place of work (to the extent that this concept exists for him). If you staying for a long time at one place - you will become a linear programmer. As a result, he is qualified to solve a fairly wide range of tasks.
Remember - a good rustler is always worth his price. And if you don’t give him enough money, the rustler will try to take a control on situation by many ways - from taking away a customer and a team ( if he has such a power ) to an honest heart-to-heart talk. If this fails, he will leave you quickly and decisively, why not? Good rustlers end up opening their own companies, but, as mentioned above, ruslter is seldom kind of personality.
Background: often self-educated. He engaged in programming because it is interesting. Higher education is pesent, but it is worth looking at the reputation of the college. If even the college was good, usually he has average marks as he has been working part time somewhere from the beginning of course. And in general, he would prefer to get the real job as soon as possible rather to study any kind of scientific subject.
Very often he is a freelancer. Some rustlers have problems with fundamental knowledge. However, if this is definitely a rustlers , then these problems are easy to solve.
Attitudes: high salary for his services ( exactly this definition ), compliance with agreements, high-quality problems solutions. Schedules and bonuses - by agreement, but usually prefers a free schedule with fixed goals, not tied to a place of work. Concerning extra benefits –instead would be better to pay money.
Strong qualities: wide and moderately profound qualification, independence, responsibility, result orientation, tolerance for instability in a company (as long as his contracts are respected), tolerance for short-term contracts and their sudden termination ( I want to underline - not violations, but terminations! ), resistant to stress as an elephant.
Weak qualities: high cost (2 times higher than a linear programmers and this is just the beginning), can violate the obligations of the contract ( if the rustler is bad and good for nothing - or just a beginner), uncontrollability in a situation "I am your boss and it means that you are a fool "( if not paid for it ), short-term plans, non-punctuality unless it’s mentioned in the contract.
Interview: it is difficult to find a good rustler. His reputation is your friend. Look at CV, do not be lazy to contact the person who collaborated with the applicant earlier. If it is a question of remote work - look at his availability. How quickly he responds to mail and messages, phone calls. Look how punctual he is. Then ask about the knowledge of the required technology, but without fanaticism. Of course, it’s nice if the rustler knows exactly what address in the memory does function of closing of connection in the proprietary library have, but believe me, this is not something to ask.
It would be nice to ask for examples about a projects that he has already implemented on your stack, using your technology. A good rustler always has something to show and tell. Tasks on design and "how to solve this problem with a given technology" always excellent, especially if it is seasoned with project details ( for example, to solve a task when the customer requires a release every week, etc. ).
What you should not ask: algorithmic questions, mathematics, tasks for attention and other nonsense, which you can ask a rock stars. Ask those questions only at the level of concept. It means that a rustler can know in general what does it mean a bicubic interpolation, but do not insist him to show his knowledge on a paper or on a computer without the Internet - he will fairly ( but politely ) tell you off. The test task should be mention as a separate topic. Do not give the standard test tasks: a good rustler had done so many such tasks in his life, that you even never dreamed of, so, don’t give him one more - he doesn’t need it at all. Further. Get over the fact that the test task is a waste of business hours of a rustler. Be ready for the fact that it will be paid. Offer to sign an NDA, temporary contract and make, for example, a commit with a fixed bug for some of your product or any system with the condition of payment for implementation and specified quality requirements. This is the most effective method. Do not forget to tell how to configure the environment. It does not take much time for a good rustler, but incidents could happen.

Acumatica Page Missing Under Google Chrome Browser

 

Hello everybody,

This one is a hot topic, recently chrome team released some changes to the Chrome Browser, so that some PAGES could get missing.

You still see Menu, still see screen list but the page itself is gone, blank, empty.

How to fix?

Just change settings in the Chrome:

1. Type chrome://flags/ in the browser address bar and press Enter.

2. You should see the list of options:

3. In the search bar type Lazy Frame or just Lazy:

4. Under Enable lazy frame loading choose Disabled:

5. Press Relaunch Now at the right bottom corner:

 

 

How To Modify Activities Behavior On Business Accounts Page

Hello everybody,

today I want to write a few words on how to modify behavior of buttons Add task, Add event, Add email, Add activity, ..., Add work item of Business Accounts page.

The main issue of chaning it is in the fact, that it is not just ordinary buttons, but separate class, which has injection of logic. Part of it's declaration goes below:

public class CRActivityList<TPrimaryView> : CRActivityListBase<TPrimaryView, CRPMTimeActivity>
  where TPrimaryView : class, IBqlTable, new()
{
  public CRActivityList(PXGraph graph)
    : base(graph)
  {
  }
 
  public CRActivityList(PXGraph graphDelegate handler)
    : base(graphhandler)
  {
  }
}

To my surprise, in order to override it's behavior you'll need to inherit from CRActivityList, and add your logic, for example like this:

public class BusinessAccountMaintExt : PXGraphExtension<BusinessAccountMaint>
{
	[PXViewName(Messages.Activities)]
	[PXFilterable]
	[CRReference(typeof(BAccount.bAccountID), Persistent = true)]
	public CRActivityListModified<BAccount> Activities;
}
 
public class CRActivityListModified<TPrimaryView> : CRActivityList<TPrimaryView>
	where TPrimaryView : classIBqlTablenew()
{
	public CRActivityListModified(PXGraph graph)
		: base(graph)
	{
	}
 
	public CRActivityListModified(PXGraph graphDelegate handler)
		: base(graphhandler)
	{
	}
 
	public override IEnumerable NewTask(PXAdapter adapter)
	{
		try
		{
			base.NewTask(adapter);  // throws exception, catch it and add you needed logic
		}
		catch (PXRedirectRequiredException ex)
		{
			var g = (CRTaskMaint)ex.Graph;
			var a = g.Tasks.Current;
			a.Subject = "Test Subject";
			a = g.Tasks.Update(a);
 
			var timeactivity = g.TimeActivity.Current;
 
			throw;
		}
 
		return adapter.Get();
	}
 
	public override IEnumerable NewEvent(PXAdapter adapter)
	{
		try
		{
			base.NewEvent(adapter);
		}
		catch (PXRedirectRequiredException ex)
		{
			var g = (EPEventMaint)ex.Graph;
			var a = g.Events.Current;
			a.Subject = "Test Subject";
			a = g.Events.Update(a);
 
			var timeactivity = g.TimeActivity.Current;
 
			throw;
		}
 
		return adapter.Get();
	}
 
	public override IEnumerable NewMailActivity(PXAdapter adapter)
	{
		try
		{
			base.NewMailActivity(adapter);
		}
		catch (PXRedirectRequiredException ex)
		{
			var g = (CREmailActivityMaint)ex.Graph;
			var a = g.Message.Current;
			a.Subject = "Test Subject";
			a = g.Message.Update(a);
 
			var timeactivity = g.TimeActivity.Current;
 
			throw;
		}
 
		return adapter.Get();
	}
 
	public override IEnumerable NewActivity(PXAdapter adapter)
	{
		return base.NewActivity(adapter);
	}
 
	protected override IEnumerable NewActivityByType(PXAdapter adapterstring type)
	{
		try
		{
			base.NewActivityByType(adaptertype);
		}
		catch (PXRedirectRequiredException ex)
		{
			var g = (CRActivityMaint)ex.Graph;
			var a = g.Activities.Current;
			a.Subject = "Test Subject";
			a = g.Activities.Update(a);
 
			var timeactivity = g.TimeActivity.Current;
 
			throw;
		}
 
		return adapter.Get();
	}
}

Few comments to presented code.

  1. All pop ups appear after exception, so you'll not be able to avoid exceptions, no matter what
  2. Your addendums should be modified in catch
  3. throw; will re-throw exception one more time. This is particularly interesitng detail, which you can re-use in some other scenarios when you need to deal with pop ups

Summary

Acumatica is very flexible, and the base flexibility mechanism is inheritance and polymorphism, two pillars of OOP.  In case if you need to change behavior of Cases screen, you'll need to inherit-override CRPMTimeActivity class.