I've added a new report design to the Sales Quotation report (AX2012).
The only way I could get the design to print out was to either amend the Standard Report Design or amend the Class SalesFormLetterReport_Quotation and change the Report Name in method getDefaultPrintJobSettings to my new report design. This is because the Quotation report uses Print Management settings and always uses the default report design.
My question is, if I want to print a different design based on some data criteria, i.e. a different customer type, how could I do this?
The only thing I can think of is to change the SalesFormLetterReport_Quotation class and override the method 'loadPrintSettings'.
I tried adding a new conditional setting in the Print Management setup but this still defaults to the default report design.
Take a look at:
\Classes\PrintMgmtDocType\getDefaultReportFormat
\Data Dictionary\Tables\PrintMgmtReportFormat\Methods\populate
\Data Dictionary\Tables\SRSReportDeploymentSettings\Methods\populateTableWithDefault
These methods has all sorts of report layouts hard coded. Really nasty shit!
To assign a different design based on customer, you can modify the Controller class which opens the SalesQuotation Report.
Edit the main method in SalesQuotationController class.
Write logic to assign the design based on your specific requirements.
You may edit the following lines on the SalesQuotationController\main method.
formLetterController.initArgs(_args, ssrsReportStr(SalesQuotation,Report));
Related
When I use a map constructor like:
Person p = new Person(name: "Bob")
through something that is called via a grails.gsp.PageRenderer, the field values are not populated. When I use an empty constructor and then set the fields individually like:
Person p = new Person()
p.name = "Bob"
it succeeds. When I use the map constructor via a render call, it also succeeds.
Any ideas as to why this is the case?
Sample project is here in case anyone wants to dig deeper: https://github.com/danduke/constructor-test/
Actual use case, as requested by Jeff below:
I have a computationally expensive view to render. Essentially it's a multi-thousand page (when PDF'd) view of some data.
This view can be broken into smaller pieces, and I can reliably determine when each has changed.
I render one piece at a time, submitting each piece to a fixed size thread pool to avoid overloading the system. I left this out of the example project, as it has no bearing on the results.
I cache the rendered results and evict them by key when data in that portion of the view has changed. This is why I am using a page renderer.
Each template used may make use of various tag libraries.
Some tag libraries need to load data from other applications in order to display things properly (actual use case: loading preferences from a shared repository for whether particular items are enabled in the view)
When loaded, these items need to be turned into an object. In my case, it's a GORM object. This is why I am creating a new object at all.
There are quite a few opportunities for improvement in my actual use case, and I'm open to suggestions on that. However, the simplest possible (for me) demonstration of the problem still does suggest that there's a problem. I'm curious whether it should be possible to use map constructors in something called from a PageRenderer at all. I'm surprised that it doesn't work, and it feels like a bug, but obviously a very precise and edge case one.
"Technically it is a bug" (which is the best kind of bug!), and has been reported here: https://github.com/grails/grails-core/issues/11870
I'll update this if/when additional information is available.
When using viewBinding with ConstraintLayout, maybe a lot of Ids will be create to help describe the view relationship, but will never used in Kotlin/Java.
I just found two useful tools attribute
tools:viewBindingIgnore="true" used to prevent whole layout generated in Binding, but not for single Id.
tools:viewBindingType="TextView" used for changing the Type generated in Binding.
So is there any way to ignore Id(s)? I don't want to expose them to pollute the Kotlin/Java.
Currently, there is no way to ignore view binding generation on view by view basis. If you use Proguard the unused ViewBinding IDs will be removed from the final APK.
I'm trying to implement a more customisable version of using ViewModel attributes and a Model Enricher to populate viewmodels lists like in this this question and associated blog post.
I would like to be able to specify the method on my select list interface from the Attribute.
Each Select List service I have returns an IEnumerable that I use to make a select list and presently exposes an All interface as the sample does. I can easily use the All method because all interfaces provide that. However I often wish to able to use other methods like the AllTradingCompanies() AllManafacturingCompanies() methods of my select list class to get filtered lists.
It is presently looking like I may have to implement a Custom attribute to map to specific e.g. [AllCompanyList] attributes but that moves me away from the nice generic method that the existing version gives me. I guess I could use it to complement it but then its starting to lose some of the charm. I also am implementing IModelEnrichers which can do custom per view model logic.
Any thoughts on a nice way to implement this?
I implemented the solution using pairs of Attributes to define a requirement for data on a ViewModel and a provider of data a repository or a service within my domain. See my follow up question asking whether this is a good idea.
Assuming you wanted to develop your Controllers so that you use a ViewModel to contain data for the Views you render, should all data be contained within the ViewModel? What conditions would it be ok to bypass the ViewModel?
The reason I ask is I'm in a position where some of the code is using ViewData and some is using the ViewModel. I want to distribute a set of guidelines in the team on when it's right to use the ViewData, and when it's just taking shortcuts. I would like opinions from other developers who have dealt with this so that I know my guidelines aren't just me being biased.
Just to further Fabian's comment; you can explicitly ensure viewdata is never used by following the steps outlined in this article. There's really no excuse not to use models for everything.
If you have no choice but to use ViewData (say on an existing project); at the very least use string constants to resolve the names to avoid using 'magic strings'. Something along the lines of: ViewData[ViewDataKeys.MyKey] = myvalue; Infact, I use this for just about anything that needs to be "string-based" (Session Keys, Cache Keys, VaryByCustom output cache keys, etc).
One approach you may wish to consider as your views become more complex, is to reserve the use of Models for input fields, and use ViewData to support anything else the View needs to render.
There are at least a couple of arguments to support this:
You have a master-page that requires some data to be present (e.g. something like the StackOverflow user information in the header). Applying a site-wide ActionFilter makes it easy to populate this information in ViewData after every action. To put it in model would require that every other Model in the site then inherit from a base Model (this may not seem bad initially, but it can become complicated quickly).
When you are validating a posted form, if there are validation errors you are probably going to want to rebind the model (with the invalid fields) back to the view and display validation messages. This is fine, as data in input fields is posted back and will be bound to the model, but what about any other data your view requires to be re-populated? (e.g. drop-down list values, information messages, etc) These will not be posted back, and it can become messy re-populating these onto the model "around" the posted-back input values. It is often simpler to have a method which populates the ViewData with the..view data.
In my experience I have found this approach works well.
And, in MVC3, the dynamic ViewModels means no more string-indexing!
I personally never use ViewData, everything goes through the Model, except when im testing something and i quickly need to be able to see the value on the view. Strongtyping!
In terms of ASP.NET MVC 2, ViewModel pattern is the preferred approach. The approach takes full advantage of compile time static type checking. This in combination with compiling mvc views will make your development work-flow much faster and more productive since errors are detected during build/compile time as opposed to run time.
I have to build an xml output that represents a data structured for a flex chart placed in the view.
I have several options:
have the controller create the xml (using data from the DB), and return it to a view that actually does nothing, since everything is ready.
have the view strongly typed to the data model from the DB, and render the xml declaratively in the view.
create an Html extension method that will contain the logic to create the xml and use it on the view.
in terms of separation of concern, what would be the best option?
in the future I don't expect many changes to the xml structure, maybe now and then.
I tend to select option 1 as it is more testable, and I feel more comfortable with the controller preparing the xml data.
I'd go for option number 1, as I feel it fits the MVC pattern the best. It's not the responsiblity of the View to create an XML file based on some data model. That's business logic and is therefor better off in the controller.
And equally important like you say, if you have your controller create the xml file you can create a unit test for it that asserts that the output xml is valid, contains all necessary nodes, etcetera.
Option 2 is the best. Your model has the data, your controller asks for it and offers it to the view. The view just has a tag to say where it goes. That to me is separation of concern.
Seeing Razzie's answer, I liked 1 as well, and I suppose that the model would have to provide some method for serializing some entity class (your chart results) into xml, in order for your strongly typed view to be able to make use of it.
Anyway I hope the answer helps, basically I don't think 3 is very good. :-)
I would say it depends on what you are more comfortable with as both options 1 and 2 are viable. People will say that option 1 is good as you can use an XmlWriter to make sure you've got valid xml to be returned and people will say option 2 is valid as mvc is all about having complete control on what is rendered in your view (which can be xml).
However, I would personally go with a variation on option 1 to keep the functionality independent of the controller and have it as a standalone utility method which takes in the data and outputs the xml. This will be easier to test but also be available to be called from other places in your code if this is needed in the future. In addition to this it also keeps the code in your controller cleaner.
And I agree with Mark I don't think option 3 is a good way to go.
That's just my thoughts, hope this helps :-)