示例#1
0
 def show_returns(self):
     product_id = self.request.matchdict['product_id']
     product = Product.load(product_id)
     self.forbid_if(not product or product.company.enterprise_id != self.enterprise_id)
     return {'product' : product,
             'events' : util.select_list(StatusEvent.find_all_applicable(self.enterprise_id, product), 'event_id', 'display_name'),
             'returns' : ProductReturn.find(product)}
示例#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'
示例#3
0
    def product(self):
        product_id = self.request.matchdict.get("product_id")
        if not util.is_uuid(product_id):
            # it's not really a product ID, but a search string from a bot.
            raise HTTPFound("/ecom/search?search=%s" % product_id)
        prod = Product.load(product_id)
        self.redir_if(not prod or not prod.enabled or not prod.web_visible)

        page = self.request.matchdict.get(
            "page", util.nvl(prod.render_template, "product")
        )  # /product/{product_id}/{page}

        self.session["last_product_id"] = product_id
        self.session["back_link"] = "/product/%s" % product_id
        params = self.params()
        self._add_to_recent_products(prod)

        params["product"] = prod
        params["products_also_liked"] = SmartCatalog.also_liked_product_list(prod, params["campaign"])
        params["products_related"] = SmartCatalog.related_product_list(prod, params["campaign"])
        params["product_attributes"] = self._prep_product_attributes(prod.get_product_attributes())
        params["attrs"] = prod.get_attrs()
        params["price"] = SmartPricing.product_price(prod, params["campaign"])
        (params["seo_title"], params["seo_keywords"], params["seo_description"]) = SmartSeo.product_seo(
            prod, self.request.ctx.site
        )
        return self.render(page, params)
示例#4
0
 def upload_picture(self):
     product_id = self.request.matchdict.get('product_id')
     product = Product.load(product_id)
     self.forbid_if(not product or product.company.enterprise_id != self.enterprise_id)
     ass = Asset.create_new(product, self.enterprise_id, self.request)
     self.flash('Uploaded new image to product')
     product.invalidate_caches()
     return str(ass.id)
示例#5
0
 def show_purchases(self):
     product_id = self.request.matchdict['product_id']
     from pvscore.model.crm.purchase import PurchaseOrderItem
     product = Product.load(product_id)
     self.forbid_if(not product or product.company.enterprise_id != self.enterprise_id)
     return {'product' : product,
             'events' : util.select_list(StatusEvent.find_all_applicable(self.enterprise_id, product), 'event_id', 'display_name'),
             'purchase_order_items' : PurchaseOrderItem.find_by_product(product)
             }
示例#6
0
 def delete_picture(self):
     product_id = self.request.matchdict.get('product_id')
     product = Product.load(product_id)
     self.forbid_if(not product or product.company.enterprise_id != self.enterprise_id)
     asset_id = self.request.matchdict.get('asset_id')
     asset = Asset.load(asset_id)
     self.forbid_if(asset.fk_type != 'Product' or str(asset.fk_id) != str(product.product_id))
     asset.delete()
     return 'True'
示例#7
0
 def save_status(self):
     product_id = self.request.POST['product_id']
     product = Product.load(product_id)
     self.forbid_if(not product or product.company.enterprise_id != self.enterprise_id)
     event = StatusEvent.load(self.request.POST['event_id'])
     self.forbid_if(not event or (not event.is_system and event.enterprise_id != self.enterprise_id))
     note = self.request.POST.get('note')
     Status.add(None, product, event, note, self.request.ctx.user)
     return HTTPFound('/crm/product/show_history/%s' % product_id)
示例#8
0
 def delete(self):
     product_id = self.request.matchdict.get('product_id')
     product = Product.load(product_id)
     self.forbid_if(not product or str(product.company.enterprise_id) != str(self.enterprise_id))
     product.mod_dt = util.now()
     product.delete_dt = util.now()
     Status.add(None, product, StatusEvent.find(self.enterprise_id, 'Product', 'DELETED'), 'Product Deleted')
     product.invalidate_caches()
     return 'True'
示例#9
0
 def update(self):
     product_id = self.request.matchdict.get('product_id')
     quantity = self.request.matchdict.get('quantity')
     redir = self.request.GET.get('redir')
     cart = self.session['cart']
     product = Product.load(product_id)
     cart.remove_item(product)
     cart.add_item(product, self.request.ctx.campaign, quantity)
     self.session.changed()
     return 'True' if not redir else HTTPFound(redir)
