Quickbooks Copy Over To Dropbox via Volume Shadow Copy Service

It’s a long title for a blog post that is very specific.

Here is the use case:

We want to backup our quickbooks file daily to Dropbox. The issue is that Quickbooks will lock the files while it is in use giving you sharing violations when trying to copy the files.

This means that in order to backup your quickbooks files you need to close down quickbooks and then run a backup. Annoying! Thankfully Windows XP and above have a service that is called Volume Shadowing. You can read all about it on the internet[s] :-D.

Previous *broken* solution

Just put all your Quickbook files straight into Dropbox… Bam! Your done, right!?  Well, it’s great if you only have one person accessing that Dropbox.  Let’s say you want someone across the country or, in our case, different countries accessing the files.  That person then has a share to the folder.

The problem comes if that other person either touches the files in anyway.  It could be through opening the files in Quickbooks, renaming, or anything.  If Dropbox sees a change it will do an upload of the files.

The problem is that at the original location, those files have been changing with new information.  Now the files end up getting overwritten and we have been finding that we can loose a days worth of information.

Eeeek! Bad news, right!  It’s nobody’s fault, it’s just that it’s hard to be careful not to change anything in Dropbox if you are on the side of the person that just wants to view the information not to write no data.

The final solution

  • Move Quickbook files out of the Dropbox folder.
  • Create a Windows task that runs daily.  The task will fire off a script (batch file).
  • The batch file mounts an additional drive that uses Volume Shadow Copy Service (also called Volume Snapshot Service or VSS)
  • The batch file copies the files through VSS that would have otherwise been inaccessible.
Details

There are many many ways to access the VSS and do this sort of thing.  I ended up coming across the following tools to help me out from this blog:

  • Volume Copy Simple Client – This just abstracts the built in volume shadow command line tool.
  • DosDev – Command line interface to the DefineDosDevice() and QueryDosDevice() API functions.  (In Windows 95/98/ME this utility is equivalent to the SUBST command.)
Now for the script…
I ended up with two scripts but I am sure you can put this together into one script:
QuickbooksCopyToDropbox.bat
This is called by the scheduler
1
2
3
@echo off

vscsc -exec=C:\\Scripts\QuickbooksCopyToDropboxRun.bat C:
QuickbooksCopyToDropboxRun.bat
1
2
3
4
5
6
7
8
9
10
11
12
rem DOS Volume Name to be assigned to the snapshot
set SNAPDOS=B:

rem The source folder and the destination folder
set DOCS_SRC=%SNAPDOS%\Users\\Documents\Quickbooks
set DOCS_DST=C:\Users\\Documents\Dropbox

dosdev %SNAPDOS% %1%\

xcopy %DOCS_SRC%\* %DOCS_DST%\* /Q /Y /R > %LOGFILE%

dosdev /D %SNAPDOS%
Done!

Erply Inventory Registration – Automatically Scan Each Item

We wanted to just continue to scan each piece of inventory without having to interact with the computer from Erply.  On the Inventory Registration page, When you enter a barcode number a drop down box is displayed with one item. Erply, by default, will not select it automatically but waits for you to select.  Once the page refreshes (which I wish it didn’t), it puts the focus on the price box.  The way we want to work is just to continue scanning and come back later to fill in price.  This script is the solution for us in this use case.

Script Download: http://userscripts.org/scripts/show/151067

Script Description:

This helps in inventory registration for Erply. If you are scanning your items into Erply this script helps by automatically clicking on the one barcode dropdown that is selected and then once the page reloads it selects the next open text box ready for you to scan another barcode.  By default, Erply will wait for keyboard input for you once you scan an item.

Details

Below is a picture.  If the script is installed correctly then you will see a fish in the upper right corner of the screen.  This means that the script is installed and working on the inventory registration page.

Next thing to do is start scanning away!

You will notice one you start scanning that the drop-down will appear for a moment and then the script will select the only one listed.  The page will quickly refresh and then the script will select the bottom barcode/name box.

Let me know if you have questions!

Yii Framework Hide index.php from Url

Be sure to follow the guide: http://www.yiiframework.com/doc/guide/1.1/en/topics.url

One thing I was missing is that you need to make sure when modifying the rewrite rules that you have the following specified for either your virtual host or in the apache conf file:

AllowOverride All

Yours might look like:

<Directory “C:/Development/Workspace_Juno/ErplyWeb”>

AllowOverride All
Order Allow,Deny
Allow from all
Options +Indexes

</Directory>

Using Erply InventoryAPI

Erply has some awesome api’s available to access backend data.  I particularly was interested in loading a bunch of suppliers through a spreadsheet saved in CSV format. I would like a quick import button but this works great as well!

