Esempio n. 1
0
    def __init__(self, textBrowser, path):
        self.textBrowser = textBrowser
        msg = u"开始初始化读取timesheet."
        LOG.info(msg)
        self.textBrowser.append(msg)
        self.config = Config()
        self.project_query_report_path = self.config.get_project_query_report_path(
        )
        self.total_cost = None
        self.path = path
        self.sheet = None
        self.first_row_values = None
        self.nrows = None
        self.ncols = None
        self.textBrowser = textBrowser
        self.all_projectid_list = list()
        self.projects_dict = dict()
        self.title_index_dict = dict()

        self.exclude_project_id = self.__get_exclude_project_id()

        # 初始化表格函数
        self.__init_sheet_obj()
        self.textBrowser.append(u"初始化TimeSheet报表完成")

        #
        self.weight = WeightData()

        self.project_query_obj = QueryProject(textBrowser,
                                              self.project_query_report_path)

        self.is_right_ratio = False

        self.project_ratio_list = self.__calculation()
Esempio n. 2
0
 def __init__(self, textBrowser, path):
     self.textBrowser = textBrowser
     self.conf = Config()
     self.excel = ExcelRead(self.textBrowser, path)
     self.sheet = self.excel.get_sheet_by_keywords(
         [PROJECT_ID, SS_COST_CETER])
     self.index_of_title = self.excel.get_col_index_of_title()
     self.nrows = self.sheet.nrows
     self.textBrowser.append(u"初始化项目查询报表完成")
Esempio n. 3
0
 def __init__(self, textBrowser, path, sheet_name):
     self.conf = Config()
     self.path = path
     self.textBrowser = textBrowser
     self.ROW = self.conf.get_cost_center_name_list()
     self.COL = self.conf.get_cost_class_list()
     try:
         self.workbook = xlwt.Workbook(encoding='utf-8')
         self.worksheet = self.workbook.add_sheet(
             sheet_name, cell_overwrite_ok=True)
         self.inital_excel()
     except Exception as e:
         msg = u"打开excel文件失败,文件名称:%s, 原因:%s" % (self.path, e)
         raise Exception(msg)
Esempio n. 4
0
    def __init__(self):
        self.config = Config()
        self.timesheet_report_path = self.config.get_timesheet_report_path()
        self.profit_report_path = self.config.get_profit_report_path()
        self.project_query_report_path = self.config.get_project_query_report_path(
        )
        self.bc_report_path = self.config.get_bc_report_path()
        self.bc_sheet_name = self.config.get_bc_sheet_name()
        self.output_path = self.config.get_output_path()
        self.textBrowser = self.config.get_textBrowser()

        #time_sheet
        self.monthly_obj = MonthlyDataExcel(self.textBrowser,
                                            self.timesheet_report_path)
        self.project_ratio_datalist = self.monthly_obj.get_project_ratio_datalist(
        )

        #利润表
        self.profit_obj = ProfitData(self.textBrowser, self.profit_report_path)

        #项目综合查询
        self.project_query_obj = QueryProject(self.textBrowser,
                                              self.project_query_report_path)

        self.weight_data_dict = dict()

        self.weight_data_dict = WeightData().get_weight_data_dict()
        #BC 报表
        self.bc_report_obj = BCReport(self.textBrowser, self.bc_report_path)
        self.bc_report_obj.init_monthly_table(self.bc_sheet_name)

        self.bc_row_title_index = self.bc_report_obj.get_row_title_index()
        self.bc_col_title_index = self.bc_report_obj.get_col_title_index()
        #结果表
        self.write_obj = WritingExcel(self.textBrowser, self.output_path,
                                      self.bc_sheet_name)

        # 初始化成本中心对象,初始化所有成本中心的各项cost
        self.cost_center_obj = CostCenter()
        self.__init_cost_center()

        # 通过比率计算后的待更新的成本中心数据
        self.new_cost_center_obj = CostCenter()
Esempio n. 5
0
    def __init__(self):
        if not WeightData.instance_flag:
            self.config = Config()
            self.textBrowser = self.config.get_textBrowser()

            self.sheet = None
            self.path = self.config.get_weight_path()
            if self.path:
                excel = ExcelRead(self.textBrowser, self.path)
                sheet_name = self.get_sheet_name()
                self.sheet = excel.get_sheet_by_name(sheet_name)
                self.title_index_dict = excel.get_col_index_of_title()

                self.cost_center_name_list = self.get_cost_center_name()
                self.weight_data_dict = self._get_weight_data_dict()
                WeightData.instance_flag = True

            else:  # 权重路径未设置的情况下,初始化为空
                self.weight_data_dict = dict()
                WeightData.instance_flag = True
Esempio n. 6
0
    def __init__(self, textBrowser, path):
        self.textBrowser = textBrowser
        msg = u"开始初始化读取利润表"
        self.textBrowser.append(msg)
        LOG.info(msg)
        self.conf = Config()
        excel = ExcelRead(self.textBrowser, path)
        sheet_name = self.__get_sheet_name()
        self.sheet = excel.get_sheet_by_name(sheet_name)
        self.index_of_title = excel.get_col_index_of_title()
        excel.clear()
        self.rowsn = self.sheet.nrows
        self.colsn = self.sheet.ncols

        self.bc_template_index = self.__get_index(u"BC模板分类")
        self.cost_center_index = self.__get_index(u"成本中心")
        self.project_id_index = self.__get_index(u"外部订单号")
        self.money_index = self.__get_index(u"公司货币金额")
        self.profit_dict = dict()

        self.all_row_datalist = self.__get_all_row_datalist()
        self.textBrowser.append(u"初始化利润报表完成")
