1 25 26 package org.ofbiz.order.thirdparty.taxware; 27 28 29 import java.io.File ; 30 import java.io.FileNotFoundException ; 31 import java.io.FileOutputStream ; 32 import java.io.IOException ; 33 import java.util.ArrayList ; 34 import java.util.Date ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 38 import org.ofbiz.base.util.Debug; 39 import org.ofbiz.base.util.UtilMisc; 40 import org.ofbiz.base.util.UtilProperties; 41 import org.ofbiz.base.util.UtilURL; 42 import org.ofbiz.datafile.DataFile; 43 import org.ofbiz.datafile.DataFileException; 44 import org.ofbiz.datafile.ModelRecord; 45 import org.ofbiz.datafile.ModelField; 46 import org.ofbiz.datafile.Record; 47 import org.ofbiz.entity.GenericDelegator; 48 import org.ofbiz.entity.GenericValue; 49 50 51 59 public class TaxwareUTL { 60 61 public static final String module = TaxwareUTL.class.getName(); 62 63 DataFile outHead = null; 65 DataFile outItem = null; 66 67 double shippingAmount = 0.00; 68 List orderAdjustments = new ArrayList (); 69 List itemAdjustments = new ArrayList (); 70 71 boolean setShipping = false; 72 GenericValue shipToAddress = null; 73 74 List records = new ArrayList (); 76 boolean processed = false; 77 78 public TaxwareUTL() throws TaxwareException { 79 init(); 80 } 81 82 public int process() throws TaxwareException { 83 checkFields(); 85 86 if (processed) 87 throw new TaxwareException("Cannot re-process records."); 88 processed = true; 89 90 Iterator i = records.iterator(); 91 92 while (i.hasNext()) { 93 Record rec = (Record) i.next(); 94 95 rec = makeItemData(rec); 96 outItem.addRecord(rec); 97 } 98 99 if (shippingAmount > 0) { 101 Record shipping = outItem.makeRecord("outItem"); 102 103 shipping = makeItemData(shipping); 104 shipping.set("FREIGHT_AMOUNT", new Double (shippingAmount)); 105 outItem.addRecord(shipping); 106 } 107 108 Record header = outHead.makeRecord("outHead"); 110 111 header.set("NUMBER_RECORDS", new Long (outItem.getRecords().size())); 112 header.set("PROCESS_INDICATOR", "1"); 113 outHead.addRecord(header); 114 115 int returnCode = -1; 116 117 try { 118 StringBuffer outBuffer = new StringBuffer (); 120 121 outBuffer.append(outHead.writeDataFile()); 122 123 outBuffer.append(outItem.writeDataFile()); 125 126 if (Debug.verboseOn()) Debug.logVerbose("::Out String::", module); 128 if (Debug.verboseOn()) Debug.logVerbose("\"" + outBuffer.toString() + "\"", module); 129 130 File outFile = new File ("TAXWARE-TEST.IN"); 131 FileOutputStream fos = null; 132 133 try { 134 fos = new FileOutputStream (outFile); 135 } catch (FileNotFoundException e) { 136 e.printStackTrace(); 137 } 138 outHead.writeDataFile(fos); 139 outItem.writeDataFile(fos); 140 try { 141 fos.close(); 142 } catch (IOException e) { 143 e.printStackTrace(); 144 } 145 146 outItem.writeDataFile("TaxwareTest.in"); 147 148 StringBuffer retBuffer = taxCalc(outBuffer); 149 150 returnCode = processOutFile(retBuffer); 152 } catch (DataFileException dfe) { 153 throw new TaxwareException("Problems with the data file.", dfe); 154 } 155 156 return returnCode; 157 } 158 159 public void setShipping(double shippingAmount) { 160 this.shippingAmount = shippingAmount; 161 setShipping = true; 162 } 163 164 public void setShipAddress(GenericValue v) { 165 this.shipToAddress = v; 166 } 167 168 public void addItem(GenericValue product, double linePrice, double itemShipping) { 169 Record record = outItem.makeRecord("outItem"); 170 171 if (product.get("taxable") == null || product.getString("taxable").equalsIgnoreCase("Y")) { 172 if (product.get("taxCategory") != null) 173 record.set("COMMODITY_PRODUCT_CODE", product.get("taxCategory")); 174 else 175 record.set("COMMODITY_PRODUCT_CODE", "DEFAULT"); 176 record.set("PART_NUMBER", product.get("productId")); 177 record.set("LINE_ITEM_AMOUNT", new Double (linePrice)); 178 if (itemShipping > 0) 179 record.set("FREIGHT_AMOUNT", new Double (itemShipping)); 180 } 181 records.add(record); 182 } 183 184 public List getItemAdjustments() { 185 return itemAdjustments; 186 } 187 188 public List getOrderAdjustments() { 189 return orderAdjustments; 190 } 191 192 private void init() throws TaxwareException { 193 TaxwareUTL.loadLib(); 194 outHead = createDataFile("TaxwareOutHead"); 195 outItem = createDataFile("TaxwareOutItem"); 196 } 197 198 private Record makeItemData(Record record) { 199 addStaticData(record); 200 addAddresses(record); 201 record.set("TAXSEL_PARM", "3"); 202 record.set("SYSTEM_INDICATOR", "1"); 203 record.set("INVOICE_DATE", new java.sql.Date (new Date ().getTime())); 204 return record; 205 } 206 207 private void addStaticData(Record record) { 208 record.set("COMPANY_ID", UtilProperties.getPropertyValue("taxware.properties", "COMPANY_ID", " ")); 210 record.set("AUDIT_FILE_INDICATOR", UtilProperties.getPropertyValue("taxware.properties", "AUDIT_FILE_INDICATOR", "2")); 211 record.set("SF_COUNTRY_CODE", UtilProperties.getPropertyValue("taxware.properties", "SF_COUNTRY_CODE", "")); 212 record.set("SF_STATE_PROVINCE", UtilProperties.getPropertyValue("taxware.properties", "SF_STATE_PROVINCE", " ")); 213 record.set("SF_CITY", UtilProperties.getPropertyValue("taxware.properties", "SF_CITY", " ")); 214 record.set("SF_POSTAL_CODE", UtilProperties.getPropertyValue("taxware.properties", "SF_POSTAL_CODE", " ")); 215 record.set("POO_COUNTRY_CODE", UtilProperties.getPropertyValue("taxware.properties", "POO_COUNTRY_CODE", "")); 216 record.set("POO_STATE_PROVINCE", UtilProperties.getPropertyValue("taxware.properties", "POO_STATE_PROVINCE", " ")); 217 record.set("POO_CITY", UtilProperties.getPropertyValue("taxware.properties", "POO_CITY", " ")); 218 record.set("POO_POSTAL_CODE", UtilProperties.getPropertyValue("taxware.properties", "POO_POSTAL_CODE", " ")); 219 record.set("POA_COUNTRY_CODE", UtilProperties.getPropertyValue("taxware.properties", "POA_COUNTRY_CODE", "")); 220 record.set("POA_STATE_PROVINCE", UtilProperties.getPropertyValue("taxware.properties", "POA_STATE_PROVINCE", " ")); 221 record.set("POA_CITY", UtilProperties.getPropertyValue("taxware.properties", "POA_CITY", " ")); 222 record.set("POA_POSTAL_CODE", UtilProperties.getPropertyValue("taxware.properties", "POA_POSTAL_CODE", " ")); 223 } 224 225 private void addAddresses(Record record) { 226 if (shipToAddress != null) { 228 if (shipToAddress.get("countryGeoId") == null) { 230 record.set("ST_COUNTRY_CODE", "US"); 231 } else if (shipToAddress.getString("countryGeoId").equals("USA")) { 232 record.set("ST_COUNTRY_CODE", "US"); 233 } else { 234 record.set("ST_COUNTRY_CODE", shipToAddress.get("countryGeoId")); 235 } 236 record.set("ST_COUNTRY_CODE", "US"); 237 record.set("ST_STATE_PROVINCE", shipToAddress.get("stateProvinceGeoId")); 238 record.set("ST_CITY", shipToAddress.get("city")); 239 record.set("ST_POSTAL_CODE", shipToAddress.get("postalCode")); 240 } 241 } 242 243 private DataFile createDataFile(String dataFile) throws TaxwareException { 244 DataFile df = null; 245 246 try { 247 df = DataFile.makeDataFile(UtilURL.fromResource("org/ofbiz/thirdparty/taxware/TaxwareFiles.xml"), dataFile); 248 } catch (DataFileException e) { 249 Debug.logError(e, module); 250 throw new TaxwareException("Cannot load datafile."); 251 } 252 return df; 253 } 254 255 public static void loadLib() throws TaxwareException { 256 try { 257 System.loadLibrary("taxcommon"); 258 } catch (UnsatisfiedLinkError e) { 259 Debug.logError(e, module); 260 throw new TaxwareException("Cannot load libtaxcommon.so/taxcommon.dll.", e); 261 } 262 } 263 264 private StringBuffer taxCalc(StringBuffer outBuffer) throws DataFileException, TaxwareException { 265 StringBuffer inBuffer = new StringBuffer (); 266 int result = callTaxware(outBuffer.toString(), inBuffer); 267 268 if (Debug.verboseOn()) Debug.logVerbose("Taxware Return: " + result, module); 269 if (result != 1) 270 throw new TaxwareException("Taxware processing failed (" + result + ")"); 271 272 if (Debug.verboseOn()) Debug.logVerbose("::Return String::", module); 273 if (Debug.verboseOn()) Debug.logVerbose("\"" + inBuffer.toString() + "\"", module); 274 return inBuffer; 275 } 276 277 private int callTaxware(String inString, StringBuffer outBuffer) throws TaxwareException { 278 try { 279 return taxcommon.CalculateTax(inString, outBuffer); 280 } catch (Exception e) { 281 throw new TaxwareException("Problems running JNI wrapper.", e); 282 } 283 } 284 285 private void checkFields() throws TaxwareException { 286 if (!setShipping) 287 throw new TaxwareException("Shipping amount has not been set."); 288 if (shipToAddress == null) 289 throw new TaxwareException("Shipping address has not been set."); 290 if (records.size() == 0) 291 throw new TaxwareException("No items have been defined."); 292 } 293 294 private int processOutFile(StringBuffer retBuffer) throws DataFileException, TaxwareException { 295 DataFile retHead = createDataFile("TaxwareInHead"); 296 DataFile retItem = createDataFile("TaxwareInItem"); 297 String headStr = retBuffer.toString().substring(0, 283); 298 String itemStr = retBuffer.toString().substring(284); 299 300 if (Debug.verboseOn()) Debug.logVerbose("Return Size: " + retBuffer.length(), module); 301 GenericDelegator delegator = shipToAddress.getDelegator(); 302 303 retHead.readDataFile(headStr); 304 retItem.readDataFile(itemStr); 305 306 List retRecords = retItem.getRecords(); 307 Iterator i = retRecords.iterator(); 308 309 if (Debug.verboseOn()) Debug.logVerbose("Returned Records: " + retRecords.size(), module); 310 if (Debug.verboseOn()) Debug.logVerbose("Sent Items: " + records.size(), module); 311 312 while (i.hasNext()) { 313 Record rec = (Record) i.next(); 314 ModelRecord model = rec.getModelRecord(); 315 316 if (itemAdjustments.size() < records.size()) { 318 List currentItem = new ArrayList (); 319 320 if (rec.getDouble("TAX_AMT_COUNTRY").doubleValue() > 0) { 321 if (Debug.verboseOn()) Debug.logVerbose("Country Tax Amount: " + rec.getDouble("TAX_AMT_COUNTRY"), module); 322 Double rate = new Double (rec.getDouble("TAX_RATE_COUNTRY").doubleValue() * 100); 323 String type = rec.getString("TAX_TYPE_COUNTRY").equals("S") ? "SALES TAX" : "USE TAX"; 324 String jur = rec.get("JUR_COUNTRY") != null ? rec.getString("JUR_COUNTRY").trim() : ""; 325 String comments = jur + "|" + type + "|" + rate.toString(); 326 327 currentItem.add(delegator.makeValue("OrderAdjustment", 328 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_COUNTRY"), 329 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 330 } 331 332 if (rec.getDouble("TAX_AMT_STATE").doubleValue() > 0) { 333 Double rate = new Double (rec.getDouble("TAX_RATE_STATE").doubleValue() * 100); 334 String type = rec.getString("TAX_TYPE_STATE").equals("S") ? "SALES TAX" : "USE TAX"; 335 String jur = rec.get("JUR_STATE") != null ? rec.getString("JUR_STATE").trim() : ""; 336 String comments = jur + "|" + type + "|" + rate.toString(); 337 338 currentItem.add(delegator.makeValue("OrderAdjustment", 339 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_STATE"), 340 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 341 } 342 343 if (rec.getDouble("TAX_AMT_COUNTY").doubleValue() > 0) { 344 Double rate = new Double (rec.getDouble("TAX_RATE_COUNTY").doubleValue() * 100); 345 String type = rec.getString("TAX_TYPE_COUNTY").equals("S") ? "SALES TAX" : "USE TAX"; 346 String jur = rec.get("JUR_COUNTY_CODE") != null ? rec.getString("JUR_COUNTY_CODE").trim() : ""; 347 String comments = jur + "|" + type + "|" + rate.toString(); 348 349 currentItem.add(delegator.makeValue("OrderAdjustment", 350 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_COUNTY"), 351 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 352 } 353 354 if (rec.getDouble("TAX_AMT_CITY").doubleValue() > 0) { 355 Double rate = new Double (rec.getDouble("TAX_RATE_CITY").doubleValue() * 100); 356 String type = rec.getString("TAX_TYPE_CITY").equals("S") ? "SALES TAX" : "USE TAX"; 357 String jur = rec.get("JUR_CITY") != null ? rec.getString("JUR_CITY").trim() : ""; 358 String comments = jur + "|" + type + "|" + rate.toString(); 359 360 currentItem.add(delegator.makeValue("OrderAdjustment", 361 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_CITY"), 362 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 363 } 364 365 if (rec.getDouble("TAX_AMT_SEC_STATE").doubleValue() > 0) { 366 Double rate = new Double (rec.getDouble("TAX_RATE_SEC_STATE").doubleValue() * 100); 367 String type = rec.getString("TAX_TYPE_SEC_STATE").equals("S") ? "SALES TAX" : "USE TAX"; 368 String jur = rec.get("JUR_SEC_STATE") != null ? rec.getString("JUR_SEC_STATE").trim() : ""; 369 String comments = jur + "|" + type + "|" + rate.toString(); 370 371 currentItem.add(delegator.makeValue("OrderAdjustment", 372 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_SEC_STATE"), 373 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 374 } 375 376 if (rec.getDouble("TAX_AMT_SEC_COUNTY").doubleValue() > 0) { 377 Double rate = new Double (rec.getDouble("TAX_RATE_SEC_COUNTY").doubleValue() * 100); 378 String type = rec.getString("TAX_TYPE_SEC_COUNTY").equals("S") ? "SALES TAX" : "USE TAX"; 379 String jur = rec.get("JUR_SEC_COUNTY_CODE") != null ? rec.getString("JUR_SEC_COUNTY_CODE").trim() : ""; 380 String comments = jur + "|" + type + "|" + rate.toString(); 381 382 currentItem.add(delegator.makeValue("OrderAdjustment", 383 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_SEC_COUNTY"), 384 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 385 } 386 387 if (rec.getDouble("TAX_AMT_SEC_CITY").doubleValue() > 0) { 388 Double rate = new Double (rec.getDouble("TAX_RATE_SEC_CITY").doubleValue() * 100); 389 String type = rec.getString("TAX_TYPE_SEC_CITY").equals("S") ? "SALES TAX" : "USE TAX"; 390 String jur = rec.get("JUR_SEC_CITY") != null ? rec.getString("JUR_SEC_CITY").trim() : ""; 391 String comments = jur + "|" + type + "|" + rate.toString(); 392 393 currentItem.add(delegator.makeValue("OrderAdjustment", 394 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_SEC_CITY"), 395 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 396 } 397 398 itemAdjustments.add(currentItem); 400 401 } else if (orderAdjustments.size() == 0) { 402 if (rec.getDouble("TAX_AMT_COUNTRY").doubleValue() > 0) { 403 Double rate = new Double (rec.getDouble("TAX_RATE_COUNTRY").doubleValue() * 100); 404 String type = rec.getString("TAX_TYPE_COUNTRY").equals("S") ? "SALES TAX" : "USE TAX"; 405 String jur = rec.get("JUR_COUNTRY") != null ? rec.getString("JUR_COUNTRY").trim() : ""; 406 String comments = jur + "|" + type + "|" + rate.toString(); 407 408 orderAdjustments.add(delegator.makeValue("OrderAdjustment", 409 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_COUNTRY"), 410 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 411 } 412 413 if (rec.getDouble("TAX_AMT_STATE").doubleValue() > 0) { 414 Double rate = new Double (rec.getDouble("TAX_RATE_STATE").doubleValue() * 100); 415 String type = rec.getString("TAX_TYPE_STATE").equals("S") ? "SALES TAX" : "USE TAX"; 416 String jur = rec.get("JUR_STATE") != null ? rec.getString("JUR_STATE").trim() : ""; 417 String comments = jur + "|" + type + "|" + rate.toString(); 418 419 orderAdjustments.add(delegator.makeValue("OrderAdjustment", 420 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_STATE"), 421 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 422 } 423 424 if (rec.getDouble("TAX_AMT_COUNTY").doubleValue() > 0) { 425 Double rate = new Double (rec.getDouble("TAX_RATE_COUNTY").doubleValue() * 100); 426 String type = rec.getString("TAX_TYPE_COUNTY").equals("S") ? "SALES TAX" : "USE TAX"; 427 String jur = rec.get("JUR_COUNTY_CODE") != null ? rec.getString("JUR_COUNTY_CODE").trim() : ""; 428 String comments = jur + "|" + type + "|" + rate.toString(); 429 430 orderAdjustments.add(delegator.makeValue("OrderAdjustment", 431 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_COUNTY"), 432 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 433 } 434 435 if (rec.getDouble("TAX_AMT_CITY").doubleValue() > 0) { 436 Double rate = new Double (rec.getDouble("TAX_RATE_CITY").doubleValue() * 100); 437 String type = rec.getString("TAX_TYPE_CITY").equals("S") ? "SALES TAX" : "USE TAX"; 438 String jur = rec.get("JUR_CITY") != null ? rec.getString("JUR_CITY").trim() : ""; 439 String comments = jur + "|" + type + "|" + rate.toString(); 440 441 orderAdjustments.add(delegator.makeValue("OrderAdjustment", 442 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_CITY"), 443 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 444 } 445 446 if (rec.getDouble("TAX_AMT_SEC_STATE").doubleValue() > 0) { 447 Double rate = new Double (rec.getDouble("TAX_RATE_SEC_STATE").doubleValue() * 100); 448 String type = rec.getString("TAX_TYPE_SEC_STATE").equals("S") ? "SALES TAX" : "USE TAX"; 449 String jur = rec.get("JUR_SEC_STATE") != null ? rec.getString("JUR_SEC_STATE").trim() : ""; 450 String comments = jur + "|" + type + "|" + rate.toString(); 451 452 orderAdjustments.add(delegator.makeValue("OrderAdjustment", 453 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_SEC_STATE"), 454 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 455 } 456 457 if (rec.getDouble("TAX_AMT_SEC_COUNTY").doubleValue() > 0) { 458 Double rate = new Double (rec.getDouble("TAX_RATE_SEC_COUNTY").doubleValue() * 100); 459 String type = rec.getString("TAX_TYPE_SEC_COUNTY").equals("S") ? "SALES TAX" : "USE TAX"; 460 String jur = rec.get("JUR_SEC_COUNTY_CODE") != null ? rec.getString("JUR_SEC_COUNTY_CODE").trim() : ""; 461 String comments = jur + "|" + type + "|" + rate.toString(); 462 463 orderAdjustments.add(delegator.makeValue("OrderAdjustment", 464 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_SEC_COUNTY"), 465 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 466 } 467 468 if (rec.getDouble("TAX_AMT_SEC_CITY").doubleValue() > 0) { 469 Double rate = new Double (rec.getDouble("TAX_RATE_SEC_CITY").doubleValue() * 100); 470 String type = rec.getString("TAX_TYPE_SEC_CITY").equals("S") ? "SALES TAX" : "USE TAX"; 471 String jur = rec.get("JUR_SEC_CITY") != null ? rec.getString("JUR_SEC_CITY").trim() : ""; 472 String comments = jur + "|" + type + "|" + rate.toString(); 473 474 orderAdjustments.add(delegator.makeValue("OrderAdjustment", 475 UtilMisc.toMap("amount", rec.getDouble("TAX_AMT_SEC_CITY"), 476 "orderAdjustmentTypeId", "SALES_TAX", "comments", comments))); 477 } 478 479 } else { 480 throw new TaxwareException("Invalid number of return adjustments."); 481 } 482 483 for (int a = 0; a < model.fields.size(); a++) { 484 ModelField mf = (ModelField) model.fields.get(a); 485 String name = mf.name; 486 String value = rec.getString(name); 487 488 if (Debug.verboseOn()) Debug.logVerbose("Field: " + name + " => " + value, module); 489 } 490 } 491 return retRecords.size(); 492 } 493 } 494 | Popular Tags |