qrpa 1.0.16__py3-none-any.whl → 1.0.18__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of qrpa might be problematic. Click here for more details.

qrpa/shein_excel.py CHANGED
@@ -159,3 +159,120 @@ class SheinExcel:
159
159
  InsertImageV2(app, wb, sheet, ['SKC图片', 'SKU图片'])
160
160
  wb.save()
161
161
  close_excel(app, wb)
162
+
163
+ def write_week_report(self):
164
+ excel_path = create_file_path(self.config.excel_week_sales_report)
165
+ log(excel_path)
166
+
167
+ cache_file = f'{self.config.auto_dir}/shein/cache/week_sales_{TimeUtils.today_date()}.json'
168
+ dict = read_dict_from_file(cache_file)
169
+
170
+ summary_excel_data = []
171
+ header = []
172
+ for store_name, excel_data in dict.items():
173
+ sheet_name = store_name
174
+ write_data(excel_path, sheet_name, excel_data)
175
+ self.format_week_report(excel_path, sheet_name)
176
+ header = excel_data[0]
177
+ summary_excel_data += excel_data[1:]
178
+ summary_excel_data = [header] + summary_excel_data
179
+ sheet_name = 'Sheet1'
180
+ write_data(excel_path, sheet_name, summary_excel_data)
181
+ self.format_week_report(excel_path, sheet_name)
182
+
183
+ def format_week_report(self, excel_path, sheet_name):
184
+ app, wb, sheet = open_excel(excel_path, sheet_name)
185
+ beautify_title(sheet)
186
+ column_to_left(sheet, ['商品信息'])
187
+ format_to_money(sheet, ['申报价', '成本价', '毛利润', '利润'])
188
+ format_to_percent(sheet, ['支付率', '点击率', '毛利率'])
189
+ self.dealFormula(sheet) # 有空再封装优化
190
+ colorize_by_field(app, wb, sheet, 'SPU')
191
+ autofit_column(sheet, ['店铺名称'])
192
+ specify_column_width(sheet, ['商品标题'], 150 / 6)
193
+ add_borders(sheet)
194
+ InsertImageV2(app, wb, sheet, ['SKC图片', 'SKU图片'], 'shein', 90, None, None, True)
195
+ wb.save()
196
+ close_excel(app, wb)
197
+
198
+ # 处理公式计算
199
+ def dealFormula(self, sheet):
200
+ # 增加列 周销增量 月销增量
201
+ col_week_increment = find_column_by_data(sheet, 1, '周销增量')
202
+ if col_week_increment is None:
203
+ col_week_increment = find_column_by_data(sheet, 1, '远30天销量')
204
+ log(f'{col_week_increment}:{col_week_increment}')
205
+ sheet.range(f'{col_week_increment}:{col_week_increment}').insert('right')
206
+ sheet.range(f'{col_week_increment}1').value = '周销增量'
207
+ log('已增加列 周销增量')
208
+
209
+ col_month_increment = find_column_by_data(sheet, 1, '月销增量')
210
+ if col_month_increment is None:
211
+ col_month_increment = find_column_by_data(sheet, 1, '总销量')
212
+ log(f'{col_month_increment}:{col_month_increment}')
213
+ sheet.range(f'{col_month_increment}:{col_month_increment}').insert('right')
214
+ sheet.range(f'{col_month_increment}1').value = '月销增量'
215
+ log('已增加列 月销增量')
216
+
217
+ col_month_profit = find_column_by_data(sheet, 1, '近30天利润')
218
+ if col_month_profit is None:
219
+ col_month_profit = find_column_by_data(sheet, 1, '总利润')
220
+ sheet.range(f'{col_month_profit}:{col_month_profit}').insert('right')
221
+ log((f'{col_month_profit}:{col_month_profit}'))
222
+ sheet.range(f'{col_month_profit}1').value = '近30天利润'
223
+ log('已增加列 近30天利润')
224
+
225
+ col_week_profit = find_column_by_data(sheet, 1, '近7天利润')
226
+ if col_week_profit is None:
227
+ col_week_profit = find_column_by_data(sheet, 1, '近30天利润')
228
+ sheet.range(f'{col_week_profit}:{col_week_profit}').insert('right')
229
+ log((f'{col_week_profit}:{col_week_profit}'))
230
+ sheet.range(f'{col_week_profit}1').value = '近7天利润'
231
+ log('已增加列 近7天利润')
232
+
233
+ # return
234
+
235
+ # 查找 申报价,成本价,毛利润,毛利润率 所在列
236
+ col_verify_price = find_column_by_data(sheet, 1, '申报价')
237
+ col_cost_price = find_column_by_data(sheet, 1, '成本价')
238
+ col_gross_profit = find_column_by_data(sheet, 1, '毛利润')
239
+ col_gross_margin = find_column_by_data(sheet, 1, '毛利率')
240
+
241
+ col_week_1 = find_column_by_data(sheet, 1, '近7天销量')
242
+ col_week_2 = find_column_by_data(sheet, 1, '远7天销量')
243
+ col_month_1 = find_column_by_data(sheet, 1, '近30天销量')
244
+ col_month_2 = find_column_by_data(sheet, 1, '远30天销量')
245
+
246
+ # 遍历可用行
247
+ used_range_row = sheet.range('A1').expand('down')
248
+ for i, cell in enumerate(used_range_row):
249
+ row = i + 1
250
+ if row < 2:
251
+ continue
252
+ rangeA = f'{col_verify_price}{row}'
253
+ rangeB = f'{col_cost_price}{row}'
254
+
255
+ rangeC = f'{col_week_increment}{row}'
256
+ rangeD = f'{col_month_increment}{row}'
257
+
258
+ # rangeE = f'{col_total_profit}{row}'
259
+ rangeF = f'{col_month_profit}{row}'
260
+ rangeG = f'{col_week_profit}{row}'
261
+
262
+ # 设置毛利润和毛利润率列公式与格式
263
+ sheet.range(f'{col_gross_profit}{row}').formula = f'=IF(ISNUMBER({rangeB}),{rangeA}-{rangeB},"")'
264
+ sheet.range(f'{col_gross_profit}{row}').number_format = '0.00'
265
+ sheet.range(f'{col_gross_margin}{row}').formula = f'=IF(ISNUMBER({rangeB}),({rangeA}-{rangeB})/{rangeA},"")'
266
+ sheet.range(f'{col_gross_margin}{row}').number_format = '0.00%'
267
+
268
+ sheet.range(rangeC).formula = f'={col_week_1}{row}-{col_week_2}{row}'
269
+ sheet.range(rangeC).number_format = '0'
270
+ sheet.range(rangeD).formula = f'={col_month_1}{row}-{col_month_2}{row}'
271
+ sheet.range(rangeD).number_format = '0'
272
+
273
+ # sheet.range(rangeE).formula = f'=IF(ISNUMBER({rangeB}),{col_total}{row}*{col_gross_profit}{row},"")'
274
+ # sheet.range(rangeE).number_format = '0.00'
275
+ sheet.range(rangeF).formula = f'=IF(ISNUMBER({rangeB}),{col_month_1}{row}*{col_gross_profit}{row},"")'
276
+ sheet.range(rangeF).number_format = '0.00'
277
+ sheet.range(rangeG).formula = f'=IF(ISNUMBER({rangeB}),{col_week_1}{row}*{col_gross_profit}{row},"")'
278
+ sheet.range(rangeG).number_format = '0.00'
qrpa/shein_lib.py CHANGED
@@ -1,6 +1,9 @@
1
- from qrpa import read_dict_from_file, write_dict_to_file, read_dict_from_file_ex, write_dict_to_file_ex
2
- from qrpa import log, fetch, send_exception, md5_string
3
- from qrpa import time_utils, TimeUtils, get_safe_value
1
+ from .fun_file import read_dict_from_file, write_dict_to_file, read_dict_from_file_ex, write_dict_to_file_ex
2
+ from .fun_base import log, send_exception, md5_string, get_safe_value
3
+ from .fun_web import fetch
4
+ from .time_utils import TimeUtils
5
+
6
+ from .shein_sqlite import insert_sales,get_last_week_sales,get_near_week_sales,get_near_month_sales,get_last_month_sales
4
7
 
