qrpa 1.0.97__py3-none-any.whl → 1.0.99__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
@@ -195,7 +195,6 @@ class SheinExcel:
195
195
  dict = read_dict_from_file(cache_file)
196
196
  for store_username, shein_back_list in dict.items():
197
197
  for item in shein_back_list:
198
-
199
198
  store_name = dict_store.get(store_username)
200
199
 
201
200
  returnOrderId = item['id']
@@ -297,7 +296,6 @@ class SheinExcel:
297
296
  dict = read_dict_from_file(cache_file)
298
297
  for store_username, shein_back_list in dict.items():
299
298
  for item in shein_back_list:
300
-
301
299
  store_name = dict_store.get(store_username)
302
300
 
303
301
  returnOrderId = item['id']
@@ -393,7 +391,6 @@ class SheinExcel:
393
391
  dict = read_dict_from_file(cache_file)
394
392
  for store_username, shein_back_list in dict.items():
395
393
  for item in shein_back_list:
396
-
397
394
  store_name = dict_store.get(store_username)
398
395
 
399
396
  returnOrderId = item['id']
@@ -1209,9 +1206,9 @@ class SheinExcel:
1209
1206
  excel_path_month = str(self.config.excel_shein_finance_month_report).replace('#store_name#', store_name)
1210
1207
 
