Esempio n. 1
0
class TestOrder(BaseOrderTestCase):
    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testOrderInUniqueShop(self):
        # test posOrder items in unique shop.
        # order: shop:1
        #        barcode:11111, barcode:11112 for sale:1
        #        barcode:22221, barcode:22222 for sale:2
        upc_shop = '11111'
        posOrder = [('11111', 1, 0),
                    ('11112', 2, 0),
                    ('22221', 3, 0),
                    ('22222', 4, 0)]
        self.success_posOrder(self.telephone, upc_shop, posOrder)

        # test wwwOrder items in unique shop.
        # order:
        wwwOrder = [
            {'id_sale': 1000001,
             'id_variant': 1000001,
             'quantity': 5,
             'id_shop': 1000001,
             'id_type': 0,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000001,
             'id_variant': 1000002,
             'quantity': 6,
             'id_shop': 1000001,
             'id_type': 0,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000002,
             'id_variant': 1000003,
             'quantity': 7,
             'id_shop': 1000001,
             'id_type': 0,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000002,
             'id_variant': 1000004,
             'quantity': 8,
             'id_shop': 1000001,
             'id_type': 0,
             'id_price_type': 0,
             'id_weight_type': 0}
        ]
        self.success_wwwOrder(self.telephone,
                              self.shipaddr,
                              self.billaddr,
                              wwwOrder)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def __testOrderInDiffShopSameBrand(self):
        # test posOrder items in shop 1, brand 1.
        # order: shop:1,
        #        barcode:11111, barcode:11112 for sale:1
        upc_shop = '11111'
        posOrder = [('11111', 1, 0),
                    ('11112', 2, 0)]
        self.success_posOrder(self.telephone,
                              upc_shop,
                              posOrder)

        # test posOrder items in shop 2, brand 1.
        #        shop:2,
        #        barcode:33331, barcode:33332 for sale:3
        upc_shop = '22222'
        posOrder = [('33331', 3, 0),
                    ('33332', 4, 0)]
        self.success_posOrder(self.telephone,
                              upc_shop,
                              posOrder)

        # test wwwOrder items in unique shop.
        # order:
        wwwOrder = [
            {'id_sale': 1000001,
             'id_variant': 1000001,
             'quantity': 5,
             'id_shop': 1000001,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000001,
             'id_variant': 1000002,
             'quantity': 6,
             'id_shop': 1000001,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000003,
             'id_variant': 1000005,
             'quantity': 7,
             'id_shop': 1000002,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000003,
             'id_variant': 1000006,
             'quantity': 8,
             'id_shop': 1000002,
             'id_price_type': 0,
             'id_weight_type': 0}
        ]
        self.success_wwwOrder(self.telephone,
                              self.shipaddr,
                              self.billaddr,
                              wwwOrder)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def __testOrderInDiffShopDiffBrand(self):
        # test posOrder items in shop 1, brand 1.
        # order: shop:1,
        #        barcode:11111, barcode:11112 for sale:1
        upc_shop = '11111'
        posOrder = [('11111', 1, 0),
                    ('11112', 2, 0)]
        self.success_posOrder(self.telephone, upc_shop, posOrder)

        # test posOrder items in shop 3, brand 2.
        #        shop:3,
        #        barcode:44441, barcode:44442 for sale:4
        upc_shop = '33333'
        posOrder = [('44441', 3, 0),
                    ('44442', 4, 0)]
        self.success_posOrder(self.telephone, upc_shop, posOrder)

        # test wwwOrder items in unique shop.
        # order:
        wwwOrder = [
            {'id_sale': 1000001,
             'id_variant': 1000001,
             'quantity': 5,
             'id_shop': 1000001,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000001,
             'id_variant': 1000002,
             'quantity': 6,
             'id_shop': 1000001,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000004,
             'id_variant': 1000007,
             'quantity': 7,
             'id_shop': 1000003,
             'id_price_type': 0,
             'id_weight_type': 0},
            {'id_sale': 1000004,
             'id_variant': 1000008,
             'quantity': 8,
             'id_shop': 1000003,
             'id_price_type': 0,
             'id_weight_type': 0}
        ]
        self.success_wwwOrder(self.telephone,
                              self.shipaddr,
                              self.billaddr,
                              wwwOrder)