示例#10
0
 def remove(self):
     if not 'cart' in self.session:
         return 'False' #pragma: no cover
     redir = self.request.GET.get('redir')
     cart = self.session['cart']
     product_id = self.request.matchdict.get('product_id')
     product = Product.load(product_id)
     cart.remove_item(product)
     self.session.changed()
     return 'True' if not redir else HTTPFound(redir)
示例#11
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
            }
示例#12
0
def import_product_list(company_id, filename='/tmp/products/products.csv'):
    company = Company.load(company_id)
    default_campaign = company.default_campaign
    
    products = []
    with open(filename) as f:
        products = f.readlines()

    products = [p.rstrip() for p in products[1:]]

    product_categories = {}

    for pline in products:
        log(pline)
        (product_name, category_id, pic) = pline.split(',')
        pic = pic.strip()
        key = '%s%s' % (product_name.strip(), category_id.strip())
        cat = ProductCategory.load(category_id.strip(), False)
        prod = None
        if key in product_categories:
            prod = Product.load(product_categories[key][0], False)
        else:
            prod = Product()
            prod.company = company
            prod.name = product_name.strip()
            prod.type = 'Parent or Child'
            prod.save()
            prod.flush()
            product_categories[key] = [str(prod.product_id), str(cat.category_id)]

        ass = Asset()
        ass.fk_type = 'Product'
        ass.fk_id = prod.product_id
        ass.enterprise_id = company.enterprise_id
        ass.name = os.path.basename(pic)
        ass.extension = os.path.splitext(pic)[1]
        ass.save()
        ass.flush()        
        storage_root = Asset.get_storage_root()
        if not storage_root:
            storage_root = '/apps/pvs/storage'
        fs_real_dir = "{root}/{reldir}".format(root=storage_root, reldir=ass.relative_dir)
        util.mkdir_p(fs_real_dir)
        fs_real_path = "{fs_real_dir}/{assid}{ext}".format(fs_real_dir=fs_real_dir,
                                                           assid=ass.id,
                                                           ext=ass.extension)
        shutil.copyfile(pic, fs_real_path)

    for pc in product_categories:
        pcat = product_categories[pc]
        cat = ProductCategory.load(pcat[1], False)
        cat.add_product(pcat[0])

    db.commit()
示例#13
0
 def add(self):
     """ KB: [2013-02-20]: MOD ATTR:  CartController.add : Allow for ajax of adding a simple item (HUS), or post/redir for adding products with attributes. """
     product_id = self.request.matchdict.get('product_id')
     quantity = self.request.matchdict.get('quantity')
     redir = self.request.POST.get('redir')
     note = self.request.POST.get('note')
     cart = self.session['cart']
     product = Product.load(product_id)
     cart.add_item(product, self.request.ctx.campaign, quantity, note=note)
     self.session.changed()
     return 'True' if not redir else HTTPFound(redir)
示例#14
0
    def add_order(self):
        """ KB: [2013-02-20]: MOD ATTR CustomerController.add_order : Modify to allow for attributes to be passed in the post. """
        customer_id = self.request.matchdict.get('customer_id')
        cust = Customer.load(customer_id)
        self.forbid_if(not cust)

        # KB: [2013-02-24]: products are passed as products[$product_id] = quantity
        product_ids = {}
        for key in self.request.POST.keys():
            if key.startswith('products'):
                match = re.search(r'^.*\[(.*)\]', key)
                if match:
                    pid = match.group(1)
                    quant = float(util.nvl(self.request.POST.get(key), '1.0'))
                    if pid not in product_ids:
                        product_ids[pid] = 0
                    product_ids[pid] += quant


        # KB: [2013-02-24]: attributes are passed as attributes[$attribute_id] = $parent_product_id
        attributes = {}
        for key in self.request.POST.keys():
            if key.startswith('attributes'):
                match = re.search(r'^.*\[(.*)\]', key)
                if match:
                    attribute_product_id = match.group(1)
                    parent_product_id = self.request.POST.get(key)
                    attributes[attribute_product_id] = { 'parent_product' : Product.load(parent_product_id),
                                                         'attribute_product' : Product.load(attribute_product_id) }

        order_id = self._add_order_impl(customer_id, product_ids, attributes,
                                        None, self.request.ctx.user,
                                        self.request.POST.get('discount_id'),
                                        self.request.POST.get('campaign_id', self.request.GET.get('campaign_id')),
                                        self.incl_tax)
        cust.invalidate_caches()
        return str(order_id)
