Exemplo n.º 1
0
 def add_into_stock(self):
     if not self.sku_id:
         logger.warn({
             'action': "add_into_stock",
             'info': 'Sku_id is not exist'
         })
         return
     if not self.can_reuse:
         return
     from shopback.items.models import SkuStock
     SkuStock.add_return_quantity(self.sku_id, self.num, stat=True)
     SkuStock.get_by_sku(self.sku_id).assign()
Exemplo n.º 2
0
 def begin(self, request, pk=None):
     product_ids = request.GET.get('product_ids', '')
     skus_dict = json.loads(request.GET.get('skus', '{}')) or {}
     sku_ids = skus_dict.keys()
     user = request.user
     orderDrAll = OrderDraft.objects.all().filter(buyer_name=user)
     if sku_ids:
         skus = ProductSku.objects.filter(
             id__in=sku_ids).select_related('product')
     elif product_ids:
         skus = ProductSku.objects.filter(
             product_id__in=product_ids).select_related('product')
     else:
         skus = []
     product_dicts = {}
     for sku in skus:
         if sku.product_id in product_dicts:
             product_dict = product_dicts.get(sku.product_id)
         else:
             product_dict = model_to_dict(sku.product)
             product_dict['prod_skus'] = []
             product_dicts[sku.product_id] = product_dict
         sku_dict = model_to_dict(sku)
         sku_dict['name'] = sku.name
         sku_dict['need_order'] = skus_dict.get(str(sku.id), 1)
         sku_dict['wait_post_num'] = SkuStock.get_by_sku(
             sku.id).wait_post_num
         product_dict['prod_skus'].append(sku_dict)
     productres = product_dicts.values()
     return render(request, 'dinghuo/purchase/purchase.html', {
         "productRestult": productres,
         "drafts": orderDrAll
     })
Exemplo n.º 3
0
def update_productskustats_adjust_num(sender, instance, created, **kwargs):
    if instance.status == 0:
        from shopback.items.models import SkuStock, InferiorSkuStats
        from shopback.items.models import ProductSku
        if not instance.inferior:
            # adjust_quantity = StockAdjust.objects.filter(sku_id=instance.sku_id, inferior=False)\
            #                  .aggregate(n=Sum('num')).get('n') or 0
            # SkuStock.update_adjust_num(instance.sku_id, adjust_quantity)
            SkuStock.add_adjust_num(instance.sku_id, instance.num)
        else:
            adjust_quantity = StockAdjust.objects.filter(sku_id=instance.sku_id, inferior=True)\
                              .aggregate(n=Sum('num')).get('n') or 0
            InferiorSkuStats.update_adjust_num(instance.sku_id,
                                               adjust_quantity)
        StockAdjust.objects.filter(id=instance.id).update(status=1)
        ProductSku.objects.filter(id=instance.sku_id).update(
            quantity=instance.sku.stat.realtime_quantity)
        if instance.num > 0:
            SkuStock.get_by_sku(instance.sku_id).assign()
        else:
            SkuStock.get_by_sku(instance.sku_id).relase_assign()
Exemplo n.º 4
0
def task_refundproduct_update_productskustats_return_quantity(sku_id):
    from shopback.refunds.models import RefundProduct
    logger.info("%s -sku_id:%s" % (get_cur_info(), sku_id))
    sum_res = RefundProduct.objects.filter(sku_id=sku_id, created__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME,
                                           can_reuse=True) \
        .aggregate(total=Sum('num'))
    total = sum_res["total"] or 0
    stat = SkuStock.get_by_sku(sku_id)
    if stat.return_quantity != total:
        stat.return_quantity = total
        stat.save(update_fields=['return_quantity'])
        stat.assign()
