Files
openclaw/skills/paradiz/scripts/sync_prices_to_sqlite.py

142 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
import csv
import hashlib
import shutil
from datetime import datetime
from pathlib import Path
import sqlite3
CSV_PATH = Path('/home/openclaw/.openclaw/workspace/skills/paradiz/references/prices.csv')
DB_PATH = Path('/home/openclaw/.openclaw/workspace/skills/paradiz/data/db/testDB.sqlite')
# Маппинг названий из прайса в фактические категории новой БД
ROOM_DB_MAP = {
'Домик Эконом': 'Домик',
'Стандарт': 'Стандарт',
'Двухкомнатный номер': 'Двухкомнатный Номер',
'Номер с кухней': 'Номер с кухней Стандарт',
'Номер Большой с кухней': 'Номер с кухней №33',
}
def mk_hash(*parts: str) -> str:
return hashlib.md5('|'.join(parts).encode('utf-8')).hexdigest()
def load_csv(path: Path):
with path.open('r', encoding='utf-8-sig', newline='') as f:
return list(csv.DictReader(f))
def date_jd(cur, s: str):
return cur.execute('SELECT julianday(?)', (s,)).fetchone()[0]
def ensure_category(cur, name: str, maxlivers: int):
row = cur.execute('SELECT id FROM hotel_room_categories WHERE name=?', (name,)).fetchone()
if row:
return row[0]
cid = mk_hash('paradiz-cat', name)
now_jd = cur.execute('SELECT julianday("now")').fetchone()[0]
h = mk_hash(cid, name)
cur.execute(
'''INSERT INTO hotel_room_categories
(id,name,ename,color,maxlivers,channelCode,additionalChannelCode,additional,description,status,lastupdate,hash)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)''',
(cid, name, name, 0, maxlivers, '', '', '', 'imported from prices.csv', 0, now_jd, h)
)
return cid
def upsert_cost(cur, category_id: str, room_name: str, guests_num: int, cost: float, dfrom: str, dto: str):
rid = mk_hash('paradiz-cost', room_name, dfrom, dto, str(guests_num))
exists = cur.execute('SELECT 1 FROM hotel_room_categories_cost WHERE id=?', (rid,)).fetchone()
df = date_jd(cur, dfrom)
dt = date_jd(cur, dto)
if exists:
cur.execute('''UPDATE hotel_room_categories_cost
SET category=?, number=?, cost=?, date_from=?, date_to=?, subtype='', days=127
WHERE id=?''',
(category_id, guests_num, cost, df, dt, rid))
else:
cur.execute('''INSERT INTO hotel_room_categories_cost
(id, category, number, cost, date_from, date_to, subtype, days)
VALUES (?,?,?,?,?,?,?,?)''',
(rid, category_id, guests_num, cost, df, dt, '', 127))
def main():
if not CSV_PATH.exists() or not DB_PATH.exists():
raise SystemExit('prices.csv or testDB.sqlite not found')
# backup db
backup_dir = DB_PATH.parent / 'backups'
backup_dir.mkdir(parents=True, exist_ok=True)
stamp = datetime.now().strftime('%Y%m%d-%H%M%S')
backup_path = backup_dir / f'testDB-{stamp}.sqlite'
shutil.copy2(DB_PATH, backup_path)
rows = load_csv(CSV_PATH)
# extra-person price by period
extra_by_period = {}
for r in rows:
if (r.get('room') or '').strip().lower() == 'доп. человек':
extra_by_period[(r['date_from'], r['date_to'])] = float(r['price_per_night'])
conn = sqlite3.connect(str(DB_PATH))
cur = conn.cursor()
room_max = {
'Домик Эконом': 4,
'Стандарт': 4,
'Двухкомнатный номер': 6,
'Номер с кухней': 4,
'Номер Большой с кухней': 6,
}
synced = 0
used_categories = set()
for r in rows:
room = (r.get('room') or '').strip()
if not room or room == 'Доп. человек':
continue
dfrom = r['date_from']
dto = r['date_to']
gmin = int(r['guests_min'])
gmax = int(r['guests_max'])
base = float(r['price_per_night'])
extra = float(extra_by_period.get((dfrom, dto), 800.0))
base_included = 4 if room in ('Двухкомнатный номер', 'Номер Большой с кухней') else 2
maxl = room_max.get(room, gmax)
db_room = ROOM_DB_MAP.get(room, room)
cat_id = ensure_category(cur, db_room, maxl)
used_categories.add(db_room)
# очищаем старые/дублирующиеся тарифы в том же диапазоне дат и вместимости
df = date_jd(cur, dfrom)
dt = date_jd(cur, dto)
cur.execute('''DELETE FROM hotel_room_categories_cost
WHERE category=? AND date_from=? AND date_to=? AND number BETWEEN ? AND ?''',
(cat_id, df, dt, gmin, gmax))
for n in range(gmin, gmax + 1):
extra_guests = max(0, n - base_included)
cost = base + extra_guests * extra
upsert_cost(cur, cat_id, db_room, n, cost, dfrom, dto)
synced += 1
conn.commit()
conn.close()
print(f'backup: {backup_path}')
print(f'synced cost rows: {synced}')
print('mapped categories:', ', '.join(sorted(used_categories)))
if __name__ == '__main__':
main()