示例#15
0
    def add_attributed_product(self):
        """ KB: [2013-02-24]:
            var attributes = {};
            attributes[$('#color_id').val()] = 0;  // quantity of zero, unless its really something that requires a quantity.
            attributes[$('#size_id').val()] = 0;

            $.post('/ecom/cart/add_attributed_product',
                   { product_id : base_product_id,
                     attributes : attributes,
                     quantity : $('#qty').val()
                   },
                   function(resp) {
                       if (resp == 'True') {
                           window.location = '/product/' + base_product_id;
                       }
                   });
        
        """
        redir = self.request.POST.get('redir')
        product_id = self.request.POST.get('product_id')
        quantity = self.request.POST.get('quantity')
        cart = self.session['cart']
        attributes = {}
        for key in self.request.POST.keys():
            if key.startswith('attributes'):
                match = re.search(r'^.*\[(.*)\]', key)
                if match:
                    pid = match.group(1)
                    quant = float(util.nvl(self.request.POST.get(key), '1.0'))
                    attributes[pid] = { 'quantity' : quant,
                                        'product' : Product.load(pid) }
        product = Product.load(product_id)
        self.forbid_if(not product)
        cart.add_item(product, self.request.ctx.campaign, quantity, attributes=attributes)
        self.session.changed()
        return 'True' if not redir else HTTPFound(redir)
示例#16
0
 def _test_save_status(self):
     ent = Enterprise.find_by_name('Healthy U Store')
     product_id = self._create_new()
     product = Product.load(product_id)
     events = StatusEvent.find_all_applicable(ent.enterprise_id, product)
     R = self.post('/crm/product/save_status',
                  {'product_id': product_id,
                   'note' : 'Test Note %s' % product_id,
                   'event_id' : events[0].event_id})
     assert R.status_int == 200
     R.mustcontain('Product Event History')
     R.mustcontain('Test Note %s' % product_id)
     # assert that the edit page has the name of the event in green
     # at the top.
     R = self.get('/crm/product/edit/%s' % product_id)
     assert R.status_int == 200
     R.mustcontain('Edit Product')
     R.mustcontain(events[0].short_name)
     self._delete_new(product_id)
示例#17
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')
示例#18
0
 def _add_order_impl(self, customer_id, product_ids, attributes, prices, user, discount_id, campaign_id, incl_tax=True):   #pylint: disable-msg=R0913
     """ KB: [2013-02-20]:
     attributes = [{quantity : 0, product : <Product...>}, {...}]
     """
     cust = Customer.load(customer_id)
     self.forbid_if(not cust or cust.campaign.company.enterprise_id != self.enterprise_id)
     cart = Cart()
     campaign_id = campaign_id if campaign_id else cust.campaign_id
     cart.discount_id = discount_id
     for pid in product_ids.keys():
         quantity = product_ids[pid]
         price = prices[pid] if prices and pid in prices else None
         attrs = {}
         for attr in [attr['attribute_product'] for attr in attributes.values() if str(attr['parent_product'].product_id) == pid]:
             attrs[attr.product_id] = { 'quantity' : 0,
                                        'product' : attr}
         cart.add_item(product=Product.load(pid),
                       campaign=cust.campaign,
                       quantity=quantity,
                       attributes=attrs,
                       base_price=price)
     order = cust.add_order(cart, user, self.enterprise_id, cust.campaign, incl_tax=incl_tax)
     order.flush()
     return order.order_id
