Example #1
0
def _remember_campaign(request):
    if 'campaign_id' in request.session:
        request.ctx.campaign = Campaign.load(request.session['campaign_id'])
    else:
        if '__cid' in request.params:
            request.ctx.campaign = Campaign.load(request.params['__cid'])
        else:
            if request.ctx.site:
                request.ctx.campaign = Campaign.load(request.ctx.site.company.default_campaign_id)
        request.session['campaign_id'] = request.ctx.campaign.campaign_id
Example #2
0
    def save_inventory(self):
        prod = Product.load(self.request.POST.get('id'))
        self.forbid_if(not prod or prod.company.enterprise_id != self.enterprise_id)
        InventoryJournal.create_new(prod, 'Inventory Adjust', float(self.request.POST.get('inventory', 0)))
        prod.name = self.request.POST.get('name')
        prod.manufacturer = self.request.POST.get('manufacturer')
        prod.unit_cost = util.nvl(self.request.POST.get('unit_cost'), 0.0)
        prod.sku = self.request.POST.get('sku')
        prod.inventory_par = util.nvl(self.request.POST.get('inventory_par'), None)
        prod.save()

        # save all the prices, prefixed by "cmp_"
        for k in self.request.POST.keys():
            if k.startswith('cmp_'):
                match = re.search(r'^.*_(.*)', k)
                if match:
                    campaign = Campaign.load(match.group(1))
                    price = self.request.POST.get(k)
                    if price:
                        price = util.float_(price)
                        prod.set_price_only(campaign, price)
                    else:
                        prod.remove_price(campaign)
                    prod.invalidate_caches(campaign_id=campaign.campaign_id)
        return 'True'
Example #3
0
    def inventory_list(self):
        products = Product.find_by_vendor(self.request.ctx.user.vendor) if self.request.ctx.user and self.request.ctx.user.is_vendor_user() else Product.find_all(self.enterprise_id) #pylint: disable-msg=E1120

        campaigns = Campaign.find_all(self.enterprise_id)

        response = {
            'page': 1,
            'total': 1,
            'records': len(products)}

        rows = []

        for prod in products:
            #log.debug('%s %s/%s' % (p.product_id, i+1, len(products)))
            # blank spot at the beginning of the row is to make room for the
            # action buttons.  don't remove it.
            cells = ['', unicode(prod.product_id),
                     util.nvl(prod.name),
                     util.nvl(prod.sku),
                     util.nvl(prod.manufacturer),
                     util.nvl(unicode(prod.inventory)),
                     util.nvl(unicode(prod.inventory_par)),
                     util.nvl(unicode(prod.unit_cost))]
            # the column ordering in the UI is dependant on the order of the
            # campaigns that comes back from Campaign.find_all().  We use the
            # same ordering here so we are fine not adding some campaign ID here.
            for camp in campaigns:
                cells.append(util.nvl(util.money(prod.get_retail_price(camp))))

            rows.append({'id': str(prod.product_id),
                         'cell': cells})

        response['rows'] = rows
        return json.dumps(response)
Example #4
0
 def _create_new(self):
     R = self.get('/crm/campaign/new')
     assert R.status_int == 200
     R.mustcontain('Edit Campaign')
     f = R.forms['frm_campaign']
     self.assertEqual(f['campaign_id'].value, '')
     f.set('name', 'Test Campaign')
     f.set('default_url', 'testxyz.com')
     f.set('email', '*****@*****.**')
     f.set('smtp_username', 'suser')
     f.set('smtp_password', 'spass')
     f.set('smtp_server', 'sserver')
     f.set('imap_username', 'imapuser')
     f.set('imap_password', 'imappass')
     f.set('imap_server', 'imapserver')
     f.set('attr_name[0]', 'attr0key')
     f.set('attr_value[0]', 'attr0val')
     f.set('attr_name[1]', 'attr1key')
     f.set('attr_value[1]', 'attr1val')
     R = f.submit('submit')
     self.assertEqual(R.status_int, 302)
     R = R.follow()
     assert R.status_int == 200
     f = R.forms['frm_campaign']
     R.mustcontain('Edit Campaign')
     campaign_id = f['campaign_id'].value
     self.assertNotEqual(f['campaign_id'].value, '')
     cmpn = Campaign.load(campaign_id)
     assert cmpn is not None
     assert cmpn.get_email_info() is not None
     return campaign_id
