This commit is contained in:
xds
2026-03-22 14:26:45 +03:00
parent 33694d68db
commit 466a27907a
28 changed files with 1334 additions and 71 deletions

View File

@@ -17,18 +17,23 @@ def verify_password(plain: str, hashed: str) -> bool:
return bcrypt.checkpw(plain.encode(), hashed.encode())
def create_access_token(user_id: int, email: str) -> str:
def create_access_token(user_id: int, email: str, token_type: str = "admin") -> str:
expire = datetime.now(timezone.utc) + timedelta(hours=settings.JWT_EXPIRE_HOURS)
payload = {
"sub": str(user_id),
"email": email,
"type": token_type,
"exp": expire,
}
token = jwt.encode(payload, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM)
logger.info("Created JWT for user_id=%d, email=%s, expires=%s", user_id, email, expire)
logger.info("Created JWT (%s) for id=%d, email=%s, expires=%s", token_type, user_id, email, expire)
return token
def create_client_token(client_id: int, email: str) -> str:
return create_access_token(client_id, email, token_type="client")
def decode_access_token(token: str) -> dict | None:
try:
payload = jwt.decode(token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM])

View File

@@ -15,6 +15,8 @@ POST_PROCESSING_COSTS = {
"acetone_smoothing": 400.0,
}
MULTICOLOR_SURCHARGE_PERCENT = 30 # наценка за многоцветную печать
QUANTITY_DISCOUNTS = [
(1, 0),
(2, 5),
@@ -71,14 +73,15 @@ def calculate_price(
layer_height_mm: float = 0.2,
quantity: int = 1,
post_processing: list[str] | None = None,
multicolor: bool = False,
) -> PriceResult:
post_processing = post_processing or []
logger.info("=== Price calculation start ===")
logger.info("Input: volume=%.2f cm3, density=%.2f g/cm3, price_per_gram=%.1f RUB",
file_info.volume_cm3, density_g_cm3, price_per_gram)
logger.info("Params: infill=%d%%, layer=%.2fmm, qty=%d, post_processing=%s",
infill_percent, layer_height_mm, quantity, post_processing)
logger.info("Params: infill=%d%%, layer=%.2fmm, qty=%d, multicolor=%s, post_processing=%s",
infill_percent, layer_height_mm, quantity, multicolor, post_processing)
effective_volume = file_info.volume_cm3 * (infill_percent / 100.0) * 0.7 + file_info.volume_cm3 * 0.3
logger.debug("Effective volume: %.2f cm3 (infill-scaled: %.2f + walls: %.2f)",
@@ -103,9 +106,15 @@ def calculate_price(
logger.debug("Total post-processing cost: %.2f RUB", pp_cost)
subtotal = round(material_cost + time_cost + pp_cost, 2)
logger.debug("Subtotal (1 pc): %.2f RUB = material(%.2f) + time(%.2f) + pp(%.2f)",
logger.debug("Subtotal before multicolor (1 pc): %.2f RUB = material(%.2f) + time(%.2f) + pp(%.2f)",
subtotal, material_cost, time_cost, pp_cost)
if multicolor:
multicolor_surcharge = round(subtotal * MULTICOLOR_SURCHARGE_PERCENT / 100.0, 2)
subtotal = round(subtotal + multicolor_surcharge, 2)
logger.debug("Multicolor surcharge: +%.2f RUB (%d%%), new subtotal: %.2f",
multicolor_surcharge, MULTICOLOR_SURCHARGE_PERCENT, subtotal)
discount_pct = get_quantity_discount(quantity)
total = round(subtotal * quantity * (1 - discount_pct / 100.0), 2)
logger.info("Total: %.2f RUB (qty=%d, discount=%d%%, subtotal_per_unit=%.2f)",