예제 #1
0
 def setUp(self):
     self.api = endicia.Endicia(EndiciaTestConfig, debug=True)
     self.shipper = Address('Adobe',
                            "345 Park Avenue",
                            'San Jose',
                            'CA',
                            95110,
                            'US',
                            phone='5122901212',
                            email='*****@*****.**')
     self.recipient = Address('Apple',
                              "1 Infinite Loop",
                              'Cupertino',
                              'CA',
                              95014,
                              'US',
                              phone='5122901212',
                              email='*****@*****.**')
     self.intl_recipient = Address('Apple Canada',
                                   "7495 Birchmount Road",
                                   'Markham',
                                   'ON',
                                   "L3R 5G2",
                                   'CA',
                                   phone='9055135800',
                                   email='*****@*****.**')
     self.package = endicia.Package(endicia.Package.shipment_types[0], 3,
                                    endicia.Package.shapes[1], 10, 10, 10)
예제 #2
0
파일: test.py 프로젝트: skwaugh/python-ship
def TestEndiciaLabel():
    package = endicia.Package(endicia.Package.shipment_types[0], 20, endicia.Package.shapes[1], 10, 10, 10)
    package_intl = endicia.Package(endicia.Package.international_shipment_types[0], 20, endicia.Package.shapes[3], 10, 10, 10)
    customs = [ endicia.Customs('hello', 1, 2, 100, 'Bermuda'), endicia.Customs('Thingy', 10, 16, 80, 'Bahamas') ]
    
    debug = True
    req0 = endicia.LabelRequest(EndiciaPartnerID, EndiciaAccountID, EndiciaPassphrase, package_intl, shipper, recipient_intl, contents_type='Merchandise', customs_info=customs, debug=debug)
    req1 = endicia.LabelRequest(EndiciaPartnerID, EndiciaAccountID, EndiciaPassphrase, package, shipper, recipient, debug=debug)
    req2 = endicia.LabelRequest(EndiciaPartnerID, EndiciaAccountID, EndiciaPassphrase, package, shipper, recipient, stealth=False, debug=debug)
    req3 = endicia.LabelRequest(EndiciaPartnerID, EndiciaAccountID, EndiciaPassphrase, package, shipper, recipient, insurance='ENDICIA', insurance_amount=1.0, debug=debug)
    req4 = endicia.LabelRequest(EndiciaPartnerID, EndiciaAccountID, EndiciaPassphrase, package, shipper, recipient, customs_form='Form2976A', customs_info=customs, contents_type='Merchandise', debug=debug)

    for request in [ req0, req1, req2, req3, req4 ]:
        response = request.send()
    
        print response
        if not isinstance(response, endicia.Error):
            _show_file(extension='.png', data=response.label)
    
    return response
예제 #3
0
 def testIntlLabel(self):
     package_intl = endicia.Package(
         endicia.Package.international_shipment_types[0], 20,
         endicia.Package.shapes[3], 10, 10, 10)
     customs = [
         endicia.Customs('Thing 1', 1, 2, 100, 'United States'),
         endicia.Customs('Thing 2', 10, 16, 80, 'Canada')
     ]
     label = self.api.label(
         package_intl,
         self.shipper,
         self.intl_recipient,
         contents_type='Merchandise',
         customs_info=customs,
         image_format="GIF"  # Only GIF is valid for international labels.
     )
     self.assertFalse(isinstance(label, endicia.Error), msg=label.message)