Example #5
0
    def _show_prep(self, report_id):
        report = Report.load(report_id)
        campaigns = products = companies = users = vendors = None
        if report.show_campaign_id:
            campaigns = util.select_list(Campaign.find_all(self.enterprise_id), 'campaign_id', 'name', True)

        if report.show_vendor_id:
            vendors = util.select_list(Vendor.find_all(self.enterprise_id), 'vendor_id', 'name', True)

        if report.show_company_id:
            companies = util.select_list(Company.find_all(self.enterprise_id), 'company_id', 'name', True)

        if report.show_user_id:
            users = util.select_list(Users.find_all(self.enterprise_id), 'user_id', 'user_id', True)

        if report.show_product_id:
            products = util.select_list(Product.find_all(self.enterprise_id), 'product_id', 'name', True)

        return {
            'today' : util.today_date(),
            'tomorrow' : util.tomorrow(),
            'thirty_ago' : util.today_date() - datetime.timedelta(days=30),
            'rpt_end_dt' : self.request.GET.get('rpt_end_dt'),
            'rpt_start_dt' : self.request.GET.get('rpt_start_dt'),
            'enterprise_id' : self.enterprise_id,
            'report' : report,
            'campaigns' : campaigns,
            'products' : products,
            'companies' : companies,
            'users' : users,
            'vendors' : vendors
            }
Example #6
0
 def test_site_alternate_campaign(self):
     ent = Enterprise.find_by_name('Healthy U Store')
     cmpns = Campaign.find_all(ent.enterprise_id)
     other_campaign = cmpns[1]
     R = self.get('/?__cid=%s' % other_campaign.campaign_id)
     assert R.status_int == 200
     R.mustcontain("campaign_id = %s" % other_campaign.campaign_id)
Example #7
0
    def _create_new_attribute(self, parent_product_id):
        ent = Enterprise.find_by_name('Healthy U Store')
        comp = Company.find_all(ent.enterprise_id)[0]
        R = self.get('/crm/product/new?is_attribute&parent_id=%s' % parent_product_id)
        assert R.status_int == 200
        R.mustcontain('Edit Attribute for')
        f = R.forms['frm_product']
        self.assertEqual(f['product_id'].value, '')
        f.set('parent_id', parent_product_id)
        f.set('is_attribute', 'True')
        f.set('type', 'Attr')
        f.set('name', 'Test Product')
        f.set('unit_cost', '10.00')
        f.set('sku', 'TEST-SKU-123')
        f.set('manufacturer', 'Test Manufacturer')
        f.set('attr_name[0]', 'attr0key')
        f.set('attr_value[0]', 'attr0val')
        f.set('attr_name[1]', 'attr1key')
        f.set('attr_value[1]', 'attr1val')

        for camp in Campaign.find_by_company(comp):
            f.set('campaign_price[%s]' % camp.campaign_id, 20.0)
            f.set('campaign_discount[%s]' % camp.campaign_id, 10.0)

        R = f.submit('submit')
        self.assertEqual(R.status_int, 302)
        R = R.follow()
        assert R.status_int == 200
        f = R.forms['frm_product']
        R.mustcontain('Edit Attribute for')
        product_id = f['product_id'].value
        self.assertNotEqual(f['product_id'].value, '')
        return product_id
Example #8
0
 def test_misc(self):
     ent = Enterprise.find_by_name('Healthy U Store')
     comps = Company.find_all(ent.enterprise_id)
     assert len(comps) > 0
     comp = comps[0]
     comp_ = Company.find_by_name(ent.enterprise_id, comp.name)
     assert comp_ is not None
     assert comp.company_id == comp_.company_id
     assert str(ent.enterprise_id) in str(ent) 
     assert ent.get_email_info() is not None
     assert comp.get_email_info() is not None
     assert Enterprise.find_by_name(ent.name).name == ent.name
     camps = Campaign.find_by_company(comp)
     assert len(camps) > 1
     ids = sorted([camp.campaign_id for camp in camps])
     ids2 = sorted([camp.campaign_id for camp in Campaign.load_ids(ids)])
     assert ids == ids2
Example #9
0
 def test_single_search(self):
     campaign_id = self._create_new()
     camp = Campaign.load(campaign_id)
     R = self.post('/crm/campaign/search',
                   {'name': 'Test Campaign',
                    'company_id' : camp.company_id})
     R.mustcontain('%s : Test Campaign' % campaign_id)
     self._delete_new(campaign_id)
