You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
814 lines
31 KiB
814 lines
31 KiB
# -*- coding: utf-8 -*-
|
|
import os
|
|
from collections import defaultdict
|
|
import pandas as pd
|
|
import numpy as np
|
|
import openpyxl
|
|
import time
|
|
from pandas import Index
|
|
from docxtpl import DocxTemplate
|
|
from calendar import monthrange
|
|
import datetime
|
|
import calendar
|
|
|
|
|
|
alter_dbr_dir = '.\\alter_data\\'
|
|
data_dir = '.\\data\\'
|
|
merge_file_dir = '.\\merge_data\\'
|
|
word_dir = '.\\word\\'
|
|
info_dir = '.\\info\\'
|
|
|
|
daimler_map = {
|
|
"DGRC": {
|
|
'032861711361',
|
|
'032968694919',
|
|
'033176839117',
|
|
'412333074862',
|
|
'412592672283',
|
|
'413185959261',
|
|
'571509464092',
|
|
'571914751254',
|
|
'572500455038',
|
|
'604214497778',
|
|
'605281233780',
|
|
'605492383956',
|
|
'606333019050',
|
|
'607073490803',
|
|
'607215769011',
|
|
'607251498050',
|
|
'745178511853',
|
|
'745186985354',
|
|
'745404617525',
|
|
'843064179036',
|
|
'843146470903',
|
|
'843403612003',
|
|
'938026107066',
|
|
'959875115713',
|
|
'846363994602',
|
|
'847121021275',
|
|
'847349672033',
|
|
'847535715113',
|
|
'787753559055'
|
|
|
|
},
|
|
"BMBS": {
|
|
'005952357992',
|
|
'006618809156',
|
|
'008855685915',
|
|
'099609831577',
|
|
'149729312152',
|
|
'158107609377',
|
|
'158515190244',
|
|
'158636931693',
|
|
'160478048914',
|
|
'161725851224',
|
|
'179818971150',
|
|
'180063110126',
|
|
'180280548979',
|
|
'259625653064',
|
|
'263249970047',
|
|
'263902424712',
|
|
'264554558165',
|
|
'381109879703',
|
|
'381965952467',
|
|
'382093053518',
|
|
'420190688017',
|
|
'420235015001',
|
|
'420347211434',
|
|
'468973200212',
|
|
'470975648111',
|
|
'471722715986',
|
|
'606431034865',
|
|
'606635571449',
|
|
'614449149933',
|
|
'614450235268',
|
|
'662090766598',
|
|
'662661601741',
|
|
'680011596858',
|
|
'693339510868',
|
|
'693619437440',
|
|
'693700422527',
|
|
'694079957533',
|
|
'694096809975',
|
|
'694098823346',
|
|
'720819555472',
|
|
'720826711875',
|
|
'720959775198',
|
|
'721033167150',
|
|
'721152002098',
|
|
'721305584708',
|
|
'731145591192',
|
|
'738568990634',
|
|
'738993122676',
|
|
'824698755435',
|
|
'824850862427',
|
|
'825095481624',
|
|
'830723988525',
|
|
'830765046968',
|
|
'833723158764',
|
|
'845876480170',
|
|
'846152349690',
|
|
'846800936473',
|
|
'864364323687',
|
|
'864518602649',
|
|
'864710874555',
|
|
'902795390617',
|
|
'939002646100',
|
|
'965407060405',
|
|
'965453987633',
|
|
'965517804909',
|
|
'060167615401',
|
|
'076513887860',
|
|
'420626856655',
|
|
'421314535486',
|
|
},
|
|
"BMBS-Rollout": {
|
|
'111035368608',
|
|
'143293953769',
|
|
'143419428863'
|
|
},
|
|
'DGRC-Rollout': {
|
|
'157701174715',
|
|
'157708043020',
|
|
'157784268223',
|
|
'157844458947',
|
|
'157876968059',
|
|
'157972004829',
|
|
'158027931531',
|
|
'767680705323',
|
|
'778776044487',
|
|
'778911054371',
|
|
'779093734419',
|
|
'779265673788',
|
|
'779378744728',
|
|
'779435304058',
|
|
'779482782114',
|
|
'779517320026',
|
|
'779563825200',
|
|
}
|
|
}
|
|
|
|
dbr_index = Index(['InvoiceID',
|
|
'PayerAccountId',
|
|
'LinkedAccountId',
|
|
'RecordType',
|
|
'RecordId',
|
|
'ProductName',
|
|
'RateId',
|
|
'SubscriptionId',
|
|
'PricingPlanId',
|
|
'UsageType',
|
|
'Operation',
|
|
'AvailabilityZone',
|
|
'ReservedInstance',
|
|
'ItemDescription',
|
|
'UsageStartDate',
|
|
'UsageEndDate',
|
|
'UsageQuantity',
|
|
'BlendedRate',
|
|
'BlendedCost',
|
|
'UnBlendedRate',
|
|
'UnBlendedCost',
|
|
'ResourceId'],
|
|
dtype='object')
|
|
|
|
data_type = {
|
|
'UsageStartDate': np.object,
|
|
'UsageEndDate': np.object,
|
|
'InvoiceID': np.object,
|
|
'ProductName': np.object,
|
|
'PayerAccountId': np.object,
|
|
'LinkedAccountId': np.object,
|
|
'UnBlendedCost': str,
|
|
'BlendedCost': str,
|
|
'ItemDescription': np.object,
|
|
'RecordType': np.object
|
|
}
|
|
|
|
def check_path_creat(path):
|
|
"""
|
|
检查路径是否存在,不存在就创建
|
|
:param path: 文件路径
|
|
:return:
|
|
"""
|
|
if not os.path.exists(path):
|
|
os.mkdir(path)
|
|
|
|
def del_file_form_path(filename: str, path: str):
|
|
if filename in os.listdir(path):
|
|
os.remove(os.path.join(merge_file_dir, filename))
|
|
|
|
def new_round(_float, _len=2) -> float:
|
|
"""
|
|
Parameters
|
|
----------
|
|
_float:
|
|
_len: int, 指定四舍五入需要保留的小数点后几位数为_len
|
|
|
|
Returns
|
|
-------
|
|
type ==> float, 返回四舍五入后的值
|
|
"""
|
|
try:
|
|
if isinstance(_float, float):
|
|
if 'e' in str(_float).lower():
|
|
return round(_float, _len)
|
|
elif str(_float)[::-1].find('.') <= _len:
|
|
return _float
|
|
elif str(_float)[-1] == '5':
|
|
return round(float(str(_float)[:-1] + '6'), _len)
|
|
else:
|
|
return round(_float, _len)
|
|
elif isinstance(_float, str):
|
|
_float = _float.replace(',', '')
|
|
return new_round(float(_float), _len)
|
|
else:
|
|
return round(_float, _len)
|
|
except Exception as e:
|
|
print(_float, _len, e)
|
|
|
|
def merge_file(filetuple: tuple):
|
|
for file in filetuple:
|
|
filename = list(file)[0]
|
|
del_file_form_path(filename, merge_file_dir)
|
|
for f in file:
|
|
filepath = os.path.join(data_dir, f)
|
|
alterpath = os.path.join(merge_file_dir, filename)
|
|
with open(filepath, 'r', encoding='utf-8') as r, open(alterpath, 'a', encoding='utf-8') as a:
|
|
num = 0
|
|
while True:
|
|
line = r.readline()
|
|
if not line:
|
|
break
|
|
num += 1
|
|
a.write(line)
|
|
if num % 10000 == 0:
|
|
print(num)
|
|
print('{}合并完成'.format(f))
|
|
|
|
|
|
def from_filename_get_datetime(filename: str):
|
|
dt = filename[-7:]
|
|
date = datetime.datetime.strptime(dt, "%Y-%m")
|
|
days = calendar.monthrange(date.year, date.month)
|
|
later1dt = date + datetime.timedelta(days[1] + 1)
|
|
later1 = later1dt.strftime("%Y-%m-%d")
|
|
n_days = calendar.monthrange(later1dt.year, later1dt.month)
|
|
later2dt = later1dt + datetime.timedelta(n_days[1])
|
|
later2 = later2dt.strftime("%Y-%m-%d")
|
|
return dt, later1, later2
|
|
|
|
class GenerateWord(object):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.args = args
|
|
self.kwargs = kwargs
|
|
|
|
def my_sum(self, data_dict, loc, length=2):
|
|
# 模板内使用
|
|
count = 0.0
|
|
for item in data_dict.values():
|
|
x = self.reverse_fill(item[loc])
|
|
count += x
|
|
a = new_round(count, length)
|
|
return a
|
|
|
|
@staticmethod
|
|
def reverse_fill(value_str: float, length=6):
|
|
return new_round(value_str, length)
|
|
|
|
@staticmethod
|
|
def get_bank(**kwargs):
|
|
info_map = {
|
|
'ch bj': os.path.join(info_dir, 'cn_bank_bj.txt'),
|
|
'ch hk': os.path.join(info_dir, 'cn_bank_hk.txt'),
|
|
'en bj': os.path.join(info_dir, 'en_bank_bj.txt'),
|
|
'en hk': os.path.join(info_dir, 'en_bank_hk.txt')
|
|
}
|
|
return info_map.get(kwargs.get('bank')) or info_map['ch bj']
|
|
|
|
@staticmethod
|
|
def get_region_display(data: dict):
|
|
for i in data.keys():
|
|
if i == 'cn-north-1':
|
|
data['北京区资源费'] = data.pop(i)
|
|
elif i == 'cn-northwest-1':
|
|
data['宁夏区资源费'] = data.pop(i)
|
|
return data
|
|
|
|
@staticmethod
|
|
def get_date_array(_date: str):
|
|
_array = monthrange(int(_date[:4]), int(_date[5:7]))
|
|
return [
|
|
"%s-%s-01" % (_date[:4], _date[5:7]),
|
|
"%s-%s-%2d" % (_date[:4], _date[5:7], _array[1]),
|
|
]
|
|
|
|
@staticmethod
|
|
def fill(value, length=2):
|
|
temp = "{:,.%sf}" % length
|
|
if isinstance(value, str):
|
|
value = value.replace(',', '')
|
|
return temp.format(float(value))
|
|
elif isinstance(value, int) or isinstance(value, float):
|
|
return temp.format(value)
|
|
else:
|
|
return temp.format(0)
|
|
|
|
@staticmethod
|
|
def display_time(day_str, str_fmt="%Y-%m-%d %H:%M:%S"):
|
|
# 设置中文编码格式
|
|
# import locale
|
|
# locale.setlocale(locale.LC_CTYPE, 'chinese')
|
|
zh_fmt = '%Y年%m月%d日'
|
|
# en_fmt = '%B %d, %Y'
|
|
return time.strftime(zh_fmt, time.strptime(str(day_str), str_fmt))
|
|
|
|
def get_currency(self):
|
|
if self.kwargs.get("currency") == 'USD':
|
|
return "$"
|
|
return "¥"
|
|
|
|
def get_temple_number(self, number):
|
|
data = [
|
|
self.fill(number * 1.06),
|
|
self.fill(number),
|
|
self.fill(0),
|
|
self.fill(number * 0.06),
|
|
]
|
|
return data
|
|
|
|
@staticmethod
|
|
def check_path_creat(path):
|
|
if not os.path.exists(path):
|
|
os.mkdir(path)
|
|
|
|
class DaimlerGenerateWord(GenerateWord):
|
|
|
|
def __init__(self, linkedid, result, filename, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.linkedid = linkedid
|
|
self.result = result
|
|
self.filename = filename
|
|
self.link_dict = kwargs.get('link_dict', None)
|
|
|
|
def create_word(self):
|
|
filedate, noticedate, due_data = from_filename_get_datetime(self.filename)
|
|
noticenumber = self.result.pop('InvoiceID')
|
|
totalcost = self.result.pop('TotalCost')
|
|
product_code_dict = defaultdict()
|
|
# order_dict = dict(sorted(self.result.items(), key=lambda t: t[1], reverse=True))
|
|
# for k, v in order_dict.items():
|
|
for k, v in self.result.items():
|
|
product_code_dict[k] = self.get_temple_number(v)
|
|
totalcost_li = self.get_temple_number(totalcost)
|
|
date = self.get_date_array(filedate)
|
|
for i in range(len(date)):
|
|
date[i] = self.display_time(date[i], str_fmt="%Y-%m-%d")
|
|
bank_info_list = []
|
|
with open(self.get_bank(), 'r', encoding='utf8') as f:
|
|
for line in f.readlines():
|
|
if "{{company_email}}" in line:
|
|
line = line.replace(
|
|
'{{company_email}}', self.kwargs.get(
|
|
'company_email', ''))
|
|
bank_info_list.append(line.strip('\n'))
|
|
xx = self.get_template()
|
|
template = DocxTemplate(xx)
|
|
link_data = [{
|
|
'linkedid': self.linkedid,
|
|
'totalcost': totalcost_li,
|
|
'product_code_dict': product_code_dict,
|
|
},
|
|
{
|
|
'linkedid': self.linkedid,
|
|
'totalcost': totalcost_li,
|
|
'product_code_dict': product_code_dict,
|
|
}
|
|
]
|
|
content = {
|
|
'storage': self.get_storage(),
|
|
'linkedid': self.linkedid,
|
|
'noticenumber': noticenumber,
|
|
'noticedate': noticedate,
|
|
'currency': self.get_currency(),
|
|
'region_display': '北京区资源费',
|
|
'totalcost': totalcost_li,
|
|
'product_code_dict': product_code_dict,
|
|
'date': date,
|
|
'workday': due_data,
|
|
'bank_info_list': bank_info_list,
|
|
'link_data': link_data,
|
|
}
|
|
file_name = '{}{}_AWS账单{}.docx'.format(
|
|
self.get_storage(), self.linkedid, filedate)
|
|
doc_file_path = os.path.join(word_dir, self.filename)
|
|
self.check_path_creat(doc_file_path)
|
|
doc_file_name = os.path.join(doc_file_path, file_name)
|
|
template.render(context=content)
|
|
template.save(doc_file_name)
|
|
print(
|
|
'{}{}_AWS账单{}.docx 生成完成'.format(
|
|
self.get_storage(),
|
|
self.linkedid,
|
|
filedate))
|
|
return [doc_file_name]
|
|
|
|
@staticmethod
|
|
def get_template():
|
|
return os.path.join(info_dir, 'china-template.docx')
|
|
|
|
def get_storage(self):
|
|
for k, v in daimler_map.items():
|
|
if self.linkedid in v:
|
|
return k
|
|
return ''
|
|
|
|
class CustomCsvByHour(object):
|
|
|
|
def __init__(self, pathlist, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.path = [pathlist]
|
|
self.finally_dict = defaultdict(float)
|
|
self.sourcename = None
|
|
self.es_iid = None
|
|
self.es_total = 0
|
|
self.edp_iid = ''
|
|
self.edp_total = 0
|
|
self.exclude_id = list()
|
|
self.unblendedcost = 0
|
|
self.payer = None
|
|
self.accountdt = pd.DataFrame()
|
|
self.statementdt = pd.DataFrame()
|
|
self.name = None
|
|
self.filename = None
|
|
self.partname = None
|
|
self.filepath = None
|
|
self.word_dict = defaultdict()
|
|
self.init_edp_dict = defaultdict()
|
|
self.es_data = None
|
|
# self.dbr_index = None
|
|
|
|
def set_deleted_data(self):
|
|
del_dict = {
|
|
'InvoiceID': self.exclude_id,
|
|
'RecordType': ['AccountTotal', 'StatementTotal', 'Rounding'],
|
|
'ItemDescription': 'AWS Solution Provider Program Discount',
|
|
'PayerAccountId': 'PayerAccountId'
|
|
}
|
|
return del_dict
|
|
|
|
def init_dbr_fill_data(self, path):
|
|
self.sourcename = path
|
|
self.filename = '改_{}'.format(path)
|
|
self.partname = '修改部分_{}'.format(path)
|
|
|
|
def get_dbr_data(self, path, name):
|
|
self.filepath = path
|
|
self.name = name
|
|
self.init_dbr_fill_data(name)
|
|
check_path_creat(os.path.join(alter_dbr_dir, self.sourcename[:-4]))
|
|
es_rule = 'Enterprise Support for month of'
|
|
reader = pd.read_csv(
|
|
path,
|
|
iterator=True,
|
|
sep=',',
|
|
chunksize=10000,
|
|
header=None,
|
|
names=dbr_index,
|
|
dtype=data_type,
|
|
low_memory=False)
|
|
num = 0
|
|
|
|
for result in reader:
|
|
word_dict = defaultdict(dict)
|
|
_edp_dict = defaultdict(dict)
|
|
num += 1
|
|
print('read', num)
|
|
# if not self.dbr_index:
|
|
# self.dbr_index = result.columns.tolist()
|
|
result['UnBlendedCost'] = result['UnBlendedCost'].apply(
|
|
pd.to_numeric, errors='coerce').fillna(0.0)
|
|
# result['ItemDescription'] = result['ItemDescription'].fillna('')
|
|
data = result[~result['ItemDescription'].str.contains(
|
|
'AWS Solution Provider Program Discount')]
|
|
# print(data)
|
|
data = data[~data['ItemDescription'].str.contains('POC 6337')]
|
|
asppd_data = result[(result['ItemDescription'].str.contains('AWS Solution Provider Program Discount')) |
|
|
(result['ItemDescription'].str.contains('AWS SOLUTION PROVIDER PROGRAM DISCOUNT'))]
|
|
self.exclude_id.extend(list(set(asppd_data['InvoiceID'])))
|
|
exclude_data = data[data['ProductName'] == 'Amazon Premium Support']
|
|
self.exclude_id.extend(list(exclude_data['InvoiceID']))
|
|
spp_data = data[data['ItemDescription'] == 'Billing error - SPP overdiscount issued for November period']
|
|
self.exclude_id.extend(list(spp_data['InvoiceID']))
|
|
if not exclude_data[exclude_data['ItemDescription']
|
|
== 'Enterprise Program Discount'].empty:
|
|
self.edp_total = exclude_data[exclude_data['ItemDescription']
|
|
== 'Enterprise Program Discount']['UnBlendedCost'].sum()
|
|
self.edp_iid = exclude_data[exclude_data['ItemDescription']
|
|
== 'Enterprise Program Discount'].iloc[0]['InvoiceID']
|
|
if not exclude_data[exclude_data['ItemDescription'].str.startswith(es_rule)].empty:
|
|
self.es_total += exclude_data[exclude_data['ItemDescription'].str.startswith(
|
|
es_rule)]['UnBlendedCost'].sum()
|
|
if not self.es_iid:
|
|
self.es_iid = exclude_data[exclude_data['ItemDescription'].str.startswith(
|
|
es_rule)].iloc[0]['InvoiceID']
|
|
self.es_data = exclude_data[exclude_data['ItemDescription'].str.startswith(
|
|
es_rule)].iloc[0]['ItemDescription']
|
|
# 去除不展示的部分
|
|
dt = data[((data['RecordType'] == 'LineItem') & (data['LinkedAccountId'] != '') &
|
|
(~data['InvoiceID'].isin(self.exclude_id))) |
|
|
((data['RecordType'] == 'InvoiceTotal') & (data['LinkedAccountId'] == '') &
|
|
(~data['InvoiceID'].isin(self.exclude_id)))]
|
|
# 去除不参与计算的部分
|
|
np_dt = dt.loc[dt['ProductName'].notna()]
|
|
linkedaccountid_set = set(np_dt['LinkedAccountId'])
|
|
productname_set = set(np_dt['ProductName'])
|
|
account_dt = data[data['RecordType'] == 'AccountTotal']
|
|
statement_dt = data[data['RecordType'] == 'StatementTotal']
|
|
self.unblendedcost += np_dt['UnBlendedCost'].sum()
|
|
for i in linkedaccountid_set:
|
|
_linked_data = np_dt[np_dt['LinkedAccountId'] == i]
|
|
self.finally_dict[i] += _linked_data['UnBlendedCost'].sum()
|
|
edp_data = _linked_data[_linked_data['ItemDescription'] == 'Enterprise Program Discount']
|
|
l_data = _linked_data[_linked_data['ItemDescription'] != 'Enterprise Program Discount']
|
|
_edp_dict[i] = edp_data['UnBlendedCost'].sum()
|
|
for p in productname_set:
|
|
word_dict[i][p] = l_data[l_data['ProductName'] == p]['UnBlendedCost'].sum()
|
|
word_dict[i]['TotalCost'] = _linked_data['UnBlendedCost'].sum()
|
|
word_dict[i]['InvoiceID'] = _linked_data.iloc[0]['InvoiceID']
|
|
for k, v in word_dict.items():
|
|
if k in self.word_dict.keys():
|
|
for c_k, c_v in v.items():
|
|
if c_k != 'InvoiceID':
|
|
chunk_c_k = self.word_dict[k].get(c_k, 0)
|
|
self.word_dict[k][c_k] = chunk_c_k + c_v
|
|
else:
|
|
self.word_dict[k] = v
|
|
for k, v in _edp_dict.items():
|
|
if k in self.init_edp_dict.keys():
|
|
self.init_edp_dict[k] += v
|
|
else:
|
|
self.init_edp_dict[k] = v
|
|
self.accountdt = pd.concat([self.accountdt, account_dt], axis=0)
|
|
self.statementdt = pd.concat(
|
|
[self.statementdt, statement_dt], axis=0)
|
|
for k, v in self.word_dict.items():
|
|
v['Enterprise Program Discount'] = self.init_edp_dict.get(
|
|
k, 0) + v.get('TotalCost', 0) / self.unblendedcost * self.edp_total
|
|
v['Enterprise Support'] = v.get('TotalCost', 0) / self.unblendedcost * self.es_total
|
|
v['TotalCost'] = v.get('TotalCost', 0) + v.get('TotalCost', 0) / self.unblendedcost * self.es_total + \
|
|
v.get('TotalCost', 0) / self.unblendedcost * self.edp_total
|
|
# print(self.word_dict)
|
|
# for k, v in self.word_dict.items():
|
|
# DaimlerGenerateWord(k, v, name[:-4]).create_word()
|
|
# self.save_lineitem_data()
|
|
# self.init_part_file()
|
|
# self.save_alter_data()
|
|
# self.save_mapping_date_to_csv()
|
|
self.save_mapping()
|
|
|
|
def save_lineitem_data(self):
|
|
del_dict = self.set_deleted_data()
|
|
filepath = os.path.join(
|
|
alter_dbr_dir, self.sourcename[:-4], self.filename)
|
|
with open(filepath, 'w', encoding='utf8') as w, open(self.filepath, 'r', encoding='utf8') as r:
|
|
w.write('"' + '","'.join(list(dbr_index)) + '"' + '\n')
|
|
num = 0
|
|
for line in r:
|
|
num += 1
|
|
if num % 10000 == 0:
|
|
print(num)
|
|
line_data = line.replace('"', '')
|
|
line_dict = dict(zip(list(dbr_index), line_data.split(',')))
|
|
if line_dict['InvoiceID'] in del_dict['InvoiceID']:
|
|
continue
|
|
elif line_dict['RecordType'] in del_dict['RecordType']:
|
|
continue
|
|
elif line_dict['ItemDescription'].startswith(del_dict['ItemDescription']):
|
|
continue
|
|
elif line_dict['ItemDescription'] == 'POC 6337':
|
|
continue
|
|
elif line_dict['PayerAccountId'] == del_dict['PayerAccountId']:
|
|
continue
|
|
w.write(line)
|
|
print('LineItem数据加载完成')
|
|
|
|
def save_alter_data(self):
|
|
print('ES总数为{}'.format(self.es_total))
|
|
print('EDP总数为{}'.format(self.edp_total))
|
|
print('消费总额为{}'.format(self.unblendedcost))
|
|
print(self.finally_dict)
|
|
print(self.exclude_id)
|
|
fill_data = self.get_fill_data(self.name)
|
|
self.save_data_to_dbr(fill_data)
|
|
self.add_round_to_dbr()
|
|
accountdt = self.alter_account_data(self.accountdt)
|
|
accountdt_dt = accountdt.to_dict(orient='list')
|
|
self.save_data_to_dbr(accountdt_dt)
|
|
statementdt = self.alter_statement_data(self.statementdt)
|
|
statementdt_dt = statementdt.to_dict(orient='list')
|
|
self.save_data_to_dbr(statementdt_dt)
|
|
print('{}文件修改完成'.format(self.sourcename))
|
|
|
|
def alter_account_data(self, data):
|
|
data = data.drop_duplicates(
|
|
subset=['LinkedAccountId'],
|
|
keep='first',
|
|
inplace=False)
|
|
data = data.reset_index(drop=True)
|
|
for i in range(data.shape[0]):
|
|
cost = self.finally_dict.get(data.loc[i, 'LinkedAccountId'], 0)
|
|
if data.loc[i, 'LinkedAccountId'] == self.payer:
|
|
data.loc[i, 'UnBlendedCost'] = '{:.6f}'.format((self.finally_dict.get(self.payer, 0) * 1.06) +
|
|
(cost / self.unblendedcost * self.es_total) +
|
|
(cost / self.unblendedcost * self.edp_total) +
|
|
(cost / self.unblendedcost * self.edp_total * 0.06))
|
|
else:
|
|
data.loc[i, 'UnBlendedCost'] = '{:.6f}'.format((cost * 1.06) +
|
|
(cost / self.unblendedcost * self.es_total) +
|
|
(cost / self.unblendedcost * self.es_total * 0.06) +
|
|
(cost / self.unblendedcost * self.edp_total) +
|
|
(cost / self.unblendedcost * self.edp_total * 0.06))
|
|
return data.fillna('')
|
|
|
|
def alter_statement_data(self, data):
|
|
data = data.drop_duplicates(
|
|
subset=['PayerAccountId'],
|
|
keep='first',
|
|
inplace=False)
|
|
data = data.reset_index(drop=True)
|
|
for i in range(data.shape[0]):
|
|
data.loc[i, 'UnBlendedCost'] = (
|
|
self.unblendedcost + self.es_total + self.edp_total) * 1.06
|
|
return data.fillna(value='')
|
|
|
|
def get_fill_data(self, name):
|
|
payer = name.split('-')[0]
|
|
self.payer = payer
|
|
date = name[-11:-4]
|
|
insert_data = defaultdict(list)
|
|
startdate, enddate = self.get_month_date(date)
|
|
for k, v in self.finally_dict.items():
|
|
insert_data['InvoiceID'].extend(
|
|
[self.es_iid, self.es_iid, self.edp_iid, self.edp_iid])
|
|
insert_data['PayerAccountId'].extend([payer, payer, payer, payer])
|
|
insert_data['LinkedAccountId'].extend([k, k, k, k])
|
|
insert_data['RecordType'].extend(['LineItem' for _ in range(4)])
|
|
insert_data['ProductName'].extend(
|
|
['Amazon Premium Support', '', 'Amazon Premium Support', ''])
|
|
insert_data['UsageStartDate'].extend([startdate for _ in range(4)])
|
|
insert_data['UsageEndDate'].extend([enddate for _ in range(4)])
|
|
insert_data['ItemDescription'].extend(
|
|
[
|
|
self.es_data,
|
|
'税金 VAT 类型',
|
|
'Enterprise Program Discount',
|
|
'税金 VAT 类型'])
|
|
insert_data['UnBlendedCost'].extend([
|
|
'{:.6f}'.format(v / self.unblendedcost * self.es_total),
|
|
'{:.6f}'.format(v / self.unblendedcost * self.es_total * 0.06),
|
|
'{:.6f}'.format(v / self.unblendedcost * self.edp_total),
|
|
'{:.6f}'.format(v / self.unblendedcost * self.edp_total * 0.06),
|
|
])
|
|
# data = pd.DataFrame(insert_data, columns=list(self.dbr_index))
|
|
return insert_data
|
|
|
|
def get_round_fill_data(self, name):
|
|
payer = name.split('-')[0]
|
|
self.payer = payer
|
|
insert_data = defaultdict(list)
|
|
linkedaccountid = 843403612003
|
|
insert_data['PayerAccountId'].extend([payer for _ in range(4)])
|
|
insert_data['LinkedAccountId'].extend(
|
|
[linkedaccountid for _ in range(4)])
|
|
insert_data['RecordType'].extend(['Rounding' for _ in range(4)])
|
|
insert_data['ItemDescription'].extend(
|
|
['Rounding of 563347375094',
|
|
'Rounding of 563646727715',
|
|
'Rounding of 565095721352',
|
|
'Rounding of 565359735310'])
|
|
insert_data['InvoiceID'].extend(
|
|
['1341453335',
|
|
'1341519427',
|
|
'1341507711',
|
|
'1341422927'])
|
|
insert_data['UnBlendedCost'].extend([
|
|
'{:.6f}'.format(-7.54),
|
|
'{:.6f}'.format(-2.43),
|
|
'{:.6f}'.format(-0.08),
|
|
'{:.6f}'.format(-0.11),
|
|
])
|
|
data = pd.DataFrame(insert_data, columns=list(dbr_index))
|
|
return data.fillna('')
|
|
|
|
def save_new_dbr(self, path, data, first=False):
|
|
filepath = os.path.join(alter_dbr_dir, self.sourcename[:-4], path)
|
|
if first:
|
|
data.to_csv(filepath, mode='w', encoding='UTF-8', index=False)
|
|
else:
|
|
data.to_csv(
|
|
filepath,
|
|
mode='a',
|
|
index=False,
|
|
encoding='UTF-8',
|
|
header=0)
|
|
|
|
@staticmethod
|
|
def get_month_date(date):
|
|
start = datetime.datetime.strptime(date, "%Y-%m")
|
|
month = start.month
|
|
year = start.year
|
|
if month == 12:
|
|
end = datetime.datetime(year + 1, 1, 1) - \
|
|
datetime.timedelta(seconds=1)
|
|
else:
|
|
end = datetime.datetime(year, month + 1, 1) - \
|
|
datetime.timedelta(seconds=1)
|
|
start_dt = start.strftime("%Y-%m-%d %H:%M:%S")
|
|
end_dt = end.strftime("%Y-%m-%d %H:%M:%S")
|
|
return start_dt, end_dt
|
|
|
|
def create_new_csv(self):
|
|
for path in self.path:
|
|
if path in os.listdir(merge_file_dir):
|
|
self.get_dbr_data(os.path.join(merge_file_dir, path), path)
|
|
else:
|
|
print('请合并文件')
|
|
# self.get_dbr_data(os.path.join(data_dir, path), path)
|
|
|
|
def save_data_to_dbr(self, insert_data):
|
|
partname = os.path.join(
|
|
alter_dbr_dir, self.sourcename[:-4], self.partname)
|
|
filename = os.path.join(
|
|
alter_dbr_dir, self.sourcename[:-4], self.filename)
|
|
with open(filename, 'a', encoding='utf-8') as fw, open(partname, 'a', encoding='utf-8') as pw:
|
|
dbr_dict = {v: int(k) for k, v in enumerate(list(dbr_index))}
|
|
for i in range(len(list(insert_data.values())[0])):
|
|
empty_data = ["" for _ in range(len(dbr_index))]
|
|
for k, v in insert_data.items():
|
|
empty_data[dbr_dict[k]] = v[i]
|
|
fw.write(','.join('"{}"'.format(x) for x in empty_data) + '\n')
|
|
pw.write(','.join('"{}"'.format(x) for x in empty_data) + '\n')
|
|
|
|
def init_part_file(self):
|
|
partname = os.path.join(
|
|
alter_dbr_dir, self.sourcename[:-4], self.partname)
|
|
with open(partname, 'w', encoding='utf-8') as f:
|
|
f.write(','.join('"{}"'.format(x) for x in list(dbr_index)) + '\n')
|
|
|
|
def add_round_to_dbr(self):
|
|
payer = self.name.split('-')[0]
|
|
if payer == '563646727715':
|
|
round_fill_data = self.get_round_fill_data(self.name)
|
|
round_data = round_fill_data.to_dict(orient='list')
|
|
self.save_data_to_dbr(round_data)
|
|
|
|
def save_mapping_date_to_csv(self):
|
|
filename = os.path.join(
|
|
alter_dbr_dir, self.sourcename[:-4], '{}_mapping.csv'.format(self.payer))
|
|
with open(filename, 'w', encoding='utf-8') as w:
|
|
w.write(','.join('"{}"'.format(x) for x in ['mapping', 'LinkedAccountId', 'UnBlendedCost']) + '\n')
|
|
for key, value in self.finally_dict.items():
|
|
mapping = ''
|
|
for k, v in daimler_map.items():
|
|
if key in v:
|
|
mapping = k
|
|
UnBlendedCost = '{:.6f}'.format((value * 1.06) +
|
|
(value / self.unblendedcost * self.es_total) +
|
|
(value / self.unblendedcost * self.es_total * 0.06) +
|
|
(value / self.unblendedcost * self.edp_total) +
|
|
(value / self.unblendedcost * self.edp_total * 0.06))
|
|
w.write(','.join('"{}"'.format(x) for x in [mapping, key, UnBlendedCost]) + '\n')
|
|
|
|
def save_mapping(self):
|
|
path = '.\\bill_checklist\\Daimler账单核对表.xlsx'
|
|
wb = openpyxl.load_workbook(path)
|
|
table = wb['Daimler账单核对表']
|
|
for row in table.iter_rows():
|
|
if str(row[4].value).isdigit():
|
|
_total = self.finally_dict.get(str(row[4].value), None)
|
|
if _total:
|
|
row[5].value = ((_total * 1.06) +
|
|
(_total / self.unblendedcost * self.es_total) +
|
|
(_total / self.unblendedcost * self.es_total * 0.06) +
|
|
(_total / self.unblendedcost * self.edp_total) +
|
|
(_total / self.unblendedcost * self.edp_total * 0.06))
|
|
wb.save('.\\bill_checklist\\Daimler22-4月账单核对表.xlsx')
|
|
print('mapping数据处理完成')
|
|
|
|
if __name__ == '__main__':
|
|
dbr_typle = (
|
|
# ('563347375094-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-2022-04.csv',
|
|
# '563347375094-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-Ningxia-2022-04.csv',),
|
|
# ('563646727715-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-2022-04.csv',
|
|
# '563646727715-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-Ningxia-2022-04.csv',),
|
|
# ('565095721352-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-2022-04.csv',
|
|
# '565095721352-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-Ningxia-2022-04.csv',),
|
|
# ('565359735310-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-2022-04.csv',
|
|
# '565359735310-aws-billing-detailed-line-items-with-resources-and-tags-ACTS-Ningxia-2022-04.csv',),
|
|
)
|
|
# 先合并文件
|
|
# merge_file(dbr_typle)
|
|
# for i in dbr_typle:
|
|
# CustomCsvByHour(i[0]).create_new_csv() |