feat: 更新十一地市计算逻辑

This commit is contained in:
han0
2024-07-10 16:08:47 +08:00
parent 5afcfc4846
commit 967bb57136
19 changed files with 144 additions and 139 deletions

View File

@@ -19,8 +19,10 @@ class AsphaltDomesticCalculator(Calculator):
query = DataNetwork.get_query(self.year, self.month, name='石油沥青', spec='国产')
data = query.first()
price = data.price if data else 0
previous_price = int(getattr(self.previous_prices, 'price_network', price))
fluctuating = price - previous_price
return price, fluctuating
def _get_survey_price(self):

View File

@@ -1,7 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.asphalt_imported import AsphaltImported
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.price_result import PriceResult
@@ -17,11 +17,11 @@ class AsphaltImportedCalculator(Calculator):
self.month = month
def _get_network_price(self):
items = AsphaltImported.get_items(year=self.year, month=self.month, name_in=('新加坡—华东',))
prices = {name: float(price or 0) for name, price in items}
query = DataNetwork.get_query(self.year, self.month, name='石油沥青', spec='进口')
data = query.first()
price = data.price if data else 0
price = prices.get('新加坡—华东', 0)
previous_price = int(getattr(self.previous_prices, 'price_network', 0))
previous_price = int(getattr(self.previous_prices, 'price_network', price))
fluctuating = price - previous_price
return price, fluctuating
@@ -29,10 +29,8 @@ class AsphaltImportedCalculator(Calculator):
def _get_survey_price(self):
query = FujianSurvey.get_query(self.year, self.month, name='石油沥青', spec='进口 (路面用)')
query = query.with_entities(func.avg(FujianSurvey.price))
result = query.all()
if not result[0][0]:
return 0, 0
price = int(result[0][0])
data = query.first()
price = int(data[0]) if data[0] else 0
fluctuating = price - int(getattr(self.previous_prices, 'price_survey', price))
return price, fluctuating
@@ -49,7 +47,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = AsphaltImportedCalculator(year=2023, month=10)
calculator = AsphaltImportedCalculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,7 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.cement import Cement
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
@@ -22,40 +22,40 @@ class Cement325Calculator(Calculator):
def _get_ftb_price(self):
query = FuzhouTransportationBureau.get_query(self.year, self.month, name='32.5级水泥')
query = query.with_entities(func.avg(FuzhouTransportationBureau.price))
result = query.all()
if not result[0][0]:
return 0, 0
price = int(result[0][0])
data = query.first()
price = int(data[0]) if data[0] else 0
fluctuating = price - int(getattr(self.previous_prices, 'ftb_price', price))
return price, fluctuating
def _get_fhb_price(self):
query = FuzhouHighwayBureau.get_query(self.year, self.month, name='32.5级水泥', spec='旋窑(散装)')
query = query.with_entities(func.avg(FuzhouHighwayBureau.price))
result = query.all()
if not result[0][0]:
return 0, 0
price = int(result[0][0])
data = query.first()
price = int(data[0]) if data[0] else 0
fluctuating = price - int(getattr(self.previous_prices, 'ftb_price', price))
return price, fluctuating
def _get_network_price(self):
result = Cement.get_items(self.year, self.month, spec_in=('', '金牛', '炼石牌'), name_in=('P.S.A32.5', 'M32.5', 'P.P 32.5R'), pack='散装')
prices = result[0][0]
if not result[0][0]:
return 0, 0
price = round(prices / 5) * 5
query = DataNetwork.get_query(self.year, self.month, name='', spec='32.5')
data = query.first()
price = data.price if data else 0
fluctuating = price - int(getattr(self.previous_prices, 'price_network', price))
return price, fluctuating
def _get_survey_price(self):
query = FujianSurvey.get_query(self.year, self.month, name='32.5级水泥', spec='旋窑')
query = query.with_entities(func.avg(FujianSurvey.price))
result = query.all()
if not result[0][0]:
return 0, 0
price = int(result[0][0])
data = query.first()
price = int(data[0]) if data[0] else 0
fluctuating = price - int(getattr(self.previous_prices, 'price_survey', price))
return price, fluctuating
def _get_recommend_price(self, round_by=5):