1211
1208
  month_data = [[
1212
- '平台SKU', '商家SKU', '属性集', '数量', '单价', '金额', '单价成本', '利润', '售出数量', '售出金额', '添加时间',
1209
+ '平台SKU', '商家SKU', '属性集', '数量', '单价', '金额', '单价成本', '利润', '售出数量', '售出金额', '售出成本', '添加时间',
1213
1210
  '业务单号', '单据号', '变动类型', '结算类型', 'SKC', '供方货号', '供应商名称', 'SKU图片',
1214
- ], ['合计', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']]
1211
+ ], ['合计', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']]
1215
1212
  log('len(ledger_list)', len(ledger_list))
1216
1213
  for month_item in ledger_list:
1217
1214
  row_item = []
@@ -1230,6 +1227,7 @@ class SheinExcel:
1230
1227
  month_item['quantity'] if month_item['cost_price'] and month_item['settleTypeName'] == '收入结算' else 0)
1231
1228
  row_item.append(
1232
1229
  month_item['amount'] if month_item['cost_price'] and month_item['settleTypeName'] == '收入结算' else 0)
1230
+ row_item.append('')
1233
1231
  row_item.append(month_item['addTime'])
1234
1232
  row_item.append(month_item['businessNo'])
1235
1233
  row_item.append(month_item['billNo'])
@@ -1250,10 +1248,11 @@ class SheinExcel:
1250
1248
  add_borders(sheet)
1251
1249
  format_to_money(sheet, ['单价', '金额', '利润'])
1252
1250
  format_to_datetime(sheet, ['时间'])
1253
- add_formula_for_column(sheet, '利润', '=IF(AND(ISNUMBER(G3),O3="收入结算"),F3-G3*D3,0)', 3)
1254
- add_formula_for_column(sheet, '售出数量', '=IF(AND(ISNUMBER(G3),O3="收入结算"),D3,0)', 3)
1255
- add_formula_for_column(sheet, '售出金额', '=IF(AND(ISNUMBER(G3),O3="收入结算"),F3,0)', 3)
1256
- add_sum_for_cell(sheet, ['数量', '金额', '利润', '售出数量', '售出金额'])
1251
+ add_formula_for_column(sheet, '利润', '=IF(AND(ISNUMBER(G3),P3="收入结算"),F3-G3*D3,0)', 3)
1252
+ add_formula_for_column(sheet, '售出数量', '=IF(AND(ISNUMBER(G3),P3="收入结算"),D3,0)', 3)
1253
+ add_formula_for_column(sheet, '售出金额', '=IF(AND(ISNUMBER(G3),P3="收入结算"),F3,0)', 3)
1254
+ add_formula_for_column(sheet, '售出成本', '=IF(AND(ISNUMBER(G3),P3="收入结算"),D3 * G3,0)', 3)
1255
+ add_sum_for_cell(sheet, ['数量', '金额', '利润', '售出数量', '售出金额', '售出成本'])
1257
1256
  column_to_left(sheet, ['平台SKU', '商家SKU', '属性集'])
1258
1257
  column_to_right(sheet, ['单价', '金额', '利润'])
1259
1258
  hidden_columns(sheet, ['SKU图片'])
@@ -1370,7 +1369,7 @@ class SheinExcel:
1370
1369
 
1371
1370
  write_dict_to_file_ex(f'{self.config.auto_dir}/shein/cache/sheet_{last_month}_补扣款列表.json', {store_username: replenish_data[:1] + replenish_data[2:]}, [store_username])
1372
1371
 
1373
- write_data(excel_path_month, sheet_name, replenish_data)
1372
+ write_data(excel_path_month, sheet_name, sort_by_column(replenish_data, 2, 2))
1374
1373
 
1375
1374
  app, wb, sheet = open_excel(excel_path_month, sheet_name)
1376
1375
  set_title_style(sheet, 2)
@@ -1540,19 +1539,28 @@ class SheinExcel:
1540
1539
 
1541
1540
  target_month = find_column_by_data(sheet, 2, last_month)
1542
1541
  sheet.range(f'{target_month}3').value = f"='{last_month}月销售明细'!I2"
1542
+
1543
1543
  sheet.range(f'{target_month}4').number_format = f"¥#,##0.00;¥-#,##0.00"
1544
1544
  sheet.range(f'{target_month}4').value = f"='{last_month}月销售明细'!J2"
1545
+
1546
+ sheet.range(f'A5').value = f"销售成本"
1545
1547
  sheet.range(f'{target_month}5').number_format = f"¥#,##0.00;¥-#,##0.00"
1546
- sheet.range(f'{target_month}5').value = f"='{last_month}月销售明细'!H2"
1548
+ sheet.range(f'{target_month}5').value = f"='{last_month}月销售明细'!K2"
1549
+
1550
+ sheet.range(f'A6').value = f"销售利润"
1547
1551
  sheet.range(f'{target_month}6').number_format = f"¥#,##0.00;¥-#,##0.00"
1552
+ sheet.range(f'{target_month}6').value = f"='{last_month}月销售明细'!H2"
1553
+
1554
+ # sheet.range(f'{target_month}6').number_format = f"¥#,##0.00;¥-#,##0.00"
1548
1555
  # sheet.range(f'{target_month}6').value = f"=-'{last_month}月退货与报废单列表'!L2 * 3"
1549
1556
  sheet.range(f'{target_month}7').number_format = f"¥#,##0.00;¥-#,##0.00"
1550
1557
  sheet.range(f'{target_month}7').value = f"=-'{last_month}月补扣款列表'!H2"
1551
1558
  sheet.range(f'{target_month}8').number_format = f"¥#,##0.00;¥-#,##0.00"
1552
1559
  sheet.range(f'{target_month}9').number_format = f"¥#,##0.00;¥-#,##0.00"
1553
- sheet.range(f'{target_month}9').value = f"=SUM({target_month}5:{target_month}8)"
1560
+ sheet.range(f'{target_month}9').value = f"=SUM({target_month}6:{target_month}8)"
1554
1561
  sheet.range(f'{target_month}10').number_format = f"¥#,##0.00;¥-#,##0.00"
1555
- sheet.range(f'{target_month}10').value = f"='{last_month}月库存结余'!J2"
1562
+ sheet.range(f'{target_month}10').value = f"='{last_month}月库存结余'!Q2"
1563
+
1556
1564
  sheet.range('A1').value = f'2025年{last_month}月 shein 利润汇总表 {store_name}'
1557
1565
  sheet.range(f'{target_month}:{target_month}').autofit()
1558
1566
  wb.save()
qrpa/shein_mysql.py CHANGED
@@ -1,62 +1,62 @@
1
- import json
2
-
3
- from .mysql_module.shein_return_order_model import SheinReturnOrderManager
4
- from .mysql_module.shein_product_model import SheinProductManager
5
- from .fun_base import log
6
-
7
- import os
8
-
9
- class SheinMysql:
10
- def __init__(self, config):
11
- self.config = config
12
-
13
- def upsert_shein_return_order(self, json_file):
14
- log(f'当前使用的数据库: {self.config.db.database_url}')
15
- # 创建管理器实例
16
- manager = SheinReturnOrderManager(self.config.db.database_url)
17
- # 创建数据表
18
- manager.create_tables()
19
- # 读取JSON文件
20
- with open(json_file, 'r', encoding='utf-8') as f:
21
- dict = json.load(f)
22
- for store_username, data_list in dict.items():
23
- manager.upsert_return_order_data(store_username, data_list)
24
-
25
- def upsert_shein_product(self, json_file):
26
- log(f'当前使用的数据库: {self.config.db.database_url}')
27
- # 创建管理器实例
28
- manager = SheinProductManager(self.config.db.database_url)
29
- # 创建数据表
30
- manager.create_tables()
31
- with open(json_file, 'r', encoding='utf-8') as f:
32
- file_list = json.load(f)
33
- for store_username, store_skc_list_file in file_list.items():
34
- with open(store_skc_list_file, 'r', encoding='utf-8') as f:
35
- dict_store_skc_list = json.load(f)
36
- for store_username, data_list in dict_store_skc_list.items():
37
- manager.upsert_product_data(data_list)
38
-
39
- def upsert_shein_product_info(self, json_file):
40
- log(f'当前使用的数据库: {self.config.db.database_url}')
41
- # 创建管理器实例
42
- manager = SheinProductManager(self.config.db.database_url)
43
- # 创建数据表
44
- manager.create_tables()
45
- with open(json_file, 'r', encoding='utf-8') as f:
46
- file_list = json.load(f)
47
- for store_username, store_spu_list in file_list.items():
48
- for spu in store_spu_list:
49
- product_detail_file = f'{self.config.auto_dir}/shein/product_detail/product_detail_{spu}.json'
50
- attribute_file = f'{self.config.auto_dir}/shein/attribute/attribute_template_{spu}.json'
51
- if os.path.exists(product_detail_file):
52
- with open(product_detail_file, 'r', encoding='utf-8') as f:
53
- data_list = json.load(f)
54
- manager.upsert_product_detail(spu, 'product_detail', data_list)
55
- else:
56
- log(f'文件不存在: {product_detail_file}')
57
- if os.path.exists(attribute_file):
58
- with open(attribute_file, 'r', encoding='utf-8') as f:
59
- data_list = json.load(f)
60
- manager.upsert_product_detail(spu, 'attribute_template', data_list)
61
- else:
62
- log(f'文件不存在: {attribute_file}')
1
+ import json
2
+
3
+ from .mysql_module.shein_return_order_model import SheinReturnOrderManager
4
+ from .mysql_module.shein_product_model import SheinProductManager
5
+ from .fun_base import log
6
+
7
+ import os
8
+
9
+ class SheinMysql:
10
+ def __init__(self, config):
11
+ self.config = config
12
+
13
+ def upsert_shein_return_order(self, json_file):
14
+ log(f'当前使用的数据库: {self.config.db.database_url}')
15
+ # 创建管理器实例
16
+ manager = SheinReturnOrderManager(self.config.db.database_url)
17
+ # 创建数据表
18
+ manager.create_tables()
19
+ # 读取JSON文件
20
+ with open(json_file, 'r', encoding='utf-8') as f:
21
+ dict = json.load(f)
22
+ for store_username, data_list in dict.items():
23
+ manager.upsert_return_order_data(store_username, data_list)
24
+
25
+ def upsert_shein_product(self, json_file):
26
+ log(f'当前使用的数据库: {self.config.db.database_url}')
27
+ # 创建管理器实例
28
+ manager = SheinProductManager(self.config.db.database_url)
29
+ # 创建数据表
30
+ manager.create_tables()
31
+ with open(json_file, 'r', encoding='utf-8') as f:
32
+ file_list = json.load(f)
33
+ for store_username, store_skc_list_file in file_list.items():
34
+ with open(store_skc_list_file, 'r', encoding='utf-8') as f:
35
+ dict_store_skc_list = json.load(f)
36
+ for store_username, data_list in dict_store_skc_list.items():
37
+ manager.upsert_product_data(data_list)
38
+
39
+ def upsert_shein_product_info(self, json_file):
40
+ log(f'当前使用的数据库: {self.config.db.database_url}')
41
+ # 创建管理器实例
42
+ manager = SheinProductManager(self.config.db.database_url)
43
+ # 创建数据表
44
+ manager.create_tables()
45
+ with open(json_file, 'r', encoding='utf-8') as f:
46
+ file_list = json.load(f)
47
+ for store_username, store_spu_list in file_list.items():
48
+ for spu in store_spu_list:
49
+ product_detail_file = f'{self.config.auto_dir}/shein/product_detail/product_detail_{spu}.json'
50
+ attribute_file = f'{self.config.auto_dir}/shein/attribute/attribute_template_{spu}.json'
51
+ if os.path.exists(product_detail_file):
52
+ with open(product_detail_file, 'r', encoding='utf-8') as f:
53
+ data_list = json.load(f)
54
+ manager.upsert_product_detail(spu, 'product_detail', data_list)
55
+ else:
56
+ log(f'文件不存在: {product_detail_file}')
57
+ if os.path.exists(attribute_file):
58
+ with open(attribute_file, 'r', encoding='utf-8') as f:
59
+ data_list = json.load(f)
60
+ manager.upsert_product_detail(spu, 'attribute_template', data_list)
61
+ else:
62
+ log(f'文件不存在: {attribute_file}')
qrpa/shein_ziniao.py CHANGED
@@ -153,8 +153,8 @@ class ZiniaoBrowser:
153
153
  self.config = config
154
154
 
155
155
  def open_store(self, store_info: str, isWebDriverReadOnlyMode: int = 0,
156
- isprivacy: int = 0, isHeadless: int = 0,
157
- cookieTypeSave: int = 0, jsInfo: str = "") -> Dict[str, Any]:
156
+ isprivacy: int = 0, isHeadless: int = 0,
157
+ cookieTypeSave: int = 0, jsInfo: str = "") -> Dict[str, Any]:
158
158
  """打开店铺"""
