from commons.models.price_result import PriceResult class Helper: @staticmethod def get_last_month(year, month): if month == 1: last_month_year = year - 1 last_month = 12 else: last_month_year = year last_month = month - 1 return last_month_year, last_month @staticmethod def get_next_month(year, month): if month == 12: last_month_year = year + 1 last_month = 1 else: last_month_year = year last_month = month + 1 return last_month_year, last_month class Calculator: material_id = "" name = "" year = 0 month = 0 price_ftb = 0 fluctuating_ftb = 0 price_ss = 0 fluctuating_ss = 0 price_fhb = 0 fluctuating_fhb = 0 price_network = 0 fluctuating_network = 0 price_survey = 0 fluctuating_survey = 0 price_last_month = 0 price_calculate = 0 price_recommend = 0 fluctuating_recommend = 0 price_fujian = 0 fluctuating_fujian = 0 unit = "" spec = '' _previous_prices = None _fluctuatings = [] def __init__(self, year, month, force=True): self.year = year self.month = month self.force = True # todo-2 已修改的的发布价不在覆盖计算 @property def previous_prices(self): if not self._previous_prices: previous_price = PriceResult.get_by_key(self.name, *Helper.get_last_month(self.year, self.month)) self._previous_prices = previous_price return self._previous_prices def result(self): return { 'material_id': self.material_id, 'name': self.name, 'year': self.year, 'month': self.month, 'price_ftb': self.price_ftb, 'fluctuating_ftb': self.fluctuating_ftb, 'price_ss': self.price_ss, 'fluctuating_ss': self.fluctuating_ss, 'price_fhb': self.price_fhb, 'fluctuating_fhb': self.fluctuating_fhb, 'price_network': self.price_network, 'fluctuating_network': self.fluctuating_network, 'price_survey': self.price_survey, 'fluctuating_survey': self.fluctuating_survey, 'price_last_month': self.price_last_month, 'price_calculate': self.price_calculate, 'price_recommend': self.price_recommend, 'fluctuating_recommend': self.fluctuating_recommend, 'price_fujian': self.price_fujian, 'fluctuating_fujian': self.fluctuating_fujian, 'unit': self.unit, 'spec': self.spec, } def run(self): self.price_ftb, self.fluctuating_ftb = self._get_ftb_price() self.price_ss, self.fluctuating_ss = self._get_ss_price() self.price_fhb, self.fluctuating_fhb = self._get_fhb_price() self.price_network, self.fluctuating_network = self._get_network_price() self.price_survey, self.fluctuating_survey = self._get_survey_price() self.price_last_month = self._get_last_month_price() self.price_calculate = self._get_calculate_price() self.price_recommend, self.fluctuating_recommend = self._get_recommend_price() self.price_fujian, self.fluctuating_fujian = self._get_fujian_price() return self def _get_ftb_price(self): return 0, 0 def _get_ss_price(self): return 0, 0 def _get_fhb_price(self): return 0, 0 def _get_network_price(self): return 0, 0 def _get_survey_price(self): return 0, 0 def _get_fujian_price(self): return 0, 0 def _get_last_month_price(self): return getattr(self.previous_prices, 'price_recommend', 0) def _get_calculate_price(self, round_dit=0): prices = ( self.price_ftb, self.price_ss, self.price_fhb, self.price_network, self.price_survey, self.price_last_month) total = sum(float(i) for i in prices) if total == 0: return 0 result = total / len([i for i in prices if i != 0]) result = round(result, round_dit) return result def _get_recommend_price(self, round_by=10): if not self.previous_prices: return 0, 0 previous_price = int(getattr(self.previous_prices, 'price_recommend', 0)) if not previous_price: previous_price = int(getattr(self.previous_prices, 'price_calculate', 0)) fluctuating = sum(self._fluctuatings) / len(self._fluctuatings) fluctuating = round(fluctuating / round_by) * round_by price = fluctuating + previous_price price = round(price / round_by) * round_by return price, fluctuating def save(self): result = self.result() PriceResult(**result).upsert() def _get_fluctuating(self, field_name, price): previous_price = getattr(self.previous_prices, field_name, 0) or price fluctuating = price - previous_price if price else 0 return fluctuating if __name__ == '__main__': from calculators.asphalt_domestic import AsphaltDomesticCalculator from calculators.asphalt_imported import AsphaltImportedCalculator from calculators.cement_325 import Cement325Calculator from calculators.cement_425 import Cement425Calculator from calculators.oil_0 import Oil0Calculator from calculators.oil_89 import Oil89Calculator from calculators.oil_92 import Oil92Calculator from calculators.steel_plate import SteelPlateCalculator from calculators.steel_rebar_300 import Reber300Calculator from calculators.steel_rebar_400 import Reber400Calculator from calculators.steel_section import SteelSectionCalculator from calculators.steel_strand import SteelStrandCalculator from calculators.asphalt_domestic_modifier import AsphaltDomesticModifierCalculator from calculators.asphalt_imported_modifier import AsphaltImportedModifierCalculator from core.factory import ClientApp for Calculator in [ AsphaltDomesticCalculator, AsphaltImportedCalculator, Cement325Calculator, Cement425Calculator, Oil0Calculator, Oil89Calculator, Oil92Calculator, SteelPlateCalculator, Reber300Calculator, Reber400Calculator, SteelSectionCalculator, SteelStrandCalculator, AsphaltDomesticModifierCalculator, AsphaltImportedModifierCalculator, ]: with ClientApp().app_context(): for month in range(8, 13): calculator = Calculator(year=2023, month=month) _result = calculator.run() calculator.save() print(_result)