<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wikido.isoftdata.com//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ghagemoser</id>
	<title>ISoft Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wikido.isoftdata.com//api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ghagemoser"/>
	<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=Special:Contributions/Ghagemoser"/>
	<updated>2026-04-28T14:30:33Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.37.2</generator>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15045</id>
		<title>Configuring a barcode scanner</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15045"/>
		<updated>2025-10-01T14:57:59Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* Windows 11 Industrial Rugged Tablet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Zebra DS2278=&lt;br /&gt;
&lt;br /&gt;
This page will cover how to setup a Zebra DS2278 Bluetooth Barcode Scanner to work with iSoft products on mobile devices.&lt;br /&gt;
&lt;br /&gt;
==Scanner Info==&lt;br /&gt;
* Approx Cost: $190-$280 depending on accessories and support&lt;br /&gt;
* Important Features: Bluetooth, 14 hour+ battery life, 5ft drop, 36 month warranty, 123Scan app, SDKs for iOS, Android, Windows&lt;br /&gt;
&lt;br /&gt;
==Quick Start Guide==&lt;br /&gt;
===Android using Chrome===&lt;br /&gt;
* The fastest way to get started is to scan the appropriate barcode for your device type. **Make sure your device is fully charged!&lt;br /&gt;
* This model of scanner can scan from a high resolution monitor or screen &lt;br /&gt;
* Each of the barcodes below will change the defaults on your scanner.  You will need to &amp;quot;forget&amp;quot; or &amp;quot;remove&amp;quot; the device in your Bluetooth settings and reconnect&lt;br /&gt;
* The below barcodes have the following settings: &amp;#039;&amp;#039;&amp;#039;Prefix : Suffix $&amp;#039;&amp;#039;&amp;#039;, HID features for iOS, Host: HID BT Classic&lt;br /&gt;
[[Image:AndroidBarcode.JPG]]&lt;br /&gt;
&lt;br /&gt;
===iOS using ITrack LX App===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Tip: You do not need to set up this device as a keyboard wedge&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1. You first need to install the Zebra iOS app https://apps.apple.com/us/app/zebra-scanner-control/id1034012069&lt;br /&gt;
&lt;br /&gt;
2. Open that app and go to Connection Help &amp;gt; Pair DS2278&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-setup-barcodes.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Follow the onscreen instructions&lt;br /&gt;
&lt;br /&gt;
4. Go back to the main screen and choose Connect&lt;br /&gt;
&lt;br /&gt;
5. Tap on the DS2278 and choose Disconnect(this will disconnect it from the Zebra app so we can connect it to the ITrack LX app)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-disconnect-screen.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
6. Go to the ITrack LX app and after a few seconds you should hear a connection beep from the scanner. Scanning in the ITrack LX app with the DS2278 should now work.&lt;br /&gt;
&lt;br /&gt;
==Charging the Scanner==&lt;br /&gt;
* The charging circuit on the scanner is capable of using as much current as possible based on the power source&lt;br /&gt;
* Preferred Method: use a BC1.2 Compliant Micro USB adapter to a wall outlet (higher current charging capability above 900 mA)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra_battery.JPG]]&lt;br /&gt;
&lt;br /&gt;
==123Scan Software==&lt;br /&gt;
&lt;br /&gt;
==Explanation of Settings==&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* Zebra Support Page [https://www.zebra.com/us/en/support-downloads/scanners/general-purpose-scanners/ds2200-series.html link]&lt;br /&gt;
* 123Scan Software Download [https://www.zebra.com/us/en/products/software/scanning-systems/123scan.html link]&lt;br /&gt;
* Full Manual Download [https://www.zebra.com/content/dam/zebra_new_ia/en-us/manuals/barcode-scanners/ds2278-prg-en.pdf link]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Honeywell=&lt;br /&gt;
&lt;br /&gt;
== Compatibility Notes ==&lt;br /&gt;
Please update the Chrome browser on the Honeywell to Chrome v101 so that the Teardown app is sized correctly. It currently ships with Chrome v70. -JW 2022-05-18&lt;br /&gt;
&lt;br /&gt;
== Setting up a Honeywell Scanner ==&lt;br /&gt;
ScanPal EDA71  &lt;br /&gt;
https://www.honeywellaidc.com/products/computer-devices/tablet/scanpaleda71&lt;br /&gt;
&lt;br /&gt;
These are the screens you set through to set up the honeywell device&lt;br /&gt;
&lt;br /&gt;
Settings -&amp;gt; Honeywell Settings -&amp;gt; Scan Settings -&amp;gt; Internal Scanner -&amp;gt; Default profile -&amp;gt; Data Processing Settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wedge = checked&lt;br /&gt;
&lt;br /&gt;
Wedge Method = Keyboard&lt;br /&gt;
&lt;br /&gt;
no Prefix&lt;br /&gt;
&lt;br /&gt;
no Suffix&lt;br /&gt;
&lt;br /&gt;
Wedge as keys = empty input&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart_of_settings.jpg|800px|thumb|center|Honeywell Setting Flowchart]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enterprise LX Honeywell config info ==&lt;br /&gt;
&lt;br /&gt;
A global database setting &amp;quot;Scanner Mode (ambleMode,honeywell)&amp;quot; needs to be set to &amp;quot;honeywell&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The current default is ambleMode which may change in the near future.&lt;br /&gt;
The following query will let you check on the setting.   Note: A user has to have logged into an lx app before the default settings are present. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
   `globalsettingvalue`.`settingid`&lt;br /&gt;
    , `setting`.`location`&lt;br /&gt;
    , `setting`.`name`&lt;br /&gt;
    , `globalsettingvalue`.`value`&lt;br /&gt;
    , `setting`.`defaultvalue`&lt;br /&gt;
    , `setting`.`scope`&lt;br /&gt;
    , `setting`.`settingtype`&lt;br /&gt;
    , `value`=`defaultvalue` AS isdefault&lt;br /&gt;
FROM&lt;br /&gt;
    `globalsettingvalue`&lt;br /&gt;
    INNER JOIN `setting` &lt;br /&gt;
        ON (`globalsettingvalue`.`settingid` = `setting`.`settingid`)&lt;br /&gt;
WHERE (`setting`.`name` = &amp;#039;Scanner Mode (ambleMode,honeywell)&amp;#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Munbyn=&lt;br /&gt;
&lt;br /&gt;
== Setting up a Munbyn Scanner ==&lt;br /&gt;
This is for the MUNBYN IPDA081/IPDA086 Mobile Data Terminal: https://pos.munbyn.com/munbyn-ipda081-rfid-handheld-computer/&amp;lt;br&amp;gt;&lt;br /&gt;
To set up:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Swipe up to see apps, then tap on &amp;quot;keyboardemulator&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;Function&amp;quot; page, make sure &amp;quot;Enable Scanner&amp;quot; is on.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner1.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;AppSettings&amp;quot; page, turn on &amp;quot;Release key off scan&amp;quot; (if it is not already enabled).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner2.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Then scroll down to &amp;quot;Process mode&amp;quot;. Make sure it is set to &amp;quot;keyboard input&amp;quot;. Under &amp;quot;End mark&amp;quot;, none of the options should be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner3.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Prefix/preamble and suffix/postamble for the device can be edited under &amp;quot;Data Format&amp;quot;. If using a test program that uses prefix/suffix, be sure that the prefix/suffix in the program and in the scanner setting app (keyboardemulator) are the same.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner4.png|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tera Scanner =&lt;br /&gt;
[[File:Tera_config.png|200px]]&lt;br /&gt;
&lt;br /&gt;
To enable the trigger on the Tera scanner handle:&lt;br /&gt;
&lt;br /&gt;
1. Get to the Scanner Config Page. &lt;br /&gt;
&lt;br /&gt;
2. Disable the scanner.&lt;br /&gt;
&lt;br /&gt;
3. Key in 293 on the scanner keypad.&lt;br /&gt;
&lt;br /&gt;
4. Re-enable the scanner.&lt;br /&gt;
&lt;br /&gt;
5. The scanner config page should look like the image above if it&amp;#039;s set correctly.&lt;br /&gt;
&lt;br /&gt;
== Windows 11 Industrial Rugged Tablet ==&lt;br /&gt;
Two additional applications are required to use the scanner features: Honeywell Download manager tool (which will manage any subsequent Honeywell software downloads), then an EZConfig for Scanning software for the configuration of scanner itself. Both parts can be downloaded from the same portal: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the zip file containing the Honeywell Download manager tool, select &amp;quot;here&amp;quot; marked by the first arrow. When finished, right-click the zip file selecting &amp;quot;Extract all...&amp;quot; then select a home/path for this installer.&lt;br /&gt;
&lt;br /&gt;
To download the EZConfig for Scanning, in the file system on the left: Software -&amp;gt; Barcode Scanner -&amp;gt; Software -&amp;gt; Tools and Utilities -&amp;gt; EZConfig for Scanning -&amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Open the EZConfig for Scanning software when it&amp;#039;s finished downloading. &lt;br /&gt;
# Open the file &amp;quot;EZConfig-Scanning v4_msedge&amp;quot;&lt;br /&gt;
# select &amp;quot;Connected Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Configure Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Data Formatting&amp;quot;&lt;br /&gt;
# in Data Formatting, verify that you are on the &amp;quot;Prefix/Suffix&amp;quot; tab&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
&lt;br /&gt;
This may be out-dated. &lt;br /&gt;
&lt;br /&gt;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;
&lt;br /&gt;
Instead of using EZConfig, we need to use another Honeywell tool named SoftWedge. It can be downloaded from the same link as the download manager and EZConfig: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the SoftWedge zip file you will need to navigate the Honeywell file system on the left when you open the link: Software &amp;gt; Barcode Scanners &amp;gt; Software &amp;gt; Tools and Utilities &amp;gt; Softwedge &amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Unzip the SoftWedge folder&lt;br /&gt;
# Open and read the PDF instructions in the folder&lt;br /&gt;
# Run SoftWedge.exe, it will pop up in the system tray&lt;br /&gt;
# Open up SoftWedge and verify the &amp;quot;port status&amp;quot; is connected&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
# Verify things are working by doing test scans in Chromium/EEweb Configuration-&amp;gt;Scanner-&amp;gt;Test Scanner&lt;br /&gt;
&lt;br /&gt;
== NOTE on ENTERPRISE LX setup ==&lt;br /&gt;
enterpise lx  default pre/postable&lt;br /&gt;
preamble = &amp;quot;126&amp;quot;    = &amp;quot;~&amp;quot;&lt;br /&gt;
postamble = &amp;quot;13&amp;quot; = &amp;quot;Enter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
For munbyn scanner,   the postamble/suffix  does not allow you to use &amp;quot;Enter&amp;quot;  so you need to leave that blank and instead check the box under EndMark  that says &amp;quot;Enter&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15044</id>
		<title>Configuring a barcode scanner</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15044"/>
		<updated>2025-10-01T14:57:39Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* Windows 11 Industrial Rugged Tablet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Zebra DS2278=&lt;br /&gt;
&lt;br /&gt;
This page will cover how to setup a Zebra DS2278 Bluetooth Barcode Scanner to work with iSoft products on mobile devices.&lt;br /&gt;
&lt;br /&gt;
==Scanner Info==&lt;br /&gt;
* Approx Cost: $190-$280 depending on accessories and support&lt;br /&gt;
* Important Features: Bluetooth, 14 hour+ battery life, 5ft drop, 36 month warranty, 123Scan app, SDKs for iOS, Android, Windows&lt;br /&gt;
&lt;br /&gt;
==Quick Start Guide==&lt;br /&gt;
===Android using Chrome===&lt;br /&gt;
* The fastest way to get started is to scan the appropriate barcode for your device type. **Make sure your device is fully charged!&lt;br /&gt;
* This model of scanner can scan from a high resolution monitor or screen &lt;br /&gt;
* Each of the barcodes below will change the defaults on your scanner.  You will need to &amp;quot;forget&amp;quot; or &amp;quot;remove&amp;quot; the device in your Bluetooth settings and reconnect&lt;br /&gt;
* The below barcodes have the following settings: &amp;#039;&amp;#039;&amp;#039;Prefix : Suffix $&amp;#039;&amp;#039;&amp;#039;, HID features for iOS, Host: HID BT Classic&lt;br /&gt;
[[Image:AndroidBarcode.JPG]]&lt;br /&gt;
&lt;br /&gt;
===iOS using ITrack LX App===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Tip: You do not need to set up this device as a keyboard wedge&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1. You first need to install the Zebra iOS app https://apps.apple.com/us/app/zebra-scanner-control/id1034012069&lt;br /&gt;
&lt;br /&gt;
2. Open that app and go to Connection Help &amp;gt; Pair DS2278&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-setup-barcodes.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Follow the onscreen instructions&lt;br /&gt;
&lt;br /&gt;
4. Go back to the main screen and choose Connect&lt;br /&gt;
&lt;br /&gt;
5. Tap on the DS2278 and choose Disconnect(this will disconnect it from the Zebra app so we can connect it to the ITrack LX app)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-disconnect-screen.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
6. Go to the ITrack LX app and after a few seconds you should hear a connection beep from the scanner. Scanning in the ITrack LX app with the DS2278 should now work.&lt;br /&gt;
&lt;br /&gt;
==Charging the Scanner==&lt;br /&gt;
* The charging circuit on the scanner is capable of using as much current as possible based on the power source&lt;br /&gt;
* Preferred Method: use a BC1.2 Compliant Micro USB adapter to a wall outlet (higher current charging capability above 900 mA)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra_battery.JPG]]&lt;br /&gt;
&lt;br /&gt;
==123Scan Software==&lt;br /&gt;
&lt;br /&gt;
==Explanation of Settings==&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* Zebra Support Page [https://www.zebra.com/us/en/support-downloads/scanners/general-purpose-scanners/ds2200-series.html link]&lt;br /&gt;
* 123Scan Software Download [https://www.zebra.com/us/en/products/software/scanning-systems/123scan.html link]&lt;br /&gt;
* Full Manual Download [https://www.zebra.com/content/dam/zebra_new_ia/en-us/manuals/barcode-scanners/ds2278-prg-en.pdf link]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Honeywell=&lt;br /&gt;
&lt;br /&gt;
== Compatibility Notes ==&lt;br /&gt;
Please update the Chrome browser on the Honeywell to Chrome v101 so that the Teardown app is sized correctly. It currently ships with Chrome v70. -JW 2022-05-18&lt;br /&gt;
&lt;br /&gt;
== Setting up a Honeywell Scanner ==&lt;br /&gt;
ScanPal EDA71  &lt;br /&gt;
https://www.honeywellaidc.com/products/computer-devices/tablet/scanpaleda71&lt;br /&gt;
&lt;br /&gt;
These are the screens you set through to set up the honeywell device&lt;br /&gt;
&lt;br /&gt;
Settings -&amp;gt; Honeywell Settings -&amp;gt; Scan Settings -&amp;gt; Internal Scanner -&amp;gt; Default profile -&amp;gt; Data Processing Settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wedge = checked&lt;br /&gt;
&lt;br /&gt;
Wedge Method = Keyboard&lt;br /&gt;
&lt;br /&gt;
no Prefix&lt;br /&gt;
&lt;br /&gt;
no Suffix&lt;br /&gt;
&lt;br /&gt;
Wedge as keys = empty input&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart_of_settings.jpg|800px|thumb|center|Honeywell Setting Flowchart]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enterprise LX Honeywell config info ==&lt;br /&gt;
&lt;br /&gt;
A global database setting &amp;quot;Scanner Mode (ambleMode,honeywell)&amp;quot; needs to be set to &amp;quot;honeywell&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The current default is ambleMode which may change in the near future.&lt;br /&gt;
The following query will let you check on the setting.   Note: A user has to have logged into an lx app before the default settings are present. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
   `globalsettingvalue`.`settingid`&lt;br /&gt;
    , `setting`.`location`&lt;br /&gt;
    , `setting`.`name`&lt;br /&gt;
    , `globalsettingvalue`.`value`&lt;br /&gt;
    , `setting`.`defaultvalue`&lt;br /&gt;
    , `setting`.`scope`&lt;br /&gt;
    , `setting`.`settingtype`&lt;br /&gt;
    , `value`=`defaultvalue` AS isdefault&lt;br /&gt;
FROM&lt;br /&gt;
    `globalsettingvalue`&lt;br /&gt;
    INNER JOIN `setting` &lt;br /&gt;
        ON (`globalsettingvalue`.`settingid` = `setting`.`settingid`)&lt;br /&gt;
WHERE (`setting`.`name` = &amp;#039;Scanner Mode (ambleMode,honeywell)&amp;#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Munbyn=&lt;br /&gt;
&lt;br /&gt;
== Setting up a Munbyn Scanner ==&lt;br /&gt;
This is for the MUNBYN IPDA081/IPDA086 Mobile Data Terminal: https://pos.munbyn.com/munbyn-ipda081-rfid-handheld-computer/&amp;lt;br&amp;gt;&lt;br /&gt;
To set up:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Swipe up to see apps, then tap on &amp;quot;keyboardemulator&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;Function&amp;quot; page, make sure &amp;quot;Enable Scanner&amp;quot; is on.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner1.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;AppSettings&amp;quot; page, turn on &amp;quot;Release key off scan&amp;quot; (if it is not already enabled).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner2.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Then scroll down to &amp;quot;Process mode&amp;quot;. Make sure it is set to &amp;quot;keyboard input&amp;quot;. Under &amp;quot;End mark&amp;quot;, none of the options should be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner3.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Prefix/preamble and suffix/postamble for the device can be edited under &amp;quot;Data Format&amp;quot;. If using a test program that uses prefix/suffix, be sure that the prefix/suffix in the program and in the scanner setting app (keyboardemulator) are the same.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner4.png|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tera Scanner =&lt;br /&gt;
[[File:Tera_config.png|200px]]&lt;br /&gt;
&lt;br /&gt;
To enable the trigger on the Tera scanner handle:&lt;br /&gt;
&lt;br /&gt;
1. Get to the Scanner Config Page. &lt;br /&gt;
&lt;br /&gt;
2. Disable the scanner.&lt;br /&gt;
&lt;br /&gt;
3. Key in 293 on the scanner keypad.&lt;br /&gt;
&lt;br /&gt;
4. Re-enable the scanner.&lt;br /&gt;
&lt;br /&gt;
5. The scanner config page should look like the image above if it&amp;#039;s set correctly.&lt;br /&gt;
&lt;br /&gt;
== Windows 11 Industrial Rugged Tablet ==&lt;br /&gt;
Two additional applications are required to use the scanner features: Honeywell Download manager tool (which will manage any subsequent Honeywell software downloads), then an EZConfig for Scanning software for the configuration of scanner itself. Both parts can be downloaded from the same portal: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the zip file containing the Honeywell Download manager tool, select &amp;quot;here&amp;quot; marked by the first arrow. When finished, right-click the zip file selecting &amp;quot;Extract all...&amp;quot; then select a home/path for this installer.&lt;br /&gt;
&lt;br /&gt;
To download the EZConfig for Scanning, in the file system on the left: Software -&amp;gt; Barcode Scanner -&amp;gt; Software -&amp;gt; Tools and Utilities -&amp;gt; EZConfig for Scanning -&amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Open the EZConfig for Scanning software when it&amp;#039;s finished downloading. &lt;br /&gt;
# Open the file &amp;quot;EZConfig-Scanning v4_msedge&amp;quot;&lt;br /&gt;
# select &amp;quot;Connected Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Configure Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Data Formatting&amp;quot;&lt;br /&gt;
# in Data Formatting, verify that you are on the &amp;quot;Prefix/Suffix&amp;quot; tab&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
&lt;br /&gt;
This may be out-dated. &lt;br /&gt;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;
&lt;br /&gt;
Instead of using EZConfig, we need to use another Honeywell tool named SoftWedge. It can be downloaded from the same link as the download manager and EZConfig: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the SoftWedge zip file you will need to navigate the Honeywell file system on the left when you open the link: Software &amp;gt; Barcode Scanners &amp;gt; Software &amp;gt; Tools and Utilities &amp;gt; Softwedge &amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Unzip the SoftWedge folder&lt;br /&gt;
# Open and read the PDF instructions in the folder&lt;br /&gt;
# Run SoftWedge.exe, it will pop up in the system tray&lt;br /&gt;
# Open up SoftWedge and verify the &amp;quot;port status&amp;quot; is connected&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
# Verify things are working by doing test scans in Chromium/EEweb Configuration-&amp;gt;Scanner-&amp;gt;Test Scanner&lt;br /&gt;
&lt;br /&gt;
== NOTE on ENTERPRISE LX setup ==&lt;br /&gt;
enterpise lx  default pre/postable&lt;br /&gt;
preamble = &amp;quot;126&amp;quot;    = &amp;quot;~&amp;quot;&lt;br /&gt;
postamble = &amp;quot;13&amp;quot; = &amp;quot;Enter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
For munbyn scanner,   the postamble/suffix  does not allow you to use &amp;quot;Enter&amp;quot;  so you need to leave that blank and instead check the box under EndMark  that says &amp;quot;Enter&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15043</id>
		<title>Configuring a barcode scanner</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15043"/>
		<updated>2025-10-01T14:47:35Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* Windows 11 Industrial Rugged Tablet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Zebra DS2278=&lt;br /&gt;
&lt;br /&gt;
This page will cover how to setup a Zebra DS2278 Bluetooth Barcode Scanner to work with iSoft products on mobile devices.&lt;br /&gt;
&lt;br /&gt;
==Scanner Info==&lt;br /&gt;
* Approx Cost: $190-$280 depending on accessories and support&lt;br /&gt;
* Important Features: Bluetooth, 14 hour+ battery life, 5ft drop, 36 month warranty, 123Scan app, SDKs for iOS, Android, Windows&lt;br /&gt;
&lt;br /&gt;
==Quick Start Guide==&lt;br /&gt;
===Android using Chrome===&lt;br /&gt;
* The fastest way to get started is to scan the appropriate barcode for your device type. **Make sure your device is fully charged!&lt;br /&gt;
* This model of scanner can scan from a high resolution monitor or screen &lt;br /&gt;
* Each of the barcodes below will change the defaults on your scanner.  You will need to &amp;quot;forget&amp;quot; or &amp;quot;remove&amp;quot; the device in your Bluetooth settings and reconnect&lt;br /&gt;
* The below barcodes have the following settings: &amp;#039;&amp;#039;&amp;#039;Prefix : Suffix $&amp;#039;&amp;#039;&amp;#039;, HID features for iOS, Host: HID BT Classic&lt;br /&gt;
[[Image:AndroidBarcode.JPG]]&lt;br /&gt;
&lt;br /&gt;
===iOS using ITrack LX App===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Tip: You do not need to set up this device as a keyboard wedge&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1. You first need to install the Zebra iOS app https://apps.apple.com/us/app/zebra-scanner-control/id1034012069&lt;br /&gt;
&lt;br /&gt;
2. Open that app and go to Connection Help &amp;gt; Pair DS2278&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-setup-barcodes.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Follow the onscreen instructions&lt;br /&gt;
&lt;br /&gt;
4. Go back to the main screen and choose Connect&lt;br /&gt;
&lt;br /&gt;
5. Tap on the DS2278 and choose Disconnect(this will disconnect it from the Zebra app so we can connect it to the ITrack LX app)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-disconnect-screen.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
6. Go to the ITrack LX app and after a few seconds you should hear a connection beep from the scanner. Scanning in the ITrack LX app with the DS2278 should now work.&lt;br /&gt;
&lt;br /&gt;
==Charging the Scanner==&lt;br /&gt;
* The charging circuit on the scanner is capable of using as much current as possible based on the power source&lt;br /&gt;
* Preferred Method: use a BC1.2 Compliant Micro USB adapter to a wall outlet (higher current charging capability above 900 mA)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra_battery.JPG]]&lt;br /&gt;
&lt;br /&gt;
==123Scan Software==&lt;br /&gt;
&lt;br /&gt;
==Explanation of Settings==&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* Zebra Support Page [https://www.zebra.com/us/en/support-downloads/scanners/general-purpose-scanners/ds2200-series.html link]&lt;br /&gt;
* 123Scan Software Download [https://www.zebra.com/us/en/products/software/scanning-systems/123scan.html link]&lt;br /&gt;
* Full Manual Download [https://www.zebra.com/content/dam/zebra_new_ia/en-us/manuals/barcode-scanners/ds2278-prg-en.pdf link]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Honeywell=&lt;br /&gt;
&lt;br /&gt;
== Compatibility Notes ==&lt;br /&gt;
Please update the Chrome browser on the Honeywell to Chrome v101 so that the Teardown app is sized correctly. It currently ships with Chrome v70. -JW 2022-05-18&lt;br /&gt;
&lt;br /&gt;
== Setting up a Honeywell Scanner ==&lt;br /&gt;
ScanPal EDA71  &lt;br /&gt;
https://www.honeywellaidc.com/products/computer-devices/tablet/scanpaleda71&lt;br /&gt;
&lt;br /&gt;
These are the screens you set through to set up the honeywell device&lt;br /&gt;
&lt;br /&gt;
Settings -&amp;gt; Honeywell Settings -&amp;gt; Scan Settings -&amp;gt; Internal Scanner -&amp;gt; Default profile -&amp;gt; Data Processing Settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wedge = checked&lt;br /&gt;
&lt;br /&gt;
Wedge Method = Keyboard&lt;br /&gt;
&lt;br /&gt;
no Prefix&lt;br /&gt;
&lt;br /&gt;
no Suffix&lt;br /&gt;
&lt;br /&gt;
Wedge as keys = empty input&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart_of_settings.jpg|800px|thumb|center|Honeywell Setting Flowchart]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enterprise LX Honeywell config info ==&lt;br /&gt;
&lt;br /&gt;
A global database setting &amp;quot;Scanner Mode (ambleMode,honeywell)&amp;quot; needs to be set to &amp;quot;honeywell&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The current default is ambleMode which may change in the near future.&lt;br /&gt;
The following query will let you check on the setting.   Note: A user has to have logged into an lx app before the default settings are present. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
   `globalsettingvalue`.`settingid`&lt;br /&gt;
    , `setting`.`location`&lt;br /&gt;
    , `setting`.`name`&lt;br /&gt;
    , `globalsettingvalue`.`value`&lt;br /&gt;
    , `setting`.`defaultvalue`&lt;br /&gt;
    , `setting`.`scope`&lt;br /&gt;
    , `setting`.`settingtype`&lt;br /&gt;
    , `value`=`defaultvalue` AS isdefault&lt;br /&gt;
FROM&lt;br /&gt;
    `globalsettingvalue`&lt;br /&gt;
    INNER JOIN `setting` &lt;br /&gt;
        ON (`globalsettingvalue`.`settingid` = `setting`.`settingid`)&lt;br /&gt;
WHERE (`setting`.`name` = &amp;#039;Scanner Mode (ambleMode,honeywell)&amp;#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Munbyn=&lt;br /&gt;
&lt;br /&gt;
== Setting up a Munbyn Scanner ==&lt;br /&gt;
This is for the MUNBYN IPDA081/IPDA086 Mobile Data Terminal: https://pos.munbyn.com/munbyn-ipda081-rfid-handheld-computer/&amp;lt;br&amp;gt;&lt;br /&gt;
To set up:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Swipe up to see apps, then tap on &amp;quot;keyboardemulator&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;Function&amp;quot; page, make sure &amp;quot;Enable Scanner&amp;quot; is on.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner1.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;AppSettings&amp;quot; page, turn on &amp;quot;Release key off scan&amp;quot; (if it is not already enabled).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner2.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Then scroll down to &amp;quot;Process mode&amp;quot;. Make sure it is set to &amp;quot;keyboard input&amp;quot;. Under &amp;quot;End mark&amp;quot;, none of the options should be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner3.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Prefix/preamble and suffix/postamble for the device can be edited under &amp;quot;Data Format&amp;quot;. If using a test program that uses prefix/suffix, be sure that the prefix/suffix in the program and in the scanner setting app (keyboardemulator) are the same.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner4.png|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tera Scanner =&lt;br /&gt;
[[File:Tera_config.png|200px]]&lt;br /&gt;
&lt;br /&gt;
To enable the trigger on the Tera scanner handle:&lt;br /&gt;
&lt;br /&gt;
1. Get to the Scanner Config Page. &lt;br /&gt;
&lt;br /&gt;
2. Disable the scanner.&lt;br /&gt;
&lt;br /&gt;
3. Key in 293 on the scanner keypad.&lt;br /&gt;
&lt;br /&gt;
4. Re-enable the scanner.&lt;br /&gt;
&lt;br /&gt;
5. The scanner config page should look like the image above if it&amp;#039;s set correctly.&lt;br /&gt;
&lt;br /&gt;
== Windows 11 Industrial Rugged Tablet ==&lt;br /&gt;
Two additional applications are required to use the scanner features: Honeywell Download manager tool (which will manage any subsequent Honeywell software downloads), then an EZConfig for Scanning software for the configuration of scanner itself. Both parts can be downloaded from the same portal: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the zip file containing the Honeywell Download manager tool, select &amp;quot;here&amp;quot; marked by the first arrow. When finished, right-click the zip file selecting &amp;quot;Extract all...&amp;quot; then select a home/path for this installer.&lt;br /&gt;
&lt;br /&gt;
To download the EZConfig for Scanning, in the file system on the left: Software -&amp;gt; Barcode Scanner -&amp;gt; Software -&amp;gt; Tools and Utilities -&amp;gt; EZConfig for Scanning -&amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Open the EZConfig for Scanning software when it&amp;#039;s finished downloading. &lt;br /&gt;
# Open the file &amp;quot;EZConfig-Scanning v4_msedge&amp;quot;&lt;br /&gt;
# select &amp;quot;Connected Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Configure Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Data Formatting&amp;quot;&lt;br /&gt;
# in Data Formatting, verify that you are on the &amp;quot;Prefix/Suffix&amp;quot; tab&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;
&lt;br /&gt;
This may be out-dated. Instead of using EZConfig, we need to use another Honeywell tool named SoftWedge. It can be downloaded from the same link as the download manager and EZConfig: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the SoftWedge zip file you will need to navigate the Honeywell file system on the left when you open the link: Software &amp;gt; Barcode Scanners &amp;gt; Software &amp;gt; Tools and Utilities &amp;gt; Softwedge &amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Unzip the SoftWedge folder&lt;br /&gt;
# Open and read the PDF instructions in the folder&lt;br /&gt;
# Run SoftWedge.exe, it will pop up in the system tray&lt;br /&gt;
# Open up SoftWedge and verify the &amp;quot;port status&amp;quot; is connected&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
# Verify things are working by doing test scans in Chromium/EEweb Configuration-&amp;gt;Scanner-&amp;gt;Test Scanner&lt;br /&gt;
&lt;br /&gt;
== NOTE on ENTERPRISE LX setup ==&lt;br /&gt;
enterpise lx  default pre/postable&lt;br /&gt;
preamble = &amp;quot;126&amp;quot;    = &amp;quot;~&amp;quot;&lt;br /&gt;
postamble = &amp;quot;13&amp;quot; = &amp;quot;Enter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
For munbyn scanner,   the postamble/suffix  does not allow you to use &amp;quot;Enter&amp;quot;  so you need to leave that blank and instead check the box under EndMark  that says &amp;quot;Enter&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15042</id>
		<title>Configuring a barcode scanner</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=Configuring_a_barcode_scanner&amp;diff=15042"/>
		<updated>2025-10-01T14:47:25Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* Windows 11 Industrial Rugged Tablet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Zebra DS2278=&lt;br /&gt;
&lt;br /&gt;
This page will cover how to setup a Zebra DS2278 Bluetooth Barcode Scanner to work with iSoft products on mobile devices.&lt;br /&gt;
&lt;br /&gt;
==Scanner Info==&lt;br /&gt;
* Approx Cost: $190-$280 depending on accessories and support&lt;br /&gt;
* Important Features: Bluetooth, 14 hour+ battery life, 5ft drop, 36 month warranty, 123Scan app, SDKs for iOS, Android, Windows&lt;br /&gt;
&lt;br /&gt;
==Quick Start Guide==&lt;br /&gt;
===Android using Chrome===&lt;br /&gt;
* The fastest way to get started is to scan the appropriate barcode for your device type. **Make sure your device is fully charged!&lt;br /&gt;
* This model of scanner can scan from a high resolution monitor or screen &lt;br /&gt;
* Each of the barcodes below will change the defaults on your scanner.  You will need to &amp;quot;forget&amp;quot; or &amp;quot;remove&amp;quot; the device in your Bluetooth settings and reconnect&lt;br /&gt;
* The below barcodes have the following settings: &amp;#039;&amp;#039;&amp;#039;Prefix : Suffix $&amp;#039;&amp;#039;&amp;#039;, HID features for iOS, Host: HID BT Classic&lt;br /&gt;
[[Image:AndroidBarcode.JPG]]&lt;br /&gt;
&lt;br /&gt;
===iOS using ITrack LX App===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Tip: You do not need to set up this device as a keyboard wedge&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
1. You first need to install the Zebra iOS app https://apps.apple.com/us/app/zebra-scanner-control/id1034012069&lt;br /&gt;
&lt;br /&gt;
2. Open that app and go to Connection Help &amp;gt; Pair DS2278&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-setup-barcodes.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
3. Follow the onscreen instructions&lt;br /&gt;
&lt;br /&gt;
4. Go back to the main screen and choose Connect&lt;br /&gt;
&lt;br /&gt;
5. Tap on the DS2278 and choose Disconnect(this will disconnect it from the Zebra app so we can connect it to the ITrack LX app)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra-DS2278-disconnect-screen.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
6. Go to the ITrack LX app and after a few seconds you should hear a connection beep from the scanner. Scanning in the ITrack LX app with the DS2278 should now work.&lt;br /&gt;
&lt;br /&gt;
==Charging the Scanner==&lt;br /&gt;
* The charging circuit on the scanner is capable of using as much current as possible based on the power source&lt;br /&gt;
* Preferred Method: use a BC1.2 Compliant Micro USB adapter to a wall outlet (higher current charging capability above 900 mA)&lt;br /&gt;
&lt;br /&gt;
[[Image:Zebra_battery.JPG]]&lt;br /&gt;
&lt;br /&gt;
==123Scan Software==&lt;br /&gt;
&lt;br /&gt;
==Explanation of Settings==&lt;br /&gt;
&lt;br /&gt;
==External Links==&lt;br /&gt;
* Zebra Support Page [https://www.zebra.com/us/en/support-downloads/scanners/general-purpose-scanners/ds2200-series.html link]&lt;br /&gt;
* 123Scan Software Download [https://www.zebra.com/us/en/products/software/scanning-systems/123scan.html link]&lt;br /&gt;
* Full Manual Download [https://www.zebra.com/content/dam/zebra_new_ia/en-us/manuals/barcode-scanners/ds2278-prg-en.pdf link]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Honeywell=&lt;br /&gt;
&lt;br /&gt;
== Compatibility Notes ==&lt;br /&gt;
Please update the Chrome browser on the Honeywell to Chrome v101 so that the Teardown app is sized correctly. It currently ships with Chrome v70. -JW 2022-05-18&lt;br /&gt;
&lt;br /&gt;
== Setting up a Honeywell Scanner ==&lt;br /&gt;
ScanPal EDA71  &lt;br /&gt;
https://www.honeywellaidc.com/products/computer-devices/tablet/scanpaleda71&lt;br /&gt;
&lt;br /&gt;
These are the screens you set through to set up the honeywell device&lt;br /&gt;
&lt;br /&gt;
Settings -&amp;gt; Honeywell Settings -&amp;gt; Scan Settings -&amp;gt; Internal Scanner -&amp;gt; Default profile -&amp;gt; Data Processing Settings&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wedge = checked&lt;br /&gt;
&lt;br /&gt;
Wedge Method = Keyboard&lt;br /&gt;
&lt;br /&gt;
no Prefix&lt;br /&gt;
&lt;br /&gt;
no Suffix&lt;br /&gt;
&lt;br /&gt;
Wedge as keys = empty input&lt;br /&gt;
&lt;br /&gt;
[[File:Flowchart_of_settings.jpg|800px|thumb|center|Honeywell Setting Flowchart]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Enterprise LX Honeywell config info ==&lt;br /&gt;
&lt;br /&gt;
A global database setting &amp;quot;Scanner Mode (ambleMode,honeywell)&amp;quot; needs to be set to &amp;quot;honeywell&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The current default is ambleMode which may change in the near future.&lt;br /&gt;
The following query will let you check on the setting.   Note: A user has to have logged into an lx app before the default settings are present. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
   `globalsettingvalue`.`settingid`&lt;br /&gt;
    , `setting`.`location`&lt;br /&gt;
    , `setting`.`name`&lt;br /&gt;
    , `globalsettingvalue`.`value`&lt;br /&gt;
    , `setting`.`defaultvalue`&lt;br /&gt;
    , `setting`.`scope`&lt;br /&gt;
    , `setting`.`settingtype`&lt;br /&gt;
    , `value`=`defaultvalue` AS isdefault&lt;br /&gt;
FROM&lt;br /&gt;
    `globalsettingvalue`&lt;br /&gt;
    INNER JOIN `setting` &lt;br /&gt;
        ON (`globalsettingvalue`.`settingid` = `setting`.`settingid`)&lt;br /&gt;
WHERE (`setting`.`name` = &amp;#039;Scanner Mode (ambleMode,honeywell)&amp;#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Munbyn=&lt;br /&gt;
&lt;br /&gt;
== Setting up a Munbyn Scanner ==&lt;br /&gt;
This is for the MUNBYN IPDA081/IPDA086 Mobile Data Terminal: https://pos.munbyn.com/munbyn-ipda081-rfid-handheld-computer/&amp;lt;br&amp;gt;&lt;br /&gt;
To set up:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Swipe up to see apps, then tap on &amp;quot;keyboardemulator&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;Function&amp;quot; page, make sure &amp;quot;Enable Scanner&amp;quot; is on.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner1.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
On the &amp;quot;AppSettings&amp;quot; page, turn on &amp;quot;Release key off scan&amp;quot; (if it is not already enabled).&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner2.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Then scroll down to &amp;quot;Process mode&amp;quot;. Make sure it is set to &amp;quot;keyboard input&amp;quot;. Under &amp;quot;End mark&amp;quot;, none of the options should be checked.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner3.png|200px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Prefix/preamble and suffix/postamble for the device can be edited under &amp;quot;Data Format&amp;quot;. If using a test program that uses prefix/suffix, be sure that the prefix/suffix in the program and in the scanner setting app (keyboardemulator) are the same.&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:scanner4.png|200px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tera Scanner =&lt;br /&gt;
[[File:Tera_config.png|200px]]&lt;br /&gt;
&lt;br /&gt;
To enable the trigger on the Tera scanner handle:&lt;br /&gt;
&lt;br /&gt;
1. Get to the Scanner Config Page. &lt;br /&gt;
&lt;br /&gt;
2. Disable the scanner.&lt;br /&gt;
&lt;br /&gt;
3. Key in 293 on the scanner keypad.&lt;br /&gt;
&lt;br /&gt;
4. Re-enable the scanner.&lt;br /&gt;
&lt;br /&gt;
5. The scanner config page should look like the image above if it&amp;#039;s set correctly.&lt;br /&gt;
&lt;br /&gt;
== Windows 11 Industrial Rugged Tablet ==&lt;br /&gt;
Two additional applications are required to use the scanner features: Honeywell Download manager tool (which will manage any subsequent Honeywell software downloads), then an EZConfig for Scanning software for the configuration of scanner itself. Both parts can be downloaded from the same portal: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the zip file containing the Honeywell Download manager tool, select &amp;quot;here&amp;quot; marked by the first arrow. When finished, right-click the zip file selecting &amp;quot;Extract all...&amp;quot; then select a home/path for this installer.&lt;br /&gt;
&lt;br /&gt;
To download the EZConfig for Scanning, in the file system on the left: Software -&amp;gt; Barcode Scanner -&amp;gt; Software -&amp;gt; Tools and Utilities -&amp;gt; EZConfig for Scanning -&amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Open the EZConfig for Scanning software when it&amp;#039;s finished downloading. &lt;br /&gt;
# Open the file &amp;quot;EZConfig-Scanning v4_msedge&amp;quot;&lt;br /&gt;
# select &amp;quot;Connected Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Configure Device&amp;quot;&lt;br /&gt;
# select &amp;quot;Data Formatting&amp;quot;&lt;br /&gt;
# in Data Formatting, verify that you are on the &amp;quot;Prefix/Suffix&amp;quot; tab&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;
This may be out-dated. Instead of using EZConfig, we need to use another Honeywell tool named SoftWedge. It can be downloaded from the same link as the download manager and EZConfig: https://hsmftp.honeywell.com/&lt;br /&gt;
&lt;br /&gt;
To download the SoftWedge zip file you will need to navigate the Honeywell file system on the left when you open the link: Software &amp;gt; Barcode Scanners &amp;gt; Software &amp;gt; Tools and Utilities &amp;gt; Softwedge &amp;gt; Current.&lt;br /&gt;
&lt;br /&gt;
# Unzip the SoftWedge folder&lt;br /&gt;
# Open and read the PDF instructions in the folder&lt;br /&gt;
# Run SoftWedge.exe, it will pop up in the system tray&lt;br /&gt;
# Open up SoftWedge and verify the &amp;quot;port status&amp;quot; is connected&lt;br /&gt;
# enter &amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt; as the Prefix&lt;br /&gt;
# enter &amp;lt;code&amp;gt;{  CR}&amp;lt;/code&amp;gt; as the Suffix&lt;br /&gt;
# Verify things are working by doing test scans in Chromium/EEweb Configuration-&amp;gt;Scanner-&amp;gt;Test Scanner&lt;br /&gt;
&lt;br /&gt;
== NOTE on ENTERPRISE LX setup ==&lt;br /&gt;
enterpise lx  default pre/postable&lt;br /&gt;
preamble = &amp;quot;126&amp;quot;    = &amp;quot;~&amp;quot;&lt;br /&gt;
postamble = &amp;quot;13&amp;quot; = &amp;quot;Enter&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
For munbyn scanner,   the postamble/suffix  does not allow you to use &amp;quot;Enter&amp;quot;  so you need to leave that blank and instead check the box under EndMark  that says &amp;quot;Enter&amp;quot;&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=Power_BI&amp;diff=14611</id>
		<title>Power BI</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=Power_BI&amp;diff=14611"/>
		<updated>2024-09-25T02:40:03Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: Created page with &amp;quot;= Power BI =  Power BI is a suite of business analytics tools developed by Microsoft. It enables users to visualize and share insights from their data through interactive reports and dashboards. Power BI helps organizations turn raw data into actionable insights, enabling better decision-making and performance tracking. == Access == Currently, two tiers of licenses are being used: Pro - for those who need to access reports, and Premium per User (PPU) - for those who crea...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Power BI = &lt;br /&gt;
Power BI is a suite of business analytics tools developed by Microsoft. It enables users to visualize and share insights from their data through interactive reports and dashboards. Power BI helps organizations turn raw data into actionable insights, enabling better decision-making and performance tracking.&lt;br /&gt;
== Access ==&lt;br /&gt;
Currently, two tiers of licenses are being used: Pro - for those who need to access reports, and Premium per User (PPU) - for those who create reports. &lt;br /&gt;
* Power BI Pro is an individual per-user license that lets users create content and also read, and interact with content that others publish to the Power BI service. Users with this license type can share content and collaborate with other Power BI Pro users. Only Power BI Pro users can publish or share content with other Pro users or consume content that&amp;#039;s created by other Pro users, unless a Power BI Premium capacity hosts that content. If a Power BI Premium capacity hosts the content, then Pro users can share content and collaborate with free and PPU users too.&lt;br /&gt;
* A PPU per-user license provides the license holder with all of the capabilities of Power BI Pro plus access to most Premium capacity-based features. A Power BI PPU license unlocks access to extra features, capabilities, and types of content that are only available with a paid license. This access is limited to the PPU license holder and other colleagues who also have a PPU license. For example, in order to collaborate and share content in a PPU workspace, all users must have a PPU license. &lt;br /&gt;
Follow these instructions to obtain access to the desired report. You will only need to complete all the steps but the final one once, for initial set up. Going forward it will just be an ordinary log in if prompted.&lt;br /&gt;
# Request a license from Hanna Reynolds or Brian Roy, who will provide you with email and password - keep those credentials somewhere safe&lt;br /&gt;
# You will need a preferred authenticator app available&lt;br /&gt;
# Go to [https://app.powerbi.com/ this website] and enter the credentials from the first step&lt;br /&gt;
# Follow the steps in the prompt to set up the authenticator instance&lt;br /&gt;
# Request access to a specific report from Yuliia Iziumova or Brian Roy, include your email address used for log in with the request; you will receive a direct link to the report that you can bookmark; alternatively, go to [https://app.powerbi.com/ your workspace] to see all reports available to you for viewing&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14101</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14101"/>
		<updated>2023-11-20T20:47:20Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The Python Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The Python Script=== &lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
*The SELECT portion of the old sql script is used in the query run by the python script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import mysql.connector&lt;br /&gt;
from mysql.connector import Error&lt;br /&gt;
import csv&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def connect():&lt;br /&gt;
    conn = None&lt;br /&gt;
    try:&lt;br /&gt;
        #Enter connection details&lt;br /&gt;
        conn = mysql.connector.connect(&lt;br /&gt;
            host=&amp;lt;hostname&amp;gt;,&lt;br /&gt;
            database=&amp;lt;database&amp;gt;,&lt;br /&gt;
            user=&amp;lt;user&amp;gt;,&lt;br /&gt;
            password=&amp;lt;password&amp;gt;,&lt;br /&gt;
            port=&amp;lt;port&amp;gt;)&lt;br /&gt;
            &lt;br /&gt;
        #Confirm that connection is successful&lt;br /&gt;
        if conn.is_connected():&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;Connected to MySQL database&amp;quot;)&lt;br /&gt;
            log.close()&lt;br /&gt;
    #Add to logs    &lt;br /&gt;
    except Error as e:&lt;br /&gt;
        log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
        log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
        log.write(e)&lt;br /&gt;
        log.close()&lt;br /&gt;
    finally:&lt;br /&gt;
        if conn is not None and conn.is_connected():&lt;br /&gt;
            curs = conn.cursor()&lt;br /&gt;
            query = &amp;#039;SELECT partuse.part AS parttype, inventory.partnum AS SKU, inventory.tagnum AS tagnumber, inventory.typenum, inventory.stocknum, inventory.vinnum AS vin, inventory.make, inventory.model, inventory.year, inventory.bodystyle, inventory.location, replace(inventory.description, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as description,inventory.core AS coreprice, inventory.interchangenum, inventory.status, inventory.suggestedprice AS retailprice, inventory.bottomprice AS wholesaleprice, inventory.replenish, inventory.deplete, inventory.quantity, inventory.dateentered, inventory.label1, inventory.data1, inventory.label2, inventory.data2, inventory.label3, inventory.data3, inventory.label4, inventory.data4, inventory.cost, inventory.pmanufacturer AS partmanufacturer, inventory.pmodel AS partmodel, inventory.minquantity, inventory.maxquantity, inventory.taxable, inventory.oemnum, inventory.condition, inventory.serialnum, inventory.side, inventory.category, inventory.listprice, replace(inventory.notes, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as notes, inventory.parentpartnum, inventory.weight, invmaster.trackingnum AS trackingnumber FROM inventory LEFT JOIN partuse ON inventory.typenum = partuse.typenum LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum LEFT JOIN locations ON inventory.partnum = locations.partnum WHERE inventory.status IN(&amp;quot;A&amp;quot;, &amp;quot;H&amp;quot;);&amp;#039;&lt;br /&gt;
            count = 0&lt;br /&gt;
            curs.execute(query)&lt;br /&gt;
            #Set up csv write location and parameters&lt;br /&gt;
            with open(&amp;#039;output.csv&amp;#039;, &amp;#039;w&amp;#039;, newline=&amp;#039;&amp;#039;) as csvfile:&lt;br /&gt;
                filewriter = csv.writer(csvfile, delimiter=&amp;#039;,&amp;#039;, quotechar=&amp;#039;&amp;quot;&amp;#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
                #Add column headers&lt;br /&gt;
                filewriter.writerow([&amp;#039;parttype&amp;#039;, &amp;#039;SKU&amp;#039;, &amp;#039;tagnumber&amp;#039;, &amp;#039;typenum&amp;#039;, &amp;#039;stocknum&amp;#039;, &amp;#039;vin&amp;#039;, &amp;#039;make&amp;#039;, &amp;#039;mdoel&amp;#039;, &amp;#039;year&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;location&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;coreprice&amp;#039;, &amp;#039;interchangenum&amp;#039;, &amp;#039;status&amp;#039;, &amp;#039;retailprice&amp;#039;, &amp;#039;wholesaleprice&amp;#039;, &amp;#039;replenish&amp;#039;, &amp;#039;deplete&amp;#039;, &amp;#039;quantity&amp;#039;, &amp;#039;dateentered&amp;#039;, &amp;#039;label1&amp;#039;, &amp;#039;data1&amp;#039;, &amp;#039;label2&amp;#039;, &amp;#039;data2&amp;#039;, &amp;#039;label3&amp;#039;, &amp;#039;data3&amp;#039;, &amp;#039;label4&amp;#039;, &amp;#039;data4&amp;#039;, &amp;#039;cost&amp;#039;, &amp;#039;partmanufacturer&amp;#039;, &amp;#039;partmodel&amp;#039;, &amp;#039;minquantity&amp;#039;,&amp;#039;maxquantity&amp;#039;, &amp;#039;taxable&amp;#039;, &amp;#039;oemnum&amp;#039;, &amp;#039;condition&amp;#039;, &amp;#039;serialnum&amp;#039;, &amp;#039;side&amp;#039;, &amp;#039;category&amp;#039;, &amp;#039;listprice&amp;#039;, &amp;#039;notes&amp;#039;, &amp;#039;parentpartnum&amp;#039;, &amp;#039;weight&amp;#039;, &amp;#039;trackingnumber&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
                #loop through each row and add append the data to the csv&lt;br /&gt;
                for (parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber) in curs:&lt;br /&gt;
                    filewriter.writerow([parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber])&lt;br /&gt;
&lt;br /&gt;
                    count = count + 1&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(str(count)+ &amp;#039; rows were added to results.csv&amp;#039;)&lt;br /&gt;
            log.close()&lt;br /&gt;
&lt;br /&gt;
            conn.close()&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;#039;__main__&amp;#039;:&lt;br /&gt;
    connect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14099</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14099"/>
		<updated>2023-11-17T15:34:52Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The Python Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The Python Script=== &lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
*The SELECT portion of the old sql script is used in the query run by the python script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import mysql.connector&lt;br /&gt;
from mysql.connector import Error&lt;br /&gt;
import csv&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def connect():&lt;br /&gt;
    conn = None&lt;br /&gt;
    try:&lt;br /&gt;
        #Enter connection details&lt;br /&gt;
        conn = mysql.connector.connect(&lt;br /&gt;
            host=&amp;lt;hostname&amp;gt;,&lt;br /&gt;
            database=&amp;lt;database?,&lt;br /&gt;
            user=&amp;lt;user&amp;gt;,&lt;br /&gt;
            password=&amp;lt;password&amp;gt;,&lt;br /&gt;
            port=&amp;lt;port&amp;gt;)&lt;br /&gt;
            &lt;br /&gt;
        #Confirm that connection is successful&lt;br /&gt;
        if conn.is_connected():&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;Connected to MySQL database&amp;quot;)&lt;br /&gt;
            log.close()&lt;br /&gt;
    #Add to logs    &lt;br /&gt;
    except Error as e:&lt;br /&gt;
        log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
        log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
        log.write(e)&lt;br /&gt;
        log.close()&lt;br /&gt;
    finally:&lt;br /&gt;
        if conn is not None and conn.is_connected():&lt;br /&gt;
            curs = conn.cursor()&lt;br /&gt;
            query = &amp;#039;SELECT partuse.part AS parttype, inventory.partnum AS SKU, inventory.tagnum AS tagnumber, inventory.typenum, inventory.stocknum, inventory.vinnum AS vin, inventory.make, inventory.model, inventory.year, inventory.bodystyle, inventory.location, replace(inventory.description, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as description,inventory.core AS coreprice, inventory.interchangenum, inventory.status, inventory.suggestedprice AS retailprice, inventory.bottomprice AS wholesaleprice, inventory.replenish, inventory.deplete, inventory.quantity, inventory.dateentered, inventory.label1, inventory.data1, inventory.label2, inventory.data2, inventory.label3, inventory.data3, inventory.label4, inventory.data4, inventory.cost, inventory.pmanufacturer AS partmanufacturer, inventory.pmodel AS partmodel, inventory.minquantity, inventory.maxquantity, inventory.taxable, inventory.oemnum, inventory.condition, inventory.serialnum, inventory.side, inventory.category, inventory.listprice, replace(inventory.notes, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as notes, inventory.parentpartnum, inventory.weight, invmaster.trackingnum AS trackingnumber FROM inventory LEFT JOIN partuse ON inventory.typenum = partuse.typenum LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum LEFT JOIN locations ON inventory.partnum = locations.partnum WHERE inventory.status IN(&amp;quot;A&amp;quot;, &amp;quot;H&amp;quot;);&amp;#039;&lt;br /&gt;
            count = 0&lt;br /&gt;
            curs.execute(query)&lt;br /&gt;
            #Set up csv write location and parameters&lt;br /&gt;
            with open(&amp;#039;results.csv&amp;#039;, &amp;#039;w&amp;#039;, newline=&amp;#039;&amp;#039;) as csvfile:&lt;br /&gt;
                filewriter = csv.writer(csvfile, delimiter=&amp;#039;,&amp;#039;, quotechar=&amp;#039;&amp;quot;&amp;#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
                #Add column headers&lt;br /&gt;
                filewriter.writerow([&amp;#039;parttype&amp;#039;, &amp;#039;SKU&amp;#039;, &amp;#039;tagnumber&amp;#039;, &amp;#039;typenum&amp;#039;, &amp;#039;stocknum&amp;#039;, &amp;#039;vin&amp;#039;, &amp;#039;make&amp;#039;, &amp;#039;mdoel&amp;#039;, &amp;#039;year&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;location&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;coreprice&amp;#039;, &amp;#039;interchangenum&amp;#039;, &amp;#039;status&amp;#039;, &amp;#039;retailprice&amp;#039;, &amp;#039;wholesaleprice&amp;#039;, &amp;#039;replenish&amp;#039;, &amp;#039;deplete&amp;#039;, &amp;#039;quantity&amp;#039;, &amp;#039;dateentered&amp;#039;, &amp;#039;label1&amp;#039;, &amp;#039;data1&amp;#039;, &amp;#039;label2&amp;#039;, &amp;#039;data2&amp;#039;, &amp;#039;label3&amp;#039;, &amp;#039;data3&amp;#039;, &amp;#039;label4&amp;#039;, &amp;#039;data4&amp;#039;, &amp;#039;cost&amp;#039;, &amp;#039;partmanufacturer&amp;#039;, &amp;#039;partmodel&amp;#039;, &amp;#039;minquantity&amp;#039;,&amp;#039;maxquantity&amp;#039;, &amp;#039;taxable&amp;#039;, &amp;#039;oemnum&amp;#039;, &amp;#039;condition&amp;#039;, &amp;#039;serialnum&amp;#039;, &amp;#039;side&amp;#039;, &amp;#039;category&amp;#039;, &amp;#039;listprice&amp;#039;, &amp;#039;notes&amp;#039;, &amp;#039;parentpartnum&amp;#039;, &amp;#039;weight&amp;#039;, &amp;#039;trackingnumber&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
                #loop through each row and add append the data to the csv&lt;br /&gt;
                for (parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber) in curs:&lt;br /&gt;
                    filewriter.writerow([parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber])&lt;br /&gt;
&lt;br /&gt;
                    count = count + 1&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(str(count)+ &amp;#039; rows were added to results.csv&amp;#039;)&lt;br /&gt;
            log.close()&lt;br /&gt;
&lt;br /&gt;
            conn.close()&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;#039;__main__&amp;#039;:&lt;br /&gt;
    connect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14098</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14098"/>
		<updated>2023-11-16T21:41:49Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The Python Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The Python Script=== &lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
*The SELECT portion of the old sql script is used in the query run by the python script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import mysql.connector&lt;br /&gt;
from mysql.connector import Error&lt;br /&gt;
import csv&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def connect():&lt;br /&gt;
    conn = None&lt;br /&gt;
    try:&lt;br /&gt;
        #Enter connection details&lt;br /&gt;
        conn = mysql.connector.connect(&lt;br /&gt;
            host=&amp;#039;hosteddb.isoftdata.com&amp;#039;,&lt;br /&gt;
            database=&amp;#039;427662&amp;#039;,&lt;br /&gt;
            user=&amp;#039;lund_user&amp;#039;,&lt;br /&gt;
            password=&amp;#039;3huSusepha&amp;#039;,&lt;br /&gt;
            port=&amp;quot;3306&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
        #Confirm that connection is successful&lt;br /&gt;
        if conn.is_connected():&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;Connected to MySQL database&amp;quot;)&lt;br /&gt;
            log.close()&lt;br /&gt;
    #Add to logs    &lt;br /&gt;
    except Error as e:&lt;br /&gt;
        log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
        log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
        log.write(e)&lt;br /&gt;
        log.close()&lt;br /&gt;
    finally:&lt;br /&gt;
        if conn is not None and conn.is_connected():&lt;br /&gt;
            curs = conn.cursor()&lt;br /&gt;
            query = &amp;#039;SELECT partuse.part AS parttype, inventory.partnum AS SKU, inventory.tagnum AS tagnumber, inventory.typenum, inventory.stocknum, inventory.vinnum AS vin, inventory.make, inventory.model, inventory.year, inventory.bodystyle, inventory.location, replace(inventory.description, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as description,inventory.core AS coreprice, inventory.interchangenum, inventory.status, inventory.suggestedprice AS retailprice, inventory.bottomprice AS wholesaleprice, inventory.replenish, inventory.deplete, inventory.quantity, inventory.dateentered, inventory.label1, inventory.data1, inventory.label2, inventory.data2, inventory.label3, inventory.data3, inventory.label4, inventory.data4, inventory.cost, inventory.pmanufacturer AS partmanufacturer, inventory.pmodel AS partmodel, inventory.minquantity, inventory.maxquantity, inventory.taxable, inventory.oemnum, inventory.condition, inventory.serialnum, inventory.side, inventory.category, inventory.listprice, replace(inventory.notes, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as notes, inventory.parentpartnum, inventory.weight, invmaster.trackingnum AS trackingnumber FROM inventory LEFT JOIN partuse ON inventory.typenum = partuse.typenum LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum LEFT JOIN locations ON inventory.partnum = locations.partnum WHERE inventory.status IN(&amp;quot;A&amp;quot;, &amp;quot;H&amp;quot;);&amp;#039;&lt;br /&gt;
            count = 0&lt;br /&gt;
            curs.execute(query)&lt;br /&gt;
            #Set up csv write location and parameters&lt;br /&gt;
            with open(&amp;#039;results.csv&amp;#039;, &amp;#039;w&amp;#039;, newline=&amp;#039;&amp;#039;) as csvfile:&lt;br /&gt;
                filewriter = csv.writer(csvfile, delimiter=&amp;#039;,&amp;#039;, quotechar=&amp;#039;&amp;quot;&amp;#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
                #Add column headers&lt;br /&gt;
                filewriter.writerow([&amp;#039;parttype&amp;#039;, &amp;#039;SKU&amp;#039;, &amp;#039;tagnumber&amp;#039;, &amp;#039;typenum&amp;#039;, &amp;#039;stocknum&amp;#039;, &amp;#039;vin&amp;#039;, &amp;#039;make&amp;#039;, &amp;#039;mdoel&amp;#039;, &amp;#039;year&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;location&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;coreprice&amp;#039;, &amp;#039;interchangenum&amp;#039;, &amp;#039;status&amp;#039;, &amp;#039;retailprice&amp;#039;, &amp;#039;wholesaleprice&amp;#039;, &amp;#039;replenish&amp;#039;, &amp;#039;deplete&amp;#039;, &amp;#039;quantity&amp;#039;, &amp;#039;dateentered&amp;#039;, &amp;#039;label1&amp;#039;, &amp;#039;data1&amp;#039;, &amp;#039;label2&amp;#039;, &amp;#039;data2&amp;#039;, &amp;#039;label3&amp;#039;, &amp;#039;data3&amp;#039;, &amp;#039;label4&amp;#039;, &amp;#039;data4&amp;#039;, &amp;#039;cost&amp;#039;, &amp;#039;partmanufacturer&amp;#039;, &amp;#039;partmodel&amp;#039;, &amp;#039;minquantity&amp;#039;,&amp;#039;maxquantity&amp;#039;, &amp;#039;taxable&amp;#039;, &amp;#039;oemnum&amp;#039;, &amp;#039;condition&amp;#039;, &amp;#039;serialnum&amp;#039;, &amp;#039;side&amp;#039;, &amp;#039;category&amp;#039;, &amp;#039;listprice&amp;#039;, &amp;#039;notes&amp;#039;, &amp;#039;parentpartnum&amp;#039;, &amp;#039;weight&amp;#039;, &amp;#039;trackingnumber&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
                #loop through each row and add append the data to the csv&lt;br /&gt;
                for (parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber) in curs:&lt;br /&gt;
                    filewriter.writerow([parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber])&lt;br /&gt;
&lt;br /&gt;
                    count = count + 1&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(str(count)+ &amp;#039; rows were added to results.csv&amp;#039;)&lt;br /&gt;
            log.close()&lt;br /&gt;
&lt;br /&gt;
            conn.close()&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;#039;__main__&amp;#039;:&lt;br /&gt;
    connect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14097</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14097"/>
		<updated>2023-11-16T21:16:01Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The Python Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The Python Script=== &lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
The select portion of the old sql script is used in the query run by the python script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import mysql.connector&lt;br /&gt;
from mysql.connector import Error&lt;br /&gt;
import csv&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def connect():&lt;br /&gt;
    conn = None&lt;br /&gt;
    try:&lt;br /&gt;
        #Enter connection details&lt;br /&gt;
        conn = mysql.connector.connect(&lt;br /&gt;
            host=&amp;#039;hosteddb.isoftdata.com&amp;#039;,&lt;br /&gt;
            database=&amp;#039;427662&amp;#039;,&lt;br /&gt;
            user=&amp;#039;lund_user&amp;#039;,&lt;br /&gt;
            password=&amp;#039;3huSusepha&amp;#039;,&lt;br /&gt;
            port=&amp;quot;3306&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
        #Confirm that connection is successful&lt;br /&gt;
        if conn.is_connected():&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;Connected to MySQL database&amp;quot;)&lt;br /&gt;
            log.close()&lt;br /&gt;
    #Add to logs    &lt;br /&gt;
    except Error as e:&lt;br /&gt;
        log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
        log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
        log.write(e)&lt;br /&gt;
        log.close()&lt;br /&gt;
    finally:&lt;br /&gt;
        if conn is not None and conn.is_connected():&lt;br /&gt;
            curs = conn.cursor()&lt;br /&gt;
            query = &amp;#039;SELECT partuse.part AS parttype, inventory.partnum AS SKU, inventory.tagnum AS tagnumber, inventory.typenum, inventory.stocknum, inventory.vinnum AS vin, inventory.make, inventory.model, inventory.year, inventory.bodystyle, inventory.location, replace(inventory.description, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as description,inventory.core AS coreprice, inventory.interchangenum, inventory.status, inventory.suggestedprice AS retailprice, inventory.bottomprice AS wholesaleprice, inventory.replenish, inventory.deplete, inventory.quantity, inventory.dateentered, inventory.label1, inventory.data1, inventory.label2, inventory.data2, inventory.label3, inventory.data3, inventory.label4, inventory.data4, inventory.cost, inventory.pmanufacturer AS partmanufacturer, inventory.pmodel AS partmodel, inventory.minquantity, inventory.maxquantity, inventory.taxable, inventory.oemnum, inventory.condition, inventory.serialnum, inventory.side, inventory.category, inventory.listprice, replace(inventory.notes, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as notes, inventory.parentpartnum, inventory.weight, invmaster.trackingnum AS trackingnumber FROM inventory LEFT JOIN partuse ON inventory.typenum = partuse.typenum LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum LEFT JOIN locations ON inventory.partnum = locations.partnum WHERE inventory.status IN(&amp;quot;A&amp;quot;, &amp;quot;H&amp;quot;);&amp;#039;&lt;br /&gt;
            count = 0&lt;br /&gt;
            curs.execute(query)&lt;br /&gt;
            #Set up csv write location and parameters&lt;br /&gt;
            with open(&amp;#039;results.csv&amp;#039;, &amp;#039;w&amp;#039;, newline=&amp;#039;&amp;#039;) as csvfile:&lt;br /&gt;
                filewriter = csv.writer(csvfile, delimiter=&amp;#039;,&amp;#039;, quotechar=&amp;#039;&amp;quot;&amp;#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
                #Add column headers&lt;br /&gt;
                filewriter.writerow([&amp;#039;parttype&amp;#039;, &amp;#039;SKU&amp;#039;, &amp;#039;tagnumber&amp;#039;, &amp;#039;typenum&amp;#039;, &amp;#039;stocknum&amp;#039;, &amp;#039;vin&amp;#039;, &amp;#039;make&amp;#039;, &amp;#039;mdoel&amp;#039;, &amp;#039;year&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;location&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;coreprice&amp;#039;, &amp;#039;interchangenum&amp;#039;, &amp;#039;status&amp;#039;, &amp;#039;retailprice&amp;#039;, &amp;#039;wholesaleprice&amp;#039;, &amp;#039;replenish&amp;#039;, &amp;#039;deplete&amp;#039;, &amp;#039;quantity&amp;#039;, &amp;#039;dateentered&amp;#039;, &amp;#039;label1&amp;#039;, &amp;#039;data1&amp;#039;, &amp;#039;label2&amp;#039;, &amp;#039;data2&amp;#039;, &amp;#039;label3&amp;#039;, &amp;#039;data3&amp;#039;, &amp;#039;label4&amp;#039;, &amp;#039;data4&amp;#039;, &amp;#039;cost&amp;#039;, &amp;#039;partmanufacturer&amp;#039;, &amp;#039;partmodel&amp;#039;, &amp;#039;minquantity&amp;#039;,&amp;#039;maxquantity&amp;#039;, &amp;#039;taxable&amp;#039;, &amp;#039;oemnum&amp;#039;, &amp;#039;condition&amp;#039;, &amp;#039;serialnum&amp;#039;, &amp;#039;side&amp;#039;, &amp;#039;category&amp;#039;, &amp;#039;listprice&amp;#039;, &amp;#039;notes&amp;#039;, &amp;#039;parentpartnum&amp;#039;, &amp;#039;weight&amp;#039;, &amp;#039;trackingnumber&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
                #loop through each row and add append the data to the csv&lt;br /&gt;
                for (parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber) in curs:&lt;br /&gt;
                    filewriter.writerow([parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber])&lt;br /&gt;
&lt;br /&gt;
                    count = count + 1&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(str(count)+ &amp;#039; rows were added to results.csv&amp;#039;)&lt;br /&gt;
            log.close()&lt;br /&gt;
&lt;br /&gt;
            conn.close()&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;#039;__main__&amp;#039;:&lt;br /&gt;
    connect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14096</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14096"/>
		<updated>2023-11-16T21:15:29Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The Python Script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The Python Script=== &lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
#The select portion of the old sql script is used in the query run by the python script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import mysql.connector&lt;br /&gt;
from mysql.connector import Error&lt;br /&gt;
import csv&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def connect():&lt;br /&gt;
    conn = None&lt;br /&gt;
    try:&lt;br /&gt;
        #Enter connection details&lt;br /&gt;
        conn = mysql.connector.connect(&lt;br /&gt;
            host=&amp;#039;hosteddb.isoftdata.com&amp;#039;,&lt;br /&gt;
            database=&amp;#039;427662&amp;#039;,&lt;br /&gt;
            user=&amp;#039;lund_user&amp;#039;,&lt;br /&gt;
            password=&amp;#039;3huSusepha&amp;#039;,&lt;br /&gt;
            port=&amp;quot;3306&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
        #Confirm that connection is successful&lt;br /&gt;
        if conn.is_connected():&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;Connected to MySQL database&amp;quot;)&lt;br /&gt;
            log.close()&lt;br /&gt;
    #Add to logs    &lt;br /&gt;
    except Error as e:&lt;br /&gt;
        log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
        log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
        log.write(e)&lt;br /&gt;
        log.close()&lt;br /&gt;
    finally:&lt;br /&gt;
        if conn is not None and conn.is_connected():&lt;br /&gt;
            curs = conn.cursor()&lt;br /&gt;
            query = &amp;#039;SELECT partuse.part AS parttype, inventory.partnum AS SKU, inventory.tagnum AS tagnumber, inventory.typenum, inventory.stocknum, inventory.vinnum AS vin, inventory.make, inventory.model, inventory.year, inventory.bodystyle, inventory.location, replace(inventory.description, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as description,inventory.core AS coreprice, inventory.interchangenum, inventory.status, inventory.suggestedprice AS retailprice, inventory.bottomprice AS wholesaleprice, inventory.replenish, inventory.deplete, inventory.quantity, inventory.dateentered, inventory.label1, inventory.data1, inventory.label2, inventory.data2, inventory.label3, inventory.data3, inventory.label4, inventory.data4, inventory.cost, inventory.pmanufacturer AS partmanufacturer, inventory.pmodel AS partmodel, inventory.minquantity, inventory.maxquantity, inventory.taxable, inventory.oemnum, inventory.condition, inventory.serialnum, inventory.side, inventory.category, inventory.listprice, replace(inventory.notes, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as notes, inventory.parentpartnum, inventory.weight, invmaster.trackingnum AS trackingnumber FROM inventory LEFT JOIN partuse ON inventory.typenum = partuse.typenum LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum LEFT JOIN locations ON inventory.partnum = locations.partnum WHERE inventory.status IN(&amp;quot;A&amp;quot;, &amp;quot;H&amp;quot;);&amp;#039;&lt;br /&gt;
            count = 0&lt;br /&gt;
            curs.execute(query)&lt;br /&gt;
            #Set up csv write location and parameters&lt;br /&gt;
            with open(&amp;#039;results.csv&amp;#039;, &amp;#039;w&amp;#039;, newline=&amp;#039;&amp;#039;) as csvfile:&lt;br /&gt;
                filewriter = csv.writer(csvfile, delimiter=&amp;#039;,&amp;#039;, quotechar=&amp;#039;&amp;quot;&amp;#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
                #Add column headers&lt;br /&gt;
                filewriter.writerow([&amp;#039;parttype&amp;#039;, &amp;#039;SKU&amp;#039;, &amp;#039;tagnumber&amp;#039;, &amp;#039;typenum&amp;#039;, &amp;#039;stocknum&amp;#039;, &amp;#039;vin&amp;#039;, &amp;#039;make&amp;#039;, &amp;#039;mdoel&amp;#039;, &amp;#039;year&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;location&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;coreprice&amp;#039;, &amp;#039;interchangenum&amp;#039;, &amp;#039;status&amp;#039;, &amp;#039;retailprice&amp;#039;, &amp;#039;wholesaleprice&amp;#039;, &amp;#039;replenish&amp;#039;, &amp;#039;deplete&amp;#039;, &amp;#039;quantity&amp;#039;, &amp;#039;dateentered&amp;#039;, &amp;#039;label1&amp;#039;, &amp;#039;data1&amp;#039;, &amp;#039;label2&amp;#039;, &amp;#039;data2&amp;#039;, &amp;#039;label3&amp;#039;, &amp;#039;data3&amp;#039;, &amp;#039;label4&amp;#039;, &amp;#039;data4&amp;#039;, &amp;#039;cost&amp;#039;, &amp;#039;partmanufacturer&amp;#039;, &amp;#039;partmodel&amp;#039;, &amp;#039;minquantity&amp;#039;,&amp;#039;maxquantity&amp;#039;, &amp;#039;taxable&amp;#039;, &amp;#039;oemnum&amp;#039;, &amp;#039;condition&amp;#039;, &amp;#039;serialnum&amp;#039;, &amp;#039;side&amp;#039;, &amp;#039;category&amp;#039;, &amp;#039;listprice&amp;#039;, &amp;#039;notes&amp;#039;, &amp;#039;parentpartnum&amp;#039;, &amp;#039;weight&amp;#039;, &amp;#039;trackingnumber&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
                #loop through each row and add append the data to the csv&lt;br /&gt;
                for (parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber) in curs:&lt;br /&gt;
                    filewriter.writerow([parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber])&lt;br /&gt;
&lt;br /&gt;
                    count = count + 1&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(str(count)+ &amp;#039; rows were added to results.csv&amp;#039;)&lt;br /&gt;
            log.close()&lt;br /&gt;
&lt;br /&gt;
            conn.close()&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;#039;__main__&amp;#039;:&lt;br /&gt;
    connect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14095</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14095"/>
		<updated>2023-11-16T21:13:27Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The batch file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The Python Script=== &lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
The Python script runs the select portion of this script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import mysql.connector&lt;br /&gt;
from mysql.connector import Error&lt;br /&gt;
import csv&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def connect():&lt;br /&gt;
    conn = None&lt;br /&gt;
    try:&lt;br /&gt;
        #Enter connection details&lt;br /&gt;
        conn = mysql.connector.connect(&lt;br /&gt;
            host=&amp;#039;hosteddb.isoftdata.com&amp;#039;,&lt;br /&gt;
            database=&amp;#039;427662&amp;#039;,&lt;br /&gt;
            user=&amp;#039;lund_user&amp;#039;,&lt;br /&gt;
            password=&amp;#039;3huSusepha&amp;#039;,&lt;br /&gt;
            port=&amp;quot;3306&amp;quot;)&lt;br /&gt;
            &lt;br /&gt;
        #Confirm that connection is successful&lt;br /&gt;
        if conn.is_connected():&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;Connected to MySQL database&amp;quot;)&lt;br /&gt;
            log.close()&lt;br /&gt;
    #Add to logs    &lt;br /&gt;
    except Error as e:&lt;br /&gt;
        log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
        log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
        log.write(e)&lt;br /&gt;
        log.close()&lt;br /&gt;
    finally:&lt;br /&gt;
        if conn is not None and conn.is_connected():&lt;br /&gt;
            curs = conn.cursor()&lt;br /&gt;
            query = &amp;#039;SELECT partuse.part AS parttype, inventory.partnum AS SKU, inventory.tagnum AS tagnumber, inventory.typenum, inventory.stocknum, inventory.vinnum AS vin, inventory.make, inventory.model, inventory.year, inventory.bodystyle, inventory.location, replace(inventory.description, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as description,inventory.core AS coreprice, inventory.interchangenum, inventory.status, inventory.suggestedprice AS retailprice, inventory.bottomprice AS wholesaleprice, inventory.replenish, inventory.deplete, inventory.quantity, inventory.dateentered, inventory.label1, inventory.data1, inventory.label2, inventory.data2, inventory.label3, inventory.data3, inventory.label4, inventory.data4, inventory.cost, inventory.pmanufacturer AS partmanufacturer, inventory.pmodel AS partmodel, inventory.minquantity, inventory.maxquantity, inventory.taxable, inventory.oemnum, inventory.condition, inventory.serialnum, inventory.side, inventory.category, inventory.listprice, replace(inventory.notes, &amp;quot;\r\n&amp;quot;, &amp;quot;&amp;quot;) as notes, inventory.parentpartnum, inventory.weight, invmaster.trackingnum AS trackingnumber FROM inventory LEFT JOIN partuse ON inventory.typenum = partuse.typenum LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum LEFT JOIN locations ON inventory.partnum = locations.partnum WHERE inventory.status IN(&amp;quot;A&amp;quot;, &amp;quot;H&amp;quot;);&amp;#039;&lt;br /&gt;
            count = 0&lt;br /&gt;
            curs.execute(query)&lt;br /&gt;
            #Set up csv write location and parameters&lt;br /&gt;
            with open(&amp;#039;results.csv&amp;#039;, &amp;#039;w&amp;#039;, newline=&amp;#039;&amp;#039;) as csvfile:&lt;br /&gt;
                filewriter = csv.writer(csvfile, delimiter=&amp;#039;,&amp;#039;, quotechar=&amp;#039;&amp;quot;&amp;#039;, quoting=csv.QUOTE_MINIMAL)&lt;br /&gt;
                #Add column headers&lt;br /&gt;
                filewriter.writerow([&amp;#039;parttype&amp;#039;, &amp;#039;SKU&amp;#039;, &amp;#039;tagnumber&amp;#039;, &amp;#039;typenum&amp;#039;, &amp;#039;stocknum&amp;#039;, &amp;#039;vin&amp;#039;, &amp;#039;make&amp;#039;, &amp;#039;mdoel&amp;#039;, &amp;#039;year&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;location&amp;#039;, &amp;#039;description&amp;#039;, &amp;#039;coreprice&amp;#039;, &amp;#039;interchangenum&amp;#039;, &amp;#039;status&amp;#039;, &amp;#039;retailprice&amp;#039;, &amp;#039;wholesaleprice&amp;#039;, &amp;#039;replenish&amp;#039;, &amp;#039;deplete&amp;#039;, &amp;#039;quantity&amp;#039;, &amp;#039;dateentered&amp;#039;, &amp;#039;label1&amp;#039;, &amp;#039;data1&amp;#039;, &amp;#039;label2&amp;#039;, &amp;#039;data2&amp;#039;, &amp;#039;label3&amp;#039;, &amp;#039;data3&amp;#039;, &amp;#039;label4&amp;#039;, &amp;#039;data4&amp;#039;, &amp;#039;cost&amp;#039;, &amp;#039;partmanufacturer&amp;#039;, &amp;#039;partmodel&amp;#039;, &amp;#039;minquantity&amp;#039;,&amp;#039;maxquantity&amp;#039;, &amp;#039;taxable&amp;#039;, &amp;#039;oemnum&amp;#039;, &amp;#039;condition&amp;#039;, &amp;#039;serialnum&amp;#039;, &amp;#039;side&amp;#039;, &amp;#039;category&amp;#039;, &amp;#039;listprice&amp;#039;, &amp;#039;notes&amp;#039;, &amp;#039;parentpartnum&amp;#039;, &amp;#039;weight&amp;#039;, &amp;#039;trackingnumber&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
                #loop through each row and add append the data to the csv&lt;br /&gt;
                for (parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber) in curs:&lt;br /&gt;
                    filewriter.writerow([parttype, SKU, tagnumber, typenum, stocknum, vin, make, mdoel, year, bodystyle, location, description, coreprice, interchangenum, status, retailprice, wholesaleprice, replenish, deplete, quantity, dateentered, label1, data1, label2, data2, label3, data3, label4, data4, cost, partmanufacturer, partmodel, minquantity, maxquantity, taxable, oemnum, condition, serialnum, side, category, listprice, notes, parentpartnum, weight, trackingnumber])&lt;br /&gt;
&lt;br /&gt;
                    count = count + 1&lt;br /&gt;
            log = open(&amp;quot;log.txt&amp;quot;, &amp;quot;a&amp;quot;)&lt;br /&gt;
            log.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
            log.write(str(count)+ &amp;#039; rows were added to results.csv&amp;#039;)&lt;br /&gt;
            log.close()&lt;br /&gt;
&lt;br /&gt;
            conn.close()&lt;br /&gt;
        &lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;#039;__main__&amp;#039;:&lt;br /&gt;
    connect()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14094</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14094"/>
		<updated>2023-11-16T21:11:34Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The sql script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The sql script=== -s&lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
The Python script runs the select portion of this script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT partuse.part AS parttype, &lt;br /&gt;
inventory.partnum AS SKU, &lt;br /&gt;
inventory.tagnum AS tagnumber,&lt;br /&gt;
inventory.typenum, &lt;br /&gt;
inventory.stocknum, &lt;br /&gt;
inventory.vinnum AS vin, &lt;br /&gt;
inventory.make, &lt;br /&gt;
inventory.model, &lt;br /&gt;
inventory.year, &lt;br /&gt;
inventory.bodystyle, &lt;br /&gt;
inventory.location, &lt;br /&gt;
inventory.description, &lt;br /&gt;
inventory.core AS coreprice, &lt;br /&gt;
inventory.interchangenum, &lt;br /&gt;
inventory.status, &lt;br /&gt;
inventory.suggestedprice AS retailprice, &lt;br /&gt;
inventory.bottomprice AS wholesaleprice, &lt;br /&gt;
inventory.replenish, &lt;br /&gt;
inventory.deplete, &lt;br /&gt;
inventory.quantity, &lt;br /&gt;
inventory.dateentered, &lt;br /&gt;
inventory.label1, &lt;br /&gt;
inventory.data1, &lt;br /&gt;
inventory.label2, &lt;br /&gt;
inventory.data2, &lt;br /&gt;
inventory.label3, &lt;br /&gt;
inventory.data3, &lt;br /&gt;
inventory.label4, &lt;br /&gt;
inventory.data4, &lt;br /&gt;
inventory.cost, &lt;br /&gt;
inventory.pmanufacturer AS partmanufacturer, &lt;br /&gt;
inventory.pmodel AS partmodel, &lt;br /&gt;
inventory.minquantity, &lt;br /&gt;
inventory.maxquantity, &lt;br /&gt;
inventory.taxable, &lt;br /&gt;
inventory.oemnum, &lt;br /&gt;
inventory.condition, &lt;br /&gt;
inventory.serialnum, &lt;br /&gt;
inventory.side, &lt;br /&gt;
inventory.category, &lt;br /&gt;
inventory.listprice, &lt;br /&gt;
inventory.notes, &lt;br /&gt;
inventory.parentpartnum, &lt;br /&gt;
inventory.weight, &lt;br /&gt;
invmaster.trackingnum AS trackingnumber &lt;br /&gt;
FROM inventory&lt;br /&gt;
LEFT JOIN partuse ON inventory.typenum = partuse.typenum&lt;br /&gt;
LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum&lt;br /&gt;
LEFT JOIN locations ON inventory.partnum = locations.partnum&lt;br /&gt;
WHERE inventory.status IN(&amp;#039;A&amp;#039;, &amp;#039;H&amp;#039;)&lt;br /&gt;
INTO OUTFILE &amp;#039;&amp;lt;PATH&amp;gt;\\output.csv&amp;#039;&lt;br /&gt;
FIELDS&lt;br /&gt;
TERMINATED BY &amp;#039;,&amp;#039;&lt;br /&gt;
ENCLOSED BY &amp;#039;&amp;quot;&amp;#039;&lt;br /&gt;
ESCAPED BY &amp;#039;\\&amp;#039;&lt;br /&gt;
LINES&lt;br /&gt;
TERMINATED BY &amp;#039;\n&amp;#039;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; Be sure to replace &amp;lt;PATH&amp;gt; in the line &amp;quot;INTO OUTFILE &amp;#039;&amp;lt;PATH&amp;gt;\\output.csv&amp;#039;&amp;quot; with where the output file needs to go. Note that this path is relative to mysql not the bat file so you may want to use an absolute path. The filename can also be changed if wished.&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14093</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14093"/>
		<updated>2023-11-16T21:10:59Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* The sql script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The sql script===&lt;br /&gt;
New exporter doesn&amp;#039;t use a sql script because it is blocked by the FILE permission as well as the secure file priv flag in the mysql config.&lt;br /&gt;
The Python script runs the select portion of this script.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT partuse.part AS parttype, &lt;br /&gt;
inventory.partnum AS SKU, &lt;br /&gt;
inventory.tagnum AS tagnumber,&lt;br /&gt;
inventory.typenum, &lt;br /&gt;
inventory.stocknum, &lt;br /&gt;
inventory.vinnum AS vin, &lt;br /&gt;
inventory.make, &lt;br /&gt;
inventory.model, &lt;br /&gt;
inventory.year, &lt;br /&gt;
inventory.bodystyle, &lt;br /&gt;
inventory.location, &lt;br /&gt;
inventory.description, &lt;br /&gt;
inventory.core AS coreprice, &lt;br /&gt;
inventory.interchangenum, &lt;br /&gt;
inventory.status, &lt;br /&gt;
inventory.suggestedprice AS retailprice, &lt;br /&gt;
inventory.bottomprice AS wholesaleprice, &lt;br /&gt;
inventory.replenish, &lt;br /&gt;
inventory.deplete, &lt;br /&gt;
inventory.quantity, &lt;br /&gt;
inventory.dateentered, &lt;br /&gt;
inventory.label1, &lt;br /&gt;
inventory.data1, &lt;br /&gt;
inventory.label2, &lt;br /&gt;
inventory.data2, &lt;br /&gt;
inventory.label3, &lt;br /&gt;
inventory.data3, &lt;br /&gt;
inventory.label4, &lt;br /&gt;
inventory.data4, &lt;br /&gt;
inventory.cost, &lt;br /&gt;
inventory.pmanufacturer AS partmanufacturer, &lt;br /&gt;
inventory.pmodel AS partmodel, &lt;br /&gt;
inventory.minquantity, &lt;br /&gt;
inventory.maxquantity, &lt;br /&gt;
inventory.taxable, &lt;br /&gt;
inventory.oemnum, &lt;br /&gt;
inventory.condition, &lt;br /&gt;
inventory.serialnum, &lt;br /&gt;
inventory.side, &lt;br /&gt;
inventory.category, &lt;br /&gt;
inventory.listprice, &lt;br /&gt;
inventory.notes, &lt;br /&gt;
inventory.parentpartnum, &lt;br /&gt;
inventory.weight, &lt;br /&gt;
invmaster.trackingnum AS trackingnumber &lt;br /&gt;
FROM inventory&lt;br /&gt;
LEFT JOIN partuse ON inventory.typenum = partuse.typenum&lt;br /&gt;
LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum&lt;br /&gt;
LEFT JOIN locations ON inventory.partnum = locations.partnum&lt;br /&gt;
WHERE inventory.status IN(&amp;#039;A&amp;#039;, &amp;#039;H&amp;#039;)&lt;br /&gt;
INTO OUTFILE &amp;#039;&amp;lt;PATH&amp;gt;\\output.csv&amp;#039;&lt;br /&gt;
FIELDS&lt;br /&gt;
TERMINATED BY &amp;#039;,&amp;#039;&lt;br /&gt;
ENCLOSED BY &amp;#039;&amp;quot;&amp;#039;&lt;br /&gt;
ESCAPED BY &amp;#039;\\&amp;#039;&lt;br /&gt;
LINES&lt;br /&gt;
TERMINATED BY &amp;#039;\n&amp;#039;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; Be sure to replace &amp;lt;PATH&amp;gt; in the line &amp;quot;INTO OUTFILE &amp;#039;&amp;lt;PATH&amp;gt;\\output.csv&amp;#039;&amp;quot; with where the output file needs to go. Note that this path is relative to mysql not the bat file so you may want to use an absolute path. The filename can also be changed if wished.&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14092</id>
		<title>ITrack/Pro/DSI Integration</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Pro/DSI_Integration&amp;diff=14092"/>
		<updated>2023-11-16T21:09:21Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* Exporting from ITrack Pro to DSI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Exporting from ITrack Pro to DSI==&lt;br /&gt;
Batch file and sql script in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIExport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran(Probably want it to happen via a scheduled task) that does the following:&lt;br /&gt;
#Navigates to the DSI export directory&lt;br /&gt;
#Runs a Python script(The script connects to the database and runs a query to get the data, then loads that data into a csv)&lt;br /&gt;
#Uploads the csv file to a directory on DSI&amp;#039;s FTP server using [ftp://ftp.ncftp.com/ncftp/binaries/Setup%20NcFTP%203.2.5.msi ncftp]&lt;br /&gt;
#Deletes the local copy of the csv file&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;&amp;lt;path to dsi export directory&amp;gt;&amp;quot;&lt;br /&gt;
python DSI_Exporter.py&lt;br /&gt;
ncftpput -u &amp;lt;FTP_Server_Username&amp;gt; -p &amp;lt;FTP_Server_Password&amp;gt; &amp;lt;FTP_Server_Name_Or_IP&amp;gt; &amp;lt;path on remote ftp server to put the file&amp;gt; &amp;quot;&amp;lt;local DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
DEL &amp;quot;&amp;lt;local server DSI Export directory&amp;gt;\output.csv&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#Make sure the line &amp;quot;DEL output.txt&amp;quot; is pointed to the output file in the first step.&lt;br /&gt;
#Make a scheduled task that runs the batch file.&lt;br /&gt;
#If you are given an ftp address in the form of &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;&amp;lt;ftp.something.com, remove the leading &amp;lt;nowiki&amp;gt;ftp://&amp;lt;/nowiki&amp;gt;, as it&amp;#039;s unnecessary and will confuse the exporter.&lt;br /&gt;
#In the event the FTP site does not use a specific directory for uploading, substitute a blank string (&amp;quot;&amp;quot;) for &amp;lt;path on remote ftp server to put the file&amp;gt;. Otherwise the exporter will get confused.&lt;br /&gt;
&lt;br /&gt;
===The sql script===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
SELECT partuse.part AS parttype, &lt;br /&gt;
inventory.partnum AS SKU, &lt;br /&gt;
inventory.tagnum AS tagnumber,&lt;br /&gt;
inventory.typenum, &lt;br /&gt;
inventory.stocknum, &lt;br /&gt;
inventory.vinnum AS vin, &lt;br /&gt;
inventory.make, &lt;br /&gt;
inventory.model, &lt;br /&gt;
inventory.year, &lt;br /&gt;
inventory.bodystyle, &lt;br /&gt;
inventory.location, &lt;br /&gt;
inventory.description, &lt;br /&gt;
inventory.core AS coreprice, &lt;br /&gt;
inventory.interchangenum, &lt;br /&gt;
inventory.status, &lt;br /&gt;
inventory.suggestedprice AS retailprice, &lt;br /&gt;
inventory.bottomprice AS wholesaleprice, &lt;br /&gt;
inventory.replenish, &lt;br /&gt;
inventory.deplete, &lt;br /&gt;
inventory.quantity, &lt;br /&gt;
inventory.dateentered, &lt;br /&gt;
inventory.label1, &lt;br /&gt;
inventory.data1, &lt;br /&gt;
inventory.label2, &lt;br /&gt;
inventory.data2, &lt;br /&gt;
inventory.label3, &lt;br /&gt;
inventory.data3, &lt;br /&gt;
inventory.label4, &lt;br /&gt;
inventory.data4, &lt;br /&gt;
inventory.cost, &lt;br /&gt;
inventory.pmanufacturer AS partmanufacturer, &lt;br /&gt;
inventory.pmodel AS partmodel, &lt;br /&gt;
inventory.minquantity, &lt;br /&gt;
inventory.maxquantity, &lt;br /&gt;
inventory.taxable, &lt;br /&gt;
inventory.oemnum, &lt;br /&gt;
inventory.condition, &lt;br /&gt;
inventory.serialnum, &lt;br /&gt;
inventory.side, &lt;br /&gt;
inventory.category, &lt;br /&gt;
inventory.listprice, &lt;br /&gt;
inventory.notes, &lt;br /&gt;
inventory.parentpartnum, &lt;br /&gt;
inventory.weight, &lt;br /&gt;
invmaster.trackingnum AS trackingnumber &lt;br /&gt;
FROM inventory&lt;br /&gt;
LEFT JOIN partuse ON inventory.typenum = partuse.typenum&lt;br /&gt;
LEFT JOIN invmaster ON inventory.stocknum = invmaster.stocknum&lt;br /&gt;
LEFT JOIN locations ON inventory.partnum = locations.partnum&lt;br /&gt;
WHERE inventory.status IN(&amp;#039;A&amp;#039;, &amp;#039;H&amp;#039;)&lt;br /&gt;
INTO OUTFILE &amp;#039;&amp;lt;PATH&amp;gt;\\output.csv&amp;#039;&lt;br /&gt;
FIELDS&lt;br /&gt;
TERMINATED BY &amp;#039;,&amp;#039;&lt;br /&gt;
ENCLOSED BY &amp;#039;&amp;quot;&amp;#039;&lt;br /&gt;
ESCAPED BY &amp;#039;\\&amp;#039;&lt;br /&gt;
LINES&lt;br /&gt;
TERMINATED BY &amp;#039;\n&amp;#039;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; Be sure to replace &amp;lt;PATH&amp;gt; in the line &amp;quot;INTO OUTFILE &amp;#039;&amp;lt;PATH&amp;gt;\\output.csv&amp;#039;&amp;quot; with where the output file needs to go. Note that this path is relative to mysql not the bat file so you may want to use an absolute path. The filename can also be changed if wished.&lt;br /&gt;
&lt;br /&gt;
===Rock and Dirt Export===&lt;br /&gt;
This script and batch file can work for exporting to other FTP sites, for example Rock &amp;amp; Dirt. The processes is functionally the same. You can find the pre-configured files for Rock and Dirt at &amp;#039;&amp;#039;&amp;#039;svn\ITrackPro\Utilities\RockAndDirt&amp;#039;&amp;#039;&amp;#039;. You will still need to create accounts and fill in the scripts with the system-appropriate paths.&lt;br /&gt;
&lt;br /&gt;
==Importing from DSI to ITrack Pro==&lt;br /&gt;
Batch file and DSI Import application in SVN: &amp;#039;&amp;#039;&amp;#039;ITrack\ITrackPro\Utilities\DSIImport\&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===How it works===&lt;br /&gt;
A batch file is ran via a scheduled task that does the following:&lt;br /&gt;
# Using a command line FTP client, connects to a DSI provided FTP server&lt;br /&gt;
## Downloads all .xml and .XML files in a certain directory on the FTP server and puts them in the DSI Import application installation directory&lt;br /&gt;
# Runs the ISoft-built DSI Import application. (You will most likely need a dev to compile you the most recent version.  Also this application requires libmysql.dll)&lt;br /&gt;
## Connects to a MySQL server and ITrack Pro database using database connection info that must be supplied in a host.ini file(this can be copied from the customer&amp;#039;s ITrack Pro client software installation).&lt;br /&gt;
# When the application is ran it scans its own directory for any &amp;amp; all .xml file(s)&lt;br /&gt;
# It then attempts to import all of the information(invoices, invoice line items, customers &amp;amp; it depletes quantity of inventory records) from all of the xml files&lt;br /&gt;
# Upon successful import it then deletes the .xml files from the DSI Import application directory&lt;br /&gt;
&lt;br /&gt;
===The batch file===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;dos&amp;quot;&amp;gt;&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.xml&lt;br /&gt;
ncftpget -DD -u &amp;lt;FTP_Username&amp;gt; -p &amp;lt;FTP_Password&amp;gt; &amp;lt;server name or IP address&amp;gt; &amp;quot;&amp;lt;Local directory of DSI Import Application&amp;gt;&amp;quot; &amp;lt;path on server where the xml file will be&amp;gt;/*.XML&lt;br /&gt;
&amp;quot;&amp;lt;Local directory with DSI Import Application&amp;gt;\DSIImport.exe&amp;quot;&lt;br /&gt;
exit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; &amp;lt;path on server where the xml file will be&amp;gt; is relative to the root.  In many cases this is something like /ISOFT-IN/&lt;br /&gt;
&lt;br /&gt;
===The DSI Import application===&lt;br /&gt;
The DSI Importer currently&lt;br /&gt;
&lt;br /&gt;
#Connects to an ITrack Pro database using information from a host.ini file in its directory&lt;br /&gt;
#Opens all .xml files in its directory&lt;br /&gt;
#For each one of those files, it:&lt;br /&gt;
##Reads in invoices based on the specs we were given by DSI long ago&lt;br /&gt;
##For each one of the invoices that it reads in, it:&lt;br /&gt;
###Creates a customer if the DSI customer on that invoice hasn&amp;#039;t been seen before&lt;br /&gt;
###Creates a new invoice using the f_create_invoice database function&lt;br /&gt;
###For every lineitem on that imported invoice, it&lt;br /&gt;
####Depletes quantity from inventory by looking for a part with a tag number matching the part number that they typed in to DSI for that lineitem&lt;br /&gt;
####Creates a new lineitem using the f_create_lineitem function&lt;br /&gt;
###Creates a new lineitem on that invoice (using f_create_lineitem) to store the tax amount&lt;br /&gt;
##Deletes the file&lt;br /&gt;
#Exits returning 0 if everything went fine, non-zero if some error happened&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In order for the importer to work correctly, the function &amp;#039;&amp;#039;&amp;#039;f_adjust_inventory&amp;#039;&amp;#039;&amp;#039; MUST be present in their database or the importer will not correctly adjust inventory when a file is processed. If a customer using the DSI import does not have the function in their database, log in to the database under their normal mysql user and run the following query:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;Mysql&amp;quot;&amp;gt;&lt;br /&gt;
DELIMITER $$&lt;br /&gt;
&lt;br /&gt;
CREATE FUNCTION `f_adjust_inventory`(in_partnum INT UNSIGNED, in_store SMALLINT UNSIGNED, in_quantity_change INT) RETURNS INT(11)&lt;br /&gt;
BEGIN&lt;br /&gt;
	DECLARE nNewQuantity INT;&lt;br /&gt;
	DECLARE cNewStatus CHAR(1);&lt;br /&gt;
	DECLARE nOldQuantity INT;&lt;br /&gt;
	DECLARE cOldStatus CHAR(1);&lt;br /&gt;
	DECLARE bReplenish ENUM(&amp;#039;False&amp;#039;,&amp;#039;True&amp;#039;);&lt;br /&gt;
	SELECT `quantity`, `status`, `replenish`&lt;br /&gt;
	INTO nOldQuantity, cOldStatus, bReplenish&lt;br /&gt;
	FROM inventory&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store&lt;br /&gt;
	LOCK IN SHARE MODE;&lt;br /&gt;
	SET nNewQuantity = nOldQuantity + in_quantity_change;&lt;br /&gt;
	&lt;br /&gt;
	IF nOldQuantity &amp;lt;= 0 AND cOldStatus = &amp;#039;S&amp;#039; AND nNewQuantity &amp;gt; 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;A&amp;#039;;&lt;br /&gt;
	ELSEIF nNewQuantity &amp;lt;= 0 THEN&lt;br /&gt;
		SET cNewStatus = &amp;#039;S&amp;#039;;&lt;br /&gt;
	END IF;&lt;br /&gt;
	&lt;br /&gt;
	UPDATE `inventory`&lt;br /&gt;
	SET `quantity` = nNewQuantity, `status` = IFNULL(cNewStatus, `status`), `datemodified` = NOW()&lt;br /&gt;
	WHERE `partnum` = in_partnum AND `store` = in_store;&lt;br /&gt;
	&lt;br /&gt;
	RETURN nNewQuantity;&lt;br /&gt;
	&lt;br /&gt;
END $$&lt;br /&gt;
DELIMITER ;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Info ===&lt;br /&gt;
* The way that the DSI Integration knows what part is referenced between the two systems, is that inventory.notes in ITrack will contain the part ID for DSI. If this information is missing, or if additional information is added to inventory.notes, then any sales in DSI will not be successfully updated in ITrack.&lt;br /&gt;
* Currently, the DSI system does not send over XML documents if it can not find any ITrack parts that were sold. It was requested that Ben Cramer change this so that DSI sends over XML files even if they are empty.&lt;br /&gt;
* Because the process automatically deletes the files once they are used, it is difficult to keep logs on what has happened. Archiving has been set up in the DSI Integration so that we now keep a log of all XML files that we have received.&lt;br /&gt;
&lt;br /&gt;
[[Category:Integrations]]&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=Template:ITrack_Enterprise/MySQL_version&amp;diff=13804</id>
		<title>Template:ITrack Enterprise/MySQL version</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=Template:ITrack_Enterprise/MySQL_version&amp;diff=13804"/>
		<updated>2023-02-08T22:22:14Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ITrack/MySQL version|product = Enterprise|version = 5.7.27 (Do not go higher than this version - Brian)}}&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=TSC_tag_printers&amp;diff=13780</id>
		<title>TSC tag printers</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=TSC_tag_printers&amp;diff=13780"/>
		<updated>2023-01-11T16:31:31Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: /* Setting Up */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Setting Up==&lt;br /&gt;
&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Make sure that the customer has calibrated the Tag Printer before beginning.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
#* The printer&amp;#039;s instruction booklet should tell the customer how to do this: On the front of the printer input Menu &amp;gt; Setup &amp;gt; Sensor &amp;gt; Calibration &amp;gt; BLine Mode.&lt;br /&gt;
# Download the latest TSC Tag Printer Driver from [https://www.seagullscientific.com/support/downloads/drivers/tsc/ here].&lt;br /&gt;
# Run through the installer&lt;br /&gt;
#* If you can not find the exact model of printer in the list then you can go to &amp;#039;Have Disk&amp;#039; and browse to &amp;#039;C:/Seagull&amp;#039; and select the model from the new list.&lt;br /&gt;
# Once the printer is created, open up the properties of the printer&lt;br /&gt;
## On the General tab, click &amp;#039;&amp;#039;&amp;#039;Printing Preferences...&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
## On the &amp;#039;&amp;#039;&amp;#039;Page Setup&amp;#039;&amp;#039;&amp;#039; tab click the &amp;#039;&amp;#039;&amp;#039;Edit...&amp;#039;&amp;#039;&amp;#039; button&lt;br /&gt;
## Change the &amp;#039;&amp;#039;&amp;#039;Label Size&amp;#039;&amp;#039;&amp;#039;: Width to 4.00 and Height to 5.50&lt;br /&gt;
## Click OK&lt;br /&gt;
## Select the radio next to &amp;#039;&amp;#039;&amp;#039;Portrait 180°&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
## Click the &amp;#039;&amp;#039;&amp;#039;Stock&amp;#039;&amp;#039;&amp;#039; tab&lt;br /&gt;
## Select &amp;#039;&amp;#039;&amp;#039;Labels With Marks&amp;#039;&amp;#039;&amp;#039; from the &amp;#039;&amp;#039;&amp;#039;Type:&amp;#039;&amp;#039;&amp;#039; drop down&lt;br /&gt;
## Change &amp;#039;&amp;#039;&amp;#039;Mark Height:&amp;#039;&amp;#039;&amp;#039; to 0.12in&lt;br /&gt;
## Click OK&lt;br /&gt;
## In the Tag Printer properties dialog, click the &amp;#039;&amp;#039;&amp;#039;Advanced&amp;#039;&amp;#039;&amp;#039; tab&lt;br /&gt;
## Click the &amp;#039;&amp;#039;&amp;#039;Printing Defaults...&amp;#039;&amp;#039;&amp;#039; button&lt;br /&gt;
## Repeat steps 4.2 through 4.9&lt;br /&gt;
# In ITrack, go to Edit &amp;gt; Options&lt;br /&gt;
# On the Printers tab, select &amp;#039;&amp;#039;&amp;#039;Tag&amp;#039;&amp;#039;&amp;#039; from the &amp;#039;&amp;#039;&amp;#039;Printer Type&amp;#039;&amp;#039;&amp;#039; dropdown&lt;br /&gt;
# Select the Tag printer that was just setup, from the &amp;#039;&amp;#039;&amp;#039;Printer Name&amp;#039;&amp;#039;&amp;#039; dropdown&lt;br /&gt;
# Open a part on the Part screen and print a tag&lt;br /&gt;
# Confirm that everything is fine and dandy&lt;br /&gt;
# If you&amp;#039;re printing on labels (2&amp;quot;x4&amp;quot; die-cut labels):&lt;br /&gt;
## Go to the Page Setup tab, choose &amp;quot;2 x 4&amp;quot;, and click on edit&lt;br /&gt;
## In the new edit window, change Width to 4.00 in and Height to 2.00 in&lt;br /&gt;
## Select the radio next to &amp;#039;&amp;#039;&amp;#039;landscape 180°&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
[[Category:Printing]]&lt;br /&gt;
[[Category:ITrack/Support]]&lt;br /&gt;
&lt;br /&gt;
==Problems/Solutions==&lt;br /&gt;
===Tags print too light to be read===&lt;br /&gt;
A problem that has been experienced before is that tags are printing out too light and the information on the tag can&amp;#039;t be read.&lt;br /&gt;
&lt;br /&gt;
To fix this issue:&lt;br /&gt;
# Open up the tag printer&amp;#039;s properties&lt;br /&gt;
# Go to the &amp;#039;&amp;#039;&amp;#039;General&amp;#039;&amp;#039;&amp;#039; tab and hit the &amp;#039;&amp;#039;&amp;#039;Printing Preferences&amp;#039;&amp;#039;&amp;#039; button&lt;br /&gt;
# The Printing Preferences dialog appears, go to the &amp;#039;&amp;#039;&amp;#039;Options&amp;#039;&amp;#039;&amp;#039; tab&lt;br /&gt;
# Change the print speed to 2.00in/sec and the darkness to 15&lt;br /&gt;
# Click Ok&lt;br /&gt;
# Make the same changes in the &amp;#039;&amp;#039;&amp;#039;Printing Defaults&amp;#039;&amp;#039;&amp;#039; on the Advanced tab&lt;br /&gt;
# There is sometimes an issue where the print speed won&amp;#039;t save&lt;br /&gt;
# Reopen the &amp;#039;&amp;#039;&amp;#039;Printing Preferences (General tab)&amp;#039;&amp;#039;&amp;#039; and &amp;#039;&amp;#039;&amp;#039;Printing Defaults (Advanced tab)&amp;#039;&amp;#039;&amp;#039; dialog&lt;br /&gt;
# Check the Options tab to make sure that the Print Speed is 2.00in/sec&lt;br /&gt;
# If it has gone back to 4.00in/sec, see the section below titled &amp;#039;&amp;#039;&amp;#039;Removing and reinstalling TSC tag printer drivers&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===Removing and reinstalling TSC tag printer drivers===&lt;br /&gt;
# Take note of the printer model and port that the tag printer is using &amp;#039;&amp;#039;&amp;#039;Properties &amp;gt; Ports (tab)&lt;br /&gt;
# Delete the printer&lt;br /&gt;
# In the Printers windows go to &amp;#039;&amp;#039;&amp;#039;File &amp;gt; Server Properties &amp;gt; Drivers (tab) &amp;gt;&amp;#039;&amp;#039;&amp;#039; find the tag printer in the list, select it and hit &amp;#039;&amp;#039;&amp;#039;Remove...&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
# If you get an error about not being able to remove the driver, hit the properties button and take note of the driver path.&lt;br /&gt;
# Delete the directory you took note of in the previous step.&lt;br /&gt;
# Repeat the steps in the &amp;#039;&amp;#039;&amp;#039;Setting Up&amp;#039;&amp;#039;&amp;#039; section above.&lt;br /&gt;
# Go to the [printers] section in Host.ini and delete the line that begins with &amp;#039;tag&amp;#039;, then go into Edit &amp;gt;&amp;gt; Options and set the &amp;#039;Tag&amp;#039; option back to the tag printer. &lt;br /&gt;
##If this is not done then ITrack will not recognize the new driver automatically and it will print to the Windows Default Printer. &lt;br /&gt;
##Another way fix this problem is to select a new printer in Edit &amp;gt;&amp;gt; Options and select a different printer then reselect the tag printer. This will cause ITrack to recognize the new driver and print to it instead of the Windows Default Printer.&lt;br /&gt;
# Tell everyone how awesome you are.&lt;br /&gt;
&lt;br /&gt;
== Setting up the tag printer over the network ==&lt;br /&gt;
The normal way that we network a tag printer so that multiple computers can connect to it is by hooking the tag printer to another computer through USB and then marking it as shared. After that, on another computer you can use Windows Explorer to navigate to the computer that the tag printer is hooked up to, and then connect it from there.&lt;br /&gt;
&lt;br /&gt;
On certain models of tag printers (like the ME240) there is a built-in modem so that it can be connected straight into the network instead of being installed on a computer first. To accomplish this:&lt;br /&gt;
# Connect the tag printer through a CAT5 cable into an ethernet port.&lt;br /&gt;
# On the tag printer, use the menu system/LED to find the IP Address of the tag printer. It will probably be something like &amp;quot;Menu &amp;gt;&amp;gt; Network &amp;gt;&amp;gt; Status.&amp;quot;&lt;br /&gt;
# Once you have the IP Address, install a printer driver of the tag printer on the computer and point the port to the IP Address that you found earlier.&lt;br /&gt;
# If all went as planned, you should now be able to print a test page from the tag printer.&lt;br /&gt;
&lt;br /&gt;
===The tag printer is not spitting the tag out to the black line or going past it===&lt;br /&gt;
# Add the printer as local (if the tag printer is physically connected to another computer then create a new port that includes the IP address of the computer it is hooked up to)&lt;br /&gt;
# Change the Feed Offset to .5 inches (make sure to change it in both the Printing Preferences and Advanced Settings)&lt;br /&gt;
# In the Printer &amp;#039;&amp;#039;&amp;#039;Properties&amp;#039;&amp;#039;&amp;#039; &amp;gt; &amp;#039;&amp;#039;&amp;#039;General&amp;#039;&amp;#039;&amp;#039; tab &amp;gt; &amp;#039;&amp;#039;&amp;#039;Preferences&amp;#039;&amp;#039;&amp;#039; &amp;gt; &amp;#039;&amp;#039;&amp;#039;Stock&amp;#039;&amp;#039;&amp;#039; tab make sure that &amp;#039;&amp;#039;&amp;#039;Post-Print Action&amp;#039;&amp;#039;&amp;#039; is set to &amp;#039;&amp;#039;&amp;#039;Tear Off&amp;#039;&amp;#039;&amp;#039;.  Then check the same setting in &amp;#039;&amp;#039;&amp;#039;Properties&amp;#039;&amp;#039;&amp;#039; &amp;gt; &amp;#039;&amp;#039;&amp;#039;Advanced&amp;#039;&amp;#039;&amp;#039; tab &amp;gt; &amp;#039;&amp;#039;&amp;#039;Printing Defaults&amp;#039;&amp;#039;&amp;#039; &amp;gt; &amp;#039;&amp;#039;&amp;#039;Stock&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
===The tag printer is hooked up to a computer that doesn&amp;#039;t have the version of the driver required for the OS version you&amp;#039;re trying to add it on===&lt;br /&gt;
# Install the tag printer as a local printer, as if it where physically connected to the computer you are trying to network it to&lt;br /&gt;
# Add a new port - make it a local port - and give it the port name &amp;quot;\\&amp;lt;name_of_computer_sharing_printer&amp;gt;\&amp;lt;printer_share_name&amp;gt;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Windows does not recognize the Tag Printer===&lt;br /&gt;
Things to try:&lt;br /&gt;
# Power Cycle the printer: Turn off power and unplug the machine for 30 seconds to a minute, then turn it back on and try to print again.&lt;br /&gt;
# Plug the tag printer into another USB port and try to print.&lt;br /&gt;
# Plug the tag printer into a different computer and test it.&lt;br /&gt;
&lt;br /&gt;
===Windows 8.1 and Printer Installing Issues===&lt;br /&gt;
# Windows 8.0 and 8.1 can present some new and frustrating quirks to the process.&lt;br /&gt;
# If you install a tag printer in Windows 8/8.1 and the printer does not appear in &amp;quot;Devices and Printers&amp;quot;, please see the following Fogbugz case for information on how to work around the problem. [https://isoftdata.fogbugz.com/f/cases/15251/ Fogbugz Case 15251]&lt;br /&gt;
&lt;br /&gt;
===TSC TTP 246M User Manual===&lt;br /&gt;
The tag printer user manual can be found at: \\file\ITRACK\Tech Support\Drivers\TTP_246M_344M.pdf&lt;br /&gt;
&lt;br /&gt;
===TSC Diagnostic Tool===&lt;br /&gt;
The wonderful folks over at TSC have created a diagnostic tool for their printers. This tool can read the printer status and tell you error the LED codes are describing, what version of printer it is, firmware version, driver version, allow you to do printer configuration and initialization without requiring the user to hold down buttons and interpret codes, set the printer settings described above without having to use the properties dialog, and other magical things. You can find it at \\file\ITRACK\Tech Support\Drivers\DiagTool_133.zip. Just transfer the tool over to the client machine and launch it from anywhere. Note the tool may not work with older versions of firmware, on older tag printers. At the very least it works with a TTP TSC 247. Instructions for using the tool can be found in the user manual (TTP_245p_247_343p_345_user_manual_eng.pdf), which you can find in the same directory on //File/ as the tool.&lt;br /&gt;
&lt;br /&gt;
===TSC Tag Printer Warranties and Refunds===&lt;br /&gt;
If a customer is unhappy with their tag printer, they can receive a full refund from Bluestar Inc, the people we buy the printers from, if the purchase was 30 days ago or less. &lt;br /&gt;
&lt;br /&gt;
If the customer believes their tag printer is broken, all tag printers have a 24 month warranty repair policy offered directly by TSC. If the customer stands by their printer being broken, in order to get a warranty repair started, they must call TSC Tech Support and their technicians will work with them to identify what is broken and instruct them where to ship it for a warranty repair. None of that is ISoft&amp;#039;s responsibility other than getting the customer contact information they&amp;#039;d need.&lt;br /&gt;
&lt;br /&gt;
===TSC Technical Support===&lt;br /&gt;
Phone Number: 1-657-220-7995. Dave is most likely the one you&amp;#039;ll be speaking to.&amp;lt;br&amp;gt;&lt;br /&gt;
Old Number: 1-657-258-0808.&amp;lt;br&amp;gt;&lt;br /&gt;
Email: service@tscprinters.com&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Another Printer&amp;#039;s Driver is Overriding the TSC&amp;#039;s Settings===&lt;br /&gt;
Sometimes another printer&amp;#039;s driver is highly aggressive and does not play nice with other drivers on the system. The solution to this is to uninstall the offending driver that is throwing off the TSC driver, however, you will not be able to print to the offending printer on that computer.&lt;br /&gt;
&lt;br /&gt;
List of drivers that override TSC drivers:&lt;br /&gt;
* HP Laserjet 200 color M251&lt;br /&gt;
* Pretty much any Canon printer&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
	<entry>
		<id>https://wikido.isoftdata.com//index.php?title=ITrack/Quickbooks/Class_not_registered&amp;diff=12517</id>
		<title>ITrack/Quickbooks/Class not registered</title>
		<link rel="alternate" type="text/html" href="https://wikido.isoftdata.com//index.php?title=ITrack/Quickbooks/Class_not_registered&amp;diff=12517"/>
		<updated>2020-07-31T17:17:44Z</updated>

		<summary type="html">&lt;p&gt;Ghagemoser: Changed link to be the newer SDK file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:QuickbooksClassNotRegistered.png]]&lt;br /&gt;
&lt;br /&gt;
== Cause ==&lt;br /&gt;
The correct version of the Quickbooks SDK (the one that ITrack expects) is not installed.&lt;br /&gt;
&lt;br /&gt;
== Solution ==&lt;br /&gt;
[https://dl.isoftdata.com//qbsdk130.exe] and install the latest version of the Quickbooks SDK (the &amp;quot;Merchant Services&amp;quot; option is not needed) on the computer that is running ITrack.&lt;/div&gt;</summary>
		<author><name>Ghagemoser</name></author>
	</entry>
</feed>