Esempio n. 7
0
class WritingExcel(object):
    def __init__(self, textBrowser, path, sheet_name):
        self.conf = Config()
        self.path = path
        self.textBrowser = textBrowser
        self.ROW = self.conf.get_cost_center_name_list()
        self.COL = self.conf.get_cost_class_list()
        try:
            self.workbook = xlwt.Workbook(encoding='utf-8')
            self.worksheet = self.workbook.add_sheet(
                sheet_name, cell_overwrite_ok=True)
            self.inital_excel()
        except Exception as e:
            msg = u"打开excel文件失败,文件名称:%s, 原因:%s" % (self.path, e)
            raise Exception(msg)

    def inital_excel(self):
        style = xlwt.XFStyle()
        font = xlwt.Font()
        font.bold = True
        style.font = font
        for j in range(len(self.COL)):
            self.worksheet.write(j + 1, 0, self.COL[j], style)

        for i in range(len(self.ROW)):
            self.worksheet.write(0, i + 1, self.ROW[i], style)

    def save(self):
        self.workbook.save(self.path)

    def write(self, row_name, col_name, value):

        # 由于表格前面有空格,因此要+1
        x = self.ROW.index(row_name) + 1
        y = self.COL.index(col_name) + 1

        # 由于行列索引号和实际是反的,因此要倒换x,y的顺序
        self.worksheet.write(y, x, value)
Esempio n. 8
0
class QueryProject(object):
    """
    项目综合查询 表 处理类
    """
    def __init__(self, textBrowser, path):
        self.textBrowser = textBrowser
        self.conf = Config()
        self.excel = ExcelRead(self.textBrowser, path)
        self.sheet = self.excel.get_sheet_by_keywords(
            [PROJECT_ID, SS_COST_CETER])
        self.index_of_title = self.excel.get_col_index_of_title()
        self.nrows = self.sheet.nrows
        self.textBrowser.append(u"初始化项目查询报表完成")

    def get_cost_ceter_name(self, project_id):
        """
        通过项目ID获取项目对应的成本中心
        :param project_id: 项目ID
        :return: 成本中心
        """
        cost_ceter_name_index = self.index_of_title.get(SS_COST_CETER)
        for i in range(self.nrows):
            rows_data = self.sheet.row_values(i)
            if project_id in rows_data:
                return self._ceter_name(project_id,
                                        rows_data[cost_ceter_name_index])

    def _ceter_name(self, project_id, name):
        """
        根据筛选出的实施成本中心名称,获得对应成本中心名称
        :param name:实施成本中心名称
        :return:成本中心名称
        """
        re_dict = self.conf.get_cost_center_re_dict()
        for ceter_name, re_pattern in re_dict.items():
            if re.findall(re_pattern, name):
                return ceter_name
        msg = u"未找到对应的成本中心:%s,project id: %s" % (name, project_id)
        self.textBrowser.append(msg)
        return None
