allnet: save billing traces

This commit is contained in:
2025-04-17 20:11:33 -04:00
parent ada9377c06
commit ce475e801b
5 changed files with 280 additions and 38 deletions

View File

@ -6,7 +6,7 @@ from sqlalchemy.dialects.mysql import insert
from sqlalchemy.engine import Row
from sqlalchemy.sql import func, select
from sqlalchemy.sql.schema import ForeignKey, PrimaryKeyConstraint
from sqlalchemy.types import JSON, Boolean, Integer, String
from sqlalchemy.types import JSON, Boolean, Integer, String, BIGINT, INTEGER, CHAR, FLOAT
from core.data.schema.base import BaseData, metadata
@ -67,6 +67,56 @@ arcade_owner: Table = Table(
mysql_charset="utf8mb4",
)
billing_charge: Table = Table(
"machine_billing_charge",
metadata,
Column("id", BIGINT, primary_key=True, nullable=False),
Column(
"machine",
Integer,
ForeignKey("machine.id", ondelete="cascade", onupdate="cascade"),
nullable=False,
),
Column("game_id", CHAR(5), nullable=False),
Column("game_ver", FLOAT, nullable=False),
Column("play_count", INTEGER, nullable=False),
Column("play_limit", INTEGER, nullable=False),
Column("product_code", INTEGER, nullable=False),
Column("product_count", INTEGER, nullable=False),
Column("func_type", INTEGER, nullable=False),
Column("player_number", INTEGER, nullable=False),
mysql_charset="utf8mb4",
)
# These settings are only really of interest
# for real cabinets operating as pay-to-play
billing_credit: Table = Table(
"machine_billing_credit",
metadata,
Column("id", BIGINT, primary_key=True, nullable=False),
Column(
"machine",
Integer,
ForeignKey("machine.id", ondelete="cascade", onupdate="cascade"),
nullable=False, unique=True
),
Column("chute_type", INTEGER, nullable=False),
Column("service_type", INTEGER, nullable=False),
Column("operation_type", INTEGER, nullable=False),
Column("coin_rate0", INTEGER, nullable=False),
Column("coin_rate1", INTEGER, nullable=False),
Column("coin_bonus", INTEGER, nullable=False),
Column("credit_rate", INTEGER, nullable=False),
Column("coin_count_slot0", INTEGER, nullable=False),
Column("coin_count_slot1", INTEGER, nullable=False),
Column("coin_count_slot2", INTEGER, nullable=False),
Column("coin_count_slot3", INTEGER, nullable=False),
Column("coin_count_slot4", INTEGER, nullable=False),
Column("coin_count_slot5", INTEGER, nullable=False),
Column("coin_count_slot6", INTEGER, nullable=False),
Column("coin_count_slot7", INTEGER, nullable=False),
mysql_charset="utf8mb4",
)
class ArcadeData(BaseData):
async def get_machine(self, serial: Optional[str] = None, id: Optional[int] = None) -> Optional[Row]:
@ -345,6 +395,71 @@ class ArcadeData(BaseData):
return result.fetchone()['count_1']
self.logger.error("Failed to count machine serials that start with A69A!")
async def billing_add_charge(self, machine_id: int, game_id: str, game_ver: float, playcount: int, playlimit, product_code: int, product_count: int, func_type: int, player_num: int) -> Optional[int]:
result = await self.execute(billing_charge.insert().values(
machine=machine_id,
game_id=game_id,
game_ver=game_ver,
play_count=playcount,
play_limit=playlimit,
product_code=product_code,
product_count=product_count,
func_type=func_type,
player_num=player_num
))
if result is None:
self.logger.error(f"Failed to add billing charge for machine {machine_id}!")
return None
return result.lastrowid
async def billing_set_credit(self, machine_id: int, chute_type: int, service_type: int, op_mode: int, coin_rate0: int, coin_rate1: int,
bonus_adder: int, coin_to_credit_rate: int, coin_count_slot0: int, coin_count_slot1: int, coin_count_slot2: int, coin_count_slot3: int,
coin_count_slot4: int, coin_count_slot5: int, coin_count_slot6: int, coin_count_slot7: int) -> Optional[int]:
sql = insert(billing_credit).values(
machine=machine_id,
chute_type=chute_type,
service_type=service_type,
operation_type=op_mode,
coin_rate0=coin_rate0,
coin_rate1=coin_rate1,
coin_bonus=bonus_adder,
credit_rate=coin_to_credit_rate,
coin_count_slot0=coin_count_slot0,
coin_count_slot1=coin_count_slot1,
coin_count_slot2=coin_count_slot2,
coin_count_slot3=coin_count_slot3,
coin_count_slot4=coin_count_slot4,
coin_count_slot5=coin_count_slot5,
coin_count_slot6=coin_count_slot6,
coin_count_slot7=coin_count_slot7,
)
conflict = sql.on_duplicate_key_update(
chute_type=chute_type,
service_type=service_type,
operation_type=op_mode,
coin_rate0=coin_rate0,
coin_rate1=coin_rate1,
coin_bonus=bonus_adder,
credit_rate=coin_to_credit_rate,
coin_count_slot0=coin_count_slot0,
coin_count_slot1=coin_count_slot1,
coin_count_slot2=coin_count_slot2,
coin_count_slot3=coin_count_slot3,
coin_count_slot4=coin_count_slot4,
coin_count_slot5=coin_count_slot5,
coin_count_slot6=coin_count_slot6,
coin_count_slot7=coin_count_slot7,
)
result = await self.execute(conflict)
if result is None:
self.logger.error(f"Failed to set billing credit settings for machine {machine_id}!")
return None
return result.lastrowid
def format_serial(
self, platform_code: str, platform_rev: int, serial_letter: str, serial_num: int, append: int, dash: bool = False
) -> str:
@ -371,7 +486,6 @@ class ArcadeData(BaseData):
month = ((month - 1) + 9) % 12 # Offset so April=0
return f"{year:02}{month // 6:01}{month % 6 + 1:01}"
def parse_keychip_suffix(self, suffix: str) -> tuple[int, int]:
year = int(suffix[0:2])
half = int(suffix[2])