View File

@@ -1,7 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.cement import Cement
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
@@ -44,11 +44,9 @@ class Cement425Calculator(Calculator):
return price, fluctuating
def _get_network_price(self):
result = Cement.get_items(self.year, self.month, spec_in=('', '金牛', '炼石牌'), name_in=('P.O 42.5',), pack='散装')
if not result[0][0]:
return 0, 0
prices = result[0][0]
price = round(prices / 5) * 5
query = DataNetwork.get_query(self.year, self.month, name='', spec='42.5')
data = query.first()
price = data.price if data else 0
fluctuating = price - int(getattr(self.previous_prices, 'price_network', price))
return price, fluctuating
@@ -75,7 +73,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = Cement425Calculator(year=2023, month=11)
calculator = Cement425Calculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,7 +1,7 @@
import datetime
from calculators import Calculator, Helper
from commons.models.oil import Oil
from commons.models.data_network import DataNetwork
from commons.models.price_result import PriceResult
@@ -17,27 +17,10 @@ class Oil0Calculator(Calculator):
self.month = month
def _get_network_price(self):
name_in = ('车用0号柴油',)
# 获取上月末价格
previous_items = Oil.get_items(*Helper.get_last_month(self.year, self.month), name_in=name_in)
previous_item = previous_items[-1]
previous_price = previous_item.price
query = DataNetwork.get_query(self.year, self.month, name='柴油', spec='0号')
data = query.first()
price = data.price if data else 0
current_items = Oil.get_items(self.year, self.month, name_in=name_in)
# 从本月1号开始计算加权总数
start_date = datetime.date(self.year, self.month, 1)
previous_date = start_date
total_with_weight = 0
for item in current_items:
total_with_weight += previous_price * (item.date - previous_date).days
previous_price = item.price
previous_date = item.date
# 直到月末
end_date = datetime.date(*Helper.get_next_month(self.year, self.month), 1) - datetime.timedelta(days=1)
if end_date > previous_date:
total_with_weight += previous_price * (end_date - previous_date).days
# 计算
price = round(total_with_weight / (end_date - start_date).days) / 1000
fluctuating = price - int(getattr(self.previous_prices, 'price_network', price))
return round(price, 2), round(fluctuating, 2)
@@ -57,7 +40,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = Oil0Calculator(year=2023, month=11)
calculator = Oil0Calculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,7 +1,7 @@
import datetime
from calculators import Calculator, Helper
from commons.models.oil import Oil
from calculators import Calculator
from commons.models.data_network import DataNetwork
from commons.models.price_result import PriceResult
@@ -17,27 +17,10 @@ class Oil89Calculator(Calculator):
self.month = month
def _get_network_price(self):
name_in = ('车用89号汽油ⅥB',)
# 获取上月末价格
previous_items = Oil.get_items(*Helper.get_last_month(self.year, self.month), name_in=name_in)
previous_item = previous_items[-1]
previous_price = previous_item.price
query = DataNetwork.get_query(self.year, self.month, name='汽油', spec='89号')
data = query.first()
price = data.price if data else 0
current_items = Oil.get_items(self.year, self.month, name_in=name_in)
# 从本月1号开始计算加权总数
start_date = datetime.date(self.year, self.month, 1)
previous_date = start_date
total_with_weight = 0
for item in current_items:
total_with_weight += previous_price * (item.date - previous_date).days
previous_price = item.price
previous_date = item.date
# 直到月末
end_date = datetime.date(*Helper.get_next_month(self.year, self.month), 1) - datetime.timedelta(days=1)
if end_date > previous_date:
total_with_weight += previous_price * (end_date - previous_date).days
# 计算
price = round(total_with_weight / (end_date - start_date).days) / 1000
fluctuating = price - int(getattr(self.previous_prices, 'price_network', price))
return round(price, 2), round(fluctuating, 2)

View File

