shipping 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,532 @@
1
+ # Author:: Lucas Carlson (mailto:lucas@rufy.com)
2
+ # Copyright:: Copyright (c) 2005 Lucas Carlson
3
+ # License:: LGPL
4
+
5
+ module Shipping
6
+ class FedEx < Base
7
+ # Gets the total price of the shipping
8
+ def price
9
+ get_price
10
+ p = @response.gsub(/.*"#{Tag.index 'net_charge_amount'}(-1)?,"([^"]+)".*99,""/,'\2').to_f
11
+ raise ShippingError, @response.gsub(/.*"3,"([^"]+)".*99,""/,'\1') if p == 0
12
+ return p
13
+ end
14
+
15
+ # Gets the base price of the shipping (with discounts taken into consideration)
16
+ def base_price
17
+ get_price
18
+ p = @response.gsub(/.*"#{Tag.index 'base_rate_amount'}(-1)?,"([^"]+)".*99,""/,'\2').to_f
19
+ raise ShippingError, @response.gsub(/.*"3,"([^"]+)".*99,""/,'\1') if p == 0
20
+ return p
21
+ end
22
+
23
+ private
24
+
25
+ def get_price #:nodoc:
26
+ @required = [:zip, :sender_zip, :weight]
27
+ @required += [:transaction_type, :fedex_account, :fedex_meter, :fedex_url]
28
+
29
+ @transaction_type ||= 'rate_services'
30
+ raise ShippingError, "No such transaction type" unless TransactionTypes.include?(@transaction_type)
31
+ @weight = @weight.to_f.to_s # all weights need to have a dot in them
32
+
33
+ post_data = ["0,\"#{TransactionTypes[@transaction_type][0]}\""] # this is required to be first
34
+
35
+ {
36
+ 'sender_fedex_express_account_number' => @fedex_account,
37
+ 'meter_number' => @fedex_meter,
38
+ 'carrier_code' => TransactionTypes[@transaction_type][1],
39
+ 'sender_postal_code' => @sender_zip,
40
+ 'sender_country_code' => @sender_country || 'US',
41
+ 'recipient_postal_code' => @zip,
42
+ 'recipient_country_code' => @country || 'US',
43
+ 'weight_units' => @weight_units || 'LBS',
44
+ 'package_total' => @package_total || '1', # total number of pieces
45
+ 'total_package_weight' => @weight,
46
+ 'declared_value' => @declared_value,
47
+ 'packaging_type' => @packaging_type || "01", # customer packaging
48
+ 'service_type' => ServiceTypes[@service_type] || ServiceTypes['ground_service']
49
+
50
+ }.each { |i,v| post_data << "#{Tag.index i},\"#{v.to_s.strip}\"" unless v.to_s.strip.empty? }
51
+
52
+ post_data += ['99,""'] # this is the terminating tag
53
+ @data = post_data.join
54
+
55
+ get_response @fedex_url
56
+ end
57
+
58
+ ServiceTypes = {
59
+ "priority" => "01",
60
+ "2day" => "03",
61
+ "standard_overnight" => "05",
62
+ "first_overnight" => "06",
63
+ "express_saver" => "20",
64
+ "1day_freight" => "70",
65
+ "2day_freight" => "80",
66
+ "3day_freight" => "83",
67
+ "international_priority" => "01",
68
+ "international_economy" => "03",
69
+ "international_first" => "06",
70
+ "international_priority_freight" => "70",
71
+ "international_economy_freight" => "86",
72
+ "home_delivery" => "90",
73
+ "ground_service" => "92",
74
+ "international_ground_service" => "92"
75
+ }
76
+
77
+ TransactionTypes = {
78
+ 'rate_ground' => ['022','FDXG'],
79
+ 'rate_express' => ['022','FDXE'],
80
+ 'rate_services' => ['025',''],
81
+ 'ship_ground' => ['021','FDXG'],
82
+ 'ship_express' => ['021','FDXE'],
83
+ 'cancel_express' => ['023','FDXE'],
84
+ 'cancel_ground' => ['023','FDXG'],
85
+ 'close_ground' => ['007','FDXG'],
86
+ 'service_available' => ['019','FDXE'],
87
+ 'fedex_locater' => ['410',''],
88
+ 'subscribe' => ['211',''],
89
+ 'sig_proof_delivery' => ['402',''],
90
+ 'track' => ['405',''],
91
+ 'ref_track' => ['403','']
92
+ }
93
+
94
+ Tag = {
95
+ 0 => 'transaction_code',
96
+ 1 => 'customer_transaction_identifier',
97
+ 2 => 'transaction_error_code',
98
+ 3 => 'transaction_error_message',
99
+ 4 => 'sender_company',
100
+ 5 => 'sender_address_line_1',
101
+ 6 => 'sender_address_line_2',
102
+ 7 => 'sender_city',
103
+ 8 => 'sender_state',
104
+ 9 => 'sender_postal_code',
105
+ 10 => 'sender_fedex_express_account_number',
106
+ 11 => 'recipient_company',
107
+ 12 => 'recipient_contact_name',
108
+ 13 => 'recipient_address_line_1',
109
+ 14 => 'recipient_address_line_2',
110
+ 15 => 'recipient_city',
111
+ 16 => 'recipient_state',
112
+ 17 => 'recipient_postal_code',
113
+ 18 => 'recipient_phone_number',
114
+ 20 => 'payer_account_number',
115
+ 23 => 'pay_type',
116
+ 24 => 'ship_date',
117
+ 25 => 'reference_information',
118
+ 27 => 'cod_flag',
119
+ 28 => 'cod_return_tracking_number',
120
+ 29 => 'tracking_number',
121
+ 30 => 'ursa_code',
122
+ 32 => 'sender_contact_name',
123
+ 33 => 'service_commitment',
124
+ 38 => 'sender_department',
125
+ 40 => 'alcohol_type',
126
+ 41 => 'alcohol_packaging',
127
+ 44 => 'hal_address',
128
+ 46 => 'hal_city',
129
+ 47 => 'hal_state',
130
+ 48 => 'hal_postal_code',
131
+ 49 => 'hal_phone_number',
132
+ 50 => 'recipient_country_code',
133
+ 51 => 'signature_release_ok_flag',
134
+ 52 => 'alcohol_packages',
135
+ 57 => 'dim_height',
136
+ 58 => 'dim_width',
137
+ 59 => 'dim_length',
138
+ 65 => 'astra_barcode',
139
+ 66 => 'broker_name',
140
+ 67 => 'broker_phone_number',
141
+ 68 => 'customs_declared_value_currency_type',
142
+ 70 => 'duties_pay_type',
143
+ 71 => 'duties_payer_account',
144
+ 72 => 'terms_of_sale',
145
+ 73 => 'parties_to_transaction',
146
+ 74 => 'country_of_ultimate_destination',
147
+ 75 => 'weight_units',
148
+ 76 => 'commodity_number_of_pieces',
149
+ 79 => 'description_of_contents',
150
+ 80 => 'country_of_manufacturer',
151
+ 81 => 'harmonized_code',
152
+ 82 => 'unit_quantity',
153
+ 83 => 'export_license_number',
154
+ 84 => 'export_license_expiration_date',
155
+ 99 => 'end_of_record',
156
+ 113 => 'commercial_invoice_flag',
157
+ 116 => 'package_total',
158
+ 117 => 'sender_country_code',
159
+ 118 => 'recipient_irs',
160
+ 120 => 'ci_marks_and_numbers',
161
+ 169 => 'importer_country',
162
+ 170 => 'importer_name',
163
+ 171 => 'importer_company',
164
+ 172 => 'importer_address_line_1',
165
+ 173 => 'importer_address_line_2',
166
+ 174 => 'importer_city',
167
+ 175 => 'importer_state',
168
+ 176 => 'importer_postal_code',
169
+ 177 => 'importer_account_number',
170
+ 178 => 'importer_number_phone',
171
+ 180 => 'importer_id',
172
+ 183 => 'sender_phone_number',
173
+ 186 => 'cod_add_freight_charges_flag',
174
+ 188 => 'label_buffer_data_stream',
175
+ 190 => 'document_pib_shipment_flag',
176
+ 194 => 'delivery_day',
177
+ 195 => 'destination',
178
+ 198 => 'destination_location_id',
179
+ 404 => 'commodity_license_exception',
180
+ 409 => 'delivery_date',
181
+ 411 => 'cod_return_label_buffer_data_stream',
182
+ 413 => 'nafta_flag',
183
+ 414 => 'commodity_unit_of_measure',
184
+ 418 => 'ci_comments',
185
+ 431 => 'dim_weight_used_flag',
186
+ 439 => 'cod_return_contact_name',
187
+ 440 => 'residential_delivery_flag',
188
+ 496 => 'freight_service_commitment',
189
+ 498 => 'meter_number',
190
+ 526 => 'form_id',
191
+ 527 => 'cod_return_form_id',
192
+ 528 => 'commodity_eccn',
193
+ 535 => 'cod_return',
194
+ 536 => 'cod_return_service_commitment',
195
+ 543 => 'cod_return_collect_plus_freight_amount',
196
+ 557 => 'message_type_code',
197
+ 558 => 'message_code',
198
+ 559 => 'message_text',
199
+ 600 => 'forwarding_agent_routed_export_transaction_indicator',
200
+ 602 => 'exporter_ein_ssn_indicator',
201
+ 603 => 'int-con_company_name',
202
+ 604 => 'int-con_contact_name',
203
+ 605 => 'int-con_address_line_1',
204
+ 606 => 'int-con_address_line_2',
205
+ 607 => 'int-con_city',
206
+ 608 => 'int-con_state',
207
+ 609 => 'int-con_zip',
208
+ 610 => 'int-con_phone_number',
209
+ 611 => 'int-con_country',
210
+ 1005 => 'manifest_invoic_e_file_name',
211
+ 1006 => 'domain_name',
212
+ 1007 => 'close_manifest_date',
213
+ 1008 => 'package_ready_time',
214
+ 1009 => 'time_companyclose',
215
+ 1032 => 'duties_payer_country_code',
216
+ 1089 => 'rate_scale',
217
+ 1090 => 'rate_currency_type',
218
+ 1092 => 'rate_zone',
219
+ 1096 => 'origin_location_id',
220
+ 1099 => 'volume_units',
221
+ 1101 => 'payer_credit_card_number',
222
+ 1102 => 'payer_credit_card_type',
223
+ 1103 => 'sender_fax',
224
+ 1104 => 'payer_credit_card_expiration_date',
225
+ 1115 => 'ship_time',
226
+ 1116 => 'dim_units',
227
+ 1117 => 'package_sequence',
228
+ 1118 => 'release_authorization_number',
229
+ 1119 => 'future_day_shipment',
230
+ 1120 => 'inside_pickup_flag',
231
+ 1121 => 'inside_delivery_flag',
232
+ 1123 => 'master_tracking_number',
233
+ 1124 => 'master_form_id',
234
+ 1137 => 'ursa_uned_prefix',
235
+ 1139 => 'sender_irs_ein_number',
236
+ 1145 => 'recipient_department',
237
+ 1159 => 'scan_description',
238
+ 1160 => 'scan_location_city',
239
+ 1161 => 'scan_location_state',
240
+ 1162 => 'scan_date',
241
+ 1163 => 'scan_time',
242
+ 1164 => 'scan_location_country',
243
+ 1167 => 'disp_exception_cd',
244
+ 1168 => 'status_exception_cd',
245
+ 1174 => 'bso_flag',
246
+ 1178 => 'ursa_suffix_code',
247
+ 1179 => 'broker_fdx_account_number',
248
+ 1180 => 'broker_company',
249
+ 1181 => 'broker_line_1_address',
250
+ 1182 => 'broker_line_2_address',
251
+ 1183 => 'broker_city',
252
+ 1184 => 'broker_state',
253
+ 1185 => 'broker_postal_code',
254
+ 1186 => 'broker_country_code',
255
+ 1187 => 'broker_id_number',
256
+ 1193 => 'ship_delete_message',
257
+ 1195 => 'payer_country_code',
258
+ 1200 => 'hold_at_location_hal_flag',
259
+ 1201 => 'sender_email_address',
260
+ 1202 => 'recipient_email_address',
261
+ 1203 => 'optional_ship_alert_message',
262
+ 1204 => 'ship_alert_email_address',
263
+ 1206 => 'ship_alert_notification_flag',
264
+ 1208 => 'no_indirect_delivery_flag_signature_required',
265
+ 1210 => 'purpose_of_shipment',
266
+ 1211 => 'pod_address',
267
+ 1213 => 'proactive_notification_flag',
268
+ 1237 => 'cod_return_phone',
269
+ 1238 => 'cod_return_company',
270
+ 1239 => 'cod_return_department',
271
+ 1240 => 'cod_return_address_1',
272
+ 1241 => 'cod_return_address_2',
273
+ 1242 => 'cod_return_city',
274
+ 1243 => 'cod_return_state',
275
+ 1244 => 'cod_return_postal_code',
276
+ 1253 => 'packaging_list_enclosed_flag',
277
+ 1265 => 'hold_at_location_contact_name',
278
+ 1266 => 'saturday_delivery_flag',
279
+ 1267 => 'saturday_pickup_flag',
280
+ 1268 => 'dry_ice_flag',
281
+ 1271 => 'shippers_load_and_count_slac',
282
+ 1272 => 'booking_number',
283
+ 1273 => 'packaging_type',
284
+ 1274 => 'service_type',
285
+ 1286 => 'exporter_ppi-_contact_name',
286
+ 1287 => 'exporter_ppi-company_name',
287
+ 1288 => 'exporter_ppi-address_line_1',
288
+ 1289 => 'exporter_ppi-address_line_2',
289
+ 1290 => 'exporter_ppi-city',
290
+ 1291 => 'exporter_ppi-state',
291
+ 1292 => 'exporter_ppi-zip',
292
+ 1293 => 'exporter_ppi-country',
293
+ 1294 => 'exporter_ppi-phone_number',
294
+ 1295 => 'exporter_ppi-ein_ssn',
295
+ 1297 => 'customer_invoice_number',
296
+ 1300 => 'purchase_order_number',
297
+ 1331 => 'dangerous',
298
+ 1332 => 'alcohol_flag',
299
+ 1333 => 'drop_off_type',
300
+ 1337 => 'package_content_information',
301
+ 1339 => 'estimated_delivery_date',
302
+ 1340 => 'estimated_delivery_time',
303
+ 1341 => 'sender_pager_number',
304
+ 1342 => 'recipient_pager_number',
305
+ 1343 => 'broker_email_address',
306
+ 1344 => 'broker_fax_number',
307
+ 1346 => 'emerge_shipment_identifier',
308
+ 1347 => 'emerge_merchant_identifier',
309
+ 1349 => 'aes_filing_status',
310
+ 1350 => 'xtn_suffix_number',
311
+ 1352 => 'sender_ein_ssn_identificator',
312
+ 1358 => 'aes_ftsr_exemption_number',
313
+ 1359 => 'sed_legend_number',
314
+ 1366 => 'close_manifest_time',
315
+ 1367 => 'close_manifest_data_buffer',
316
+ 1368 => 'label_type',
317
+ 1369 => 'label_printer_type',
318
+ 1370 => 'label_media_type',
319
+ 1371 => 'manifest_only_request_flag',
320
+ 1372 => 'manifest_total',
321
+ 1376 => 'rate_weight_unit_of_measure',
322
+ 1377 => 'dim_weight_unit_of_measure',
323
+ 1391 => 'client_revision_indicator',
324
+ 1392 => 'inbound_visibility_block_shipment_data_indicator',
325
+ 1394 => 'shipment_content_records_total',
326
+ 1395 => 'part_number',
327
+ 1396 => 'sku_item_upc',
328
+ 1397 => 'receive_quantity',
329
+ 1398 => 'description',
330
+ 1399 => 'aes_entry_number',
331
+ 1400 => 'total_shipment_weight',
332
+ 1401 => 'total_package_weight',
333
+ 1402 => 'billed_weight',
334
+ 1403 => 'dim_weight',
335
+ 1404 => 'total_volume',
336
+ 1405 => 'alcohol_volume',
337
+ 1406 => 'dry_ice_weight',
338
+ 1407 => 'commodity_weight',
339
+ 1408 => 'commodity_unit_value',
340
+ 1409 => 'cod_amount',
341
+ 1410 => 'commodity_customs_value',
342
+ 1411 => 'total_customs_value',
343
+ 1412 => 'freight_charge',
344
+ 1413 => 'insurance_charge',
345
+ 1414 => 'taxes_miscellaneous_charge',
346
+ 1415 => 'declared_value',
347
+ 1416 => 'base_rate_amount',
348
+ 1417 => 'total_surcharge_amount',
349
+ 1418 => 'total_discount_amount',
350
+ 1419 => 'net_charge_amount',
351
+ 1420 => 'total_rebate_amount',
352
+ 1429 => 'list_variable_handling_charge_amount',
353
+ 1431 => 'list_total_customer_charge',
354
+ 1432 => 'cod_customer_amount',
355
+ 1450 => 'more_data_indicator',
356
+ 1451 => 'sequence_number',
357
+ 1452 => 'last_tracking_number',
358
+ 1453 => 'track_reference_type',
359
+ 1454 => 'track_reference',
360
+ 1456 => 'spod_type_request',
361
+ 1458 => 'spod_fax_recipient_name',
362
+ 1459 => 'spod_fax_recipient_number',
363
+ 1460 => 'spod_fax_sender_name',
364
+ 1461 => 'spod_fax_sender_phone_number',
365
+ 1462 => 'language_indicator',
366
+ 1463 => 'spod_fax_recipient_company_name_mail',
367
+ 1464 => 'spod_fax_recipient_address_line_1_mail',
368
+ 1465 => 'spod_fax_recipient_address_line_2_mail',
369
+ 1466 => 'spod_fax_recipient_city_mail',
370
+ 1467 => 'spod_fax_recipient_state_mail',
371
+ 1468 => 'spod_fax_recipient_zip_postal_code_mail',
372
+ 1469 => 'spod_fax_recipient_country_mail',
373
+ 1470 => 'spod_fax_confirmation',
374
+ 1471 => 'spod_letter',
375
+ 1472 => 'spod_ground_recipient_name',
376
+ 1473 => 'spod_ground_recipient_company_name',
377
+ 1474 => 'spod_ground_recipient_address_line_1',
378
+ 1475 => 'spod_ground_recipient_address_line_2',
379
+ 1476 => 'spod_ground_recipient_city',
380
+ 1477 => 'spod_ground_recipient_state_province',
381
+ 1478 => 'spod_ground_recipient_zip_postal_code',
382
+ 1479 => 'spod_ground_recipient_country',
383
+ 1480 => 'more_information',
384
+ 1507 => 'list_total_surcharge_amount',
385
+ 1525 => 'effective_net_discount',
386
+ 1528 => 'list_net_charge_amount',
387
+ 1529 => 'rate_indicator_1_numeric_valid_values',
388
+ 1530 => 'list_base_rate_amount',
389
+ 1531 => 'list_total_discount_amount',
390
+ 1532 => 'list_total_rebate_amount',
391
+ 1534 => 'detail_scan_indicator',
392
+ 1535 => 'paging_token',
393
+ 1536 => 'number_of_relationships',
394
+ 1537 => 'search_relationship_string',
395
+ 1538 => 'search_relationship_type_code',
396
+ 1551 => 'delivery_notification_flag',
397
+ 1552 => 'language_code',
398
+ 1553 => 'shipper_delivery_notification_flag',
399
+ 1554 => 'shipper_ship_alert_flag',
400
+ 1555 => 'shipper_language_code',
401
+ 1556 => 'recipient_delivery_notification_flag',
402
+ 1557 => 'recipient_ship_alert_flag',
403
+ 1558 => 'recipient_language_code',
404
+ 1559 => 'broker_delivery_notification_flag',
405
+ 1560 => 'broker_ship_alert_flag',
406
+ 1561 => 'broker_language_code',
407
+ 1562 => 'fedex_staffed_location_flag',
408
+ 1563 => 'fedex_self_service_location_indicator',
409
+ 1564 => 'fasc',
410
+ 1565 => 'latest_express_dropoff_flag',
411
+ 1566 => 'express_dropoff_after_time',
412
+ 1567 => 'fedex_location_intersection_street_address',
413
+ 1568 => 'distance',
414
+ 1569 => 'hours_of_operation',
415
+ 1570 => 'hours_of_operation_sat',
416
+ 1571 => 'last_express_dropoff',
417
+ 1572 => 'last_express_dropoff_sat',
418
+ 1573 => 'express_service_flag',
419
+ 1574 => 'location_count',
420
+ 1575 => 'fedex_location_business_name',
421
+ 1576 => 'fedex_location_business_type',
422
+ 1577 => 'fedex_location_city',
423
+ 1578 => 'fedex_location_state',
424
+ 1579 => 'fedex_location_postal_code',
425
+ 1580 => 'dangerous_goods_flag',
426
+ 1581 => 'saturday_service_flag',
427
+ 1582 => 'begin_date',
428
+ 1583 => 'end_date',
429
+ 1584 => 'tracking_groups',
430
+ 1606 => 'variable_handling_charge_level',
431
+ 1607 => 'doc_tab_header_1',
432
+ 1608 => 'doc_tab_header_2',
433
+ 1609 => 'doc_tab_header_3',
434
+ 1610 => 'doc_tab_header_4',
435
+ 1611 => 'doc_tab_header_5',
436
+ 1612 => 'doc_tab_header_6',
437
+ 1613 => 'doc_tab_header_7',
438
+ 1614 => 'doc_tab_header_8',
439
+ 1615 => 'doc_tab_header_9',
440
+ 1616 => 'doc_tab_header_10',
441
+ 1617 => 'doc_tab_header_11',
442
+ 1618 => 'doc_tab_header_12',
443
+ 1624 => 'doc_tab_field_1',
444
+ 1625 => 'doc_tab_field_2',
445
+ 1626 => 'doc_tab_field_3',
446
+ 1627 => 'doc_tab_field_4',
447
+ 1628 => 'doc_tab_field_5',
448
+ 1629 => 'doc_tab_field_6',
449
+ 1630 => 'doc_tab_field_7',
450
+ 1631 => 'doc_tab_field_8',
451
+ 1632 => 'doc_tab_field_9',
452
+ 1633 => 'doc_tab_field_10',
453
+ 1634 => 'doc_tab_field_11',
454
+ 1635 => 'doc_tab_field_12',
455
+ 1636 => 'delivery_area_surcharge',
456
+ 1637 => 'list_delivery_area_surcharge',
457
+ 1638 => 'fuel_surcharge',
458
+ 1639 => 'list_fuel_surcharge',
459
+ 1640 => 'fice_surcharge',
460
+ 1642 => 'value_added_tax',
461
+ 1644 => 'offshore_surcharge',
462
+ 1645 => 'list_offshore_surcharge',
463
+ 1649 => 'other_surcharges',
464
+ 1650 => 'list_other_surcharges',
465
+ 1704 => 'service_type_description',
466
+ 1705 => 'deliver_to',
467
+ 1706 => 'signed_for',
468
+ 1707 => 'delivery_time',
469
+ 1711 => 'status_exception',
470
+ 1713 => 'tracking_cod_flag',
471
+ 1715 => 'number_of_track_activities',
472
+ 1716 => 'delivery_reattempt_date',
473
+ 1717 => 'delivery_reattempt_time',
474
+ 1718 => 'package_type_description',
475
+ 1720 => 'delivery_date_numeric',
476
+ 1721 => 'tracking_activity_line_1',
477
+ 1722 => 'tracking_activity_line_2',
478
+ 1723 => 'tracking_activity_line_3',
479
+ 1724 => 'tracking_activity_line_4',
480
+ 1725 => 'tracking_activity_line_5',
481
+ 1726 => 'tracking_activity_line_6',
482
+ 1727 => 'tracking_activity_line_7',
483
+ 1728 => 'tracking_activity_line_8',
484
+ 1729 => 'tracking_activity_line_9',
485
+ 1730 => 'tracking_activity_line_10',
486
+ 1731 => 'tracking_activity_line_11',
487
+ 1732 => 'tracking_activity_line_12',
488
+ 1733 => 'tracking_activity_line_13',
489
+ 1734 => 'tracking_activity_line_14',
490
+ 1735 => 'tracking_activity_line_15',
491
+ 2254 => 'recipient_fax_number',
492
+ 2382 => 'return_shipment_indicator',
493
+ 3000 => 'cod_type_collection',
494
+ 3001 => 'fedex_ground_purchase_order',
495
+ 3002 => 'fedex_ground_invoice',
496
+ 3003 => 'fedex_ground_customer_reference',
497
+ 3008 => 'autopod_flag',
498
+ 3009 => 'aod_flag',
499
+ 3010 => 'oversize_flag',
500
+ 3011 => 'other_oversize_flag',
501
+ 3018 => 'nonstandard_container_flag',
502
+ 3019 => 'fedex_signature_home_delivery_flag',
503
+ 3020 => 'fedex_home_delivery_type',
504
+ 3023 => 'fedex_home_delivery_date',
505
+ 3024 => 'fedex_home_delivery_phone_number',
506
+ 3025 => 'carrier_code',
507
+ 3028 => 'ground_account_number',
508
+ 3035 => 'ship_alert_fax_number',
509
+ 3045 => 'cod_return_reference_indicator',
510
+ 3046 => 'additional_handling_detected',
511
+ 3053 => 'multiweight_net_charge',
512
+ 3090 => 'last_ground_dropoff',
513
+ 3091 => 'last_ground_dropoff_sat',
514
+ 3092 => 'ground_service_flag',
515
+ 3124 => 'oversize_classification',
516
+ 4003 => 'subscriber_contact_name',
517
+ 4004 => 'subscriber_password_reminder',
518
+ 4007 => 'subscriber_company_name',
519
+ 4008 => 'subscriber_address_line_1',
520
+ 4009 => 'subscriber_address_line_2',
521
+ 4011 => 'subscriber_city_name',
522
+ 4012 => 'subscriber_state_code',
523
+ 4013 => 'subscriber_postal_code',
524
+ 4014 => 'subscriber_country_code',
525
+ 4015 => 'subscriber_phone_number',
526
+ 4017 => 'subscriber_pager_number',
527
+ 4018 => 'subscriber_email_address',
528
+ 4021 => 'subscription_service_name',
529
+ 4022 => 'subscriber_fax_number'
530
+ }
531
+ end
532
+ end
@@ -0,0 +1,83 @@
1
+ # Author:: Lucas Carlson (mailto:lucas@rufy.com)
2
+ # Copyright:: Copyright (c) 2005 Lucas Carlson
3
+ # License:: LGPL
4
+
5
+ =begin
6
+ UPS Service transaction_type
7
+ ---------------------------------------------
8
+ Next Day Air Early 1DM
9
+ Next Day Air 1DA
10
+ Next Day Air Intra 1DAPI (Puerto Rico)
11
+ Next Day Air Saver 1DP
12
+ 2nd Day Air A M2DM
13
+ 2nd Day Air 2DA
14
+ 3 Day Select 3DS
15
+ Ground GND
16
+ Canada Standard STD
17
+ Worldwide Express XPR
18
+ Worldwide Express XDM
19
+ Worldwide Expedited XPD
20
+ =end
21
+
22
+ module Shipping
23
+ class UPS < Base
24
+
25
+ API_VERSION = "1.0001"
26
+
27
+ def price
28
+ @required = [:zip, :country, :sender_zip, :weight]
29
+
30
+ @insured_value ||= 0
31
+ @country ||= 'US'
32
+ @sender_country ||= 'US'
33
+ @transaction_type ||= 'GND' # default to UPS ground
34
+
35
+ @data = "AppVersion=1.2&AcceptUPSLicenseAgreement=yes&ResponseType=application/x-ups-rss&ActionCode=3&RateChart=Customer+Counter&DCISInd=0&SNDestinationInd1=0&SNDestinationInd2=0&ResidentialInd=$r&PackagingType=00&ServiceLevelCode=#{@transaction_type}&ShipperPostalCode=#{@sender_zip}&ShipperCountry=#{@sender_country}&ConsigneePostalCode=#{@zip}&ConsigneeCountry=#{@country}&PackageActualWeight=#{@weight}&DeclaredValueInsurance=#{@insured_value}"
36
+
37
+ get_response "http://www.ups.com/using/services/rave/qcost_dss.cgi"
38
+
39
+ price = @response.split("%")
40
+ price = price[price.size-2]
41
+
42
+ return price.to_f
43
+ end
44
+
45
+ def valid_address?( delta = 1.0 )
46
+ @required = [:ups_account, :ups_user, :ups_password]
47
+
48
+ state = STATES.has_value?(@state.downcase) ? STATES.index(@state.downcase) : @state
49
+
50
+ @data = "<?xml version=\"1.0\"?>
51
+ <AccessRequest>
52
+ <AccessLicenseNumber>#{@ups_account}</AccessLicenseNumber>
53
+ <UserId>#{@ups_user}</UserId>
54
+ <Password>#{@ups_password}</Password>
55
+ </AccessRequest>
56
+ <?xml version=\"1.0\"?>
57
+ <AddressValidationRequest xml:lang=\"en-US\">
58
+ <Request>
59
+ <TransactionReference>
60
+ <CustomerContext>#{@city}, #{state} #{@zip}</CustomerContext>
61
+ <XpciVersion>#{API_VERSION}</XpciVersion>
62
+ </TransactionReference>
63
+ <RequestAction>AV</RequestAction>
64
+ </Request>
65
+ <Address>
66
+ <City>#{@city}</City>
67
+ <StateProvinceCode>#{state}</StateProvinceCode>
68
+ <PostalCode>#{@zip}</PostalCode>
69
+ </Address>
70
+ </AddressValidationRequest>"
71
+
72
+ get_response "https://wwwcie.ups.com/ups.app/xml/AV"
73
+
74
+ doc = REXML::Document.new(@response)
75
+
76
+ if doc.root.elements["Response"].elements["ResponseStatusCode"].text == "1" && doc.root.elements["AddressValidationResult"].elements["Quality"].text.to_f >= delta
77
+ return true
78
+ else
79
+ return false
80
+ end
81
+ end
82
+ end
83
+ end
data/lib/shipping.rb ADDED
@@ -0,0 +1,33 @@
1
+ #--
2
+ # Copyright (c) 2005 Lucas Carlson
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+ # Author:: Lucas Carlson (mailto:lucas@rufy.com)
24
+ # Copyright:: Copyright (c) 2005 Lucas Carlson
25
+ # License:: LGPL
26
+
27
+ require 'yaml'
28
+ require 'rexml/document'
29
+ require 'net/http'
30
+ require 'net/https'
31
+ require 'shipping/base'
32
+ require 'shipping/fedex'
33
+ require 'shipping/ups'
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ class BaseTest < Test::Unit::TestCase
3
+ def setup
4
+ @ship = Shipping::Base.new :zip => 97202, :state => "OR", :sender_zip => 10001, :sender_state => "New York", :weight => 2
5
+ end
6
+
7
+ def test_ups
8
+ ups = @ship.ups
9
+ assert_instance_of Shipping::UPS, ups
10
+ assert_equal ups.zip, @ship.zip
11
+ end
12
+
13
+ def test_fedex
14
+ fedex = @ship.fedex
15
+ assert_instance_of Shipping::FedEx, fedex
16
+ assert_equal fedex.zip, @ship.zip
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+ class FedExTest < Test::Unit::TestCase
3
+ def setup
4
+ @ship = Shipping::FedEx.new :zip => 97202, :state => "OR", :sender_zip => 10001, :sender_state => "New York", :weight => 2
5
+ end
6
+
7
+ def test_price
8
+ assert_equal 5.17, @ship.price
9
+ end
10
+ end