Esempio n. 9
0
class MonthlyDataExcel(object):
    """ 该Excel sheet页名称不确定,sheet 数量不确定,因此通过关键字来匹配,
    包含”费率,成本“的页签 为目标页签

    """
    def __init__(self, textBrowser, path):
        self.textBrowser = textBrowser
        msg = u"开始初始化读取timesheet."
        LOG.info(msg)
        self.textBrowser.append(msg)
        self.config = Config()
        self.project_query_report_path = self.config.get_project_query_report_path(
        )
        self.total_cost = None
        self.path = path
        self.sheet = None
        self.first_row_values = None
        self.nrows = None
        self.ncols = None
        self.textBrowser = textBrowser
        self.all_projectid_list = list()
        self.projects_dict = dict()
        self.title_index_dict = dict()

        self.exclude_project_id = self.__get_exclude_project_id()

        # 初始化表格函数
        self.__init_sheet_obj()
        self.textBrowser.append(u"初始化TimeSheet报表完成")

        #
        self.weight = WeightData()

        self.project_query_obj = QueryProject(textBrowser,
                                              self.project_query_report_path)

        self.is_right_ratio = False

        self.project_ratio_list = self.__calculation()

    def __init_sheet_obj(self):
        """
        获取表格数据
        :return:
        """
        excel = ExcelRead(self.textBrowser, self.path)
        self.sheet = excel.get_sheet_by_keywords([u'费率', u'成本'])
        excel.clear()
        # 首行所有数据
        self.title_index_dict = excel.get_col_index_of_title()

        self.nrows = self.sheet.nrows
        self.ncols = self.sheet.ncols

    def __get_all_projects_list(self):
        """
        获取所有项目编号的list
        :return: 所有项目的set
        """
        if u"项目编号" not in self.title_index_dict:
            msg = u"未找到项目编号列"
            self.textBrowser.append(msg)
            raise Exception(msg)

        index_of_projectid_col_num = self.title_index_dict.get(u"项目编号")
        # 所有项目编号数据
        self.all_projectid_list = self.__get_all_project_id_list(
            index_of_projectid_col_num)

    def __get_all_project_id_list(self, index_of_projectid_col_num):
        col_list = self.sheet.col_values(index_of_projectid_col_num)
        # 去掉第一行Title行
        col_list.pop(0)
        all_projectid_list = set(col_list)
        if not all_projectid_list:
            msg = u"获取所有的项目编号为空"
            self.textBrowser.append(msg)
            raise Exception(msg)
        return all_projectid_list

    def __current_project_data(self, project_id, cost_ceter_index, cost_index,
                               item_dict):
        """
        通过项目编号获取当前项目关联 所有成本中心 数据行列表

        :param project_id: 项目ID
        :param cost_ceter_index: 项目ID
        :param cost_index: 项目ID

        :return: 项目数据列表
        """

        for i in range(self.nrows):
            row_value = self.sheet.row_values(i)
            if project_id in row_value:
                self.__find_data_in_row(cost_ceter_index, cost_index,
                                        row_value, item_dict)

    def get_project_ratio_datalist(self):
        """
        获取所有项目数据,项目id -key,项目关联数据行 -value
        :return: 项目数据字典
        """
        return self.project_ratio_list

    def __filter_project(self):
        if not self.all_projectid_list:
            self.__get_all_projects_list()

        # 成本中心列 的index值
        cost_ceter_index = self.title_index_dict[u"成本中心"]
        # 成本列 的index值
        cost_index = self.title_index_dict[u"成本"]

        error_project_id = list()
        filter_project_id = list()
        for project_id in self.all_projectid_list:

            # 排除项目
            if self.__is_exclude_project_id(project_id):
                filter_project_id.append(project_id)
                continue

            # 当前项目所有成本中心对应的成本数据 累加字典,{成都企业IT部:1000000,杭州企业IT部:200000,...}
            item = dict()
            self.__current_project_data(project_id, cost_ceter_index,
                                        cost_index, item)
            if not item:
                continue

            # 剔除只有一个成本中心,且为主成本中心的项目
            # 从项目查询中去查询主要成本中心
            main_center_name = self.project_query_obj.get_cost_ceter_name(
                project_id)
            if main_center_name is None:
                error_project_id.append(project_id)
                continue

            # 比较当前项目只有一个成本中心,且成本中心和主要成本中心相等则不纳入计算
            if len(item.keys()) == 1 and item.keys()[0] == main_center_name:
                continue

            # 计算获得满足条件的项目
            self.projects_dict[project_id] = item

        if filter_project_id:
            msg = u"过滤掉的项目id:%s" % filter_project_id
            LOG.info(msg)
            self.textBrowser.append(msg)

        if error_project_id:
            msg = u"存在脏数据,项目id: %s 在<项目综合查询表>中不存在,请确认项目月度timesheet报表中的项目ID" \
                  u"在项目综合查询中是否存在" % error_project_id
            self.textBrowser.append(msg)
            LOG.info(msg)

    def __calculation(self):
        """
        获取project 对象list
        :param
        :return: [project1,project2,project3...}
        """
        self.__filter_project()
        project_list = list()
        for project_id, cost_dict in self.projects_dict.items():
            #创建一个project对象用于保存project_id和其占比
            project = Project()
            current_project_weight = self.__get_weight(project_id)

            if current_project_weight:
                weight_ratio_dict = self.__get_ratio_with_weight(
                    project_id, current_project_weight, cost_dict)
                ratio_dict = self.__get_ratio_without_weight(
                    project_id, cost_dict)

                project.set_project_id(project_id)
                project.set_ratio({
                    "ratio": ratio_dict,
                    "weight_ratio": weight_ratio_dict
                })
            else:
                ratio_dict = self.__get_ratio_without_weight(
                    project_id, cost_dict)
                project.set_project_id(project_id)
                project.set_ratio({"ratio": ratio_dict})
                LOG.info("project_id: %s, ratio_dict: %s" %
                         (project_id, ratio_dict))

            project_list.append(project)
        if self.is_right_ratio:
            msg = u"表格数据异常,请整改后重试."
            LOG.error(msg)
            self.textBrowser.append(msg)
            raise Exception(msg)

        return project_list

    def __find_data_in_row(self, cost_ceter_index, cost_index, row, item_dict):
        """ 将同一个项目下的成本中心拆分{成本中心1:totalcost,成本中心2:totalcost, other:totalcost}
        :param cost_ceter_index:
        :param row:
        :param item_dict:
        :return:
        """
        if not row:
            raise Exception(u"该行数据为空")
        re_dict = self.config.get_cost_center_re_dict()

        flag = False
        for k, r in re_dict.items():
            if re.match(r, row[cost_ceter_index]):
                value = item_dict.get(k, 0)
                value += row[cost_index]
                item_dict[k] = value
                flag = True
                break

        if flag == False:
            value = item_dict.get("other", 0)
            value += row[cost_index]
            item_dict["other"] = value

    def __get_exclude_project_id(self):
        result = self.config.get_value("Default",
                                       "Exclude_Project_ID").split("|")
        return [value for value in result if value]

    def __is_exclude_project_id(self, project_id):
        if not self.exclude_project_id:
            return False

        for r in self.exclude_project_id:
            if re.findall(r, str(project_id)):
                return True
        return False

    def __get_weight(self, project_id):
        """
        获取当前项目id的权重数据字典
        :param project_id:
        :return:
        """
        weight_data_dict = self.weight.get_weight_data_dict()
        current_project_weight = weight_data_dict.get(project_id)
        return current_project_weight

    def __get_ratio_with_weight(self, project_id, current_project_weight,
                                cost_dict):
        """
        获取有权重的 成本中心占比 比率 字典
        :param project_id:当前项目ID
        :param current_project_weight: 当前项目的权重字典
        :param cost_dict: 当前项目的各成本中心总收入字典
        :return:
        """

        # 判断ts中的成本中心和权重表中成本中心是否一一对应
        list1 = current_project_weight.keys()
        list2 = cost_dict.keys()
        if not Util.is_equal(list1, list2):
            msg = u"项目ID:%s,TS中成本中心和权重表中成本中心无法对应!!!" % project_id
            self.is_right_ratio = True
            LOG.error(msg)
            self.textBrowser.append(msg)

        total_cost = 0
        #获取当前项目总成本*权重的值,得到新的总成本
        for cost_ceter, cost in cost_dict.items():
            # 获取成本中心权重
            weight_value = current_project_weight.get(cost_ceter)
            if cost_ceter == "other":
                weight_value = 1
            if weight_value is None:
                msg = u"项目ID:%s, 成本中心:%s 权重为空!!!" % (project_id, cost_ceter)
                LOG.warn(msg)
                self.textBrowser.append(msg)
                weight_value = 1
                self.is_right_ratio = True
            total_cost += cost * weight_value

        if total_cost == 0:
            msg = u"项目ID:%s 总成本为0,请检查TS表格" % project_id
            LOG.error(msg)
            self.textBrowser.append(msg)
            self.is_right_ratio = True
            total_cost = -1

        # 当前项目对应的各成本中心的总成本 * 当前成本中心权重值 / 当前项目新的总成本
        weigth_ratio = dict()
        for cost_ceter, cost in cost_dict.items():
            weight_value = current_project_weight.get(cost_ceter, 0)
            if weight_value is None:
                weight_value = 1
            weigth_ratio[cost_ceter] = cost * weight_value / total_cost
        return weigth_ratio

    def __get_ratio_without_weight(self, project_id, cost_dict):
        """
        获取没有权重的成本中心占比 字典
        :param project_id:
        :param cost_dict:
        :return:
        """
        # 计算总成本,用于求比值的分母
        total_cost = 0
        for cost in cost_dict.values():
            total_cost += cost

        if total_cost == 0:
            msg = u"项目ID:%s 总成本为0,请检查TS表格" % project_id
            LOG.error(msg)
            self.textBrowser.append(msg)
            self.is_right_ratio = True
            total_cost = -1

        ratio = dict()
        for cost_ceter, cost in cost_dict.items():
            ratio[cost_ceter] = cost / total_cost
        return ratio
