// Wanda POS - Africa's Gift to the World // Copyright (c) 2014-2015 Wanda POS // http://www.wandaapos.com // Modified by Openbravo SL on March 22, 2007 // These modifications are copyright Openbravo SL // Author/s: A. Romero // You may contact Openbravo SL at: http://www.openbravo.com // // Contributor: Redhuan D. Oon - ActiveMQ XML read from MClient.readmessage() // Please refer to notes at http://red1.org/adempiere/viewtopic.php?f=29&t=1356 // // This file is part of Openbravo POS. // // Openbravo POS is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Openbravo POS is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Openbravo POS. If not, see <http://www.gnu.org/licenses/>. package com.openbravo.possync; import com.openbravo.activemq.ActiveMQClient; import com.openbravo.basic.BasicException; import com.openbravo.compiere.model.MBPartner; import com.openbravo.compiere.model.MLocation; import com.openbravo.compiere.model.MProduct; import com.openbravo.compiere.model.MProductPrice; import com.openbravo.compiere.model.MUser; import com.openbravo.data.gui.MessageInf; import com.openbravo.data.loader.ImageUtils; import com.openbravo.pos.customers.CustomerInfoExt; import com.openbravo.pos.forms.AppLocal; import com.openbravo.pos.forms.DataLogicSales; import com.openbravo.pos.forms.DataLogicSystem; import com.openbravo.pos.forms.ProcessAction; import com.openbravo.pos.inventory.MovementReason; import com.openbravo.pos.inventory.TaxCategoryInfo; import com.openbravo.pos.ticket.CategoryInfo; import com.openbravo.pos.ticket.ProductInfoExt; import com.openbravo.pos.ticket.TaxInfo; import com.openbravo.ws.externalsales.Category; import com.openbravo.ws.externalsales.Product; import com.openbravo.ws.externalsales.ProductPlus; import com.openbravo.ws.externalsales.Tax; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.StringReader; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Date; import java.util.UUID; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.TextMessage; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; public class ProductsQueueSync implements ProcessAction { private final DataLogicSystem dlsystem; private final DataLogicIntegration dlintegration; private final DataLogicSales dlsales; private final String warehouse; private ExternalSalesHelper externalsales; private String appUser = ""; /** * Creates a new instance of ProductsSync * * @param dlsystem * @param dlintegration * @param warehouse * @param dlsales * @param appUser */ public ProductsQueueSync(DataLogicSystem dlsystem, DataLogicIntegration dlintegration, DataLogicSales dlsales, String warehouse, String appUser) { this.dlsystem = dlsystem; this.dlintegration = dlintegration; this.dlsales = dlsales; this.warehouse = warehouse; externalsales = null; this.appUser = appUser; } @Override public MessageInf execute() throws BasicException { int productsSynch = 0; int customersSynch = 0; try { if (externalsales == null) { externalsales = new ExternalSalesHelper(dlsystem); } //red1 using XML string from ActiveMQ -- automatically check either path (so do not use same if u want to synch customers also) //red1 convert string to models deprecated approach below ActiveMQClient mqClient = new ActiveMQClient(externalsales.getActivemqBrokerUrl(), externalsales.getActivemqUsername(), externalsales.getActivemqPassword()); if (!mqClient.init()) { return new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.serviceexception")); } ArrayList<Message> customersMessageList = mqClient.consumeAllMessages(externalsales.getM_iERPPos() + externalsales.getCustomersQueue()); ArrayList<CustomerInfoExt[]> customersList = new ArrayList<>(); for (int i = 0; i < customersMessageList.size(); ++i) { customersList.add(importQueue2Customers(((TextMessage)customersMessageList.get(i)).getText())); } if (!customersList.isEmpty()) { dlintegration.syncCustomersBefore(); for (CustomerInfoExt[] customers : customersList) { for (CustomerInfoExt customer : customers) { // Synch this customer dlintegration.syncCustomer(customer); ++customersSynch; } } } ArrayList<Message> productsMessageList = mqClient.consumeAllMessages(externalsales.getM_iERPPos() + externalsales.getProductsQueue()); ArrayList<ProductPlus[]> productsList = new ArrayList<>(); for (int i = 0; i < productsMessageList.size(); ++i) { productsList.add(importQueue2Products(((TextMessage)productsMessageList.get(i)).getText())); } if (!productsList.isEmpty()) { for (ProductPlus[] products : productsList) { //dlintegration.syncProductsBefore(); Date now = new Date(); for (Product product : products) { if (product == null) { break; } // Synchonization of taxcategories TaxCategoryInfo tc = new TaxCategoryInfo(product.getTax().getId(), product.getTax().getName()); dlintegration.syncTaxCategory(tc); // Synchonization of taxes TaxInfo t = new TaxInfo(product.getTax().getId(), product.getTax().getName(), tc.getID(), null, null, product.getTax().getPercentage() / 100, false, 0); dlintegration.syncTax(t); // Synchonization of categories CategoryInfo c = new CategoryInfo(product.getCategory().getId(), product.getCategory().getName(), null, product.getCategory().getDescription(), true); dlintegration.syncCategory(c); // Synchonization of products ProductInfoExt p = new ProductInfoExt(); p.setID(product.getId()); p.setReference(product.getId()); p.setCode(product.getEan() == null || product.getEan().equals("") ? product.getId() : product.getEan()); p.setName(product.getName()); p.setCom(false); p.setScale(false); p.setPriceBuy(product.getPurchasePrice()); p.setPriceSell(product.getListPrice()); p.setCategoryID(c.getID()); p.setTaxCategoryID(tc.getID()); p.setImage(ImageUtils.readImage(product.getImageUrl())); dlintegration.syncProduct(p); // Synchronization of stock if (product instanceof ProductPlus) { ProductPlus productplus = (ProductPlus) product; double diff = productplus.getQtyonhand() - dlsales.findProductStock(warehouse, p.getID(), null); Object[] diary = new Object[9]; diary[0] = UUID.randomUUID().toString(); diary[1] = now; diary[2] = diff > 0.0 ? MovementReason.IN_MOVEMENT.getKey() : MovementReason.OUT_MOVEMENT.getKey(); diary[3] = warehouse; diary[4] = p.getID(); diary[5] = p.getAttributeSetID(); diary[6] = diff; diary[7] = p.getPriceBuy(); diary[8] = appUser; dlsales.getStockDiaryInsert().exec(diary); ++productsSynch; } } } // datalogic.syncProductsAfter(); } if (productsList.isEmpty() && customersList.isEmpty()) { return new MessageInf(MessageInf.SGN_NOTICE, AppLocal.getIntString("message.zeroproducts")); } } catch (/*ServiceException |*/ JMSException e) { throw new BasicException(AppLocal.getIntString("message.serviceexception"), e); } catch (SAXException | IOException | ParserConfigurationException e) { throw new BasicException(e); } return new MessageInf(MessageInf.SGN_SUCCESS, AppLocal.getIntString("message.syncproductsok"), AppLocal.getIntString("message.syncproductsinfo", productsSynch, customersSynch)); } private ProductPlus[] importQueue2Products(String productsXML) throws SAXException, IOException, ParserConfigurationException { if (productsXML.equals("")) { return new ProductPlus[0]; } DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new InputSource(new StringReader(productsXML))); Element docEle = doc.getDocumentElement(); NodeList records = docEle.getElementsByTagName("detail"); ProductPlus[] productList = new ProductPlus[records.getLength()]; for (int i = 0; i < records.getLength(); i++) { //check if XML type is about Products if (!records.item(i).getFirstChild().getTextContent().equals(MProduct.Table_Name)) { break; } NodeList details = records.item(i).getChildNodes(); ProductPlus product = new ProductPlus(); Tax newtax = new Tax(); newtax.setPercentage(0.0d); Category cate = new Category(); for (int j = 0; j < details.getLength(); j++) { Node n = details.item(j); String column = n.getNodeName(); if (column.equals("ProductName")) { product.setName(n.getTextContent()); } else if (column.equals(MProduct.COLUMNNAME_M_Product_Category_ID)) { cate.setId(n.getTextContent()); product.setCategory(cate); } else if (column.equals("CategoryName")) { cate.setName(n.getTextContent()); product.setCategory(cate); } else if (column.equals(MProduct.COLUMNNAME_M_Product_ID)) { product.setId(n.getTextContent()); } else if (column.equals(MProduct.COLUMNNAME_C_TaxCategory_ID)) { newtax.setId(n.getTextContent()); product.setTax(newtax); } else if (column.equals("TaxName")) { newtax.setName(n.getTextContent()); product.setTax(newtax); } else if (column.equals("QtyOnHand")) { product.setQtyonhand(Double.parseDouble(n.getTextContent())); } else if (column.equals(MProductPrice.COLUMNNAME_PriceList)) { product.setListPrice(Double.parseDouble(n.getTextContent())); } else if (column.equals(MProductPrice.COLUMNNAME_PriceLimit)) { product.setPurchasePrice(Double.parseDouble(n.getTextContent())); } else if (column.equals(MProduct.COLUMNNAME_UPC)) { product.setEan(n.getTextContent()); } } productList[i] = product; } return productList; } private CustomerInfoExt[] importQueue2Customers(String customersXML) throws ParserConfigurationException, SAXException, IOException { if (customersXML.equals("")) { return new CustomerInfoExt[0]; } DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new InputSource(new StringReader(customersXML))); Element docEle = doc.getDocumentElement(); NodeList records = docEle.getElementsByTagName("detail"); CustomerInfoExt[] customer = new CustomerInfoExt[records.getLength()]; for (int i = 0; i < records.getLength(); i++) { if (!records.item(i).getFirstChild().getTextContent().equals(MBPartner.Table_Name)) { break; } customer[i] = new CustomerInfoExt(""); NodeList details = records.item(i).getChildNodes(); for (int j = 0; j < details.getLength(); j++) { Node n = details.item(j); String column = n.getNodeName(); switch (column) { case "CustomerName" : customer[i].setName(n.getTextContent()); break; case MBPartner.COLUMNNAME_Value : customer[i].setSearchkey(n.getTextContent()); break; case MBPartner.COLUMNNAME_C_BPartner_ID : customer[i].setId(n.getTextContent()); break; case MBPartner.COLUMNNAME_Description : customer[i].setNotes(n.getTextContent()); break; case MBPartner.COLUMNNAME_TaxID : customer[i].setTaxid(n.getTextContent()); break; case MLocation.COLUMNNAME_Address1 : customer[i].setAddress(n.getTextContent()); break; case MLocation.COLUMNNAME_Address2 : customer[i].setAddress2(n.getTextContent()); break; case MLocation.COLUMNNAME_City : customer[i].setCity(n.getTextContent()); break; case "RegionName" : customer[i].setRegion(n.getTextContent()); break; case "Country" : customer[i].setCountry(n.getTextContent()); break; case "Image" : customer[i].setImage(n.getTextContent()); break; case MUser.COLUMNNAME_EMail : customer[i].setEmail(n.getTextContent()); break; case MUser.COLUMNNAME_Fax : customer[i].setFax(n.getTextContent()); break; case MUser.COLUMNNAME_Name : customer[i].setName(n.getTextContent()); break; case MUser.COLUMNNAME_Phone : customer[i].setPhone(n.getTextContent()); break; case MUser.COLUMNNAME_Phone2 : customer[i].setPhone2(n.getTextContent()); break; default: break; } } } return customer; } }