Exemplo n.º 5
0
def task_saleorder_update_productskustats_waitingpay_num(sku_id):
    """
    Recalculate and update post_num.
    """
    from flashsale.pay.models import SaleOrder

    product_id = ProductSku.objects.get(id=sku_id).product.id
    waitingpay_num_res = SaleOrder.objects.filter(
        item_id=product_id, sku_id=sku_id,
        status=SaleOrder.WAIT_BUYER_PAY).aggregate(Sum('num'))
    total = waitingpay_num_res['num__sum'] or 0
    stat = SkuStock.get_by_sku(sku_id)
    if stat.waitingpay_num != total:
        stat.waitingpay_num = total
        stat.save(update_fields=["waitingpay_num"])
Exemplo n.º 6
0
def task_update_product_sku_stat_rg_quantity(sku_id):
    from shopback.dinghuo.models.purchase_return import RGDetail, ReturnGoods
    logger.info("%s -sku_id:%s" % (get_cur_info(), sku_id))
    sum_res = RGDetail.objects.filter(
        skuid=sku_id,
        created__gte=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME,
        return_goods__status__in=[
            ReturnGoods.DELIVER_RG, ReturnGoods.REFUND_RG,
            ReturnGoods.SUCCEED_RG
        ],
        type=RGDetail.TYPE_REFUND).aggregate(total=Sum('num'))
    total = sum_res["total"] or 0
    stat = SkuStock.get_by_sku(sku_id)
    if stat.rg_quantity != total:
        stat.rg_quantity = total
        stat.save(update_fields=['rg_quantity'])
        stat.assign()
Exemplo n.º 7
0
def task_orderdetail_update_productskustats_inbound_quantity(instance):
    """
    Whenever we have products inbound, we update the inbound quantity.
    0) OrderDetail arrival_time add db_index=True
    1) we should build joint-index for (sku,arrival_time)?
    --Zifei 2016-04-18
    """
    from shopback.dinghuo.models import OrderDetail
    sku_id = instance.sku_id
    logger.info("%s -sku_id:%s" % (get_cur_info(), sku_id))
    sum_res = OrderDetail.objects.filter(chichu_id=sku_id,
                                         arrival_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME) \
        .aggregate(total=Sum('arrival_quantity'))
    total = sum_res["total"] or 0
    stat = SkuStock.get_by_sku(sku_id)
    stat.inbound_quantity = total
    stat.save(update_fields=['inbound_quantity', 'modified'])
    stat.assign(orderlist=instance.orderlist)
Exemplo n.º 8
0
def task_packageskuitem_update_productskustats(sku_id):
    """
    1) we added db_index=True for pay_time in packageskuitem;
    2) we should built joint-index for (sku_id, assign_status,pay_time)?
    -- Zifei 2016-04-18
    """
    from shopback.trades.models import PackageSkuItem
    logger.info("%s -sku_id:%s" % (get_cur_info(), sku_id))
    sum_res = PackageSkuItem.objects.filter(sku_id=sku_id, pay_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, type=0). \
        exclude(assign_status=PackageSkuItem.CANCELED).values("assign_status").annotate(total=Sum('num'))
    wait_assign_num, assign_num, post_num, third_assign_num = 0, 0, 0, 0

    for entry in sum_res:
        if entry["assign_status"] == PackageSkuItem.NOT_ASSIGNED:
            wait_assign_num = entry["total"]
        elif entry["assign_status"] == PackageSkuItem.ASSIGNED:
            assign_num = entry["total"]
        elif entry["assign_status"] == PackageSkuItem.FINISHED:
            post_num = entry["total"]
        elif entry['assign_status'] == PackageSkuItem.VIRTUAL_ASSIGNED:
            third_assign_num = entry["total"]
    sold_num = wait_assign_num + assign_num + post_num + third_assign_num
    params = {
        "sold_num": sold_num,
        "assign_num": assign_num,
        "post_num": post_num
    }
    klogger = logging.getLogger('service')
    klogger.info({
        'action': 'skustat.pstat.task_packageskuitem_update_productskustats',
        'sku_id': sku_id,
        'params': json.dumps(params),
    })
    stat = SkuStock.get_by_sku(sku_id)
    update_fields = []
    for k, v in params.iteritems():
        if hasattr(stat, k):
            if getattr(stat, k) != v:
                setattr(stat, k, v)
                update_fields.append(k)
    if update_fields:
        update_fields.append('modified')
        stat.save(update_fields=update_fields)