I made a quick script to load in the file. Done 😀

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php
/**
 * Used for importing Suppliers into Erply from a CSV spreadsheet.
 *
 * The format should look something like this:
 *
 * Code | First & Last Name | GroupID number | Notes
 *
 * Example:
 * 100  Dieula Etienne  7 ED
 *
 */

ini_set('max_execution_time', 180);
 
session_start();

// include ERPLY API class
include('EAPI.class.php');

// Initialise class
$api = new EAPI();

// Configuration settings
$api->url = "https://s3.erply.com/api/";
$api->clientCode = "49102";
$api->username = "<insert username>";
$api->password = "<insert password>";


////////////////////////////////////
// Supplier Groups
////////////////////////////////////
function getSupplierGroups() {
  $supplierGroups = $api->sendRequest("getSupplierGroups", array());
  $supplierGroupsOutput = json_decode($supplierGroups, true);
 
  print "<pre>";
  print_r($supplierGroupsOutput);
  print "</pre>";
}


////////////////////////////////////
// Load CSV
////////////////////////////////////
function loadCSV() {
  $csv = array();
  $lines = file('suppliers.csv', FILE_IGNORE_NEW_LINES);
 
  foreach ($lines as $key => $value)
  {
      $csv[$key] = str_getcsv($value);
  }
   
  echo '<pre>';
  print_r($csv);
  echo '</pre>';
 
  return $csv;
}


////////////////////////////////////
// Get Suppliers
////////////////////////////////////

// Get client groups from API
// No input parameters are needed
$result = $api->sendRequest("getSuppliers", array("recordsOnPage" => 100));

// Default output format is JSON, so we'll decode it into a PHP array
$suppliers = json_decode($result, true);
//print_r($suppliers);

print "<pre>";
foreach (loadCSV() as $key => $row) {
  $newCode = $row[0];
  list($newFirst, $newLast) = explode(" ", $row[1]);
  $newGroupID = $row[2];
  $newNote = $row[3];
  print "$newFirst | $newLast | $newCode | $newGroupID | $newNote <br />";
 
  $isFound = FALSE;
  $supplierId;
 
  foreach ($suppliers["records"] as $key => $value) {
    //print "Value code: " . strcmp($value["code"],$newCode) . " | " . $value["code"] . " | " . $newCode . " | <br />";
   
    if(isset($value["code"]) && strcmp($value["code"],$newCode) == 0) {
      $isFound = TRUE;
      $supplierId = $value["supplierID"];
      print "Found Code: $newCode for $newFirst with supplier id of $supplierId <br />";
      break;
    }
  }

  $saveSupplier;
 
  if ($isFound) {
    //Update supplier  
    $saveSupplier = array(
      "supplierID" => $supplierId,
      "firstName" => $newFirst,
      "lastName" => $newLast,
      "groupID" => $newGroupID,
      "notes" => $newNote,
      "code" => $newCode
    );
    print "Supplier will be *updated* with code: $newCode for $newFirst <br />\n";

  } else {
    //New Supplier
    $saveSupplier = array(
      "firstName" => $newFirst,
      "lastName" => $newLast,
      "groupID" => $newGroupID,
      "notes" => $newNote,
      "code" => $newCode
    );
    print "New Supplier will be added with code: $newCode for $newFirst <br />\n";
       
  }
 
  $result = $api->sendRequest("saveSupplier", $saveSupplier);
  $suppliers = json_decode($result, true);
  print_r($suppliers);
  break;
}




print "</pre>";

?>

The script works great but I do have an issue with names that have special characters for example: “Marléne Dessalines”. The “é” get’s cut off. I haven’t spent anytime to see if it’s a problem with CurL or if it’s an issue with the server accepting it.

Posted in PHP

Printing Labels from a Zebra LP2824 Printer in Erply

We are beginning to use Erply system for inventory. By the way, it is a fantastic system! Anyway… we were wanting to get the Zebra LP2824 Plus printer working here in Haiti.  Unfortunately, at this time of writing, there wasn’t an option to print a 2 1/4″ x 1/2″ label in Erply.  No problemo!

Erply recommends that you use Firefox (which is a great browser – I happen to switch between Google Chrome and Firefox).  So if you are using Firefox then you can head over and install Greasemonkey addon.

Then you can install the greasemonkey script for printing the barcode labels:

http://userscripts.org/scripts/show/138788

To use: You will need to pick “Barcode label (90mm x 14mm). The next page will automatically size the image and barcodes to fit the 2 1/4″ x 1/2”.

This script makes the label large enough so that the iPad Point of Sale application will be able to scan the barcode printed. Most barcode scanners will work but the label wasn’t large enough for the iPad to scan it.

