1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.kuali.kfs.module.purap.document.service.impl;
20
21 import java.text.SimpleDateFormat;
22 import java.util.Date;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.kuali.kfs.module.purap.PurapConstants;
28 import org.kuali.kfs.module.purap.businessobject.PurchaseOrderItem;
29 import org.kuali.kfs.module.purap.dataaccess.B2BDao;
30 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
31 import org.kuali.kfs.module.purap.document.RequisitionDocument;
32 import org.kuali.kfs.module.purap.document.service.B2BPurchaseOrderService;
33 import org.kuali.kfs.module.purap.document.service.RequisitionService;
34 import org.kuali.kfs.module.purap.exception.B2BConnectionException;
35 import org.kuali.kfs.module.purap.exception.CxmlParseError;
36 import org.kuali.kfs.module.purap.util.PurApDateFormatUtils;
37 import org.kuali.kfs.module.purap.util.cxml.B2BParserHelper;
38 import org.kuali.kfs.module.purap.util.cxml.PurchaseOrderResponse;
39 import org.kuali.kfs.sys.context.SpringContext;
40 import org.kuali.kfs.vnd.businessobject.ContractManager;
41 import org.kuali.rice.core.api.datetime.DateTimeService;
42 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
43 import org.kuali.rice.kew.api.WorkflowDocument;
44 import org.kuali.rice.kim.api.identity.Person;
45 import org.kuali.rice.kim.api.identity.PersonService;
46 import org.kuali.rice.kim.api.identity.principal.Principal;
47 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
48 import org.kuali.rice.krad.util.ObjectUtils;
49 import org.springframework.transaction.annotation.Transactional;
50
51 @Transactional
52 public class B2BPurchaseOrderSciquestServiceImpl implements B2BPurchaseOrderService {
53 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(B2BPurchaseOrderSciquestServiceImpl.class);
54
55 protected B2BDao b2bDao;
56 protected RequisitionService requisitionService;
57 protected ParameterService parameterService;
58 protected PersonService personService;
59
60
61 private String b2bEnvironment;
62 private String b2bUserAgent;
63 private String b2bPurchaseOrderURL;
64 private String b2bPurchaseOrderIdentity;
65 private String b2bPurchaseOrderPassword;
66
67
68
69
70 public String sendPurchaseOrder(PurchaseOrderDocument purchaseOrder) {
71
72
73
74
75
76
77
78
79 ContractManager contractManager = purchaseOrder.getVendorContract().getContractManager();
80 String contractManagerEmail = getContractManagerEmail(contractManager);
81
82 String vendorDuns = purchaseOrder.getVendorDetail().getVendorDunsNumber();
83
84 RequisitionDocument r = requisitionService.getRequisitionById(purchaseOrder.getRequisitionIdentifier());
85 WorkflowDocument reqWorkflowDoc = r.getDocumentHeader().getWorkflowDocument();
86 String requisitionInitiatorPrincipalId = getRequisitionInitiatorPrincipal(reqWorkflowDoc.getInitiatorPrincipalId());
87
88 if (LOG.isDebugEnabled()) {
89 LOG.debug("sendPurchaseOrder(): b2bPurchaseOrderURL is " + b2bPurchaseOrderURL);
90 }
91
92 String validateErrors = verifyCxmlPOData(purchaseOrder, requisitionInitiatorPrincipalId, b2bPurchaseOrderPassword, contractManager, contractManagerEmail, vendorDuns);
93 if (!StringUtils.isEmpty(validateErrors)) {
94 return validateErrors;
95 }
96
97 StringBuffer transmitErrors = new StringBuffer();
98
99 try {
100 LOG.debug("sendPurchaseOrder() Generating cxml");
101 String cxml = getCxml(purchaseOrder, requisitionInitiatorPrincipalId, b2bPurchaseOrderPassword, contractManager, contractManagerEmail, vendorDuns);
102
103 LOG.info("sendPurchaseOrder() Sending cxml\n" + cxml);
104 String responseCxml = b2bDao.sendPunchOutRequest(cxml, b2bPurchaseOrderURL);
105
106 LOG.info("sendPurchaseOrder(): Response cXML for po #" + purchaseOrder.getPurapDocumentIdentifier() + ":\n" + responseCxml);
107
108 PurchaseOrderResponse poResponse = B2BParserHelper.getInstance().parsePurchaseOrderResponse(responseCxml);
109 String statusText = poResponse.getStatusText();
110 if (LOG.isDebugEnabled()) {
111 LOG.debug("sendPurchaseOrder(): statusText is " + statusText);
112 }
113 if (ObjectUtils.isNull(statusText) || (!"success".equalsIgnoreCase(statusText.trim()))) {
114 LOG.error("sendPurchaseOrder(): PO cXML for po number " + purchaseOrder.getPurapDocumentIdentifier() + " failed sending to SciQuest:\n" + statusText);
115 transmitErrors.append("Unable to send Purchase Order: " + statusText);
116
117
118 List errorMessages = poResponse.getPOResponseErrorMessages();
119 if (ObjectUtils.isNotNull(errorMessages) && !errorMessages.isEmpty()) {
120 for (Iterator iter = errorMessages.iterator(); iter.hasNext();) {
121 String errorMessage = (String) iter.next();
122 if (ObjectUtils.isNotNull(errorMessage)) {
123 LOG.error("sendPurchaseOrder(): SciQuest error message for po number " + purchaseOrder.getPurapDocumentIdentifier() + ": " + errorMessage);
124 transmitErrors.append("Error sending Purchase Order: " + errorMessage);
125 }
126 }
127 }
128 }
129 }
130 catch (B2BConnectionException e) {
131 LOG.error("sendPurchaseOrder() Error connecting to b2b", e);
132 transmitErrors.append("Connection to Sciquest failed.");
133 }
134 catch (CxmlParseError e) {
135 LOG.error("sendPurchaseOrder() Error Parsing", e);
136 transmitErrors.append("Unable to read cxml returned from Sciquest.");
137 }
138 catch (Throwable e) {
139 LOG.error("sendPurchaseOrder() Unknown Error", e);
140 transmitErrors.append("Unexpected error occurred while attempting to transmit Purchase Order.");
141 }
142
143 return transmitErrors.toString();
144 }
145
146
147
148
149
150
151 public String getCxml(PurchaseOrderDocument purchaseOrder, String requisitionInitiatorPrincipalId, String password, ContractManager contractManager, String contractManagerEmail, String vendorDuns) {
152
153 StringBuffer cxml = new StringBuffer();
154
155 cxml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
156 cxml.append("<!DOCTYPE PurchaseOrderMessage SYSTEM \"PO.dtd\">\n");
157 cxml.append("<PurchaseOrderMessage version=\"2.0\">\n");
158 cxml.append(" <Header>\n");
159
160
161 cxml.append(" <MessageId>KFS_cXML_PO</MessageId>\n");
162
163
164 Date d = SpringContext.getBean(DateTimeService.class).getCurrentDate();
165 SimpleDateFormat date = PurApDateFormatUtils.getSimpleDateFormat(PurapConstants.NamedDateFormats.CXML_SIMPLE_DATE_FORMAT);
166 SimpleDateFormat time = PurApDateFormatUtils.getSimpleDateFormat(PurapConstants.NamedDateFormats.CXML_SIMPLE_TIME_FORMAT);
167 cxml.append(" <Timestamp>").append(date.format(d)).append("T").append(time.format(d)).append("+05:30").append("</Timestamp>\n");
168
169 cxml.append(" <Authentication>\n");
170 cxml.append(" <Identity>").append(b2bPurchaseOrderIdentity).append("</Identity>\n");
171 cxml.append(" <SharedSecret>").append(password).append("</SharedSecret>\n");
172 cxml.append(" </Authentication>\n");
173 cxml.append(" </Header>\n");
174 cxml.append(" <PurchaseOrder>\n");
175 cxml.append(" <POHeader>\n");
176 cxml.append(" <PONumber>").append(purchaseOrder.getPurapDocumentIdentifier()).append("</PONumber>\n");
177 cxml.append(" <Requestor>\n");
178 cxml.append(" <UserProfile username=\"").append(requisitionInitiatorPrincipalId.toUpperCase()).append("\">\n");
179 cxml.append(" </UserProfile>\n");
180 cxml.append(" </Requestor>\n");
181 cxml.append(" <Priority>High</Priority>\n");
182 cxml.append(" <AccountingDate>").append(purchaseOrder.getPurchaseOrderCreateTimestamp()).append("</AccountingDate>\n");
183
184
185 cxml.append(" <Supplier id=\"").append(purchaseOrder.getExternalOrganizationB2bSupplierIdentifier()).append("\">\n");
186 cxml.append(" <DUNS>").append(vendorDuns).append("</DUNS>\n");
187 cxml.append(" <SupplierNumber>").append(purchaseOrder.getVendorNumber()).append("</SupplierNumber>\n");
188
189
190 cxml.append(" <ContactInfo type=\"main\">\n");
191
192
193 cxml.append(" <Phone>\n");
194 cxml.append(" <TelephoneNumber>\n");
195 cxml.append(" <CountryCode>1</CountryCode>\n");
196 if (contractManager.getContractManagerPhoneNumber().length() > 4) {
197 cxml.append(" <AreaCode>").append(contractManager.getContractManagerPhoneNumber().substring(0, 3)).append("</AreaCode>\n");
198 cxml.append(" <Number>").append(contractManager.getContractManagerPhoneNumber().substring(3)).append("</Number>\n");
199 }
200 else {
201 LOG.error("getCxml() The phone number is invalid for this contract manager: " + contractManager.getContractManagerUserIdentifier() + " " + contractManager.getContractManagerName());
202 cxml.append(" <AreaCode>555</AreaCode>\n");
203 cxml.append(" <Number>").append(contractManager.getContractManagerPhoneNumber()).append("</Number>\n");
204 }
205 cxml.append(" </TelephoneNumber>\n");
206 cxml.append(" </Phone>\n");
207 cxml.append(" </ContactInfo>\n");
208 cxml.append(" </Supplier>\n");
209
210
211 cxml.append(" <BillTo>\n");
212 cxml.append(" <Address>\n");
213 cxml.append(" <TemplateName>Bill To</TemplateName>\n");
214 cxml.append(" <AddressCode>").append(purchaseOrder.getDeliveryCampusCode()).append("</AddressCode>\n");
215
216 cxml.append(" <Contact label=\"FirstName\" linenumber=\"1\"><![CDATA[Accounts]]></Contact>\n");
217 cxml.append(" <Contact label=\"LastName\" linenumber=\"2\"><![CDATA[Payable]]></Contact>\n");
218 cxml.append(" <Contact label=\"Company\" linenumber=\"3\"><![CDATA[").append(purchaseOrder.getBillingName().trim()).append("]]></Contact>\n");
219
220 if (!StringUtils.isEmpty(purchaseOrder.getBillingEmailAddress())) {
221 cxml.append(" <Contact label=\"Email\" linenumber=\"4\"><![CDATA[").append(purchaseOrder.getBillingEmailAddress().trim()).append("]]></Contact>\n");
222 }
223
224 if (!StringUtils.isEmpty(purchaseOrder.getBillingPhoneNumber())) {
225 cxml.append(" <Contact label=\"Phone\" linenumber=\"5\"><![CDATA[").append(purchaseOrder.getBillingPhoneNumber().trim()).append("]]></Contact>\n");
226 }
227
228 cxml.append(" <AddressLine label=\"Street1\" linenumber=\"1\"><![CDATA[").append(purchaseOrder.getBillingLine1Address()).append("]]></AddressLine>\n");
229 cxml.append(" <AddressLine label=\"Street2\" linenumber=\"2\"><![CDATA[").append(purchaseOrder.getBillingLine2Address()).append("]]></AddressLine>\n");
230 cxml.append(" <City><![CDATA[").append(purchaseOrder.getBillingCityName()).append("]]></City>\n");
231 cxml.append(" <State>").append(purchaseOrder.getBillingStateCode()).append("</State>\n");
232 cxml.append(" <PostalCode>").append(purchaseOrder.getBillingPostalCode()).append("</PostalCode>\n");
233 cxml.append(" <Country isocountrycode=\"").append(purchaseOrder.getBillingCountryCode()).append("\">").append(purchaseOrder.getBillingCountryCode()).append("</Country>\n");
234 cxml.append(" </Address>\n");
235 cxml.append(" </BillTo>\n");
236
237
238 cxml.append(" <ShipTo>\n");
239 cxml.append(" <Address>\n");
240 cxml.append(" <TemplateName>Ship To</TemplateName>\n");
241
242 cxml.append(" <AddressCode>").append(purchaseOrder.getDeliveryCampusCode()).append(purchaseOrder.getOrganizationCode()).append("</AddressCode>\n");
243 cxml.append(" <Contact label=\"Name\" linenumber=\"1\"><![CDATA[").append(purchaseOrder.getDeliveryToName().trim()).append("]]></Contact>\n");
244 cxml.append(" <Contact label=\"PurchasingEmail\" linenumber=\"2\"><![CDATA[").append(contractManagerEmail).append("]]></Contact>\n");
245 if (ObjectUtils.isNotNull(purchaseOrder.getInstitutionContactEmailAddress())) {
246 cxml.append(" <Contact label=\"ContactEmail\" linenumber=\"3\"><![CDATA[").append(purchaseOrder.getInstitutionContactEmailAddress()).append("]]></Contact>\n");
247 }
248 else {
249 cxml.append(" <Contact label=\"ContactEmail\" linenumber=\"3\"><![CDATA[").append(purchaseOrder.getRequestorPersonEmailAddress()).append("]]></Contact>\n");
250 }
251 if (ObjectUtils.isNotNull(purchaseOrder.getInstitutionContactPhoneNumber())) {
252 cxml.append(" <Contact label=\"Phone\" linenumber=\"4\"><![CDATA[").append(purchaseOrder.getInstitutionContactPhoneNumber().trim()).append("]]></Contact>\n");
253 }
254 else {
255 cxml.append(" <Contact label=\"Phone\" linenumber=\"4\"><![CDATA[").append(purchaseOrder.getRequestorPersonPhoneNumber()).append("]]></Contact>\n");
256 }
257
258
259 if (purchaseOrder.getAddressToVendorIndicator()) {
260 cxml.append(" <AddressLine label=\"Street1\" linenumber=\"1\"><![CDATA[").append(purchaseOrder.getReceivingName().trim()).append("]]></AddressLine>\n");
261 cxml.append(" <AddressLine label=\"Street2\" linenumber=\"2\"><![CDATA[").append(purchaseOrder.getReceivingLine1Address().trim()).append("]]></AddressLine>\n");
262 if (ObjectUtils.isNull(purchaseOrder.getReceivingLine2Address())) {
263 cxml.append(" <AddressLine label=\"Street3\" linenumber=\"3\"><![CDATA[").append(" ").append("]]></AddressLine>\n");
264 }
265 else {
266 cxml.append(" <AddressLine label=\"Street3\" linenumber=\"3\"><![CDATA[").append(purchaseOrder.getReceivingLine2Address()).append("]]></AddressLine>\n");
267 }
268 cxml.append(" <City><![CDATA[").append(purchaseOrder.getReceivingCityName().trim()).append("]]></City>\n");
269 cxml.append(" <State>").append(purchaseOrder.getReceivingStateCode()).append("</State>\n");
270 cxml.append(" <PostalCode>").append(purchaseOrder.getReceivingPostalCode()).append("</PostalCode>\n");
271 cxml.append(" <Country isocountrycode=\"").append(purchaseOrder.getReceivingCountryCode()).append("\">").append(purchaseOrder.getReceivingCountryCode()).append("</Country>\n");
272 }
273 else {
274
275
276
277
278
279 cxml.append(getBuildingLine(purchaseOrder));
280 cxml.append(" <AddressLine label=\"Street1\" linenumber=\"1\"><![CDATA[").append(purchaseOrder.getDeliveryBuildingLine1Address().trim()).append("]]></AddressLine>\n");
281 cxml.append(" <AddressLine label=\"Street2\" linenumber=\"2\"><![CDATA[Room #").append(purchaseOrder.getDeliveryBuildingRoomNumber().trim()).append("]]></AddressLine>\n");
282 cxml.append(" <AddressLine label=\"Company\" linenumber=\"4\"><![CDATA[").append(purchaseOrder.getBillingName().trim()).append("]]></AddressLine>\n");
283 if (ObjectUtils.isNull(purchaseOrder.getDeliveryBuildingLine2Address())) {
284 cxml.append(" <AddressLine label=\"Street3\" linenumber=\"3\"><![CDATA[").append(" ").append("]]></AddressLine>\n");
285 }
286 else {
287 cxml.append(" <AddressLine label=\"Street3\" linenumber=\"3\"><![CDATA[").append(purchaseOrder.getDeliveryBuildingLine2Address()).append("]]></AddressLine>\n");
288 }
289 cxml.append(" <City><![CDATA[").append(purchaseOrder.getDeliveryCityName().trim()).append("]]></City>\n");
290 cxml.append(" <State>").append(purchaseOrder.getDeliveryStateCode()).append("</State>\n");
291 cxml.append(" <PostalCode>").append(purchaseOrder.getDeliveryPostalCode()).append("</PostalCode>\n");
292 cxml.append(" <Country isocountrycode=\"").append(purchaseOrder.getDeliveryCountryCode()).append("\">").append(purchaseOrder.getDeliveryCountryCode()).append("</Country>\n");
293 }
294
295 cxml.append(" </Address>\n");
296 cxml.append(" </ShipTo>\n");
297 cxml.append(" </POHeader>\n");
298
299
300 List detailList = purchaseOrder.getItems();
301 for (Iterator iter = detailList.iterator(); iter.hasNext();) {
302 PurchaseOrderItem poi = (PurchaseOrderItem) iter.next();
303 if ((ObjectUtils.isNotNull(poi.getItemType())) && poi.getItemType().isLineItemIndicator()) {
304 cxml.append(" <POLine linenumber=\"").append(poi.getItemLineNumber()).append("\">\n");
305 cxml.append(" <Item>\n");
306
307 cxml.append(" <CatalogNumber><![CDATA[").append(poi.getItemCatalogNumber()).append("]]></CatalogNumber>\n");
308 if (ObjectUtils.isNotNull(poi.getItemAuxiliaryPartIdentifier())) {
309 cxml.append(" <AuxiliaryCatalogNumber><![CDATA[").append(poi.getItemAuxiliaryPartIdentifier()).append("]]></AuxiliaryCatalogNumber>\n");
310 }
311 cxml.append(" <Description><![CDATA[").append(poi.getItemDescription()).append("]]></Description>\n");
312 cxml.append(" <ProductUnitOfMeasure type=\"supplier\"><Measurement><MeasurementValue><![CDATA[").append(poi.getItemUnitOfMeasureCode()).append("]]></MeasurementValue></Measurement></ProductUnitOfMeasure>\n");
313 cxml.append(" <ProductUnitOfMeasure type=\"system\"><Measurement><MeasurementValue><![CDATA[").append(poi.getItemUnitOfMeasureCode()).append("]]></MeasurementValue></Measurement></ProductUnitOfMeasure>\n");
314
315 if (poi.getExternalOrganizationB2bProductTypeName().equals("Punchout")) {
316 cxml.append(" <ProductReferenceNumber>null</ProductReferenceNumber>\n");
317 }
318 else {
319 cxml.append(" <ProductReferenceNumber>").append(poi.getExternalOrganizationB2bProductReferenceNumber()).append("</ProductReferenceNumber>\n");
320 }
321
322 cxml.append(" <ProductType>").append(poi.getExternalOrganizationB2bProductTypeName()).append("</ProductType>\n");
323 cxml.append(" </Item>\n");
324 cxml.append(" <Quantity>").append(poi.getItemQuantity()).append("</Quantity>\n");
325
326
327 cxml.append(" <LineCharges>\n");
328 cxml.append(" <UnitPrice>\n");
329 cxml.append(" <Money currency=\"USD\">").append(poi.getItemUnitPrice()).append("</Money>\n");
330 cxml.append(" </UnitPrice>\n");
331 cxml.append(" </LineCharges>\n");
332 cxml.append(" </POLine>\n");
333 }
334 }
335
336 cxml.append(" </PurchaseOrder>\n");
337 cxml.append("</PurchaseOrderMessage>");
338
339 if (LOG.isDebugEnabled()) {
340 LOG.debug("getCxml(): cXML for po number " + purchaseOrder.getPurapDocumentIdentifier() + ":\n" + cxml.toString());
341 }
342
343 return cxml.toString();
344 }
345
346
347
348
349
350
351 public String verifyCxmlPOData(PurchaseOrderDocument purchaseOrder, String requisitionInitiatorPrincipalName, String password, ContractManager contractManager, String contractManagerEmail, String vendorDuns) {
352 StringBuffer errors = new StringBuffer();
353
354 if (ObjectUtils.isNull(purchaseOrder)) {
355 LOG.error("verifyCxmlPOData() The Purchase Order is null.");
356 errors.append("Error occurred retrieving Purchase Order\n");
357 return errors.toString();
358 }
359 if (ObjectUtils.isNull(contractManager)) {
360 LOG.error("verifyCxmlPOData() The contractManager is null.");
361 errors.append("Error occurred retrieving Contract Manager\n");
362 return errors.toString();
363 }
364 if (StringUtils.isEmpty(password)) {
365 LOG.error("verifyCxmlPOData() The B2B PO password is required for the cXML PO but is missing.");
366 errors.append("Missing Data: B2B PO password\n");
367 }
368 if (ObjectUtils.isNull(purchaseOrder.getPurapDocumentIdentifier())) {
369 LOG.error("verifyCxmlPOData() The purchase order Id is required for the cXML PO but is missing.");
370 errors.append("Missing Data: Purchase Order ID\n");
371 }
372 if (StringUtils.isEmpty(requisitionInitiatorPrincipalName)) {
373 LOG.error("verifyCxmlPOData() The requisition initiator principal name is required for the cXML PO but is missing.");
374 errors.append("Missing Data: Requisition Initiator Principal Name\n");
375 }
376 if (ObjectUtils.isNull(purchaseOrder.getPurchaseOrderCreateTimestamp())) {
377 LOG.error("verifyCxmlPOData() The PO create date is required for the cXML PO but is null.");
378 errors.append("Create Date\n");
379 }
380 if (StringUtils.isEmpty(contractManager.getContractManagerPhoneNumber())) {
381 LOG.error("verifyCxmlPOData() The contract manager phone number is required for the cXML PO but is missing.");
382 errors.append("Missing Data: Contract Manager Phone Number\n");
383 }
384 if (StringUtils.isEmpty(contractManager.getContractManagerName())) {
385 LOG.error("verifyCxmlPOData() The contract manager name is required for the cXML PO but is missing.");
386 errors.append("Missing Data: Contract Manager Name\n");
387 }
388 if (StringUtils.isEmpty(purchaseOrder.getDeliveryCampusCode())) {
389 LOG.error("verifyCxmlPOData() The Delivery Campus Code is required for the cXML PO but is missing.");
390 errors.append("Missing Data: Delivery Campus Code\n");
391 }
392 if (StringUtils.isEmpty(purchaseOrder.getBillingName())) {
393 LOG.error("verifyCxmlPOData() The Delivery Billing Name is required for the cXML PO but is missing.");
394 errors.append("Missing Data: Delivery Billing Name\n");
395 }
396 if (StringUtils.isEmpty(purchaseOrder.getBillingLine1Address())) {
397 LOG.error("verifyCxmlPOData() The Billing Line 1 Address is required for the cXML PO but is missing.");
398 errors.append("Missing Data: Billing Line 1 Address\n");
399 }
400 if (StringUtils.isEmpty(purchaseOrder.getBillingLine2Address())) {
401 LOG.error("verifyCxmlPOData() The Billing Line 2 Address is required for the cXML PO but is missing.");
402 errors.append("Missing Data: Billing Line 2 Address\n");
403 }
404 if (StringUtils.isEmpty(purchaseOrder.getBillingCityName())) {
405 LOG.error("verifyCxmlPOData() The Billing Address City Name is required for the cXML PO but is missing.");
406 errors.append("Missing Data: Billing Address City Name\n");
407 }
408 if (StringUtils.isEmpty(purchaseOrder.getBillingStateCode())) {
409 LOG.error("verifyCxmlPOData() The Billing Address State Code is required for the cXML PO but is missing.");
410 errors.append("Missing Data: Billing Address State Code\n");
411 }
412 if (StringUtils.isEmpty(purchaseOrder.getBillingPostalCode())) {
413 LOG.error("verifyCxmlPOData() The Billing Address Postal Code is required for the cXML PO but is missing.");
414 errors.append("Missing Data: Billing Address Postal Code\n");
415 }
416 if (StringUtils.isEmpty(purchaseOrder.getDeliveryToName())) {
417 LOG.error("verifyCxmlPOData() The Delivery To Name is required for the cXML PO but is missing.");
418 errors.append("Missing Data: Delivery To Name\n");
419 }
420 if (StringUtils.isEmpty(contractManagerEmail)) {
421 LOG.error("verifyCxmlPOData() The Contract Manager Email is required for the cXML PO but is missing.");
422 errors.append("Missing Data: Contract Manager Email\n");
423 }
424 if (StringUtils.isEmpty(purchaseOrder.getRequestorPersonEmailAddress())) {
425 LOG.error("verifyCxmlPOData() The Requesting Person Email Address is required for the cXML PO but is missing.");
426 errors.append("Missing Data: Requesting Person Email Address\n");
427 }
428 if (StringUtils.isEmpty(purchaseOrder.getRequestorPersonPhoneNumber())) {
429 LOG.error("verifyCxmlPOData() The Requesting Person Phone Number is required for the cXML PO but is missing.");
430 errors.append("Missing Data: Requesting Person Phone Number\n");
431 }
432 if (StringUtils.isEmpty(purchaseOrder.getDeliveryBuildingLine1Address())) {
433 LOG.error("verifyCxmlPOData() The Delivery Line 1 Address is required for the cXML PO but is missing.");
434 errors.append("Missing Data: Delivery Line 1 Address\n");
435 }
436 if (StringUtils.isEmpty(purchaseOrder.getDeliveryToName())) {
437 LOG.error("verifyCxmlPOData() The Delivery To Name is required for the cXML PO but is missing.");
438 errors.append("Missing Data: Delivery To Name\n");
439 }
440 if (StringUtils.isEmpty(purchaseOrder.getDeliveryCityName())) {
441 LOG.error("verifyCxmlPOData() The Delivery City Name is required for the cXML PO but is missing.");
442 errors.append("Missing Data: Delivery City Name\n");
443 }
444 if (StringUtils.isEmpty(purchaseOrder.getDeliveryStateCode())) {
445 LOG.error("verifyCxmlPOData() The Delivery State is required for the cXML PO but is missing.");
446 errors.append("Missing Data: Delivery State\n");
447 }
448 if (StringUtils.isEmpty(purchaseOrder.getDeliveryPostalCode())) {
449 LOG.error("verifyCxmlPOData() The Delivery Postal Code is required for the cXML PO but is missing.");
450 errors.append("Missing Data: Delivery Postal Code\n");
451 }
452
453
454 List detailList = purchaseOrder.getItems();
455 for (Iterator iter = detailList.iterator(); iter.hasNext();) {
456 PurchaseOrderItem poi = (PurchaseOrderItem) iter.next();
457 if (ObjectUtils.isNotNull(poi.getItemType()) && poi.getItemType().isLineItemIndicator()) {
458 if (ObjectUtils.isNull(poi.getItemLineNumber())) {
459 LOG.error("verifyCxmlPOData() The Item Line Number is required for the cXML PO but is missing.");
460 errors.append("Missing Data: Item Line Number\n");
461 }
462 if (StringUtils.isEmpty(poi.getItemCatalogNumber())) {
463 LOG.error("verifyCxmlPOData() The Catalog Number for item number " + poi.getItemLineNumber() + " is required for the cXML PO but is missing.");
464 errors.append("Missing Data: Item#" + poi.getItemLineNumber() + " - Catalog Number\n");
465 }
466 if (StringUtils.isEmpty(poi.getItemDescription())) {
467 LOG.error("verifyCxmlPOData() The Description for item number " + poi.getItemLineNumber() + " is required for the cXML PO but is missing.");
468 errors.append("Missing Data: Item#" + poi.getItemLineNumber() + " - Description\n");
469 }
470 if (StringUtils.isEmpty(poi.getItemUnitOfMeasureCode())) {
471 LOG.error("verifyCxmlPOData() The Unit Of Measure Code for item number " + poi.getItemLineNumber() + " is required for the cXML PO but is missing.");
472 errors.append("Missing Data: Item#" + poi.getItemLineNumber() + " - Unit Of Measure\n");
473 }
474 if (StringUtils.isEmpty(poi.getExternalOrganizationB2bProductTypeName())) {
475 LOG.error("verifyCxmlPOData() The External Org B2B Product Type Name for item number " + poi.getItemLineNumber() + " is required for the cXML PO but is missing.");
476 errors.append("Missing Data: Item#" + poi.getItemLineNumber() + " - External Org B2B Product Type Name\n");
477 }
478 if (poi.getItemQuantity() == null) {
479 LOG.error("verifyCxmlPOData() The Order Quantity for item number " + poi.getItemLineNumber() + " is required for the cXML PO but is missing.");
480 errors.append("Missing Data: Item#" + poi.getItemLineNumber() + " - Order Quantity\n");
481 }
482 if (poi.getItemUnitPrice() == null) {
483 LOG.error("verifyCxmlPOData() The Unit Price for item number " + poi.getItemLineNumber() + " is required for the cXML PO but is missing.");
484 errors.append("Missing Data: Item#" + poi.getItemLineNumber() + " - Unit Price\n");
485 }
486 }
487 }
488
489 return errors.toString();
490 }
491
492
493
494
495 protected String getContractManagerEmail(ContractManager cm) {
496
497 Person contractManager = getPersonService().getPerson(cm.getContractManagerUserIdentifier());
498 if (ObjectUtils.isNotNull(contractManager)) {
499 return contractManager.getEmailAddressUnmasked();
500 }
501 return "";
502 }
503
504
505
506
507 protected String getRequisitionInitiatorPrincipal(String requisitionInitiatorPrincipalId) {
508
509 Principal requisitionInitiator = KimApiServiceLocator.getIdentityService().getPrincipal(requisitionInitiatorPrincipalId);
510 if (ObjectUtils.isNotNull(requisitionInitiator)) {
511 return requisitionInitiator.getPrincipalName();
512 }
513 return "";
514 }
515
516 public void setRequisitionService(RequisitionService requisitionService) {
517 this.requisitionService = requisitionService;
518 }
519
520 public void setParameterService(ParameterService parameterService) {
521 this.parameterService = parameterService;
522 }
523
524 public void setB2bDao(B2BDao b2bDao) {
525 this.b2bDao = b2bDao;
526 }
527
528
529
530
531 protected PersonService getPersonService() {
532 if(personService==null) {
533 personService = SpringContext.getBean(PersonService.class);
534 }
535 return personService;
536 }
537
538 public void setB2bEnvironment(String environment) {
539 b2bEnvironment = environment;
540 }
541
542 public void setB2bUserAgent(String userAgent) {
543 b2bUserAgent = userAgent;
544 }
545
546 public void setB2bPurchaseOrderURL(String purchaseOrderURL) {
547 b2bPurchaseOrderURL = purchaseOrderURL;
548 }
549
550 public void setB2bPurchaseOrderIdentity(String b2bPurchaseOrderIdentity) {
551 this.b2bPurchaseOrderIdentity = b2bPurchaseOrderIdentity;
552 }
553
554 public void setB2bPurchaseOrderPassword(String purchaseOrderPassword) {
555 b2bPurchaseOrderPassword = purchaseOrderPassword;
556 }
557
558 public String getB2bEnvironment() {
559 return b2bEnvironment;
560 }
561
562 public String getB2bUserAgent() {
563 return b2bUserAgent;
564 }
565
566 public String getB2bPurchaseOrderURL() {
567 return b2bPurchaseOrderURL;
568 }
569
570 public String getB2bPurchaseOrderIdentity() {
571 return b2bPurchaseOrderIdentity;
572 }
573
574 public String getB2bPurchaseOrderPassword() {
575 return b2bPurchaseOrderPassword;
576 }
577
578
579
580
581 public String getBuildingLine(PurchaseOrderDocument purchaseOrder) {
582 StringBuffer line = new StringBuffer();
583 if (StringUtils.isNotEmpty(purchaseOrder.getDeliveryBuildingName())) {
584 line.append(" <Contact label=\"Building\" linenumber=\"5\"><![CDATA[").append(purchaseOrder.getDeliveryBuildingName()).append(" (").append(purchaseOrder.getDeliveryBuildingCode()).append(")]]></Contact>\n");
585 }
586 return line.toString();
587 }
588 }