Example #10
0
 def test_create_new(self):
     listing_id = self._create_new()
     cust = Customer.find(TEST_CUSTOMER_EMAIL, Campaign.load(self.site.default_campaign_id))
     listings = Listing.find_by_customer(cust)
     assert len(listings) == 1
     assert str(listings[0].listing_id) == listing_id
     Listing.find_last_n_assets(10)
     self._delete_new(listing_id)
Example #11
0
 def search(self):
     name = self.request.POST.get('name')
     company_id = self.request.POST.get('company_id')
     return {
         'companies' : util.select_list(Company.find_all(self.enterprise_id), 'company_id', 'name'),
         'name' : name,
         'company_id' : company_id,
         'campaigns' : Campaign.search(self.enterprise_id, name, company_id)
     }
Example #12
0
 def _edit_impl(self):
     company_id = self.request.matchdict.get('company_id')
     comms = []
     campaigns = util.select_list(Campaign.find_all(self.enterprise_id), 'campaign_id', 'name')
     company = None
     if company_id:
         company = Company.load(company_id)
         comms = util.select_list(Communication.find_all_by_company(company), 'comm_id', 'name')
     else:
         company = Company()
     return {'comms': comms,
             'company': company,
             'campaigns': campaigns}
Example #13
0
 def _edit_impl(self):
     site_id = self.request.matchdict.get('site_id')
     self.session['last_site_id'] = site_id
     if site_id:
         site = Site.load(site_id)
         self.forbid_if(not site or str(site.company.enterprise_id) != str(self.enterprise_id))
     else:
         site = Site()
     return {
         'site' : site,
         'shipping_methods' : Site.get_shipping_methods(),
         'tax_methods' : Site.get_tax_methods(),
         'companies' : util.select_list(Company.find_all(self.enterprise_id), 'company_id', 'name'),
         'campaigns' : util.select_list(Campaign.find_all(self.enterprise_id), 'campaign_id', 'name')
         }
Example #14
0
    def _edit_impl(self):
        campaign_id = self.request.matchdict.get('campaign_id')
        comms = []
        companies = util.select_list(Company.find_all(self.enterprise_id),
                                       'company_id', 'name')
        campaign = None
        if campaign_id:
            campaign = Campaign.load(campaign_id)
            self.forbid_if(not campaign or campaign.company.enterprise_id != self.enterprise_id)
            comms = util.select_list(Communication.find_all_by_company(campaign.company), 'comm_id', 'name', True)
        else:
            campaign = Campaign()

        return {'comms': comms,
                'campaign': campaign,
                'companies': companies}
Example #15
0
 def _edit_impl(self):
     customer_id = self.request.matchdict.get('customer_id')
     customer = None
     if customer_id:
         customer = Customer.load(customer_id)
         self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id)
         self._add_to_recent(customer)
     else:
         customer = Customer()
         customer.campaign = self.request.ctx.site.company.default_campaign
     return {
         'customer' : customer,
         'users' : util.select_list(Users.find_all(self.enterprise_id), 'user_id', ['fname', 'lname'], True),
         'phases' : util.select_list(CustomerPhase.find_all(self.enterprise_id), 'phase_id', 'display_name', True),
         'campaigns' : util.select_list(Campaign.find_all(self.enterprise_id), 'campaign_id', 'name')
         }
Example #16
0
    def provision(self):
        ent = Enterprise()
        ent.bind(self.request.POST, True, 'ent')
        ent.save()
        ent.flush()

        comp = Company()
        comp.bind(self.request.POST, True, 'cmp')
        comp.enterprise_id = ent.enterprise_id
        comp.save()
        comp.flush()

        campaign = Campaign()
        campaign.name = comp.name + ' Default'
        campaign.company_id = comp.company_id
        campaign.save()
        campaign.flush()

        comp.default_campaign_id = campaign.campaign_id
        comp.save()
        comp.flush()

        user = Users()
        user.bind(self.request.POST, True, 'u')
        user.password = Users.encode_password('password')
        user.enterprise_id = ent.enterprise_id
        user.type = 'Admin'
        user.save()
        user.flush()

        site = Site()
        site.bind(self.request.POST, True, 'st')
        site.company = comp
        site.description = comp.name + ' Site'
        site.creator = user
        #site.template = Template.find_by_name('default')
        site.save()
        site.flush()

        return {
            'enterprise' : ent,
            'company' : comp,
            'campaign' : campaign,
            'user' : user,
            'site' : site,
            'done' : True
            }
