~serpent-consulting-services/openerp-usa/fix-shipping_api_ups_cc

« back to all changes in this revision

Viewing changes to shipping_api_usps/stock.py

  • Committer: npgllc
  • Date: 2012-07-30 13:49:29 UTC
  • mfrom: (59.3.1 Shipping_USPS)
  • Revision ID: npgllc-20120730134929-kjevcau0o06ms4az
ADD: shipping_api_usps

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2011 NovaPoint Group LLC (<http://www.novapointgroup.com>)
 
6
#    Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>)
 
7
#
 
8
#    This program is free software: you can redistribute it and/or modify
 
9
#    it under the terms of the GNU General Public License as published by
 
10
#    the Free Software Foundation, either version 3 of the License, or
 
11
#    (at your option) any later version.
 
12
#
 
13
#    This program is distributed in the hope that it will be useful,
 
14
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
#    GNU General Public License for more details.
 
17
#
 
18
#    You should have received a copy of the GNU General Public License
 
19
#    along with this program.  If not, see <http://www.gnu.org/licenses/>
 
20
#
 
21
##############################################################################
 
22
 
 
23
 
 
24
from osv import fields,osv
 
25
from xml.dom.minidom import Document
 
26
from tools.translate import _
 
27
import httplib
 
28
import xml2dic
 
29
 
 
30
import time
 
31
import datetime
 
32
from urlparse import urlparse
 
33
import Image
 
34
import tempfile
 
35
import re
 
36
 
 
37
 
 
38
import netsvc
 
39
import base64
 
40
import logging
 
41
import tools
 
42
 
 
43
from base64 import b64decode
 
44
import binascii
 
45
 
 
46
 
 
47
class logistic_company(osv.osv):
 
48
    _inherit="logistic.company"
 
49
    def _get_company_code(self, cr, user, context=None):
 
50
        res =  super(logistic_company, self)._get_company_code(cr, user, context=context)
 
51
        res.append(('usps', 'USPS'))
 
52
        
 
53
        return res
 
54
    _columns = {
 
55
                                        
 
56
                    'ship_company_code' : fields.selection(_get_company_code, 'Ship Company', method=True, required=True, size=64),
 
57
                    'usps_userid'       : fields.char('User ID', size=128),
 
58
                    'usps_url_test'     : fields.char('Test Url', size=512),
 
59
                    'usps_url'          : fields.char('Production URL', size=512),
 
60
                    'usps_url_secure_test'     : fields.char('Test Url SSL', size=512),
 
61
                    'usps_url_secure'          : fields.char('Production URL SSL', size=512),
 
62
                
 
63
                }
 
64
 
 
65
logistic_company()
 
66
class stock_packages(osv.osv):
 
67
    _inherit = "stock.packages"
 
68
    _columns = {
 
69
                    'usps_confirmation_number': fields.char('USPS Confirm Number', size=64, readonly=True),
 
70
                }
 
71
 
 
72
stock_packages()
 
73
 
 
74
class stock_picking(osv.osv):
 
75
 
 
76
 
 
77
    _inherit = "stock.picking"
 
78
    def _get_company_code(self, cr, user, context=None):
 
79
        res =  super(stock_picking, self)._get_company_code(cr, user, context=context)
 
80
        res.append(('usps', 'USPS'))
 
81
        
 
82
        return res
 
83
    def _get_service_type_usps(self, cr, uid, context=None):
 
84
        return [
 
85
            ('First Class', 'First Class'),
 
86
            ('First Class HFP Commercial', 'First Class HFP Commercial'),
 
87
            ('FirstClassMailInternational', 'First Class Mail International'),
 
88
            ('Priority', 'Priority'),
 
89
            ('Priority Commercial', 'Priority Commercial'),
 
90
            ('Priority HFP Commercial', 'Priority HFP Commercial'),
 
91
            ('PriorityMailInternational', 'Priority Mail International'),
 
92
            ('Express', 'Express'),
 
93
            ('Express Commercial', 'Express Commercial'),
 
94
            ('Express SH', 'Express SH'),
 
95
            ('Express SH Commercial', 'Express SH Commercial'),
 
96
            ('Express HFP', 'Express HFP'),
 
97
            ('Express HFP Commercial', 'Express HFP Commercial'),
 
98
            ('ExpressMailInternational', 'Express Mail International'),
 
99
            ('ParcelPost', 'Parcel Post'),
 
100
            ('ParcelSelect', 'Parcel Select'),
 
101
            ('StandardMail', 'Standard Mail'),
 
102
            ('CriticalMail', 'Critical Mail'),
 
103
            ('Media', 'Media'),
 
104
            ('Library', 'Library'),
 
105
            ('All', 'All'),
 
106
            ('Online', 'Online'),
 
107
        ]
 
108
    
 
109
    def _get_first_class_mail_type_usps(self, cr, uid, context=None):
 
110
        return [
 
111
            ('Letter', 'Letter'),
 
112
            ('Flat', 'Flat'),
 
113
            ('Parcel', 'Parcel'),
 
114
            ('Postcard', 'Postcard'),
 
115
        ]
 
116
    
 
117
    def _get_container_usps(self, cr, uid, context=None):
 
118
        return [
 
119
            ('Variable', 'Variable'),
 
120
            ('Card', 'Card'),
 
121
            ('Letter', 'Letter'),
 
122
            ('Flat', 'Flat'),
 
123
            ('Parcel', 'Parcel'),
 
124
            ('Large Parcel', 'Large Parcel'),
 
125
            ('Irregular Parcel', 'Irregular Parcel'),
 
126
            ('Oversized Parcel', 'Oversized Parcel'),
 
127
            ('Flat Rate Envelope', 'Flat Rate Envelope'),
 
128
            ('Padded Flat Rate Envelope', 'Padded Flat Rate Envelope'),
 
129
            ('Legal Flat Rate Envelope', 'Legal Flat Rate Envelope'),
 
130
            ('SM Flat Rate Envelope', 'SM Flat Rate Envelope'),
 
131
            ('Window Flat Rate Envelope', 'Window Flat Rate Envelope'),
 
132
            ('Gift Card Flat Rate Envelope', 'Gift Card Flat Rate Envelope'),
 
133
            ('Cardboard Flat Rate Envelope', 'Cardboard Flat Rate Envelope'),
 
134
            ('Flat Rate Box', 'Flat Rate Box'),
 
135
            ('SM Flat Rate Box', 'SM Flat Rate Box'),
 
136
            ('MD Flat Rate Box', 'MD Flat Rate Box'),
 
137
            ('LG Flat Rate Box', 'LG Flat Rate Box'),
 
138
            ('RegionalRateBoxA', 'RegionalRateBoxA'),
 
139
            ('RegionalRateBoxB', 'RegionalRateBoxB'),
 
140
            ('Rectangular', 'Rectangular'),
 
141
            ('Non-Rectangular', 'Non-Rectangular'),
 
142
         ]
 
143
    
 
144
    def _get_size_usps(self, cr, uid, context=None):
 
145
        return [
 
146
            ('REGULAR', 'Regular'),
 
147
            ('LARGE', 'Large'),
 
148
         ]
 
149
    _columns = {
 
150
                    'ship_company_code': fields.selection(_get_company_code, 'Ship Company', method=True,  size=64),
 
151
                    'usps_confirmation_number' : fields.char('Confirmation Number', size=64, readonly=True),
 
152
                    'usps_service_type' : fields.selection(_get_service_type_usps, 'Service Type', size=100),
 
153
                    'usps_package_location' : fields.selection([
 
154
                            ('Front Door','Front Door'),
 
155
                            ('Back Door','Back Door'),
 
156
                            ('Side Door','Side Door'),
 
157
                            ('Knock on Door/Ring Bell','Knock on Door/Ring Bell'),
 
158
                            ('Mail Room','Mail Room'),
 
159
                            ('Office','Office'),
 
160
                            ('Reception','Reception'),
 
161
                            ('In/At Mailbox','In/At Mailbox'),
 
162
                            ('Other','Other'),
 
163
                       ],'Package Location'),
 
164
                    'usps_first_class_mail_type' : fields.selection(_get_first_class_mail_type_usps, 'First Class Mail Type', size=50),
 
165
                    'usps_container' : fields.selection(_get_container_usps,'Container', size=100),
 
166
                    'usps_size' : fields.selection(_get_size_usps,'Size'),
 
167
                    'usps_length' : fields.float('Length'),
 
168
                    'usps_width' :  fields.float('Width'),
 
169
                    'usps_height' :  fields.float('Height'),
 
170
                    'usps_girth' :  fields.float('Girth'),
 
171
                }
 
172
    _defaults = {
 
173
        'usps_service_type'         : 'Priority',
 
174
        'usps_package_location'     : 'Front Door',
 
175
        'usps_first_class_mail_type': 'Parcel',
 
176
        'usps_size'                 : 'REGULAR',
 
177
        'usps_container'            : 'Variable',
 
178
    }
 
179
 
 
180
    def process_ship(self,cr, uid, ids, context=None):
 
181
        do = self.browse(cr, uid, type(ids)==type([]) and ids[0] or ids, context=context)
 
182
        user = self.pool.get('res.users').browse(cr, uid, uid,  context=context)
 
183
        if do.ship_company_code != 'usps':
 
184
            return super(stock_picking, self).process_ship(cr, uid, ids, context=context)
 
185
 
 
186
        if not (do.logis_company and do.logis_company.ship_company_code=='usps'):
 
187
            return super(stock_picking, self).process_ship(cr, uid, ids, context=context)
 
188
        userid = do.logis_company.usps_userid
 
189
        url = do.logis_company.test_mode and do.logis_company.usps_url_secure_test or do.logis_company.usps_url_secure
 
190
        url_prd =  do.logis_company.usps_url
 
191
        url_prd_secure =  do.logis_company.usps_url_secure
 
192
        test=do.logis_company.test_mode
 
193
        str_error = ''
 
194
        ship_message = ''
 
195
        error = False
 
196
        for package in do.packages_ids:
 
197
                    str_error = ''
 
198
        #if do.packages_ids:
 
199
                    #@Changing to production URL SINCE DelivConfirmCertifyV3.0Request works only with production url and test data
 
200
                    url = do.logis_company.usps_url_secure
 
201
                    if test:
 
202
                        request_xml = """<DelivConfirmCertifyV3.0Request USERID="%(user_id)s">
 
203
                                <Option>1</Option>
 
204
                                <ImageParameters></ImageParameters>
 
205
                                <FromName>Joe Smith</FromName>
 
206
                                <FromFirm>ABD Corp.</FromFirm>
 
207
                                <FromAddress1>Apt. 3C</FromAddress1>
 
208
                                <FromAddress2>6406 Ivy Lane</FromAddress2>
 
209
                                <FromCity>Greenbelt</FromCity>
 
210
                                <FromState>MD</FromState>
 
211
                                <FromZip5>20770</FromZip5>
 
212
                                <FromZip4>1234</FromZip4>
 
213
                                <ToName>Tom Collins</ToName>
 
214
                                <ToFirm>XYZ Corp.</ToFirm>
 
215
                                <ToAddress1>Suite 4D</ToAddress1>
 
216
                                <ToAddress2>8 Wildwood Drive</ToAddress2>
 
217
                                <ToCity>Old Lyme</ToCity>
 
218
                                <ToState>CT</ToState>
 
219
                                <ToZip5>06371</ToZip5>
 
220
                                <ToZip4></ToZip4>
 
221
                                <WeightInOunces>1</WeightInOunces>
 
222
                                <ServiceType>Priority</ServiceType>
 
223
                                <SeparateReceiptPage></SeparateReceiptPage>
 
224
                                <POZipCode></POZipCode>
 
225
                                <ImageType>TIF</ImageType>
 
226
                                <LabelDate></LabelDate>
 
227
                                <CustomerRefNo></CustomerRefNo>
 
228
                                <AddressServiceRequested></AddressServiceRequested>
 
229
                                <SenderName></SenderName>
 
230
                                <SenderEMail></SenderEMail>
 
231
                                <RecipientName></RecipientName>
 
232
                                <RecipientEMail></RecipientEMail>
 
233
                                </DelivConfirmCertifyV3.0Request>
 
234
                    """%{   
 
235
                            'user_id'      : userid,
 
236
                        }
 
237
                        request_url = url + '?API=DelivConfirmCertifyV3&XML=' + request_xml
 
238
                    elif  do.company_id.partner_id.address:
 
239
                        from_address = do.company_id.partner_id.address[0]
 
240
                        request_xml = """<DeliveryConfirmationV3.0Request USERID="%(user_id)s">
 
241
                                            <Option>1</Option>
 
242
                                            <ImageParameters />
 
243
                                            <FromName>%(from_name)s</FromName>
 
244
                                            <FromFirm>%(from_firm)s</FromFirm>
 
245
                                            <FromAddress1 />
 
246
                                            <FromAddress2>%(from_address2)s</FromAddress2>
 
247
                                            <FromCity>%(from_city)s</FromCity>
 
248
                                            <FromState>%(from_state)s</FromState>
 
249
                                            <FromZip5>%(from_zip5)s</FromZip5>
 
250
                                            <FromZip4>%(from_zip4)s</FromZip4>
 
251
                                            <ToName>%(to_name)s</ToName>
 
252
                                            <ToFirm>%(to_firm)s</ToFirm>
 
253
                                            <ToAddress1>%(to_address1)s</ToAddress1>
 
254
                                            <ToAddress2>%(to_address2)s</ToAddress2>
 
255
                                            <ToCity>%(to_city)s</ToCity>
 
256
                                            <ToState>%(to_state)s</ToState>
 
257
                                            <ToZip5>%(to_zip5)s</ToZip5>
 
258
                                            <ToZip4>%(to_zip4)s</ToZip4>
 
259
                                            <WeightInOunces>%(weight)s</WeightInOunces>
 
260
                                            <ServiceType>%(service_type)s</ServiceType>
 
261
                                            <POZipCode></POZipCode>
 
262
                                            <ImageType>TIF</ImageType>
 
263
                                            <LabelDate></LabelDate>
 
264
                                            <CustomerRefNo></CustomerRefNo>
 
265
                                            <AddressServiceRequested>TRUE</AddressServiceRequested>
 
266
                                            </DeliveryConfirmationV3.0Request>
 
267
                        """%{   
 
268
                            'user_id'       : userid,
 
269
                            'from_name'     : from_address.name,
 
270
                            'from_firm'     : '',
 
271
                            'from_address2' : from_address.street or '',
 
272
                            'from_city'     : from_address.city or '',
 
273
                            'from_state'    : from_address.state_id and from_address.state_id.code or '',
 
274
                            'from_zip5'     : from_address.zip_id and from_address.zip_id.zipcode or '',
 
275
                            'from_zip4'     : from_address.zip or '',
 
276
                            'to_name'       : do.address_id.name ,
 
277
                            'to_firm'       : '',
 
278
                            'to_address1'   : do.address_id.street,
 
279
                            'to_address2'   : do.address_id.street2,
 
280
                            'to_city'       : do.address_id.city,
 
281
                            'to_state'      : do.address_id.state_id and do.address_id.state_id.code or '',
 
282
                            'to_zip5'       : do.address_id.zip_id and do.address_id.zip_id.zipcode or '',
 
283
                            'to_zip4'       : do.address_id.zip,
 
284
                            'weight'        : package.weight,
 
285
                            'service_type'  : do.usps_service_type,
 
286
                        }
 
287
                        request_url = url + '?API=DeliveryConfirmationV3&XML=' + request_xml
 
288
                    try :
 
289
                        import urllib
 
290
                        f = urllib.urlopen(request_url)
 
291
                        from xml.dom.minidom import parse, parseString
 
292
                        import xml2dic
 
293
                        
 
294
                        str_response = f.read()
 
295
                        xml_response =  parseString(str_response)
 
296
                        xml_dic = xml2dic.main(str_response)
 
297
                        
 
298
                        if  'Error' in xml_dic.keys():
 
299
                            error = True
 
300
                            for item in xml_dic.get('Error'):
 
301
                                
 
302
                                if item.get('Number'):
 
303
                                    if str_error:
 
304
                                        str_error = str_error+ "\n----------------------"
 
305
                                    str_error= str_error + "\nNumber : " + item['Number']
 
306
                                if item.get('Description'):
 
307
                                    str_error =  str_error + "\nDescription : " + item['Description']
 
308
 
 
309
                        else:
 
310
                            confirmation_number = xml_dic['DelivConfirmCertifyV3.0Response'][0]['DeliveryConfirmationNumber']
 
311
                            label_data = xml_dic['DelivConfirmCertifyV3.0Response'][1]['DeliveryConfirmationLabel']
 
312
                            #logo = binascii.b2a_base64(str(b64decode(label_data)))
 
313
                            #logo = str(b64decode(label_data))
 
314
                            
 
315
                            logo=base64.decodestring(label_data)
 
316
 
 
317
                            import os
 
318
                            import tempfile
 
319
                            dir_temp = tempfile.gettempdir()
 
320
                            
 
321
                            f = open(dir_temp + '/usps.tif', 'w+')
 
322
                            f.write(logo)
 
323
                            f.close()
 
324
                            label_image=''
 
325
 
 
326
                            cp=False
 
327
                            if os.name == 'posix' or 'nt':
 
328
                                try:
 
329
                                    os.system("tiffcp -c none "+ dir_temp  +"/usps.tif " + dir_temp +"/usps_temp.tif")
 
330
                                    cp=True
 
331
                                except Exception, e:
 
332
                                    str_error = "Please install tiffcp."
 
333
                            if cp:
 
334
                                im = Image.open(dir_temp + '/usps_temp.tif')
 
335
                                im.thumbnail(im.size)
 
336
                                im.save(dir_temp+'/usps_temp.jpg', "JPEG", quality=100)
 
337
                                label_from_file=open(dir_temp+'/usps_temp.jpg','rb')
 
338
                                label_image=base64.encodestring(label_from_file.read())
 
339
 
 
340
                                self.pool.get('stock.packages').write(cr, uid, [package.id], {'logo': label_image, 'tracking_no': confirmation_number, 'usps_confirmation_number': confirmation_number,'ship_message': 'Shipment has processed'})
 
341
                                
 
342
                    except Exception, e:
 
343
                        str_error = str(e)
 
344
            
 
345
                    cr.commit()
 
346
                    if str_error:
 
347
                        self.pool.get('stock.packages').write(cr, uid, do.id, {'ship_message': str_error}, context=context)
 
348
                                
 
349
        
 
350
                
 
351
        if not error:
 
352
            self.write(cr, uid, do.id, {'ship_state':'ready_pick','ship_message': 'Shipment has been processed.'}, context=context)
 
353
            return {
 
354
                'type': 'ir.actions.report.xml',
 
355
                'report_name':'multiple.label.print',
 
356
                'datas': {
 
357
                        'model':'stock.picking',
 
358
                        'id': ids and ids[0] or False,
 
359
                        'ids': ids and ids or [],
 
360
                        'report_type': 'pdf'
 
361
                    },
 
362
                'nodestroy': True
 
363
                }
 
364
        else:
 
365
            self.write(cr, uid, do.id, {'ship_message': 'Error occured on processing some of packages, for details please see the status packages.'}, context=context)
 
366
            #@todo: raise appropriate error msg
 
367
            raise osv.except_osv(_('Error'), _('%s' % ('No package lines are created for shippment process.')))
 
368
                
 
369
        return True
 
370
    
 
371
    def process_void(self,cr, uid, ids, context=None):
 
372
 
 
373
        do = self.browse(cr, uid, type(ids)==type([]) and ids[0] or ids, context=context)
 
374
        if do.ship_company_code != 'usps':
 
375
            return super(stock_picking, self).process_void(cr, uid, ids, context=context)
 
376
 
 
377
        if not (do.logis_company and do.logis_company.ship_company_code=='usps'):
 
378
            return super(stock_picking, self).process_void(cr, uid, ids, context=context)
 
379
        
 
380
        userid = do.logis_company.usps_userid
 
381
        url = do.logis_company.test_mode and do.logis_company.usps_url_secure_test or do.logis_company.usps_url_secure
 
382
        url_prd =  do.logis_company.usps_url
 
383
        url_prd_secure =  do.logis_company.usps_url_secure
 
384
        test=do.logis_company.test_mode
 
385
 
 
386
        error = False
 
387
        str_error = '' 
 
388
        
 
389
        for pack in do.packages_ids:
 
390
            if pack.tracking_no:
 
391
                url = test and do.logis_company.usps_url_secure_test or do.logis_company.usps_url_secure
 
392
                url_sec = test and do.logis_company.usps_url_secure_test or do.logis_company.usps_url_secure
 
393
                if test:
 
394
                    request_xml = """<CarrierPickupCancelRequest USERID="%(user_id)s">
 
395
                        <FirmName>ABC Corp.</FirmName>
 
396
                        <SuiteOrApt>Suite 777</SuiteOrApt>
 
397
                        <Address2>1390 Market Street</Address2>
 
398
                        <Urbanization></Urbanization>
 
399
                        <City>Houston</City>
 
400
                        <State>TX</State>
 
401
                        <ZIP5>77058</ZIP5>
 
402
                        <ZIP4>1234</ZIP4>
 
403
                        <ConfirmationNumber>WTC123456789</ConfirmationNumber>
 
404
                        </CarrierPickupCancelRequest>
 
405
                        """%{'user_id': do.logis_company.usps_userid}
 
406
                else:
 
407
                    request_xml = """<CarrierPickupCancelRequest USERID="%(user_id)">
 
408
                        <FirmName>ABC Corp.</FirmName>
 
409
                        <SuiteOrApt>Suite 777</SuiteOrApt>
 
410
                        <Address2>1390 Market Street</Address2>
 
411
                        <Urbanization></Urbanization>
 
412
                        <City>Houston</City>
 
413
                        <State>TX</State>
 
414
                        <ZIP5>77058</ZIP5>
 
415
                        <ZIP4>1234</ZIP4>
 
416
                        <ConfirmationNumber>%(confirmation_number)</ConfirmationNumber>
 
417
                        </CarrierPickupCancelRequest>
 
418
                        """%{
 
419
                                'user_id': do.logis_company.usps_userid,
 
420
                                'confirmation_number' : pack.tracking_no,
 
421
                             }
 
422
                request_url = url + '?API=CarrierPickupCancel&XML=' + request_xml
 
423
                try :
 
424
                    import urllib
 
425
                    f = urllib.urlopen(request_url)
 
426
                    from xml.dom.minidom import parse, parseString
 
427
                    import xml2dic
 
428
                
 
429
                    str_response = f.read()
 
430
                except Exception:
 
431
                    self.pool.get('stock.packages').write(cr, uid, pack.id, {'ship_message': str(Exception)}, context=context)
 
432
                    
 
433
                    print "Shipment Cancel response :", str_response
 
434
                    
 
435
                xml_response =  parseString(str_response)
 
436
                xml_dic = xml2dic.main(str_response)
 
437
                
 
438
                if  'Error' in xml_dic.keys():
 
439
                    error = True
 
440
                    for item in xml_dic.get('Error'):
 
441
                        self.pool.get('stock.packages').write(cr, uid, pack.id, {'ship_message': str_error}, context=context)
 
442
                        break
 
443
                else:
 
444
                    self.pool.get('stock.packages').write(cr, uid, pack.id, {      
 
445
                                                                           'negotiated_rates' : 0.00,
 
446
                                                                           'shipment_identific_no' :'',
 
447
                                                                           'tracking_no': '',
 
448
                                                                           'tracking_url': '',
 
449
                                                                           'logo' : '',
 
450
                                                                           'ship_message' : 'Shipment Cancelled'}, context=context)
 
451
 
 
452
        if not error:
 
453
            self.write(cr, uid, do.id, {'ship_state'    :'draft', 'ship_message' : 'Shipment has been cancelled.'}, context=context)
 
454
        else :
 
455
            self.write(cr, uid, do.id, { 'ship_message'  : 'Cancellation of some of shipment has failed, please check the status of pakages.'}, context=context)
 
456
        return True
 
457
stock_picking()
 
458
 
 
459