5
8
  import math
6
9
  import time
@@ -418,15 +421,15 @@ class SheinLib:
418
421
  def query_obm_activity_list(self):
419
422
  page_num = 1
420
423
  page_size = 100
421
- date_60_days_ago = time_utils.get_past_nth_day(59)
422
- cache_file = f'{self.config.auto_dir}/shein/cache/obm_activity_{self.store_name}_{date_60_days_ago}_{time_utils.today_date()}.json'
424
+ date_60_days_ago = TimeUtils.get_past_nth_day(59)
425
+ cache_file = f'{self.config.auto_dir}/shein/cache/obm_activity_{self.store_name}_{date_60_days_ago}_{TimeUtils.today_date()}.json'
423
426
  list_item = read_dict_from_file(cache_file, 3600 * 8)
424
427
  if len(list_item) > 0:
425
428
  return list_item
426
429
 
427
430
  url = f"https://sso.geiwohuo.com/mrs-api-prefix/promotion/obm/query_obm_activity_list"
428
431
  payload = {
429
- "insert_end_time" : f"{time_utils.today_date()} 23:59:59",
432
+ "insert_end_time" : f"{TimeUtils.today_date()} 23:59:59",
430
433
  "insert_start_time": f"{date_60_days_ago} 00:00:00",
431
434
  "page_num" : page_num,
432
435
  "page_size" : page_size,
@@ -497,8 +500,8 @@ class SheinLib:
497
500
  log(f'正在获取 {self.store_name} 活动列表')
498
501
  page_num = 1
499
502
  page_size = 100
500
- date_60_days_ago = time_utils.get_past_nth_day(59)
501
- cache_file = f'{self.config.auto_dir}/shein/cache/platform_activity_{self.store_name}_{date_60_days_ago}_{time_utils.today_date()}.json'
503
+ date_60_days_ago = TimeUtils.get_past_nth_day(59)
504
+ cache_file = f'{self.config.auto_dir}/shein/cache/platform_activity_{self.store_name}_{date_60_days_ago}_{TimeUtils.today_date()}.json'
502
505
  list_item = read_dict_from_file(cache_file, 3600 * 8)
503
506
  if len(list_item) > 0:
504
507
  return list_item
@@ -506,7 +509,7 @@ class SheinLib:
506
509
  url = f"https://sso.geiwohuo.com/mrs-api-prefix/mbrs/activity/get_partake_activity_goods_list?page_num={page_num}&page_size={page_size}"
507
510
  payload = {
508
511
  "goods_audit_status" : 1,
509
- "insert_zone_time_end" : f"{time_utils.today_date()} 23:59:59",
512
+ "insert_zone_time_end" : f"{TimeUtils.today_date()} 23:59:59",
510
513
  "insert_zone_time_start": f"{date_60_days_ago} 00:00:00"
511
514
  }
512
515
 
@@ -536,8 +539,8 @@ class SheinLib:
536
539
  activity_id = activity['activity_id']
537
540
  activity_name = activity['act_name']
538
541
  sub_type_id = activity['sub_type_id'] # 1.不限量 2.限量
539
- dateBegin = time_utils.convert_datetime_to_date(activity['start_time'])
540
- dateEnd = time_utils.convert_datetime_to_date(activity['end_time'])
542
+ dateBegin = TimeUtils.convert_datetime_to_date(activity['start_time'])
543
+ dateEnd = TimeUtils.convert_datetime_to_date(activity['end_time'])
541
544
  skc_list = self.query_goods_detail(activity_id)
542
545
  for skc_item in skc_list:
543
546
  attend_num_sum = skc_item['attend_num_sum']
@@ -556,8 +559,8 @@ class SheinLib:
556
559
  activity_name = platform_activity['activity_name']
557
560
  text_tag_content = platform_activity['text_tag_content']
558
561
  attend_num = platform_activity['attend_num']
559
- dateBegin = time_utils.convert_timestamp_to_date(platform_activity['start_time'])
560
- dateEnd = time_utils.convert_timestamp_to_date(platform_activity['end_time'])
562
+ dateBegin = TimeUtils.convert_timestamp_to_date(platform_activity['start_time'])
563
+ dateEnd = TimeUtils.convert_timestamp_to_date(platform_activity['end_time'])
561
564
  if text_tag_content != '新品':
562
565
  attend_num = '-'
563
566
  for sku_item in platform_activity['activity_sku_list']:
@@ -569,7 +572,7 @@ class SheinLib:
569
572
  write_dict_to_file(cache_file, dict_activity_price)
570
573
 
571
574
  def get_skc_week_actual_sales(self, skc):
572
- first_day, last_day = time_utils.TimeUtils.get_past_7_days_range()
575
+ first_day, last_day = TimeUtils.get_past_7_days_range()
573
576
  cache_file = f'{self.config.auto_dir}/shein/cache/{skc}_{first_day}_{last_day}.json'
574
577
  if datetime.now().hour >= 9:
575
578
  DictSkuSalesDate = read_dict_from_file(cache_file)
@@ -687,13 +690,291 @@ class SheinLib:
687
690
  log(f'dt: {self.dt}')
688
691
  return self.dt
689
692
 
693
+ def get_dict_skc_week_trend(self):
694
+ page_num = 1
695
+ page_size = 100
696
+
697
+ date_7_days_ago = TimeUtils.get_past_nth_day(7, None, '%Y%m%d')
698
+ log('-7', date_7_days_ago)
699
+ date_1_days_ago = TimeUtils.get_past_nth_day(1, None, '%Y%m%d')
700
+ log('-1', date_1_days_ago)
701
+
702
+ url = f"https://sso.geiwohuo.com/sbn/new_goods/get_skc_diagnose_list"
703
+ payload = {
704
+ "areaCd" : "cn",
705
+ "countrySite": [
706
+ "shein-all"
707
+ ],
708
+ "startDate" : date_7_days_ago,
709
+ "endDate" : date_1_days_ago,
710
+ "pageNum" : page_num,
711
+ "pageSize" : page_size
712
+ }
713
+ response_text = fetch(self.web_page, url, payload)
714
+ error_code = response_text.get('code')
715
+ if str(error_code) != '0':
716
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
717
+ spu_list = response_text['info']['data']
718
+ total = response_text['info']['meta']['count']
719
+ totalPage = math.ceil(total / page_size)
720
+
721
+ for page in range(2, totalPage + 1):
722
+ log(f'获取商品列表 第{page}/{totalPage}页')
723
+ page_num = page
724
+ payload = {
725
+ "areaCd" : "cn",
726
+ "countrySite": [
727
+ "shein-all"
728
+ ],
729
+ "startDate" : date_7_days_ago,
730
+ "endDate" : date_1_days_ago,
731
+ "pageNum" : page_num,
732
+ "pageSize" : page_size
733
+ }
734
+ response_text = fetch(self.web_page, url, payload)
735
+ spu_list_new = response_text['info']['data']
736
+ spu_list += spu_list_new
737
+ time.sleep(0.3)
738
+
739
+ DictSkcWeekTrend = {}
740
+ for spu_item in spu_list:
741
+ skc = str(spu_item['skc'])
742
+ DictSkcWeekTrend[skc] = spu_item
743
+
744
+ log('len(DictSkcWeekTrend)', len(DictSkcWeekTrend))
745
+ write_dict_to_file(f'{self.config.auto_dir}/shein/dict/dict_skc_week_trend_{self.store_username}.json', DictSkcWeekTrend)
746
+ return DictSkcWeekTrend
747
+
748
+ def get_skc_sales(self, skc, start_date, end_date):
749
+ url = "https://sso.geiwohuo.com/idms/stockadvice/saleTrendDetail"
750
+ payload = {
751
+ "skc" : skc,
752
+ "startDate": start_date,
753
+ "endDate" : end_date
754
+ }
755
+ response_text = fetch(self.web_page, url, payload)
756
+ error_code = response_text.get('code')
757
+ error_msg = response_text.get('msg')
758
+ if str(error_code) != '0':
759
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
760
+
761
+ sales_list = response_text['info']['saleTrendDetailList']
762
+ if sales_list:
763
+ for skc_list in sales_list:
764
+ date = skc_list['date']
765
+ if date == '合计':
766
+ log('无销量skc: ', skc)
767
+ continue
768
+ skc_sale = skc_list['skcSale']
769
+ skc_order = skc_list['skcOrder']
770
+ for sku_list in skc_list['skuSaleTrendDetailList']:
771
+ sku = sku_list['skuCode']
772
+ attr_name = sku_list['attributeName']
773
+ sku_sale = sku_list['skuSale']
774
+ sku_order = sku_list['skuOrder']
775
+ if sku_sale > 0:
776
+ insert_sales(skc, date, skc_sale, skc_order, sku, attr_name, sku_sale, sku_order)
777
+ return sales_list
778
+
779
+ # 获取商品包含sku销量的列表
780
+ def get_product_sku_sales_list(self, source='mb'):
781
+ log(f'获取销量列表')
782
+ url = "https://sso.geiwohuo.com/idms/goods-skc/list"
783
+ pageNumber = 1
784
+ pageSize = 100
785
+ dictPayload = {
786
+ "pageNumber" : pageNumber,
787
+ "pageSize" : pageSize,
788
+ "supplierCodes" : "",
789
+ "skcs" : "",
790
+ "spu" : "",
791
+ "c7dSaleCntBegin" : "",
792
+ "c7dSaleCntEnd" : "",
793
+ "goodsLevelIdList" : [],
794
+ "supplyStatus" : "",
795
+ "shelfStatus" : 1,
796
+ "categoryIdList" : [],
797
+ "skcStockBegin" : "",
798
+ "skcStockEnd" : "",
799
+ "skuStockBegin" : "",
800
+ "skuStockEnd" : "",
801
+ "skcSaleDaysBegin" : "",
802
+ "skcSaleDaysEnd" : "",
803
+ "skuSaleDaysBegin" : "",
804
+ "skuSaleDaysEnd" : "",
805
+ "planUrgentCountBegin" : "",
806
+ "planUrgentCountEnd" : "",
807
+ "skcAvailableOrderBegin": "",
808
+ "skcAvailableOrderEnd" : "",
809
+ "skuAvailableOrderBegin": "",
810
+ "skuAvailableOrderEnd" : "",
811
+ "shelfDateBegin" : "",
812
+ "shelfDateEnd" : "",
813
+ "stockWarnStatusList" : [],
814
+ "labelFakeIdList" : [],
815
+ "sheinSaleByInventory" : "",
816
+ "tspIdList" : [],
817
+ "adviceStatus" : [],
818
+ "sortBy7dSaleCnt" : 2
819
+ }
820
+ payload = dictPayload
821
+ response_text = fetch(self.web_page, url, payload)
822
+ error_code = response_text.get('code')
823
+ if str(error_code) != '0':
824
+ raise send_exception(json.dumps(response_text, ensure_ascii=False))
825
+
826
+ spu_list = response_text['info']['list']
827
+
828
+ total = response_text['info']['count']
829
+ totalPage = math.ceil(total / pageSize)
830
+ for page in range(2, totalPage + 1):
831
+ log(f'获取SKU销量列表 第{page}/{totalPage}页')
832
+ dictPayload['pageNumber'] = page
833
+ payload = dictPayload
834
+ response_text = fetch(self.web_page, url, payload)
835
+ spu_list_new = response_text['info']['list']
836
+ spu_list += spu_list_new
837
+ time.sleep(0.3)
838
+
839
+ cache_file = f'{self.config.auto_dir}/shein/sku_price/sku_price_{self.store_username}.json'
840
+ dict_sku_price = read_dict_from_file(cache_file)
841
+
842
+ cache_file2 = f'{self.config.auto_dir}/shein/dict/dict_skc_week_trend_{self.store_username}.json'
843
+ DictSkcWeekTrend = read_dict_from_file(cache_file2)
844
+
845
+ cache_file3 = f'{self.config.auto_dir}/shein/dict/product_list_{self.store_username}.json'
846
+ DictSpuInfo = read_dict_from_file(cache_file3)
847
+
848
+ product_sku_list = [
849
+ [
850
+ '店铺名称', '商品信息', 'SKC图片', 'SKU图片', 'SKU', 'SKU货号', '在售天数', '库存(模式/本地/在途/希音)',
851
+ '今天销量', '今日订单数', # 9
852
+ '远7天销量', '远7天订单数', '近7天销量', '近7天订单数', '周销增量', '远30天销量', '远30天订单数',
853
+ '近30天销量', '近30天订单数', '月销增量', '总销量', # 11
854
+ '申报价', '成本价', '毛利润', '毛利率', '近7天利润', '近30天利润', # 6
855
+ 'SPU', 'SKC', 'SKC货号', '商品标题', '叶子类目', # 5
856
+ 'SKC近7天销量', 'SKC近7天曝光人数', 'SKC近7天商详访客', 'SKC近7天点击率', 'SKC近7天支付人数',
857
+ 'SKC近7天支付率', 'SKC近7天评论数'
858
+ ]
859
+ ]
860
+
861
+ date_60_days_ago = TimeUtils.get_past_nth_day(60, None, '%Y-%m-%d')
862
+ log('-60', date_60_days_ago)
863
+ date_7_days_ago = TimeUtils.get_past_nth_day(7, None, '%Y-%m-%d')
864
+ log('-7', date_7_days_ago)
865
+ date_1_days_ago = TimeUtils.get_past_nth_day(1, None, '%Y-%m-%d')
866
+ log('-1', date_1_days_ago)
867
+
868
+ count = 0
869
+ for spu_info in spu_list:
870
+ count += 1
871
+ # if count > 10:
872
+ # break
873
+ spu = spu_info['spu']
874
+ skc = str(spu_info['skc'])
875
+ # if not shein_db.exists_sales_1_days_ago(skc):
876
+ # log(f'未查到昨天销量: {skc}')
877
+ self.get_skc_sales(skc, date_60_days_ago, date_1_days_ago)
878
+ skcCode = spu_info['supplierCode']
879
+ product_name = DictSpuInfo[spu]['product_name_en']
880
+ category_name = spu_info['categoryName']
881
+ shelfDays = spu_info['shelfDays']
882
+ shelf_status = DictSpuInfo[spu]['shelf_status']
883
+ dictStatus = {
884
+ 'WAIT_SHELF': "待上架",
885
+ 'ON_SHELF' : "已上架",
886
+ 'SOLD_OUT' : "已售罄",
887
+ 'OUT_SHELF' : "已下架"
888
+ }
889
+ status_cn = dictStatus[shelf_status]
890
+ good_level = spu_info['goodsLevel']['name']
891
+ sale_model = spu_info['saleModel']['name']
892
+
893
+ for sku_info in spu_info['skuList']:
894
+ sku = sku_info['skuCode']
895
+ skuExtCode = str(sku_info['supplierSku'])
896
+ if sku == '合计':
897
+ continue
898
+ sku_item = ["" for _ in range(len(product_sku_list[0]))]
899
+ sku_item[0] = f'{self.store_name}\n({status_cn})\n{good_level}\n{date_7_days_ago}\n{date_1_days_ago}' # 店铺名称
900
+ product_info = f"{product_name}\n类目: {category_name}\nSKC: {skc}\nSKC货号: {skcCode}\nSPU: {spu}\n在售天数: {shelfDays}"
901
+ sku_item[1] = product_info # 商品信息
902
+ sku_item[2] = spu_info['picUrl'] # skc图片
903
+
904
+ sku_img = self.bridge.get_sku_img(skuExtCode, source)
905
+
906
+ sku_item[3] = sku_img # sku图片
907
+ sku_item[4] = sku # sku
908
+ sku_item[5] = f"{sku_info['supplierSku']}" # sku货号
909
+ sku_item[6] = shelfDays # 在售天数
910
+
911
+ stock = self.bridge.get_sku_stock(skuExtCode, source)
912
+
913
+ shein_stock = sku_info['stock']
914
+ transit = sku_info['transit'] # 在途
915
+ real_transit = transit + sku_info['stayShelf'] - sku_info['transitSale']
916
+ sku_item[7] = f'{sale_model}\n{stock}/{real_transit}/{shein_stock}' # 本地组合库存
917
+
918
+ sku_item[8] = sku_info['totalSaleVolume'] # 今日销量
919
+ sku_item[9] = sku_info['orderCnt'] # 今日订单数
920
+
921
+ week_sales = get_last_week_sales(sku)
922
+ sku_item[10] = week_sales[0] # 远7日销量
923
+ sku_item[11] = week_sales[1] # 远7日订单数
924
+
925
+ week_sales2 = get_near_week_sales(sku)
926
+ sku_item[12] = week_sales2[0] # 近7日销量
927
+ sku_item[13] = week_sales2[1] # 近7日订单数
928
+ sku_item[14] = week_sales2[1] - week_sales2[0] # 周增销量
929
+
930
+ month_sales = get_last_month_sales(sku)
931
+ sku_item[15] = month_sales[0] # 远30日销量
932
+ sku_item[16] = month_sales[1] # 远30日订单数
933
+
934
+ month_sales2 = get_near_month_sales(sku)
935
+ sku_item[17] = month_sales2[0] # 近30日销量
936
+ sku_item[18] = month_sales2[1] # 近30日订单数
937
+ sku_item[19] = month_sales2[1] - month_sales2[0] # 月增销量
938
+ sku_item[20] = '-' # 总销量
939
+
940
+ sku_item[21] = dict_sku_price[sku] # 申报价
941
+
942
+ cost_price = self.bridge.get_sku_cost(skuExtCode, source)
943
+
944
+ sku_item[22] = cost_price # 成本价
945
+ sku_item[23] = '' # 毛利润
946
+ sku_item[24] = '' # 毛利率
947
+ sku_item[25] = '' # 近7天利润
948
+ sku_item[26] = '' # 近30天利润
949
+ sku_item[27] = spu # spu
950
+ sku_item[28] = skc # skc
951
+ sku_item[29] = spu_info['supplierCode'] # skc货号
952
+ sku_item[30] = product_name # 商品标题
953
+ sku_item[31] = category_name # 叶子类目
954
+
955
+ key = str(skc)
956
+ sku_item[32] = DictSkcWeekTrend.get(key, {'saleCnt': 0})['saleCnt'] # 'SKC近7天销量',
957
+ sku_item[33] = DictSkcWeekTrend.get(key, {'epsUvIdx': 0})['epsUvIdx'] # 'SKC近7天曝光人数',
958
+ sku_item[34] = DictSkcWeekTrend.get(key, {'goodsUvIdx': 0})['goodsUvIdx'] # 'SKC近7天商详访客',
959
+ sku_item[35] = DictSkcWeekTrend.get(key, {'epsGdsCtrIdx': 0})['epsGdsCtrIdx'] # 'SKC近7天点击率',
960
+ sku_item[36] = DictSkcWeekTrend.get(key, {'payUvIdx': 0})['payUvIdx'] # 'SKC近7天支付人数',
961
+ sku_item[37] = DictSkcWeekTrend.get(key, {'gdsPayCtrIdx': 0})['gdsPayCtrIdx'] # 'SKC近7天支付率',
962
+ sku_item[38] = DictSkcWeekTrend.get(key, {'totalCommentCnt': 0})['totalCommentCnt'] # '评论数'
963
+
964
+ product_sku_list.append(sku_item)
965
+
966
+ cache_file = f'{self.config.auto_dir}/shein/cache/week_sales_{TimeUtils.today_date()}.json'
967
+ write_dict_to_file_ex(cache_file, {self.store_name: product_sku_list}, [self.store_name])
968
+
969
+ return product_sku_list
970
+
690
971
  # 获取一个skc一周内的销售趋势(商品明细中的)
691
972
  def get_dict_skc_week_trend_v2(self, spu, skc):
692
973
  dt = self.get_dt_time()
693
974
 
694
- date_7_days_ago = time_utils.TimeUtils.get_past_nth_day(7, None, '%Y%m%d')
975
+ date_7_days_ago = TimeUtils.get_past_nth_day(7, None, '%Y%m%d')
695
976
  log('-7', date_7_days_ago)
696
- date_1_days_ago = time_utils.TimeUtils.get_past_nth_day(1, None, '%Y%m%d')
977
+ date_1_days_ago = TimeUtils.get_past_nth_day(1, None, '%Y%m%d')
697
978
  log('-1', date_1_days_ago)
698
979
 
699
980
  cache_file = f'{self.config.auto_dir}/shein/dict/dict_skc_week_trend_{skc}_{date_7_days_ago}_{date_1_days_ago}.json'
@@ -735,8 +1016,8 @@ class SheinLib:
735
1016
 
736
1017
  def get_skc_week_sale_list(self, spu, skc, sku):
737
1018
  dict_skc = self.get_dict_skc_week_trend_v2(spu, skc)
738
- date_list = time_utils.get_past_7_days_list()
739
- first_day, last_day = time_utils.TimeUtils.get_past_7_days_range()
1019
+ date_list = TimeUtils.get_past_7_days_list()
1020
+ first_day, last_day = TimeUtils.get_past_7_days_range()
740
1021
  cache_file = f'{self.config.auto_dir}/shein/cache/{skc}_{first_day}_{last_day}.json'
741
1022
  DictSkuSalesDate = read_dict_from_file(cache_file)
742
1023
  sales_detail = []
@@ -747,7 +1028,7 @@ class SheinLib:
747
1028
  saleCnt = get_safe_value(dict_skc.get(date, {}), 'saleCnt', 0)
748
1029
  epsUvIdx = get_safe_value(dict_skc.get(date, {}), 'epsUvIdx', 0)
749
1030
 
750
- sales_detail.append(f'{date}({time_utils.get_weekday_name(date)}): {sales_num}/{saleCnt}/{epsUvIdx}')
1031
+ sales_detail.append(f'{date}({TimeUtils.get_weekday_name(date)}): {sales_num}/{saleCnt}/{epsUvIdx}')
751
1032
 
752
1033
  sales_data = []
753
1034
  for date in date_list:
@@ -757,7 +1038,7 @@ class SheinLib:
757
1038
  payUvIdx = get_safe_value(dict_skc.get(date, {}), 'payUvIdx', 0) # 支付人数
758
1039
  gdsPayCtrIdx = get_safe_value(dict_skc.get(date, {}), 'gdsPayCtrIdx', 0) # 转化率
759
1040
 
760
- sales_data.append(f'{date}({time_utils.get_weekday_name(date)}): {epsGdsCtrIdx:.2%}({goodsUvIdx})/{gdsPayCtrIdx:.2%}({payUvIdx})')
1041
+ sales_data.append(f'{date}({TimeUtils.get_weekday_name(date)}): {epsGdsCtrIdx:.2%}({goodsUvIdx})/{gdsPayCtrIdx:.2%}({payUvIdx})')
761
1042
 
762
1043
  return sales_detail, sales_data
763
1044
 
@@ -891,7 +1172,7 @@ class SheinLib:
891
1172
  dict_advice = read_dict_from_file(cache_file)
892
1173
  cache_file = f'{self.config.auto_dir}/shein/sku_price/sku_price_{self.store_username}.json'
893
1174
  dict_sku_price = read_dict_from_file(cache_file)
894
- date_list = time_utils.get_past_7_days_list()
1175
+ date_list = TimeUtils.get_past_7_days_list()
895
1176
  if mode in [2, 5, 6, 7, 8, 9, 10]:
896
1177
  excel_data = [[
897
1178
  '店铺名称', 'SKC图片', 'SKU图片', '商品信息', '建议现货数量', '现有库存数量', '已采购数量', '预测日销',
@@ -1068,7 +1349,7 @@ class SheinLib:
1068
1349
  sales_num = DictSkuSalesDate.get(date, {}).get(sku, {}).get("hisActualValue", 0)
1069
1350
  sales_num = sales_num if sales_num is not None else 0
1070
1351
  sales7cn += sales_num
1071
- if time_utils.is_yesterday_date(date) and sales_num == 0:
1352
+ if TimeUtils.is_yesterday_date(date) and sales_num == 0:
1072
1353
  flag_yesterday = 1
1073
1354
 
1074
1355
  if mode == 4 and flag_yesterday:
@@ -1114,10 +1395,10 @@ class SheinLib:
1114
1395
  row_item.append(sku)
1115
1396
  excel_data.append(row_item)
1116
1397
 
1117
- cache_file = f'{self.config.auto_dir}/shein/cache/bak_advice_{mode}_{time_utils.today_date()}.json'
1398
+ cache_file = f'{self.config.auto_dir}/shein/cache/bak_advice_{mode}_{TimeUtils.today_date()}.json'
1118
1399
  write_dict_to_file_ex(cache_file, {self.store_name: excel_data}, {self.store_name})
1119
1400
 
1120
- cache_file = f'{self.config.auto_dir}/shein/cache/bak_advice_notify_{mode}_{time_utils.today_date()}.json'
1401
+ cache_file = f'{self.config.auto_dir}/shein/cache/bak_advice_notify_{mode}_{TimeUtils.today_date()}.json'
1121
1402
  NotifyItem = [self.store_name, len(excel_data[1:])]
1122
1403
  write_dict_to_file_ex(cache_file, {self.store_name: NotifyItem}, {self.store_name})
1123
1404