示例#19
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)
示例#20
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))
示例#21
0
    def create_new(cart, customer, enterprise_id, campaign, user_created, order_note=None, incl_tax=True):
        """ KB: [2010-09-09]: Given a cart full of products, create a new order and return it.
        if a given product is a parent, then create an kid order_item of zero cost and attach it to the parent.
        """
        cord = CustomerOrder()
        cord.creator = user_created
        cord.customer = customer
        cord.campaign = campaign
        cord.shipping_total = util.nvl(cart.shipping_total, 0.0)
        cord.shipping_note = cart.shipping_selection_name
        cord.handling_total = util.nvl(cart.handling_total, 0.0)
        cord.shipping_addr1 = cart.shipping_addr1
        cord.shipping_addr2 = cart.shipping_addr2
        cord.shipping_city = cart.shipping_city
        cord.shipping_state = cart.shipping_state
        cord.shipping_zip = cart.shipping_zip
        cord.shipping_country = cart.shipping_country
        cord.shipping_phone = cart.shipping_phone
        cart.calculate_cart_discount_for_order(cord)
        cord.note = order_note
        cord.save()
        cord.flush()
        for cart_item in cart.items:
            prd = Product.load(cart_item["product"].product_id)
            item = OrderItem()
            item.order = cord
            item.product = prd
            item.creator = user_created
            item.start_dt = cart_item["start_dt"]
            item.note = cart_item["note"]
            item.save()
            item.flush()

            attribute_order_items = []
            for attribute_product_id in cart_item["attributes"].keys():
                attribute_order_item = OrderItem()
                attribute_order_item.parent_id = item.order_item_id
                attribute_order_item.order = cord
                ao_prd = Product.load(attribute_product_id)
                attribute_order_item.product = ao_prd
                attribute_order_item.creator = user_created
                attribute_order_item.unit_cost = ao_prd.unit_cost
                attribute_order_item.unit_discount_price = ao_prd.get_discount_price(campaign)
                attribute_order_item.unit_retail_price = ao_prd.get_retail_price(campaign)
                attribute_order_item.quantity = cart_item["attributes"][attribute_product_id]["quantity"]
                attribute_order_item.save()
                attribute_order_items.append(attribute_order_item)

            # KB: [2013-02-24]: Discount is calculated by using the highest price of the discounts for the product and all of its selected attributes
            discount = max(
                [util.nvl(aois.unit_discount_price) for aois in attribute_order_items]
                + [prd.get_discount_price(campaign)]
            )
            # KB: [2013-02-24]: Retail is calculated by using the highest price of the retail prices for the product and all its selected attributes.
            retail = max(
                [util.nvl(aois.unit_retail_price, 0.0) for aois in attribute_order_items]
                + [cart_item["base_price"] if "base_price" in cart_item else prd.get_retail_price(campaign)]
            )

            item.quantity = float(cart_item["quantity"])
            item.unit_price = discount if discount else retail
            if campaign.tax_rate and incl_tax:
                item.tax = (item.unit_price * item.quantity) * campaign.tax_rate
            item.unit_cost = prd.unit_cost
            item.unit_discount_price = discount if discount else None
            item.unit_retail_price = retail
            item.save()
            if prd.track_inventory:
                InventoryJournal.create_new(prd, "Sale", int(item.quantity), item)
            if item.unit_discount_price is not None:
                discount = DiscountProduct.find_by_product(prd)
                Journal.create_new(
                    (item.unit_retail_price - item.unit_discount_price) * int(item.quantity),
                    customer,
                    cord,
                    None,
                    typ="AutomaticDiscount",
                    attachment=discount,
                )
            Status.add(
                customer,
                item,
                Status.find_event(enterprise_id, item, "CREATED"),
                "Item added to order %s @ $%s" % (prd.name, util.money(item.unit_price)),
            )
            if prd.can_have_children():
                item.flush()  # we need this to get the parent ID.
                children = prd.get_children()
                if children and len(children) > 0:
                    for kid in children:
                        child_item = OrderItem()
                        child_item.order = cord
                        child_item.parent_id = item.order_item_id
                        child_item.product = kid.child
                        child_item.creator = user_created
                        child_item.start_dt = cart_item["start_dt"]
                        child_item.unit_price = 0.0
                        child_item.unit_discount_price = None
                        child_item.unit_retail_price = 0.0
                        child_item.unit_cost = prd.unit_cost
                        child_item.quantity = kid.child_quantity
                        if kid.child.track_inventory:
                            InventoryJournal.create_new(kid.child, "Sale", child_item.quantity, child_item)
        Status.add(customer, cord, Status.find_event(enterprise_id, cord, "CREATED"), "Order created ")
        if cord.discount:
            discount_amount = None
            if cord.discount.percent_off:
                item_price = cord.total_item_price()
                discount_amount = item_price - (item_price * cord.discount.percent_off)
            elif cord.discount.shipping_percent_off:
                # (9.0 / (1.0-0.1)) = 10.00
                discount_amount = cart.shipping_discount_total
            if discount_amount and int(discount_amount) > 0:
                Journal.create_new(
                    discount_amount, customer, cord, None, typ="AutomaticDiscount", attachment=cord.discount
                )
        cord.save()
        cord.flush()
        return cord
