Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Onamuji
Aged Yak Warrior
504 Posts |
Posted - 2002-01-10 : 10:16:49
|
For our purchase order system we want to specify a set of workflow for the following variations... - cost center charged by the PO if the is no appropriations request (ar)- purchase order type (planned, unplanned, budgeted, etc)- catalog item categories (each catalog belongs to a master set or is a child of the master set (Desktop, ESS, Telecom, Other, Hardware, Software)- True|False (based on if an AR is entered in the PO)- PO item total (sum(quantity * unitprice)) - Compare type (<=, <, >=, >, =, !=) The top set is pretty easy to go through, the point i'm having problems (logically) is deciding how to find the default workflow for the compare type. I guess I could define a logical order but I'm hoping that someone else can help me. Here's what I have so far:CREATE TABLE dbo.PurchaseOrderDefaultWorkflows ( PurchaseOrderDefaultWorkflowID INT NOT NULL IDENTITY, Step INT NOT NULL CHECK(Step > 0), LogonUser VARCHAR(255) NOT NULL CHECK(LEN(LogonUser) > 0), CostCenterID INT NULL, CategoryID INT NULL, POTypeID INT NULL, AttachedAR BIT NOT NULL DEFAULT 0, TotalLimit MONEY NOT NULL DEFAULT 0.0000, TotalLimitCompare VARCHAR(2) NOT NULL DEFAULT '<=',) CREATE PROCEDURE GeneratePOWorkflow @po INT ASSET NOCOUNT ON DECLARE @ar BIT DECLARE @cc INT DECLARE @pt INT DECLARE @t MONEY DECLARE @cat INT DECLARE @mcat INT DECLARE @categories TABLE (catid INT) DECLARE @workflow TABLE (step INT, logonuser VARCHAR(255)) -- Get the basic information SELECT @ar = CASE WHEN ARID IS NULL THEN 0 ELSE 1 END, @cc = CostCenterID, @pt = TypeID FROM PurchaseOrders WHERE ID = @po -- If an AR is entered don't require cost center IF @ar = 1 SET @cc = NULL -- Get total of items SELECT @t = SUM(Quantity * UnitPrice) FROM PurchaseOrderItems WHERE PurchaseOrderID = @po -- Get all distinct categories from items INSERT INTO @categories SELECT CategoryID FROM PurchaseOrderItems poi INNER JOIN CatalogItems ci ON poi.CatalogItemID = ci.CatalogItemID WHERE poi.PurchaseOrderID = @po -- For each category find the default workflow and insert WHILE (SELECT COUNT(*) FROM @categories) > 0 BEGIN -- Select a category SELECT @cat = catid FROM @categories -- Find master category SELECT @mcat = dbo.fn_MasterCatalogCategory(@cat) -- This is where I need to add some good logic, this function -- Returns 1 or 0 depending on if it can find a workflow for the set -- See below for continuation... SELECT dbo.fn_HasDefaultPurchaseOrderWorkflow(@cc, @mcat, @pt, @ar, '<=', @t) -- Delete from categories list DELETE FROM @categories WHERE catid = @cat END Now I'm guessing I could just do every compare type but I want to select the best fitting one, for example there could be a compare set like the following: (<= 500.00) and one for (<= 8000.00) and one for (> 500.00) ... how can I limit this... obviously if my PO total was 500 < x <= 8000 both the workflows should be included logically I guess I want to pick the closest matching one where the difference between the two is the smallest. Another possibility is to havex < 500 < 8000 which would result in the workflow for 8000 being included but I only want to include the one from 500. Oh and there are times when the value will be 0.00 in the total column which will mean if no other workflow is found for that set to include that workflow.Any helps, suggestions are gladly welcomed. If you see anything in my code that could be enhanced let me know :-) <update>Here's the fn_HasDefaultPurchaseOrderWorkflow function .. it needs to be modified to handle the different value and compare types right now it just looks for an exact match.CREATE FUNCTION dbo.fn_HasDefaultPurchaseOrderWorkflow ( @CostCenterID INT, @CategoryID INT, @TypeID INT, @AttachedAR BIT, @LimitCompare VARCHAR(2), @Limit MONEY) RETURNS BIT AS BEGIN DECLARE @rc BIT IF EXISTS(SELECT PurchaseOrderDefaultWorkflowID FROM PurchaseOrderDefaultWorkflows WHERE (CostCenterID = @CostCenterID OR (@CostCenterID IS NULL AND CostCenterID IS NULL)) AND (CategoryID = @CategoryID OR (@CategoryID IS NULL AND CategoryID IS NULL)) AND (POTypeID = @TypeID OR (@TypeID IS NULL AND POTypeID IS NULL)) AND (AttachedAR = @AttachedAR) AND (TotalLimit = @Limit) AND (TotalLimitCompare = @LimitCompare)) SET @rc = 1 ELSE SET @rc = 0 RETURN @rc END </update> Thanks!Edited by - onamuji on 01/10/2002 10:32:42 |
|
|
Onamuji
Aged Yak Warrior
504 Posts |
Posted - 2002-01-10 : 11:58:18
|
So the solution for the time being is this, select the closet value and it's compare operator, then see if the compare operator selected it valid, if not remove it from the list and try again. INSERT INTO @wf (total, compare) SELECT DISTINCT TotalLimit, TotalLimitCompare FROM PurchaseOrderDefaultWorkflows WHERE (CostCenterID = @cc OR (@cc IS NULL AND CostCenterID IS NULL)) AND (CategoryID = @mcat OR (@mcat IS NULL AND CategoryID IS NULL)) AND (POTypeID = @pt OR (@pt IS NULL AND POTypeID IS NULL)) AND (AttachedAR = @ar)FindWorkflow3: SELECT @total = total, @compare = compare FROM @wf WHERE ABS(total - @t) = (SELECT MIN(ABS(total - @t)) FROM @wf) AND total <> 0 SELECT @use = CASE @compare WHEN '<=' THEN CASE WHEN @t <= @total THEN 1 ELSE 0 END WHEN '>=' THEN CASE WHEN @t >= @total THEN 1 ELSE 0 END WHEN '<' THEN CASE WHEN @t < @total THEN 1 ELSE 0 END WHEN '>' THEN CASE WHEN @t > @total THEN 1 ELSE 0 END WHEN '=' THEN CASE WHEN @t = @total THEN 1 ELSE 0 END WHEN '!=' THEN CASE WHEN @t <> @total THEN 1 ELSE 0 END END IF (@use = 1) BEGIN INSERT INTO @workflow SELECT Step, LogonUser FROM dbo.fn_DefaultPurchaseOrderWorkflow(@cc, @mcat, @pt, @ar, @compare, @total) END ELSE BEGIN DELETE FROM @wf WHERE total = @total AND compare = @compare IF (SELECT COUNT(*) FROM @wf) > 0 BEGIN GOTO FindWorkflow3 END END I know, dear god I used a GOTO ... first time in ages but it suited the purpose quite fine, what's the status of GOTO in T-SQL code? is it ok to use?Thanks!- Onamuji |
 |
|
|
|
|
|
|
|