Example #17
0
 def _edit_impl(self):
     site_id = self.request.matchdict.get('site_id')
     site = Site.load(site_id)
     self.forbid_if(not site or str(site.company.enterprise_id) != str(self.enterprise_id))
     content_id = self.request.matchdict.get('content_id')
     if content_id:
         content = Content.load(content_id)
         self.forbid_if(not content
                        or str(content.site.company.enterprise_id) != str(self.enterprise_id)
                        or str(content.site_id) != str(site_id))
     else:
         content = Content()
         content.site_id = site_id
     return {
         'site' : site,
         'content' : content,
         'companies' : util.select_list(Company.find_all(self.enterprise_id), 'company_id', 'name'),
         'campaigns' : util.select_list(Campaign.find_all(self.enterprise_id), 'campaign_id', 'name')
         }
Example #18
0
    def _edit_impl(self):
        product_id = self.request.matchdict.get('product_id')
        campaigns = Campaign.find_all(self.enterprise_id)
        companies = util.select_list(Company.find_all(self.enterprise_id), 'company_id', 'name')
        product_types = Product.get_types()
        vendors = util.select_list(Vendor.find_all(self.enterprise_id), 'vendor_id', 'name', True)
        categories = util.select_list(ProductCategory.find_all(self.enterprise_id), 'category_id', 'name', True)
        if product_id:
            product = Product.load(product_id)
            self.forbid_if(not product or product.company.enterprise_id != self.enterprise_id)
            product_categories = ProductCategory.find_by_product(product)
        else:
            product = Product()
            product_categories = []
        self.forbid_if(self.request.ctx.user.is_vendor_user() and product.product_id and not self.request.ctx.user.vendor_id == product.vendor_id)
        children = product.get_children()
        other_products = product.find_eligible_children()
        non_children = []
        for prod in other_products:
            found = False
            for kid in children:
                if kid.child_id == prod.product_id:
                    found = True
                    break
            if found == False:
                non_children.append(prod)

        return  {
            'product' : product,
            'campaigns' : campaigns,
            'companies' : companies,
            'product_types' : product_types,
            'vendors' : vendors,
            'categories' : categories,
            'product_categories' : product_categories,
            'children' : children,
            'non_children': non_children,
            'other_products' : other_products,
            'events' : util.select_list(StatusEvent.find_all_applicable(self.enterprise_id, product), 'event_id', 'display_name'),
            'is_attribute' : self.request.GET.get('is_attribute') == 'True', 
            'parent_product' : Product.load(self.request.GET.get('parent_id')) if 'parent_id' in self.request.GET else None
            }
Example #19
0
    def _site_purchase(self, cust, cart=None):  #pylint: disable-msg=R0912,R0915
        """ KB: [2013-02-20]: MOD ATTR CustomerController._site_purchase : Allow for attributes passed in the post """
        bill = self._create_billing(cust)
        campaign = Campaign.load(cust.campaign_id)

        if not cart:
            cart = Cart()
            product_skus = self.request.POST.getall('product_sku')
            for sku in product_skus:
                prod = Product.find_by_sku(self.enterprise_id, campaign, sku)
                if prod:
                    cart.add_item(product=prod,
                                  campaign=cust.campaign,
                                  start_dt=self.request.POST.get('bill_start_dt')
                                  )
                else:
                    self.flash("No such product sku: %s" % sku)
                    self.raise_redirect(self.request.referrer)
        order = cust.add_order(cart, None, self.enterprise_id, campaign,
                               order_note=self.request.POST.get('order_note'))
        return self._bill_credit_card(cust, order, bill)
