| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- import json
- import os
- from mcp.server.fastmcp import FastMCP
- _here = os.path.dirname(__file__)
- with open(os.path.join(_here, "config.json")) as f:
- _config = json.load(f)
- SERVICES = _config['services']
- SALES_TAX = _config['global']['taxes']['sales']
- mcp = FastMCP("room-price-calc")
- def _dollar(v: float) -> str:
- return "{:.2f}".format(round(v, 2))
- def _details_fmt(details: dict) -> dict:
- return {k.replace('_', ' ').title(): _dollar(v) for k, v in details.items()}
- def _resolve_service(service: str):
- svc = SERVICES.get(service.lower().strip())
- if svc is None:
- keys = ', '.join(SERVICES.keys())
- raise ValueError(f"Unknown service '{service}'. Valid keys: {keys}")
- return svc
- def _n2l(svc, net, det):
- comm_rate = svc.get('fees', {}).get('commission', 0)
- wrong_rate = svc.get('taxes', {}).get('wrong', SALES_TAX)
- list_ = net / (1 - comm_rate - SALES_TAX + wrong_rate)
- if 'fees' in svc and 'commission' in svc['fees']:
- det['commission'] = list_ * comm_rate
- if 'taxes' in svc and 'wrong' in svc['taxes']:
- det['wrong_tax'] = list_ * wrong_rate
- det['sales_tax'] = list_ * SALES_TAX
- det['wrong_tax_loss'] = det['sales_tax'] - det['wrong_tax']
- return round(list_, 2)
- def _l2n(svc, list_, det):
- net = list_
- if 'fees' in svc and 'commission' in svc['fees']:
- det['commission'] = net * svc['fees']['commission']
- if 'taxes' in svc and 'wrong' in svc['taxes']:
- det['sales_tax'] = net * SALES_TAX
- det['wrong_tax'] = net * svc['taxes']['wrong']
- det['wrong_tax_loss'] = det['sales_tax'] - det['wrong_tax']
- for k in ['commission', 'wrong_tax_loss']:
- if k in det:
- net -= det[k]
- return round(net, 2)
- def _l2r(svc, list_, det):
- retail = list_
- if 'fees' in svc and 'client_fee' in svc['fees']:
- det['client_fee'] = retail * svc['fees']['client_fee']
- retail += det['client_fee']
- if 'taxes' in svc and 'wrong' in svc['taxes']:
- det['wrong_tax'] = retail * svc['taxes']['wrong']
- retail += det['wrong_tax']
- else:
- det['sales_tax'] = retail * SALES_TAX
- retail += det['sales_tax']
- if 'taxes' in svc and 'flat_tax' in svc['taxes']:
- det['service_tax'] = svc['taxes']['flat_tax']
- retail += det['service_tax']
- return round(retail, 2)
- def _r2l(svc, retail, det):
- list_ = retail
- if 'taxes' in svc and 'flat_tax' in svc['taxes']:
- det['service_tax'] = svc['taxes']['flat_tax']
- list_ -= det['service_tax']
- if 'taxes' in svc and 'wrong' in svc['taxes']:
- det['wrong_tax'] = list_ - (list_ / (1 + svc['taxes']['wrong']))
- list_ -= det['wrong_tax']
- else:
- det['sales_tax'] = list_ - (list_ / (1 + SALES_TAX))
- list_ -= det['sales_tax']
- if 'fees' in svc and 'client_fee' in svc['fees']:
- det['client_fee'] = list_ - (list_ / (1 + svc['fees']['client_fee']))
- list_ -= det['client_fee']
- return round(list_, 2)
- def _result(service_key, **amounts) -> dict:
- det = {k: _dollar(v) for k, v in amounts.items() if k != 'details'}
- return {'service': service_key, **det}
- @mcp.tool()
- def list_services() -> list:
- """List all available booking services with their keys and display names."""
- return [{'key': k, 'name': v['name']} for k, v in SERVICES.items()]
- @mcp.tool()
- def net_to_list(service: str, amount: float) -> dict:
- """Convert a net (owner payout) amount to the list (booking) price for a service.
- Args:
- service: Service key (e.g. 'airbnb', 'booking')
- amount: Net amount in dollars
- """
- svc = _resolve_service(service)
- det = {}
- list_ = _n2l(svc, amount, det)
- return {'service': service, 'net': _dollar(amount), 'list': _dollar(list_), 'details': _details_fmt(det)}
- @mcp.tool()
- def list_to_net(service: str, amount: float) -> dict:
- """Convert a list (booking) price to the net (owner payout) amount for a service.
- Args:
- service: Service key (e.g. 'airbnb', 'booking')
- amount: List price in dollars
- """
- svc = _resolve_service(service)
- det = {}
- net = _l2n(svc, amount, det)
- return {'service': service, 'list': _dollar(amount), 'net': _dollar(net), 'details': _details_fmt(det)}
- @mcp.tool()
- def list_to_retail(service: str, amount: float) -> dict:
- """Convert a list (booking) price to the retail (guest-facing) price for a service.
- Args:
- service: Service key (e.g. 'airbnb', 'booking')
- amount: List price in dollars
- """
- svc = _resolve_service(service)
- det = {}
- retail = _l2r(svc, amount, det)
- return {'service': service, 'list': _dollar(amount), 'retail': _dollar(retail), 'details': _details_fmt(det)}
- @mcp.tool()
- def retail_to_list(service: str, amount: float) -> dict:
- """Convert a retail (guest-facing) price to the list (booking) price for a service.
- Args:
- service: Service key (e.g. 'airbnb', 'booking')
- amount: Retail price in dollars
- """
- svc = _resolve_service(service)
- det = {}
- list_ = _r2l(svc, amount, det)
- return {'service': service, 'retail': _dollar(amount), 'list': _dollar(list_), 'details': _details_fmt(det)}
- @mcp.tool()
- def net_to_retail(service: str, amount: float) -> dict:
- """Convert a net (owner payout) amount to the retail (guest-facing) price for a service.
- Args:
- service: Service key (e.g. 'airbnb', 'booking')
- amount: Net amount in dollars
- """
- svc = _resolve_service(service)
- det = {}
- list_ = _n2l(svc, amount, det)
- det2 = {}
- retail = _l2r(svc, list_, det2)
- det.update(det2)
- return {'service': service, 'net': _dollar(amount), 'list': _dollar(list_), 'retail': _dollar(retail), 'details': _details_fmt(det)}
- @mcp.tool()
- def retail_to_net(service: str, amount: float) -> dict:
- """Convert a retail (guest-facing) price to the net (owner payout) amount for a service.
- Args:
- service: Service key (e.g. 'airbnb', 'booking')
- amount: Retail price in dollars
- """
- svc = _resolve_service(service)
- det = {}
- list_ = _r2l(svc, amount, det)
- det2 = {}
- net = _l2n(svc, list_, det2)
- det.update(det2)
- return {'service': service, 'retail': _dollar(amount), 'list': _dollar(list_), 'net': _dollar(net), 'details': _details_fmt(det)}
- if __name__ == "__main__":
- mcp.run()
|