I'm trying to import invoices from xero account using the Xero API in c#. LineItems collection in invoice object represents the invoice items which are part of invoice. I want to identify products in invoice with unique Id e.g.
Invoice1 has 2 line items say P1 and P2. Sameway, Invoice2 has 2 line items again say P1 and P2. While I iterate through the collection of invoices, I want to identify product P1 and P2 with unique Id and store them in my database. Then during the iteration loop, whenever I encounter P1/P2 item, I should know that these product has already been stored to database with unique id and no need to save these products again as it has already been stored.
I thought LineItemId and ItemCode might help but LineItemId is new Id generated every time and I noticed that Itemcode is null many times. So is there any way to assign unique product id to line items?
Thanks for help,
LineItemId is a unique ID per line item per invoice, nothing to do with the product so that's not what you want.
If ItemCode is missing or null, this means that the product is not saved in the Xero product database and has just been added as a "once off", and in theory it will never be seen again. So there is just no way to identify a product that doesn't exist. If these items really aren't just "once off" then they should be added to the database and given an ItemCode. So the problem is the way Xero is being used.
Once it is added as an Item, you can use the Items endpoint (/api.xro/2.0/Items) to also grab the ItemID which is a GUID and should be used to store in your database with the ItemCode.
Related
I'm working on a website in Laravel where we have realised that what we want to do is setup a matrix where the rows contain buyer IDs and the columns contain seller IDs. Each user on this website is both a buyer and a seller. And in each (buyer,seller) cell contains the quantity that the buyer has bought from that respective seller. This matrix is ordered so that the buyer on the 7th row is also a seller on the 7th column and it also needs to be dynamic in the sense that a buyer and seller can be added or removed. I'm new to SQL and eloquent so how could I go about creating this?
Don't!
Use a many to many relationship on the Users table to realize this. You can use a primary key on the table consisting of buyer_id and seller_id to prevent duplicates. And you can add an extra field to the pivot table to keep track of the quantity.
The database structure of your application should never be changed because of data.
I'm trying to think of the most straightforward way to store quantities of an item in a database. I'm creating a database to work in conjunction with a web app I'm developing to monitor and log gear lent out to people. So, I've thought a few different ways already, though I'm not sure if they will be easy to maintain into the future.
Idea 1
I have a gear table that stores the types of gear (e.g. shirt, pants, hat) along with data like sizes etc. Then for each time gear is taken out, it is logged in the gear_inventory table, storing details such as user id, gear type and boolean to signify if it was returned and return date. Then to track quantities, we'll have total_quantiy and count of gear out for a specific gear item in the gear table, this being updated manual with a second query triggered when an item is taken out or returned to plus or minus the given quantity.
Idea 2
Have the aforementioned total quantity out linked to the gear_inventory as a count of all non-returned items of that type.
Idea 3
Have an update task to change these quantities on table update or insert. Then do the same by adding or subtracting the quantity of a given query.
Idea 1 would be the easiest but not as reliable as the others. Idea 2 being the most reliable the handling of quantities is entering on the database to ensure. Then Idea 3 not as reliable since it's still relying on a scheduled task to update it.
So, how would you implement a quantity amount to ensure it doesn't get out of sync with the logged inventory records?
Edit 1
More info - The core solution I am trying to achive is having a method of storing or having a count of items taken out which can be compared to a total nunber associates with that item. As suggeated below, it will act in a similar fashsion to a bowling alley's loaning/borrowing shoes, exect users will be logged. So a record will be inserted when an item is borrrowed, and that record will be updated with return date on return. The types of items will be in its own table to store details on a general item, and that will have a one to many relationship with the logged gear table. The problem is, what is a full proof/reliable way to store/retrieve number of items out. Or am I overthinking this and a simple count query would sufice, not sure how intensive count is when performed oved and over again.
Let's think about what we're keeping track of.
Information about kinds of items.
Current inventory.
Which item?
How many?
What's been loaned out.
To whom?
Which items?
How many?
What's been returned.
By whom?
Which items?
How many?
First cut might look something like this:
create table items (
id serial,
name text,
...
);
create table inventory (
id serial,
item integer references items(id),
quantity integer check(quantity >= 0)
);
create table loans (
id serial,
user integer references users(id),
item integer references items(id),
quantity integer check(quantity >= 0),
when_loaned timestamp not null default now(),
when_returned timestamp
);
When you loan something out, insert a row into loans. When its returned, set loans.when_returned. If loans.when_returned is null, it's still out.
You could decrement the inventory when items are loaned, and increment it when they're returned. To preserve data integrity this should be done as a trigger, not as a scheduled process.
Alternatively, don't change the inventory quantities. Instead, subtract the number of loaned items from the amount in inventory. That's select sum(quantity) from loans where item = ? and when_returned is null from select quantity from inventory where item = ?. This makes loans and returns simpler, and avoids the possibility of the inventory count being corrupted, but it might cost performance problems if there's many, many outstanding loans.
What happens if you loan out 5 items and they return 3? How do you track that? One simple option is to split a single loan into two loans.
-- Copy the loan row
insert into loans
select * from loans where id = :orig_id
-- Track that 3 were returned
update loans
set quantity = 3, returned = now()
where id = :orig_id
-- Two are now outstanding
update loans
set quantity = 2
where id = :new_id
Without knowing more about what you're using this for, what the use cases are, and what the scale is, that's about all I can say. It's a good starting point.
I'm currently trying to redesign a Point of Sale database to make it more normalized, which will help tremendously with managing the data, etc. I'm a little bit unsure about the best design practices, based on the data I have to deal with. First of all there are basically two sets of measures, which share common keys. There is inventory data, units and dollars, and then point of sale data, units and dollars. Each of these is a customer, store, item and date level.
What I've done (mostly in theory at this point) is to create separates table for
Item level information
Item_ID,
Customer_ID
itemnumber
(and a few other item specific information).
Stores
Store_ID,
Customer_ID,
Store Number,
(and essentially address information)
Customer
Customer_ID,
Customer Number
(other customer specific information like name).
So in addition to those "support" tables, I have the
Main Inventory Data
Store_ID
Item_ID
I also have POS Data table, with the exact same ID's.
Basically my questions are:
should I include the Customer ID in the Pos Data and Inventory Data tables, even though they are a part of both the stores and items tables?
My second question would be, if I do add the customer ID, if I would join all of these tables together,
would I join the customer ID from all of the tables (Pos Data, Stores and Items OR Inventory Data, Stores and Items) to the customers table or
would just joining from the Pos Data table be sufficient.
Let me give a few additional details, regarding the data. As an example, we have two Customers, CustomerA and CustomerB. CustomerA has several stores whose store numbers are 1000,1025, 1036 and 1037. CustomerB also has several stores, whose store numbers are 1025, 1030, and 1037. Store numbers 1025 and 1037 happen to be the same between customers, but the stores themselves are unique and completely different.
CustomerA's Store Number 1000 sells three of our items (this is a wholesale perspective), which are Items ABC, DEF and EFG. CustomerA's Store Number 1025 also sells three of our items, which are ABC, HIJ and XYZ.
Each of these items contains two import pieces of data, in regards to its relationship to its specific customer and store number, Point of Sale data and Inventory Data. Point of Sale data would be in the form of PosUnits, which would be the quantity of an item that were sold, and PosDollars, which would be the total Dollars of the item that were sold in that store (essentially the number of units times the price it was sold for). The Inventory Data would be in InventoryUnits, which is the quantity of an item that is in stock at a store. [one thing to note, I separated inventory and pos data into separate tables, because we don't always receive both pieces of data from every customer. Also inventory and POS data are generally analyzed separately].
So, back to my example, CustomerA's Store Number 1000, item ABC may have sold 100 units, which is $1245.00. CustomerA's Store Number 1025, may have sold only 10 units of the same item for $124.50.
Now if we go back to CustomerB, it just so happens this Customer also has an item named ABC that it sells in many of their stores. CustomerA's item ABC is a completely different product from CustomerB's item ABC. It's purely coincidental that they named them the same thing.
Let me add this last point of clarification, which I probably should have stated earlier. My perspective is as a wholesaler. When I say item, I'm speaking of the customers item number, not the wholesalers item number. There is a cross reference involved in getting to the wholesalers item and the customer may have more than one of their item number the reference the same wholesaler item number. I don't think it' necessary to delve into that, though.
Question #1: As part of the normalization rules, you should avoid to include redundant data in any table unless there are performance issues that require de-normalization. there are thousands of articles that will explain why avoiding redundancy.
As for Question #2: in the rules are only pick the columns that you need in your queries, if you need the Customer_ID pick it from where is cheaper for the database
Allow me to raise one more question
why do you have repeated Customer_ID in Stores and Item_level when you can join them thought the Main Inventory Data. this is another redundancy.
I have a table with data called InvoiceShipments. It continues a row for each product shipped on an invoice. Each product belongs to a product category, which I can query and filter by. Some of the products are finished good products with a Bill of Material, where the Bill of Materials (BOM) is a list of the parts that combine to make the finished good.
In the InvoiceShipments table, the finished good is listed with a price but no cost. It is then followed by the components (BOM) of that finished good, which in turn have a cost but no price. I have a separate table that lists all of the component items and which finished goods it goes to. Note that component goods can belong to more than one BOM.
I can currently filter the InvoiceShipments by the products that I want based on the product category (from a join to a different table). What I want to do is grab that finished good number, and get a list of all the part #s that make up that BOM, then go back to the InvoiceShipments and sum the costs for all of the rows that match those component #s and invoice#. But I haven't been using Crystal long enough to know what to do at the query level, what to do with a command table, what to do with a formula, etc.
Sample Screenshots:
Top table in the gallery is BOM table, second table is the InvoiceShipments, and the third is the desired outcome.
Any help would be appreciated.
From what I gather you want to combine the invoice number but use the finished product information. I've done something similar, solution is a little weird but it works. You only need your InvoiceShipments table
Group by invoice number
Create a formula for Order ID, SKU and ProductName
IF Price <> 0 AND Cost = 0 THEN
Orider ID '<-Change this according to the formula (SKU, ProductName)
ELSE
""
Insert-> Summary on each of the formula as Maximum and place it on the grouped invoice line.
Since the Quantity is constant you can put that field on the grouped invoice line.
Insert-> Summary on Price then on Cost using SUM and place it on the grouped invoice line.
Hide the details.
This should give you the result you need. What's happening is because your formula is only printing the finished goods information, the other items are blank. So when you use MAXIMUM, the non-blank items will print.
Hope this helps.
NEW SOLUTION
I don't have any tables or views that is setup like your data so I can't test this solution, but hopefully there is enough info that you can formulate a good solution
I noticed that you can't use the materials in the InvoiceShipments to idenfity the Finished Product in BillofMaterials. The Materials repeats itself. We'll have to identify them using the finished product.
Add in InvoiceShipments and rename it InvoiceShipments1 (when adding tables, the right side windows, right click on the table and rename.
Using select expert, isolate your finished products. (Price <> 0 and Cost = 0)
Database -> Database Expert. Add in your BillofMaterials table. Link SKU to ProductSKU. Left Outer Join
Now the materials are associated with an invoice number, We can try and link another copy of the INvoiceShipments to the BOM. This is tricky.
Database -> Database Expert. Add in your InvoiceShipments table rename to InvoiceShipments2. Link InvoiceShipments2.invoice# to InvoiceShipments1.Invoice#, and InvoiceShipments2.SKU to Material#. Use Left Outer Join
Create a formula that alternates between InvoiceShipments1 and InvoiceShipments2 on columns OrderID, SKU, and ProductName
IF ISNULL({InvoiceShipments1.OrderID}) THEN
{InvoiceShipments2.OrderID}
ELSE
{InvoiceShipments1.OrderID}
Create a formula combining InvoiceShipments2.invoice# and SKU (SKU formula version)
Group by formula in previous step (If the invoice contains 2 finished products, it will create 2 lines for one invoice.
On the GF put InvoiceShipments2.invoice#, OrderID (formula version), SKU (formula version), ProductNmae (formula version), InvoiceShipments2.quantity, Summerize(InvoiceShipments2.price), Summerize(InvoiceShipments2.cost)
Hide GH
Hope it works!
These are actually two questions relating to an online bookstore.
I have a table for customers in SQL, and it has all this customer info, including a customer ID. Then I have a table full of books on sale. Lastly, I have a table for a shopping cart.
Now the shopping cart is going to be a table very similar to the books table, only it will have less items since it'll contain some subset of the book table's contents.
I want the entire cart to be tied to a single customer's ID, and I want every entry in that cart to come directly from the Books table.
How to I go about defining such a table, I mean what statements do I need?
As it is, I'm confused about the issue, because the entire cart table essentially an attribute of a single customer, but I have no idea how to represent that in SQL. I want to be able to look up the cart table using the customer ID, basically.
Any help would be greatly appreciated.
You basically need these four tables:
create table books (book_id int, name varchar(200), author(200));
create table customers (customer_id int, name varchar(200));
create table carts (cart_id int, customer_id int);
create table cart_details (cart_id int, line_number int, book_id int, qty int, price numeric(18,2));
In essence, you will store objects like this:
Books into books table
Customers into customers table
Carts into carts and cart_details table. carts will represent a cart for a certain customer, and cart_details will represent cart's content.
Whenever you want to retrieve a cart corresponding to a certain customer you can just do:
select * from carts inner join customers using (customer_id);
If you also want cart's detail you can do:
select * from carts
inner join cart_details using (cart_id)
inner join customers using (customer_id)
;
Note: Tried to write examples in a as general as possible SQL syntax since you didn't provide the RDBMS you are using. Also, left out on purpose all details related to primary and foreign keys so you can understand tables and their attributes first.
You could address this by creating a CustomerCart table that references the Customer and Book tables. It could have a format like the following (I'm making this as non-implementation-specific as possible, partly because you haven't indicated what RDBMS you're using):
Composite primary key consisting of CustomerId + a CartId (allows a Customer to have multiple / saved / historical carts)
BookId (each record then represents an instance of a book from the catalog being added to a customer's cart)
Measures, such as Quantity, that relate to the instance of the given book in the given customer's cart
Think of your problem like this... one customer can have many books in their shopping cart, and one book can exist in many customers' shopping carts, so you have a many-to-many relationship.
With this in mind, the way to handle this problem is create a table that tracks the associations between customers and books, including any other information that is relevant.
create table shopping_cart (
customerId int,
bookId int,
quantity int,
etc...
)
It depends on the functionality you want to support with a cart.
The easiest would be to create a cart table with BookID and CustomerID. However if a customer or book is ever removed; you will, though cascade deletes if allowed, automatically remove something from someone's cart... or remove all their cart items for a person if the person is removed... do you want that to happen? If not then you need to keep all book and customer information in the cart.
Secondly, do you want to keep record of everything they've purchased over time in a "Cart" do you want them to be able to checkout with a subset of items in their cart? Is the life of the cart their visit to the site, or would the items remain months/years after they come back?
The answers to these types of questions determine the appropriate design.