Esempio n. 10
0
class ProfitData(object):
    """
    利润中心表
    """
    def __init__(self, textBrowser, path):
        self.textBrowser = textBrowser
        msg = u"开始初始化读取利润表"
        self.textBrowser.append(msg)
        LOG.info(msg)
        self.conf = Config()
        excel = ExcelRead(self.textBrowser, path)
        sheet_name = self.__get_sheet_name()
        self.sheet = excel.get_sheet_by_name(sheet_name)
        self.index_of_title = excel.get_col_index_of_title()
        excel.clear()
        self.rowsn = self.sheet.nrows
        self.colsn = self.sheet.ncols

        self.bc_template_index = self.__get_index(u"BC模板分类")
        self.cost_center_index = self.__get_index(u"成本中心")
        self.project_id_index = self.__get_index(u"外部订单号")
        self.money_index = self.__get_index(u"公司货币金额")
        self.profit_dict = dict()

        self.all_row_datalist = self.__get_all_row_datalist()
        self.textBrowser.append(u"初始化利润报表完成")

    def __get_all_row_datalist(self):
        projects_datalist = []
        for i in range(self.rowsn):
            try:
                row = self.sheet.row_values(i)
                projects_datalist.append(row)
            except Exception as e:
                msg = "获取行内容失败行号:%d, 原因:%s" % (i, e)
                LOG.info(msg)
                self.textBrowser.append(str(msg))
                raise Exception
        return projects_datalist

    def get_project_costitem_dict(self, project_id):
        if not project_id:
            raise Exception("proejct id 为空")
        current_profit = dict()
        # 获取分类字典
        cost_class_list = self.conf.get_cost_class_list()
        for row in self.all_row_datalist:
            if project_id != row[self.project_id_index]:
                continue
            key = row[self.bc_template_index]
            if key in cost_class_list:
                try:
                    value = current_profit.get(key, 0)
                    value += row[self.money_index]
                    current_profit[key] = value
                except Exception as e:
                    msg = "获取行数据,失败原因:%s,行:%s,列标题%e" % (e, row, key)
                    LOG.error(msg)
                    raise Exception
        return current_profit

    def __get_index(self, title):
        index = self.index_of_title.get(title)
        if not index:
            msg = "利润表中不存在:%s列,请检查利润表中标题行" % title
            LOG.error(msg)
            self.textBrowser.append(msg)
            raise Exception
        msg = u"获取利润行首:%s 所在索引号:%d" % (title, index)
        LOG.info(msg)
        return index

    def __get_sheet_name(self):
        return self.conf.get_value("SHEET_NAME", "profit_sheet_name")