Esempio n. 2
0
class TestInvoice(BaseOrderTestCase):
    ''' Shop address are configured to US - AL in backoffice
    for shop 1000002
    '''
    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testDiffCountry(self):

        # update user address to China BJ
        self.b.update_account_address(self.users_id, "CN", "BJ", "BeiJing")

        qty = 2
        item = {
            'id_sale': 1000031,
            'id_variant': 1000012,
            'quantity': qty,
            'id_shop': 1000002,
            'id_type': 1000003,
            'id_price_type': 1000003,
            'id_weight_type': 1000003
        }

        # conf data in backtoshops
        type_attr_price = 3 * (1 + 0.02)  # + premium
        weight = 2
        shipping_fee = 2.0 * weight * qty
        handling_fee = 6.0
        tax1 = 3 / 100.0
        tax2 = 4 / 100.0
        expect_amount = (type_attr_price * qty + handling_fee + shipping_fee +
                         (to_round(type_attr_price *
                                   (1 + tax1)) - type_attr_price) * qty +
                         (to_round(type_attr_price *
                                   (1 + tax2)) - type_attr_price) * qty)

        wwwOrder = [item]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        id_shp = self._shipmentsCountCheck(id_order, 1)[0]
        self._shipping_conf(id_shp)

        self.b.post_invoices(id_order)
        self.expect_one_item_result(id_order, expect_amount)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testDiffProvince(self):
        # update user address to US AK
        self.b.update_account_address(self.users_id, "US", "AK", "Alaska")

        qty = 2
        item = {
            'id_sale': 1000031,
            'id_variant': 1000012,
            'quantity': qty,
            'id_shop': 1000002,
            'id_type': 1000003,
            'id_price_type': 1000003,
            'id_weight_type': 1000003
        }

        # conf data in backoffice
        type_attr_price = 3 * (1 + 0.02)  # + premium
        weight = 2
        shipping_fee = 2.0 * weight * qty
        handling_fee = 6.0
        tax1 = 1 / 100.0
        tax2 = 2 / 100.0

        t1_amount = (to_round(type_attr_price *
                              (1 + tax1)) - type_attr_price) * qty
        after_amount = to_round(type_attr_price * (1 + tax1))
        t2_amount = (to_round(after_amount * (1 + tax2)) - after_amount) * qty
        expect_amount = (type_attr_price * qty + handling_fee + shipping_fee +
                         t1_amount + t2_amount)

        wwwOrder = [item]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)

        id_shp = self._shipmentsCountCheck(id_order, 1)[0]
        self._shipping_conf(id_shp)

        self.b.post_invoices(id_order)
        self.expect_one_item_result(id_order, expect_amount)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testSameProvince(self):
        # update user address to US AK
        self.b.update_account_address(self.users_id, "US", "AL", "ALABAMA")

        qty = 2
        item = {
            'id_sale': 1000031,
            'id_variant': 1000012,
            'quantity': qty,
            'id_shop': 1000002,
            'id_type': 1000003,
            'id_price_type': 1000003,
            'id_weight_type': 1000003
        }

        # conf data in backoffice
        type_attr_price = 3 * (1 + 0.02)  # + premium
        weight = 2
        shipping_fee = 2.0 * weight * qty
        handling_fee = 6.0
        tax1 = 1 / 100.0
        tax2 = 0.5 / 100.0
        tax3 = 1 / 100.0  # taxable
        expect_amount = (type_attr_price * qty + handling_fee + shipping_fee +
                         (to_round(type_attr_price *
                                   (1 + tax1)) - type_attr_price) * qty +
                         (to_round(type_attr_price *
                                   (1 + tax2)) - type_attr_price) * qty +
                         (to_round(type_attr_price *
                                   (1 + tax3)) - type_attr_price) * qty +
                         to_round((handling_fee + shipping_fee) *
                                  (1 + tax3)) - (handling_fee + shipping_fee))

        wwwOrder = [item]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        id_shp = self._shipmentsCountCheck(id_order, 1)[0]
        self._shipping_conf(id_shp)

        self.b.post_invoices(id_order)
        self.expect_one_item_result(id_order, expect_amount)

    def expect_one_item_result(self, id_order, exp_amount_due):
        sql = """SELECT amount_due
                   FROM invoices
                  WHERE id_order = %s
        """
        with db_utils.get_conn() as conn:
            amount_due = db_utils.query(conn, sql, (id_order, ))
            self.assertEqual(
                len(amount_due), 1,
                "There should have one invoice record for order %s" % id_order)
            amount_due = amount_due[0][0]
            self.assertAlmostEqual(
                float(amount_due),
                float(exp_amount_due),
                msg="order(%s) amount_due %s is not same with expected: %s" %
                (id_order, amount_due, exp_amount_due))

    def _shipping_conf(self, id_shipment=None):
        id_carrier = 1
        id_service = 1
        params = {
            'shipment': id_shipment,
            'carrier': id_carrier,
            'service': id_service
        }
        url = "webservice/1.0/pub/shipping/conf"
        resp = self.b._access(url, params)
        return ujson.loads(resp.get_data())
