We’re using a program at work called Fishbowl Inventory for managing our sample inventory. The program is a full blown ISRP (Inventory, Shipping, Receiving, and Packing) solution that does everything from sales order entry to warehouse logistics. It’s been pretty rock-solid (tho I do regular full backups/restores and database re-indexes). As of today, we are still using version 4.7 (very old) because the product road map changed after version 5.0 ( I’m not sure who drove their road map, but I feel the went the wrong way on a bunch of changes and every change was followed with huge bug lists). In a nutshell, Fishbowl is a Java application that uses a Firebird database to store it’s data. Upon the release of version 4.x, Fishbowl released a new “integration” feature that allowed developers to write applications that could communicate with Fishbowl via XML. This was a big “improvement”, since previously I had written a few applications directly against the DB that generates labels (another missing feature) with a Dymo thermal printer and ran into lots of problems because Fishbowl does not like DB SCHEMA changes (even very simple benign changes gave me and support many issues).
Fast forward 4 years and here I am, I need to get some data out of Fishbowl but I find the ODBC drivers very unstable and I get errors > 50% of the time when I try to pull data out of Fishbowl. I also tried their C# SDK and also received a bunch of random errors (probably because it’s for version 2011.7 vs. 4.7). Since I needed to get some data out, I did a quick google search and found somebody made a PHP wrapper called fishconnect based on the SDK for version 2010.4. It says it required Fishbowl Inventory 2010.4+ to work, but after reviewing the code (don’t have PHP server, so I didn’t test anything), I’m convinced that it will probably work for all previous versions back to v4.7. After a few minutes reading the code, I figured I could make myself a nice C# wrapper to use on our ASP.NET intranet site.
Here is a quick summary of what I used to put this together….
1. Have XSD file, now generate me some objects!
I grabbed the “fbimsg.xsd” from fishbowlconnect PHP project, which is also provided with the official Fishbowl Java SDK.
Microsoft has had the “XSD.EXE” for a long time, it will generate your objects based on a XSD file. The command was moved into the Visual Studio Command Prompt with VS2010. To use the XSD tool, go to your Microsoft Visual Studio 2010 folder and launch “Visual Studio Command Prompt (2010)”. Once your at a command prompt, type the following.
xsd <location of XSD>.xsd /s
Presto, you got a nice DAL that is strongly typed!!!
2. Communications with Fishbowl Requires a Big Endian Stream
Why MS only supports Little Endian streams out of the box is a mystery to me, maybe a push to use the MS stack? I don’t know, but regardless you have to solve this problem to talk with Fishbowl. I did a quick and dirty sample to get it working, but it was a terrible “permanent” solution and required “Allow unsafe code” to be enabled. I ran to StackOverflow to find somebody smarter with better code and ended up grabbing what I needed from Jon Skeet’s MiscUtil Library. With this, I now had full support for BigEndian data streams.
3. Approving Fishbowl Integrated Applications
Fishbowl Inventory requires you to approve all 3rd party applications in the Fishbowl Server GUI, before the become active. If you are running Fishbowl as a service you’ll have to stop it and then run it interactively. Once started, go to “Integrated Applications” and you should see Fishbowl Connect C# listed, select and check the green check mark to approve.
4. Putting it all together and a working example.
The final product consists of a single class called “FishbowlSession” that implements IDisposable. This class handles all the communications with fishbowl. In addition to this class we have a DAL that was created from our XSD file and a Utilities library to provide a few helpers. I wrote the main class by writing NUnit tests, if you want to test against your Fishbowl Server then change values in [Setup] test to reference valid data for your server (e.g. Server IP, Login, Password, Part Numbers).
If you find bugs please let me know, I only tested sending/receiving 4 message types so I’m not sure if all message types will work.
Example showing how to get the inventory for a part in Fishbowl.
private static string GetFishbowlPartInventory(string part)
{
string inventoryResults = "Fishbowl Inventory Offline!";
using (FishbowlSession fishbowlInventory = new FishbowlSession("192.168.168.168"))
{
// Connect to fishbowl using a valid login/password
fishbowlInventory.Connect("app","app");
// Make sure we are authenticated before we try to send/receive messages
if (fishbowlInventory.IsAuthenticated)
{
// Build PartTagQueryRqType Request
PartTagQueryRqType partTagQueryRqType = new PartTagQueryRqType { LocationGroup = "Product", PartNum = part };
// Submit Request and get Response
PartTagQueryRsType partTagQueryRsType = fishbowlInventory.IssueRequest<PartTagQueryRsType>(partTagQueryRqType);
// Unregister Part, show custom message
if (partTagQueryRsType.statusCode != "1000")
{
inventoryResults = Utilities.StatusCodeMessage(partTagQueryRsType.statusCode);
}
// Tag object is optional, if there is no tag element you can not get the quantity
if (partTagQueryRsType.Tag != null && partTagQueryRsType.Tag.Length > 0)
{
Tag tag = partTagQueryRsType.Tag[0];
inventoryResults = int.Parse(tag.Quantity) > 0
? tag.Quantity + " Available in Fishbowl Inventory."
: "No Inventory Available in Fishbowl Inventory.";
}
}
}
return inventoryResults;
}
IMPORTANT NOTE: There is an important caveat to this solution… Communication with the server will consume one of your seats that you have available based on your license key. This means, if your key only allows for 5 concurrent users and your app tries to connect when all the seats are full… it will fail! I have put a lot of other “things” in place to prevent this in my setup; short session timeouts, terminal server user caps, etc… but it’s still possible…
#1 by Mike on May 16, 2014 - 1:33 pm
Just an FYI…
We updated to the latest version of Fishbowl today, and your code is still going strong! No changes needed.
(We are only using the ImportRq and ExportRq transactions, but the main thing is the communication still works.)
Thanks again!
-Mike
#2 by L. on April 24, 2014 - 10:15 am
I am looking at the newest SDK and the C# example which uses EXAMPLE.FDB. Does it matter in which directory the FDB file is located?
#3 by Zach on April 24, 2014 - 11:42 am
I have not used a new version of Fishbowl or it’s SDK in a few years, but the example above was based on using the DB in the default location. I’d use the current SDK XSD file to generate a new wrapper, since things have probably change a lot over the past few years.
#4 by Vetri on May 10, 2013 - 9:53 pm
Thanks a lot… While login i am getting success status code and able to retrieve the session key..
#5 by Vetri on May 10, 2013 - 9:40 pm
i am using fishbowl 2011.5.. while inserting value i am “There was an error with database” error..But while retrieving value it doesn’t show errors but not retrieving the values.. Whether it is the version problem???
#6 by Vetri on May 10, 2013 - 7:42 am
Thank you zach.. Even the getInventory method is not retrieving the quantity.. it is always returning zero.. While directly using api calls it is retrieving the values but can’t able to insert..
#7 by Zach on May 10, 2013 - 8:29 am
As others have mentioned, the XML Requests have changed formats in newer versions of Fishbowl. Since I don’t have/use a newer version, I can’t test/upgrade anything to work with the new version of the software. You should find a new XSD (maybe in FB developer tools) of the current requests and generate new objects. Also, did you get any messages or errors (have you authorized the app, were you able to open a connection, what status did you get back on login, etc…). Good Luck!
#8 by Vetri on May 10, 2013 - 7:37 am
I am using SaveDiscountRq. Since it doesn’t have any dependency..
Even using api calls can’t able to insert but getting success status code.. what might be the problem??
#9 by Zach on May 10, 2013 - 8:30 am
Sorry, read the replies out of orders… this answers a bunch, what version of FB are you using. I will try the same call and see what I get.
#10 by Vetri on May 9, 2013 - 10:45 pm
Provide a sample code how to insert a record in fishbowl database using c#..
#11 by Zach on May 10, 2013 - 12:01 am
A bit vague, right… A row of what? Inserting data is similar to the inventory check example, just pick the right message type and fire away. If you plan to enter an order, you may need to add a customer first. I still have some apps that talk to the raw DB, but it’s a much better design paradigm to use the API.
#12 by Daniel on November 23, 2012 - 1:47 pm
Hey Zach,
So I’ve actually been using your wrapper for a over a year now and once they changed the API calls I stopped using the objects in your wrapper and just wrote out the XML request in a string. But now I’m reading the comments and I see that I can update your wrapper by making new objects out of an updated XSD. So my question is where do I find the XSD? I found the PHP sample code at http://www.fishbowlinventory.com/developer-network/tools but there were no XSD files. Any chance you know were I can find those?
Daniel
#13 by Zach on November 27, 2012 - 4:51 pm
You can create your own XSD file using the Microsoft XML Schema Definition Tool, this is what I used to build my XSD file for the original project. If possible, please send me a copy of your working XSD/XML file along with your version of Fishbowl, so I can post it in the thread for others to download. Thanks!
#14 by Mike on September 18, 2012 - 2:34 pm
FYI – it works perfectly with the latest release of Fishbowl.
Nice job.
#15 by Zach on September 19, 2012 - 7:19 am
Mike,
I’m glad it worked on the new version of fishbowl, can you tell me the specific version number so I can add it to the post as confirmed working. Thanks.
Zach
#16 by Mike on September 6, 2012 - 10:47 am
Hi Zach,
Just checking to see if you have updated the code at all since April.
Fishbowl has done some updates, so I wonder if you are updating as well. Hopefully none of their changes will affect your code too much.
Thanks
#17 by Zach on September 6, 2012 - 2:43 pm
I’ve not updated my version of FB since v4.7 (~2005′). I thought about upgrading to 5.x, but they changed a lot of feature we build our processes around and it was going add hiccups to our workflow. Also, their prices went trough the roof if your using basic ISRP features. I think we paid ~4.5K for a 6 user edition, and the last time I got a quote for adding a user the price was ~1.5K per/additional user. If you do get a chance to try it out, let me know your results. It should be pretty easy to adapt the code to a different set of messages, as long as they provide specs in their SDK. I’ve been using the code in a production website with real-time stock checks for over a year without any problems.
Zach
#18 by Mike on April 10, 2012 - 1:36 pm
True. Although Fishbowl may be requiring developers to join the FDN (Fishbowl Developer Network) to get the latest SDK, which is kinda steep, at $1495 per year. I just checked their web site.
Looks like documentation and code samples are still available for download, though.
Thanks for your help today.
I’ve been told by my colleagues that recent versions of Fishbowl are much improved from earlier versions, probably the ones you refer to after 4.7.
#19 by Mike on April 10, 2012 - 12:51 pm
I got the connection working, by the way.
Up until now, I had been using Fishbowl’s DLL in my .NET code.
As you may be aware, Fishbowl disontinued their DLL for .NET in 2012.
So you may be getting a little more traffic as people discover that their code doesn’t work after upgrading!
#20 by Zach on April 10, 2012 - 1:00 pm
Interesting news, I didn’t know they discontinued it. I’m still way far behind on versions, we are still running 4.7x in production because they went and changed everything (for the worse) on 5.0+. I generated my objects based on a old XSD file I found for v.2010, if people need support for new features/functions, they can probably re-generate the objects using later XSD file that will probably be included with the Java SDK.
#21 by Mike on April 10, 2012 - 12:43 pm
Is the “endian” problem simply because of the encryption of the key? I thought XML was plain text…so I was surprised that you had to handle that.
#22 by Zach on April 10, 2012 - 12:47 pm
Java requires raw socket data to be “endian” and since FB was written in Java, this is an inter-op issue between .NET and Java (nothing really to do with FB). The data you are sending to FB is RAW XML.
#23 by Mike on April 10, 2012 - 12:36 pm
Just saw your 2nd response. Thanks!
#24 by Mike on April 10, 2012 - 12:34 pm
I was under the impression that your connect method performed a login and obtained a key.
Is the login a separate process?
I see that SessionKey is a public variable of the fishbowlInventory object, so I think I’m almost there.
#25 by Zach on April 10, 2012 - 12:38 pm
I have an overload of the Connect method that does a login if you pass it a “userName” and “password”. In my example I’m using the overload.
#26 by Mike on April 10, 2012 - 12:20 pm
I see now that I need to start from the tag, which is a switch from the SDK version.
Do you include a wrapper function that does that?
Otherwise, how do I get the value for the key to include?
Thanks,
Mike
#27 by Zach on April 10, 2012 - 12:29 pm
Yes, I have a wrapper for it since I need the ticket for all remaining requests. In the code example above, this line “fishbowlInventory.Connect(“app”,”app”);” is doing the opening of the connection to the server and a login where it captures the ticket key. I also implemented Dispose() on my object, since you want to make sure you disconnect from the server when your done or you’ll leave open connections that will exceed the max connections allowed for your FB License Key.
#28 by Mike on April 10, 2012 - 11:57 am
Thanks for converting the fishconnect project…I had the same idea, but not enough time (or skill…I didn’t know about the whole Endian problem).
If I want to send raw XML in the request, what is the first element I need to start with?
Thanks,
Mike
#29 by Zach on April 10, 2012 - 12:09 pm
If you want to send raw XML, you should download the Fishbowl SDK and review the documentation. It’ll give you detailed examples of all the XML requests/responses that you’ll share with the server. The first thing you’ll send is a “LoginRq” (XML sample can be found in SDK) which will send back a ticket that you’ll need for your remaining requests.