@@ -1,6 +1,7 @@
import datetime
from calculators import Calculator, Helper
from commons.models.data_network import DataNetwork
from commons.models.oil import Oil
from commons.models.price_result import PriceResult
@@ -17,27 +18,10 @@ class Oil92Calculator(Calculator):
self.month = month
def _get_network_price(self):
name_in = ('车用92号汽油ⅥB',)
# 获取上月末价格
previous_items = Oil.get_items(*Helper.get_last_month(self.year, self.month), name_in=name_in)
previous_item = previous_items[-1]
previous_price = previous_item.price
query = DataNetwork.get_query(self.year, self.month, name='汽油', spec='92号')
data = query.first()
price = data.price if data else 0
current_items = Oil.get_items(self.year, self.month, name_in=name_in)
# 从本月1号开始计算加权总数
start_date = datetime.date(self.year, self.month, 1)
previous_date = start_date
total_with_weight = 0
for item in current_items:
total_with_weight += previous_price * (item.date - previous_date).days
previous_price = item.price
previous_date = item.date
# 直到月末
end_date = datetime.date(*Helper.get_next_month(self.year, self.month), 1) - datetime.timedelta(days=1)
if end_date > previous_date:
total_with_weight += previous_price * (end_date - previous_date).days
# 计算
price = round(total_with_weight / (end_date - start_date).days) / 1000
fluctuating = price - int(getattr(self.previous_prices, 'price_network', price))
return round(price, 2), round(fluctuating, 2)
@@ -57,7 +41,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = Oil92Calculator(year=2023, month=11)
calculator = Oil92Calculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,11 +1,11 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
from commons.models.price_result import PriceResult
from commons.models.steel_plate import SteelPlate
class SteelPlateCalculator(Calculator):
@@ -42,9 +42,11 @@ class SteelPlateCalculator(Calculator):
return price, fluctuating
def _get_network_price(self):
result = SteelPlate.get_items(self.year, self.month)
prices = {spec: float(price) for spec, price in result}
price = 0.2 * prices.get('12', 0) + 0.6 * prices.get('16-20', 0) + 0.2 * prices.get('22-28', 0)
query = DataNetwork.get_query(self.year, self.month, name='钢板')
data = query.all()
prices = {item.spec.strip(): float(item.price) for item in data}
price = 0.2 * prices.get('12mm', 0) + 0.6 * prices.get('16-20mm', 0) + 0.2 * prices.get('22-28mm', 0)
price = round(price)
fluctuating = price - getattr(self.previous_prices, 'price_network', price)
@@ -73,7 +75,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = SteelPlateCalculator(year=2023, month=11)
calculator = SteelPlateCalculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
@@ -50,10 +51,9 @@ class Reber300Calculator(Calculator):
return price, fluctuating
def _get_network_price(self):
result = SteelRebar.get_items(self.year, self.month, 'HPB300')
price_dict = {spec: price for spec, material, price in result}
price = 0.3 * float(price_dict.get('Φ6', 0)) + 0.7 * float(price_dict.get('Φ8-10', 0))
price = round(price)
query = DataNetwork.get_query(self.year, self.month, name='光圆钢筋', spec='综合')
data = query.first()
price = round(data.price) if data else 0
fluctuating = price - getattr(self.previous_prices, 'price_network', price)
return price, fluctuating
@@ -81,7 +81,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = Reber300Calculator(year=2023, month=10)
calculator = Reber300Calculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
@@ -50,11 +51,9 @@ class Reber400Calculator(Calculator):
return price, fluctuating
def _get_network_price(self):
result = SteelRebar.get_items(self.year, self.month, 'HRB400E')
price_dict = {spec: price for spec, material, price in result}
price = 0.2 * float(price_dict.get('Φ12', 0)) + 0.2 * float(price_dict.get('Φ14', 0)) + \
0.4 * float(price_dict.get('Φ18-22', 0)) + 0.2 * float(price_dict.get('Φ28-32', 0))
price = round(price)
query = DataNetwork.get_query(self.year, self.month, name='带肋钢筋') # spec='综合' 部分历史表格没有填写规格
data = query.first()
price = round(data.price) if data else 0
fluctuating = price - getattr(self.previous_prices, 'price_network', price)
return price, fluctuating
@@ -82,7 +81,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = Reber400Calculator(year=2023, month=10)
calculator = Reber400Calculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
@@ -42,10 +43,9 @@ class SteelSectionCalculator(Calculator):
return price, fluctuating
def _get_network_price(self):
result = SteelSection.get_items(self.year, self.month)
if not result[0][0]:
return 0, 0
price = round(result[0][0])
query = DataNetwork.get_query(self.year, self.month, name='型钢')
data = query.first()
price = round(data.price) if data else 0
fluctuating = price - getattr(self.previous_prices, 'price_network', price)
return price, fluctuating
@@ -73,7 +73,7 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculator = SteelSectionCalculator(year=2023, month=11)
calculator = SteelSectionCalculator(year=2024, month=5)
result = calculator.run()
calculator.save()
print(result)