Esempio n. 3
0
class TestCoupon(BaseTestCase):
    def setUp(self):
        super(TestCoupon, self).setUp()
        self.id_brand = 1000001
        self.bo_user = 1000002
        self.id_coupon = None
        with db_utils.get_conn() as conn:
            db_utils.update(conn, "coupons", values={'valid': False})

    def tearDown(self):
        if self.id_coupon:
            # delete coupon
            self._post_coupon({
                'action': 'delete',
                'id_coupon': self.id_coupon,
            })
        super(TestCoupon, self).tearDown()

    def _list_coupons(self, params=None):
        query = {
            'id_brand': self.id_brand,
            'debugging': 'true',
        }
        if params:
            query.update(params)
        url = "webservice/1.0/private/coupon/list?%s" % urllib.urlencode(query)
        resp = self.b._access(url)
        data = xmltodict.parse(resp.get_data())
        if not data.get('coupons', {}).get('coupon'):
            return []
        elif isinstance(data.get('coupons', {}).get('coupon'), list):
            return data['coupons']['coupon']
        else:
            return [data['coupons']['coupon']]

    def _post_coupon(self, values):
        values.update({
            'id_issuer': self.id_brand,
            'debugging': 'true',
        })
        resp = self.b._access("webservice/1.0/private/coupon", values)
        data = xmltodict.parse(resp.get_data())
        id_coupon = data.get('coupons', {}).get('coupon', {}).get('@id')
        self.assert_(isinstance(id_coupon, basestring) and id_coupon.isdigit())
        return id_coupon

    @unittest.skipUnless(not is_backoffice_server_running(), SKIP_REASON)
    def test_sale_discount_coupon(self):
        id_sale = 1000001
        today = str(datetime.now().date())
        coupon_values = {
            'author': self.bo_user,
            'reward_type': 'COUPON_DISCOUNT',
            'discount_applies_to': 'VALUE_MATCHING',
            'discount': 5,
            'require': ujson.dumps({"invoice_match": {
                "sale": [id_sale]
            }}),
            'effective_time': today,
            'expiration_time': today,
        }

        # check coupon list before create new coupon
        coupons_data = self._list_coupons(params={'id_item': id_sale})
        num = len(coupons_data)

        # create new coupon
        coupon_values.update({'action': 'create'})
        self.id_coupon = self._post_coupon(coupon_values)
        coupons_data = self._list_coupons(params={'id_item': id_sale})
        self.assertEquals(len(coupons_data), num + 1)
        self.assertEquals(
            xmltodict.unparse(OrderedDict([(u'coupon', coupons_data[-1])])),
            '<?xml version="1.0" encoding="utf-8"?>\n'
            '<coupon id="%s" issuer="%s" stackable="false" author="%s">'
            '<type>COUPON_DISCOUNT</type>'
            '<desc></desc>'
            '<password></password>'
            '<valid from="%s 00:00:00" to="%s 23:59:59"></valid>'
            '<redeemable always="true"></redeemable>'
            '<require order="any">'
            '<order match="sale" id="%s"></order>'
            '<operation>NONE</operation>'
            '</require>'
            '<reward>'
            '<rebate type="VALUE_MATCHING">5.0</rebate>'
            '</reward>'
            '</coupon>' % (self.id_coupon, self.id_brand, self.bo_user, today,
                           today, id_sale))

        # expired coupon
        coupon_values.update({
            'action': 'update',
            'id_coupon': self.id_coupon,
            'expiration_time': str(datetime.now())[:19],
        })
        self._post_coupon(coupon_values)
        coupons_data = self._list_coupons(params={'id_item': id_sale})
        self.assertEquals(len(coupons_data), num)
        if len(coupons_data) > 0:
            self.assertNotEquals(coupons_data[-1]['@id'], self.id_coupon)

        # coupon without expiration_time
        coupon_values.pop('expiration_time')
        self._post_coupon(coupon_values)
        coupons_data = self._list_coupons(params={'id_item': id_sale})
        self.assertEquals(len(coupons_data), num + 1)
        self.assertEquals(coupons_data[-1]['@id'], self.id_coupon)

        # delete coupon
        self._post_coupon({
            'action': 'delete',
            'id_coupon': self.id_coupon,
        })
        coupons_data = self._list_coupons(params={'id_item': id_sale})
        self.assertEquals(len(coupons_data), num)
        if len(coupons_data) > 0:
            self.assertNotEquals(coupons_data[-1]['@id'], self.id_coupon)
        self.id_coupon = None

    @unittest.skipUnless(not is_backoffice_server_running(), SKIP_REASON)
    def test_store_credit_coupon(self):
        today = str(datetime.now().date())
        id_shop = 1000001
        coupon_values = {
            'action': 'create',
            'author': self.bo_user,
            'reward_type': 'COUPON_CURRENCY',
            'store_credit_amount': 10,
            'store_credit_currency': 'EUR',
            'require': ujson.dumps({"invoice_match": {
                "shop": [id_shop]
            }}),
            'effective_time': today,
            'expiration_time': today,
        }
        self.id_coupon = self._post_coupon(coupon_values)
        coupons_data = self._list_coupons(params={'id_shop': id_shop})
        self.assert_(len(coupons_data) > 0)
        self.assertEquals(
            xmltodict.unparse(OrderedDict([(u'coupon', coupons_data[-1])])),
            '<?xml version="1.0" encoding="utf-8"?>\n'
            '<coupon id="%s" issuer="%s" stackable="true" author="%s">'
            '<type>COUPON_CURRENCY</type>'
            '<desc></desc>'
            '<password></password>'
            '<valid from="%s 00:00:00" to="%s 23:59:59"></valid>'
            '<redeemable always="true"></redeemable>'
            '<require order="any">'
            '<order match="shop" id="%s"></order>'
            '<operation>NONE</operation>'
            '</require>'
            '<reward>'
            '<credit currency="EUR">10.0</credit>'
            '</reward>'
            '</coupon>' % (self.id_coupon, self.id_brand, self.bo_user, today,
                           today, id_shop))

        self._post_coupon({
            'action': 'delete',
            'id_coupon': self.id_coupon,
        })
        coupons_data = self._list_coupons(params={'id_shop': id_shop})
        if len(coupons_data) > 0:
            self.assertNotEquals(coupons_data[-1]['@id'], self.id_coupon)
        self.id_coupon = None

    @unittest.skipUnless(not is_backoffice_server_running(), SKIP_REASON)
    def test_give_away_coupon(self):
        today = str(datetime.now().date())
        id_item_brand = 1000001
        coupon_values = {
            'action':
            'create',
            'author':
            self.bo_user,
            'reward_type':
            'COUPON_GIVEAWAY',
            'require':
            ujson.dumps({
                "invoice_match": {
                    "brand": [id_item_brand],
                    "operation": "SUM_PRICE",
                    "more_than": 100,
                    "equal": 100,
                },
            }),
            'gift':
            ujson.dumps([{
                "id": 1000001,
                "quantity": 1
            }, {
                "id": 1000002,
                "quantity": 2
            }]),
            'effective_time':
            today,
            'expiration_time':
            today,
        }
        self.id_coupon = self._post_coupon(coupon_values)
        coupons_data = self._list_coupons(params={'item_brand': id_item_brand})
        self.assert_(len(coupons_data) > 0)
        self.assertEquals(
            xmltodict.unparse(OrderedDict([(u'coupon', coupons_data[-1])])),
            '<?xml version="1.0" encoding="utf-8"?>\n'
            '<coupon id="%s" issuer="%s" stackable="false" author="%s">'
            '<type>COUPON_GIVEAWAY</type>'
            '<desc></desc>'
            '<password></password>'
            '<valid from="%s 00:00:00" to="%s 23:59:59"></valid>'
            '<redeemable always="true"></redeemable>'
            '<require order="any">'
            '<order match="brand" id="%s"></order>'
            '<operation>SUM_PRICE</operation>'
            '<threshold sum="price" must="GTE">100.0</threshold>'
            '</require>'
            '<reward>'
            '<gifts>'
            '<gift quantity="1">1000001</gift>'
            '<gift quantity="2">1000002</gift>'
            '</gifts>'
            '</reward>'
            '</coupon>' % (self.id_coupon, self.id_brand, self.bo_user, today,
                           today, id_item_brand))

        self._post_coupon({
            'action': 'delete',
            'id_coupon': self.id_coupon,
        })
        coupons_data = self._list_coupons(params={'item_brand': id_item_brand})
        if len(coupons_data) > 0:
            self.assertNotEquals(coupons_data[-1]['@id'], self.id_coupon)
        self.id_coupon = None
