Beispiel #1
0
class CompanyClientFlag(BaseModel, db.Model):
    __tablename__ = 'company_client_flags'
    PER_PAGE = 10

    company_id = Column(Integer, ForeignKey("companies.id"))
    client_flag = Column(EnumType(enum_class=ClientFlag))

    def __init__(self,
                 company_id=None,
                 client_flag=None,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(CompanyClientFlag, self).__init__(created_at, created_user, updated_at, updated_user)
        self.company_id = company_id
        self.client_flag = client_flag

    def __repr__(self):
        return "<CompanyClientFlag:" + \
                "'id='{}".format(self.id) + \
                "', company_id='{}".format(self.company_id) + \
                "', client_flag='{}".format(self.client_flag) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"
class ProjectAttachment(BaseModel, db.Model):
    __tablename__ = 'project_attachments'
    PER_PAGE = 10

    project_id = Column(Integer, ForeignKey("projects.id"), nullable=False)
    attachment_id = Column(Integer, ForeignKey("attachments.id"), nullable=False)
    type = Column(EnumType(enum_class=ProjectAttachmentType), nullable=False)
    remarks = Column(String(256))

    attachment = relationship(Attachment, lazy='subquery')

    def __init__(self,
                 project_id=None,
                 attachment_id=None,
                 type=None,
                 remarks=None,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(ProjectAttachment, self).__init__(created_at, created_user, updated_at, updated_user)
        self.project_id = project_id
        self.attachment_id = attachment_id
        self.type = type
        self.remarks = remarks

    def __repr__(self):
        return "<ProjectAttachment:" + \
                "'id='{}".format(self.id) + \
                "', project_id='{}".format(self.project_id) + \
                "', attachment_id='{}".format(self.attachment_id) + \
                "', type='{}".format(self.type.name) + \
                "', remarks='{}".format(self.remarks) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"
class Project(BaseModel, db.Model):
    __tablename__ = 'projects'
    PER_PAGE = 10

    project_name = Column(String(128), nullable=False)
    project_name_for_bp = Column(String(128))
    status = Column(EnumType(enum_class=Status), nullable=False, default=1)
    recorded_department_id = Column(Integer, ForeignKey("departments.id"))
    sales_person = Column(String(128))
    estimation_no = Column(String(64), unique=True)
    end_user_company_id = Column(Integer, ForeignKey("companies.id"))
    client_company_id = Column(Integer, ForeignKey("companies.id"))
    _start_date = Column('start_date', Date, nullable=False)
    end_date = Column(Date, nullable=False)
    contract_form = Column(EnumType(enum_class=Contract))
    billing_timing = Column(EnumType(enum_class=BillingTiming))
    estimated_total_amount = Column(Integer)
    billing_tax = Column(EnumType(enum_class=Tax))
    scope = Column(String(1024))
    contents = Column(String(1024))
    working_place = Column(String(1024))
    delivery_place = Column(String(1024))
    deliverables = Column(String(1024))
    inspection_date = Column(Date)
    responsible_person = Column(String(128))
    quality_control = Column(String(128))
    subcontractor = Column(String(128))
    remarks = Column(String(1024))
    client_order_no = Column(String(64))

    end_user_company = relationship(Company,
                                    lazy='joined',
                                    foreign_keys=[end_user_company_id])
    client_company = relationship(Company,
                                  lazy='joined',
                                  foreign_keys=[client_company_id])
    recorded_department = relationship(Department, lazy='joined')
    project_attachments = relationship(ProjectAttachment,
                                       cascade='all, delete-orphan')
    project_details = relationship(ProjectDetail, cascade='all, delete-orphan')
    project_months = relationship(ProjectMonth,
                                  order_by="desc(ProjectMonth.project_month)",
                                  cascade='all, delete-orphan')

    _is_start_date_change = False

    @hybrid_property
    def start_date(self):
        return self._start_date

    @start_date.setter
    def start_date(self, value):
        old = self._get_fiscal_year(self._start_date)
        new = self._get_fiscal_year(value)

        if old != new:
            self._is_start_date_change = True
        self._start_date = value

    @property
    def is_start_date_change(self):
        if not self.id:
            return True
        return self._is_start_date_change

    def __init__(self,
                 project_name=None,
                 project_name_for_bp=None,
                 status=Status.start,
                 recorded_department_id=None,
                 sales_person=None,
                 estimation_no=None,
                 end_user_company_id=None,
                 client_company_id=None,
                 start_date=None,
                 end_date=None,
                 contract_form=None,
                 billing_timing=None,
                 estimated_total_amount=None,
                 billing_tax=None,
                 scope=None,
                 contents=None,
                 working_place=None,
                 delivery_place=None,
                 deliverables=None,
                 inspection_date=None,
                 responsible_person=None,
                 quality_control=None,
                 subcontractor=None,
                 remarks=None,
                 client_order_no=None,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(Project, self).__init__(created_at, created_user, updated_at,
                                      updated_user)
        self.project_name = project_name
        self.project_name_for_bp = project_name_for_bp
        self.status = status
        self.recorded_department_id = recorded_department_id
        self.sales_person = sales_person
        self.estimation_no = estimation_no
        self.end_user_company_id = end_user_company_id
        self.client_company_id = client_company_id
        self._start_date = start_date
        self.end_date = end_date
        self.contract_form = contract_form
        self.billing_timing = billing_timing
        self.estimated_total_amount = estimated_total_amount
        self.billing_tax = billing_tax
        self.scope = scope
        self.contents = contents
        self.working_place = working_place
        self.delivery_place = delivery_place
        self.deliverables = deliverables
        self.inspection_date = inspection_date
        self.responsible_person = responsible_person
        self.quality_control = quality_control
        self.subcontractor = subcontractor
        self.remarks = remarks
        self.client_order_no = client_order_no

    def get_fiscal_year(self):
        return self._get_fiscal_year(self.start_date)

    def get_project_attachments(self):
        tmp = sorted(
            self.project_attachments,
            key=lambda project_attachment: project_attachment.type.value)
        project_attachments = attachments = []
        old_type = None
        for attachment in tmp:
            if old_type == attachment.type.value:
                attachments += [attachment]
            else:
                attachments = [attachment]
                project_attachments += [{
                    "type": attachment.type.name,
                    "attachments": attachments
                }]
                old_type = attachment.type.value
        return project_attachments

    @staticmethod
    def _get_fiscal_year(date_):
        if not date_:
            return None
        if int(date_.strftime('%m')) >= 10:
            return int(date_.strftime('%y')) + 1
        else:
            return int(date_.strftime('%y'))

    # 開始・終了日のそれぞれの年月をリストで返すメソッド
    def get_project_month_list(self):
        project_month_list = []
        i = 0
        start = self.start_date
        while (date(start.year, start.month, 1) +
               relativedelta(months=i)) <= self.end_date:
            project_month_list.append(
                date(start.year, start.month, 1) + relativedelta(months=i))
            i += 1
        return project_month_list

    # 見積もり合計金額を月々で割った値を取得
    def get_estimated_total_amount_by_month(self):
        return self.estimated_total_amount / len(self.get_project_month_list())

    # プロジェクトの年月情報を作成
    def create_project_months(self):
        project_dates = self.get_project_month_list()
        jst = tz.gettz('Asia/Tokyo')
        now = datetime.now(jst)
        for project_date in project_dates:
            calculator = Calculator(project_date,
                                    self.client_company.billing_site,
                                    self.client_company.bank_holiday_flag)
            project_month = ProjectMonth(
                project_month=project_date,
                billing_tax=self.client_company.billing_tax,
                deposit_date=calculator.get_deposit_date(),
                created_at=now,
                created_user=session['user']['user_name'],
                updated_at=now,
                updated_user=session['user']['user_name'])
            if self.billing_timing == BillingTiming.billing_by_month:
                money = self.get_estimated_total_amount_by_month()
                project_month.billing_estimated_money = money
                project_month.billing_confirmation_money = money
            else:
                if project_date == max(project_dates):
                    project_month.billing_estimated_money = self.estimated_total_amount
                    project_month.billing_confirmation_money = self.estimated_total_amount
            self.project_months.append(project_month)
        return self

    def require_result(self):
        for project_detail in self.project_details:
            if project_detail.is_engineer():
                return True
        return False

    def has_not_project_results(self):
        for project_detail in self.project_details:
            if project_detail.project_results:
                return False
        return True

    def has_not_project_billings(self):
        for project_detail in self.project_details:
            if project_detail.project_billings:
                return False
        return True

    def has_not_project_months(self):
        return not self.project_months

    def has_payment(self):
        return True in [
            project_detail.has_payment()
            for project_detail in self.project_details
        ]

    def tax_of_estimated_total_amount(self):
        if self.billing_tax:
            return numpy.trunc(
                (self.estimated_total_amount or 0) * self.billing_tax.rate)
        else:
            return 0

    def __repr__(self):
        return "<Project:" + \
                "'id='{}".format(self.id) + \
                "', project_name='{}".format(self.project_name) + \
                "', project_name_for_bp='{}".format(self.project_name_for_bp) + \
                "', status='{}".format(self.status) + \
                "', recorded_department_id='{}".format(self.recorded_department_id) + \
                "', sales_person='{}".format(self.sales_person) + \
                "', estimation_no='{}".format(self.estimation_no) + \
                "', end_user_company_id='{}".format(self.end_user_company_id) + \
                "', client_company_id='{}".format(self.client_company_id) + \
                "', start_date='{}".format(self.start_date) + \
                "', end_date='{}".format(self.end_date) + \
                "', contract_form='{}".format(self.contract_form) + \
                "', billing_timing='{}".format(self.billing_timing) + \
                "', estimated_total_amount='{}".format(self.estimated_total_amount) + \
                "', billing_tax='{}".format(self.billing_tax) + \
                "', scope='{}".format(self.scope) + \
                "', contents='{}".format(self.contents) + \
                "', working_place='{}".format(self.working_place) + \
                "', delivery_place='{}".format(self.delivery_place) + \
                "', deliverables='{}".format(self.deliverables) + \
                "', inspection_date='{}".format(self.inspection_date) + \
                "', responsible_person='{}".format(self.responsible_person) + \
                "', quality_control='{}".format(self.quality_control) + \
                "', subcontractor='{}".format(self.subcontractor) + \
                "', remarks='{}".format(self.remarks) + \
                "', client_order_no='{}".format(self.client_order_no) + \
                "', project_attachments='{}".format(self.project_attachments) + \
                "', project_months='{}".format(self.project_months) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"
class ProjectResult(BaseModel, db.Model):
    __tablename__ = 'project_results'
    PER_PAGE = 10

    project_detail_id = Column(Integer, ForeignKey("project_details.id"), nullable=False)
    result_month = Column(Date)
    work_time = Column(DECIMAL(6, 2))
    billing_transportation = Column(Integer)
    billing_adjustments = Column(Integer)
    billing_confirmation_number = Column(String(128))
    billing_confirmation_money = Column(Integer)
    payment_transportation = Column(Integer)
    payment_adjustments = Column(Integer)
    payment_confirmation_money = Column(Integer)
    remarks = Column(String(1024))
    billing_receipted_date = Column(Date)
    payment_expected_date = Column(Date)
    payment_flag = Column(EnumType(enum_class=InputFlag), nullable=False, default=0)

    project_detail = relationship("ProjectDetail", lazy='joined')

    def __init__(self,
                 project_detail_id=None,
                 result_month=None,
                 work_time=None,
                 billing_transportation=None,
                 billing_adjustments=None,
                 billing_confirmation_number=None,
                 billing_confirmation_money=None,
                 payment_transportation=None,
                 payment_adjustments=None,
                 payment_confirmation_money=None,
                 remarks=None,
                 billing_receipted_date=None,
                 payment_expected_date=None,
                 payment_flag=InputFlag.yet,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(ProjectResult, self).__init__(created_at, created_user, updated_at, updated_user)
        self.project_detail_id = project_detail_id
        self.result_month = result_month
        self.work_time = work_time
        self.billing_transportation = billing_transportation
        self.billing_adjustments = billing_adjustments
        self.billing_confirmation_number = billing_confirmation_number
        self.billing_confirmation_money = billing_confirmation_money
        self.payment_transportation = payment_transportation
        self.payment_adjustments = payment_adjustments
        self.payment_confirmation_money = payment_confirmation_money
        self.remarks = remarks
        self.billing_receipted_date = billing_receipted_date
        self.payment_expected_date = payment_expected_date
        self.payment_flag = payment_flag

    def is_result_input(self):
        return (self.work_time or 0) > 0

    # 指定した月の支払い税率を取得
    def tax_of_payment_confirmation_money(self, engineer_history):
        if engineer_history:
            return numpy.trunc((self.payment_confirmation_money or 0) * engineer_history.payment_tax.rate)
        else:
            return 0

    # 交通費の税額を取得
    def get_tax_of_payment_transportation(self, engineer_history):
        if engineer_history:
            return numpy.trunc((self.payment_transportation or 0) * engineer_history.payment_tax.rate_if_exclude_tax)
        else:
            return 0

    def __repr__(self):
        return "<ProjectResult:" + \
                "'id='{}".format(self.id) + \
                "', project_detail_id='{}".format(self.project_detail_id) + \
                "', result_month='{}".format(self.result_month) + \
                "', work_time='{}".format(self.work_time) + \
                "', billing_transportation='{}".format(self.billing_transportation) + \
                "', billing_adjustments='{}".format(self.billing_adjustments) + \
                "', billing_confirmation_number='{}".format(self.billing_confirmation_number) + \
                "', billing_confirmation_money='{}".format(self.billing_confirmation_money) + \
                "', payment_transportation='{}".format(self.payment_transportation) + \
                "', payment_adjustments='{}".format(self.payment_adjustments) + \
                "', payment_confirmation_money='{}".format(self.payment_confirmation_money) + \
                "', remarks='{}".format(self.remarks) + \
                "', billing_receipted_date='{}".format(self.billing_receipted_date) + \
                "', payment_expected_date='{}".format(self.payment_expected_date) + \
                "', payment_flag='{}".format(self.payment_flag) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"
Beispiel #5
0
class Company(BaseModel, db.Model):
    __tablename__ = 'companies'
    PER_PAGE = 10

    company_name = Column(String(128), nullable=False)
    company_name_kana = Column(String(128))
    company_short_name = Column(String(128))
    contract_date = Column(Date)
    postal_code = Column(String(32))
    address = Column(String(1024))
    phone = Column(String(256))
    fax = Column(String(256))
    client_code = Column(String(128))
    bp_code = Column(String(128))
    billing_site = Column(EnumType(enum_class=Site))
    payment_site = Column(EnumType(enum_class=Site))
    billing_tax = Column(EnumType(enum_class=Tax))
    payment_tax = Column(EnumType(enum_class=Tax))
    bank_id = Column(Integer, ForeignKey("banks.id"))
    bank_holiday_flag = Column(EnumType(enum_class=HolidayFlag))
    remarks = Column(String(1024))
    print_name = Column(String(1024))

    bank = relationship(Bank, lazy='joined')
    company_client_flags = relationship(CompanyClientFlag,
                                        cascade='all, delete-orphan')
    engineers = relationship("Engineer", foreign_keys="Engineer.company_id")
    end_user_projects = relationship(
        "Project", foreign_keys="Project.end_user_company_id")
    client_projects = relationship("Project",
                                   foreign_keys="Project.client_company_id")

    def __init__(self,
                 company_name=None,
                 company_name_kana=None,
                 company_short_name=None,
                 contract_date=None,
                 postal_code=None,
                 address=None,
                 phone=None,
                 fax=None,
                 client_code=None,
                 bp_code=None,
                 billing_site=None,
                 payment_site=None,
                 billing_tax=None,
                 payment_tax=None,
                 bank_id=None,
                 bank_holiday_flag=None,
                 remarks=None,
                 print_name=None,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(Company, self).__init__(created_at, created_user, updated_at,
                                      updated_user)
        self.company_name = company_name
        self.company_name_kana = company_name_kana
        self.company_short_name = company_short_name
        self.contract_date = contract_date
        self.postal_code = postal_code
        self.address = address
        self.phone = phone
        self.fax = fax
        self.client_code = client_code
        self.bp_code = bp_code
        self.billing_site = billing_site
        self.payment_site = payment_site
        self.billing_tax = billing_tax
        self.payment_tax = payment_tax
        self.bank_id = bank_id
        self.bank_holiday_flag = bank_holiday_flag
        self.remarks = remarks
        self.print_name = print_name

    def is_bp(self):
        for company_client_flag in self.company_client_flags:
            if company_client_flag.client_flag == ClientFlag.bp:
                return True
        return False

    # 会社が他のmodelと紐づいているならtrue
    def has_relationship(self):
        return self.end_user_projects or self.client_projects or self.engineers

    def __repr__(self):
        return "<Company:" + \
                "'id='{}".format(self.id) + \
                "', company_name='{}".format(self.company_name) + \
                "', company_name_kana='{}".format(self.company_name_kana) + \
                "', company_short_name='{}".format(self.company_short_name) + \
                "', contract_date='{}".format(self.contract_date) + \
                "', postal_code='{}".format(self.postal_code) + \
                "', address='{}".format(self.address) + \
                "', phone='{}".format(self.phone) + \
                "', fax='{}".format(self.fax) + \
                "', client_code='{}".format(self.client_code) + \
                "', bp_code='{}".format(self.bp_code) + \
                "', billing_site='{}".format(self.billing_site) + \
                "', payment_site='{}".format(self.payment_site) + \
                "', billing_tax='{}".format(self.payment_tax) + \
                "', payment_tax='{}".format(self.payment_tax) + \
                "', bank='{}".format(self.bank) + \
                "', bank_holiday_flag='{}".format(self.bank_holiday_flag) + \
                "', remarks='{}".format(self.remarks) + \
                "', print_name='{}".format(self.print_name) + \
                "', company_client_flags='{}".format(self.company_client_flags) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"
class Engineer(BaseModel, db.Model):
    __tablename__ = 'engineers'
    PER_PAGE = 10

    engineer_name = Column(String(128), nullable=False)
    engineer_name_kana = Column(String(128))
    birthday = Column(Date)
    gender = Column(EnumType(enum_class=Gender))
    company_id = Column(Integer, ForeignKey("companies.id"))

    company = relationship(Company, lazy='joined')
    engineer_skills = relationship(EngineerSkill, cascade='all, delete-orphan')
    engineer_business_categories = relationship(EngineerBusinessCategory,
                                                cascade='all, delete-orphan')
    engineer_histories = relationship(EngineerHistory,
                                      cascade='all, delete-orphan')
    project_details = relationship(ProjectDetail, cascade='all, delete-orphan')

    def __init__(self,
                 engineer_name=None,
                 engineer_name_kana=None,
                 birthday=None,
                 gender=None,
                 company_id=None,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(Engineer, self).__init__(created_at, created_user, updated_at,
                                       updated_user)
        self.engineer_name = engineer_name
        self.engineer_name_kana = engineer_name_kana
        self.birthday = birthday
        self.gender = gender
        self.company_id = company_id

    def is_bp(self):
        return self.company and self.company.is_bp()

    # 指定された日の期間内にある支払いサイトを返却
    def get_payment_site_by_date(self, date):
        for history in self.engineer_histories:
            if history.payment_start_day <= date <= history.payment_end_day:
                return history.payment_site
        return None

    # 指定された日の期間内にある履歴を返却
    def get_histories_by_date(self, date):
        for h in self.engineer_histories:
            if h.payment_start_day <= date <= h.payment_end_day:
                return h
        return EngineerHistory()

    def get_age(self):

        age = ""
        if self.birthday:
            today = int(datetime.today().date().strftime('%Y%m%d'))
            birthday = int(self.birthday.strftime('%Y%m%d'))
            age = int((today - birthday) / 10000)
        return age

    def __repr__(self):
        return "<Engineer:" + \
                "'id='{}".format(self.id) + \
                "', engineer_name='{}".format(self.engineer_name) + \
                "', engineer_name_kana='{}".format(self.engineer_name_kana) + \
                "', birthday='{}".format(self.birthday) + \
                "', gender='{}".format(self.gender) + \
                "', company='{}".format(self.company) + \
                "', engineer_skills='{}".format(self.engineer_skills) + \
                "', engineer_business_categories='{}".format(self.engineer_business_categories) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"
class EngineerHistory(BaseModel, db.Model):
    __tablename__ = 'engineer_histories'
    PER_PAGE = 10

    engineer_id = Column(Integer, ForeignKey("engineers.id"))
    payment_start_day = Column(Date, nullable=False)
    payment_end_day = Column(Date, nullable=False)
    payment_site = Column(EnumType(enum_class=Site))
    payment_tax = Column(EnumType(enum_class=Tax))
    payment_per_month = Column(Integer, nullable=False)
    payment_rule = Column(EnumType(enum_class=Rule), nullable=False)
    payment_bottom_base_hour = Column(Integer)
    payment_top_base_hour = Column(Integer)
    payment_free_base_hour = Column(String(128))
    payment_per_hour = Column(String(128))
    payment_per_bottom_hour = Column(Integer)
    payment_per_top_hour = Column(Integer)
    payment_fraction = Column(EnumType(enum_class=Fraction))
    payment_fraction_rule = Column(EnumType(enum_class=Round))
    payment_condition = Column(String(1024))
    remarks = Column(String(1024))

    engineer = relationship("Engineer", lazy='joined')

    def __init__(self,
                 engineer_id=None,
                 payment_start_day=None,
                 payment_end_day=date(2099, 12, 31),
                 payment_per_month=None,
                 payment_rule=None,
                 payment_site=None,
                 payment_tax=None,
                 payment_bottom_base_hour=None,
                 payment_top_base_hour=None,
                 payment_free_base_hour=None,
                 payment_per_hour=None,
                 payment_per_bottom_hour=None,
                 payment_per_top_hour=None,
                 payment_fraction=None,
                 payment_fraction_rule=None,
                 payment_condition=None,
                 remarks=None,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(EngineerHistory, self).__init__(created_at, created_user,
                                              updated_at, updated_user)
        self.engineer_id = engineer_id
        self.payment_start_day = payment_start_day
        self.payment_end_day = payment_end_day
        self.payment_site = payment_site
        self.payment_tax = payment_tax
        self.payment_per_month = payment_per_month
        self.payment_rule = payment_rule
        self.payment_bottom_base_hour = payment_bottom_base_hour
        self.payment_top_base_hour = payment_top_base_hour
        self.payment_free_base_hour = payment_free_base_hour
        self.payment_per_hour = payment_per_hour
        self.payment_per_bottom_hour = payment_per_bottom_hour
        self.payment_per_top_hour = payment_per_top_hour
        self.payment_fraction = payment_fraction
        self.payment_fraction_rule = payment_fraction_rule
        self.payment_condition = payment_condition
        self.remarks = remarks

    # 履歴を切る際にengineer情報を紐づけたまま新規履歴を作成して返すメソッド
    def create_new_history(self):
        # engineerをhistoryに紐づけた状態で返す
        engineer_history = EngineerHistory()
        engineer_history.engineer = self.engineer
        return engineer_history

    def is_contract(self):
        return self.payment_end_day <= datetime.today().date()

    def __repr__(self):
        return "<EngineerHistory:" + \
                "'id='{}".format(self.id) + \
                "', engineer='{}".format(self.engineer) + \
                "', payment_start_day='{}".format(self.payment_start_day) + \
                "', payment_end_day='{}".format(self.payment_end_day) + \
                "', payment_site='{}".format(self.payment_site) + \
                "', payment_tax='{}".format(self.payment_tax) + \
                "', payment_per_month='{}".format(self.payment_per_month) + \
                "', payment_rule='{}".format(self.payment_rule) + \
                "', payment_bottom_base_hour='{}".format(self.payment_bottom_base_hour) + \
                "', payment_top_base_hour='{}".format(self.payment_top_base_hour) + \
                "', payment_free_base_hour='{}".format(self.payment_free_base_hour) + \
                "', payment_per_hour='{}".format(self.payment_per_hour) + \
                "', payment_per_bottom_hour='{}".format(self.payment_per_bottom_hour) + \
                "', payment_per_top_hour='{}".format(self.payment_per_top_hour) + \
                "', payment_fraction='{}".format(self.payment_fraction) + \
                "', payment_fraction_rule='{}".format(self.payment_fraction_rule) + \
                "', payment_condition='{}".format(self.payment_condition) + \
                "', remarks='{}".format(self.remarks) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"
Beispiel #8
0
class ProjectDetail(BaseModel, db.Model):
    __tablename__ = 'project_details'
    PER_PAGE = 10

    project_id = Column(Integer, ForeignKey("projects.id"), nullable=False)
    detail_type = Column(EnumType(enum_class=DetailType), nullable=False)
    work_name = Column(String(128))
    engineer_id = Column(Integer, ForeignKey("engineers.id"))
    billing_money = Column(Integer)
    remarks = Column(String(1024))
    _billing_start_day = Column('billing_start_day', Date)
    billing_end_day = Column(Date)
    billing_per_month = Column(Integer)
    billing_rule = Column(EnumType(enum_class=Rule))
    billing_bottom_base_hour = Column(Integer)
    billing_top_base_hour = Column(Integer)
    billing_free_base_hour = Column(String(128))
    billing_per_hour = Column(String(128))
    billing_per_bottom_hour = Column(Integer)
    billing_per_top_hour = Column(Integer)
    billing_fraction = Column(EnumType(enum_class=Fraction))
    billing_fraction_rule = Column(EnumType(enum_class=Round))
    bp_order_no = Column(String(128))
    client_order_no_for_bp = Column(String(128))

    engineer = relationship("Engineer", lazy='joined')
    project = relationship("Project", lazy='joined')
    project_billings = relationship(ProjectBilling,
                                    cascade='all, delete-orphan')
    project_results = relationship(ProjectResult, cascade='all, delete-orphan')

    _is_billing_start_day_change = False

    @hybrid_property
    def billing_start_day(self):
        return self._billing_start_day

    @billing_start_day.setter
    def billing_start_day(self, value):
        old = self._get_fiscal_year(self._billing_start_day)
        new = self._get_fiscal_year(value)

        if old != new:
            self._is_billing_start_day_change = True
        self._billing_start_day = value

    @property
    def is_billing_start_day_change(self):
        if not self.id:
            return True
        return self._is_billing_start_day_change

    def __init__(self,
                 project_id=None,
                 detail_type=None,
                 work_name=None,
                 engineer_id=None,
                 billing_money=None,
                 remarks=None,
                 billing_start_day=None,
                 billing_end_day=None,
                 billing_per_month=None,
                 billing_rule=None,
                 billing_bottom_base_hour=None,
                 billing_top_base_hour=None,
                 billing_free_base_hour=None,
                 billing_per_hour=None,
                 billing_per_bottom_hour=None,
                 billing_per_top_hour=None,
                 billing_fraction=None,
                 billing_fraction_rule=None,
                 bp_order_no=None,
                 client_order_no_for_bp=None,
                 created_at=None,
                 created_user=None,
                 updated_at=None,
                 updated_user=None):
        super(ProjectDetail, self).__init__(created_at, created_user,
                                            updated_at, updated_user)
        self.project_id = project_id
        self.detail_type = detail_type
        self.work_name = work_name
        self.engineer_id = engineer_id
        self.billing_money = billing_money
        self.remarks = remarks
        self._billing_start_day = billing_start_day
        self.billing_end_day = billing_end_day
        self.billing_per_month = billing_per_month
        self.billing_rule = billing_rule
        self.billing_bottom_base_hour = billing_bottom_base_hour
        self.billing_top_base_hour = billing_top_base_hour
        self.billing_free_base_hour = billing_free_base_hour
        self.billing_per_hour = billing_per_hour
        self.billing_per_bottom_hour = billing_per_bottom_hour
        self.billing_per_top_hour = billing_per_top_hour
        self.billing_fraction = billing_fraction
        self.billing_fraction_rule = billing_fraction_rule
        self.bp_order_no = bp_order_no
        self.client_order_no_for_bp = client_order_no_for_bp

    @staticmethod
    def _get_fiscal_year(date_):
        if not date_:
            return None
        if int(date_.strftime('%m')) >= 10:
            return int(date_.strftime('%y')) + 1
        else:
            return int(date_.strftime('%y'))

    def is_engineer(self):
        return self.detail_type == DetailType.engineer

    def has_payment(self):
        return self.is_engineer() and self.engineer.is_bp()

    def get_fiscal_year(self):
        return self._get_fiscal_year(self.billing_start_day)

    # 支払フラグが前倒しか後ろ倒しか判断
    def get_holiday_flag_if_payment(self):
        payment_site = self.get_payment_site()

        # 支払いの場合、末日は前倒し、その他後ろ倒し
        if payment_site.is_last_day():
            bank_holiday_flag = HolidayFlag.before
        else:
            bank_holiday_flag = HolidayFlag.after

        return bank_holiday_flag

    # 開始・終了日のそれぞれの年月をリストで返すメソッド
    def get_contract_month_list(self):
        contract_month_list = []
        i = 0
        start = self.billing_start_day
        while (date(start.year, start.month, 1) +
               relativedelta(months=i)) <= self.billing_end_day:
            contract_month_list.append(
                date(start.year, start.month, 1) + relativedelta(months=i))
            i += 1
        return contract_month_list

    # 作業の請求単価(ひと月当たりに請求する金額)を取得
    def get_payment_per_month_by_work(self):
        payment = self.billing_money / len(
            self.project.get_project_month_list())
        return payment

    # 月々の実績情報を作成
    def create_results(self):
        contract_dates = self.get_contract_month_list()
        for contract_date in contract_dates:
            jst = tz.gettz('Asia/Tokyo')
            now = datetime.now(jst)
            project_result = ProjectResult(
                result_month=contract_date,
                created_at=now,
                created_user=session['user']['user_name'],
                updated_at=now,
                updated_user=session['user']['user_name'])
            if self.has_payment():
                calculator = Calculator(contract_date, self.get_payment_site(),
                                        self.get_holiday_flag_if_payment())
                project_result.payment_expected_date = calculator.get_deposit_date(
                )
            self.project_results.append(project_result)
        return self

    # 請求情報を作成
    def create_billings(self):
        if self.project.billing_timing == BillingTiming.billing_by_month:
            self.create_billing_by_month()
        else:
            self.create_billing_at_last()
        return self

    # 月々の請求情報を作成
    def create_billing_by_month(self):
        project_dates = self.project.get_project_month_list()
        for project_date in project_dates:
            jst = tz.gettz('Asia/Tokyo')
            now = datetime.now(jst)
            project_billing = ProjectBilling(
                billing_month=project_date,
                billing_content=self.work_name,
                billing_confirmation_money=self.get_payment_per_month_by_work(
                ),
                created_at=now,
                created_user=session['user']['user_name'],
                updated_at=now,
                updated_user=session['user']['user_name'])
            self.project_billings.append(project_billing)
        return self

    # 最終月の請求情報を作成
    def create_billing_at_last(self):
        project_dates = self.project.get_project_month_list()
        jst = tz.gettz('Asia/Tokyo')
        now = datetime.now(jst)
        project_billing = ProjectBilling(
            billing_month=max(project_dates),
            billing_content=self.work_name,
            billing_confirmation_money=self.billing_money,
            created_at=now,
            created_user=session['user']['user_name'],
            updated_at=now,
            updated_user=session['user']['user_name'])
        self.project_billings.append(project_billing)
        return self

    # 技術者履歴から支払いサイトを取得する。履歴が存在しない場合は会社から取得
    def get_payment_site(self):
        site = self.engineer.get_payment_site_by_date(self.project.start_date)
        return site or self.engineer.company.payment_site

    def __repr__(self):
        return "<ProjectDetails:" + \
                "'id='{}".format(self.id) + \
                "', project='{}".format(self.project) + \
                "', detail_type='{}".format(self.detail_type) + \
                "', work_name='{}".format(self.work_name) + \
                "', engineer_id='{}".format(self.engineer_id) + \
                "', billing_money='{}".format(self.billing_money) + \
                "', remarks='{}".format(self.remarks) + \
                "', billing_start_day='{}".format(self.billing_start_day) + \
                "', billing_end_day='{}".format(self.billing_end_day) + \
                "', billing_per_month='{}".format(self.billing_per_month) + \
                "', billing_rule='{}".format(self.billing_rule) + \
                "', billing_bottom_base_hour='{}".format(self.billing_bottom_base_hour) + \
                "', billing_top_base_hour='{}".format(self.billing_top_base_hour) + \
                "', billing_free_base_hour='{}".format(self.billing_free_base_hour) + \
                "', billing_per_hour='{}".format(self.billing_per_hour) + \
                "', billing_per_bottom_hour='{}".format(self.billing_per_bottom_hour) + \
                "', billing_per_top_hour='{}".format(self.billing_per_top_hour) + \
                "', billing_fraction='{}".format(self.billing_fraction) + \
                "', billing_fraction_rule='{}".format(self.billing_fraction_rule) + \
                "', bp_order_no='{}".format(self.bp_order_no) + \
                "', client_order_no_for_bp='{}".format(self.client_order_no_for_bp) + \
                "', created_at='{}".format(self.created_at) + \
                "', created_user='******', updated_at='{}".format(self.updated_at) + \
                "', updated_user='******'>"