Exemplo n.º 9
0
 def sync_stock_by_adjust(self, data):
     """
         更新实时库存数据,如果数据不与skustock的数据一致,则将原记录/新记录/skustock数据都保存到stockadjust当中。
     :param data:
     :return:
     """
     from shopback.warehouse.models import StockAdjust, constants
     from shopback.items.models import SkuStock, ProductSku, InferiorSkuStats
     ori_dict = self.to_dict()
     self.pull_bad_qty = data['bad_qty']
     self.pull_good_available_qty = data['good_available_qty']
     self.pull_good_lock_qty = data['good_lock_qty']
     self.last_pull_time = datetime.datetime.now()
     self.save()
     now_dict = self.to_dict()
     sku = ProductSku.get_by_outer_id(self.sku_code)
     stock = SkuStock.get_by_sku(sku.id)
     inferior_sku_stats = InferiorSkuStats.get_by_sku(sku.id)
     # 正品数不同
     if self.now_quantity != stock.realtime_quantity:
         note = '%s实时库存不同,我方%d,对方%d。本次新数据%s~我仓数据%s~原数据%s' %\
                (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.now_quantity, stock.realtime_quantity, json.dumps(ori_dict, cls=CJsonEncoder),
                 json.dumps(stock.to_dict(), cls=CJsonEncoder), json.dumps(now_dict, cls=CJsonEncoder))
         delta = self.now_quantity - stock.realtime_quantity
         StockAdjust.create(None,
                            sku.id,
                            delta,
                            constants.WARE_NONE,
                            inferior=False,
                            note=note)
     # 次品数不同
     elif self.now_bad_quantity != inferior_sku_stats.realtime_quantity:
         note = '%s次品库存不同,我方%d,对方%d。本次对方数据%s~我方数据%s~上次对方数据%s' %\
                (datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), self.now_quantity, inferior_sku_stats.realtime_quantity, json.dumps(ori_dict, cls=CJsonEncoder),
                 json.dumps(now_dict, cls=CJsonEncoder), json.dumps(inferior_sku_stats.to_dict(), cls=CJsonEncoder))
         delta = self.now_bad_quantity - inferior_sku_stats.realtime_quantity
         StockAdjust.create(None,
                            sku.id,
                            delta,
                            constants.WARE_NONE,
                            inferior=True,
                            note=note)
Exemplo n.º 10
0
def task_shoppingcart_update_productskustats_shoppingcart_num(sku_id):
    """
    Recalculate and update shoppingcart_num.
    """
    from flashsale.pay.models import ShoppingCart
    try:
        # product_id = ProductSku.objects.get(id=sku_id).product.id
        shoppingcart_num_res = ShoppingCart.objects.filter(
            sku_id=sku_id, status=ShoppingCart.NORMAL).aggregate(Sum('num'))
        total = shoppingcart_num_res['num__sum'] or 0
        stat = SkuStock.get_by_sku(sku_id)
        if stat.shoppingcart_num != total:
            stat.shoppingcart_num = total
            stat.save(update_fields=["shoppingcart_num"])
    except IntegrityError as exc:
        logger.warn(
            "IntegrityError - productskustat/shoppingcart_num | sku_id: %s, shoppingcart_num: %s"
            % (sku_id, total))
        raise task_shoppingcart_update_productskustats_shoppingcart_num.retry(
            exc=exc)
