I am currently developing a program that should create invoices and add lines based on the selection of table.
This is my table (created using DevExpress):
These are future invoice lines that have a company ID as reference.
What I want to do with the future button 'Create invoices' is create 1 invoice per selected ID and add all of the selected lines to the invoicelines table.
My tables are:
Invoice
InvoiceID
CompanyID
InvoiceLines
ID
InvoiceID
Title
....
Based on my example picture, the result I would desire is:
2 invoices with each having 2 lines added
The problem is that I do not know how to handle this in my code.
I currently have:
private void btn_ExportToDB_ItemClick(object sender, ItemClickEventArgs e)
{
List<int> PWIDs = new List<int>();
List<int> distinct = new List<int>();
Dictionary<int, int> lines = new Dictionary<int, int>();
if (gridView.SelectedRowsCount > 0)
{
for (int i = gridView.SelectedRowsCount - 1; i >= 0; i--)
{
int rowHandle = gridView.GetSelectedRows()[i];
int PWID = int.Parse(gridView.GetRowCellValue(rowHandle, "pwID_PW").ToString());
PWIDs.Add(PWID);
lines.Add(rowHandle, PWID);
MessageBox.Show("customer id " + PWID);
distinct = PWIDs.Distinct().ToList();
}
foreach (int value in distinct)
{
}
}
}
I tried to do the following:
1- Create a dictionary in which I put the selected rowhandle + pwID.
2- After, I loop through my dictionary and select distinct pwID values (these are used for my invoices).
3- Hereafter, I'm stuck with my invoice lines, that I can't seem to add to my invoicelines table because I think my design on handling this problem is wrong.
How could I solve this in the most efficient way?
If you can return the entire ticket objects from the selection list in your screenshot then you could run a piece of code as below;
public List<Invoice> CreateInvoices(IEnumerable<Ticket> selectedTickets)
{
// Group tickets by company id
return selectedTickets.GroupBy(ticket => ticket.CompanyId)
// Convert grouping into new Invoice objects
.Select(g => new Invoice
{
// Build invoice object
CompanyId = g.Key,
// Build invoice lines
InvoiceLines = g.Select(line => new InvoiceLine() {Title = line.Title}).ToList()
}).ToList();
}
This shall return a IEnumerable of Invoices containing multiple InvoiceLines inside of each.
Related
I am not able to set "Created From" on Invoice to reference a Sales Order record through the SOAP web service. I have tried setting this field directly and also through Initialize API (initializing a invoice record using the sales order and then copying the CreatedFrom field from the initialized invoice to the invoice being created).
I don't get any errors yet the Created From field doesn't get set on the created invoice record.
The code I am trying looks something like this:
// initialize invoice from sales order
var initializeRecord = new InitializeRecord()
{
type = InitializeType.invoice,
reference = new InitializeRef() { internalId = "sales-order-internal-id", type = InitializeRefType.salesOrder, typeSpecified = true }
};
var result = Utility.Do(async () => await connector.NetSuiteClient.initializeAsync(initializeRecord));
SuiteTalk.Invoice initializedInvoice = result.record;
// create a invoice and copy over the "createdFrom" field
var invoice = new SuiteTalk.Invoice();
invoice.createdFrom = initializedInvoice.createdFrom;
/* set other fields on the invoice and add some line items
....
...
..
*/
// finally create the invoice
var result = Utility.Do(async () => await connector.NetSuiteClient.addAsync(invoice));
How I can associate this invoice to a sales order while creating it?
What you will have to do -- as painful as it is -- is to use the transformed record provided to you by netsuite from the initializeRecord call, and then modify it. It is a pain because there are several fields that you will have to unset as you fill in the record.
The issue is that there are createdFrom associations on both the header level, and the line level, that need to be filled in for the sales order to invoice association to take.
here are the list of line fields that I had to unset in the invoice:
line-level:
quantityRemaining
quantityAvailable
quantityFulfilled
quantityOrdered
quantityOnHand
costEstimate
taxRate1
here are the header-level fields:
subTotal
total
totalCostEstimate
estGrossProfit
estGrossProfitPercent
discountTotal
giftCertApplied
shippingTax1Rate
Thank you 2ps.
In my case this code was enough
Invoice invoice = (Invoice)initializeResponse.record;
invoice.totalCostEstimateSpecified = false;
invoice.estGrossProfitPercentSpecified = false;
invoice.discountTotalSpecified = false;
invoice.totalSpecified = false;
foreach (var item in invoice.itemList?.item)
{
item.quantityRemainingSpecified = false;
item.costEstimateSpecified = false;
}
var writeResponse = svc2.add(invoice);
Well I have a list which is called employeeList. In the emoloyee Liste there are stored employees with some attributes like id, lastname ...
One of the attributes is Department. Now I want to create Radio Buttons with the Department. As there are more employees per department one department can appear several times but this I'd like to avoid. This is what I already got:
for (int i = 0; i < employeeList.Count(); i++)
{
panDepartments.Children.Add(new RadioButton() { Content = employeeList.ElementAt(i).Department.Distinct()});
}
Just filter the list before you iterate over it. One possibility would be LINQ (i.e. Distinct()) or just do the filtering yourself.
I think you can try something like this.
//First of all we need to get unique departments.
var departments = employeeList.Select(e => e.Department).Distinct();
//And after that we can create radio buttons and add them as children elements.
foreach(var dep in departments)
{
panDepartments.Children.Add(new RadioButton() { Content = dep });
}
//foreach loop can be replaced something like this if "panDepartments.Children"
//supports "AddRange" method
var radioBtns = departments.Select(d => new RadioButton() { Content = dep });
panDepartments.Children.AddRange(radioBtns);
I am using the following code in my .NET web service that gets its data form a CSV file.
private List<Item> ietms = new List<Item>();
public ItemRepository()
{
string filename = HttpRuntime.AppDomainAppPath + "App_Data\\items.csv";
var lines = File.ReadAllLines(filename).Skip(1).ToList();
for (int i = 0; i < lines.Count; i++)
{
var line = lines[i];
var columns = line.Split('$');
//get rid of newline characters in the middle of data lines
while (columns.Length < 9)
{
i += 1;
line = line.Replace("\n", " ") + lines[i];
columns = line.Split('$');
}
//Remove Starting and Trailing open quotes from fields
columns = columns.Select(c => { if (string.IsNullOrEmpty(c) == false) { return c.Substring(1, c.Length - 2); } return string.Empty; }).ToArray();
var temp = columns[5].Split('|', '>');
items.Add(new Item()
{
Id = int.Parse(columns[0]),
Name = columns[1],
Description = columns[2],
Category = temp[0]
});
}
}
This code gets a list of products from the CSV file along with its name, description etc. Each product belongs to either one or two categories : Category = temp[0].
Each product's category is found in a column of the csv file with it's data structured as such:
Groups>Subgroup>item, in which case, this product belongs to category "Groups".
The category column of a product may also be structured as:
MajorGroup|Groups>Subgroup>item, in which case this product belongs to category "MajorGroup".
Also, in many cases a product's category column may be structured as:
MajorGroup|Groups>Subgroup>item|SecondGroup, in which case this product belong to both the categories "MajorGroup" and "SecondGroup"
The code above that I am currently using does half the job. If a product has a category defined in the CSV file as MajorGroup|Groups>Subgroup>item|SecondGroup, it assigns it to category "MajorGroups" but not "SecondGroup".
This line var temp = columns[5].Split('|', '>'); gets the first value structured taht way and separated by a pipe and sets it as the product's category here Category = temp[0].
How do I fix this so that if the category is structured as MajorGroup|Groups>Subgroup>item|SecondGroup, with two categories, then it will show up in both categories.
How do I assign the product to one or more categories depending on the structure of the category column data.
This works for the most part, but how do I alter the code to check and assign for both categories?
Can I change this var temp = columns[5].Split('|', '>'); to get both teh first and the last value if it exists and assign both to Category = temp[0].
To get the second group values given the problem statement as specified you could do the following.
...
var temp = columns[5].Split('|', '>');
string categories= temp[0];
if (input.Count(x => x == '|') >= 2)
{
categories+= "," + temp.Last();
}
...
Category = categories;
Then one could get a list of Items that is assigned to a category by the following function:
static public IList<Item> GetProductsByCategory(string category, IList<Item> items)
{
return items.Where(x => x.Category.Split(',').Contains(category,StringComparer.OrdinalIgnoreCase)).ToList();
}
A much cleaner solution is to store the categories within the Item class as something that implements ILIST.
You should definitely use some CSV parser instead of doing this manually. There are too many potential problems and issues when parsing CSV manually that it is much easier and faster to use some existing tool like:
FileHelpers
Fast CSV Reader
I am creating a Pie Chart and its name-value pair are being retrieved from the database.
how to read the row details in order to get the values and store it one property ?
public override void OnApplyTemplate()
{
Ram.DataContext = new List<UsageRAM>()
{ new UsageRAM() { name = "Available" , value =/*how to get the value here*/ },
new UsageRAM() { name = "Used" , value =/*how to get the value here*/ }};
base.OnApplyTemplate();
}
public class UsageRAM
{
public string name { get; set; }
public double value { get; set; }
}
EDIT
--Answer which worked for me--
using (DB db = new DB())
{
var row = (from c in db.UsageRAMs
orderby c.UsageRamID descending
select c).First();
Ram.DataContext = new List<UsageRAM>()
{ new UsageRAM() { name = "Available" , value = row.Available},
new UsageRAM() { name = "Used" , value = row.Used }};
If you're using EF, simply add a new model to your project and include the requried table(s) in this model. Then you can use the newly created Entities object to read your db values as follows:
var Rows = context.YourTableName.Where(YourCondition).ToArray();
You can then iterate over the Rows collection using foreach or something.
If you need to read values from a single row, you may want to use First instead of Where above. That will return a single object whose properties will map to your db fields and can directly be assigned in the example code you posted in the question.
EXAMPLE
Say your model's Entity class is named MyEntities and it contains the table UsageRam, which has two fields Available and Used. Then it will take the following code:
using(MyEntities e = new MyEntities)
{
var Row = e.MyTable.First(x => x.UsageRamID = **[ID]**);
MessageBox.Show("Available=" + Row.Available.ToString() + ",Used=" + Row.Used.ToString();
}
I have just shown values in message box, you can assign them to anything you want.
Another Example
using(MyEntities e = new MyEntities)
{
var Rows = e.MyTable.Where(x => x.UsageRamID > 10 && x.UsageRamID < 20);
foreach(var Row in Rows)
MessageBox.Show("Available=" + Row.Available.ToString() + ",Used=" + Row.Used.ToString();
}
EXAMPLE 3
The code in your updated post appears fine to me, though I do have some doubts about the db design, but given your table is indexed on RamUsageID column, this should give you correct results without much performance impact. I generally prefer lambada expressions over query, so I'd rather write it like:
db.RamUsage.OrderByDescending(x => x.RamUsageID).First()
I am a bit stuck here and can't think further.
public struct CandidateDetail
{
public int CellX { get; set; }
public int CellY { get; set; }
public int CellId { get; set; }
}
var dic = new Dictionary<int, List<CandidateDetail>>();
How can I compare each CandidateDetail item against other CandidateDetail items within the same dictionary in the most efficient way?
Example: There are three keys for the dictionary: 5, 6 and 1. Therefore we have three entries. now each of these key entries would have a List associated with. In this case let say each of these three numbers has exactly two CandidateDetails items within the list associated to each key. This means in other words we have two 5, two 6 and two 1 in different or in the same cells. I would like to know:
if[5].1stItem.CellId == [6].1stItem.CellId => we got a hit. That means we have a 5 and a 6 within the same Cell
if[5].2ndItem.CellId == [6].2ndItem.CellId => perfect. We found out that the other 5 and 6
are together within a different cell.
if[1].1stItem.CellId == ...
Now I need to check the 1 also against the other 5 and 6 to see if the one exists within the previous same two cells or not.
Could a Linq expression help perhaps? I am quite stuck here...
I don't know...Maybe I am taking the wrong approach. I am trying to solve the "Hidden pair" of the game Sudoku. :)
http://www.sudokusolver.eu/ExplainSolveMethodD.aspx
Many Thanks,
Kave
Process every pair in a sequence shows how you can process every pair within a list
from kvp1 in dic
from i1 in Enumerable.Range(0, kvp1.Value.Count)
let candidate1 = kvp1.Value[i2]
from kvp2 in dic
where kvp2.Key >= kvp1.Key
from i2 in Enumerable.Range(0, kvp2.Value.Count)
let candidate2 = kvp2.Value[i2]
where kvp1.Key != kvp2.Key || i2 > i1
where candidate1.CellId == candidate2.CellId
select new {
Key1 = kvp1.Key,
Key2 = kvp2.Key,
Candidate1 = candidate1,
Candidate2 = candidate2
}
You may want to modify the select clause for only the information you want or add another where clause if you want only matching candidates from different keys.