SQL using lookup table to create a supplier quote - sql

I have a lookup table called supplier, which has all of my suppliers information.
I also have a lookup table called materials, which has all of my materials information.
I'm creating another table called supplier_quote in which I will store 3 suppliers with at least 3 raw materials each as well as price and quantity.
the purpose of this is that the user in visual basic can call 1 supplier and get a price for each of the 3 materials, call the next supplier and input the price of the same 3 materials and again with the 3rd supplier.
I was thinking a drop down box in the form to display each suppliers name and raw material, but so far I can't seem to understand the logic behind it.
I need something like this:
supplier 1
raw material A. $23
raw material B. $25
raw material C $30
supplier 2
raw material A. $22
raw material B. $21
raw material c. $35
supplier 3
raw material A. $23
raw material B. $32
raw material C. $29
all that information would be one record in the supplier_quote table, because it all goes in one same quote. the prices are input by the person doing the quote, so I'm guessing they get stored in this same table.
anyone please help? I appreciate it in advance. I'm using visual basic 2010 and SQL 2008.

Quote (just some ideas on what I may track but this is where requirements need clarification)
ID
Name
Reason for quote (Why do you need this quote?)
Requested By (who's asking for it perhaps linked back to user?)
For Project #... (Do you track these to a specific project or RFP?)
Due By Date (when do all the proposals from vendors need to be returned by?)
Etc...
Request For Proposal # (internally how do you track quote requests ?)
Supplier
ID
Name
Material
ID
Name
Supplier_Quote
Quote_ID
Supplier_ID
StartDate (Date supplier pricing is good form)
EndDate (date supplier pricing is good to leave null if open ended.)
Supplier_Quote_Materials
Quote_ID
Supplier_ID
Material_ID
Price
Quantity limits etc...
User Interface:
User enters "Quote Maintenance transaction"
tabbed interface or multiple sections you decide.
Tab 1 - Quotes
Search
Quote Listing Results (when selected detail section is updated to reflect selection)
Detail (Add/Delete/save buttons)
Tab 2 - Suppliers ( Disabled until a quote is selected on tab 1)
Search
Supplier Listing Results (when selected detail section is updated to reflect selection)
Detail (Add/Delete/Save buttons)
Tab 3 - Materials (disabled until a supplier is selected on tab 2)
Search
Materials Listing (when selected detail section is updated to reflect selection)
Detail (add/Delete/Save buttons
The relationships between quote, supplier and materials is maintained though sections/tabs. thus a user is adding suppliers to quotes, and then materials to suppliers which are related to quotes.

Related

How can I get accurate totals from a subform when in splitform view, currently each record needs to be selected before the total is correct

I am setting up a system for the reconciliation process of accounts payable. I set up a few tables for inputting the groups of tickets that we get every day to log them before we get in the invoices.
I have a handful of tables that provide information about some of the fields in the tables but the key tables are:
Ticket_Group:
TGID(autonumber)
Ticket_Date
SupplierID(Unique Identifier for Raw Material Provider)
ShipperID(Unique Identifier for Shipping Company of classification)
MaterialID(Unique Identifier for material)
gl_dep(general ledger department)
mat_inv_rec(true/false if material invoice has been received)
freight_inv_rec(true/false if freight invoice has been received)
Ticket:
TID(Autonumber for Each Ticket)
TGID(Links to TGID in Ticket_Group, Many TID to One TGID)
qty(Quantity of Material)
What I want to be able to do is see all of the Records from Ticket_Group that still have their invoices not received. But I also need to see the totals so I can match them correctly. Not exactly the ideal way to do AP reconciliation but it is much better than how we currently do it(pseudo-pivot table with supplier and shipper combinations along one side and days of the month along the top and individual tickets as values being added together in each cell).
What I have now is a splitform of the Ticket_Group table with the Ticket subform. I put a sum([qty]) in the footer of the subform and referenced that field in the mainform. This only half works because the total is right in the single form view but the datasheet view displays the selected records total as the total for all records until each individual record has been selected.
I thought maybe an onload event for the form that cycled through every record might work, but I figured there must be a better way.
I am super new with MS Access so I really appreciate the help!
Referring to the Subform-Field can't work because it refers to the actual (selected) record of the mainform.
That's why the Datasheet-View shows the value of the actual selected record of mainform for all records, because there is only one subform with the caclulated field that changes depending on the mainforms record, not a new one for every record of the mainform.
To get the value in the Datasheet-View get it from the tables, not the subform.
E.g. set the Control-Sourceof a TextBpx to:
=DSum("qty","Ticket","TGID = " & Ticket_Group.TGID)
or add the expression to yourForm.RecordSourceas a field like:
Select Ticket_Group.TGID, Ticket_Group.Ticket_Date, ... , DSum("qty","Ticket","TGID = " & Ticket_Group.TGID) as SumQty FROM Ticket_Group
to have the form editable.
Or join
Select TGID, Sum(qty) As SumTicketQty FROM Ticket Group By TGID
with your mainform's query and then bind it to the mainform, but that leads to a readonly query.

track the items that are in the inventory

I have a database that is tracking medical samples, you can think of each sample like a unique serial number.
The design: I have 3 tables (Inventory, InventoryTransactions, Manifests).
please see the attaced photo.
Inventory: has all the items and their properties either we have it right now or had it before, you can think of it as products.
Manifests: It records the transfer of multiple blocks at once from a place to another place and it records the type of movement(Transfer, Sale, Return,Received, Replacement) you can think of it as orders.
(Transfer and Received) mean that this SKU is in the company, but (sale, return, Replacement) mean that this SKU is going outside.
Inventory transaction is the conjunction table between the two tables which relates which SKU is transfered in which Manifest, You can think of it as OrderDetails.
example : we have item 1A we received at manifest m1, then transfered to another warehouse in the company in manifest m2, then sold to a customer in manifest m3.
What I want is that I want to query the items that is in hand right now, In any warehouse of the company, but as you see in my example if the where clause is movement = 'received' or movement = 'transfer')
doesn't give me correct information because the SKU maybe sold later.
I have an idea for a solution: which pulls the latest movement for an SKU and if it's not going outside the company we can assume it's "in" the company. but I think this is a flawed solution.
This is a MS Access Database, but I am familiar with SQL Statements, I want to know how logically this can be achieved.
sorry for my English. I hope I have expressed myself right.
Update: This is My solution
SELECT Inventory.ID, Last(Manifests.MovementID) AS Lmove
FROM Manifests INNER JOIN (Inventory INNER JOIN InventoryTransactions ON Inventory.ID = InventoryTransactions.SKUID) ON Manifests.ID = InventoryTransactions.ManifestID
GROUP BY Inventory.ID
HAVING (((Last(Manifests.MovementID))<>2 And (Last(Manifests.MovementID))<>3 And (Last(Manifests.MovementID))<>5));
where 2,3,5 is the outgoing movements IDs
The expected result is all the items that we received but didn't sell yet.
here some samples from every table
"Inventory"
SKU
TS-15 - 0415-A
"InventoryTransactions"
SKUID ManifestID
TS-15 - 0415-A NHSBC 1316 081915
TS-15 - 0415-A Medimmune (PO # A-20190)
"Manifests"
ID MovementID
NHSBC 1316 081915 Received
Medimmune (PO # A-20190) Sale
In this sample "TS-15 - 0415-A" is received in the manifest "NHSBC 1316 081915" and then sold at the manifest "Medimmune (PO # A-20190)"
the ideal result shouldn't include "TS-15 - 0415-A" i the query because right now it's sold, therefore we don't have it in our inventory.

Suggestions on how to design a sql table to store menu item modifiers?

I've been searching for hours but I guess I can't find the right terms. Say you were making an online ordering system with 6 products and wanted to allow modifiers (some swap ingredients, some add extra to the cost, etc).
My idea right now is to create the products table with the 6 main items. Then I'd create a table for each item that includes the modifiers only for that item.
I'm trying to figure out how to get them stored in a SQL database, and able to be displayed as a receipt.
For Example:
Order # 123512353
##### Item 1 #####
Hamburger $8
---Add Cheese + $1
---No Ketchup
##### Item 2 #####
Hamburger $8
---No Lettuce
TOTAL $17
I plan on using sessions and to allow for up to 12 items per ticket. I just can't figure out how to associate the item modifiers to the items on a per ticket basis.
I believe your model should have 3 tables:
Products
Modifications
Orders
Products is your master list of 6 items (ex: Hamburger, Salad)
Modifications is your 1:N list of potential modifiers (ex: Hamburger:Cheese, Hamburger:Pickles, Salad:Ranch)
Orders is your transaction list (ex: Order 1:Hamburger:Cheese, Order1:Hamburger:Pickles, Order1:Salad:Ranch, Order2:Salad:Italian Dressing, Order3:Hamburger:NULL)
I know the formatting isn't great, but hopefully this makes sense.
edit: You can also take it one step further and break out the Order and Details. In that case, you would have a OrderHeader and OrderDetails table, where the OrderDetails table references back to the Products and Modifications, and the OrderHeader contains the header level info (Customer, Order number, etc.)

Access 2013 SQL to perform linear interpolation where necessary

I have a database in which there are 13 different products, sold in 6 different countries.
Prices increase once a year.
Prices need to be calculated using a linear interpolation method.  I have 21 different price and quantity increments for each product for each country for each year.
The user needs to be able to see how much an order would cost for any given value (as you would expect).
What the database needs to do (in English!) is to:
If there is a matching quantity from TblOrderDetail in the TblPrices,
use the price for the current product, country and year
if there isn't a matching quantity but the quantity required is greater than 1000 for one product (GT) and greater than 100 for every other product:
Find the highest quantity for the product, country and year (so, 1000 or 100, depending on the product), and calculate a pro-rated price.  eg.  If someone wanted 1500 of product GT for the UK for 2015, we'd look at the price for 1000 GT in the UK for 2015 and multiply it by 1.5.  If 1800 were required, we'd multiply it by 1.8.  I haven't been able to get this working yet as I'm looking at it alongside the formula for the next possibility...
If there isn't a matching quantity and the quantity required is less than 1000 for the product GT but 100 for the other products (this is the norm)...
Find the quantity and price for the increment directly below the quantity required by the user for the required product, country and year (let's call these quantitybelow and pricebelow)
Find the quantity and price for the increment directly above the quantity required by the user for the required product, country and year (let's call these quantityabove and priceabove)
Calculate the price for the required number of products for an account holder in a particular country for a given year using this formula.
ActualPrice: PriceBelow + ((PriceAbove - PriceBelow) * (The quantity required in the order detail - QuantityBelow) / (QuantityAbove - QuantityBelow))
I have spent days on this and have sought advice about this before but I am still getting very stuck.
The tables I've been working with to try and make this work are as follows:
TblAccount (primary key is AccountID, it also has a Country field which joins to the TblCountry.Code (primary key)
TblOrders (primary key is Order ID) which joins to TblAccount via the AccountID field; TblOrderDetail via the OrderID.  This table also holds the OrderDate and Recipient ID which links to a person in TblContact - I don't need that here but will need it later to generate an invoice 
TblOrderDetail (primary key is DetailID) which joins to TblOrders via OrderID field; TblProducts via ProductID field, and holds the Quantity required as well as the product
TblProducts (primary key is ProductCode) which as well as joining to TblOrderDetail, also joins to TblPrice via the Product field
TblPrices links to the TblProducts (as you have just read).  I've also created an Alias for the TblCountry (CountryAliasForProductCode) so I can link it to the TblPrices to show the country link. I'm not sure if I needed to do this - it doesn't work if I do or I don't do it, so I seek guidance again here.
This is the code I've been trying to use (and failing) to get my price and quantity steps above and I hope to replicate it, making a couple of tweaks to get the steps below:
SELECT MIN(TblPrices.stepquantity) AS QuantityAbove, MIN(TblPrices.StepPrice) AS PriceAbove, TblOrders.OrderID, TblOrders.OldOrderID, TblOrders.AccountID, TblOrders.OrderDate, TblOrders.RecipientID, TblOrders.OrderStatus, TblOrderDetail.DetailID, TblOrderDetail.Product, TblOrderDetail.Quantity
FROM (TblCountry INNER JOIN ((TblAccount INNER JOIN TblOrders ON TblAccount.AccountID = TblOrders.AccountID) INNER JOIN (TblOrderDetail INNER JOIN TblProducts ON TblOrderDetail.Product = TblProducts.ProductCode) ON TblOrders.OrderID = TblOrderDetail.OrderID) ON TblCountry.Code = TblAccount.Country) INNER JOIN (TblCountry AS CountryAliasForProduct INNER JOIN TblPrices ON CountryAliasForProduct.Code = TblPrices.CountryCode) ON TblProducts.ProductCode = TblPrices.Product
WHERE (StepQuantity >= TblOrderDetails.Quantity)
AND (TblPrices.CountryCode = TblAccount.Country)
AND (TblOrderDetail.Product = TblPrices.Product)
AND (DATEPART('yyyy', TblPrices.DateEffective) = DATEPART('yyyy', TblOrders.OrderDate));
I've also tried...
I've even tried going back to basics and trying again to generate the steps below in 1 query, then try the steps above in another and finally, create the final calculation in another query.
This is what I have been trying to get my prices and quantities below:
SELECT Max(StepQuantity) AS quantity_below, Max(StepPrice) AS price_below, TblOrderDetails.Quantity, TblAccounts.Country
FROM 
(TblProducts INNER JOIN TblPrices ON TblProducts.ProductCode = TblPrices.Product)
(TblOrderDetail INNER JOIN TblProducts ON TblOrderDetail.Product = TblProducts.ProductCode)
(TblOrders INNER JOIN TblOrderDetail ON TblOrders.OrderID = TblOrderDetail.OrderID)
(TblAccount INNER JOIN TblOrders ON TblAccount.AccountID = TblOrders.AccountID),
WHERE (((TblPrices.StepQuantity)<=(TblOrderDetail.Quantity)) AND ((TblPrices.CountryCode)=([TblAccounts].[country])) AND ((TblPrices.Product)=([TblOrderDetail].[product])) AND ((DatePart('yyyy',[TblPrices].[DateApplicable]))=(DatePart('yyyy',[TblOrders].[OrderDate]))));
You may be able to see glaring errors in this but I'm afraid I can't.  I've tried re-jigging it and I'm getting nowhere.
I need to be able to tie the information in to the OrderDetail records as the price generated will need to be added to a financial transactions table as a debit amount and will show as an amount owing on statements.
I'm really not very good at SQL.  I've read and worked though several self-study books and I have asked part of this question before; but I really am struggling with it.  If anyone has any ideas on how to proceed, or even where I've gone wrong with my code, I'd be delighted, even if you tell me I shouldn't be using SQL. For the record, I originally posted this question on a different forum under Visual Basic. Responses from that forum brought me to SQL - however, anything that works would be good!
I've even tried, using Excel, concatenating the Year&Product&Country&Quantity to get a unique product code, interpolating the prices for every quantity between 1 and 1000 for each product, country and year and bringing them into a TblProductsAndPrices table. In Access, I created a query to concatenate the Year(of order date from tblOrders)&Product(of tblorderdetails)&Country(of tblAccount) in order to get the required product code for the order. Another query would find a price for me. However, any product code that doesn't appear on the list (such as where a quantity isn't listed in the tblProductsAndPrices as it is larger than the highest price increment) doesn't have a price.
If there was a workable solution to what I've just described that would generate a price for everything, then I'd be so pleased.
I'd really like to be able to generate an order for any quantity of any product for any account based in any country on any date and retrieve a price which will be used to "debit" a financial account in the database, who in a transaction history for an account and appear on statements. I'd also like to be able to do an ad-hoc price check on the spot.
Thank you very much for taking the time to read this.  I really appreciate it. If you could offer any help or words of encouragement, I'd be very grateful.
Many thanks
Karen
Maybe no one thinks on an easy solution to the problem, since not all minds work in database thinking.
Easy solution: Create one view that gives all calculated values, not only the final one you need, each one as a column. Then you can use such view in a relation view and use on some rows one of the values and on other rows other values, etc.
How to think is simple, think in reverse order, instead of thinking "if that then I need to calculate such else I need this other", think as "I need "such" and I need "this other", both are columns of an intermediate view, then think on top level "if" that would be another view, such view will select the correct value ignoring the rest.
Never ever try to solve all in one step, that can be a really big headache.
Pros: You can isolate calculated values (needed or not), sql is much more easy to write and maintain.
Cons: Resources use is bigger than minimal, but most of times that extra calculated values does not represent a really big impact.
In terms of tutorial out there: Instead of a Top-Down method, use a Down-Top method.
Sometimes it is better (with your example) to calculate all three values (you write sentences on bold) ignoring the if part, and have all three possible values for your order and after that discard the ones not wanted, than trying to only calculate one.
Trying to calculate only one is thinking as a procedural programming, when working with databases most times one must get rid of such thinking and think as reverse, first do the most internal part of such procedural programming to have all data collected, then do the external selection of the procedural programing.
Note: If one of the values can not be calculated, just generate a Null.
I know it is hard to think on First in, last out (Down-Top) model, but it is great for things as the one you want.
Step1 (on specific view, or a join from one view per calculation):
Calculate column 1 as price for the current product, country and
year
Calculate column 2 as calculate a pro-rated price as if 1000
Calculate column 3 as calculate a pro-rated price as if 100
Calculate column 4 as etc
Calculate column N as etc
Step 2 (Another view, the one you want):
Calculate the if part, so you can choose adequate column from previous view (you can use immediately if or a calculated auxiliary field).
Hope you can follow theese way of thinking, I have solved a lot of things like that one (and more complex) thinking in that way, but it is not easy to think as that, needs an extra effort.

Finding the cheapest shop which has all the requested list items

I am currently trying to use pure T-SQL with no additional work done using C# to find the cheapest store match to a list of products.
Finding the cheapest match works well, but my problem is that the found matches (the stores) do not necessarily have all the items in the list.
The tables necessary for this operation are:
Supermarkets - All available supermarkets.
ListItems - A table connecting item lists and products.
AvailProducts - A table that links between a product and a supermarket. If a row does not exist for a certain product ID and supermarket ID, then it means the supermarket does not have this product at all. This is the table which holds the Price for the product.
My current testing SQL statement is supposed to return up to 5 supermarkets which have the wanted products ordered from the cheapest to the most expensive sum, and it looks like this:
SELECT TOP 5 AvailProducts.[SuperID], SUM(AvailProducts.[Price]) AS "Price"
FROM AvailProducts, ListItems, Supermarkets
WHERE ListItems.[ListID]=3
AND AvailProducts.[ProductID]=ListItems.[ProductID]
AND AvailProducts.[SuperID]=Supermarkets.[ID]
AND (SELECT COUNT(*) FROM AvailProducts, ListItems WHERE AvailProducts.[ProductID]=ListItems.[ProductID] AND ListItems.[ListID]=3 AND AvailProducts.[SuperID]=)=(SELECT COUNT(*) FROM ListItems WHERE [ListID]=3)
GROUP BY AvailProducts.[SuperID]
ORDER BY SUM(AvailProducts.[Price])
The third line from the bottom is supposed to count the number of list items that are available in the supermarket and only return the supermarket's ID if the number of list items and the number of available items in this supermarket equal.
However, this does not work, because I cannot specify the current super market's ID in this statement.