data.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. import json
  2. from ..data_metaclass import DataBaseModel
  3. import copy
  4. import pandas as pd
  5. import settings
  6. import numpy as np
  7. class DataModeGenerateDetail(DataBaseModel):
  8. def __init__(self):
  9. super().__init__()
  10. self.get_online_data.refresh_headers()
  11. def get_real_color_name(self, color_name: str):
  12. _ = ["薄棉", "加厚", "厚棉"]
  13. for i in _:
  14. color_name = color_name.replace(i, "")
  15. return color_name
  16. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None):
  17. if goods_art_list:
  18. data_list = copy.deepcopy(goods_art_list)
  19. flag = "Goods_Art"
  20. else:
  21. data_list = copy.deepcopy(numbers_list)
  22. flag = "NUM"
  23. _list = []
  24. # 单次请求数少于20个
  25. goods_dict = {}
  26. while data_list:
  27. one_data = data_list.pop()
  28. _list.append(one_data)
  29. if len(_list) == 20 or len(data_list) == 0:
  30. if flag == "NUM":
  31. # 注意,红蜻蜓和惠利玛函数不同
  32. online_goods_art_data = self.get_online_data.get_goods_art_no_info(numbers_list=_list)
  33. else:
  34. online_goods_art_data = self.get_online_data.get_goods_art_no_info(goods_art_list=_list)
  35. if online_goods_art_data:
  36. for key in online_goods_art_data:
  37. # 映射为真实的文件夹名称
  38. goods_dict[key] = online_goods_art_data[key]
  39. _list = []
  40. return goods_dict
  41. def get_basic_goods_art_data_by_hqt_and_hlm(self, folder_name_list):
  42. """
  43. 查询红蜻蜓货号的对应数据,输入写入为编码,可能带有@,可能为货号等 NUN为编码
  44. """
  45. original_folder_name_list = copy.deepcopy(folder_name_list)
  46. # 编号与文件名映射表
  47. return_dict = {}
  48. for folder_name in original_folder_name_list:
  49. folder_name: str
  50. if "NUM" not in folder_name:
  51. # 即为货号
  52. return_dict[folder_name] = {"type": "goods_art_no",
  53. "name": folder_name.upper(),
  54. "文件夹名称": folder_name,
  55. "data": {}
  56. }
  57. else:
  58. if "@" not in folder_name:
  59. return_dict[folder_name] = {"type": "goods_number",
  60. "name": folder_name.upper().replace("NUM", ""),
  61. "文件夹名称": folder_name,
  62. "data": {}
  63. }
  64. else:
  65. return_dict[folder_name] = {"type": "goods_number",
  66. "name": folder_name.upper().replace("NUM", "").split("@")[1],
  67. "文件夹名称": folder_name,
  68. "data": {}
  69. }
  70. # -----------请求货号数据处理------------
  71. goods_art_no_list = [v["name"] for k, v in return_dict.items() if v["type"] == "goods_art_no"]
  72. goods_art_no_all_data = self.get_goods_art_no_info(goods_art_list=goods_art_no_list)
  73. for folder_name, value in return_dict.items():
  74. if value["type"] == "goods_art_no":
  75. if value["name"] in goods_art_no_all_data:
  76. return_dict[folder_name]["data"] = goods_art_no_all_data[value["name"]]
  77. # ------------请求编码数据----------------------
  78. goods_number_list = [v["name"] for k, v in return_dict.items() if v["type"] == "goods_number"]
  79. goods_number_all_data = self.get_goods_art_no_info(numbers_list=goods_number_list)
  80. for folder_name, value in return_dict.items():
  81. if value["type"] == "goods_number":
  82. if value["name"] in goods_number_all_data:
  83. return_dict[folder_name]["data"] = goods_number_all_data[value["name"]]
  84. # 清空没有值的数据
  85. error_key = []
  86. for folder_name, value in return_dict.items():
  87. if not value["data"]:
  88. error_key.append(folder_name)
  89. if error_key:
  90. for folder_name in error_key:
  91. return_dict.pop(folder_name)
  92. return {"code": 0, "message": "", "data": return_dict}
  93. def get_basic_goods_art_data_form_excel(self, folder_name_list, excel_path, keys):
  94. # =====创建虚拟表格并进行连表处理
  95. need_df = pd.DataFrame(columns=["商品货号"])
  96. for folder_name in folder_name_list:
  97. new_row = {"商品货号": str(folder_name),
  98. }
  99. need_df = need_df._append(new_row, ignore_index=True)
  100. need_df = need_df.fillna(value='')
  101. # 打开表格并进行匹配
  102. _df = pd.read_excel(excel_path, sheet_name=0, header=0)
  103. # 去重数据
  104. duplicates = _df.duplicated(subset=['商品货号'], keep="first")
  105. _df = _df.loc[~duplicates]
  106. _df = _df.fillna(value='')
  107. _df = _df.astype(str)
  108. # 数据匹配关联,左关联
  109. need_df = pd.merge(need_df, _df, on=["商品货号"], how="left", indicator=False, )
  110. # 补全字段
  111. header_list = need_df.columns.values.tolist()
  112. for key in keys:
  113. if key not in header_list:
  114. need_df[key] = ""
  115. need_df = need_df.fillna(value='')
  116. need_df = need_df.astype(str)
  117. # 数据转字典
  118. return_dict = {}
  119. message = ""
  120. for index, row in need_df.iterrows():
  121. if settings.PROJECT == "红蜻蜓":
  122. if row["商品货号"] and row["款号"]:
  123. return_dict[row["商品货号"]] = {
  124. "type": "goods_art_no",
  125. "name": row["商品货号"].upper(),
  126. "template_name": row["模板名称"],
  127. "data": row.to_dict(),
  128. }
  129. else:
  130. message = "商品货号、款号、编号必须有值"
  131. else:
  132. if row["商品货号"] and row["款号"]:
  133. return_dict[row["商品货号"]] = {
  134. "type": "goods_art_no",
  135. "name": row["商品货号"].upper(),
  136. "文件夹名称": row["商品货号"],
  137. "template_name": row["模板名称"],
  138. "data": row.to_dict(),
  139. }
  140. print("return_dict", return_dict)
  141. if not return_dict:
  142. message += "\n没有找到任何匹配的数据"
  143. return {"code": 99, "message": message, "data": return_dict}
  144. else:
  145. return {"code": 0, "message": message, "data": return_dict}
  146. def check_goods_is_not_deficiency(self, goods_no_dict: dict):
  147. # 数据返回结果为款号列表
  148. error_data = {}
  149. for key, value in goods_no_dict.items():
  150. number = value["货号资料"][0]["编号"].replace("NUM", "")
  151. number_list = [x["编号"].replace("NUM", "") for x in value["货号资料"]]
  152. all_color_name = [self.get_real_color_name(x["颜色名称"]) for x in value["货号资料"]] # 本地数据
  153. goods_no = key
  154. _t_goods_number, all_goods_number = self.get_online_data.get_on_goods_all_art(number=number)
  155. # all_goods_number------》 [{'number': '14250232', 'goods_art_no': 'AC52001173', 'color': '杏色'}]
  156. for i in all_goods_number:
  157. if i["number"] not in number_list:
  158. # 检查款号+颜色名称是否已经存在
  159. real_color = self.get_real_color_name(i["color"])
  160. if real_color not in all_color_name:
  161. if goods_no not in error_data:
  162. error_data[goods_no] = {"message": "颜色:"}
  163. error_data[goods_no]["message"] += "{}缺失 ".format(real_color)
  164. return error_data
  165. def get_basic_template_information(self, _goods_no_dict, excel_path: str):
  166. # 本地的文件夹数据形成一个虚拟表格
  167. original_df = pd.DataFrame(columns=["款号"])
  168. for goods_no in _goods_no_dict:
  169. new_row = {"款号": str(goods_no),
  170. "flag": "是"
  171. }
  172. original_df = original_df._append(new_row, ignore_index=True)
  173. original_df = original_df.fillna(value='')
  174. # EXCEL表格数据
  175. local_df = pd.read_excel(excel_path, sheet_name=0, header=0)
  176. values = {'模板名称': "任意", }
  177. # 确保所有模板都有名称
  178. local_df.fillna(value=values, inplace=True)
  179. # 分组后取第一个有效值(即不是NaN的值);此处用于获取某个款号的所有基础信息
  180. group_local_df = local_df.groupby(['模板名称', '款号']).agg(
  181. lambda x: x.dropna().iloc[0] if not x.dropna().empty else np.nan)
  182. group_local_df = group_local_df.reset_index()
  183. # -----------数据匹配关联,左关联
  184. group_local_df = pd.merge(group_local_df, original_df, on=["款号"], how="left", indicator=False, )
  185. # -----------只取有标记的数据
  186. group_local_df = group_local_df.loc[~group_local_df['flag'].isnull(), :]
  187. group_local_df = group_local_df.loc[group_local_df['模板名称'] != "任意", :]
  188. # -----------数据规整
  189. group_local_df = group_local_df.fillna(value='')
  190. group_local_df = group_local_df.astype(str)
  191. # 组装成字典
  192. temp_goods_no_dict = {}
  193. for index, row in group_local_df.iterrows():
  194. goods_no = row["款号"]
  195. if goods_no not in temp_goods_no_dict:
  196. temp_goods_no_dict[goods_no] = {}
  197. temp_goods_no_dict[goods_no][row["模板名称"]] = row.to_dict()
  198. return temp_goods_no_dict
  199. def check_goods_is_not_deficiency_form_excel(self, goods_no_dict: dict, excel_path: str):
  200. # 检查颜色是否齐全,基于Excel处理
  201. """
  202. 步骤:
  203. 1、goods_no_dict款号生成一个表格(款号+颜色)
  204. 2、excel表格数据进行款号+颜色去重
  205. 3、excel表格关联 上述的款号 进行标记,其他删除
  206. 4、excel表格关联 上述款号与颜色,进行标记
  207. 5、上述未标记的就是没有的颜色(有对应款号)。
  208. 6、对对应的款号进行设置为错误数据
  209. 返回数据结构
  210. {
  211. “A00001--款号”:{“message”:“这个款的错误原因”},
  212. “A00002--款号”:{“message”:“这个款的错误原因”},
  213. }
  214. """
  215. def change_to_int(x):
  216. if pd.isna(x):
  217. return 0
  218. else:
  219. try:
  220. x = int(x)
  221. return str(x)
  222. except:
  223. return x
  224. error_data = {}
  225. # -----------------goods_no_dict款号生成一个表格(款号+颜色)
  226. new_df = pd.DataFrame(columns=['款号', '颜色名称', '款色标记'])
  227. for key, value in goods_no_dict.items():
  228. goods_no = value["款号"]
  229. for color_name in [x["颜色名称"] for x in value["货号资料"]]:
  230. new_row = {"款号": goods_no,
  231. "颜色名称": self.get_real_color_name(color_name),
  232. "款色标记": 1,
  233. }
  234. new_df = new_df._append(new_row, ignore_index=True)
  235. new_df.drop_duplicates(subset=['款号', "颜色名称"], keep='first', inplace=True)
  236. # -------------参考的本地excel表格数据进行款号+颜色去重------------
  237. local_df = pd.read_excel(excel_path, sheet_name=0, header=0)
  238. local_df.fillna(value={'颜色名称': "", }, inplace=True)
  239. local_df = local_df.astype({"颜色名称": str})
  240. header_list = local_df.columns.values.tolist()
  241. for key in ["帮高", "鞋宽", "跟高"]:
  242. if key in header_list:
  243. local_df[key] = local_df[key].apply(change_to_int)
  244. # 颜色名称规整
  245. local_df["颜色名称"] = local_df["颜色名称"].apply(self.get_real_color_name)
  246. local_df.drop_duplicates(subset=['款号', "颜色名称"], keep='first', inplace=True)
  247. # ------------excel表格关联 上述的款号 进行标记,其他删除
  248. _df = new_df.drop_duplicates(subset=['款号'], keep='first', inplace=False)
  249. _df = _df[["款号"]]
  250. _df["对应款号"] = 1
  251. local_df = pd.merge(local_df, _df, on=["款号"], how="left", indicator=False, )
  252. local_df = local_df.loc[local_df['对应款号'] == 1, :]
  253. # ------------excel表格关联 上述款号与颜色,进行标记;取没有关联的颜色数据---------
  254. local_df = pd.merge(local_df, new_df, on=['款号', "颜色名称"], how="left", indicator=False, )
  255. local_df.fillna(value={'款色标记': 0, }, inplace=True)
  256. local_df = local_df.loc[local_df['款色标记'] == 0, :]
  257. print("local_df")
  258. print(local_df)
  259. # ------------数据分组,对对应的款号进行设置为错误数据---------------
  260. grouped_df = local_df.groupby('款号')['颜色名称'].apply(lambda x: '、'.join(x)).reset_index()
  261. for index, row in grouped_df.iterrows():
  262. error_data[row["款号"]] = {"message": "颜色:{}缺失".format(row["颜色名称"])}
  263. print("======error_data")
  264. print(json.dumps(error_data))
  265. return error_data
  266. class DataModeUploadPic(DataBaseModel):
  267. def __init__(self, token):
  268. super().__init__(token)
  269. self.token = token
  270. self.get_online_data.refresh_headers(token)
  271. self.is_deal_goods_no = []
  272. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None):
  273. return self.get_online_data.get_goods_art_no_info(numbers_list=numbers_list, goods_art_list=goods_art_list,token=self.token)
  274. def upload_pic_list_data(self, data):
  275. return self.get_online_data.upload_pic_list_data(data, token=self.token)
  276. def upload_pic(self,goods_data):
  277. return self.get_online_data.upload_pic(goods_data, token=self.token)
  278. def check_is_uploaded(self,goods_art_no=None):
  279. return self.get_online_data.check_detail_image(goods_art_no, token=self.token)