Exemplo n.º 11
0
def task_product_upshelf_update_productskusalestats(sku_id):
    """
    Recalculate and update init_waitassign_num,sale_start_time.
    """
    from shopback.items.models import ProductSku, SkuStock, \
        ProductSkuSaleStats, gen_productsksalestats_unikey
    sku = ProductSku.objects.get(id=sku_id)
    product_id = sku.product_id
    sku_stats = SkuStock.get_by_sku(sku_id)
    wait_assign_num = sku_stats.wait_assign_num

    stats_uni_key = gen_productsksalestats_unikey(sku_id)
    stats = ProductSkuSaleStats.objects.filter(uni_key=stats_uni_key,
                                               sku_id=sku_id)

    if stats.count() == 0:
        model_product = sku.product.get_product_model()
        try:
            stat = ProductSkuSaleStats(
                uni_key=stats_uni_key,
                sku_id=sku_id,
                product_id=product_id,
                init_waitassign_num=wait_assign_num,
                sale_start_time=model_product.onshelf_time,
                sale_end_time=model_product.offshelf_time)
            stat.save()
        except IntegrityError as exc:
            logger.warn(
                "IntegrityError - productskusalestat/init_waitassign_num | sku_id: %s, init_waitassign_num: %s"
                % (sku_id, wait_assign_num))
            raise task_product_upshelf_update_productskusalestats.retry(
                exc=exc)
    else:
        logger.warn(
            "RepeatUpshelf- productskusalestat/init_waitassign_num | sku_id: %s, init_waitassign_num: %s"
            % (sku_id, wait_assign_num))