Esempio n. 11
0
class Caculating(object):
    def __init__(self):
        self.config = Config()
        self.timesheet_report_path = self.config.get_timesheet_report_path()
        self.profit_report_path = self.config.get_profit_report_path()
        self.project_query_report_path = self.config.get_project_query_report_path(
        )
        self.bc_report_path = self.config.get_bc_report_path()
        self.bc_sheet_name = self.config.get_bc_sheet_name()
        self.output_path = self.config.get_output_path()
        self.textBrowser = self.config.get_textBrowser()

        #time_sheet
        self.monthly_obj = MonthlyDataExcel(self.textBrowser,
                                            self.timesheet_report_path)
        self.project_ratio_datalist = self.monthly_obj.get_project_ratio_datalist(
        )

        #利润表
        self.profit_obj = ProfitData(self.textBrowser, self.profit_report_path)

        #项目综合查询
        self.project_query_obj = QueryProject(self.textBrowser,
                                              self.project_query_report_path)

        self.weight_data_dict = dict()

        self.weight_data_dict = WeightData().get_weight_data_dict()
        #BC 报表
        self.bc_report_obj = BCReport(self.textBrowser, self.bc_report_path)
        self.bc_report_obj.init_monthly_table(self.bc_sheet_name)

        self.bc_row_title_index = self.bc_report_obj.get_row_title_index()
        self.bc_col_title_index = self.bc_report_obj.get_col_title_index()
        #结果表
        self.write_obj = WritingExcel(self.textBrowser, self.output_path,
                                      self.bc_sheet_name)

        # 初始化成本中心对象,初始化所有成本中心的各项cost
        self.cost_center_obj = CostCenter()
        self.__init_cost_center()

        # 通过比率计算后的待更新的成本中心数据
        self.new_cost_center_obj = CostCenter()

    def update(self):
        LOG.info(u"开始更新BC报表数据")
        for project in self.project_ratio_datalist:
            project_id = project.get_project_id()

            # 需要拆分的部分项目
            profit_data = self.profit_obj.get_project_costitem_dict(project_id)

            # 该项目对应的正确成本中心
            main_center_name = self.project_query_obj.get_cost_ceter_name(
                project_id)
            self.__caculation(project, profit_data, main_center_name)
        self.__write_to_excel()

    def _is_weight_error(self, weight, center_name):
        """
        权重异常判断
        :return:
        """
        if center_name in weight:
            del (weight[center_name])
        if weight.keys():
            msg = u"存在项目id: %s 权重表异常"
            self.textBrowser.append(msg)

    def __write_to_excel(self):
        LOG.info(u"将更新后的BC报表数据保存")
        zone_dict = self.config.get_zone_dict()
        costitem_dict = self.config.get_cost_class_dict()
        for zone, center_name in zone_dict.items():
            for item, cost_item in costitem_dict.items():
                value = getattr(self.cost_center_obj, zone + "_" + item)
                self.write_obj.write(center_name, cost_item, value)
        # 保存文件
        self.write_obj.save()

    def __get_x_index(self, name):
        """
        获取横向坐标
        :param name:
        :return:
        """
        return self.bc_row_title_index.get(name)

    def __get_y_index(self, name):
        """
        获取纵向坐标 字典
        :param name:
        :return:
        """

        return self.bc_col_title_index.get(name)

    def __init_cost_center(self):
        """
        初始化所有的成本中心值
        :return:
        """
        zone_dict = self.config.get_zone_dict()
        for zone_en, zone_zh in zone_dict.items():
            try:
                colx_index = self.__get_x_index(zone_zh)
                if not colx_index:
                    LOG.info("BC报表中不存在'%s'列" % zone_zh)
                    zone_dict.pop(zone_en)
                    self.config.set_zone_dict(zone_dict)
                    continue
            except Exception as e:
                msg = u"未从表格中解析到%s所在列的列号, error: %s" % (zone_zh, str(e))
                LOG.error(msg)
                self.textBrowser.append(msg)
                raise Exception(msg)
            costitem_dict = self.config.get_cost_class_dict()
            for costitem_en, costitem_zh in costitem_dict.items():
                try:
                    value = 0
                    if costitem_zh == "Revenue":
                        costitem_zh = u"总收入"
                    if costitem_zh == "Sales Tax":
                        costitem_zh = u"税金"
                    rowx_index = self.__get_y_index(costitem_zh)
                    if rowx_index:
                        # 获取bc报表单元格值
                        value = self.bc_report_obj.get_monthly_cell_value(
                            rowx_index, colx_index)
                    if not value:
                        value = 0
                    # # 初始化对应成本中心,各项值
                    # if costitem_zh == "Revenue" or costitem_zh == u"总收入":
                    #     value = abs(value)
                    setattr(self.cost_center_obj, zone_en + "_" + costitem_en,
                            value)
                except Exception as err:
                    msg = u"总成本中心解析出错, 总成本中心:%s, 项目:%s, error: %s" % (
                        zone_zh, costitem_zh, str(err))
                    LOG.error(msg)
                    self.textBrowser.append(msg)
                    raise Exception(msg)
        LOG.info(u"总成本中心数据初始化完毕。")

    def __caculation(self, project, profit_data, master_costcenter_zh):
        zone_dict = self.config.get_zone_dict()
        costitem_dict = self.config.get_cost_class_dict()
        master_zone_en = Util.get_zone_en(master_costcenter_zh, zone_dict)
        ratio_dict = project.get_ratio().get("ratio")
        weight_ratio_dict = project.get_ratio().get("weight_ratio")
        for slave_csostcenter_zh, ratio in ratio_dict.items():

            # 成本中心为other的不计算
            if slave_csostcenter_zh == "other":
                continue

            if master_costcenter_zh == slave_csostcenter_zh:
                # 遍历出的主成本中心时,不需要计算成本变化
                continue

            weight_ratio = 0
            if weight_ratio_dict:
                weight_ratio = weight_ratio_dict.get(slave_csostcenter_zh)

            if not weight_ratio:  # 当获取不到权重占比时,就采用一般占比
                weight_ratio = ratio

            slave_costcenter_en = Util.get_zone_en(slave_csostcenter_zh,
                                                   zone_dict)
            for costitem, value in profit_data.items():
                """
                如果有成本中心(x,y),总收入分别为A,B
                主要成本中心为x

                总金额占比:x:y = 0.4:0.6

                权重占比为x:y=0.2:0.8

                成本中心x 总收入和税金 x-0.8*a , 其他收入  x-0.6a

                成本中心y 总收入和税金:B+0.8a, 其他收入  x+0.6a
                """
                if costitem == "Revenue" or costitem == u"税金":
                    temp_value = value * weight_ratio
                else:
                    temp_value = value * ratio

                if costitem == "Revenue":
                    temp_value = 0 - temp_value

                costitem_en = Util.get_costitem_en(costitem, costitem_dict)
                # 主要成本中心默认的总成本
                master_value = getattr(self.cost_center_obj,
                                       master_zone_en + '_' + costitem_en)
                # 次要成本中心默认值
                slave_value = getattr(self.cost_center_obj,
                                      slave_costcenter_en + '_' + costitem_en)
                # 从主要成本中心扣除成本
                new_master_value = master_value - temp_value
                # 次要成本中心增加
                new_slave_value = slave_value + temp_value

                # 更新成本中心
                setattr(self.cost_center_obj,
                        master_zone_en + '_' + costitem_en, new_master_value)

                setattr(self.cost_center_obj,
                        slave_costcenter_en + '_' + costitem_en,
                        new_slave_value)
