I have a RDLC report that displays count of Test Packs issued each day. I want to change this report in such a way that it should show the count of test packs issued per week instead of per day. How can i achieve that?
Here is the result of the current report (exported to excel).
The report is generated Island wise, then issue date wise test packs count.
The property in my ViewModel returns a collection that contains Test Pack records with fields like
public class TestPack
{
public string TestPackNo { get;set; }
public string Island { get;set; }
public string IssueDate { get;set; }
}
There two ways to achieve this.
Work with underlying data - for example, add column "MondayofCurrentWeek" (since every week would have Monday) and group by that column instead. (This would be my preferred solution.)
Add group by "week start" expression. You might need to add function to report's code to find it base on current date function. Since the language for report's code is VB, this may help: https://msdn.microsoft.com/en-us/library/aa227527(v=vs.60).aspx
Related
How can I use variables in my feature file? Specifically, I need to use dateTime.now. Ideally, something like...
Given the API returns items for "dateTime.now"
when my function is run
then I want that data in my database
And in my acceptance test file...
[Given("The API returns line items for (.*)")]
Is this the proper way to go about this? I'm unsure of how to use variables in my feature file. I want my acceptance test to use the current date.
The easiest way is to write a step specific for returning lines items for "right now":
Given the API returns items for right now
You can call the other version of the step from the new version:
[Given(#"the API returns items for right now")]
public void GivenTheAPIReturnsItemsForRightNow()
{
GivenTheAPIReturnsItemsFor(DateTime.Now);
}
This avoids code duplication between steps.
I partially agree with Greg Brughardts answer. Because the feature file is something you can share with business stakeholders (or other non-IT persons in your organisation), it would make more sense to use 'real world' language in your feature files.
Also, when you would pass this to a reporting tool at the end of the test it would be more readable.
I'd approach it like this. The switch statement makes it easy to add other types of dates with real world language:
[Given("The API returns line items for '(.*)'")]
public void GivenTheAPIReturnsItemsForTime(string mydate)
{
switch (mydate)
{
case:"the current date":
HandleApiDateTime(DateTime.Now.ToString("dd-MM-yyyy"))
// pass the current date to the Api handler
break;
case:"yesterday":
HandleApiDateTime(DateTime.Now.AddDays(-1).ToString("dd-MM-yyyy"))
// pass yesterdays date to the Api handler
break;
default:
Console.Writeline("I didnt recognize this command");
// or other error handling
break;
}
}
private void HandleApiDateTime(DateTime mydate)
{
// do your api magic with a date object
}
Your feature file could then look like
Given the API returns items for 'yesterday'
when my function is run
then I want that data in my database
One way , easiest imo, to get current dateTime in your test is [StepArgumentTransformation] and then you can extract date or other things out of it . This way you can use [StepArgumentTransformation] in other steps in your Gherkin like below resulting in less code
Given the API returns items for currentTime
Given the database1 returns items for rightNowTime
Given the database2 returns items for presentTime
Above is just ex , but basically match it with whatever string variable you like
public class binding {
public DateTime datetime;
[Given(#"the API returns items for (.*)")]
[Given(#"Given the database1 returns items for (.*)")]
[Given(#"Given the database2 returns items for (.*)")]
public void currentDatetime(DateTime dt)
{
log.Info("current time: " + datetime);
log.Info("current date: " + datetime.Date);
}
[StepArgumentTransformation]
public DateTime convertToDatetime(string c)
{
datetime = DateTime.Now;
return datetime;
}
}
The above code logs current time and current date three times
Is there any way that I can limit the results given by an export scenario to only those that have a date matching the current date? It's possible in Generic Inquiries, but I don't see any way to do it in an export scenario. It allows you to apply a source restriction for the date, but you have to hardcode a value. You can't give it a value like "#Today" or "Today()"
I can build a customization if that's needed.
I add a datediff using datelastmodified to the GI so I can filter by days since last modified.
Of course would work for datecreated or creating a isToday field.
Another option is to filter the GI itself if it's only used for this Export.
Has anyone solved the riddle of how to apply SpecFlow Step Argument Transformations to cells in a table, in conjunction with the SpecFlow.Assist CreateInstance/CreateSet? (code combined here to save space)
Given a table like the following:
| Price | Zip | Effective Date |
| 10.00 | 90210 | in 2 days |
When the 'given' step executes
And the table data populates a poco
Then the effective date should be transformed into a DateTime with value of 2 days from today
[Given(#"a table like the following:")]
public void GivenATableLikeTheFollowing(Table table)
{
var temp = table.CreateInstance<Temp>();
}
internal class Temp
{
decimal Price { get; set; }
int Zip { get; set; }
DateTime EffectiveDate { get; set; }
}
[Binding]
public class Transforms
{
[StepArgumentTransformation(#"in (\d+) days?")]
public DateTime InXDaysTransform(int days)
{
return DateTime.Today.AddDays(days);
}
}
StepArgumentTransformation bindings apparently don't apply to table cell contents (since the step's argument is type Table), but somehow the SpecFlow.Assist CreateInstance/CreateSet will still transform cell data for basic types.
For example , if the Effective Date's contents are '11/13/2016' instead of 'in 2 days', the underlying poco's EffectiveDate property transforms to a DateTime just fine (or an int, decimal, etc).
I see some other solutions like applying a conversion within the step definition itself like here or creating a StepArgumentTransformation for the whole table, but... obvious cons. Update: this question is similar, but solutions also avoid mingling StepArgumentTransformation with CreateInstance/CreateSet.
There is also a section in the SpecFlow Assist Helpers docs about extending by registering value retrievers/comparers, but in my example, a DateTime set already exists. So, perhaps a custom DateTime type? It seems like perhaps there could be a check for StepArgumentTransformations on the known types, or something like that.
In the DateTime retriever, something like..
public virtual DateTime GetValue(string value)
{
var returnValue = DateTime.MinValue;
// check for StepArgumentTransformations here first?
DateTime.TryParse(value, out returnValue);
return returnValue;
}
Any ideas on what I am missing to get the StepArgumentTransformation to apply to the table cell contents when using table.CreateInstance? Or is one of the mentioned solutions the best/only way?
I have created a small prototype that can be used to reconfigure Assist to be able to pick up conversions with [StepArgumentTransformation] bindings.
My plan is to make a blog post about it, but until it is ready, maybe you can get out the essence from this gist. (I did it a year ago for SpecFlow v2.0, so some smaller adaptions might be necessary.)
https://gist.github.com/gasparnagy/a478e5b7ccb8f557a6dc
I don't think what you want is implemented currently, but theoretically I think it could be implemented. You can probably implement a new, enhanced DateTimeValueRetriever yourself which checks to see if the string is parseable as a datetime first and if not checks if any of the [StepArgumentTransformation] methods can parse it, and then replace the current DateTimeValueRetriever with your enhanced one. Then you could submit a pr offering your new version as an enhancement to the existing version, and see what the appetite is.
This is my first time using c# and sql server to code a simple monthly reporting application which will print the report to paper.
Everything just fine but there is a complicated problem for me when comparing two value.
Suppose there are 14 columns(originally 37 columns) and 12 rows for each month. The last column i am using for month name.
Columns are:
Name, col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,monthName.
Logically there will be 12 reports in a year.
col2+col5+col6
and
col7+col10+col11 sum of current month's
must be same as last month col4 and col9-12 rows
This is my main problem!
For example if monthName has January(as past month) and I am filling the current month February . There is a pushButton called "Verify".
If I click on verify then the February's 3 columns sum will be compared to January's 1 column sum as above.
I have tried some sql query like select * from table1 where sum(col4)=sum(col2+col5+col6) and sum(col9)=sum(col7+col10+col11)
But my logic and knowledge is completely flawed since it did not work as expected.
Secondly, I thought appending data from sql query results to List<> and comparing the col4/col9 would be an idea but again flawed as there is no gurantee that Name column's value would not be shuffled which will lead to compare to wrong data, also I am not confident at it.
I need help from c# and sql database expert to get an idea to do this as I am not sure what is my options!
Update: I am doing some experiment in visual studio. All codes are just ugly but i will upload it on dropbox if someone care to try it.
I think your best solution here is to keep the business logic and the database query separate. If the user clicks the "verify" button on the "February" row, you just submit a database query along the lines of SELECT * FROM table1 WHERE monthName = 'january' although:
Probably you should actually use a date field to identify your months).
How you actually retrieve the data will depend on what type of data access you are using (ADO.NET, Entity Framework, etc.)
Once you get back that result, you just use straightforward C# logic to do the verification, along the lines of:
int priorMonthSum1 = priorMonthResultset.col4;
int priorMonthSum2 = priorMonthResultset.col9 + priorMonthResultset.col10 + priorMonthResultset.col11 + priorMonthResultset.col12;
int currentMonthSum1 = currentMonthResultset.col2 + currentMonthResultset.col5 + currentMonthResultset.col6;
int currentMonthSum2 = currentMonthResultset.col7 + currentMonthResultset.col10 + currentMonthResultset.col1;
if(priorMonthSum1 != currentMonthSum1 || priorMonthSum2 != currentMonthSum2)
{
// handle mismatch (highlight red?)
}
else
{
// handle match (highlight green?)
}
I am writing a currency converting module for one of our applications. I have a list of products, a list of currencies we are interested in seeing prices for, and a list of currency rates. I want the user to be able to select which currencies from the list they see in the GridView.
I also want to be able to amend my list of currencies and include a new currency, without having to make additional changes to this module. So my GridView display has to be dynamic.
Essentially I am planning on ending up with a GridView that has the following columns:
Part No - Description - USD Price - AUD Price - GBP Price
The USD price would be static as it's our base currency, the AUD and GBP are user selected and could have potentially any number of currencies listed.
I would normally use a DataSet and DataTables for this work, but I am sure there is a "better" way to do it using System.Collections.Generics.
Right now I have all of the data I need in List collections, but there does not seem to be a way to define how these collections relate to each other, or combine these collections into one so it can be bound to a GridView.
Should I be looking at something other than List to achieve this or do I need to go back to my original approach of a DataSet and DataTables.
Thanks!
******UPDATE / SOME CODE******
OK, someone asked for some code, so I will explain a little bit more about what I have setup so far.
List of Products & Currencies - These come from an SQL DB via LINQ, so they can be any of the System.Collections.Generics objects, e.g. List, IEnumerable etc.
Currency Rates - These I am pulling from the European Bank public XML file. I download the file, strip the data I need out of it and currently store that as a List object.
I could store the currency rates in the database table as well, but then I have to have some sort of background process that goes and updates the rates each day. This way the rates only get updated when someone accesses the report function (which is only going to happen occasionally). So I would rather grab the latest rates "on demand".
What I know I need to end up with is some object that has the following structure:
PartNo - Description - Base Price - Currency Price 1, Currency Price 2, Currency Price 3
Where the number of Currency Prices is undefined, as it's based on what currencies the user wants the report to display.
It's the undefined part that I am struggling with, essentially how can I create a structured object, that I don't know the complete structure of until runtime ?
Hope this makes more sense / helps!
Just thinking out loud here, but if you stored your "foreign" prices in a Dictionary or similar data structure like so:
class Product {
public String PartNo { get; set; }
public String Description { get; set; }
public Decimal BasePrice { get; set; }
public Dictionary<String, Decimal> ForeignPrices;
}
Then you could write a simple routine that would take a collection of the above objects and convert it into a DataTable that you could then bind to. Said routine would always create the following columns:
PartNo, Description, BasePrice
It would then loop through the items in the Dictionary, adding additional columns for each item. So if you had three items in ForeignPrices:
ForeignPrices.Items.Add("AUD", 10.50);
ForeignPrices.Items.Add("GBP", 6.20);
ForeignPrices.Items.Add("CAD", 5.95);
You would end up with three additional columns on your dynamically-created DataTable:
PartNo, Description, BasePrice, AUD, GBP, CAD
Of course you may want to do away with the BasePrice property and just make "USD" another item in ForeignPrices (in which case it would simply be called Prices).
HTH.