PageRenderTime 29ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/google/code/magja/service/product/ProductRemoteServiceImpl.java

http://magja.googlecode.com/
Java | 751 lines | 463 code | 111 blank | 177 comment | 128 complexity | 2865535f9d31ce4cf391e482712ae991 MD5 | raw file
  1. /**
  2. * @author andre
  3. *
  4. */
  5. package com.google.code.magja.service.product;
  6. import java.util.ArrayList;
  7. import java.util.HashMap;
  8. import java.util.HashSet;
  9. import java.util.LinkedList;
  10. import java.util.List;
  11. import java.util.Map;
  12. import java.util.Set;
  13. import org.apache.axis2.AxisFault;
  14. import com.google.code.magja.magento.ResourcePath;
  15. import com.google.code.magja.model.category.Category;
  16. import com.google.code.magja.model.product.ConfigurableAttributeData;
  17. import com.google.code.magja.model.product.ConfigurableProductData;
  18. import com.google.code.magja.model.product.Product;
  19. import com.google.code.magja.model.product.ProductAttributeSet;
  20. import com.google.code.magja.model.product.ProductLink;
  21. import com.google.code.magja.model.product.ProductMedia;
  22. import com.google.code.magja.model.product.ProductType;
  23. import com.google.code.magja.model.product.ProductTypeEnum;
  24. import com.google.code.magja.model.product.Visibility;
  25. import com.google.code.magja.service.GeneralServiceImpl;
  26. import com.google.code.magja.service.ServiceException;
  27. import com.google.code.magja.service.category.CategoryRemoteService;
  28. public class ProductRemoteServiceImpl extends GeneralServiceImpl<Product>
  29. implements ProductRemoteService {
  30. private static final long serialVersionUID=-3943518467672208326L;
  31. private CategoryRemoteService categoryRemoteService;
  32. private ProductMediaRemoteService productMediaRemoteService;
  33. private ProductLinkRemoteService productLinkRemoteService;
  34. /*
  35. * (non-Javadoc)
  36. *
  37. * @seecom.google.code.magja.service.product.ProductRemoteService#
  38. * setCategoryRemoteService
  39. * (com.google.code.magja.service.category.CategoryRemoteService)
  40. */
  41. @Override
  42. public void setCategoryRemoteService(
  43. CategoryRemoteService categoryRemoteService) {
  44. this.categoryRemoteService = categoryRemoteService;
  45. }
  46. /*
  47. * (non-Javadoc)
  48. *
  49. * @seecom.google.code.magja.service.product.ProductRemoteService#
  50. * setProductMediaRemoteService
  51. * (com.google.code.magja.service.product.ProductMediaRemoteService)
  52. */
  53. @Override
  54. public void setProductMediaRemoteService(
  55. ProductMediaRemoteService productMediaRemoteService) {
  56. this.productMediaRemoteService = productMediaRemoteService;
  57. }
  58. /*
  59. * (non-Javadoc)
  60. *
  61. * @seecom.google.code.magja.service.product.ProductRemoteService#
  62. * setProductLinkRemoteService
  63. * (com.google.code.magja.service.product.ProductLinkRemoteService)
  64. */
  65. @Override
  66. public void setProductLinkRemoteService(
  67. ProductLinkRemoteService productLinkRemoteService) {
  68. this.productLinkRemoteService = productLinkRemoteService;
  69. }
  70. /**
  71. * Create a object product with basic fields from the attribute map
  72. *
  73. * @param mpp
  74. * - the attribute map
  75. * @return Product
  76. */
  77. private Product buildProductBasic(Map<String, Object> mpp) {
  78. Product product = new Product();
  79. // populate the basic fields
  80. for (Map.Entry<String, Object> attribute : mpp.entrySet())
  81. product.set(attribute.getKey(), attribute.getValue());
  82. return product;
  83. }
  84. /**
  85. * Build the object Product with your dependencies, for the queries
  86. *
  87. * @param mpp
  88. * @param dependencies
  89. * - if will or not load dependencies
  90. * @return Product
  91. * @throws ServiceException
  92. */
  93. private Product buildProduct(Map<String, Object> mpp, boolean dependencies)
  94. throws ServiceException {
  95. Product product = buildProductBasic(mpp);
  96. // product visibility
  97. if(mpp.get("visibility") != null) {
  98. Integer visi = new Integer(mpp.get("visibility").toString());
  99. switch (visi) {
  100. case 1:
  101. product.setVisibility(Visibility.NOT_VISIBLE_INDIVIDUALLY);
  102. break;
  103. case 2:
  104. product.setVisibility(Visibility.CATALOG);
  105. break;
  106. case 3:
  107. product.setVisibility(Visibility.SEARCH);
  108. break;
  109. case 4:
  110. product.setVisibility(Visibility.CATALOG_SEARCH);
  111. break;
  112. default:
  113. product.setVisibility(Visibility.CATALOG_SEARCH);
  114. break;
  115. }
  116. }
  117. // set product type
  118. if (mpp.get("type") != null) {
  119. ProductType type = ProductTypeEnum.getTypeOf((String) mpp
  120. .get("type"));
  121. if (type == null && dependencies) {
  122. /*
  123. * means its a type not covered by the enum, so we have to look
  124. * in magento api to get this type
  125. */
  126. List<ProductType> types = listAllProductTypes();
  127. for (ProductType productType : types) {
  128. if (productType.getType().equals((String) mpp.get("type"))) {
  129. type = productType;
  130. break;
  131. }
  132. }
  133. }
  134. if (type != null)
  135. product.setType(type);
  136. }
  137. // set the attributeSet
  138. if (mpp.get("set") != null && dependencies)
  139. product.setAttributeSet(getAttributeSet((String) mpp.get("set")));
  140. // categories - dont get the full tree, only basic info of categories
  141. if (mpp.get("category_ids") != null) {
  142. if (dependencies) {
  143. product.getCategories().addAll(
  144. getCategoriesBasicInfo((List<Object>) mpp
  145. .get("category_ids")));
  146. } else {
  147. List<Category> categories = new ArrayList<Category>();
  148. for (Object obj : (List<Object>) mpp.get("category_ids")) {
  149. Integer id = Integer.parseInt((String) obj);
  150. categories.add(new Category(id));
  151. }
  152. product.setCategories(categories);
  153. }
  154. }
  155. // Inventory
  156. if (dependencies) {
  157. Set<Product> products = new HashSet<Product>();
  158. products.add(product);
  159. getInventoryInfo(products);
  160. }
  161. // medias
  162. if (dependencies)
  163. product.setMedias(productMediaRemoteService.listByProduct(product));
  164. // product links
  165. if (dependencies)
  166. product.setLinks(productLinkRemoteService.list(product));
  167. return product;
  168. }
  169. /**
  170. * @param ids
  171. * @return list of categories with specified ids, just the basic info
  172. * @throws ServiceException
  173. */
  174. private List<Category> getCategoriesBasicInfo(List<Object> ids)
  175. throws ServiceException {
  176. List<Category> categories = new ArrayList<Category>();
  177. for (Object obj : ids) {
  178. Integer id = Integer.parseInt((String) obj);
  179. Category category = categoryRemoteService.getByIdClean(id);
  180. categories.add(category);
  181. }
  182. return categories;
  183. }
  184. /**
  185. * @param id
  186. * @return the ProductAttributeSet with the specified id
  187. * @throws ServiceException
  188. */
  189. private ProductAttributeSet getAttributeSet(String id)
  190. throws ServiceException {
  191. ProductAttributeSet prdAttSet = new ProductAttributeSet();
  192. Integer set_id = Integer.parseInt(id);
  193. // if are the default attribute set, that not list on the api, so we
  194. // have to set manually
  195. if (set_id.equals(soapClient.getConfig().getDefaultAttributeSetId())) {
  196. prdAttSet.setId(set_id);
  197. prdAttSet.setName("Default");
  198. } else {
  199. List<Map<String, Object>> setList;
  200. try {
  201. setList = (List<Map<String, Object>>) soapClient.call(
  202. ResourcePath.ProductAttributeSetList, "");
  203. } catch (AxisFault e) {
  204. if (debug)
  205. e.printStackTrace();
  206. throw new ServiceException(e.getMessage());
  207. }
  208. if (setList != null) {
  209. for (Map<String, Object> set : setList) {
  210. if (set.get("set_id").equals(set_id.toString())) {
  211. for (Map.Entry<String, Object> att : set.entrySet())
  212. prdAttSet.set(att.getKey(), att.getValue());
  213. break;
  214. }
  215. }
  216. }
  217. }
  218. return prdAttSet;
  219. }
  220. /**
  221. * Delete a product by your id (prefered) or your sku
  222. *
  223. * @param id
  224. * @param sku
  225. * @throws ServiceException
  226. */
  227. private void delete(Integer id, String sku) throws ServiceException {
  228. Boolean success = false;
  229. try {
  230. if (id != null) {
  231. success = (Boolean) soapClient.call(ResourcePath.ProductDelete,
  232. id);
  233. } else if (sku != null) {
  234. success = (Boolean) soapClient.call(ResourcePath.ProductDelete,
  235. sku);
  236. }
  237. } catch (AxisFault e) {
  238. if (debug)
  239. e.printStackTrace();
  240. throw new ServiceException(e.getMessage());
  241. }
  242. if (!success)
  243. throw new ServiceException("Not success deleting product.");
  244. }
  245. /**
  246. * Delete a product by sku and category if empty
  247. *
  248. * @param sku
  249. * @throws ServiceException
  250. */
  251. public void deleteWithEmptyCategory(String sku) throws ServiceException {
  252. Product product = getBySku(sku);
  253. List<Category> categories = product.getCategories();
  254. delete(sku);
  255. if (categories != null) {
  256. for (Category category : categories) {
  257. categoryRemoteService.deleteEmptyRecursive(category);
  258. }
  259. }
  260. }
  261. /**
  262. * List the products, if dependencies is true, the products will be
  263. * populated with all your dependencies, otherwise, no.
  264. *
  265. * @param dependencies
  266. * @return List<Product>
  267. * @throws ServiceException
  268. */
  269. private List<Product> list(boolean dependencies) throws ServiceException {
  270. List<Product> products = new ArrayList<Product>();
  271. List<Map<String, Object>> productList;
  272. try {
  273. productList = (List<Map<String, Object>>) soapClient.call(
  274. ResourcePath.ProductList, "");
  275. } catch (AxisFault e) {
  276. if (debug)
  277. e.printStackTrace();
  278. throw new ServiceException(e.getMessage());
  279. }
  280. if (productList == null)
  281. return products;
  282. for (Map<String, Object> mpp : productList)
  283. products.add(buildProduct(mpp, dependencies));
  284. return products;
  285. }
  286. /*
  287. * (non-Javadoc)
  288. *
  289. * @see
  290. * com.google.code.magja.service.product.ProductRemoteService#getBySku(java.
  291. * lang.String)
  292. */
  293. @Override
  294. public Product getBySku(String sku) throws ServiceException {
  295. return getBySku(sku, true);
  296. }
  297. public Product getBySku(String sku, boolean dependencies)
  298. throws ServiceException {
  299. Map<String, Object> mpp;
  300. try {
  301. mpp = (Map<String, Object>) soapClient.call(
  302. ResourcePath.ProductInfo, sku);
  303. } catch (AxisFault e) {
  304. if (debug)
  305. e.printStackTrace();
  306. throw new ServiceException(e.getMessage());
  307. }
  308. if (mpp == null)
  309. return null;
  310. else
  311. return buildProduct(mpp, dependencies);
  312. }
  313. /*
  314. * (non-Javadoc)
  315. *
  316. * @see
  317. * com.google.code.magja.service.product.ProductRemoteService#getById(java
  318. * .lang .Integer)
  319. */
  320. @Override
  321. public Product getById(Integer id) throws ServiceException {
  322. Map<String, Object> mpp;
  323. try {
  324. mpp = (Map<String, Object>) soapClient.call(
  325. ResourcePath.ProductInfo, id);
  326. } catch (AxisFault e) {
  327. if (debug)
  328. e.printStackTrace();
  329. throw new ServiceException(e.getMessage());
  330. }
  331. if (mpp == null)
  332. return null;
  333. else
  334. return buildProduct(mpp, true);
  335. }
  336. /*
  337. * (non-Javadoc)
  338. *
  339. * @see com.google.code.magja.service.product.ProductRemoteService#listAll()
  340. */
  341. @Override
  342. public List<Product> listAll() throws ServiceException {
  343. return list(true);
  344. }
  345. /*
  346. * (non-Javadoc)
  347. *
  348. * @see
  349. * com.google.code.magja.service.product.ProductRemoteService#listAllNoDep()
  350. */
  351. @Override
  352. public List<Product> listAllNoDep() throws ServiceException {
  353. return list(false);
  354. }
  355. /*
  356. * (non-Javadoc)
  357. *
  358. * @see
  359. * com.google.code.magja.service.product.ProductRemoteService#save(code.
  360. * google .magja.model.product.Product)
  361. */
  362. @Override
  363. public void save(Product product) throws ServiceException {
  364. save(product, "");
  365. }
  366. public void save(Product product, String storeView) throws ServiceException {
  367. int id = 0;
  368. try {
  369. id = getBySku(product.getSku(), false).getId();
  370. } catch (ServiceException e) {
  371. if (debug) {
  372. e.printStackTrace();
  373. }
  374. }
  375. if (id > 0) {
  376. // means its a existing product
  377. Boolean success = false;
  378. try {
  379. List<Object> newProduct = new LinkedList<Object>();
  380. newProduct.add(product.getSku());
  381. newProduct.add(product.getAllProperties());
  382. if (!storeView.isEmpty()) {
  383. newProduct.add(storeView);
  384. }
  385. success = (Boolean) soapClient.call(ResourcePath.ProductUpdate,
  386. newProduct);
  387. if (success) {
  388. product.setId(id);
  389. if (storeView.isEmpty()) {
  390. // FIXME: compare new and existing media instead of
  391. // delete and create
  392. for (ProductMedia media : productMediaRemoteService
  393. .listByProduct(product)) {
  394. productMediaRemoteService.delete(media);
  395. }
  396. }
  397. } else {
  398. throw new ServiceException("Error updating Product");
  399. }
  400. } catch (NumberFormatException e) {
  401. if (debug)
  402. e.printStackTrace();
  403. throw new ServiceException(e.getMessage());
  404. } catch (AxisFault e) {
  405. if (debug)
  406. e.printStackTrace();
  407. throw new ServiceException(e.getMessage());
  408. }
  409. } else {
  410. // means its a new product
  411. // if is a configurable product, call the proper handle
  412. if (product.getType().equals(ProductTypeEnum.CONFIGURABLE.getProductType()))
  413. handleConfigurableForNewProducts(product);
  414. try {
  415. List<Object> newProduct = (LinkedList<Object>) product
  416. .serializeToApi();
  417. id = Integer.parseInt((String) soapClient.call(
  418. ResourcePath.ProductCreate, newProduct));
  419. if (id > 0)
  420. product.setId(id);
  421. else
  422. throw new ServiceException("Error inserting new Product");
  423. } catch (NumberFormatException e) {
  424. if (debug)
  425. e.printStackTrace();
  426. throw new ServiceException(e.getMessage());
  427. } catch (AxisFault e) {
  428. if (debug)
  429. e.printStackTrace();
  430. throw new ServiceException(e.getMessage());
  431. }
  432. }
  433. // inventory
  434. if (product.getQty() != null)
  435. updateInventory(product);
  436. // if have media, create it too
  437. if (product.getMedias() != null) {
  438. if (!product.getMedias().isEmpty()) {
  439. for (ProductMedia media : product.getMedias()) {
  440. if (media.getImage() != null
  441. && media.getImage().getData() != null)
  442. productMediaRemoteService.save(media);
  443. }
  444. }
  445. }
  446. // if has links, create too
  447. if (product.getLinks() != null) {
  448. if (!product.getLinks().isEmpty()) {
  449. for (ProductLink link : product.getLinks()) {
  450. if (link.getLinkType() != null
  451. && (link.getId() != null || link.getSku() != null))
  452. productLinkRemoteService.assign(product, link);
  453. }
  454. }
  455. }
  456. }
  457. /*
  458. * Handle configurable products just for insert new products
  459. */
  460. private void handleConfigurableForNewProducts(Product product)
  461. throws ServiceException {
  462. // if isn't a configurable product, stop the execution
  463. if (!product.getType().equals(ProductTypeEnum.CONFIGURABLE.getProductType()))
  464. return;
  465. if(product.getConfigurableAttributesData() != null) {
  466. Map<String, Object> confAttrDataMap = new HashMap<String, Object>();
  467. Integer i = 0;
  468. for (ConfigurableAttributeData configAttr : product.getConfigurableAttributesData()) {
  469. confAttrDataMap.put(i.toString(), configAttr.serializeToApi());
  470. i++;
  471. }
  472. product.set("configurable_attributes_data", confAttrDataMap);
  473. }
  474. if (product.getConfigurableSubProducts() != null) {
  475. if (product.getConfigurableProductsData() == null)
  476. product.setConfigurableProductsData(new HashMap<String, Map<String, Object>>());
  477. for (ConfigurableProductData prdData : product
  478. .getConfigurableSubProducts()) {
  479. Product subprd = prdData.getProduct();
  480. // only save new simple products
  481. if (subprd.getId() == null
  482. && subprd.getType().equals(ProductTypeEnum.SIMPLE.getProductType()))
  483. this.save(subprd);
  484. product.getConfigurableProductsData().put(subprd.getId().toString(),
  485. prdData.serializeToApi());
  486. }
  487. }
  488. }
  489. /*
  490. * (non-Javadoc)
  491. *
  492. * @see com.google.code.magja.service.product.ProductRemoteService#
  493. * listAllProductTypes ()
  494. */
  495. @Override
  496. public List<ProductType> listAllProductTypes() throws ServiceException {
  497. List<ProductType> resultList = new ArrayList<ProductType>();
  498. List<Map<String, Object>> productTypes;
  499. try {
  500. productTypes = (List<Map<String, Object>>) soapClient.call(
  501. ResourcePath.ProductTypeList, "");
  502. } catch (AxisFault e) {
  503. if (debug)
  504. e.printStackTrace();
  505. throw new ServiceException(e.getMessage());
  506. }
  507. if (productTypes == null)
  508. return resultList;
  509. for (Map<String, Object> type : productTypes) {
  510. ProductType productType = new ProductType();
  511. for (Map.Entry<String, Object> attribute : type.entrySet())
  512. productType.set(attribute.getKey(), attribute.getValue());
  513. resultList.add(productType);
  514. }
  515. return resultList;
  516. }
  517. /*
  518. * (non-Javadoc)
  519. *
  520. * @see
  521. * com.google.code.magja.service.product.ProductRemoteService#delete(java
  522. * .lang .Integer)
  523. */
  524. @Override
  525. public void delete(Integer id) throws ServiceException {
  526. delete(id, null);
  527. }
  528. /*
  529. * (non-Javadoc)
  530. *
  531. * @see
  532. * com.google.code.magja.service.product.ProductRemoteService#delete(java
  533. * .lang .String)
  534. */
  535. @Override
  536. public void delete(String sku) throws ServiceException {
  537. delete(null, sku);
  538. }
  539. /*
  540. * (non-Javadoc)
  541. *
  542. * @see
  543. * com.google.code.magja.service.product.ProductRemoteService#deleteAll()
  544. */
  545. @Override
  546. public void deleteAll() throws ServiceException {
  547. List<Product> products = listAllNoDep();
  548. for (Product product : products) {
  549. delete(product.getId());
  550. }
  551. }
  552. /*
  553. * (non-Javadoc)
  554. *
  555. * @see
  556. * com.google.code.magja.service.product.ProductRemoteService#getInventoryInfo
  557. * (java.util.Set)
  558. */
  559. @Override
  560. public void getInventoryInfo(Set<Product> products) throws ServiceException {
  561. String[] productIds = new String[products.size()];
  562. int i = 0;
  563. for (Product product : products)
  564. productIds[i++] = product.getId().toString();
  565. List<Object> param = new LinkedList<Object>();
  566. param.add(productIds);
  567. List<Map<String, Object>> resultList = null;
  568. try {
  569. resultList = (List<Map<String, Object>>) soapClient.call(
  570. ResourcePath.ProductStockList, param);
  571. } catch (AxisFault e) {
  572. if (debug)
  573. e.printStackTrace();
  574. throw new ServiceException(e.getMessage());
  575. }
  576. for (Map<String, Object> iv : resultList) {
  577. for (Product product : products) {
  578. if (product.getId().equals(
  579. Integer.parseInt((String) iv.get("product_id")))) {
  580. if (iv.get("qty") != null || !"".equals(iv.get("qty")))
  581. product.setQty(Double.parseDouble((String) iv
  582. .get("qty")));
  583. if (iv.get("is_in_stock") != null
  584. || !"".equals(iv.get("is_in_stock"))) {
  585. if (iv.get("is_in_stock").toString().equals("0")
  586. || iv.get("is_in_stock").toString()
  587. .equals("false"))
  588. product.setInStock(false);
  589. else
  590. product.setInStock(true);
  591. }
  592. }
  593. }
  594. }
  595. }
  596. /*
  597. * (non-Javadoc)
  598. *
  599. * @see
  600. * com.google.code.magja.service.product.ProductRemoteService#updateInventory
  601. * (com.google.code.magja.model.product.Product)
  602. */
  603. @Override
  604. public void updateInventory(Product product) throws ServiceException {
  605. if (product.getId() == null && product.getSku() == null)
  606. throw new ServiceException(
  607. "The product must have the id or the sku seted for update inventory");
  608. Map<String, Object> properties = new HashMap<String, Object>();
  609. properties.put("qty", product.getQty());
  610. if (product.getInStock() == null)
  611. product.setInStock(product.getQty() > 0);
  612. properties.put("is_in_stock", (product.getInStock() ? "1" : "0"));
  613. List<Object> param = new LinkedList<Object>();
  614. param.add((product.getId() != null ? product.getId() : product.getSku()));
  615. param.add(properties);
  616. try {
  617. soapClient.call(ResourcePath.ProductStockUpdate, param);
  618. } catch (AxisFault e) {
  619. if (debug)
  620. e.printStackTrace();
  621. throw new ServiceException(e.getMessage());
  622. }
  623. }
  624. /**
  625. * Get products without category
  626. *
  627. * @return List<Product>
  628. * @throws ServiceException
  629. */
  630. public List<Product> getWithoutCategory() throws ServiceException {
  631. List<Product> withoutCategory = new ArrayList<Product>();
  632. List<Product> products = listAllNoDep();
  633. for (Product product : products) {
  634. if (product.getCategories().isEmpty()) {
  635. withoutCategory.add(product);
  636. }
  637. }
  638. return withoutCategory;
  639. }
  640. }