예제 #4
0
    def generate_usps_tracking_no(self, picking, error=False):
        '''
        This function is used to Generated USPS Shipping Label in Delivery order
        parameters: 
            picking : (int) stock picking ID,(delivery order ID)
        '''
        sale_id = self.env['sale.order'].search([('name', '=', picking.origin)
                                                 ])
        context = dict(self._context or {})
        if not self.env['shipping.usps'].search([('active', '=', True)]):
            raise osv.except_osv(_('Error'),
                                 _('Default Endicia settings not defined'))
        ship_endicia = self.env['shipping.usps'].search([('active', '=', True)
                                                         ])
        context['usps_active'] = False
        #Endicia Quotes Selected
        stockpicking_obj = self.env['stock.picking']
        if picking.service_type_usps.find('First') != -1:
            mail_class = 'First'
        elif picking.service_type_usps.find('Express') != -1:
            mail_class = 'Express'
        else:
            mail_class = picking.service_type_usps

        cust_address = ship_endicia.config_shipping_address_id
        shipper = Address(
            cust_address.name or '', cust_address.street, cust_address.street2
            or '', cust_address.city, cust_address.state_id.code or '',
            cust_address.zip, cust_address.country_id.code, cust_address.phone
            or '', cust_address.email,
            (cust_address.name != cust_address.name) and cust_address.name
            or '')
        cust_address = picking.partner_id
        receipient = Address(
            cust_address.name or '', cust_address.street
            and cust_address.street.rstrip(','), cust_address.street2 and
            (cust_address.street != cust_address.street2)
            and cust_address.street2.rstrip(',') or '', cust_address.city
            and cust_address.city.rstrip(','), cust_address.state_id.code
            or '', cust_address.zip, cust_address.country_id.code,
            cust_address.phone or '', cust_address.email,
            (cust_address.name != cust_address.name) and cust_address.name
            or '')
        international_label = False
        if receipient.country_code.lower(
        ) != 'us' and receipient.country_code.lower(
        ) != 'usa' and receipient.country_code.lower() != 'pr':
            international_label = True
            if picking.service_type_usps.find('First') != -1:
                mail_class = 'FirstClassMailInternational'
            elif picking.service_type_usps.find('Express') != -1:
                mail_class = 'ExpressMailInternational'
            elif picking.service_type_usps.find('Priority') != -1:
                mail_class = 'PriorityMailInternational'
        package = endicia.Package(
            mail_class,
            int(
                round(picking.weight_package * 10 >= 1.0
                      and picking.weight_package * 10
                      or 1.0)), endicia.Package.shapes[picking.container_usps],
            picking.length_package, picking.width_package,
            picking.height_package, picking.name, sale_id.amount_total)
        customs = []
        if international_label:
            for move_line in picking.move_lines:
                weight_net = move_line.product_id.product_tmpl_id.weight_net * 16 >= 1.0 and move_line.product_id.product_tmpl_id.weight_net * 16 * move_line.product_qty or 1.0
                customs.append(
                    endicia.Customs(
                        move_line.product_id.default_code + '-' +
                        move_line.product_id.name, int(move_line.product_qty),
                        int(round(weight_net)),
                        move_line.price_unit > 0.00 and move_line.price_unit
                        or 39.00, shipper.country_code))

        reference = ''
        reference2 = ''
        for move_line in picking.move_lines:
            reference += ' (' + str(int(move_line.product_qty)) + ')'
            if move_line.product_id.default_code:
                reference += str(move_line.product_id.default_code) + '+'

        reference = reference[:-1]
        reference = reference[20:]
        reference2 += ' ' + ship_endicia.config_shipping_address_id.name

        #        try:

        include_postage = picking.include_postage_usps
        if picking.service_type_usps.find(
                'International'
        ) != -1 or picking.container_usps == 'Letter' != -1:
            image_rotation = 'Rotate90'
        else:
            image_rotation = ship_endicia.image_rotation

        request = endicia.LabelRequest(
            ship_endicia.requester_id,
            ship_endicia.account_id,
            ship_endicia.passphrase,
            ship_endicia.label_type
            if not international_label else 'International',
            ship_endicia.label_size,
            ship_endicia.image_format,
            image_rotation,
            package,
            shipper,
            receipient,
            reference,
            reference2,
            include_postage,
            debug=ship_endicia.test,
            destination_confirm=True
            if picking.service_type_usps == 'First Class'
            and picking.container_usps == 'Letter' else False,
            customs_info=customs)
        response = request.send()
        if isinstance(response, (str)):
            log_data = picking.write({
                'error_for_faulty': str(response),
                'is_faulty_deliv_order': True
            })
            return True
        endicia_res = response._get_value()
        im_barcode = cStringIO.StringIO(
            endicia_res['label'])  # constructs a StringIO holding the image
        img_barcode = Image.open(im_barcode)
        output = StringIO.StringIO()
        img_barcode.save(output, format='PNG')
        data = binascii.b2a_base64(output.getvalue())
        f = open('/tmp/test.png', 'wb')
        f.write(output.getvalue())
        f.close()
        c = canvas.Canvas("/tmp/picking_list.pdf")
        c.setPageSize((400, 650))
        c.drawImage('/tmp/test.png', 10, 10, 380, 630)
        c.save()
        f = open('/tmp/picking_list.pdf', 'rb')

        attachment_pool = self.env['ir.attachment']
        data_attach = {
            'name': 'PackingList.pdf',
            'datas': base64.b64encode(f.read()),
            'description': 'Packing List',
            'res_name': picking.name,
            'res_model': 'stock.picking',
            'res_id': picking.id,
        }
        attach_id = attachment_pool.search([('res_id', '=', picking.id),
                                            ('res_name', '=', picking.name)])
        if not attach_id:
            attach_id = attachment_pool.create(data_attach)
            os.remove('/tmp/test.png')
            os.remove('/tmp/picking_list.pdf')
        else:
            attach_result = attachment_pool.write(cr, uid, attach_id,
                                                  data_attach)
            attach_id = attach_id[0]
        context['attach_id'] = attach_id

        if endicia_res['tracking']:
            carrier_id = self.env['delivery.carrier'].search([
                ('service_code', '=', picking.service_type_usps),
                ('container_usps', '=', picking.container_usps)
            ])
            if len(carrier_id):
                carrier_id = carrier_id[0]
                cost = endicia_res['cost']
            else:
                carrier_id = False
                cost = False
            vals = {
                'carrier_tracking_ref': endicia_res['tracking'],
                'carrier_id': carrier_id.id,
                'shipping_rate': cost
            }
            picking.write(vals)
            context['track_success'] = True
            context['tracking_no'] = endicia_res['tracking']
        return True