159
159
  request_id = str(uuid.uuid4())
160
160
  data = {
@@ -272,7 +272,7 @@ class ZiniaoTaskManager:
272
272
  self.browser = browser
273
273
  self.config = config
274
274
 
275
- def daily_cleanup_superbrowser(self, browser_id):
275
+ def daily_cleanup_superbrowser(self, browser_id, force=False):
276
276
  """
277
277
  每天删除一次SuperBrowser缓存文件夹
278
278
 
@@ -318,7 +318,7 @@ class ZiniaoTaskManager:
318
318
  log(f"读取标志文件时出错: {e}")
319
319
  # 如果读取出错,继续执行清理
320
320
 
321
- if need_cleanup:
321
+ if need_cleanup or force:
322
322
  try:
323
323
  # 删除目标文件夹
324
324
  log(f"正在删除文件夹: {target_folder}")
@@ -340,10 +340,10 @@ class ZiniaoTaskManager:
340
340
  return True
341
341
 
342
342
  def run_single_store_task(self, browser_info: Dict[str, Any],
343
- run_func: Callable, task_key: str,
344
- just_store_username: Optional[List[str]] = None,
345
- is_skip_store: Optional[Callable] = None
346
- ):
343
+ run_func: Callable, task_key: str,
344
+ just_store_username: Optional[List[str]] = None,
345
+ is_skip_store: Optional[Callable] = None
346
+ ):
347
347
  """运行单个店铺的任务"""
348
348
  store_id = browser_info.get('browserOauth')
349
349
  store_name = browser_info.get("browserName")
@@ -420,24 +420,25 @@ class ZiniaoTaskManager:
420
420
  break
421
421
  except:
422
422
  send_exception(f'第{retry_count}次运行失败,准备重新打开店铺: {store_username},{store_name},{store_id}')
423
+ self.daily_cleanup_superbrowser(browser_id)
423
424
  if retry_count > 5:
424
425
  break
425
426
 
426
427
  def run_all_stores_task(self, browser_list: List[Dict[str, Any]],
427
- run_func: Callable, task_key: str,
428
- just_store_username: Optional[List[str]] = None,
429
- is_skip_store: Optional[Callable] = None
430
- ):
428
+ run_func: Callable, task_key: str,
429
+ just_store_username: Optional[List[str]] = None,
430
+ is_skip_store: Optional[Callable] = None
431
+ ):
431
432
  """循环运行所有店铺的任务"""
432
433
  for browser_info in browser_list:
433
434
  self.run_single_store_task(browser_info, run_func, task_key, just_store_username, is_skip_store)
434
435
 
435
436
  def run_with_thread_pool(self, browser_list: List[Dict[str, Any]],
436
- max_threads: int = 3, run_func: Callable = None,
437
- task_key: str = None,
438
- just_store_username: Optional[List[str]] = None,
439
- is_skip_store: Optional[Callable] = None
440
- ):
437
+ max_threads: int = 3, run_func: Callable = None,
438
+ task_key: str = None,
439
+ just_store_username: Optional[List[str]] = None,
440
+ is_skip_store: Optional[Callable] = None
441
+ ):
441
442
  """使用线程池控制最大并发线程数运行任务"""
442
443
  with ThreadPoolExecutor(max_workers=max_threads) as executor:
443
444
  task = partial(self.run_single_store_task,
@@ -460,14 +461,14 @@ class ZiniaoRunner:
460
461
  self.task_manager = ZiniaoTaskManager(self.browser, config)
461
462
 
462
463
  def execute(self, run_prepare: Optional[Callable] = None,
463
- run: Optional[Callable] = None,
464
- run_summary: Optional[Callable] = None,
465
- run_notify: Optional[Callable] = None,
466
- task_key: Optional[str] = None,
467
- just_store_username: Optional[List[str]] = None,
468
- is_skip_store: Optional[Callable] = None,
469
- platform_name: Optional[str] = "SHEIN-全球",
470
- ):
464
+ run: Optional[Callable] = None,
465
+ run_summary: Optional[Callable] = None,
466
+ run_notify: Optional[Callable] = None,
467
+ task_key: Optional[str] = None,
468
+ just_store_username: Optional[List[str]] = None,
469
+ is_skip_store: Optional[Callable] = None,
470
+ platform_name: Optional[str] = "SHEIN-全球",
471
+ ):
471
472
  """主执行入口"""
472
473
  # 前置执行 if run_prepare:
473
474
  run_prepare()