示例#22
0
    def edit_order(self):   #pylint: disable-msg=R0915,R0912
        customer_id = self.request.matchdict.get('customer_id')
        order_id = self.request.matchdict.get('order_id')
        oids_to_delete = self.request.POST.getall('order_items_to_delete[]')
        customer = Customer.load(customer_id)
        self.forbid_if(not customer or customer.campaign.company.enterprise_id != self.enterprise_id)
        order = customer.get_order(order_id)
        self.forbid_if(not order)
        order.shipping_total = self.request.POST.get('shipping_total') if self.request.POST.get('shipping_total') else 0.0
        order.create_dt = self.request.POST.get('create_dt') if self.request.POST.get('create_dt') else order.create_dt
        order.save()

        total_payments_applied = order.total_payments_applied()

        for oid in oids_to_delete:
            oitem = OrderItem.load(oid)
            Status.add(customer, oitem, Status.find_event(self.enterprise_id, oitem, 'DELETED'), 'OrderItem deleted ')
            prod = oitem.product
            if prod.track_inventory:
                InventoryJournal.create_new(prod, 'Cancelled Item', oitem.quantity, oitem)
            for attr_kid in oitem.children:
                Status.add(customer, attr_kid, Status.find_event(self.enterprise_id, attr_kid, 'DELETED'), 'OrderItem deleted ')
                attr_kid_prod = attr_kid.product
                if attr_kid_prod.track_inventory:
                    InventoryJournal.create_new(attr_kid_prod, 'Cancelled Item', oitem.quantity, attr_kid)
                attr_kid.soft_delete()
            oitem.soft_delete()                

        # extract order_items[27][quantity] to set those properties.
        order_items = {}
        for key in self.request.POST.keys():
            if key.startswith('order_items'):
                match = re.search(r'^.*\[(.*)\]\[(.*)\]', key)
                if match:
                    order_item_id = match.group(1)
                    attr = match.group(2)
                    new_val = float(self.request.POST.get(key)) if attr != 'product_id' else self.request.POST.get(key)
                    # KB: [2011-03-07]: If the ID ends in '_', its not really an ID but a new item.
                    # product_id will only show up as non-null in the hash of a new product
                    if order_item_id[-1] == '_':
                        order_item_product = Product.load(self.request.POST.get('order_items[%s][product_id]' % order_item_id))
                        if not order_items.has_key(order_item_id):
                            order_items[order_item_id] = order.augment_order(customer,
                                                                             order_item_product,
                                                                             customer.campaign,
                                                                             self.request.ctx.user)
                        oitem = order_items[order_item_id]
                        assert oitem.product is not None
                        if 'quantity' == attr:
                            new_val = float(new_val)
                            if order_item_product.track_inventory:
                                InventoryJournal.create_new(order_item_product, 'Sale', new_val, oitem)
                        setattr(oitem, attr, new_val)
                        oitem.save()
                    else:
                        if not order_items.has_key(order_item_id):
                            order_items[order_item_id] = OrderItem.load(order_item_id)
                        oitem = order_items[order_item_id]
                        order_item_product = oitem.product

                        if util.money(getattr(oitem, attr)) != util.money(new_val):
                            Status.add(customer, oitem, Status.find_event(self.enterprise_id, oitem, 'MODIFIED'),
                                       'Order Item modified: (id=%s). %s : %s -> %s' % (oitem.order_item_id, attr, util.money(getattr(oitem, attr)), util.money(new_val)))
                        if 'quantity' == attr:
                            new_val = float(new_val)
                            if not total_payments_applied:
                                if order_item_product.track_inventory:
                                    InventoryJournal.cleanup(oitem, 'Sale')
                                    InventoryJournal.create_new(order_item_product, 'Sale', new_val, oitem)
                        setattr(oitem, attr, new_val)
                        oitem.save()
        Status.add(customer, order, Status.find_event(self.enterprise_id, order, 'MODIFIED'), 'Order modified')
        customer.invalidate_caches()
        self.flash("Saved Order")
        return 'True'