예제 #5
0
    def endicia_send_shipping(self, pickings):
        res = []
        for picking in pickings:
            # Sender
            international_label = False
            shipper_address = picking.company_id.partner_id
            if not shipper_address.name:
                raise ValidationError(_("You must enter Shipper Name."))
            if not (shipper_address.street or shipper_address.street2):
                raise ValidationError(_("You must enter Shipper Street."))
            if not shipper_address.city:
                raise ValidationError(_("You must enter Shipper City."))
            if not shipper_address.state_id:
                raise ValidationError(_("You must enter Shipper State."))
            if not shipper_address.state_id.code:
                raise ValidationError(_("You must enter Shipper State Code."))
            if not shipper_address.zip:
                raise ValidationError(_("You must enter Shipper Zip."))
            if not shipper_address.country_id.code:
                raise ValidationError(_("You must enter Shipper Country."))
            if not shipper_address.email:
                raise ValidationError(_("You must enter Shipper email."))

            # added handling because endicia api support zip5 format.
            if str(shipper_address.zip).find("-") != -1:
                zip_code = str(shipper_address.zip).split("-")[0]
            else:
                zip_code = str(shipper_address.zip)
            shipper = endicia.Address(shipper_address.name,
                            shipper_address.street or shipper_address.street2,
                            shipper_address.city,
                            shipper_address.state_id and shipper_address.state_id.code or '',
                            zip_code,
                            shipper_address.country_id.code,
                            shipper_address.street and shipper_address.street2 or '',
                            shipper_address.phone or '',
                            shipper_address.email,
                            True,
#                            shipper_address.name
                          )
            # Recipient
            cust_address = picking.partner_id
            if not cust_address.name:
                raise ValidationError(_("You must enter Recipient Name."))
            if not (cust_address.street or cust_address.street2):
                raise ValidationError(_("You must enter Recipient Street."))
            if not cust_address.city:
                raise ValidationError(_("You must enter Recipient City."))
            if not cust_address.state_id:
                raise ValidationError(_("You must enter Recipient State."))
            if not cust_address.state_id.code:
                raise ValidationError(_("You must enter Recipient State Code."))
            if not cust_address.zip:
                raise ValidationError(_("You must enter Recipient Zip."))
            if not cust_address.country_id.code:
                raise ValidationError(_("You must enter Recipient Country."))

            # added handling because usps api support zip5 format.
            if str(cust_address.zip).find("-") != -1:
                zip_code = str(cust_address.zip).split("-")[0]
            else:
                zip_code = str(cust_address.zip)
            recipient = endicia.Address(cust_address.name or '',
                            cust_address.street or cust_address.street2,
                            cust_address.city,
                            cust_address.state_id and cust_address.state_id.code or '',
                            zip_code,
                            cust_address.country_id and cust_address.country_id.code,
                            cust_address.street and cust_address.street2 or '',
                            cust_address.phone or '',
                            cust_address.email, ''
                        )
            package_value = picking.sale_id.amount_total
            prod_weight = 0.0
            weight = self._convert_weight(picking.weight_bulk*0.453592, self.endicia_weight_unit) #weight reversed back to kg since client decides put all product weights in pounds
            if self.endicia_weight_unit == 'LB':
                prod_weight = weight * 16
            elif self.endicia_weight_unit == 'KG':
                prod_weight = weight * 35.274
            elif self.endicia_weight_unit == 'OUNCE':
                prod_weight = weight
            else:
                prod_weight = weight
            package = endicia.Package(self.endicia_service_type,
                                      round(prod_weight or 1.0),
                                      endicia.Package.shapes[self.endicia_container],
                                      self.endicia_length,
                                      self.endicia_width,
                                      self.endicia_height,
                                      picking.name,
                                      package_value
                                      )
            if recipient.country.lower() != 'us' and recipient.country.lower() != 'usa' and recipient.country.lower() != 'pr':
                if self.endicia_service_type not in ['FirstClassMailInternational', 'Priority Mail International']:
                    raise ValidationError("Please select carrier First Class Mail or Priority Mail International for international delivery")
                # (self, mail_class, weight_in_ozs, shape, length, width, height,
                #  description = '', value = 0, require_signature = False,
                #                                                   reference = u'')
                package = endicia.Package(self.endicia_service_type,
                                          int(round(prod_weight or 1.0)),
                                          endicia.Package.shapes[self.endicia_container],
                                          self.endicia_length,
                                          self.endicia_width,
                                          self.endicia_height,
                                          picking.name,
                                          package_value
                                          )
                international_label = True
            customs = []
            if international_label or self.endicia_label_type == 'Domestic':
                for move in picking.move_lines:
                    # if not move.product_id.bom_ids:
                    prod_weight = 0
                    prod_weight_unit = move.product_id.uom_po_id and move.product_id.uom_po_id.name or ''
                    weight_net = move.product_id.weight * move.product_qty or 0.1
                    if prod_weight_unit == 'LB':
                        prod_weight = weight_net * 16
                    elif prod_weight_unit == 'KG':
                        prod_weight = weight_net * 35.274
                    elif prod_weight_unit == 'OUNCE':
                        prod_weight = weight_net
                    else:
                        prod_weight = weight_net
                    custom_value = move.product_id.list_price or 1.0
                    customs.append(endicia.Customs(move.product_id.name,
                                                   int(move.product_qty),
                                                   float(prod_weight) or 1.0,
                                                   float(custom_value * move.product_qty) or 1.0,
                                                   shipper_address.country_id.code
                                                   ))
                    # elif prod_info.get('subproducts', False):
                    #     for component in prod_info.get('subproducts', False):
                    #         prod_brw = product_obj.browse(cr, uid, component.get('product_id', False))
                    #         prod_weight_unit = prod_brw.weight_unit
                    #         weight_net = prod_brw.product_tmpl_id.weight and prod_brw.product_tmpl_id.weight * int(
                    #             component['product_qty'] or 0) or 0.1
                    #         if prod_weight_unit and prod_weight_unit == 'LB':
                    #             prod_weight = weight_net * 16
                    #         elif prod_weight_unit and prod_weight_unit == 'KG':
                    #             prod_weight = weight_net * 35.274
                    #         elif prod_weight_unit and prod_weight_unit == 'OUNCE':
                    #             prod_weight = weight_net
                    #         else:
                    #             prod_weight = weight_net
                    #         custome_value = float(prod_brw.list_price) or 1.0
                    #         comp_qty = component.get('product_qty', 1) * move_line.product_qty
                    #         customs.append(endicia.Customs(str(component['name']),
                    #                                        int(comp_qty or 1),
                    #                                        float(prod_weight * comp_qty) or 1.0,
                    #                                        float(custome_value * comp_qty) or 1.0,
                    #                                        shipper_address.country_id.code
                    #                                        ))
            if self.endicia_label_type == 'DestinationConfirm' and not (
                self.endicia_container in ['Flat', 'Letter'] and package.mail_class in ['First',
                                                                                     'FirstClassMailInternational',
                                                                                     'PriorityMailInternational',
                                                                                     'Priority Mail Express International']):
                raise ValidationError('Container should be "Flat or Letter" and Shipping Service should be \
                "First-Class Mail", "First Class Mail International","Priority Mail International","Priority Mail \
                Express International" for Label Type "Destination Confirm"!')
            if self.endicia_label_type == 'CertifiedMail' and not (
                    self.endicia_container in ['Flat', 'Letter', 'Parcel'] and package.mail_class in [
                'First', 'Priority', 'FirstClassMailInternational', 'PriorityMailInternational',
                'Priority Mail Express International']):
                raise ValidationError('Container should be "Flat or Letter or Parcel" and supported Shipping'
                      ' Service are "First-Class Mail","Priority Mail","Priority Mail International","Priority Mail\
                       Express International","First Class Mail International" for Label Type "Certified Mail"!')
            # sending request to endicia for label
            request = endicia.LabelRequest(self.endicia_requester_id,
                                           self.endicia_account_id,
                                           self.endicia_passphrase,
                                           self.endicia_label_type,
                                           self.endicia_label_size,
                                           self.endicia_image_format,
                                           self.endicia_image_rotation,
                                           package, shipper, recipient,
                                           debug=self.endicia_test_mode,
                                           destination_confirm=True if self.endicia_service_type == 'First-Class Mail' and self.endicia_container == 'Letter' else False,
                                           customs_info=customs)
            response = request.send()
            endicia_res = response._get_value()
            ## creating attachment for label
            # label_name = 'ShippingLabel' + picking.name + '.' + self.endicia_image_format
            carrier_tracking_ref = endicia_res.get('tracking', False)
            carrier_price = float(endicia_res.get('cost',0))
            logmessage = (_("Shipment created into Endicia <br/> <b>Tracking Number : </b>%s") % (carrier_tracking_ref))
            picking.message_post(body=logmessage,
                                 attachments=[('LabelEndicia-%s.%s' % (carrier_tracking_ref, self.endicia_image_format), str(endicia_res['label']))])
            shipping_data = {
                'exact_price': carrier_price,
                'tracking_number': carrier_tracking_ref
            }
            res = res + [shipping_data]
        return res