Esempio n. 12
0
 def __init__(self):
     QWidget.__init__(self)
     self.config = Config()
Esempio n. 13
0
class Ui_Dialog(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.config = Config()

    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8(u"财务报表统计"))
        Dialog.resize(632, 466)
        self.groupBox = QtGui.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(0, 0, 553, 210))
        self.groupBox.setObjectName(_fromUtf8("groupBox"))
        self.formLayoutWidget = QtGui.QWidget(self.groupBox)
        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 500, 191))
        self.formLayoutWidget.setObjectName(_fromUtf8("formLayoutWidget"))
        self.formLayout = QtGui.QFormLayout(self.formLayoutWidget)
        self.formLayout.setFieldGrowthPolicy(
            QtGui.QFormLayout.AllNonFixedFieldsGrow)
        self.formLayout.setContentsMargins(-1, 0, -1, -1)
        self.formLayout.setHorizontalSpacing(6)
        self.formLayout.setObjectName(_fromUtf8("formLayout"))

        self.pushButton = QtGui.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(555, 180, 75, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.run)

        self.timesheetLabel = QtGui.QLabel(self.formLayoutWidget)
        self.timesheetLabel.setObjectName(_fromUtf8("timesheetLabel"))
        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
                                  self.timesheetLabel)
        self.timesheetLineEdit = QtGui.QLineEdit(self.formLayoutWidget)
        self.timesheetLineEdit.setEnabled(True)
        self.timesheetLineEdit.setObjectName(_fromUtf8("timesheetLineEdit"))
        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
                                  self.timesheetLineEdit)

        self.Li_run_zhong_xin_label = QtGui.QLabel(self.formLayoutWidget)
        self.Li_run_zhong_xin_label.setObjectName(
            _fromUtf8("Li_run_zhong_xin_label"))
        self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
                                  self.Li_run_zhong_xin_label)
        self.Li_Run_ReportEdit = QtGui.QLineEdit(self.formLayoutWidget)
        self.Li_Run_ReportEdit.setObjectName(_fromUtf8("LineEdit"))
        self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole,
                                  self.Li_Run_ReportEdit)

        self.proeject_query_label = QtGui.QLabel(self.formLayoutWidget)
        self.proeject_query_label.setObjectName(
            _fromUtf8("proeject_query_label"))
        self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole,
                                  self.proeject_query_label)
        self.proeject_queryEdit = QtGui.QLineEdit(self.formLayoutWidget)
        self.proeject_queryEdit.setObjectName(_fromUtf8("LineEdit_2"))
        self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole,
                                  self.proeject_queryEdit)

        self.bCLabel = QtGui.QLabel(self.formLayoutWidget)
        self.bCLabel.setObjectName(_fromUtf8("bCLabel"))
        self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.bCLabel)
        self.bCLineEdit = QtGui.QLineEdit(self.formLayoutWidget)
        self.bCLineEdit.setObjectName(_fromUtf8("bCLineEdit"))
        self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole,
                                  self.bCLineEdit)

        self.formLayout_3 = QtGui.QFormLayout()
        self.formLayout_3.setObjectName(_fromUtf8("formLayout_3"))
        self.bCSheetLabel = QtGui.QLabel(self.formLayoutWidget)
        self.bCSheetLabel.setObjectName(_fromUtf8("bCSheetLabel"))
        self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole,
                                    self.bCSheetLabel)

        self.bCSheetLineEdit = QtGui.QLineEdit(self.formLayoutWidget)
        self.bCSheetLineEdit.setInputMask(_fromUtf8(""))
        self.bCSheetLineEdit.setEchoMode(QtGui.QLineEdit.Normal)
        self.bCSheetLineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.bCSheetLineEdit.setObjectName(_fromUtf8("bCSheetLineEdit"))
        self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole,
                                    self.bCSheetLineEdit)

        self.formLayout.setLayout(4, QtGui.QFormLayout.FieldRole,
                                  self.formLayout_3)
        self.weightLabel = QtGui.QLabel(self.formLayoutWidget)
        self.weightLabel.setObjectName(_fromUtf8("weightLabel"))
        self.formLayout.setWidget(5, QtGui.QFormLayout.LabelRole,
                                  self.weightLabel)
        self.weightEdit = QtGui.QLineEdit(self.formLayoutWidget)
        self.weightEdit.setObjectName(_fromUtf8("weight"))
        self.formLayout.setWidget(5, QtGui.QFormLayout.FieldRole,
                                  self.weightEdit)

        self.formLayout.setLayout(6, QtGui.QFormLayout.FieldRole,
                                  self.formLayout_3)
        self.outputpathLabel = QtGui.QLabel(self.formLayoutWidget)
        self.outputpathLabel.setObjectName(_fromUtf8("outputpathLabel"))
        self.formLayout.setWidget(7, QtGui.QFormLayout.LabelRole,
                                  self.outputpathLabel)
        self.outputpathEdit = QtGui.QLineEdit(self.formLayoutWidget)
        self.outputpathEdit.setObjectName(_fromUtf8("LineEdit_3"))
        self.formLayout.setWidget(7, QtGui.QFormLayout.FieldRole,
                                  self.outputpathEdit)
        self.groupBox_2 = QtGui.QGroupBox(Dialog)
        self.groupBox_2.setGeometry(QtCore.QRect(5, 210, 620, 250))

        self.groupBox_2.setObjectName(_fromUtf8("groupBox_2"))
        self.textBrowser = QtGui.QTextBrowser(self.groupBox_2)
        self.textBrowser.setGeometry(QtCore.QRect(5, 14, 610, 232))
        self.textBrowser.setObjectName(_fromUtf8("textBrowser"))

        self.toolButton_time_sheet = QtGui.QToolButton(Dialog)
        self.toolButton_time_sheet.setGeometry(QtCore.QRect(510, 19, 40, 20))
        self.toolButton_time_sheet.setObjectName(
            _fromUtf8("toolButton_time_sheet"))
        self.toolButton_lirun = QtGui.QToolButton(Dialog)
        self.toolButton_lirun.setGeometry(QtCore.QRect(510, 45, 40, 20))
        self.toolButton_lirun.setObjectName(_fromUtf8("toolButton_lirun"))
        self.toolButton_project_qurey = QtGui.QToolButton(Dialog)
        self.toolButton_project_qurey.setGeometry(QtCore.QRect(
            510, 74, 40, 20))
        self.toolButton_project_qurey.setObjectName(
            _fromUtf8("toolButton_project_qurey"))
        self.toolButton_bc = QtGui.QToolButton(Dialog)
        self.toolButton_bc.setGeometry(QtCore.QRect(510, 100, 40, 20))
        self.toolButton_bc.setObjectName(_fromUtf8("toolButton_bc"))

        self.toolButton_weight = QtGui.QToolButton(Dialog)
        self.toolButton_weight.setGeometry(QtCore.QRect(510, 150, 40, 20))
        self.toolButton_weight.setObjectName(_fromUtf8("toolButton_weight"))

        #
        self.toolButton_output = QtGui.QToolButton(Dialog)
        self.toolButton_output.setGeometry(QtCore.QRect(510, 180, 40, 20))
        self.toolButton_output.setObjectName(_fromUtf8("toolButton_output"))

        self.connect(self.toolButton_time_sheet, SIGNAL("clicked()"),
                     lambda: self.brower_file(self.timesheetLineEdit))
        self.connect(self.toolButton_lirun, SIGNAL("clicked()"),
                     lambda: self.brower_file(self.Li_Run_ReportEdit))
        self.connect(self.toolButton_project_qurey, SIGNAL("clicked()"),
                     lambda: self.brower_file(self.proeject_queryEdit))
        self.connect(self.toolButton_bc, SIGNAL("clicked()"),
                     lambda: self.brower_file(self.bCLineEdit))
        self.connect(self.toolButton_weight, SIGNAL("clicked()"),
                     lambda: self.brower_file(self.weightEdit))
        self.connect(self.toolButton_output, SIGNAL("clicked()"),
                     lambda: self.brower_dir(self.outputpathEdit))

        self.retranslateUi(Dialog)

        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(_translate("Dialog", "财务报表统计", None))
        self.groupBox.setTitle(_translate("Dialog", "路径输入框", None))
        self.timesheetLabel.setText(_translate("Dialog", "TimeSheet报表", None))
        self.Li_run_zhong_xin_label.setText(
            _translate("Dialog", "利润中心报表", None))
        self.proeject_query_label.setText(
            _translate("Dialog", "项目综合查询报表", None))
        self.bCLabel.setText(_translate("Dialog", "BC报表", None))
        self.bCSheetLabel.setText(
            _translate("Dialog", "BC报表中的sheet页名称                ", None))
        self.bCSheetLineEdit.setText(_translate("Dialog", "2019-07", None))
        self.weightLabel.setText(_translate("Dialog", "权重表", None))
        self.outputpathLabel.setText(_translate("Dialog", "汇总后输出路径", None))
        self.groupBox_2.setTitle(_translate("Dialog", "输出", None))
        self.pushButton.setText(_translate("Dialog", "Run", None))
        self.toolButton_time_sheet.setText(_translate("Dialog", "...", None))
        self.toolButton_lirun.setText(_translate("Dialog", "...", None))
        self.toolButton_project_qurey.setText(_translate(
            "Dialog", "...", None))
        self.toolButton_bc.setText(_translate("Dialog", "...", None))
        self.toolButton_weight.setText(_translate("Dialog", "...", None))
        self.toolButton_output.setText(_translate("Dialog", "...", None))

    def initial_config(self):
        self.bc_sheet_name = unicode(self.bCSheetLineEdit.text())
        self.bc_report_path = unicode(self.bCLineEdit.text())
        self.li_run_report_path = unicode(self.Li_Run_ReportEdit.text())
        self.proeject_query_report_path = unicode(
            self.proeject_queryEdit.text())
        self.timesheet_report_path = unicode(self.timesheetLineEdit.text())
        self.weight_path = unicode(self.weightEdit.text())
        self.output_path = os.path.join(unicode(self.outputpathEdit.text()),
                                        "result.xls")

        self.config.set_timesheet_report_path(self.timesheet_report_path)
        self.config.set_bc_report_path(self.bc_report_path)
        self.config.set_bc_sheet_name(self.bc_sheet_name)
        self.config.set_profit_report_path(self.li_run_report_path)
        self.config.set_project_query_report_path(
            self.proeject_query_report_path)
        self.config.set_weight_path(self.weight_path)
        self.config.set_output_path(self.output_path)
        self.config.set_textBrowser(self.textBrowser)

    def brower_file(self, line_edit):
        path = QFileDialog.getOpenFileName(self, 'Open file', '.', "*")
        if path:
            line_edit.setText(unicode(path))

    def brower_dir(self, line_edit):
        dir_path = QFileDialog.getExistingDirectory(self, "select directory ",
                                                    "/")
        if dir_path:
            line_edit.setText(dir_path)

    def is_empty(self, path):
        if not path:
            return False
        return True

    def run(self):

        if self.get_is_run():
            self.textBrowser.clear()
            time.sleep(0.2)
            self.textBrowser.insertPlainText(u"正在处理,请稍等...\n")
            return

        self.initial_config()
        result = map(self.is_empty, [
            self.proeject_query_report_path, self.bc_report_path,
            self.timesheet_report_path, self.li_run_report_path,
            self.bc_sheet_name, self.output_path
        ])
        if False in result:
            msg = u"输入框不能为空\n"
            self.textBrowser.insertPlainText(msg)
            LOG.info(msg)
            return

        t = threading.Thread(target=self.caculate)
        t.setDaemon(True)
        t.start()
        self.textBrowser.clear()
        self.textBrowser.insertPlainText(u"请稍后...\n")
        self.set_is_run(True)

    def caculate(self):
        try:
            main_process = process.Caculating()
            main_process.update()

            self.textBrowser.append("completed.")
            self.textBrowser.append(u"文件已经输出到:%s" % self.output_path)
            LOG.info(u"计算完成,文件路径:%s" % self.output_path)
        except Exception as e:
            LOG.info(e)
            if type(e) != unicode or type(e) != str:
                e = str(e)
            self.textBrowser.append(e)
            self.set_is_run(False)

    def set_is_run(self, boolean):
        global is_run
        is_run = boolean

    def get_is_run(self):
        global is_run
        return is_run
