====SQL Stored Procedure - QuickBooks Import====
**WARNING:** This is not kids stuff. Use of this feature requires expertise in SQL Server and in the Cyrious database structure. It is very possible to irreversibly damage your Cyrious Control database if you make a mistake. Always develop your tests using a separate database on a separate machine. If you are interested in using sql_bridge but are not a SQL guru, please contact a sales or consulting at Cyrious.
**Note:** This feature requires Control 5.75 or higher.
==== Overview ====
The stored procedure can be used to Import Customers and Orders from a QuickBooks IIF file into Control.
The following values are **required**:
* @ImportPath = 'C:\Users\scott\Accounting\QB Import\',
* @ImportFile = 'TEST.iif',
The following values may be supplied, but will use the default value is not supplied:
* @CustomerNotes - Anything here will appear in the notes for imported customers.
* @OrderStatusID - The status of the imported order. Can be 1 (WIP), 2 (Built), or 3 (Sale)
* @AltFreightProduct - The product code to map all imported Freight to. Leave this blank.
* @DivisionID - Enter the Division.ID for new companies and orders. Omit if you are not using Division.
* @OrderStatusID TINYINT = 1, -- The status of the imported order. Can be 1 (WIP), 2 (Built), or 3 (Sale)
* @OrderStationID INT = NULL, -- The StationID for the Order
* @SaleStationID INT = NULL, -- The Sales StationID fo the Order
* @IsPriceLocked bit = 1, -- Indicates if the order is price locked. 0 = Unlocked, 1 = Locked
* @SuccessSubFolderName VARCHAR(255) = NULL, -- The name of a sub-folder to move the Import file to if all of the import is successful.
The Stored Procedure returns a table of newly creates records (Customers, Contacts, Orders, Line Items).
Notes:
* Payments are NOT Imported. Orders come in with full balance due.
* Taxes are NOT imported but are recomputed when the order is saved.
* However, when importing customers and orders the IsTaxable is set.
* If the Customer or Contact already exist, they are NOT updated.
* If the customer exists but not the contact, just the contact is imported.
* The Recompute can take 2-10 minutes depending on how many orders are
* imported. Until that time, all order totals will be $0.00. You should
* not edit or change the order until it is recomputed.
The stored procedure requires **[[sql_bridge]]** in order to obtain IDs for the inserted records. sql_bridge is a collection of SQL Server stored procedures and functions and external modules that can be called to safely insert or update data into the Control database and notify the CHAPI service that data has been updated. The CHAPI service is a controller program that will then notify the SSLIP and all copies of Control about the changes.
==== Example Usage ====
This imports all Customers and Invoices into Control and sets the orders to Sale.
DECLARE @CustomerNotes VARCHAR(255) = 'Imported from Vivid South on '+CONVERT(VARCHAR(25), GetDate());
EXEC csp_ImportQBIIF_Customers_Orders
-- Define some Input variables
@ImportPath = 'C:\Dat\QB Import\', -- '
@ImportFile = 'Test.iif',
@CustomerNotes = @CustomerNotes,
@DivisionID = 10, -- From Division.ID. (Use 10 if not using divisions!)
@OrderStatusID = 1, -- The status of the imported order. Can be 1 (WIP), 2 (Built), or 3 (Sale)
@AltFreightProduct = 'VS FREIGHT', -- If this is not null, all freight line items will be mapped to this product name.
@IsPriceLocked = 0, -- 0 = Unlocked, 1 = Locked
@SuccessSubFolderName = 'Success' -- moves successfully imported files to this folder if provided
;
==== Stored Procedure ====
The SQL to create the QuickBooks Import Function.
* This must be run to create the stored procedure before it can be used.
* This function also requires two additional SQL procedures found below. They must be run to create those functions before this method can be used.
===csp_ImportQBIIF_Customers_Orders===
-- =============================================
-- Author: Cyrious Sofware
-- Create date: May-2016
-- Description: This stored procedure imports a QuickBooks IIF file with the
-- following information:
--
-- Customer (!CUST)
-- Orders (!TRNS)
-- Line Items (!SPL)
--
-- Notes:
-- ** Payments are NOT Imported. Orders come in with full balance due.
-- ** Taxes are NOT imported but are recomputed when the order is saved.
-- ** However, when importing customers and orders the IsTaxable is set.
--
-- ** If the Customer or Contact already exist, they are NOT updated.
-- ** If the customer exists but not the contact, just the contact is imported.
--
-- ** The Recompute can take 2-10 minutes depending on how many orders are
-- ** imported. Until that time, all order totals will be $0.00. You should
-- ** not edit or change the order until it is recomputed.
--
-- To Enable the File Copy, you must enable SQL to run a command shell.
-- To do this, run the following commands (in order) in SQL Server Management Console.
--
-- ---- To allow advanced options to be changed.
-- EXEC sp_configure 'show advanced options', 1
-- GO
-- ---- To update the currently configured value for advanced options.
-- RECONFIGURE
-- GO
-- ---- To enable the feature.
-- EXEC sp_configure 'xp_cmdshell',1
-- GO
-- ---- To update the currently configured value for this feature.
-- RECONFIGURE
-- GO
--
-- Returns: Table of new records
-- =============================================
ALTER PROCEDURE csp_ImportQBIIF_Customers_Orders
-- The Path and File Name (with extension) is the only required input
@ImportPath VARCHAR(512),
@ImportFile VARCHAR(512),
-- Optional inputs - Leave off for the default value or if they don't apply
@CustomerNotes VARCHAR(4096) = 'Imported from QB',
@OrderStatusID TINYINT = 1, -- The status of the imported order. Can be 1 (WIP), 2 (Built), or 3 (Sale)
@OrderStationID INT = NULL, -- The StationID for the Order
@SaleStationID INT = NULL, -- The Sales StationID fo the Order
@AltFreightProduct VARCHAR(64) = NULL, -- If this is not null, all freight line items will be mapped to this product name.
@IsPriceLocked bit = 1, -- Indicates if the order is price locked. 0 = Unlocked, 1 = Locked
@DivisionID INT = 10, -- Division for new Customers and Orders. From Division.ID. (Leave off if not using divisions!)
@SuccessSubFolderName VARCHAR(255) = NULL, -- The name of a sub-folder to move the Import file to if all of the import is sucecssful.
@StripLeadingCoNumbers bit = 0, -- If set to 1, will remove the number:number from the company name that QuickBooks places there for subsidiaries
@DeveloperMode bit = 0 -- Show addtional information helpful for development
AS
BEGIN
-- Define some variables used in the import
DECLARE @Logs TABLE( ID INT, ClassTypeID INT, ParentID INT, IsError BIT,
Summary VARCHAR(255),
Detail VARCHAR(2000)
);
DECLARE @NewCompanies SMALLINT = 0;
DECLARE @NewContacts SMALLINT = 0;
DECLARE @Neworders SMALLINT = 0;
DECLARE @AccountID INT;
DECLARE @ContactID INT;
DECLARE @THID INT;
DECLARE @OrderNumber INT;
DECLARE @CreateCompany BIT;
DECLARE @CreateContact BIT;
DECLARE @RowID SMALLINT;
DECLARE @CompanyName VARCHAR(128);
DECLARE @WorkPhoneAC VARCHAR(25);
DECLARE @WorkPhoneNumber VARCHAR(25);
DECLARE @BillingAddress1 VARCHAR(256);
DECLARE @BillingAddress2 VARCHAR(256);
DECLARE @BillingCSZ VARCHAR(256);
DECLARE @BillingCity VARCHAR(256);
DECLARE @BillingState VARCHAR(256);
DECLARE @BillingPostalCode VARCHAR(256);
DECLARE @ShippingAddressSameAsBilling BIT;
DECLARE @UseCompanyShippingAddress BIT;
DECLARE @ShippingAddress1 VARCHAR(256);
DECLARE @ShippingAddress2 VARCHAR(256);
DECLARE @ShippingCSZ VARCHAR(256);
DECLARE @ShippingCity VARCHAR(256);
DECLARE @ShippingState VARCHAR(256);
DECLARE @ShippingPostalCode VARCHAR(256);
DECLARE @FirstName VARCHAR(25);
DECLARE @LastName VARCHAR(25);
DECLARE @EmailAddress VARCHAR(50);
DECLARE @AddCellPhone BIT;
DECLARE @CellPhoneAC VARCHAR(10);
DECLARE @CellPhoneNumber VARCHAR(25);
DECLARE @OrderPlacedDate SMALLDATETIME;
DECLARE @OrderNotes VARCHAR(2000);
DECLARE @SalespersonID INT;
DECLARE @RepFirstName VARCHAR(255);
DECLARE @RepLastName VARCHAR(255);
DECLARE @Amount DECIMAL(18,4);
DECLARE @DocNum VARCHAR(255);
DECLARE @OrderDescription VARCHAR(255);
DECLARE @IsTaxExempt BIT;
DECLARE @ShipVia VARCHAR(255);
DECLARE @ShipToCompanyName VARCHAR(255);
DECLARE @Terms VARCHAR(255);
DECLARE @PONumber VARCHAR(255);
DECLARE @OrderDueDate SMALLDATETIME;
DECLARE @TDID INT;
DECLARE @GLAccountName VARCHAR(255);
DECLARE @ProductName VARCHAR(255);
DECLARE @BasePrice DECIMAL(18,4);
DECLARE @Discount DECIMAL(18,4);
DECLARE @Tax DECIMAL(18,4);
DECLARE @Quantity DECIMAL(18,4);
DECLARE @UnitPrice DECIMAL(18,4);
DECLARE @Description VARCHAR(255);
DECLARE @IsFreight BIT;
DECLARE @TaxClassID INT;
DECLARE @TaxClassName VARCHAR(255);
SET NOCOUNT ON;
-- Define some error variables in case we need them
DECLARE @DT SMALLDATETIME = GetDate();
DECLARE @ComputerName VARCHAR(25) = @@ServerName;
DECLARE @NewLine CHAR(2) = CHAR(10)+CHAR(13);
DECLARE @Pos INT = 0;
-- If the Temp Tables we are going to use exist, we need to drop them first
IF (OBJECT_ID('TempDB.dbo.#Temp_IIFFileCols' , 'U') IS NOT NULL) DROP TABLE #Temp_IIFFileCols;
IF (OBJECT_ID('TempDB.dbo.#Temp_IIF_Customers', 'U') IS NOT NULL) DROP TABLE #Temp_IIF_Customers;
IF (OBJECT_ID('TempDB.dbo.#Temp_IIF_Orders' , 'U') IS NOT NULL) DROP TABLE #Temp_IIF_Orders;
IF (OBJECT_ID('TempDB.dbo.#Temp_IIF_Items' , 'U') IS NOT NULL) DROP TABLE #Temp_IIF_Items;
IF (OBJECT_ID('TempDB.dbo.#Temp_IIF_Freight' , 'U') IS NOT NULL) DROP TABLE #Temp_IIF_Freight;
IF (OBJECT_ID('TempDB.dbo.#Temp_IIF_SalesTax' , 'U') IS NOT NULL) DROP TABLE #Temp_IIF_SalesTax;
-- Create the main table for the results
CREATE TABLE #Temp_IIFFileCols (
RowID SMALLINT PRIMARY KEY,
Col01 VARCHAR(2000), Col02 VARCHAR(2000), Col03 VARCHAR(2000), Col04 VARCHAR(2000), Col05 VARCHAR(2000), Col06 VARCHAR(2000), Col07 VARCHAR(2000), Col08 VARCHAR(2000), Col09 VARCHAR(2000), Col10 VARCHAR(2000),
Col11 VARCHAR(2000), Col12 VARCHAR(2000), Col13 VARCHAR(2000), Col14 VARCHAR(2000), Col15 VARCHAR(2000), Col16 VARCHAR(2000), Col17 VARCHAR(2000), Col18 VARCHAR(2000), Col19 VARCHAR(2000), Col20 VARCHAR(2000),
Col21 VARCHAR(2000), Col22 VARCHAR(2000), Col23 VARCHAR(2000), Col24 VARCHAR(2000), Col25 VARCHAR(2000), Col26 VARCHAR(2000), Col27 VARCHAR(2000), Col28 VARCHAR(2000), Col29 VARCHAR(2000), Col30 VARCHAR(2000)
);
-- --------------------------------------------------
-- Upload the IIF File into #Temp_IIFFileCols
-- --------------------------------------------------
IF RIGHT(@ImportPath,1) NOT IN ('/','\') -- 'Need TO ADD a final delimiter IF NOT there
SET @ImportPath = @ImportPath + '/';
-- Now combine the FilePath and Name
SET @ImportFile = @ImportPath + @ImportFile;
-- And run the import routine
INSERT INTO #Temp_IIFFileCols
EXEC csp_ImportTextFileToCols
@FileName = @ImportFile
;
-- --------------------------------------------------
-- Now split the import into the following different temp files
-- --------------------------------------------------
-- #Temp_IIF_Customers;
-- #Temp_IIF_Orders;
-- #Temp_IIF_Items;
-- #Temp_IIF_Freight;
-- #Temp_IIF_SalesTax;
-- Create #Temp_IIF_Customers list
SELECT
-- ID fields looked up or assigned
RowID,
ROW_NUMBER() OVER (ORDER BY RowID) AS CustRowNum,
CONVERT(INT, 0) AS AccountID,
CONVERT(INT, 0) AS ContactID,
-- Straight data fields from IIF File
Col02 AS Name,
Col03 AS BAddr1, -- Always a duplicate of the company name
Col04 AS BAddr2,
Col05 AS BAddr3,
Col06 AS BAddr4,
Col07 AS BAddr5,
Col08 AS SAddr1, -- Always a duplicate of the company name
Col09 AS SAddr2,
Col10 AS SAddr3,
Col11 AS SAddr4,
Col12 AS SAddr5,
Col13 AS Phone1,
Col14 AS Phone2,
Col15 AS FaxNum,
Col16 AS Email,
Col17 AS Cont1,
Col18 AS CType,
Col19 AS Terms,
Col20 AS Taxable,
Col21 AS TaxItem,
Col22 AS ResaleNum,
Col23 AS CompanyName,
Col24 AS CustomerID,
Col25 AS UserID,
-- Derived Fields
(CASE WHEN CHARINDEX(' ',Col17) = 0
THEN Col17
ELSE LEFT(Col17, CHARINDEX(' ',Col17)-1) END
) AS FirstName,
(CASE WHEN CHARINDEX(' ',Col17) = 0
THEN ''
ELSE SUBSTRING(Col17, CHARINDEX(' ',Col17)+1, 99) END
) AS LastName,
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(Col13, ' ', ''), '(', ''), ')', ''), '.', ''), '-', '') AS WorkPhone,
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(Col14, ' ', ''), '(', ''), ')', ''), '.', ''), '-', '') AS CellPhone,
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(Col15, ' ', ''), '(', ''), ')', ''), '.', ''), '-', '') AS FaxNumber,
Col04 AS BillingAddress1,
(CASE WHEN Len(COALESCE(Col06, '')) > 1 THEN COALESCE(Col05, '') ELSE '' END)
+ (CASE WHEN Len(COALESCE(Col07, '')) > 1 THEN @NewLine + COALESCE(Col06, '') ELSE '' END)
AS BillingAddress2,
(CASE WHEN Len(COALESCE(Col07, '')) > 1 THEN Col07
WHEN Len(COALESCE(Col06, '')) > 1 THEN Col06
ELSE Col05 END) AS BillingCSZ,
Col09 AS ShippingAddress1,
(CASE WHEN Len(COALESCE(Col11, '')) > 1 THEN COALESCE(Col10, '') ELSE '' END)
+ (CASE WHEN Len(COALESCE(Col12, '')) > 1 THEN @NewLine + COALESCE(Col11, '') ELSE '' END)
AS ShippingAddress2,
(CASE WHEN Len(COALESCE(Col12, '')) > 1 THEN Col12
WHEN Len(COALESCE(Col11, '')) > 1 THEN Col11
ELSE Col10 END) AS ShippingCSZ
INTO #Temp_IIF_Customers
FROM #Temp_IIFFileCols
WHERE Col01 = 'CUST'
;
-------------------------------------------------------------------
-- Import the Customers
-------------------------------------------------------------------
--
-- Loop through the customer data in the inmport file and create them
--
DECLARE CustomerList CURSOR FOR
SELECT
RowID , -- Unique RowID. used to update the record back
Name , -- CompanyName
LEFT(WorkPhone, 3) , -- WorkPhoneAC
SUBSTRING(WorkPhone, 4, 99) , -- WorkPhoneNumber
BillingAddress1 , -- Billing StreetAddress1
BillingAddress2 , -- Billing StreetAddress2
BillingCSZ , -- Billing City, State, Zip
ShippingAddress1 , -- Shipping StreetAddress1
ShippingAddress2 , -- Shipping StreetAddress2
ShippingCSZ , -- Shipping City, State, Zip
FirstName , -- Contact First Name
LastName , -- Contact Last Name
Email , -- Contact Email
LEFT(CellPhone, 3) , -- Contact CellPhoneAC
SUBSTRING(CellPhone, 4, 99) -- Contact CellPhoneNumber
FROM #Temp_IIF_Customers C;
OPEN CustomerList;
FETCH NEXT FROM CustomerList INTO
@RowID ,
@CompanyName ,
@WorkPhoneAC ,
@WorkPhoneNumber ,
@BillingAddress1 ,
@BillingAddress2 ,
@BillingCSZ ,
@ShippingAddress1 ,
@ShippingAddress2 ,
@ShippingCSZ ,
@FirstName ,
@LastName ,
@EmailAddress ,
@CellPhoneAC ,
@CellPhoneNumber ;
WHILE @@FETCH_STATUS = 0
BEGIN
-- For each customer, create a separate transaction
BEGIN TRANSACTION
BEGIN TRY
PRINT @CompanyName;
-- Remove leading numbers from the CompanyName if desired
IF ((@StripLeadingCoNumbers = 1) AND ( IsNumeric( LEFT(@CompanyName,1) ) =1 ) )
BEGIN
-- Search for Colon and remove up to that if is numeric
SET @Pos = CHARINDEX(':', @CompanyName);
IF ((@Pos>1) AND (@Pos < 10) AND (IsNumeric( LEFT( @CompanyName, @Pos-1 ) ) =1 ) )
SET @CompanyName = RIGHT(@CompanyName, Len(@CompanyName)-@Pos );
-- Search for Space and remove up to that if is numeric
SET @Pos = CHARINDEX(' ', @CompanyName);
IF ((@Pos>1) AND (@Pos < 10) AND (IsNumeric( LEFT( @CompanyName, @Pos-1 ) ) =1 ) )
SET @CompanyName = RIGHT(@CompanyName, Len(@CompanyName)-@Pos );
END;
-- See if the customer exists already
SELECT TOP(1)
@AccountID = A.ID,
@ContactID = A.PrimaryContactID -- use as a default
FROM Account A
WHERE A.CompanyName = @CompanyName;
SET @FirstName = (CASE WHEN COALESCE(@FirstName, '') = '' THEN '.' ELSE @FirstName END);
SET @LastName = (CASE WHEN COALESCE(@LastName , '') = '' THEN '.' ELSE @LastName END);
IF (@AccountID IS NULL)
BEGIN
SET @CreateCompany = 1;
SET @CreateContact = 1;
END
ELSE
BEGIN
SET @CreateCompany = 0;
IF (@FirstName = '.') AND (@LastName = '.')
SET @CreateContact = 0
ELSE
BEGIN
SET @ContactID = (SELECT TOP(1) ID FROM AccountContact
WHERE AccountID = @AccountID
AND FirstName = @FirstName AND LastName = @LastName);
SET @CreateContact = (CASE WHEN @ContactID IS NULL THEN 1 ELSE 0 END);
END;
END;
-- Compute some additional data (which may or may not be needed)
IF (@CreateCompany = 1 OR @CreateContact = 1)
BEGIN
-- Split City/State/Zip
IF ( CHARINDEX(',', @BillingCSZ) > 0)
BEGIN
SET @BillingCity = LEFT(@BillingCSZ, CHARINDEX(',', @BillingCSZ)-1 );
SET @BillingState = SUBSTRING(@BillingCSZ, CHARINDEX(',', @BillingCSZ)+2, 2 );
SET @BillingPostalCode = RIGHT(@BillingCSZ, CHARINDEX(' ', REVERSE(@BillingCSZ))-1 );
END
ELSE
BEGIN
SET @BillingCity = @BillingCSZ;
SET @BillingState = '';
SET @BillingPostalCode = '';
END;
IF ( CHARINDEX(',', @ShippingCSZ) > 0)
BEGIN
SET @ShippingCity = LEFT(@ShippingCSZ, CHARINDEX(',', @ShippingCSZ)-1 );
SET @ShippingState = SUBSTRING(@ShippingCSZ, CHARINDEX(',', @ShippingCSZ)+2, 2 );
SET @ShippingPostalCode = RIGHT(@ShippingCSZ, CHARINDEX(' ', REVERSE(@ShippingCSZ))-1 );
END
ELSE
BEGIN
SET @ShippingCity = @ShippingCSZ;
SET @ShippingState = '';
SET @ShippingPostalCode = '';
END;
SET @AddCellPhone = (CASE WHEN LEN(@CellPhoneNumber) > 1 THEN 1 ELSE 0 END);
SET @ShippingAddressSameAsBilling =
(CASE WHEN (@ShippingAddress1 = '' ) OR
((@ShippingAddress1 = @BillingAddress1)
AND (@ShippingAddress2 = @BillingAddress2)
AND (@ShippingCity = @BillingCity) AND (@ShippingState = @BillingState))
THEN 1
ELSE 0 END);
END;
-- insert the new company record if needed
IF (@CreateCompany = 1)
BEGIN
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
EXEC csp_ImportCompany
-- OUTPUT Variables to Capture the Key
@AccountID = @AccountID OUTPUT,
@ContactID = @ContactID OUTPUT,
-- Input Variables
@CompanyName = @CompanyName,
@WorkPhoneAC = @WorkPhoneAC,
@WorkPhoneNumber = @WorkPhoneNumber,
-- Company Billing Address Info
@BillingAddress1 = @BillingAddress1,
@BillingAddress2 = @BillingAddress2,
@BillingCity = @BillingCity,
@BillingState = @BillingState,
@BillingPostalCode = @BillingPostalCode,
-- Company Shipping Address Info
@ShippingAddressSameAsBilling = @ShippingAddressSameAsBilling,
@ShippingAddress1 = @ShippingAddress1,
@ShippingAddress2 = @ShippingAddress2,
@ShippingCity = @ShippingCity,
@ShippingState = @ShippingState,
@ShippingPostalCode = @ShippingPostalCode,
-- Add other company information
@Notes = @CustomerNotes,
@DivisionID = @DivisionID,
-- Contact #1 Information
@AddContact = 1,
@FirstName = @FirstName,
@LastName = @LastName,
@EmailAddress = @EmailAddress,
@AddCellPhone = @AddCellPhone,
@CellPhoneAC = @CellPhoneAC,
@CellPhoneNumber = @CellPhoneNumber
;
SET @NewCompanies = @NewCompanies + 1;
SET @NewContacts = @NewContacts + 1;
PRINT ' Company and Contact Created';
END
-- insert the new contact record if needed
ELSE IF (@CreateContact = 1)
BEGIN
SET @UseCompanyShippingAddress = (CASE WHEN @ShippingAddress1 = '' THEN 1 ELSE 0 END);
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
EXEC csp_ImportContact
-- OUTPUT Variables to Capture the Key
@ContactID = @ContactID OUTPUT,
-- INPUT Variables
@AccountID = @AccountID,
@FirstName = @FirstName,
@LastName = @LastName,
@EmailAddress = @EmailAddress,
@AddCellPhone = @AddCellPhone,
@CellPhoneAC = @CellPhoneAC,
@CellPhoneNumber = @CellPhoneNumber,
@Notes = @CustomerNotes,
@UseDefaultPhone = 0,
@WorkPhoneAC = @WorkPhoneAC,
@WorkPhoneNumber = WorkPhoneNumber,
@UseCompanyShippingAddress = @UseCompanyShippingAddress,
@ShippingAddress1 = @ShippingAddress1,
@ShippingAddress2 = @ShippingAddress2,
@ShippingCity = @ShippingCity,
@ShippingState = @ShippingState,
@ShippingPostalCode = @ShippingPostalCode
;
SET @NewContacts = @NewContacts + 1;
PRINT ' Company Exists; Contact Created';
END
ELSE
PRINT ' Company and Contact Exist Already';
-- now save the AccountID and ContactID back in the temp table
--
UPDATE #Temp_IIF_Customers
SET AccountID = @AccountID, ContactID = @ContactID
WHERE RowID = @RowID;
-- and reset the variables for the next time
SET @AccountID = NULL;
SET @ContactID = NULL;
-- Make it so, #1
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
VALUES(
@AccountID, 2000, NULL, 1,
'Company '+@CompanyName+' Import FAILED due to Unhandled Exception.',
'Exception: '+ERROR_MESSAGE()
);
END CATCH;
-- Now continue to the next customer
FETCH NEXT FROM CustomerList INTO
@RowID ,
@CompanyName ,
@WorkPhoneAC ,
@WorkPhoneNumber ,
@BillingAddress1 ,
@BillingAddress2 ,
@BillingCSZ ,
@ShippingAddress1 ,
@ShippingAddress2 ,
@ShippingCSZ ,
@FirstName ,
@LastName ,
@EmailAddress ,
@CellPhoneAC ,
@CellPhoneNumber ;
END;
CLOSE CustomerList;
DEALLOCATE CustomerList;
-------------------------------------------------------------------
-- Map the IIF Order Transactions
-------------------------------------------------------------------
-- Create the #Temp_IIF_Orders table for the orders
SELECT
-- ID fields looked up or assigned
RowID,
ROW_NUMBER() OVER (ORDER BY RowID) AS OrderRowNum,
CONVERT(INT, 0) AS THID,
CONVERT(INT, 0) AS AccountID,
CONVERT(INT, 0) AS ContactID,
-- Straight data fields from IIF File
Col02 AS TrnsID,
Col03 AS TrnsType,
CONVERT(DATE, Col04) AS OrderDate ,
Col05 AS Accnt ,
Col06 AS Name ,
Col07 AS Rep ,
Col08 AS Class ,
CONVERT(DECIMAL(18,4), Col09) AS Amount ,
CONVERT(INT, Col10) AS DocNum ,
Col11 AS Memo ,
Col12 AS ShipVia,
(CASE WHEN COALESCE(Col13, '') = '' THEN NULL WHEN Col13 = 'Y' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END) AS Clear ,
(CASE WHEN COALESCE(Col14, '') = '' THEN NULL WHEN Col14 = 'Y' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END) AS ToPrint ,
(CASE WHEN COALESCE(Col15, '') = '' THEN NULL WHEN Col15 = 'Y' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END) AS NameIsTaxable ,
Col16 AS Addr1 ,
Col17 AS Addr2 ,
Col18 AS Addr3 ,
Col19 AS Addr4 ,
Col20 AS SAddr1 ,
Col21 AS SAddr2 ,
Col22 AS SAddr3 ,
Col23 AS SAddr4 ,
Col24 AS Terms ,
Col25 AS PONum ,
CONVERT(DATE, Col26) AS DueDate ,
COl27 AS CustomID,
-- Derived Fields
(CASE WHEN CHARINDEX(' ',Col07) = 0
THEN Col07
ELSE LEFT(Col07, CHARINDEX(' ',Col07)-1) END
) AS RepFirstName,
(CASE WHEN CHARINDEX(' ',Col07) = 0
THEN ''
ELSE SUBSTRING(Col07, CHARINDEX(' ',Col07)+1, 99) END
) AS RepLastName,
Col20 AS ShipToCompanyName,
Col21 AS ShippingAddress1,
(CASE WHEN Len(COALESCE(Col23, '')) > 1 THEN Col22 ELSE '' END) AS ShippingAddress2,
(CASE WHEN Len(COALESCE(Col23, '')) > 1 THEN Col23 ELSE Col22 END) AS ShippingCSZ
INTO #Temp_IIF_Orders
FROM #Temp_IIFFileCols
WHERE Col01 = 'TRNS' AND Col03 = 'INVOICE'
;
-- Now fill in the AccountID and ContactID
-- The only way to match them is by the name and order they are in the file (yuck!)
UPDATE O
SET O.AccountID = C.AccountID,
O.ContactID = C.ContactID
FROM #Temp_IIF_Orders O
JOIN #Temp_IIF_Customers C ON C.CustRowNum = O.OrderRowNum
WHERE O.Name = C.Name -- this line should not be necessary, but a nice safety to have
;
-- We need to map the Tax Items too so that we can look up the tax class for the order
-- -----------------------------------------------------------------
-- Map the IIF Sales Tax Lines
-- -----------------------------------------------------------------
-- Create the #Temp_IIF_SalesTax table for the sales tax
SELECT
RowID,
ROW_NUMBER() OVER (ORDER BY RowID) AS ItemRowNum,
CONVERT(INT, 0) AS THID,
Col02 AS SplID ,
Col03 AS TrnsType ,
CONVERT(DATE, Col04) AS [DATE] ,
Col05 AS Accnt ,
Col06 AS Name ,
Col07 AS Class ,
(CASE WHEN ISNUMERIC(Col08)=1 THEN CONVERT(DECIMAL(18,4), Col08) ELSE NULL END) AS Amount,
CONVERT(INT, Col09) AS DocNum ,
Col10 AS Memo ,
(CASE WHEN COALESCE(Col11, '') = '' THEN NULL WHEN Col11 = 'Y' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END) AS Clear,
(CASE WHEN ISNUMERIC(Col12)=1 THEN CONVERT(DECIMAL(18,4), Col12) ELSE NULL END) AS Qnty,
(CASE WHEN ISNUMERIC(Col13)=1 THEN CONVERT(DECIMAL(18,4), Col13) ELSE NULL END) AS Price,
Col14 AS InvItem,
Col15 AS PayMeth,
(CASE WHEN COALESCE(Col16, '') = '' THEN NULL WHEN Col16 = 'Y' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END) AS Taxable,
Col17 AS ValAdj ,
(CASE WHEN COALESCE(Col18, '') <> '' THEN CONVERT(DATE, Col18) ELSE NULL END) AS ServiceDate,
Col19 AS Extra ,
Col20 AS CustomID
INTO #Temp_IIF_SalesTax
FROM #Temp_IIFFileCols
WHERE (Col01 = 'SPL') AND (Col05 ='Sales Tax Payable')
;
-------------------------------------------------------------------
-- Import the Orders
-------------------------------------------------------------------
--
-- Loop through the order data in the inmport file and create them
--
DECLARE OrderList CURSOR FOR
SELECT
RowID ,
AccountID ,
ContactID ,
DATEADD(HOUR, 12, CONVERT(SmallDateTime, OrderDate)) , -- Place the order time at noon of the day
RepFirstName ,
RepLastName ,
Amount ,
DocNum ,
Memo ,
ShipVia ,
(CASE WHEN NameIsTaxable = 1 THEN 0 ELSE 1 END) AS IsTaxExempt ,
ShipToCompanyName ,
ShippingAddress1 ,
ShippingAddress2 ,
(CASE WHEN CHARINDEX(',', @ShippingCSZ ) > 0 THEN LEFT(@ShippingCSZ, CHARINDEX(',', @ShippingCSZ )-1 ) ELSE @ShippingCSZ END) AS ShippingCity,
(CASE WHEN CHARINDEX(',', @ShippingCSZ ) > 0 THEN SUBSTRING(@ShippingCSZ, CHARINDEX(',', @ShippingCSZ )+2, 2 ) ELSE '' END) AS ShippingState,
(CASE WHEN CHARINDEX(' ', @ShippingCSZ ) > 0 THEN RIGHT(@ShippingCSZ, CHARINDEX(' ', REVERSE(@ShippingCSZ) )-1 ) ELSE '' END) AS ShippingPostalCode,
Terms,
PONum,
DATEADD(HOUR, 16, CONVERT(SMALLDATETIME, DueDate)) -- Place the due time at 4pm
FROM #Temp_IIF_Orders;
OPEN OrderList;
FETCH NEXT FROM OrderList INTO
@RowID ,
@AccountID ,
@ContactID ,
@OrderPlacedDate ,
@RepFirstName ,
@RepLastName ,
@Amount ,
@DocNum ,
@OrderDescription ,
@ShipVia ,
@IsTaxExempt ,
@ShipToCompanyName ,
@ShippingAddress1 ,
@ShippingAddress2 ,
@ShippingCity ,
@ShippingState ,
@ShippingPostalCode ,
@Terms ,
@PONumber ,
@OrderDueDate
;
WHILE @@FETCH_STATUS = 0
BEGIN
-- For each customer, create a separate transaction
BEGIN TRANSACTION
BEGIN TRY
PRINT @DocNum;
-- Look up or fix up some fields
SET @OrderDescription = 'VIG South #'+CONVERT(VARCHAR(12), @DocNum)+
(CASE WHEN @OrderDescription = '' THEN '' ELSE ' : '+@OrderDescription END);
SET @SalespersonID = COALESCE( (SELECT ID FROM Employee WHERE FirstName = @RepFirstName AND LastName = @RepLastName), 10);
SET @OrderNotes = 'Reference Vivid South Order #'+CONVERT(VARCHAR(12), @DocNum);
-- Lookup the Tax Class from the #Temp_IIF_SalesTax table
SET @TaxClassName = (SELECT TOP(1) InvItem FROM #Temp_IIF_SalesTax WHERE DocNum = @DocNum );
SET @TaxClassID = dbo.csf_MapTaxClassByName(@TaxClassName);
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
EXEC csp_ImportOrder
-- OUTPUT Variables to Capture the Key
@THID = @THID OUTPUT,
-- Input Variables
@AccountID = @AccountID,
@ContactID = @ContactID,
@DivisionID = @DivisionID,
@OrderDescription = @OrderDescription, -- The description of the order
@OrderPlacedDate = @OrderPlacedDate, -- The create date *AND TIME* of the order. Leave blank to use current date and time
@OrderBuiltDate = @DT,
@OrderSaleDate = @DT,
@OrderDueDate = @OrderDueDate, -- The create date *AND TIME* of the order. Leave blank to use current date and time
@OrderNotes = @OrderNotes,
@OrderProductionNotes= NULL,
@OrderStationID = @OrderStationID,
@SaleStationID = @SaleStationID,
@OriginalOrderNumber = @DocNum, -- Pass the original order number
@Salesperson1ID = @SalespersonID,
@PONumber = @PONumber,
@IsTaxExempt = @IsTaxExempt,
@TaxClassID = @TaxClassID,
-- Shipping Address Info
@IsShipped = 0,
--@UseOneTimeShippingAddress = 1, -- Set to 1 if adding a new shiping address. This address is then added as a one-time use address.
--@ShippingAddress1 = @ShippingAddress1,
--@ShippingAddress2 = @ShippingAddress2,
--@ShippingCity = @ShippingCity,
--@ShippingState = @ShippingState,
--@ShippingPostalCode = @ShippingPostalCode,
--@ShippingNotes = NULL, -- Shipping notes
-- Other configuration fields
@StatusID = @OrderStatusID,
@RecomputeOnSave = 0,
@RefreshOnSave = 0,
@IsPriceLocked = @IsPriceLocked,
@IsServiceTicket = 0
;
SET @NewOrders = @NewOrders + 1;
PRINT ' Order Created';
-- now save the THID back in the temp table
--
UPDATE #Temp_IIF_Orders
SET THID = @THID
WHERE RowID = @RowID;
-- Make it so, #1
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
VALUES(
@THID, 10000, @AccountID, 1,
'Original Order '+CONVERT(VARCHAR(12),@DocNum)+' Import FAILED due to Unhandled Exception.',
'Exception: '+ERROR_MESSAGE()
);
END CATCH;
-- Now continue to the next order
FETCH NEXT FROM OrderList INTO
@RowID ,
@AccountID ,
@ContactID ,
@OrderPlacedDate ,
@RepFirstName ,
@RepLastName ,
@Amount ,
@DocNum ,
@OrderDescription ,
@ShipVia ,
@IsTaxExempt ,
@ShipToCompanyName ,
@ShippingAddress1 ,
@ShippingAddress2 ,
@ShippingCity ,
@ShippingState ,
@ShippingPostalCode ,
@Terms ,
@PONumber ,
@OrderDueDate
END;
CLOSE OrderList;
DEALLOCATE OrderList;
-------------------------------------------------------------------
-- Map the IIF Line Items Transactions (non-shipment and sales tax)
-------------------------------------------------------------------
-- Create #Temp_IIF_Items temp table for the line items
SELECT
-- ID fields looked up or assigned
RowID,
ROW_NUMBER() OVER (ORDER BY RowID) AS ItemRowNum,
CONVERT(INT, 0) AS THID,
-- Straight data fields from IIF File
Col02 AS SplID ,
Col03 AS TrnsType ,
CONVERT(DATE, Col04) AS OrderDate,
Col05 AS Accnt ,
Col06 AS Name ,
Col07 AS Class ,
(CASE WHEN ISNUMERIC(Col08)=1 THEN CONVERT(DECIMAL(18,4), Col08) ELSE NULL END) AS Amount,
CONVERT(INT, Col09) AS DocNum ,
Col10 AS Memo ,
(CASE WHEN COALESCE(Col11, '') = '' THEN NULL WHEN Col11 = 'Y' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END) AS Clear,
(CASE WHEN ISNUMERIC(Col12)=1 THEN CONVERT(DECIMAL(18,4), Col12) ELSE NULL END) AS Qnty,
(CASE WHEN ISNUMERIC(Col13)=1 THEN CONVERT(DECIMAL(18,4), Col13) ELSE NULL END) AS Price,
Col14 AS InvItem,
Col15 AS PayMeth,
(CASE WHEN COALESCE(Col16, '') = '' THEN NULL WHEN Col16 = 'Y' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END) AS Taxable,
Col17 AS ValAdj,
(CASE WHEN COALESCE(Col18, '') <> '' THEN CONVERT(DATE, Col18) ELSE NULL END) AS ServiceDate,
Col19 AS Extra,
Col20 AS CustomID
INTO #Temp_IIF_Items
FROM #Temp_IIFFileCols
WHERE (Col01 = 'SPL') AND (Col05 <> 'Sales Tax Payable')
;
-- Now fill in the THID by matching on the DocNum
UPDATE #Temp_IIF_Items
SET THID = (SELECT O.THID
FROM #Temp_IIF_Orders O
WHERE O.DocNum = #Temp_IIF_Items.DocNum ) ;
-------------------------------------------------------------------
-- Import the Line Items
-------------------------------------------------------------------
--
-- Loop through the line item data in the import file and create them
--
DECLARE ItemList CURSOR FOR
SELECT
RowID ,
THID ,
Accnt AS GLAccountName ,
-Amount AS BasePrice ,
DocNum ,
Memo AS Description ,
-Qnty AS Quantity ,
Price AS UnitPrice ,
InvItem AS ProductName ,
(CASE WHEN Taxable = 1 THEN 0 ELSE 1 END) AS IsTaxExempt,
(CASE WHEN Accnt = 'Freight Income' THEN 1 ELSE 0 END) AS IsFreight
FROM #Temp_IIF_Items
WHERE THID IS NOT NULL; -- Don't import if no THID, since that means Order Failed
OPEN ItemList;
FETCH NEXT FROM ItemList INTO
@RowID ,
@THID ,
@GLAccountName ,
@BasePrice ,
@DocNum ,
@Description ,
@Quantity ,
@UnitPrice ,
@ProductName ,
@IsTaxExempt ,
@IsFreight
;
WHILE @@FETCH_STATUS = 0
BEGIN
-- For each customer, create a separate transaction
BEGIN TRANSACTION
BEGIN TRY
-- If Freight, check if we need to map freight to another field
IF (@IsFreight=1)
BEGIN
-- Check if we need to map freight to another field
SET @ProductName = COALESCE(@AltFreightProduct, @ProductName);
END;
-- And set a quantity since it is usually 0
IF (COALESCE(@Quantity,0) = 0) SET @Quantity = 1;
-- Now create the line items
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
EXEC csp_ImportLineItem
-- OUTPUT Variables to Capture the Key
@TDID = @TDID OUTPUT,
-- Input Variables
@THID = @THID,
@ProductName = @ProductName,
@Quantity = @Quantity,
@BasePrice = @BasePrice,
@BasePriceOV = 1,
-- @Discount = 0.0,
-- @Tax = 0.0,
@Description = @Description, -- The description of the order
@ProductionNotes = 'Imported from Vivid South',
-- Other configuration fields
@RecomputeOnSave = 0,
@RefreshOnSave = 0,
@AddJournal = 0,
@StationID = NULL
;
PRINT ' Item Created';
-- Make it so, #1
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
SET @OrderNumber = (SELECT OrderNumber FROM TransHeader WHERE ID = @THID);
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
VALUES(
NULL, 10100, @THID, 1,
'Line Item '+@ProductName+' Import for Order #'+CONVERT(VARCHAR(12),@OrderNumber)+' FAILED due to Unhandled Exception.',
'Exception: '+ERROR_MESSAGE()
);
END CATCH;
-- Now continue to the next Item
FETCH NEXT FROM ItemList INTO
@RowID ,
@THID ,
@GLAccountName ,
@BasePrice ,
@DocNum ,
@Description ,
@Quantity ,
@UnitPrice ,
@ProductName ,
@IsTaxExempt ,
@IsFreight ;
END;
CLOSE ItemList;
DEALLOCATE ItemList;
-------------------------------------------------------------------
-- Map the IIF Sales Tax Lines
-------------------------------------------------------------------
-- -- Create the #Temp_IIF_SalesTax table for the sales tax
-- SELECT
-- RowID,
-- ROW_NUMBER() OVER (Order by RowID) AS ItemRowNum,
-- CONVERT(INT, 0) AS THID,
--
-- Col02 AS SplID ,
-- Col03 AS TrnsType ,
-- convert(Date, Col04) AS [Date] ,
-- Col05 AS Accnt ,
-- Col06 AS Name ,
-- Col07 AS Class ,
-- (case when ISNUMERIC(Col08)=1 THEN convert(DECIMAL(18,4), Col08) ELSE NULL END) AS Amount,
-- convert(INT, Col09) AS DocNum ,
-- Col10 AS Memo ,
-- (case when Coalesce(Col11, '') = '' then NULL when Col11 = 'Y' then convert(bit, 1) else convert(bit, 0) end) AS Clear,
-- (case when ISNUMERIC(Col12)=1 THEN convert(DECIMAL(18,4), Col12) ELSE NULL END) AS Qnty,
-- (case when ISNUMERIC(Col13)=1 THEN convert(DECIMAL(18,4), Col13) ELSE NULL END) AS Price,
-- Col14 AS InvItem,
-- Col15 AS PayMeth,
-- (case when Coalesce(Col16, '') = '' then NULL when Col16 = 'Y' then convert(bit, 1) else convert(bit, 0) end) AS Taxable,
-- Col17 AS ValAdj ,
-- (case when Coalesce(Col18, '') <> '' then convert(date, Col18) else NULL end) AS ServiceDate,
-- Col19 AS Extra ,
-- Col20 AS CustomID
-- INTO #Temp_IIF_SalesTax
-- FROM #Temp_IIFFileCols
-- WHERE (Col01 = 'SPL') AND (Col05 ='Sales Tax Payable')
-- ;
-- Now fill in the THID by matching on the DocNum
-- Update #Temp_IIF_SalesTax
-- SET THID = (SELECT O.THID
-- FROM #Temp_IIF_Orders O
-- WHERE O.DocNum = #Temp_IIF_SalesTax.DocNum ) ;
-------------------------------------------------------------------
-- Import the Sales Tax
-------------------------------------------------------------------
--
-- FUTURE TASK (if required)
--
-------------------------------------------------------------------
-- Now Loop Through and RECOMPUTE all the orders
-------------------------------------------------------------------
DECLARE RecomputeList CURSOR FOR
SELECT
RowID,
THID
FROM #Temp_IIF_Orders
WHERE THID IS NOT NULL; -- Don't recompute if no THID, since that means Order Failed
OPEN RecomputeList;
FETCH NEXT FROM RecomputeList INTO
@RowID ,
@THID
;
WHILE @@FETCH_STATUS = 0
BEGIN
-- For each customer, create a separate transaction
BEGIN TRY
SET @OrderNumber = (SELECT OrderNumber FROM TransHeader WHERE ID = @THID);
PRINT @THID;
EXEC dbo.csf_chapi_recompute @THID, 10000, 'Recompute on Import';
PRINT ' Order Recomputed';
END TRY
BEGIN CATCH
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
VALUES(
@THID, 10100, NULL, 1,
'Exception in RECOMPUTE',
'Exception in RECOMPUTE: '+ERROR_MESSAGE()
);
END CATCH;
-- Now continue to the next order
FETCH NEXT FROM RecomputeList INTO
@RowID ,
@THID ;
END;
CLOSE RecomputeList;
DEALLOCATE RecomputeList;
-------------------------------------------------------------------
---- Move the Outut File if we are all successful and a path is given
-------------------------------------------------------------------
--
-- Note: This requires that the
IF (@SuccessSubFolderName IS NOT NULL) AND NOT EXISTS(SELECT 1 FROM @Logs WHERE IsError = 1)
BEGIN
DECLARE @CMD VARCHAR(512) =
'MOVE "' + @ImportFile + '" "' + @ImportPath + @SuccessSubFolderName + '"';
DECLARE @MoveResults TABLE(VALUE VARCHAR(255));
INSERT INTO @MoveResults
EXEC XP_CMDSHELL @CMD;
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
SELECT NULL, NULL, NULL, 0,
'Import File Moved',
'Import File moved from "' + @ImportFile + '" to "' + @ImportPath + @SuccessSubFolderName + ''' : '+VALUE
FROM @MoveResults
WHERE VALUE IS NOT NULL;
END;
-------------------------------------------------------------------
---- Output an Informational Summary of Results
-------------------------------------------------------------------
--
IF (@DeveloperMode = 1)
BEGIN
SELECT (CASE WHEN IsError = 1 THEN 'ERROR' ELSE 'Information' END) AS [Message TYPE], *
FROM @Logs
ORDER BY IsError DESC, ClassTypeID, COALESCE(ParentID, ID);
SELECT * FROM #Temp_IIF_Customers;
SELECT * FROM #Temp_IIF_Orders;
SELECT * FROM #Temp_IIF_Items;
END
ELSE
BEGIN
SELECT (CASE WHEN IsError = 1 THEN 'ERROR' ELSE 'Information' END) AS [Message TYPE],
Summary, ParentID, ID, ClassTypeID, Detail
FROM @Logs
ORDER BY IsError DESC, ClassTypeID, COALESCE(ParentID, ID);
END;
END;
==== Source ====
Contributor: Cyrious Software\\
Date: 5/2016\\
Version: Control 5.7+\\