class TestShippingConf(BaseShipmentTestCase):
    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def test(self):
        item1_with_2_services = {
            'id_sale': 1000031,
            'id_variant': 1000012,
            'quantity': 2,
            'id_shop': 1000002,
            'id_type': 1000003,
            'id_price_type': 1000003,
            'id_weight_type': 1000003}
        item1_weight = 2.0
        item1_fee = item1_weight * 2 * 2

        item2_free_shipping = {
            'id_sale': 1000032,
            'id_variant': 1000013,
            'quantity': 1,
            'id_shop': 1000002,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item2_weight = 3.3
        item2_fake_fee = item2_weight * 2

        item3_with_1_service = {
            'id_sale': 1000033,
            'id_variant': 1000014,
            'quantity': 2,
            'id_shop': 1000002,
            'id_type': 1000003,
            'id_price_type': 1000003,
            'id_weight_type': 1000003}
        item3_weight = 3
        item3_fee = item3_weight * 2 * 2

        id_carrier1 = 1
        id_service1 = 1

        # test conf service for shipment which support 2 services
        wwwOrder = [item1_with_2_services]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        id_shp = self._shipmentsCountCheck(id_order, 1)[0]
        r = self._shipping_conf(id_shipment=id_shp,
                                id_carrier=id_carrier1,
                                id_service=id_service1)
        self._success_check(id_shp, r,
                            exp_postage=id_service1,
                            exp_fee=item1_fee)

        # test conf service for shipment which support 1 service
        # and grouped with free item
        wwwOrder = [item3_with_1_service, item2_free_shipping]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        id_shp = self._shipmentsCountCheck(id_order, 1)[0]
        r = self._shipping_conf(id_shipment=id_shp,
                                id_carrier=id_carrier1,
                                id_service=id_service1)
        self._success_check(id_shp, r,
                            exp_postage=id_service1,
                            exp_fee=item3_fee,
                            exp_free_fee=item2_fake_fee)

        # failure test conf service with wrong service id
        r = self._shipping_conf(id_shipment=id_shp,
                                id_carrier=id_carrier1,
                                id_service=id_service1 + 10)
        self.assertEqual(r[FAILURE], E_C.SP_INVALID_SERVICE[0])

        # failure test access others shipment
        self.login_with_new_user()
        r = self._shipping_conf(id_shipment=id_shp,
                                id_carrier=id_carrier1,
                                id_service=id_service1)
        self.assertEqual(r[FAILURE], E_C.SP_PRIORITY_ERROR[0])

    def _success_check(self, id_shipment, resp_content, exp_postage=None,
                       exp_fee=None, exp_free_fee=None):
        self.assertEqual(resp_content, SUCCESS)

        conn = db_utils.get_conn()
        if exp_postage is not None:
            query_str = ("SELECT id_postage "
                           "FROM shipping_supported_services "
                          "WHERE id_shipment=%s")
            r = db_utils.query(conn, query_str, (id_shipment,))

            self.assert_(len(r),
                         "No supported service record for shipment: %s"
                         % id_shipment)
            self.assertEqual(int(r[0][0]), int(exp_postage))

        if exp_fee is not None:
            query_str = ("SELECT shipping_fee "
                           "FROM shipping_fee "
                          "WHERE id_shipment=%s")
            r = db_utils.query(conn, query_str, (id_shipment,))

            self.assert_(len(r),
                         "No shipping fee record for shipment: %s"
                         % id_shipment)
            self.assertEqual(float(r[0][0]), float(exp_fee))

        if exp_free_fee is not None:
            query_str = ("SELECT fee "
                           "FROM free_shipping_fee "
                          "WHERE id_shipment=%s")
            r = db_utils.query(conn, query_str, (id_shipment,))

            self.assert_(len(r),
                         "No free shipping fee record for shipment: %s"
                         % id_shipment)
            self.assertEqual(float(r[0][0]), float(exp_free_fee))

    def _shipping_conf(self, id_shipment=None,
                       id_carrier=None, id_service=None):
        params = {
            'shipment': id_shipment,
            'carrier': id_carrier,
            'service': id_service
        }
        url = "webservice/1.0/pub/shipping/conf"
        resp = self.b._access(url, params)
        return ujson.loads(resp.get_data())
class TestShippingFee(BaseShipmentTestCase):
    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testShipmentShippingFee(self):
        item = {
            'id_sale': 1000031,
            'id_variant': 1000012,
            'quantity': 2,
            'id_shop': 1000002,
            'id_type': 1000003,
            'id_price_type': 1000003,
            'id_weight_type': 1000003}

        wwwOrder = [item]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        id_shp = self._shipmentsCountCheck(id_order, 1)[0]
        id_carrier1 = 1
        id_carrier2 = 2
        id_service1 = 1
        id_service2 = 2

        exp_fee_1 = {
            'pk': id_carrier1,
            'name': 'EMS',
            'carrier_services': [
                {'pk': id_service1,
                 'name': 'Express',
                 'desc': 'EMS express service',
                 'shipping_fee': 8}]
        }

        exp_fee_2 = {
            'pk': id_carrier2,
            'name': 'USPS',
            'carrier_services': [
                {'pk': id_service2,
                 'name': 'Express',
                 'desc': 'USPS express service',
                 'shipping_fee': 12}]
        }

        # test shipping fee for shipment without specify service
        resp_content = self._shipping_fee({'shipment': id_shp})
        exp = {'carrier_rules': [exp_fee_1, exp_fee_2],
               'default_currency': SHIPPING_CURRENCY}

        self._xml_resp_check('shipping_fees_test.xml',
                             exp,
                             resp_content)

        # test shipping fee for shipment with specify service
        resp_content = self._shipping_fee({'shipment': id_shp,
                                           'carrier': id_carrier1,
                                           'service': id_service1})
        exp = {'carrier_rules': [exp_fee_1],
               'default_currency': SHIPPING_CURRENCY}

        self._xml_resp_check('shipping_fees_test.xml',
                             exp,
                             resp_content)

        # test shipping fee for shipment with not supported service
        resp_content = self._shipping_fee({'shipment': id_shp,
                                           'carrier': id_carrier1,
                                           'service': id_service1 + 10})
        exp = {'error': E_C.SPSF_NOT_SUPPORT_SERVICE[0]}

        self._xml_resp_check('error.xml',
                             exp,
                             resp_content)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testSaleShippingFee(self):
        id_sale = 1000031
        id_weight_type = 1000003

        id_carrier1 = 1
        id_carrier2 = 2
        id_service1 = 1
        id_service2 = 2

        exp_fee_1 = {
            'pk': id_carrier1,
            'name': 'EMS',
            'carrier_services': [
                {'pk': id_service1,
                 'name': 'Express',
                 'desc': 'EMS express service',
                 'shipping_fee': 4}]
        }

        exp_fee_2 = {
            'pk': id_carrier2,
            'name': 'USPS',
            'carrier_services': [
                {'pk': id_service2,
                 'name': 'Express',
                 'desc': 'USPS express service',
                 'shipping_fee': 6}]
        }

        # test shipping fee for sale without specify service
        resp_content = self._shipping_fee({'sale': id_sale,
                                           'weight_type': id_weight_type,
                                           'shop': 1000002})
        exp = {'carrier_rules': [exp_fee_1, exp_fee_2],
               'default_currency': SHIPPING_CURRENCY}

        self._xml_resp_check('shipping_fees_test.xml',
                             exp,
                             resp_content)

        # test shipping fee for sale with specify service
        resp_content = self._shipping_fee({'sale': id_sale,
                                           'weight_type': id_weight_type,
                                           'shop': 1000002,
                                           'carrier': id_carrier1,
                                           'service': id_service1})
        exp = {'carrier_rules': [exp_fee_1],
               'default_currency': SHIPPING_CURRENCY}

        self._xml_resp_check('shipping_fees_test.xml',
                             exp,
                             resp_content)

        # test shipping fee for sale with not supported service
        resp_content = self._shipping_fee({'sale': id_sale,
                                           'weight_type': id_weight_type,
                                           'shop': 1000002,
                                           'carrier': id_carrier1,
                                           'service': id_service1 + 10})
        exp = {'error': E_C.SSF_NOT_SUPPORT_SERVICE[0]}

        self._xml_resp_check('error.xml',
                             exp,
                             resp_content)

    def _shipping_fee(self, params):
        params = urllib.urlencode(params)
        url = "webservice/1.0/pub/shipping/fees?%s" % params
        resp = self.b._access(url)
        return resp.get_data()
class TestShipment(BaseShipmentTestCase):
    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testShipmentGroupInOneShop(self):
        """ Test case:
        target market: all items in shop 1000006
        Sale Items:
           * two items with automatic carrier shipping fees
           * one item with invoice shipping fees
           * one item with flat rate
           * one item with free shipping
           * one item with a custom computation
        Expect result:
           * 5 shipments
           * invoice shipping fee without a price.
        """
        carrier_shipping_item1 = {
            'id_sale': 1000006,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item1_handling_fee = 12.0
        item1_shipping_fee = 1.05*2
        carrier_shipping_item2 = {
            'id_sale': 1000007,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item2_handling_fee = 23.0
        item2_shipping_fee = 2.0*2
        invoice_shipping_item3 = {
            'id_sale': 1000008,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        flat_rate_shipping_item4 = {
            'id_sale': 1000009,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item4_handling_fee = 21.0
        item4_shipping_fee = 15.0
        free_shipping_item5 = {
            'id_sale': 1000010,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item5_fake_fee = 9.0 * 2
        custom_shipping_item6 = {
            'id_sale': 1000011,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item6_handling_fee = 23.0
        item6_shipping_fee = 5.0

        # order:
        wwwOrder = [carrier_shipping_item1,
                    carrier_shipping_item2,
                    invoice_shipping_item3,
                    flat_rate_shipping_item4,
                    free_shipping_item5,
                    custom_shipping_item6]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        shipment_index = self._shipmentsCountCheck(id_order, 4)
        (id_spm_flat_rate, id_spm_invoice, id_spm_carrier,
         id_spm_custom) = shipment_index
        self._successShipment(id_spm_flat_rate,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_handling_fee=item4_handling_fee,
                              expect_shipping_fee=item4_shipping_fee)
        self._successShipment(id_spm_invoice,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_none_handling_fee=True,
                              expect_none_shipping_fee=True)
        expect_handling_fee = max([item1_handling_fee, item2_handling_fee])
        expect_shipping_fee = (item1_shipping_fee +
                               item2_shipping_fee)
        services = '{"1":"1"}'
        self._successShipment(id_spm_carrier,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_handling_fee=expect_handling_fee,
                              expect_shipping_fee=expect_shipping_fee,
                              expect_supported_services=services)
        services = '{"1000001":"0"}'
        self._successShipment(id_spm_custom,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_handling_fee=item6_handling_fee,
                              expect_shipping_fee=item6_shipping_fee,
                              expect_supported_services=services)
        self._freeShippingCheck(id_spm_carrier, item5_fake_fee)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testShipmentGroupInDiffShop(self):
        """ Test Case:
        target market:
          * one item in shop5
          * one item in shop6
        sale items:
          * item1 - shop5, allow group, support EMS-Express, quantity 2
          * item1 - shop6, allow group, support EMS-Express, quantity 2
        expected result:
          * 2 shipments created

        """
        item1_in_shop5 = {
            'id_sale': 1000027,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000005,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item2_in_shop6 = {
            'id_sale': 1000028,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        wwwOrder = [item1_in_shop5,
                    item2_in_shop6]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        self._shipmentsCountCheck(id_order, 2)


    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testGroupByDiffCorporate(self):
        """ Test Case:
        target market: 2 internet sale items.
        sale items:
          * item for corporate 3 with carrier EMS service
          * item for corporate 4 with carrier EMS service
        expected result:
          * 2 shipments created

        """
        item1_for_corporate3 = {
            'id_sale': 1000012,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 0,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}

        item2_for_corporate4 = {
            'id_sale': 1000013,
            'id_variant': 0,
            'quantity': 1,
            'id_shop': 0,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}

        wwwOrder = [item1_for_corporate3, item2_for_corporate4]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        shipment_index = self._shipmentsCountCheck(id_order, 2)

        services = '{"1":"1"}'
        for id_shipment in shipment_index:
            self._successShipment(id_shipment,
                                  expect_order=id_order,
                                  expect_status=SHIPMENT_STATUS.PACKING,
                                  expect_supported_services=services)


    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testGroupByMostCommonCarrierService(self):
        """ Test Case:
        target market:  all items in shop 1000006
        sale items:
          * item1 supports EMS-Express, USPS-Express, quantity 2
          * item2 supports EMS-Express, USPS-Express, quantity 3
          * item3 supports USPS-Express, quantity 2
          * item4 supports EMS-Express, quantity 2
        Expect result:
          * shipment1: groups item1, item2, item4
          * shipment2: groups item3
        """
        item1_quantity = 3
        item1_with_ems_usps = {
            'id_sale': 1000014,
            'id_variant': 0,
            'quantity': item1_quantity,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item1_handling_fee = 11.0
        item1_weight = 1.0

        item2_quantity = 2
        item2_with_ems_usps = {
            'id_sale': 1000015,
            'id_variant': 0,
            'quantity': item2_quantity,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item2_weight = 2.0
        item2_handling_fee = 12.0

        item3_quantity = 2
        item3_with_usps = {
            'id_sale': 1000016,
            'id_variant': 0,
            'quantity': item3_quantity,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item3_weight = 3.0
        item3_handling_fee = 13.0

        item4_quantity = 2
        item4_with_ems = {
            'id_sale': 1000017,
            'id_variant': 0,
            'quantity': item4_quantity,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item4_weight = 4.0
        item4_handling_fee = 14.0

        wwwOrder = [item1_with_ems_usps, item2_with_ems_usps,
                    item3_with_usps, item4_with_ems]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        spm1, spm2 = self._shipmentsCountCheck(id_order, 2)


        expect_handling_fee = max([item1_handling_fee,
                    item2_handling_fee,
                    item4_handling_fee])
        expect_shipping_fee =  2.0 * (item1_weight * item1_quantity +
                                      item2_weight * item2_quantity +
                                      item4_weight * item4_quantity)
        services = '{"1":"1"}'
        self._successShipment(spm1,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_handling_fee=expect_handling_fee,
                              expect_shipping_fee=expect_shipping_fee,
                              expect_supported_services=services)

        expect_handling_fee = item3_handling_fee
        expect_shipping_fee = 3.0 * item3_weight * item3_quantity
        services = '{"2":"2"}'
        self._successShipment(spm2,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_handling_fee=expect_handling_fee,
                              expect_shipping_fee=expect_shipping_fee,
                              expect_supported_services=services)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testGroupByMostCommonCustomService(self):
        """ Test Case:
        target market:  all items in shop 1000006
        sale items:
          * item1 supports custom shipping 1, custom shipping2, quantity 2
          * item2 supports custom shipping 1, custom shipping2, quantity 3
          * item3 supports custom shipping 1, quantity 2
          * item4 supports custom shipping 2, quantity 2
        Expect result:
          * shipment1: groups item1, item2, item3
          * shipment2: groups item4
        """
        item1_with_custom1_custom2 = {
            'id_sale': 1000018,
            'id_variant': 0,
            'quantity': 3,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item1_handling_fee = 17.0

        item2_with_custom1_custom2 = {
            'id_sale': 1000019,
            'id_variant': 0,
            'quantity': 2,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item2_handling_fee = 18.0

        item3_with_custom1 = {
            'id_sale': 1000020,
            'id_variant': 0,
            'quantity': 2,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item3_handling_fee = 19.0

        item4_with_custom2 = {
            'id_sale': 1000021,
            'id_variant': 0,
            'quantity': 2,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}
        item4_handling_fee = 20.0

        custom1_fee = 5.0
        custom2_fee = 6.0

        wwwOrder = [item1_with_custom1_custom2, item2_with_custom1_custom2,
                    item3_with_custom1, item4_with_custom2]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        spm1, spm2 = self._shipmentsCountCheck(id_order, 2)
        expect_handling_fee = max(item1_handling_fee,
                   item2_handling_fee,
                   item3_handling_fee)
        services = '{"1000001":"0"}'
        self._successShipment(spm1,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_handling_fee=expect_handling_fee,
                              expect_shipping_fee=custom1_fee,
                              expect_supported_services=services)

        services = '{"1000002":"0"}'
        self._successShipment(spm2,
                              expect_order=id_order,
                              expect_status=SHIPMENT_STATUS.PACKING,
                              expect_handling_fee=item4_handling_fee,
                              expect_shipping_fee=custom2_fee,
                              expect_supported_services=services)

    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def testNotAllowGroups(self):
        """ Test Case:
        target market:  all items in shop 1000006
        sale items:
          * item1 - free shipping, quantity 2
          * item2 - flat rate, quantity 3
          * item3 - carrier shipping rate, quantity 2
          * item4 - custom shipping rate, quantity 3
          * item5 - invoice shipping, quantity 2
        Expect result:
          * 12 shipments create.
        """
        item1_with_free_shipping = {
            'id_sale': 1000022,
            'id_variant': 0,
            'quantity': 2,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}

        item2_with_flat_rate = {
            'id_sale': 1000023,
            'id_variant': 0,
            'quantity': 3,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}

        item3_with_carrier_shipping = {
            'id_sale': 1000024,
            'id_variant': 0,
            'quantity': 2,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}

        item4_with_custom_shipping = {
            'id_sale': 1000025,
            'id_variant': 0,
            'quantity': 3,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}

        item5_with_invoice_shipping = {
            'id_sale': 1000026,
            'id_variant': 0,
            'quantity': 2,
            'id_shop': 1000006,
            'id_type': 0,
            'id_price_type': 0,
            'id_weight_type': 0}

        wwwOrder = [item1_with_free_shipping,
                    item2_with_flat_rate,
                    item3_with_carrier_shipping,
                    item4_with_custom_shipping,
                    item5_with_invoice_shipping]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        self._shipmentsCountCheck(id_order, 12)
class TestShippingList(BaseShipmentTestCase):
    @unittest.skipUnless(is_backoffice_server_running(), SKIP_REASON)
    def test(self):
        item_with_carrier_shipping = {
            'id_sale': 1000029,
            'id_variant': 1000011,
            'quantity': 2,
            'id_shop': 1000002,
            'id_type': 1000003,
            'id_price_type': 1000003,
            'id_weight_type': 1000003}

        wwwOrder = [item_with_carrier_shipping]
        id_order = self.success_wwwOrder(self.telephone, self.shipaddr,
                                         self.billaddr, wwwOrder)
        self._reqInvoice(id_order)

        id_shp = self._shipmentsCountCheck(id_order, 1)[0]
        resp_content = self._shippingList(id_order)
        id_order_item = self._order_item(id_order)[0]
        id_spl_item = self._shipping_list_item(id_shp)[0]
        shipping_data = {
            'object_list': [
                {'carriers': [
                    {'id': u'1',
                     'name': u'EMS',
                     'services': [
                         {'desc': u'EMS express service',
                          'id': u'1',
                          'name': u'Express'}]
                    }],
                 'fee_info': {'handling_fee': 5.0,
                              'id': 349,
                              'id_shipment': 427L,
                              'shipping_fee': 6.0},
                 'id': 431,
                 'calculation_method': 3,
                 'id_brand': 1000001,
                 'id_shop': 1000002,
                 'tracking_name': None,
                 'shipping_carrier': 1,
                 'shipping_list': [
                     {'id_shipping_list': id_spl_item,
                      'id_item': id_order_item,
                      'shipping_status': 1,
                      'id_sale': 1000029L,
                      'id_variant': 1000011L,
                      'id_weight_type': 1000003L,
                      'quantity': 2,
                      'sale_item': {
                          'id': u'1000029',
                          'name': u'item1 type weight type price with variant',
                          'currency': 'EUR',
                          'quantity': 2,
                          'packing_quantity': 2,
                          'remaining_quantity': 0,
                          'sel_variant': {
                              'id': u'1000011',
                              'name': u'product brand attr for test',
                              'premium': {'text': u'1.0', 'type': u'ratio'},
                              'thumb': None},
                          'sel_weight_type': {
                              'id': u'1000003',
                              'name': u'common attr1 for product type 1',
                              'weight': u'1.5'},
                          'type': {
                              'id': u'1000001',
                              'name': u'product type 1'},
                          'weight': u'3.0',
                          'weight_unit': u'kg'}}],
                 'status': 1,
                 'postage': 1,
                 'tracking_info': None}],
            'shipping_currency': 'EUR',
            'shipping_weight_unit': 'kg',
            'order_create_date': datetime.datetime.now().strftime("%Y-%m-%d"),
            'order_status': 2}
        shipping_data['object_list'][0]['id'] = id_shp
        self._xml_resp_check('shipping_list.xml',
                            shipping_data,
                            resp_content)

    def _shippingList(self, id_order):
        params = urllib.urlencode({'id_order': id_order})
        url = "webservice/1.0/pub/shipping/list?%s" % params
        resp = self.b._access(url)
        return resp.get_data()

    def _reqInvoice(self, id_order):
        url = "webservice/1.0/pub/invoice/request"
        resp = self.b._access(url, {'order': id_order})
        return resp.get_data()