예제 #6
0
    def endicia_get_shipping_price_from_so(self, orders):
        res = []
        for order in orders:
            if not order.order_line:
                raise ValidationError(_("Please provide at least one item to ship."))
            if order.order_line.filtered(
                    lambda line: not line.product_id.weight and not line.is_delivery and not line.product_id.type in [
                        'service', 'digital']):
                raise ValidationError(
                    _('The estimated price cannot be computed because the weight of your product is missing.'))
            # assume the weight in KG
            weight = sum([(line.product_id.weight * line.product_qty) for line in order.order_line])* 0.453592 #weight reversed back to kg since client decides put all product weights in pounds
            weight = self._convert_weight(weight, self.endicia_weight_unit)
            # weight_unit = saleorder.weight_unit
            if not weight:
                raise ValidationError(_('Package Weight Invalid!'))
            # added handling for maximum weight limitation.
            if self.endicia_weight_unit == 'KG' and weight > 31.75147:
                raise ValidationError(_('Package Weight should not exceed 31.75 kg!'))
            if self.endicia_weight_unit == 'LB' and weight > 70:
                raise ValidationError(_('Package Weight should not exceed 70 lb!'))
            if self.endicia_weight_unit == 'OUNCE' and weight > 1120:
                raise ValidationError(_('Package Weight should not exceed 1120 ounce!'))
            # added for weight conversion
            # Convert weight to ounce before creating package
            #1kg = 35.274 Ounce
            if self.endicia_weight_unit == 'KG':
                weight *= 35.274
            #1lb = 16 Ounce
            if self.endicia_weight_unit == 'LB':
                weight *= 16

            ### Sender
            shipper = order.company_id.partner_id
            if not shipper:
                raise ValidationError(_('Shop Address not defined!'))
            if str(shipper.zip).find("-") != -1:
                zip_code = str(shipper.zip).split("-")[0]
            else:
                zip_code = str(shipper.zip)
            shipper = endicia.Address(
                                    shipper.name,
                                    shipper.street,
                                    shipper.city,
                                    shipper.state_id and shipper.state_id.code,
                                    zip_code,
                                    shipper.country_id and shipper.country_id.code,
                                    shipper.street2,
                                    shipper.phone,
                                    shipper.email,
                                    shipper.name
                            )
            ### Recipient
            recipient = order.partner_shipping_id
            if str(recipient.zip).find("-") != -1:
                zip_code = str(recipient.zip).split("-")[0]
            else:
                zip_code = str(recipient.zip)
            recipient = endicia.Address(recipient.name,
                        recipient.street and recipient.street.rstrip(','),
                        recipient.city and recipient.city.rstrip(','),
                        recipient.state_id and recipient.state_id.code,
                        zip_code,
                        recipient.country_id and recipient.country_id.code,
                        recipient.street2 and (recipient.street != recipient.street2) and recipient.street2.rstrip(','),
                        recipient.phone or '',
                        recipient.email,
                        recipient.name or '')
            credentials = {
                            'partner_id': self.endicia_requester_id,
                            'account_id': self.endicia_account_id,
                            'passphrase': self.endicia_passphrase
                           }
            en = endicia.Endicia(credentials, self.endicia_test_mode)
            #creating packages
            packages = [endicia.Package(self.endicia_service_type,
                                        round(weight, 1),
                                        endicia.Package.shapes[self.endicia_container],
                                        self.endicia_length,
                                        self.endicia_width,
                                        self.endicia_height,
                                        value=1000)
                        ]
            response = en.rate(packages, endicia.Package.shapes[self.endicia_container], shipper, recipient)
            if response['status'] == 0:
                for resp in response["info"]:
                    if resp['service'] == self.endicia_service_type:
                        res += [resp['cost']]
        return res or [0]