120 lines
6.9 KiB
Python
120 lines
6.9 KiB
Python
from collections import defaultdict
|
|
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
|
|
from flask import current_app, jsonify, request, url_for
|
|
from flask_login import current_user, login_required, login_user
|
|
from sqlalchemy import extract
|
|
from sqlalchemy.exc import IntegrityError
|
|
|
|
from . import api
|
|
from .common import accessible_vehicles, boolv, fail, payload, response, role_required, station_dict, user_dict, vehicle_dict
|
|
from .. import THEMES
|
|
from ..api_tokens import create_access_token
|
|
from ..extensions import db
|
|
from ..models import AppSetting, CompanySettings, FuelCard, FuelCardPolicy, FuelCardStationRule, FuelEntry, FuelStationCompany, FuelStationPoint, OrlenPrice, User, Vehicle
|
|
from ..services import POLISH_REGIONS, aggregate_ure_companies, calculate_costs, fetch_orlen_price, fetch_orlen_range, fetch_ure_stations, invoice_period
|
|
from ..station_catalog import sync_station_catalog
|
|
|
|
FUEL_TYPES = ("PB95", "PB98", "DIESEL", "LPG")
|
|
|
|
@api.get('/companies')
|
|
@role_required('boss','admin')
|
|
def companies_list():
|
|
return response([{'id':c.id,'name':c.name,'entity_type':c.entity_type,'region':c.region,'active':c.active,'users_count':len(c.users),'cards_count':FuelCard.query.filter_by(company_id=c.id).count()} for c in CompanySettings.query.order_by(CompanySettings.name).all()])
|
|
|
|
@api.post('/companies')
|
|
@role_required('admin')
|
|
def companies_create():
|
|
d=payload()
|
|
try:
|
|
c=CompanySettings(name=(d.get('name') or '').strip(),entity_type=d.get('entity_type','JDG'),vat_rate=Decimal(d.get('vat_rate') or 23),vat_deduction_percent=Decimal(d.get('vat_deduction_percent') or 50),region=(d.get('region') or 'mazowieckie').lower(),invoice_split_day=int(d.get('invoice_split_day') or 15),active=True,station_access_mode='all_prefer_favorites')
|
|
if not c.name: raise ValueError('Nazwa firmy jest wymagana')
|
|
db.session.add(c);db.session.commit();return response({'id':c.id,'redirect':url_for('main.admin_companies',company_id=c.id)},'Dodano firmę',201)
|
|
except Exception as exc:db.session.rollback();return fail(str(exc))
|
|
|
|
@api.delete('/companies/<int:company_id>')
|
|
@role_required('admin')
|
|
def companies_delete(company_id):
|
|
company = CompanySettings.query.get_or_404(company_id)
|
|
blockers = []
|
|
users_count = User.query.filter_by(company_id=company.id).count()
|
|
vehicles_count = Vehicle.query.filter_by(company_id=company.id).count()
|
|
cards_count = FuelCard.query.filter_by(company_id=company.id).count()
|
|
if users_count:
|
|
blockers.append(f'{users_count} użytkowników')
|
|
if vehicles_count:
|
|
blockers.append(f'{vehicles_count} pojazdów')
|
|
if cards_count:
|
|
blockers.append(f'{cards_count} kart paliwowych')
|
|
if blockers:
|
|
return fail(
|
|
'Nie można usunąć firmy, ponieważ ma przypisane: ' + ', '.join(blockers) +
|
|
'. Najpierw przenieś lub usuń te dane albo dezaktywuj firmę.',
|
|
409,
|
|
)
|
|
company.favorite_stations.clear()
|
|
company.allowed_stations.clear()
|
|
db.session.delete(company)
|
|
db.session.commit()
|
|
return response({'redirect':url_for('main.admin_companies')}, 'Usunięto firmę')
|
|
|
|
@api.put('/companies/<int:company_id>')
|
|
@role_required('boss','admin')
|
|
def companies_update(company_id):
|
|
c=CompanySettings.query.get_or_404(company_id);d=payload()
|
|
if current_user.role=='boss' and current_user.company_id!=c.id:return fail('Brak uprawnień',403)
|
|
try:
|
|
c.name=(d.get('name') or c.name).strip();c.entity_type=d.get('entity_type',c.entity_type);c.vat_rate=Decimal(d.get('vat_rate') or c.vat_rate);c.vat_deduction_percent=Decimal(d.get('vat_deduction_percent') or c.vat_deduction_percent);c.region=(d.get('region') or c.region).lower();c.invoice_split_day=int(d.get('invoice_split_day') or c.invoice_split_day);c.active=boolv(d,'active')
|
|
db.session.commit();return response(message='Zapisano firmę')
|
|
except Exception as exc:db.session.rollback();return fail(str(exc))
|
|
|
|
@api.put('/companies/<int:company_id>/favorite-stations')
|
|
@role_required('boss','admin')
|
|
def company_favorites(company_id):
|
|
c=CompanySettings.query.get_or_404(company_id)
|
|
if current_user.role=='boss' and current_user.company_id!=c.id:return fail('Brak uprawnień',403)
|
|
d=payload();ids=request.form.getlist('station_ids') if request.form else d.get('station_ids',[]);ids=[ids] if isinstance(ids,(str,int)) else ids
|
|
try: ids=[int(x) for x in ids]
|
|
except Exception:return fail('Nieprawidłowa lista stacji')
|
|
if len(ids)>25:return fail('Firma może mieć maksymalnie 25 ulubionych stacji')
|
|
c.favorite_stations=FuelStationCompany.query.filter(FuelStationCompany.id.in_(ids),FuelStationCompany.active.is_(True)).all() if ids else []
|
|
db.session.commit();return response(message='Zapisano ulubione stacje firmy')
|
|
|
|
|
|
@api.put('/companies/<int:company_id>/station-access')
|
|
@role_required('boss','admin')
|
|
def company_station_access(company_id):
|
|
company=CompanySettings.query.get_or_404(company_id)
|
|
if current_user.role=='boss' and current_user.company_id!=company.id:return fail('Brak uprawnień',403)
|
|
d=payload();mode=(d.get('station_access_mode') or '').strip()
|
|
modes={'all_prefer_favorites','all','allowed_only','favorites_allowed_only'}
|
|
if mode not in modes:return fail('Nieprawidłowy tryb dostępu do stacji')
|
|
company.station_access_mode=mode
|
|
db.session.commit()
|
|
return response({'station_access_mode':mode},'Zapisano politykę dostępu do stacji')
|
|
|
|
@api.put('/companies/<int:company_id>/allowed-stations')
|
|
@role_required('boss','admin')
|
|
def company_allowed_stations(company_id):
|
|
company=CompanySettings.query.get_or_404(company_id)
|
|
if current_user.role=='boss' and current_user.company_id!=company.id:return fail('Brak uprawnień',403)
|
|
d=payload();ids=request.form.getlist('station_ids') if request.form else d.get('station_ids',[]);ids=[ids] if isinstance(ids,(str,int)) else ids
|
|
try: ids=[int(x) for x in ids]
|
|
except Exception:return fail('Nieprawidłowa lista stacji')
|
|
company.allowed_stations=FuelStationCompany.query.filter(FuelStationCompany.id.in_(ids),FuelStationCompany.active.is_(True)).all() if ids else []
|
|
db.session.commit()
|
|
message='Wszystkie aktywne stacje są dozwolone' if not ids else 'Zapisano zamkniętą listę dozwolonych stacji'
|
|
return response([station_dict(x) for x in company.allowed_stations],message)
|
|
|
|
@api.post('/companies/<int:company_id>/favorite-stations/<int:station_id>/toggle')
|
|
@role_required('boss','admin')
|
|
def company_favorite_toggle(company_id,station_id):
|
|
c=CompanySettings.query.get_or_404(company_id);s=FuelStationCompany.query.get_or_404(station_id)
|
|
if current_user.role=='boss' and current_user.company_id!=c.id:return fail('Brak uprawnień',403)
|
|
if s in c.favorite_stations:c.favorite_stations.remove(s);state=False
|
|
else:
|
|
if len(c.favorite_stations)>=25:return fail('Firma może mieć maksymalnie 25 ulubionych stacji')
|
|
c.favorite_stations.append(s);state=True
|
|
db.session.commit();return response({'favorite':state},'Zmieniono ulubione stacje')
|