Esempio n. 14
0
class WeightData(object):
    '''
    获取权重数据表数据
    '''
    instance_flag = False
    _instance_lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if not hasattr(WeightData, "_instance"):
            with WeightData._instance_lock:
                if not hasattr(WeightData, "_instance"):
                    WeightData._instance = object.__new__(cls)
        return WeightData._instance

    def __init__(self):
        if not WeightData.instance_flag:
            self.config = Config()
            self.textBrowser = self.config.get_textBrowser()

            self.sheet = None
            self.path = self.config.get_weight_path()
            if self.path:
                excel = ExcelRead(self.textBrowser, self.path)
                sheet_name = self.get_sheet_name()
                self.sheet = excel.get_sheet_by_name(sheet_name)
                self.title_index_dict = excel.get_col_index_of_title()

                self.cost_center_name_list = self.get_cost_center_name()
                self.weight_data_dict = self._get_weight_data_dict()
                WeightData.instance_flag = True

            else:  # 权重路径未设置的情况下,初始化为空
                self.weight_data_dict = dict()
                WeightData.instance_flag = True

    def get_sheet_name(self):
        try:
            sheet_name = self.config.get_value("Weight", "weight_sheet_name")
        except Exception as e:
            msg = u"从配置文件获取 weight_sheet_name 出错: %s" % e
            LOG.error(msg)
            self.textBrowser.append(str(msg))
            return None
        return sheet_name

    def get_cost_center_name(self):
        return self.config.get_cost_center_name_list()

    def _get_weight_data_dict(self):
        """
        获取 权重 数据对象的字典集合,key为project id
        :return: 数据字典
        """
        if not self.title_index_dict.has_key(u"项目编号"):
            msg = u"未找到项目编号列"
            self.textBrowser.append(msg)
            raise Exception(msg)

        index_of_project_col_num = self.title_index_dict.get(u"项目编号")

        zone_dict = self.config.get_zone_dict()

        # 取交集,判断权重表 与 配置文件中的所有成本中心,是否存在交集
        if not Util.has_intersection(self.title_index_dict.keys(), zone_dict.values()):
            msg = u"权重表中的成本中心名称和配置的成本中心名称无法对应。"
            LOG.error(msg)
            raise Exception(msg)

        weight_data_dict = dict()
        for row in range(1, self.sheet.nrows):
            tmp_dict = dict()
            proejct_id = self.sheet.cell_value(row, index_of_project_col_num)
            # 获取各成本中心权重
            for zone_US, zone_ZH in zone_dict.items():
                col_index = self.title_index_dict.get(zone_ZH)
                # 权重表中不存在该条成本中心,则继续循环
                if not col_index:
                    continue
                value = self.sheet.cell_value(row, col_index)
                if value:
                    tmp_dict[zone_ZH] = value
            weight_data_dict[proejct_id] = tmp_dict
        return weight_data_dict

    def get_weight_data_dict(self):
        return self.weight_data_dict