class WXProduct(models.Model): UP_SHELF = 1 DOWN_SHELF = 2 UP_ACTION = 1 DOWN_ACTION = 0 PRODUCT_STATUS = ((UP_SHELF, u'上架'), (DOWN_SHELF, u'下架')) product_id = models.CharField(max_length=32, primary_key=True, verbose_name=u'商品ID') product_name = models.CharField(max_length=64, verbose_name=u'商品标题') product_img = models.CharField(max_length=512, verbose_name=u'商品图片') product_base = JSONCharMyField(max_length=3000, blank=True, default={}, verbose_name=u'图文信息') sku_list = JSONCharMyField(max_length=3000, blank=True, default={}, verbose_name=u'规格信息') attrext = JSONCharMyField(max_length=1000, blank=True, default={}, verbose_name=u'附加信息') delivery_info = JSONCharMyField(max_length=200, blank=True, default={}, verbose_name=u'发货信息') sync_stock = models.BooleanField(default=True, verbose_name=u'同步库存') status = models.IntegerField(null=False, default=0, choices=PRODUCT_STATUS, verbose_name=u'是否上架') modified = models.DateTimeField(auto_now=True, verbose_name=u'修改日期') created = models.DateTimeField(auto_now_add=True, verbose_name=u'创建日期') objects = WeixinProductManager() class Meta: db_table = 'shop_weixin_product' app_label = 'weixin' verbose_name = u'微信小店商品' verbose_name_plural = u'微信小店商品列表' def __unicode__(self): return u'<WXProduct:%s>' % (self.product_id)
class StockDailyReportItem(models.Model): report = models.ForeignKey(StockDailyReport) sku_id = models.IntegerField() sys_data = JSONCharMyField(max_length=5000, verbose_name=u'系统sku数据', help_text=u"") stat_data = JSONCharMyField(max_length=5000, verbose_name=u'统计sku数据', help_text=u"") class Meta: db_table = 'stat_stockdailyreportitem'
class DailyBoutiqueStat(BaseModel): """ 每日精品商品及券数量统计 规格统计数据结构: [ {'sku_id':somevalue,'sku_stock_num':0, 'sku_sale_num':0, 'sku_refund_num':0} ] """ model_id = models.IntegerField(verbose_name=u'款式ID') stat_date = models.DateField(default=datetime.date.today, db_index=True, verbose_name=u'业务日期') model_stock_num = models.IntegerField(default=0, db_index=True, verbose_name=u'商品库存数量') model_sale_num = models.IntegerField(default=0, db_index=True, verbose_name=u'商品销售数量') model_refund_num = models.IntegerField(default=0, db_index=True, verbose_name=u'商品退款数') coupon_sale_num = models.IntegerField(default=0, db_index=True, verbose_name=u'券销售数量') coupon_use_num = models.IntegerField(default=0, db_index=True, verbose_name=u'券使用数量') coupon_refund_num = models.IntegerField(default=0, db_index=True, verbose_name=u'退券数量') sku_stats = JSONCharMyField(max_length=2048, default=[], blank=False, verbose_name=u"规格统计") # TODO@MENTION 需要补充券销售额, 退券金额 class Meta: db_table = 'flashsale_daily_boutique_stat' unique_together = ['model_id', 'stat_date'] app_label = 'daystats' verbose_name = u'精品/每日销售数量统计' verbose_name_plural = u'精品/每日销售数量统计列表'
class OutwarePackageSku(BaseWareModel): """ 外仓实际发货包裹SKU """ package = models.ForeignKey(OutwarePackage, verbose_name=u'关联包裹') origin_skuorder_no = models.CharField(max_length=32, db_index=True, verbose_name=u'原始SKU订单编号', help_text=u'该字段存在争议暂不使用') sku_code = models.CharField(max_length=64, blank=True, db_index=True, verbose_name=u'内部SKU编号') batch_no = models.CharField(max_length=32, db_index=True, verbose_name=u'批次号') sku_qty = models.IntegerField(default=0, verbose_name=u'推送订单SKU数量') uni_key = models.CharField(max_length=128, unique=True, verbose_name=u'唯一标识') extras = JSONCharMyField(max_length=512, default={}, verbose_name=u'附加信息') class Meta: db_table = 'outware_packagesku' app_label = 'outware' verbose_name = u'外仓/出仓包裹sku' verbose_name_plural = u'外仓/出仓包裹sku' @classmethod def generate_unikey(self, sku_code, batch_no, package_id): return '{sku_code}-{package_id}-{batch_no}'.format( sku_code=sku_code, batch_no=batch_no, package_id=package_id)
class WeixinTplMsg(BaseModel): """ """ wx_template_id = models.CharField(max_length=255, verbose_name=u'微信模板ID') template_ids = JSONCharMyField(max_length=512, blank=True, default={}, verbose_name=u'模版ID集合') content = models.TextField(blank=True, null=True, verbose_name=u'模板内容') header = models.CharField(max_length=512, blank=True, null=True, verbose_name=u'模板消息头部') footer = models.CharField(max_length=512, blank=True, null=True, verbose_name=u'模板消息尾部') status = models.BooleanField(default=True, verbose_name=u"使用") class Meta: db_table = 'shop_weixin_template_msg' app_label = 'weixin' verbose_name = u'微信模板消息' verbose_name_plural = u'微信模板消息列表'
class DailySqlRecord(BaseModel): """ 查询sql记录保存 """ query_data = JSONCharMyField(max_length=5000, verbose_name=u'查询条件') uni_key = models.CharField(max_length=32, blank=False, unique=True, verbose_name=u'唯一标识') status = models.BooleanField(default=True, verbose_name=u'是否使用') class Meta: db_table = 'flashsale_daily_sqlrecord' app_label = 'daystats' verbose_name = u'每日统计/查询sql记录' verbose_name_plural = u'每日统计/查询sql记录' @classmethod def gen_unikey(cls, key_string): return hashlib.md5(key_string).hexdigest() @classmethod def normal_records(cls): return DailySqlRecord.objects.filter(status=True) def set_invalid(self): self.status = False
class ProductSkuContrast(models.Model): """ 商品规格尺寸参数 """ product = models.OneToOneField('items.Product', primary_key=True, related_name='contrast', verbose_name=u'商品ID') contrast_detail = JSONCharMyField(max_length=10240, blank=True, default=SKU_DEFAULT, verbose_name=u'对照表详情') created = models.DateTimeField(null=True, auto_now_add=True, blank=True, verbose_name=u'生成日期') modified = models.DateTimeField(null=True, auto_now=True, verbose_name=u'修改日期') class Meta: db_table = 'shop_items_productskucontrast' app_label = 'items' verbose_name = u'对照内容表' verbose_name_plural = u'对照内容表' @classmethod def format_contrast(cls, origin_contrast): result_data = {} constants_maps = ContrastContent.contrast_maps() for k1, v1 in origin_contrast.items(): temp_dict = {} for k2, v2 in v1.items(): content = constants_maps.get(k2, k2) temp_dict[content] = v2 result_data[k1] = temp_dict return result_data @property def get_correspond_content(self): return ProductSkuContrast.format_contrast(self.contrast_detail) def __unicode__(self): return '<%s,%s>' % (self.product_id, self.contrast_detail)
class BrandEntry(BaseModel): """ deprecated 专题活动入口 这个结构不再使用了""" PROMOTION_TOP10 = 1 PROMOTION_TOPIC = 2 PROMOTION_BRAND = 3 PROMOTION_CHOICES = ( (PROMOTION_TOP10, u'Top10'), (PROMOTION_TOPIC, u'专题'), (PROMOTION_BRAND, u'品牌'), ) id = models.AutoField(primary_key=True) brand_name = models.CharField(max_length=32, db_index=True, blank=True, verbose_name=u'专题名称') brand_desc = models.TextField(max_length=512, blank=True, verbose_name=u'专题活动描述') brand_pic = models.CharField(max_length=256, blank=True, verbose_name=u'品牌LOGO') brand_post = models.CharField(max_length=256, blank=True, verbose_name=u'专题海报') brand_applink = models.CharField(max_length=256, blank=True, verbose_name=u'专题APP协议链接') mask_link = models.CharField(max_length=256, blank=True, verbose_name=u'专题活动弹窗提示图') share_icon = models.CharField(max_length=128, blank=True, verbose_name=u'专题活动分享图片') share_link = models.CharField(max_length=256, blank=True, verbose_name=u'专题活动分享链接') promotion_type = models.IntegerField(choices=PROMOTION_CHOICES, default=PROMOTION_TOP10, db_index=True, verbose_name=u'专题活动类型') start_time = models.DateTimeField(blank=True, null=True, db_index=True, verbose_name=u'开始时间') end_time = models.DateTimeField(blank=True, null=True, verbose_name=u'结束时间') order_val = models.IntegerField(default=0, verbose_name=u'排序值') is_active = models.BooleanField(default=True, verbose_name=u'上线') extra_pic = JSONCharMyField(max_length=1024, blank=True, default=[], verbose_name=u'推广展示其它图片') class Meta: db_table = 'flashsale_brand_entry' app_label = 'pay' verbose_name = u'特卖/推广专题入口' verbose_name_plural = u'特卖/推广专题入口' def __unicode__(self): return u'<%s,%s>' % (self.id, self.brand_name) @classmethod def get_brand(cls): acts = cls.objects.filter(is_active=True) if acts.exists(): return acts return [] @classmethod def get_effect_brands(cls, btime): """ 根据时间获取活动列表 """ brands = cls.objects.filter(is_active=True, end_time__gte=btime) \ .order_by('-order_val', '-modified') if brands.exists(): return brands return cls.objects.none()
class Mamaexam(BaseModel): sheaves = models.IntegerField(db_index=True, verbose_name=u'考试轮数') start_time = models.DateTimeField(db_index=True, null=True, verbose_name=u'开放时间') expire_time = models.DateTimeField(db_index=True, null=True, verbose_name=u'结束时间') valid = models.BooleanField(db_index=True, default=False, verbose_name=u'是否有效') participant = models.IntegerField(choices=exam_participant_choice(), default=constants.XLMM_EXAM, verbose_name=u'目标用户') extras = JSONCharMyField(max_length=512, blank=True, null=True, default=default_mamaexam_extras, verbose_name=u"附加信息") def __unicode__(self): return '%s' % self.sheaves @property def single_point(self): return self.extras['single_point'] @property def multiple_point(self): return self.extras['multiple_point'] @property def judge_point(self): return self.extras['judge_point'] @property def past_point(self): return self.extras['past_point'] @property def upper_agencylevel(self): return self.extras['upper_agencylevel'] def get_question_type_point(self, question_type): if question_type == 1: return self.single_point if question_type == 2: return self.multiple_point if question_type == 3: return self.judge_point return 0 class Meta: db_table = 'flashsale_mmexam_sheaves' app_label = 'mmexam' verbose_name = u'代理考试轮数' verbose_name_plural = u'代理考试题目轮数列表'
class WareHouse(models.Model): """ 仓库 """ store_code = models.CharField(max_length=32, db_index=True, default='', verbose_name=u'仓库编码', help_text='后面应改为unique') ware_name = models.CharField(max_length=32, blank=True, verbose_name=u'仓库名') manager = models.CharField(max_length=16, blank=True, verbose_name='负责人') province = models.CharField(max_length=32, blank=True, verbose_name=u'所在省') city = models.CharField(max_length=32, blank=True, verbose_name=u'所在城市') district = models.CharField(max_length=32, blank=True, verbose_name=u'所在区/县') address = models.CharField(max_length=256, blank=True, verbose_name=u'详细地址') mobile = models.CharField(max_length=11, blank=True, verbose_name=u'手机') phone = models.CharField(max_length=11, blank=True, verbose_name=u'电话') ware_source = models.CharField(max_length=16, default='', choices=constants.SOURCE_CHOICES, verbose_name=u'仓库所属') # TYPE_CHOICES = ( # ("normal", u"普通仓库"), # ("bonded", u'保税仓库'), # ("direct", u'直邮仓库'), # ) # declare_type = models.CharField(choices=TYPE_CHOICES, default=0, max_length=64, verbose_name=u"类型") in_active = models.BooleanField(default=True, verbose_name=u'有效') extra_info = models.TextField(blank=True, verbose_name=u'备注') extras = JSONCharMyField(max_length=512, default={}, verbose_name='附加信息') class Meta: db_table = 'shop_ware_house' app_label = 'warehouse' verbose_name = u'仓库' verbose_name_plural = u'仓库列表' def __unicode__(self): return smart_unicode(self.ware_name) @classmethod def get_fengchao_warehouses(cls): return cls.objects.filter(ware_source=constants.SOURCE_FENGCHAO, in_active=True) @property def is_fengchao_warehouse(self): return self.SOURCE_FENGCHAO == constants.SOURCE_FENGCHAO
class BankAccount(models.Model): """ 是否考虑可被供应商使用? """ NORMAL = 0 DELETE = 1 STATUS_CHOICES = ( (NORMAL, u'正常'), (DELETE, u'作废'), ) user = models.ForeignKey('auth.user', verbose_name='所属用户') account_no = models.CharField(max_length=32, verbose_name='银行卡账号') account_name = models.CharField(max_length=32, verbose_name='银行卡持有人名称') bank_name = models.CharField(max_length=32, verbose_name='银行全称') created = models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='创建时间') modified = models.DateTimeField(auto_now=True, verbose_name='创建时间') default = models.BooleanField(default=False, verbose_name='默认使用') status = models.SmallIntegerField(default=NORMAL, choices=STATUS_CHOICES, db_index=True, verbose_name='状态') # uni_key = models.CharField(max_length=96, unique=True, verbose_name='唯一键') extras = JSONCharMyField(max_length=512, default={}, verbose_name='附加信息') class Meta: db_table = 'flashsale_bankaccount' app_label = 'pay' verbose_name = u'用户/银行卡' verbose_name_plural = u'用户/银行卡' @classmethod def gen_uni_key(cls, account_no, account_name, user_id): return '{}-{}-{}'.format(account_no, account_name, user_id) def set_invalid(self): self.status = self.DELETE self.save() if self.default: first_card = BankAccount.objects.filter( user=self.user, status=self.NORMAL).first() if first_card: first_card.set_default() def set_default(self): self.default = True self.save() user_banks = BankAccount.objects.filter( user=self.user, status=self.NORMAL).exclude(id=self.id) if user_banks.exists(): user_banks.update(default=False)
class PreferencePool(BaseModel): name = models.CharField(max_length=64, verbose_name=u'参数名称') unit = models.CharField(max_length=32, blank=True, verbose_name=u'单位') is_sku = models.BooleanField(default=False, verbose_name=u'是否是sku属性') categorys = JSONCharMyField(max_length=512, default=[], verbose_name=u'包含类别', help_text=u'哪些类别(保存id列表)包含本参数') preference_value = JSONCharMyField(max_length=10240, default=[], verbose_name=u"参数值") class Meta: db_table = 'supplychain_preference_pool' app_label = 'supplier' verbose_name = u'特卖/产品资料参数表' verbose_name_plural = u'特卖/产品资料参数列表' def __unicode__(self): return '<%s-%s>' % (self.id, self.name)
class Credential(BaseModel): order_no = models.CharField(max_length=64, blank=False, verbose_name=u'商家订单号') channel = models.CharField(max_length=16, choices=ChargeOrder.CHANNEL_CHOICES, blank=False, verbose_name=u'支付渠道') extra = JSONCharMyField(max_length=1024, default={}, verbose_name=u'渠道凭证') class Meta: db_table = 'xiaolupay_credential' unique_together = ["order_no", "channel"] app_label = 'xiaolupay' verbose_name = u'小鹿支付/凭证' verbose_name_plural = u'小鹿支付/凭证列表'
class OutwareOrderSku(BaseWareModel): """ 实际推送给外仓的组合销售订单sku """ outware_account = models.ForeignKey('outware.OutwareAccount', verbose_name=u'关联账号') union_order_code = models.CharField(max_length=64, blank=True, db_index=True, verbose_name=u'关联组合订单编号') origin_skuorder_no = models.CharField(max_length=32, db_index=True, verbose_name=u'原始SKU订单编号') sku_code = models.CharField(max_length=64, blank=True, db_index=True, verbose_name=u'内部SKU编号') sku_qty = models.IntegerField(default=0, verbose_name=u'推送订单SKU数量') is_valid = models.BooleanField(default=True, db_index=True, verbose_name=u'是否有效') uni_key = models.CharField(max_length=128, unique=True, verbose_name=u'唯一标识') extras = JSONCharMyField(max_length=1024, default={}, verbose_name=u'附加信息') class Meta: db_table = 'outware_ordersku' app_label = 'outware' verbose_name = u'外仓/推送订单sku' verbose_name_plural = u'外仓/推送订单sku' @classmethod def generate_unikey(self, account_id, origin_skuorder_no): return '{origin_skuorder_no}-{account_id}'.format( origin_skuorder_no=origin_skuorder_no, account_id=account_id) def set_invalid(self): self.is_valid = False def set_valid(self): self.is_valid = True @property def is_reproducible(self): return self.is_valid == False
class ProductBrand(BaseModel): """ 商品品牌 """ brand_name = models.CharField(max_length=64, unique=True, blank=True, verbose_name=u'品牌名称(国内)') brand_desc = models.TextField(blank=True, null=True, verbose_name=u'品牌简介') extras= JSONCharMyField(max_length=1024, blank=True, default={}, verbose_name=u'附加信息') class Meta: db_table = 'flashsale_product_brand' app_label = 'pay' verbose_name = u'特卖/商品品牌' verbose_name_plural = u'特卖/商品品牌' def __unicode__(self): return u'<%s,%s>' % (self.id, self.brand_name)
class WeixinFans(BaseModel): openid = models.CharField(max_length=32, verbose_name=u'OPENID') app_key = models.CharField(max_length=24, verbose_name=u'APPKEY') unionid = models.CharField(max_length=32, verbose_name=u'UNIONID') subscribe = models.BooleanField(default=False, verbose_name=u"订阅该号") subscribe_time = models.DateTimeField(blank=True, null=True, verbose_name=u"订阅时间") unsubscribe_time = models.DateTimeField(blank=True, null=True, verbose_name=u"取消订阅时间") extras = JSONCharMyField(max_length=512, default={'qrscene': '0'}, verbose_name=u'额外参数') class Meta: db_table = 'shop_weixin_fans' unique_together = [('unionid', 'app_key')] index_together = [('openid', 'app_key')] app_label = 'weixin' verbose_name = u'微信公众号粉丝' verbose_name_plural = u'微信公众号粉丝列表' @classmethod def get_openid_by_unionid(cls, unionid, app_key): """ 没关注也返回 None """ fans = cls.objects.filter(unionid=unionid, app_key=app_key, subscribe=True).first() if fans: return fans.openid else: return None @classmethod def get_unionid_by_openid_and_appkey(cls, openid, app_key): fans = cls.objects.filter(openid=openid, app_key=app_key, subscribe=True).first() if fans: return fans.unionid return None def set_qrscene(self, qrscene, force_update=False): if not self.extras: self.extras = {} if not self.get_qrscene() or force_update: self.extras['qrscene'] = qrscene.strip() def get_qrscene(self): qrscene = self.extras.get('qrscene') if qrscene and (not qrscene.isdigit()): # 如果是订单编号,仍然返回空。 return '' if qrscene == '0' or qrscene == 0: return '' return qrscene
class FengchaoOrderChannel(BaseModel): CHANNEL_TYPE_CHOICES = ( ('1', '淘宝'), ('2', '天猫'), ('7', '京东商城'), ('11', '亚马逊'), ('12', '一号店'), ('13', '国美商城'), ('14', '苏宁'), ('15', '阿里巴巴'), ('16', '当当网'), ('17', 'eBay'), ('18', '唯品会'), ('19', '聚美优品'), ('20', '自有商城'), ('32', '蜜芽'), ('33', 'JD全球售'), ) channel_id = models.CharField(max_length=16, unique=True, verbose_name=u'销售渠道 ID') channel_name = models.CharField(max_length=16, db_index=True, verbose_name=u'销售渠道名字') channel_type = models.CharField(max_length=16, db_index=True, choices=CHANNEL_TYPE_CHOICES, verbose_name=u'渠道类型') channel_client_id = models.CharField(max_length=16, db_index=True, verbose_name=u'销售渠道商家代码') status = models.BooleanField(default=False, verbose_name='更新状态') extras = JSONCharMyField(max_length=512, default={}, verbose_name=u'附加信息') class Meta: db_table = 'fengchao_orderchannnel' app_label = 'fengchao' verbose_name = u'外仓/蜂巢订单来源渠道' verbose_name_plural = u'外仓/蜂巢订单来源渠道' @classmethod def get_default_channel(cls): return cls.objects.first()
class MamaVebViewConf(BaseModel): version = models.CharField(max_length=32, db_index=True, verbose_name=u'版本号') is_valid = models.BooleanField(db_index=True, default=False, verbose_name=u'是否有效') extra = JSONCharMyField(max_length=2048, default={}, blank=True, null=True, verbose_name=u'配置内容') class Meta: db_table = 'flashsale_xlmm_webview_config' app_label = 'xiaolumm' verbose_name = u'客户端妈妈页面配置表' verbose_name_plural = u'客户端妈妈页面配置列表'
class IntegralLog(PayBaseModel): """ 记录用户积分的使用情况 """ CONFIRM = 1 CANCEL = 0 PENDING = 2 INTEGRAL_STATUS = ((CONFIRM, u'已确定'), (CANCEL, u'已取消'), (PENDING, u'待确定')) ORDER_INTEGRA = 1 LOG_TYPE = ((ORDER_INTEGRA, u'订单积分'), ) LOG_IN = 1 LOG_OUT = 0 IN_OUT = ((LOG_IN, u'增加积分'), (LOG_OUT, u"减少积分")) integral_user = models.BigIntegerField(null=False, db_index=True, verbose_name=u"用户ID") order_id = models.BigIntegerField(null=False, db_index=True, verbose_name=u"订单ID") mobile = models.CharField(max_length=11, db_index=True, blank=True, verbose_name=u'手机') log_value = models.IntegerField(default=0, verbose_name=u'记录积分值') log_status = models.IntegerField(choices=INTEGRAL_STATUS, verbose_name=u'记录状态') log_type = models.IntegerField(choices=LOG_TYPE, verbose_name=u'积分类型') in_out = models.IntegerField(choices=IN_OUT, verbose_name=u'积分收支') order = JSONCharMyField(max_length=10240, blank=True, default={}, verbose_name=u'订单信息') class Meta: unique_together = ('integral_user', 'order_id') db_table = "sale_user_integral_log" app_label = 'pay' verbose_name = u"特卖用户/积分记录表" verbose_name_plural = u"特卖用户/积分记录列表" def __unicode__(self): return '<%s-%s>' % (self.id, self.order_id)
class CategoryPreference(BaseModel): category = models.ForeignKey('supplier.SaleCategory', related_name='category_pool_preference', verbose_name=u'类别') preferences = JSONCharMyField(max_length=1024, default=[], verbose_name=u"参数选项") is_default = models.BooleanField(default=False, verbose_name=u'设为默认') class Meta: db_table = 'supplychain_category_preference_conf' app_label = 'supplier' verbose_name = u'特卖/产品类别参数配置表' verbose_name_plural = u'特卖/产品类别参数配置列表' def __unicode__(self): return '<%s-%s-%s>' % (self.id, self.category.__unicode__(), self.category.id) def get_preferences(self): return list(set(self.preferences + [1, 2]))
class XlmmTeamEffScore(BaseModel): mama_id = models.IntegerField(null=True, db_index=True) member_ids = JSONCharMyField(max_length=5120, default={}, blank=True, verbose_name=u'活动数据') score = models.IntegerField(default=0, verbose_name=u'评分') stat_time = models.DateTimeField(verbose_name=u'统计时间') class Meta: db_table = 'xiaolumm_xlmmteameffscore' unique_together = ('mama_id', 'stat_time') app_label = 'xiaolumm' verbose_name = u'小鹿妈妈真实性团队评分' verbose_name_plural = u'小鹿妈妈真实性团队评分列表' @staticmethod def generate(mama_ids, stat_time=None): if not stat_time: stat_time = datetime.datetime.now() mama_dict = ReferalRelationship.get_referal_dict(mama_ids) xres = {x.id: x for x in XlmmEffectScore.objects.all()} scores = [] for mama_id in mama_dict: x = XlmmTeamEffScore( mama_id=mama_id, member_ids=mama_dict[mama_id], #score=XlmmEffectScore.objects.filter(mama_id__in=mama_dict.get(mama_id, [])).aggregate(t=Sum('score')).get('t') or 0, score=sum([xres[id].score for id in mama_dict[mama_id] if id in xres]) if mama_dict[mama_id] else 0, stat_time=stat_time ) scores.append(x) XlmmTeamEffScore.objects.bulk_create(scores) @staticmethod def batch_generate(stat_time=None): if not stat_time: stat_time = datetime.datetime.now() condition = {} # mama_ids = XiaoluMama.objects.filter(**condition).values_list('id',flat=True) mama_ids = XlmmEffectScore.objects.values_list('mama_id', flat=True) XlmmTeamEffScore.generate(mama_ids, stat_time)
class OutwareInboundSku(BaseWareModel): outware_inboind = models.ForeignKey(OutwareInboundOrder, verbose_name=u'关联推送入仓单') sku_code = models.CharField(max_length=64, db_index=True, verbose_name=u'内部SKU编号') batch_no = models.CharField(max_length=32, db_index=True, verbose_name=u'批次号') push_qty = models.IntegerField(default=0, verbose_name=u'入仓创建数量') pull_good_qty = models.IntegerField(default=0, verbose_name=u'外仓入仓良品数') pull_bad_qty = models.IntegerField(default=0, verbose_name=u'外仓入仓次品数') uni_key = models.CharField(max_length=128, unique=True, verbose_name=u'唯一标识') extras = JSONCharMyField(max_length=1024, default={}, verbose_name=u'附加信息') #商品的基础资料及款式信息 class Meta: db_table = 'outware_inboundsku' app_label = 'outware' verbose_name = u'外仓/推送入仓SKU' verbose_name_plural = u'外仓/推送入仓SKU' def __unicode__(self): return '<inbound_id:%s, %s>' % (self.outware_inboind_id, self.sku_code) @classmethod def generate_unikey(self, inbound_id, sku_code, batch_no): return '{batch_no}-{sku_code}-{inbound_id}'.format( inbound_id=inbound_id, sku_code=sku_code, batch_no=batch_no, )
class TweetAdvertorial(models.Model): title = models.CharField(max_length=128, db_index=True, verbose_name=u'推文标题') content = models.TextField(max_length=6400, verbose_name=u'推文文字内容') pic_arry = JSONCharMyField(max_length=6400, default={}, null=True, blank=True, verbose_name=u'推文图片') release_date = models.DateField(blank=True, null=True, verbose_name=u"投放日期") class Meta: db_table = 'flashsale_xlmm_tweet' app_label = 'xiaolumm' verbose_name = u'分享推文表' verbose_name_plural = u'分享推文列表' def __unicode__(self): return u'<%s,%s>' % (self.id, self.title)
class OutwareSupplier(BaseWareModel): outware_account = models.ForeignKey('outware.OutwareAccount', verbose_name=u'关联账号') vendor_code = models.CharField(max_length=64, blank=True, db_index=True, verbose_name=u'供应商编号') vendor_name = models.CharField(max_length=64, blank=True, db_index=True, verbose_name=u'供应商名称') uni_key = models.CharField(max_length=128, unique=True, verbose_name=u'唯一标识') extras = JSONCharMyField(max_length=1024, default={}, verbose_name=u'附加信息') class Meta: db_table = 'outware_supplier' app_label = 'outware' verbose_name = u'外仓/对接供应商' verbose_name_plural = u'外仓/对接供应商' def __unicode__(self): return '<%s, %s>' % (self.id, self.vendor_code) @classmethod def generate_unikey(cls, account_id, vdr_code): return '{vendor_code}-{account_id}'.format(vendor_code=vdr_code, account_id=account_id) @property def is_pushed_ok(self): return self.is_action_success(constants.ACTION_SUPPLIER_CREATE['code'])
class OutwarePackage(BaseWareModel): """ 外仓实际发货包裹(含销售订单/退仓单) """ PACKAGE_TYPE_CHOICES = ( (s['code'], s['name']) for s in [constants.ORDER_SALE, constants.ORDER_RETURN]) outware_account = models.ForeignKey('outware.OutwareAccount', verbose_name=u'关联账号') package_type = models.IntegerField(db_index=True, choices=PACKAGE_TYPE_CHOICES, verbose_name=u'包裹类型') package_order_code = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=u'销单/退仓单编号') store_code = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=u'外部仓库编号') logistics_no = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=u'快递单号') carrier_code = models.CharField(max_length=20, blank=True, db_index=True, verbose_name=u'快递公司编码') uni_key = models.CharField(max_length=128, unique=True, verbose_name=u'唯一标识') extras = JSONCharMyField(max_length=512, default={}, verbose_name=u'附加信息') class Meta: db_table = 'outware_package' app_label = 'outware' verbose_name = u'外仓/出仓包裹' verbose_name_plural = u'外仓/出仓包裹' @classmethod def generate_unikey(self, account_id, logistics_no, carrier_code): return '{logistics_no}-{carrier_code}-{account_id}'.format( logistics_no=logistics_no, carrier_code=carrier_code, account_id=account_id) def get_sku_dict(self): return { skuitem.sku_code: skuitem.sku_qty for skuitem in self.outwarepackagesku_set.all() } @property def mall_order_code(self): return OutwareOrder.parse_order_code( self.package_order_code, prefix=self.outware_account.order_prefix) @staticmethod def create_by_push_info(order_code, order_type, dict_obj): """ 包含普通订单/退仓单出仓确认 """ from shopback.outware.models import OutwareAccount, OutwareOrder ware_account = OutwareAccount.get_fengchao_account() ow_packages = [] with transaction.atomic(): for package in dict_obj.packages: # firstly, update outware package status and sku qty ow_package, state = OutwarePackage.objects.get_or_create( outware_account=ware_account, carrier_code=package.carrier_code, logistics_no=package.logistics_no, package_type=order_type, uni_key=OutwarePackage.generate_unikey( ware_account.id, package.logistics_no, package.carrier_code)) # # 忽略重复单 if not state: continue ow_package.package_order_code = order_code ow_package.store_code = package.store_code ow_package.save() for item in package.package_items: OutwarePackageSku.objects.create( package=ow_package, sku_code=item.sku_code, batch_no=item.batch_no, sku_qty=item.sku_qty, uni_key=OutwarePackageSku.generate_unikey( item.sku_code, item.batch_no, ow_package.id)) ow_packages.append(ow_package) ow_packages = runner.get_runner(order_type)(ow_packages).execute() try: # 更新outware_order status outware_order = OutwareOrder.objects.get( union_order_code=order_code, order_source=constants.ORDER_SALE['code']) outware_order.change_order_status(constants.SENDED) except Exception, exc: logger.error(str(exc), exc_info=True) return ow_packages
class OutwareOrder(BaseWareModel): """ 实际推送给外仓的组合销售订单 """ DEFAULT_ORDER_TYPE = constants.SOURCE_TYPE_USUAL['code'] ORDER_TYPE_CHOICES = ((s['code'], s['name']) for s in [ constants.SOURCE_TYPE_USUAL, constants.SOURCE_TYPE_CROSSBOADER, constants.SOURCE_TYPE_BOOKING, ]) DEFAULT_ORDER_SOURCE = constants.ORDER_SALE['code'] ORDER_SOURCE_CHOICES = ((s['code'], s['name']) for s in [ constants.ORDER_RETURN, constants.ORDER_SALE, ]) outware_account = models.ForeignKey('outware.OutwareAccount', verbose_name=u'关联账号') order_type = models.IntegerField(db_index=True, choices=ORDER_TYPE_CHOICES, default=DEFAULT_ORDER_TYPE, verbose_name=u'订单类型') order_source = models.IntegerField(db_index=True, choices=ORDER_SOURCE_CHOICES, default=DEFAULT_ORDER_SOURCE, verbose_name=u'订单来源') store_code = models.CharField(max_length=32, blank=True, db_index=True, verbose_name=u'外部仓库编号') union_order_code = models.CharField(max_length=64, blank=True, db_index=True, verbose_name=u'组合订单编号') status = models.SmallIntegerField(db_index=True, default=constants.NORMAL, choices=constants.STATUS_CHOICES, verbose_name='订单状态') state = models.IntegerField(default=constants.NORMAL, choices=constants.STATE_CHOICES, verbose_name='外仓订单状态') uni_key = models.CharField(max_length=128, unique=True, verbose_name=u'唯一标识') extras = JSONCharMyField(max_length=1024, default={}, verbose_name=u'附加信息') class Meta: db_table = 'outware_order' app_label = 'outware' verbose_name = u'外仓/推送订单' verbose_name_plural = u'外仓/推送订单' @classmethod def generate_unikey(cls, account_id, order_code, order_type): return '{order_code}-{order_type}-{account_id}'.format( order_code=order_code, order_type=order_type, account_id=account_id) @staticmethod def format_order_code(order_code, prefix=''): if type(order_code) in (str, unicode) and order_code.startswith(prefix): return order_code return '{}{}'.format(prefix, order_code) @staticmethod def parse_order_code(order_code, prefix=''): return order_code.lstrip(prefix) @property def order_skus(self): return OutwareOrderSku.objects.filter( union_order_code=self.union_order_code, is_valid=True) @property def is_reproducible(self): return self.status in (constants.NORMAL, constants.CANCEL) def change_order_status(self, status_code): self.status = status_code self.save() if status_code == constants.CANCEL: for order_sku in self.order_skus: order_sku.set_invalid() order_sku.save() def change_order_state(self, state_code): self.state = state_code self.save()
class Lesson(BaseModel): STATUS_EFFECT = 1 STATUS_FINISHED = 2 STATUS_CANCELED = 3 STATUS_TYPES = ((STATUS_EFFECT, u'有效'), (STATUS_FINISHED, u'已完成'), (STATUS_CANCELED, u'取消')) lesson_topic_id = models.IntegerField(default=0, db_index=True, verbose_name=u'课程主题ID') title = models.CharField(max_length=128, blank=True, verbose_name=u'课程主题') description = models.TextField(max_length=512, blank=True, verbose_name=u'课程描述') content_link = models.CharField(max_length=256, blank=True, verbose_name=u'内容链接') instructor_id = models.IntegerField(default=0, db_index=True, verbose_name=u'讲师ID') instructor_name = models.CharField(max_length=32, blank=True, verbose_name=u'讲师昵称') instructor_title = models.CharField(max_length=64, blank=True, verbose_name=u'讲师头衔') instructor_image = models.CharField(max_length=256, blank=True, verbose_name=u'讲师头像') num_attender = models.IntegerField(default=0, verbose_name=u'总听课人数') effect_num_attender = models.IntegerField(default=0, verbose_name=u'有效听课人数') num_score = models.IntegerField(default=0, verbose_name=u'课程评分') start_time = models.DateTimeField(db_index=True, blank=True, null=True, verbose_name=u'开始时间') # at most 10 qrcode_links qrcode_links = JSONCharMyField(max_length=1024, default={}, blank=True, verbose_name=u'群二维码链接') # uni_key: lesson_topic_id + instructor_id + start_time uni_key = models.CharField(max_length=128, blank=True, unique=True, verbose_name=u'唯一ID') status = models.IntegerField(db_index=True, default=1, choices=STATUS_TYPES, verbose_name=u'状态') class Meta: db_table = 'flashsale_xlmm_lesson' app_label = 'xiaolumm' verbose_name = u'小鹿大学/课程' verbose_name_plural = u'小鹿大学/课程列表' def __unicode__(self): return "%s:%s:%s" % (self.title, self.instructor_name, self.start_time) @property def status_display(self): return get_choice_name(Lesson.STATUS_TYPES, self.status) @property def start_time_display(self): year = self.start_time.year month = self.start_time.month day = self.start_time.day hour = self.start_time.hour minute = self.start_time.minute return "%02d月%02d日 %02d:%02d" % (month, day, hour, minute) @property def is_started(self): qrcode_release_time = self.start_time - datetime.timedelta(minutes=30) if datetime.datetime.now( ) > qrcode_release_time and self.status == Lesson.STATUS_EFFECT: return 1 return 0 @property def m_static_url(self): return settings.M_STATIC_URL def carry(self): base_carry = 3000 # 6000 cents == 60RMB if self.effect_num_attender >= 100: base_carry = 6000 if self.effect_num_attender >= 300: base_carry = 8000 if self.effect_num_attender >= 400: base_carry = 10000 return base_carry def customer_idx(self): return None def is_canceled(self): return self.status == Lesson.STATUS_CANCELED def is_confirmed(self): return self.status == Lesson.STATUS_FINISHED @classmethod def create_instruct_lesson(cls, lesson_topic_id, title, description, content_link, instructor_id, instructor_name, instructor_title, instructor_image, start_time, uni_key, status): lesson = cls.objects.filter(uni_key=uni_key).first() if lesson: return lesson lesson = cls(lesson_topic_id=lesson_topic_id, title=title, description=description, content_link=content_link, instructor_id=instructor_id, instructor_name=instructor_name, instructor_title=instructor_title, instructor_image=instructor_image, start_time=start_time, uni_key=uni_key, status=status) lesson.save() return lesson
class StockDailyReport(models.Model): stat_time = models.DateTimeField(auto_now=True) stat_sku_cnt = models.IntegerField(default=0) err_skus = JSONCharMyField(default=[], max_length=10000, verbose_name=u'出错sku列表', help_text=u"") class Meta: db_table = 'stat_stockdailyreport' @staticmethod def create(): sdr = StockDailyReport() sdr.save() queryset = SkuStock.objects.filter(status=0).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0) sdr.stat_sku_cnt = queryset.count() check_ids = StockDailyReport.check_all() for stock in SkuStock.objects.filter(sku_id__in=check_ids): ori_dict = copy(stock.to_dict()) stat = stock.restat() stat_dict = stock.to_dict() if stat: sdr.err_skus.append(stock.sku_id) StockDailyReportItem(report=sdr, sku_id=stock.sku_id, sys_data=ori_dict, stat_data=stat_dict).save() sdr.save() return sdr def screenshot(self, ids): check_ids = StockDailyReport queryset = SkuStock.objects.filter(status=0).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0) self.stat_sku_cnt = queryset.count() for stock in queryset.all(): ori_dict = copy(stock.to_dict()) stat = stock.restat() stat_dict = stock.to_dict() if stat: self.err_skus.append(stock.sku_id) StockDailyReportItem(report=self, sku_id=stock.sku_id, sys_data=ori_dict, stat_data=stat_dict).save() self.save() @staticmethod def check_all(): res = StockDailyReport.check_assign_num() res.extend(StockDailyReport.check_inbound_quantity()) res.extend(StockDailyReport.check_sold_num()) res.extend(StockDailyReport.check_post_num()) res.extend(StockDailyReport.check_adjust_quantity()) res.extend(StockDailyReport.check_rg_quantity()) res.extend(StockDailyReport.check_shoppingcart_num()) res.extend(StockDailyReport.check_waitingpay_num()) res.extend(StockDailyReport.check_paid_num()) res.extend(StockDailyReport.check_return_quantity()) for status in ('paid', 'prepare_book', 'booked', 'third_send', 'assigned', 'merged', 'waitscan', 'waitpost', 'sent', 'finish'): res.extend(StockDailyReport.check_psi_status_num(status)) return list(set(res)) @staticmethod def check_assign_num(sku_ids=[]): err_skus = set([]) condition = {'status': 0, 'product__type': 0} if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.assign_num for p in queryset.all()} condition2 = { 'type__in': [ PSI_TYPE.NORMAL, PSI_TYPE.BYHAND, PSI_TYPE.RETURN_GOODS, PSI_TYPE.TIANMAO ], 'pay_time__gt': SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, 'assign_status': 2 } if sku_ids: condition2['sku_id__in'] = sku_ids res = PackageSkuItem.objects.filter( pay_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, assign_status=1).values('sku_id').annotate(total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_inbound_quantity(sku_ids=[]): from shopback.dinghuo.models import OrderDetail err_skus = set([]) condition = {'status': 0, 'product__type': 0} if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.inbound_quantity for p in queryset.all()} res = OrderDetail.objects.filter( arrival_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME).values( 'chichu_id').annotate(total=Sum('arrival_quantity')) OrderDetail.objects.filter( arrival_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME).aggregate( total=Sum('arrival_quantity')) res = {int(k['chichu_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_sold_num(sku_ids=[]): from flashsale.pay.models import SaleOrder err_skus = set([]) condition = {'status': 0, 'product__type__in': [0, 1]} if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.sold_num for p in queryset.all()} res = PackageSkuItem.objects.filter( type=PSI_TYPE.NORMAL, pay_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, assign_status__in=[2, 0, 1, 4]).values('sku_id').annotate(total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} virtual_sku_ids = list( ProductSku.objects.filter(id__in=sku_ids_dict.keys(), product__type=1).values_list('id', flat=True)) res2 = SaleOrder.objects.filter( sku_id__in=virtual_sku_ids, status__in=[2, 3, 4, 5], pay_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME).values( 'sku_id').annotate(total=Sum('num')) res2 = {int(k['sku_id']): k['total'] for k in res2} res.update(res2) for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_post_num(sku_ids=[]): err_skus = set([]) condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.post_num for p in queryset.all()} condition2 = { 'type__in': [ PSI_TYPE.NORMAL, PSI_TYPE.TIANMAO, PSI_TYPE.BYHAND, PSI_TYPE.RETURN_GOODS ], 'pay_time__gt': SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, 'assign_status': 2 } if sku_ids: condition2['sku_id__in'] = sku_ids res = PackageSkuItem.objects.filter( **condition2).values('sku_id').annotate(total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_adjust_quantity(sku_ids=[]): from shopback.warehouse.models import StockAdjust err_skus = set([]) condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.adjust_quantity for p in queryset.all()} res = StockAdjust.objects.filter(status=1).values('sku_id').annotate( total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_rg_quantity(sku_ids=[]): from shopback.dinghuo.models import OrderDetail, RGDetail, ReturnGoods err_skus = set([]) condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.rg_quantity for p in queryset.all()} res = RGDetail.objects.filter( created__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, return_goods__status__in=[ ReturnGoods.DELIVER_RG, ReturnGoods.REFUND_RG, ReturnGoods.SUCCEED_RG ], type=RGDetail.TYPE_REFUND).values('skuid').annotate( total=Sum('num')) res = {int(k['skuid']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_shoppingcart_num(sku_ids=[]): from flashsale.pay.models import ShoppingCart err_skus = set([]) condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.shoppingcart_num for p in queryset.all()} res = ShoppingCart.objects.filter( status=ShoppingCart.NORMAL).values('sku_id').annotate( total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_waitingpay_num(sku_ids=[]): from flashsale.pay.models import SaleOrder err_skus = set([]) condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0, waitingpay_num=0) sku_ids_dict = {p.sku_id: p.waitingpay_num for p in queryset.all()} res = SaleOrder.objects.filter( status=SaleOrder.WAIT_BUYER_PAY).values('sku_id').annotate( total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_paid_num(sku_ids=[]): from flashsale.pay.models import SaleOrder err_skus = set([]) condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0, paid_num=0) sku_ids_dict = {p.sku_id: p.paid_num for p in queryset.all()} res = SaleOrder.objects.filter( status__in=[2, 3, 4, 5], created__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME).values( 'sku_id').annotate(total=Sum('num')) SaleOrder.objects.filter( sku_id=296989, status__in=[2, 3, 4, 5], created__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME).values( 'sku_id').annotate(total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_return_quantity(sku_ids=[]): from shopback.refunds.models import RefundProduct err_skus = set([]) condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: p.return_quantity for p in queryset.all()} res = RefundProduct.objects.filter( created__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, can_reuse=True).exclude(sku_id=None).values('sku_id').annotate( total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus) @staticmethod def check_psi_status_num(status='paid', sku_ids=[]): err_skus = set([]) psi_attr_status = [l[0] for l in PSI_STATUS.CHOICES] psi_attrs_dict = {s: 'psi_%s_num' % s for s in psi_attr_status} attr = psi_attrs_dict[status] condition = { 'status': 0, } if sku_ids: condition['sku_id__in'] = sku_ids queryset = SkuStock.objects.filter(**condition).exclude( adjust_quantity=0, history_quantity=0, inbound_quantity=0, return_quantity=0, rg_quantity=0, post_num=0, sold_num=0) sku_ids_dict = {p.sku_id: getattr(p, attr) for p in queryset.all()} res = PackageSkuItem.objects.filter(type=PSI_TYPE.NORMAL, pay_time__gt=SkuStock.PRODUCT_SKU_STATS_COMMIT_TIME, status=status). \ exclude(status=PSI_STATUS.CANCEL).exclude(type__in=[PSI_TYPE.RETURN_INFERIOR, PSI_TYPE.RETURN_OUT_ORDER]).values('sku_id').annotate( total=Sum('num')) res = {int(k['sku_id']): k['total'] for k in res} for sku_id in res: if res[sku_id] != sku_ids_dict.get(sku_id, 0): print sku_id, res[sku_id], sku_ids_dict.get(sku_id, 0) err_skus.add(sku_id) for sku_id in sku_ids_dict: if sku_ids_dict[sku_id] != res.get(sku_id, 0): print sku_id, sku_ids_dict[sku_id], res.get(sku_id, 0) err_skus.add(sku_id) return list(err_skus)
class ActivityEntry(BaseModel): """ 商城活动入口 """ ACT_COUPON = 'coupon' ACT_WEBVIEW = 'webview' ACT_MAMA = 'mama' ACT_BRAND = 'brand' ACT_TOP = 'atop' ACT_TOPIC = 'topic' ACT_JINGPIN = 'jingpin' ACT_FOCUS = 'focus' ACT_CHOICES = ( (ACT_WEBVIEW, u'普通活动'), (ACT_TOP, u'商城Top10'), (ACT_TOPIC, u'专题活动'), (ACT_BRAND, u'品牌专场'), (ACT_COUPON, u'优惠券活动'), (ACT_MAMA, u'妈妈活动'), (ACT_JINGPIN, u'精品汇活动'), (ACT_FOCUS, u'每日焦点'), ) title = models.CharField(max_length=32, db_index=True, blank=True, verbose_name=u'活动/品牌名称') act_desc = models.TextField(max_length=512, blank=True, verbose_name=u'活动描述') act_img = models.CharField(max_length=256, blank=True, verbose_name=u'活动入口图片') act_logo = models.CharField(max_length=256, blank=True, verbose_name=u'品牌LOGO') act_link = models.CharField(max_length=256, blank=True, verbose_name=u'活动链接') mask_link = models.CharField(max_length=256, blank=True, verbose_name=u'活动弹窗提示图') act_applink = models.CharField(max_length=256, blank=True, verbose_name=u'活动APP协议链接') share_icon = models.CharField(max_length=128, blank=True, verbose_name=u'活动分享图片') share_link = models.CharField(max_length=256, blank=True, verbose_name=u'活动分享链接') act_type = models.CharField(max_length=8, choices=ACT_CHOICES, db_index=True, verbose_name=u'活动类型') login_required = models.BooleanField(default=False, verbose_name=u'需要登陆') start_time = models.DateTimeField(blank=True, null=True, db_index=True, verbose_name=u'开始时间') end_time = models.DateTimeField(blank=True, null=True, verbose_name=u'结束时间') order_val = models.IntegerField(default=default_activity_order_val, db_index=True, verbose_name=u'排序值') extras = JSONCharMyField(max_length=5120, default={}, blank=True, verbose_name=u'活动数据') is_active = models.BooleanField(default=True, verbose_name=u'上线') objects = ActivityManager() class Meta: db_table = 'flashsale_activity_entry' app_label = 'pay' verbose_name = u'特卖/商城活动入口' verbose_name_plural = u'特卖/商城活动入口' def __unicode__(self): return u'<%s,%s>' % (self.id, self.title) def is_on(self): return self.is_active and self.start_time <= datetime.datetime.now( ) < self.end_time def get_shareparams(self, **params): share_link = replace_domain(self.share_link.format(**params)) return { 'id': self.id, 'title': self.title.format(**params), 'share_type': 'link', 'share_icon': self.share_icon, 'share_link': share_link, 'active_dec': self.act_desc.format(**params), } @property def schedule_id(self): # type: () -> Optional[int] """专题类型在extras获取关联的排期id """ if isinstance(self.extras, dict): return self.extras.get('schedule_id') return None def get_schedule_suppliers(self): # type : (None) -> Optional[List[SaleSupplier]] if self.schedule_id: from ..deps import get_schedule_by_id schedule = get_schedule_by_id(id=int(self.schedule_id)) return schedule.sale_suppliers return None def get_html(self, key): htmls = self.extras.get("html", {}) if key in htmls: return htmls[key] return None def total_member_num(self): return 2000 def friend_member_num(self): return 16
class UserAddress(BaseModel): """ extras: { idcard: { face: ‘/path/to/image-face’, back: ‘/path/to/image-back’, } } """ NORMAL = 'normal' DELETE = 'delete' STATUS_CHOICES = ((NORMAL, u'正常'), (DELETE, u'删除')) CUS = 1 SUPPLIER = 2 TYPE_CHOICES = ((CUS,u'用户'), (SUPPLIER,u'供应商')) PERSONALINFO_LEVEL_ZERO = 0 # 无需填写地址信息 PERSONALINFO_LEVEL_ONE = 1 PERSONALINFO_LEVEL_TWO = 2 PERSONALINFO_LEVEL_THREE = 3 PERSONALINFO_LEVEL_CHOICES = ( (PERSONALINFO_LEVEL_ONE, '已填写基本收货信息'), (PERSONALINFO_LEVEL_TWO, '已填写身份证号'), (PERSONALINFO_LEVEL_THREE, '已上传身份证图片'), ) cus_uid = models.BigIntegerField(db_index=True, null=True, verbose_name=u'客户ID') supplier_id = models.IntegerField(db_index=True, null=True, verbose_name=u"供应商ID") receiver_name = models.CharField(max_length=25, blank=True, verbose_name=u'收货人姓名') receiver_state = models.CharField(max_length=16, blank=True, verbose_name=u'省') receiver_city = models.CharField(max_length=16, blank=True, verbose_name=u'市') receiver_district = models.CharField(max_length=16, blank=True, verbose_name=u'区') receiver_address = models.CharField(max_length=128, blank=True, verbose_name=u'详细地址') receiver_zip = models.CharField(max_length=10, blank=True, verbose_name=u'邮编') receiver_mobile = models.CharField(max_length=11, db_index=True, blank=True, verbose_name=u'手机') receiver_phone = models.CharField(max_length=20, blank=True, verbose_name=u'电话') default = models.BooleanField(default=False, verbose_name=u'默认地址') logistic_company_code = models.CharField(max_length=16, blank=True, verbose_name=u'优先快递编码') type = models.IntegerField(default=1, choices=TYPE_CHOICES, verbose_name=u'类型') status = models.CharField(max_length=8, blank=True, db_index=True, default=NORMAL, choices=STATUS_CHOICES, verbose_name=u'状态') identification_no = models.CharField(max_length=32, blank=True, verbose_name=u'身份证号码', help_text=u'准备废弃!!!') # type : text_type idcard_no = EncryptedCharField(max_length=128, blank=True, verbose_name=u'身份证号', help_text=u'自动加密存储、读取解码') # type : text_type extras = JSONCharMyField(max_length=256, default={}, verbose_name=u'附加参数') objects = models.Manager() normal_objects = useraddress.NormalUserAddressManager() class Meta: db_table = 'flashsale_address' app_label = 'pay' verbose_name = u'特卖用户/地址' verbose_name_plural = u'特卖用户/地址列表' def __unicode__(self): return '<%s,%s>' % (self.id, self.get_inline_address()) def set_default_address(self): """ 设置默认地址 """ current_address = self.__class__.objects.filter(cus_uid=self.cus_uid) # 当前用户的地址 current_address.update(default=False) # 全部更新为非默认 self.default = True self.save() # 保存当前的为默认地址 return True def is_complete(self): if all([self.supplier_id, self.receiver_name, self.receiver_state, self.receiver_city, self.receiver_district, self.receiver_address, self.receiver_mobile]): return True else: return False @property def full_address_string(self): return '{}{}{}{}'.format(self.receiver_state, self.receiver_city, self.receiver_district, self.receiver_address) def set_logistic_company(self, company_code): """ 设置物流公司 """ self.logistic_company_code = company_code self.save(update_fields=['logistic_company_code']) return True def clean_strip(self): changed = False for attr in ['receiver_name', 'receiver_phone', 'receiver_state', 'receiver_city', 'receiver_district', 'receiver_address']: val = getattr(self, attr) if val.strip() != val: changed = True setattr(self, attr, val.strip()) return changed def get_inline_address(self): return '{cus_uid}-{receiver_name}-{receiver_mobile}-{receiver_state},{receiver_city},{receiver_district},{receiver_address}'.format( **model_to_dict(self) ) def set_idcard_image(self, side, card_imgpath): """ side choices: face and back """ self.extras.setdefault('idcard', { 'face': '', 'back': '', }) self.extras['idcard'][side] = card_imgpath def get_idcard_image(self, side): if 'idcard' not in self.extras: return '' return self.extras['idcard'][side] def get_personal_info_level(self): idcard_info = self.extras.get('idcard',{}) if self.idcard_no and idcard_info.get('face') and idcard_info.get('back'): return self.PERSONALINFO_LEVEL_THREE if self.receiver_name and self.idcard_no: return self.PERSONALINFO_LEVEL_TWO return self.PERSONALINFO_LEVEL_ONE def check_idcard_valid(self): idcard_valid = self.extras.get('idcard_valid', {}) valid = idcard_valid.get('valid', False) err_num = idcard_valid.get('err_num', 0) if valid: return True if err_num > 6: logger.error({ 'message': u'num err,身份证校验错误次数过多,请联系管理员修改', 'address_id': self.id, 'action': 'check_idcard_valid', 'data': 'idno=%s, name=%s, valid=%s, err_num=%s' % (self.idcard_no, self.receiver_name, valid, err_num) }) return False try: is_valid = idcard.check_name(self.idcard_no, self.receiver_name) if not is_valid: err_num = err_num + 1 self.extras['idcard_valid'] = {'valid': is_valid, 'err_num': err_num} self.save() except Exception, e: logger.error({ 'message': u'check except,身份证校验第三方接口错误{}'.format(e.message), 'address_id': self.id, 'action': 'check_idcard_valid', 'data': 'idno=%s, name=%s, valid=%s, err_num=%s' % (self.idcard_no, self.receiver_name, valid, err_num) }, exc_info=True) is_valid = False return is_valid