Example #20
0
    def _test_save_inventory(self):
        ent = Enterprise.find_by_name('Healthy U Store')
        cmpns = Campaign.find_all(ent.enterprise_id)

        R = self.get('/crm/product/inventory_list')
        assert R.status_int == 200
        prods = json.loads(R.body)
        self.assertGreater(prods['records'], 100)
        self.assertEqual(prods['records'], len(prods['rows']))
        # get the first product ID
        prod = prods['rows'][1]['cell']         # ['', '1451', '5-HTP 100 mg- Pharmax', 'SUP-1003', 'Seroyal', '123', '8.0', '15.0', '25.00', '', '25.00', '25.00']
        pid = prod[1]
        name = prod[2]
        #sku = prod[3]
        #manu = prod[4]
        inventory = int(prod[5])
        inventory_par = prod[6]
        unitcost = prod[7]
        R = self.post('/crm/product/save_inventory',
                      {'id' : pid,
                       'inventory' : inventory + 10,
                       'inventory_par' : inventory_par,
                       'name' : name + ' xxx',
                       'unit_cost' : unitcost,
                       'cmp_%s' % cmpns[0].campaign_id : '999',
                       'cmp_%s' % cmpns[1].campaign_id : ''})

        self.assertEquals(R.body, 'True')
        prod = Product.load(pid)
        tot = InventoryJournal.total(prod)
        self.assertEqual(tot, inventory + 10)
        self.assertEqual(999, prod.campaign_prices[cmpns[0].campaign_id].retail_price)
        self.assertEqual(True, cmpns[1].campaign_id not in prod.campaign_prices.keys())

        R = self.get('/crm/product/edit/%s' % pid)
        assert R.status_int == 200
        f = R.forms['frm_product']
        R.mustcontain('Edit Product')
        self.assertEqual(f['product_id'].value, pid)
        self.assertEqual(f['name'].value, name + ' xxx')
Example #21
0
 def clear_caches(self):
     for camp in Campaign.find_all(self.enterprise_id):
         camp.invalidate_caches()
     return "ok"
Example #22
0
 def show_inventory(self):
     return {'products' : Product.find_by_vendor(self.enterprise_id, self.request.ctx.user.vendor) \
                 if self.request.ctx.user.is_vendor_user() else Product.find_inventory_tracked(self.enterprise_id),
             'campaigns' : Campaign.find_all(self.enterprise_id)
             }
Example #23
0
    def save(self):  #pylint: disable-msg=R0912,R0915
        product_id = self.request.POST.get('product_id')
        if product_id:
            prod = Product.load(product_id)
        else:
            prod = Product()
        prod.bind(self.request.POST, True)
        prod.mod_dt = util.now()
        prod.save()
        self.db_flush()

        new_children = {}
        for k in self.request.POST.keys():
            if k.startswith('campaign_price'):
                match = re.search(r'^.*\[(.*)\]', k)
                if match:
                    campaign = Campaign.load(match.group(1))
                    price = self.request.POST.get(k)
                    discount = self.request.POST.get('campaign_discount[%s]' % campaign.campaign_id)
                    if price:
                        price = util.float_(price)
                        discount = util.float_(util.nvl(discount, 0.0))
                        prod.set_price(campaign, price, discount)
                    else:
                        prod.remove_price(campaign)

            if k.startswith('child_incl'):
                child_product_id = self.request.POST.get(k)
                child_product_quantity = self.request.POST.get('child_quantity_%s' % child_product_id)
                new_children[child_product_id] = child_product_quantity


        # KB: [2013-02-23]: Clear out old children that were just deselected and add the ones that are still selected.
        for current_child in prod.get_children():
            if current_child.child_id not in new_children.keys():
                prod.clear_child(current_child.child_id)
                
        for new_child_product_id in new_children.keys():
            new_child_product_quantity = new_children[new_child_product_id]
            prod.add_child(new_child_product_id, new_child_product_quantity)

        prod.save()
        self.db_flush()

        redir_params = ''
        if 'parent_id' in self.request.POST and self.request.POST['parent_id']:
            parent = Product.load(self.request.POST['parent_id'])
            if not parent.has_child(prod.product_id):
                parent.add_child(prod.product_id)
                parent.save()
            redir_params = '?is_attribute=True&parent_id=%s' % parent.product_id

        inventory = str(self.request.POST.get('prod_inventory', '0'))
        if inventory and str(round(float(inventory), 2)) != str(round(util.nvl(InventoryJournal.total(prod), 0), 2)):
            InventoryJournal.create_new(prod, 'Inventory Adjust', inventory)
            self.db_flush()
            self.flash('Inventory Adjusted to %s' % inventory)

        prod.clear_attributes()
        for i in range(30):
            attr_name = self.request.POST.get('attr_name[%d]' % i)
            attr_value = self.request.POST.get('attr_value[%d]' % i)
            if attr_name and attr_value:
                prod.set_attr(attr_name, attr_value)

        category_id = self.request.POST.get('category_id')
        if category_id:
            category = ProductCategory.load(category_id)
            self.forbid_if(not category)
            category.add_product(prod.product_id)

        self.flash('Successfully saved %s.' % prod.name)
        return HTTPFound('/crm/product/edit/%s%s' % (prod.product_id, redir_params))