Exemplo n.º 12
0
    def multi_create(self, request, *args, **kwargs):
        """ 新增库存商品 新增款式
        {
          "qs_code": "",
          "products": [
            {
              "remain_num": "1",
              "agent_price": "4",
              "cost": "2",
              "name": "\u82e6\u4e01\u8336",
              "std_sale_price": "3"
            },
            {
              "remain_num": "1",
              "agent_price": "4",
              "cost": "2",
              "name": "\u5c71\u6942\u5e72",
              "std_sale_price": "3"
            },
            {
              "remain_num": "1",
              "agent_price": "4",
              "cost": "2",
              "name": "\u8377\u53f6\u8336",
              "std_sale_price": "3"
            }
          ],
          "name": "",
          "sale_time": "",
          "category_id": "19",
          "memo": "",
          "head_img": "",
          "saleproduct_id": "",
          "qhby_code": ""
        }
        """
        content = request.data
        creator = request.user
        saleproduct_id = content.get("saleproduct_id", "")
        products_data = content.get('products')
        saleproduct = SaleProduct.objects.filter(id=saleproduct_id).first()
        if not saleproduct:
            raise exceptions.APIException(u"选品ID错误")

        supplier = saleproduct.sale_supplier
        category_id = content.get("category_id", "")
        category_item = ProductCategory.objects.get(cid=category_id)
        category_maps = {
            3: '3',
            39: '3',
            6: '6',
            5: '9',
            52: '5',
            44: '7',
            8: '8',
            49: '4',
            10: '1'
        }
        if category_maps.has_key(category_item.parent_cid):
            outer_id = category_maps.get(category_item.parent_cid) + str(
                category_item.cid) + "%05d" % supplier.id
        elif category_item.cid == 9:
            outer_id = "100" + "%05d" % supplier.id
        else:
            raise exceptions.APIException(u"请选择正确分类")
        saleways = content.get("saleways")
        teambuy = False
        if saleways and (2 in saleways or '2' in saleways):
            teambuy = True
            teambuy_price = int(content.get("teambuy_price"))
        count = Product.objects.filter(
            outer_id__startswith=outer_id).count() or 1
        inner_outer_id = outer_id + "%03d" % count
        while True:
            product_ins = Product.objects.filter(
                outer_id__startswith=inner_outer_id).count()
            if not product_ins or count > 998:
                break
            count += 1
            inner_outer_id = outer_id + "%03d" % count

        if len(inner_outer_id) > 12:
            raise exceptions.APIException(u"编码位数不能超出12位")
        try:
            extras = default_modelproduct_extras_tpl()
            extras.setdefault('properties', {})
            for key, value in content.iteritems():
                if key.startswith('property.'):
                    name = key.replace('property.', '')
                    extras['properties'].update({name: value})
            is_flatten = False
            if len(products_data) == 1:
                skus_data = products_data[0].get('skus', [])
                if not skus_data or len(skus_data) == 1:
                    is_flatten = True

            # TODO@meron 考虑到亲子装问题,支持同一saleproduct录入多个modelproduct
            with transaction.atomic():
                model_pro = ModelProduct(
                    name=content['name'],
                    head_imgs=content['head_img'],
                    salecategory=saleproduct.sale_category,
                    saleproduct=saleproduct,
                    is_flatten=is_flatten,
                    lowest_agent_price=round(
                        min([float(p['agent_price']) for p in products_data]),
                        2),
                    lowest_std_sale_price=round(
                        min([
                            float(p['std_sale_price']) for p in products_data
                        ]), 2),
                    extras=extras,
                )
                if teambuy:
                    model_pro.is_teambuy = True
                    model_pro.teambuy_price = teambuy_price
                model_pro.save()
                log_action(creator.id, model_pro, ADDITION,
                           u'新建一个modelproduct new')
                pro_count = 1
                for color in content['products']:
                    # product除第一个颜色外, 其余的颜色的outer_id末尾不能为1
                    if (pro_count % 10) == 1 and pro_count > 1:
                        pro_count += 1

                    one_product = Product(
                        name=content['name'] + "/" + color['name'],
                        outer_id=inner_outer_id + str(pro_count),
                        model_id=model_pro.id,
                        sale_charger=creator.username,
                        category=category_item,
                        remain_num=color['remain_num'],
                        cost=color['cost'],
                        agent_price=color['agent_price'],
                        std_sale_price=color['std_sale_price'],
                        ware_by=supplier.ware_by,
                        pic_path=content['head_img'],
                        sale_product=saleproduct.id,
                        is_flatten=is_flatten,
                    )
                    one_product.save()
                    log_action(creator.id, one_product, ADDITION,
                               u'新建一个product_new')
                    pro_count += 1
                    # one_product_detail = Productdetail(
                    # product=one_product, material=material,
                    # color=content.get("all_colors", ""),
                    # wash_instructions=wash_instroduce, note=note
                    # )
                    # one_product_detail.save()

                    barcode = '%s%d' % (one_product.outer_id, 1)
                    one_sku = ProductSku(
                        outer_id=barcode,
                        product=one_product,
                        remain_num=color['remain_num'],
                        cost=color['cost'],
                        std_sale_price=color['std_sale_price'],
                        agent_price=color['agent_price'],
                        properties_name=color['name'],
                        properties_alias=color['name'],
                        barcode=barcode)
                    one_sku.save()
                    try:
                        SkuStock.get_by_sku(one_sku.id)
                    except Exception, exc:
                        logger.error('product skustats: new_sku_id=%s, %s' %
                                     (one_sku.id, exc.message),
                                     exc_info=True)

        except Exception, exc:
            logger.error('%s' % exc or u'商品资料创建错误', exc_info=True)
            raise exceptions.APIException(u'出错了:%s' % exc)
Exemplo n.º 13
0
 def assign_sku(self):
     from shopback.items.models import SkuStock
     for idetail in self.details.all():
         for r in idetail.records.all():
             SkuStock.get_by_sku(idetail.sku_id).assign(
                 orderlist=r.orderdetail.orderlist, again=False)
Exemplo n.º 14
0
 def set_stock_inbound(self):
     from shopback.items.models import SkuStock
     sku_dict = self.get_sku_instock_dict()
     for sku in sku_dict:
         stock = SkuStock.get_by_sku(sku)
         stock.add_inbound_quantity(sku, sku_dict[sku])
Exemplo n.º 15
0
def task_add_shoppingcart_num(instance):
    stat = SkuStock.get_by_sku(instance.sku_id)
    SkuStock.objects.filter(sku_id=stat.sku_id).update(
        shoppingcart_num=F('shoppingcart_num') + instance.num)
    return close_timeout_carts_and_orders_reset_cart_num([instance.sku_id])