View File

@@ -1,6 +1,7 @@
from sqlalchemy import func
from calculators import Calculator
from commons.models.data_network import DataNetwork
from commons.models.fujian_survey import FujianSurvey
from commons.models.fuzhou_highway_bureau import FuzhouHighwayBureau
from commons.models.fuzhou_transportation_bureau import FuzhouTransportationBureau
@@ -42,9 +43,9 @@ class SteelStrandCalculator(Calculator):
return price, fluctuating
def _get_network_price(self):
result = SteelStrand.get_items(self.year, self.month)
prices = {material: float(price) for material, price in result}
price = round(prices.get('SWRH82B', 0))
query = DataNetwork.get_query(self.year, self.month, name='钢绞线')
data = query.first()
price = round(data.price) if data else 0
fluctuating = price - getattr(self.previous_prices, 'price_network', price)
return price, fluctuating

View File

@@ -266,9 +266,6 @@ class Collector:
self.get_avg()
# todo 调查表入库时名称去除空格
if __name__ == '__main__':
from core.factory import ClientApp

View File

@@ -41,14 +41,14 @@ class DataNetwork(db.Model, Model, BaseModelMixin):
return result
@classmethod
def get_query(cls, year, month, name, spec, region="福州"):
def get_query(cls, year, month, name, spec=None, region="福州"):
start_date = datetime.date(year, month, 1)
end_date = start_date + relativedelta(months=1)
query = cls.query
query = query.filter(cls.date >= start_date)
query = query.filter(cls.date < end_date)
if name:
query = query.filter(cls.name == name)
query = query.filter(cls.name.like(f'%{name}%'))
if spec:
query = query.filter(cls.spec.like(f'%{spec}%'))
if region:

View File

@@ -17,6 +17,7 @@ class FujianSurvey(db.Model):
unit = Column('UNIT', String(128), comment='单位')
brand = Column('BRAND', String(128), comment='品牌')
tax = Column('TAX', Integer, comment='税率')
region = Column('REGION', String(128), comment='地区')
__table_args__ = (
UniqueConstraint(name, spec, date, name='Idx_key'),
@@ -24,7 +25,7 @@ class FujianSurvey(db.Model):
)
@classmethod
def get_query(cls, year=None, month=None, name=None, spec=None, name_in=None):
def get_query(cls, year=None, month=None, name=None, spec=None, name_in=None, region='福州'):
query = cls.query
if year and month:
start_date = datetime.date(year, month, 1)
@@ -37,4 +38,6 @@ class FujianSurvey(db.Model):
query = query.filter(cls.name.in_(name_in))
if spec:
query = query.filter(cls.spec == spec)
if region:
query = query.filter(cls.region.like(f'%{region}%'))
return query

View File

@@ -16,14 +16,15 @@ class FuzhouHighwayBureau(db.Model):
material_id = Column('MATERIAL_ID', String(128), comment='材料id')
unit = Column('UNIT', String(128), comment='单位')
brand = Column('BRAND', String(128), comment='品牌')
region = Column('REGION', String(128), comment='地区')
__table_args__ = (
UniqueConstraint(name, spec, date, name='Idx_key'),
UniqueConstraint(name, spec, date, region, name='Idx_key'),
{'comment': '福州公路局'},
)
@classmethod
def get_query(cls, year, month, name, spec=None):
def get_query(cls, year, month, name, spec=None, region='福州'):
start_date = datetime.date(year, month, 1)
end_date = start_date + relativedelta(months=1)
query = cls.query
@@ -33,4 +34,6 @@ class FuzhouHighwayBureau(db.Model):
query = query.filter(cls.name == name)
if spec:
query = query.filter(cls.spec == spec)
if region:
query = query.filter(cls.region.like(f'%{region}%'))
return query