Example #24
0
 def _delete_new(self, campaign_id):
     camp = Campaign.load(campaign_id)
     self.assertNotEqual(camp, None)
     camp.delete()
     self.commit()
Example #25
0
    def save(self):
        cmpn = Campaign.load(self.request.POST.get('campaign_id'))
        if not cmpn:
            cmpn = Campaign()
        else:
            self.forbid_if(cmpn.company.enterprise_id != self.enterprise_id)
        cmpn.bind(self.request.POST)
        cmpn.save()

        cmpn.clear_attributes()
        for i in range(10):
            attr_name = self.request.POST.get('attr_name[%d]' % i)
            attr_value = self.request.POST.get('attr_value[%d]' % i)
            if attr_name and attr_value:
                cmpn.set_attr(attr_name, attr_value)

        cmpn.save()
        cmpn.flush()
        cmpn.invalidate_self()
        cmpn.invalidate_caches()
        self.request.session.flash('Successfully saved %s.' % cmpn.name)
        return HTTPFound('/crm/campaign/edit/%s' % cmpn.campaign_id)
Example #26
0
 def list(self):
     return {'campaigns' : Campaign.find_all(self.enterprise_id)}
Example #27
0
    def _test_save_existing(self):
        ent = Enterprise.find_by_name('Healthy U Store')
        cmpns = Campaign.find_all(ent.enterprise_id)

        product_id = self._create_new()
        R = self.get('/crm/product/list')
        assert R.status_int == 200
        R.mustcontain('Test Product')
        R.mustcontain('Product Search')   # make sure product search is in 2 places

        R = self.get('/crm/product/edit/%s' % product_id)
        R.mustcontain('Edit Product')
        f = R.forms['frm_product']
        self.assertEqual(f['product_id'].value, product_id)
        self.assertEqual(f['name'].value, 'Test Product')
        self.assertEqual(f['seo_keywords'].value, 'SEO Test')

        f.set('name', 'Test Product New')
        f.set('seo_keywords', 'SEO Test New')

        for prod in Product.find_all_except(Product.load(product_id))[:3]:
            f.set('child_incl_%s' % prod.product_id, prod.product_id)
            f.set('child_quantity_%s' % prod.product_id, 2)

        f.set('campaign_price[%s]' % cmpns[0].campaign_id, "123")
        f.set('campaign_price[%s]' % cmpns[1].campaign_id, None)

        f.set('prod_inventory', 25)

        #cat = ProductCategory.find_all(ent.enterprise_id)[0]
        #f.set('category_id', cat.category_id)

        R = f.submit('submit')
        self.assertEqual(R.status_int, 302)
        R = R.follow()
        assert R.status_int == 200
        f = R.forms['frm_product']
        R.mustcontain('Edit Product')

        self.assertEqual(f['product_id'].value, product_id)
        self.assertEqual(f['name'].value, 'Test Product New')
        self.assertEqual(f['seo_keywords'].value, 'SEO Test New')
        self.assertEqual(f['campaign_price[%s]' % cmpns[0].campaign_id].value, "123.00")
        self.assertEqual(f['campaign_price[%s]' % cmpns[1].campaign_id].value, "")

        #self.assertEqual(f['category_id'].value, cat.category_id)

        prod = Product.load(product_id)
        self.assertEqual(25, InventoryJournal.total(prod))

        for prod in Product.find_all_except(Product.load(product_id))[:3]:
            self.assertEqual(int(f['child_quantity_%s' % prod.product_id].value), 2)

        #put pricing back.
        R = self.get('/crm/product/edit/%s' % product_id)
        R.mustcontain('Edit Product')
        f = R.forms['frm_product']
        self.assertEqual(f['product_id'].value, product_id)
        f.set('campaign_price[%s]' % cmpns[0].campaign_id, "123")
        f.set('campaign_price[%s]' % cmpns[1].campaign_id, "234")
        R = f.submit('submit')
        self.assertEqual(R.status_int, 302)
        R = R.follow()
        assert R.status_int == 200
        f = R.forms['frm_product']
        R.mustcontain('Edit Product')
        self.assertEqual(f['product_id'].value, product_id)
        self.assertEqual(f['campaign_price[%s]' % cmpns[1].campaign_id].value, "234.00")
        self._delete_new(product_id)