Details:

– This script is made specifically for printing only EAN-8 labels. If you want to print EAN-13 you will need to adjust the script manually.

– Won’t work if you want to print the mass of the item on the label.

Sencha Touch 2 Showing Old Data After Refresh on Production

I am not totally understanding why even after updating production and seeing the correct delta’s that I am seeing the old site information.

For now: I have figured out that you can clear the local storage in google chrome (very easy to do).

On my andriod device I needed to do the following in the browser url bar:

javascript:localStorage.clear();

This would then allow me to see the newest production site.

I am hoping this problem is because I have been messing around and deleting the production base. Guessing I will learn more once I get closer to actually putting it in production!

VirtualHost Forbidden on Windows 7 using XAMPP

Thought I would share a quick fix that was needed to have local subdomain when running XAMPP on Windows 7.

Go to C:\WINDOWS\system32\drivers\etc then locate ‘hosts’ file. NOTE: Create a backup of the file before editing.

Update it to include your virtual host:

127.0.0.1 localhost
127.0.0.1 dummy.localhost

Here is the reference I found:  http://www.codingcereal.com/2011/05/setting-up-multiple-subdomains-in-your-localhost-using-xampp/

Buying SSL Certificate from GoDaddy and Installing on Amazon EC2 Apache Instance

I ended up choosing GoDaddy.  I bought it for a year just in case things didn’t pan out as it was my first time buying and setting this type of thing up.

What I bought was a ssl certificate that will allow us to process credit card payments directly on our website. For example, when you buy something online your website will get a certificate that says, “I am really the merchant who I say I am and you can trust me”. If you don’t have a certificate that is from a trusted source then you web browser will pop-up a message saying, “this could be an intruder trying to steal your information”. Worse yet, if you don’t secure your site then credit card numbers are in plain sight for anybody to capture as the information travels through the internet.

It is pretty important to buy a certificate for the buyers protection and for the protection of the organization. The certificates ranges from $20/year to over $1000/year depending on where you buy them. The key is that you get them from a reliable, trusted source. Especially a source that you know will be around for a long time. Microsoft, Google and others will not trust just any company. You need a company that other companies trust. I went with GoDaddy because it is very cost effective but as a trusted company.

What did I do:

  • Bought a Turbo SSL Certificate from GoDaddy
  • Sign into the SSL Certificate Management
  • You will see a line amongst the clutter “SSL Certificate”  *New Certificate*  then the button “Launch”.
  • Add your CSR.  You will see “Enter your Certificate Signing Request (CSR) below”
  • To learn about generating the CSR you can go here

Generate the Certificate:

  • I made a new folder under /etc/ssl called /newcerts

/etc/ssl/newcerts$ sudo openssl req -new -newkey rsa:2048 -nodes -keyout heartlineministries.key -out heartlineministries.csr

  • Couple notes from GoDaddy help on answering the questions:

Common Name: The fully-qualified domain name, or URL, you’re securing.  If you add the name with www.domain.com then it will work for both www.domain.com and domain.com.

Organization: The legally-registered name for your business. If you are enrolling as an individual, enter the certificate requestor’s name.

 Verify Host

  • You will need to verify that you own the domain you are registering the certificate to. The easiest method, in my mind, is that you put the file on your server but you can either put a file on your server or add a TXT DNS record with a specific value.
  • After you are verified you will be able to download the certificate in a zip file.  GoDaddy has excellent instructions on how to install the certificate depending on what host you will be using.  For DreamHost, I downloaded the “cpanel/web managed” option.

Host Configuration

  • I have signed up for DreamHost. We are thankful for them! This is perfect because they all SSL whereas our previous place did not.
  • You will need to add the ability to have a static ip address.  In the case of DreamHost, this costed an extra $3.95/month.
  • In order to load your certificate you will need the private key, public certificate (crt) and optionally the certificate signing request (csr).
After this is all done, you are ready for HTTPS protocol!

 

Mobile Credit Card Processing

I signed up for two different mobile payment processing options.  I have ordered the Square (which is free) and have applied for the GoPayment (which has a two-month free trial).  The GoPayment will also send a free credit card scanner.  I figured we can just choose which one we like better 😉

Advantage / Disadvantage

Both Have
  • Mobile apps for ipad/iphone/android
Square
  • + More popular
  • + Possibly easier (not sure until we try 🙂
  • – Higher fee 2.75%
  • – No link with Quickbooks
GoPayment
  • + Links with Quickbooks (made by Intuit the same guys that make Quickbooks)
  • + Lower credit card fees 1.64% + 0.27 cents
  • –  Monthly fee 15.95