View File

@@ -16,14 +16,15 @@ class FuzhouTransportationBureau(db.Model):
material_id = Column('MATERIAL_ID', String(128), comment='材料id')
unit = Column('UNIT', String(128), comment='单位')
brand = Column('BRAND', String(128), comment='品牌')
region = Column('REGION', String(128), comment='地区')
__table_args__ = (
UniqueConstraint(name, spec, date, name='Idx_key'),
UniqueConstraint(name, spec, date, region, name='Idx_key'),
{'comment': '福州交通局'},
)
@classmethod
def get_query(cls, year, month, name):
def get_query(cls, year, month, name, region='福州'):
start_date = datetime.date(year, month, 1)
end_date = start_date + relativedelta(months=1)
query = cls.query
@@ -31,4 +32,6 @@ class FuzhouTransportationBureau(db.Model):
query = query.filter(cls.date < end_date)
if name:
query = query.filter(cls.name == name)
if region:
query = query.filter(cls.region.like(f'%{region}%'))
return query

View File

@@ -0,0 +1,53 @@
import os
import zipfile
from pathlib import Path
def main(zip_path=r'C:\Users\Administrator\Desktop\材料管理系统模版\造价站近两年价格数据.zip'):
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
for file_info in zip_ref.infolist():
filename = file_info.filename.encode('cp437').decode('gbk')
is_excel = filename.endswith('.xlsx') or filename.endswith('.xls')
is_fuzhou = '福州' in filename
# 地材
# if is_excel and is_fuzhou and '地材汇总/' in filename and '福州市交通工程地方材料价格信息汇总表(数据处理)' not in filename\
# and '混凝土价格' not in filename:
# year, month = get_month(filename)
# print(year, month, filename)
# 调查表
if is_excel and is_fuzhou and '11地市调查表/' in filename and '福建省' not in filename and '通闽公司' not in filename and '-' not in filename:
year, month = get_month(filename)
print(year, month, filename)
target_file_path = f'./{year}-{month}-调查表-福州{Path(filename).suffix}'
with open(target_file_path, 'wb') as f:
f.write(zip_ref.read(file_info))
# 公路局
# if is_excel and is_fuzhou and '4.福州公路' in filename:
# print(filename)
# 交通局
# if is_excel and is_fuzhou and '1.福州交通局' in filename:
# print(filename)
# 网络价格
# if is_excel and is_fuzhou and '网络价格(' in filename and '通闽公司' not in filename and '5.福州' not in filename:
# print(filename)
# 改性剂
# if is_excel and '改性剂和沙钢' in filename :
# print(filename)
# 三明钢铁
# if is_excel and '2.三明钢铁' in filename:
# print(filename)
def get_month(filename):
if '年信息价/' in filename:
year = filename.split('年信息价')[0].split('/')[-1]
month = filename.split('月发布)')[0].split('')[-1]
return year, month
elif '月份地材汇总/' in filename:
year = filename.split('年地材/')[0].split('/')[-1]
month = filename.split('月份地材汇总')[0].split('')[-1]
return year, month
if __name__ == '__main__':
main()

View File

@@ -19,10 +19,6 @@ def calculate(year=2023, month=8):
计算生成趋势表
"""
# todo-1 价格计算触发器
# todo-1 十一地市 交通局 计算调整
# todo-1 十一地市 公路局 计算调整
# todo-1 十一地市 调查表 计算调整
# todo-1 十一地市 网络价格 计算调整
for Calculator in [
AsphaltDomesticCalculator,
AsphaltImportedCalculator,
@@ -49,4 +45,4 @@ if __name__ == '__main__':
from core.factory import ClientApp
with ClientApp().app_context():
calculate(2024, 4)
calculate(2024, 5)