Commit 0b546372 authored by 邱阿朋's avatar 邱阿朋

build: 更新环境配置和构建脚本

- 移除 .env 文件中的敏感信息
- 删除 .gitignore 文件,准备重新配置- 移除现有的源代码文件
- 更新 build.bat 脚本,适应新的项目结构
parent 8dc775b3
亚马逊-财务报表
\ No newline at end of file
# coding: utf-8
import re
import pandas as pd
from openpyxl.reader.excel import load_workbook
def save_xls(data, output_file, sheet_name='Sheet1', adjusted=False):
try:
# 如果文件已存在,则追加新的 sheet
......@@ -39,29 +38,3 @@ def save_xls(data, output_file, sheet_name='Sheet1', adjusted=False):
ws.column_dimensions[column_letter].width = adjusted_width
wb.save(output_file)
def remove_last_comma(csv_file, skip_rows=2):
# 创建一个空列表用于存储处理后的行
cleaned_lines = []
# 读取原始 CSV 文件并处理行末的逗号
with open(csv_file, 'r', encoding='utf-8') as file:
# 跳过指定数量的行
for _ in range(skip_rows):
next(file) # 跳过每一行
for line in file:
# 使用正则表达式替换 空格 + 数字 + 引号
cleaned_line = re.sub(r'(\s\d+)"', r'\1 ', line) # 去掉空格 + 数字后面的引号
# 使用正则表达式替换每个逗号前的空格为引号
cleaned_line = re.sub(r'\s+,\s*"', r'", "', cleaned_line)
# 去掉末尾的逗号和换行符
cleaned_line = cleaned_line.rstrip(',\n')
# 不添加换行符,待会写入时统一处理
cleaned_lines.append(cleaned_line)
# 将处理后的数据逐行写回文件
with open(csv_file, 'w', encoding='utf-8', newline='') as cleaned_file:
for line in cleaned_lines:
cleaned_file.write(line + '\n') # 每一行单独写入,确保每行独立处理
......@@ -4,17 +4,8 @@ import sys
import traceback
def make_dir(path):
# 检查下载目录是否存在,如果不存在则创建
if not os.path.exists(path):
os.makedirs(path)
return False
return True
def get_input_with_default(prompt, default):
user_input = input(f"{prompt}(默认为 '{default}'):")
user_input = input(f"{prompt}; ( 默认'{default}'):")
return user_input.upper() or default
......
# coding: utf-8
import os
import redis
......
# coding: utf-8
from app.helper import logger
log = logger.ConsoleLog()
\ No newline at end of file
# coding: utf-8
from abc import ABC, abstractmethod
# 定义一个接口
class AutoInterface(ABC):
@abstractmethod
def run(self, file_name: str):
pass
# coding: utf-8
# 回款
import os
from datetime import datetime
import pandas as pd
from DrissionPage.errors import ElementNotFoundError
from app.helper import domain, file, rabbitmq, api, excel
from app.vc import log
from app.vc.interface import AutoInterface
from DrissionPage import ChromiumPage as Page
class Payment(AutoInterface):
def __init__(self, page: Page, country: str, payee_code: str, shop_code: str):
self.page = page
self.country = country
self.payeeCode = payee_code
self.shop_code = shop_code
def __page_get(self, url: str):
host = domain.switch_domain(self.country)
full_url = host + url
self.page.get(full_url, timeout=5)
def __export_item_read_data(self, return_id: str):
file_name = f"return_goods\\{return_id}.xls"
if not os.path.isfile(file_name):
while True:
try:
# 打开退回详情下载明细
self.__page_get(f"katalmonsapp/vendor/members/returns/{return_id}")
self.page.ele("#file-download-button").click.to_download(rename=file_name)
file.wait_for_downloads(file_name)
break
except ElementNotFoundError:
log.warning("元素未找到,刷新网页")
self.page.refresh()
# 读取回退商品详情
return pd.read_excel(file_name)
def __push_data_queue(self, file_name: str):
rabbit = rabbitmq.RabbitMQClient()
rabbit.connect(queue='return_robot', routing_key='return_robot', exchange='reports')
data = pd.read_excel(file_name, keep_default_na=False, na_values=[])
for _, item_row in data.iterrows():
push_data = {
'return_id': item_row.get('Return ID', ''),
'asin': item_row.get('ASIN', ''), # ASIN
'order_no': item_row.get('Purchase order', ''), # 订单号
'sku_quantity': item_row.get('Quantity', 0), # 退回数量
'sku_amount': item_row.get('Total cost', 0), # Total cost
'currency': item_row.get('Currency code', ''), # Currency code
'data_date': str(item_row.get('Return Date', '')), # Return Date
'erp_sku': item_row.get("SKU", ''), # ERP SKU # SKU1匹配
'shop_code': self.shop_code, # 店铺code
'supplier_code': item_row.get('Vendor code', ''), # 供应商编码
'group_name': item_row.get('Group Name', ""), # 组别 运营一组 运营二组
'group_code': item_row.get('Group Code', ""), # 组别 T1 T2
}
# 推送数据
rabbit.send_message(push_data)
def run(self, file_name: str):
if not os.path.isfile(file_name):
raise FileNotFoundError(f"{file_name},文件不存在")
# 读取sku映射关系
relations_dict = api.sku_relations(self.country)
list_data = pd.read_excel(file_name)
# 下载并读取list数据
log.info(f"共计:{len(list_data)} 订单")
new_list_data = []
i = 0
for _, data in list_data.iterrows():
i += 1
return_id = data.get('Return ID')
log.info({"index": i, "return_id": return_id})
# 下载退货详情表格读取数据
item_data = self.__export_item_read_data(return_id)
# 按 'Purchase order' 和 'ASIN' 分组,并对 'Quantity' 和 Total amount 进行求和
item_data_result = item_data.groupby(['Purchase order', 'ASIN', 'Reason'], as_index=False).agg({
'Quantity': 'sum',
'Total amount': 'sum',
})
for _, item_row in item_data_result.iterrows():
relation = relations_dict.get(item_row.get('ASIN'))
erp_sku = relation.get('erp_sku', "")
data_dict = data.to_dict()
data_dict.update({
'Return Date': data_dict['Return Date'].strftime('%m/%d/%Y'),
'Return ID': str(data_dict['Return ID']),
'PO': item_row.get('Purchase order', ""),
'ASIN': item_row.get('ASIN', ""),
'SKU': erp_sku,
'Quantity': item_row.get('Quantity', 0),
# 替换回会数量和金额为详情里面的值
'Return quantity': item_row.get('Quantity', 0), # 替换回会数量
'Reason': item_row.get('Reason', ""),
'Total cost': item_row.get('Total amount', 0), # 替换金额
'Group Name': relation.get("name", ""),
'Group Code': relation.get("code", ""),
})
# 追加数据
new_list_data.append(data_dict)
# 获取当前日期和时间并格式化
current_datetime = datetime.now().strftime('%Y-%m-%d-%H-%M')
# 原文件名
file_name = "退货明细.xlsx"
# 拼接新的文件名
new_file_name = f"{current_datetime}_{self.country}_{file_name}"
excel.save_xls(new_list_data, new_file_name)
# 推送消息
self.__push_data_queue(new_file_name)
\ No newline at end of file
# coding: utf-8
# 回款明细
import pandas as pd
from DrissionPage import ChromiumPage as Page
from app.helper import rabbitmq
from app.vc import log
from app.vc.interface import AutoInterface
class PaymentPush(AutoInterface):
def __init__(self, page: Page, country: str, payee_code: str, shop_code: str):
self.page = page
self.country = country
self.payeeCode = payee_code
self.shop_code = shop_code
@staticmethod
def __read_data(file_name):
df = pd.read_excel(file_name, header=None)
# 定位标题行
pay_title = df[df[0].str.contains('Remittance payments', case=False, na=False)].index[0]
inv_title = df[df[0].str.contains('Invoices', case=False, na=False)].index[0]
# 定位表头起始行(跳过标题后的空行)
pay_header = df.loc[pay_title + 1:].notna().any(axis=1).idxmax()
inv_header = df.loc[inv_title + 1:].notna().any(axis=1).idxmax()
# 计算第一个表格的结束位置(第二个标题前的空行)
empty_lines = df.index[df.isnull().all(axis=1)].tolist()
separator = max([x for x in empty_lines if pay_header < x < inv_title], default=inv_title - 1)
# 读取并清理数据
test = separator - pay_header - 1
payments = pd.read_excel(file_name, header=pay_header, nrows=test).dropna(how='all')
invoices = pd.read_excel(file_name, header=inv_header).dropna(how='all')
return [payments, invoices]
def run(self, file_name: str):
payments, invoices = self.__read_data(file_name)
# 将 'Payment Number' 列设置为索引
payments.set_index('Payment Number', inplace=True)
# 转换为字典,orient='index' 表示以索引为键
payments_map = payments.to_dict(orient='index')
log.info(f"共计:{len(invoices)} 订单")
rabbit = rabbitmq.RabbitMQClient()
rabbit.connect(queue='refund_robot', routing_key='refund_robot', exchange='reports')
i = 0
for _, data in invoices.iterrows():
i += 1
payment_number = data.get("Payment Number")
payment_date = payments_map.get(payment_number, {}).get('Payment Date', '')
platform_payable_amount = data.get('Invoice Amount', '')
if self.country == 'FR' or self.country == 'UK':
platform_payable_amount = data.get('Net Amount Paid', '')
push_data = {
'payment_number': data.get('Payment Number', ''), # 订单id
'order_date': str(data.get('Invoice Date', '')), # 发票时间
'payment_date': str(payment_date),
'order_no': data.get('Invoice Number', 0), # 订单号
'payment_type': data.get('Description', ''), # Description
'platform_payable_amount': platform_payable_amount, # 平台应付金额
'fee_amount': data.get("Terms Discount Taken", ''), # 手续费
'actual_payment': data.get('Amount Paid', ''), # 实际支付金额
'currency': data.get('Invoice Currency', ''), # 货币
'shop_code': self.shop_code, # 店铺code
}
# 推送数据
rabbit.send_message(push_data)
# coding: utf-8
# 退货
import os
from datetime import datetime
import pandas as pd
from DrissionPage.errors import ElementNotFoundError
from app.helper import domain, api, excel, rabbitmq, file
from app.vc import log
from app.vc.interface import AutoInterface
from DrissionPage import ChromiumPage as Page
class ReturnGoods(AutoInterface):
def __init__(self, page: Page, country: str, payee_code: str, shop_code: str):
self.page = page
self.country = country
self.payeeCode = payee_code
self.shop_code = shop_code
def __page_get(self, url):
host = domain.switch_domain(self.country)
full_url = host + url
self.page.get(full_url, timeout=5)
def __export_item_read_data(self, return_id: str):
file_name = f"return_goods\\{return_id}.xls"
if not os.path.isfile(file_name):
while True:
try:
# 打开退回详情下载明细
self.__page_get(f"katalmonsapp/vendor/members/returns/{return_id}")
self.page.ele("#file-download-button").click.to_download(rename=file_name)
file.wait_for_downloads(file_name)
break
except ElementNotFoundError:
log.warning("元素未找到,刷新网页")
self.page.refresh()
# 读取回退商品详情
return pd.read_excel(file_name)
def __push_data_queue(self, file_name):
rabbit = rabbitmq.RabbitMQClient()
rabbit.connect(queue='return_robot', routing_key='return_robot', exchange='reports')
data = pd.read_excel(file_name, keep_default_na=False, na_values=[])
for _, item_row in data.iterrows():
push_data = {
'return_id': item_row.get('Return ID', ''),
'asin': item_row.get('ASIN', ''), # ASIN
'order_no': item_row.get('Purchase order', ''), # 订单号
'sku_quantity': item_row.get('Quantity', 0), # 退回数量
'sku_amount': item_row.get('Total cost', 0), # Total cost
'currency': item_row.get('Currency code', ''), # Currency code
'data_date': str(item_row.get('Return Date', '')), # Return Date
'erp_sku': item_row.get("SKU", ''), # ERP SKU # SKU1匹配
'shop_code': self.shop_code, # 店铺code
'supplier_code': item_row.get('Vendor code', ''), # 供应商编码
'group_name': item_row.get('Group Name', ""), # 组别 运营一组 运营二组
'group_code': item_row.get('Group Code', ""), # 组别 T1 T2
}
# 推送数据
rabbit.send_message(push_data)
def run(self, file_name: str):
if not os.path.isfile(file_name):
raise FileNotFoundError(f"{file_name},文件不存在")
# 读取sku映射关系
relations_dict = api.sku_relations(self.country)
# 读取list数据
list_data = pd.read_excel(file_name)
log.info(f"共计:{len(list_data)} 订单")
new_list_data = []
i = 0
for _, data in list_data.iterrows():
i += 1
return_id = data.get('Return ID')
log.info({"index": i, "return_id": return_id})
# 下载退货详情表格读取数据
item_data = self.__export_item_read_data(return_id)
# 按 'Purchase order' 和 'ASIN' 分组,并对 'Quantity' 和 Total amount 进行求和
item_data_result = item_data.groupby(['Purchase order', 'ASIN', 'Reason'], as_index=False).agg({
'Quantity': 'sum',
'Total amount': 'sum',
})
for _, item_row in item_data_result.iterrows():
relation = relations_dict.get(item_row.get('ASIN'))
erp_sku = relation.get('erp_sku', "")
data_dict = data.to_dict()
data_dict.update({
'Return Date': data_dict['Return Date'].strftime('%m/%d/%Y'),
'Return ID': str(data_dict['Return ID']),
'PO': item_row.get('Purchase order', ""),
'ASIN': item_row.get('ASIN', ""),
'SKU': erp_sku,
'Quantity': item_row.get('Quantity', 0),
# 替换回会数量和金额为详情里面的值
'Return quantity': item_row.get('Quantity', 0), # 替换回会数量
'Reason': item_row.get('Reason', ""),
'Total cost': item_row.get('Total amount', 0), # 替换金额
'Group Name': relation.get("name", ""),
'Group Code': relation.get("code", ""),
})
# 追加数据
new_list_data.append(data_dict)
# 获取当前日期和时间并格式化
current_datetime = datetime.now().strftime('%Y-%m-%d-%H-%M')
# 原文件名
file_name = "退货明细.xlsx"
# 拼接新的文件名
new_file_name = f"{current_datetime}_{self.country}_{file_name}"
excel.save_xls(new_list_data, new_file_name)
# 推送消息
self.__push_data_queue(new_file_name)
This diff is collapsed.
pip.exe install -i https://mirrors.cloud.tencent.com/pypi/simple -r requirements.txt
pyinstaller -F -n payment.exe .\src\payment.py
pyinstaller -F -n payment_erp.exe .\src\payment_erp.py
pyinstaller -F -n advertise_erp.exe .\src\advertise_erp.py
pyinstaller -F -n return_goods.exe .\src\return_goods.py
pyinstaller -F -n spa_search.exe .\src\spa_search.py
pyinstaller -F -n easy_storage.exe .\src\easy_storage.py
pyinstaller -F -n diff_spa.exe .\cmd\diff_spa.py
pyinstaller -F -n amazon_vc.exe main.py
rd /s /q build
del *.spec
\ No newline at end of file
import os.path
import pandas as pd
import argparse
class InvoiceIDComparator:
def __init__(self, file_a, file_b, invoice_column_name):
self.file_a = file_a
self.file_b = file_b
self.invoice_column_name = invoice_column_name
def get_invoice_ids_from_excel(self, file_path):
"""从Excel文件中获取所有sheet的Invoice ID"""
excel_file = pd.ExcelFile(file_path)
invoice_ids = set() # 使用集合去重
for sheet_name in excel_file.sheet_names:
# 读取每个sheet的内容
df = excel_file.parse(sheet_name)
# 确保指定的列存在
if self.invoice_column_name in df.columns:
invoice_ids.update(df[self.invoice_column_name].dropna().unique())
invoice_ids.add(sheet_name) # 将sheet名也加入到集合中
return invoice_ids
def compare_invoice_ids(self):
"""比较两个Excel文件中的Invoice ID"""
# 获取文件A中的Invoice ID和所有sheet名称
invoice_ids_a = self.get_invoice_ids_from_excel(self.file_a)
# 获取文件B中的Invoice ID和所有sheet名称
invoice_ids_b = self.get_invoice_ids_from_excel(self.file_b)
only_in_a = invoice_ids_a - invoice_ids_b
only_in_b = invoice_ids_b - invoice_ids_a
# 输出比较结果
print("文件A中存在,但文件B中没有的 Invoice IDs:")
print(only_in_a)
print("\n文件B中存在,但文件A中没有的 Invoice IDs:")
print(only_in_b)
def main():
# 设置命令行参数
parser = argparse.ArgumentParser(description="比较两个Excel文件中的Invoice ID差异")
parser.add_argument('--original_file', default="ContraCogsInvoices.xls", help="原文件路径")
parser.add_argument('--result_file', default="result.xls", help="结果文件路径")
parser.add_argument('--invoice_column', default='Invoice ID', help="Invoice ID列的名称")
# 解析命令行参数
args = parser.parse_args()
if os.path.exists(args.original_file) is False:
raise FileExistsError("源文件不存在")
if os.path.exists(args.result_file) is False:
raise FileExistsError("结果文件不存在")
# 创建 InvoiceIDComparator 实例并进行比较
comparator = InvoiceIDComparator(args.original_file, args.result_file, args.invoice_column)
comparator.compare_invoice_ids()
# 程序入口
if __name__ == "__main__":
try:
main()
except Exception as e:
print(e)
\ No newline at end of file
# coding: utf-8
import json
from datetime import datetime
import requests
import xmltodict
import pandas as pd
from datetime import datetime
class YcClient:
......
# coding: utf-8
import os
from app.helper import file, domain, helper
from app.vc.payment import Payment
from app.vc.return_goods import ReturnGoods
from app.vc.spa import Spa
from DrissionPage import ChromiumPage
from dotenv import load_dotenv
if __name__ == '__main__':
load_dotenv()
page = ChromiumPage()
page.set.load_mode.normal()
page.set.when_download_file_exists('overwrite')
# 下载目录
download_path = os.getcwd()
# 检查下载目录是否存在,如果不存在则创建
file.make_dir(download_path)
# 设置下载路径,确保在打开浏览器前设置
page.set.download_path(download_path)
try:
country = helper.get_input_with_default("国家: [ DE, FR, JP, CA, UK, US ]", "US")
shop_code = helper.get_input_with_default("店铺编码: [ DE-VC, FR-VC, JP-VC, CA-VC, UK-VC, VECELO ]", "VECELO")
payee_code = helper.get_input_with_default("回款Code: [ 详情页url参数 payeeCode ]", "VECET")
action = helper.get_input_with_default("功能:[ spa, return, payment ]", "")
file_name = helper.get_input_with_default("文件名 : [ 例如: ContraCogsInvoices.xls ]", "")
if action.lower() == "payment":
object_instate = Payment(page, country, payee_code, shop_code)
elif action.lower() == "return":
object_instate = ReturnGoods(page, country, payee_code, shop_code)
elif action.lower() == "spa":
object_instate = Spa(page, country, payee_code, shop_code)
else:
raise Exception("请输入正确的功能")
if file_name == "":
raise Exception("请输入文件名")
domain.domain_page(page, country)
object_instate.run(file_name)
except KeyboardInterrupt:
pass
except Exception as e:
helper.print_trace("main", e)
finally:
page.close()
# coding: utf-8
# 广告费
import os
import warnings
import pandas as pd
from dotenv import load_dotenv
from helper import helper, logger, redisx, rabbitmq
from helper import api
# 忽略 openpyxl 样式警告
warnings.filterwarnings("ignore", category=UserWarning, module="openpyxl")
country = None
payeeCode = None
shop_code = None
load_dotenv()
log = logger.ConsoleLog()
rdb = redisx.RedisClient()
def main():
# 读取sku映射关系
relations_dict = api.sku_relations(country)
file_name = "Sponsored_Products_Advertised_product_report.xlsx"
if not os.path.isfile(file_name):
raise FileNotFoundError(f"{file_name},文件不存在")
result = pd.read_excel(file_name, keep_default_na=False, na_values=[])
log.info(f"共计:{len(result)} 订单")
rabbit = rabbitmq.RabbitMQClient()
rabbit.connect(queue='advertising_robot', routing_key='advertising_robot', exchange='reports')
for _, data in result.iterrows():
relation = relations_dict.get(data.get('Advertised ASIN',""), {})
push_data = {
'ad_date': str(data.get("End Date", "")), # 日期
'erp_sku': relation.get('erp_sku', ""), # erp_sku
'ad_amount': data.get("Spend", ""), # 金额
'ad_amount_currency': data.get("Currency", ""), # 币种
'operator_name': "", # 运营名
'group_code': relation.get("code", ""),
'asin': data.get("Advertised ASIN", ""), # asin
'shop_code': shop_code, # 店铺code
}
rabbit.send_message(push_data)
if __name__ == '__main__':
try:
country = helper.get_input_with_default("国家(目前支持[DE,FR,JP,CA,UK,US])", "US")
shop_code = helper.get_input_with_default("店铺编码(DE-VC,FR-VC,JP-VC,CA-VC,UK-VC,VECELO])", "VECELO")
main()
except KeyboardInterrupt:
pass
except Exception as e:
log.error(e)
helper.print_trace("main", e)
This diff is collapsed.
# coding: utf-8
# 回款明细
import os
import warnings
import pandas as pd
from DrissionPage import ChromiumPage
from DrissionPage.errors import ElementNotFoundError
from dotenv import load_dotenv
from helper import helper, file, domain, logger, redisx, rabbitmq
country = None
shop_code = None
load_dotenv()
log = logger.ConsoleLog()
rdb = redisx.RedisClient()
page = ChromiumPage()
page.set.load_mode.normal()
page.set.when_download_file_exists('overwrite')
# 下载目录
download_path = os.getcwd()
# 检查下载目录是否存在,如果不存在则创建
helper.make_dir(download_path)
# 设置下载路径,确保在打开浏览器前设置
page.set.download_path(download_path)
# 忽略 openpyxl 样式警告
warnings.filterwarnings("ignore", category=UserWarning, module="openpyxl")
def page_get(url):
host = domain.switch_domain(country)
full_url = host + url
page.get(full_url, timeout=5)
def export_list_read_data():
file_name = 'Payments.xlsx'
# try:
# while True:
# page_get(f"hz/vendor/members/remittance/home")
#
# # 选择日期下拉框
# page.ele("#date-range-option-wrap").click()
# page.wait(1)
# # 点击第一个选项
# page.ele("#date-range-option_0").click()
# page.wait(1)
# # 点击搜索按钮
# page.ele("#remittanceSearchForm-submit-aui-button").click()
# page.wait(2)
#
# page.ele("#remittance-home-select-all").click()
# page.ele("#remittance-home-export-link").click.to_download()
# is_down = file.wait_for_downloads(file_name, 30)
# if is_down: break
# log.warning(f"下载失败,重新下载")
# except ElementNotFoundError:
# log.error("页面加载失败,刷新重新加载")
# page.refresh()
df = pd.read_excel(file_name, header=None)
# 定位标题行
pay_title = df[df[0].str.contains('Remittance payments', case=False, na=False)].index[0]
inv_title = df[df[0].str.contains('Invoices', case=False, na=False)].index[0]
# 定位表头起始行(跳过标题后的空行)
pay_header = df.loc[pay_title + 1:].notna().any(axis=1).idxmax()
inv_header = df.loc[inv_title + 1:].notna().any(axis=1).idxmax()
# 计算第一个表格的结束位置(第二个标题前的空行)
empty_lines = df.index[df.isnull().all(axis=1)].tolist()
separator = max([x for x in empty_lines if pay_header < x < inv_title], default=inv_title - 1)
# 读取并清理数据
test = separator - pay_header - 1
payments = pd.read_excel(file_name, header=pay_header, nrows=test).dropna(how='all')
invoices = pd.read_excel(file_name, header=inv_header).dropna(how='all')
return [payments, invoices]
def main():
payments, invoices = export_list_read_data()
# 将 'Payment Number' 列设置为索引
payments.set_index('Payment Number', inplace=True)
# 转换为字典,orient='index' 表示以索引为键
payments_map = payments.to_dict(orient='index')
log.info(f"共计:{len(invoices)} 订单")
rabbit = rabbitmq.RabbitMQClient()
rabbit.connect(queue='refund_robot', routing_key='refund_robot', exchange='reports')
i = 0
for _, data in invoices.iterrows():
i += 1
payment_number = data.get("Payment Number")
payment_date = payments_map.get(payment_number, {}).get('Payment Date', '')
platform_payable_amount = data.get('Invoice Amount', '')
if country == 'FR' or country == 'UK':
platform_payable_amount = data.get('Net Amount Paid', '')
push_data = {
'payment_number': data.get('Payment Number', ''), # 订单id
'order_date': str(data.get('Invoice Date', '')), # 发票时间
'payment_date': str(payment_date),
'order_no': data.get('Invoice Number', 0), # 订单号
'payment_type': data.get('Description', ''), # Description
'platform_payable_amount': platform_payable_amount, # 平台应付金额
'fee_amount': data.get("Terms Discount Taken", ''), # 手续费
'actual_payment': data.get('Amount Paid', ''), # 实际支付金额
'currency': data.get('Invoice Currency', ''), # 货币
'shop_code': shop_code, # 店铺code
}
# 推送数据
rabbit.send_message(push_data)
if __name__ == '__main__':
try:
country = helper.get_input_with_default("国家(目前支持[DE,FR,JP,CA,UK,US])", "US")
shop_code = helper.get_input_with_default("店铺编码(DE-VC,FR-VC,JP-VC,CA-VC,UK-VC,VECELO])", "VECELO")
domain.domain_page(page, country)
main()
except KeyboardInterrupt:
pass
except Exception as e:
log.error(e)
helper.print_trace("main", e)
# coding: utf-8
# 导出退款记录
import os
from datetime import datetime
import pandas as pd
from DrissionPage import ChromiumPage
from DrissionPage.errors import ElementNotFoundError
from dotenv import load_dotenv
from helper import helper, excel, file, domain, logger, api, rabbitmq
country = None
shop_code = None
load_dotenv()
log = logger.ConsoleLog()
page = ChromiumPage()
page.set.load_mode.normal()
page.set.when_download_file_exists('overwrite')
# 下载目录
download_path = os.getcwd()
# 检查下载目录是否存在,如果不存在则创建
helper.make_dir(download_path)
# 设置下载路径,确保在打开浏览器前设置
page.set.download_path(download_path)
def page_get(url):
host = domain.switch_domain(country)
full_url = host + url
page.get(full_url, timeout=5)
def export_list_read_data():
file_name = "Return_Summary.xls"
if not os.path.isfile(file_name):
raise FileNotFoundError(f"{file_name},文件不存在")
return pd.read_excel(file_name)
def export_item_read_data(return_id):
file_name = f"{country}_return_goods\\{return_id}.xls"
if not os.path.isfile(file_name):
while True:
try:
# 打开退回详情下载明细
page_get(f"katalmonsapp/vendor/members/returns/{return_id}")
page.ele("#file-download-button").click.to_download(rename=file_name)
file.wait_for_downloads(file_name)
break
except ElementNotFoundError:
log.warning("元素未找到,刷新网页")
page.refresh()
# 读取回退商品详情
return pd.read_excel(file_name)
def main():
# 读取sku映射关系
relations_dict = api.sku_relations(country)
# 下载并读取list数据
list_data = export_list_read_data()
log.info(f"共计:{len(list_data)} 订单")
new_list_data = []
i = 0
for _, data in list_data.iterrows():
i += 1
return_id = data.get('Return ID')
log.info({"index": i, "return_id": return_id})
# 下载退货详情表格读取数据
item_data = export_item_read_data(return_id)
# 按 'Purchase order' 和 'ASIN' 分组,并对 'Quantity' 和 Total amount 进行求和
item_data_result = item_data.groupby(['Purchase order', 'ASIN', 'Reason'], as_index=False).agg({
'Quantity': 'sum',
'Total amount': 'sum',
})
for _, item_row in item_data_result.iterrows():
relation = relations_dict.get(item_row.get('ASIN'))
erp_sku = relation.get('erp_sku', "")
data_dict = data.to_dict()
data_dict.update({
'Return Date': data_dict['Return Date'].strftime('%m/%d/%Y'),
'Return ID': str(data_dict['Return ID']),
'PO': item_row.get('Purchase order', ""),
'ASIN': item_row.get('ASIN', ""),
'SKU': erp_sku,
'Quantity': item_row.get('Quantity', 0),
# 替换回会数量和金额为详情里面的值
'Return quantity': item_row.get('Quantity', 0), # 替换回会数量
'Reason': item_row.get('Reason', ""),
'Total cost': item_row.get('Total amount', 0), # 替换金额
'Group Name': relation.get("name", ""),
'Group Code': relation.get("code", ""),
})
# 追加数据
new_list_data.append(data_dict)
# 获取当前日期和时间并格式化
current_datetime = datetime.now().strftime('%Y-%m-%d-%H-%M')
# 原文件名
file_name = "退货明细.xlsx"
# 拼接新的文件名
new_file_name = f"{current_datetime}_{country}_{file_name}"
excel.save_xls(new_list_data, new_file_name)
# 推送消息
push_data_queue(new_file_name)
def push_data_queue(file_name):
rabbit = rabbitmq.RabbitMQClient()
rabbit.connect(queue='return_robot', routing_key='return_robot', exchange='reports')
data = pd.read_excel(file_name, keep_default_na=False, na_values=[])
for _, item_row in data.iterrows():
push_data = {
'return_id': item_row.get('Return ID', ''),
'asin': item_row.get('ASIN', ''), # ASIN
'order_no': item_row.get('Purchase order', ''), # 订单号
'sku_quantity': item_row.get('Quantity', 0), # 退回数量
'sku_amount': item_row.get('Total cost', 0), # Total cost
'currency': item_row.get('Currency code', ''), # Currency code
'data_date': str(item_row.get('Return Date', '')), # Return Date
'erp_sku': item_row.get("SKU", ''), # ERP SKU # SKU1匹配
'shop_code': shop_code, # 店铺code
'supplier_code': item_row.get('Vendor code', ''), # 供应商编码
'group_name': item_row.get('Group Name', ""), # 组别 运营一组 运营二组
'group_code': item_row.get('Group Code', ""), # 组别 T1 T2
}
# 推送数据
rabbit.send_message(push_data)
if __name__ == '__main__':
try:
country = helper.get_input_with_default("国家(目前支持[DE,FR,JP,CA,UK,US])", "US")
shop_code = helper.get_input_with_default("店铺编码(DE-VC,FR-VC,JP-VC,CA-VC,UK-VC,VECELO])", "VECELO")
domain.domain_page(page, country)
main()
page.close()
except KeyboardInterrupt:
pass
except Exception as e:
log.error(e)
helper.print_trace("main", e)
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment