95 lines
3.1 KiB
Dart
95 lines
3.1 KiB
Dart
/// 価格設定のヘルパー関数群
|
|
///
|
|
/// 店員の感覚に寄り添った価格処理を提供します:
|
|
/// - スマート丸め処理 (キリの良い価格に自動調整)
|
|
/// - サイズ別価格の自動計算
|
|
/// - 価格表示フォーマット (カンマ区切り、円表記)
|
|
class PricingHelper {
|
|
/// サイズ別の価格比率
|
|
///
|
|
/// 店員が感覚的に使っている「一合を基準にした比率」
|
|
static const sizeRatios = {
|
|
'45ml': 0.40, // 一合の約1/4
|
|
'90ml': 0.65, // 一合の半分弱
|
|
'180ml': 1.0, // 基準 (一合)
|
|
};
|
|
|
|
/// スマート丸め処理
|
|
///
|
|
/// 店員が手作業でやる「端数を切る」処理を自動化。
|
|
/// 価格帯に応じて、キリの良い単位に丸めます:
|
|
/// - 500円未満: 50円単位 (例: 720円 → 700円)
|
|
/// - 500円以上: 100円単位 (例: 1,170円 → 1,200円)
|
|
///
|
|
/// [rawPrice] 計算された生の価格
|
|
/// 戻り値: 丸められた価格
|
|
static int smartRound(double rawPrice) {
|
|
if (rawPrice <= 0) return 0;
|
|
|
|
if (rawPrice < 500) {
|
|
// 500円未満 → 50円単位
|
|
return ((rawPrice / 50).round() * 50).toInt();
|
|
} else {
|
|
// 500円以上 → 100円単位
|
|
return ((rawPrice / 100).round() * 100).toInt();
|
|
}
|
|
}
|
|
|
|
/// サイズ別価格の計算
|
|
///
|
|
/// 一合価格を基準に、各サイズの価格を自動計算します。
|
|
///
|
|
/// [basePrice] 一合 (180ml) の価格
|
|
/// [size] サイズ (45ml, 90ml, 180ml)
|
|
/// 戻り値: 計算・丸め処理された価格
|
|
static int calculateSizePrice(int basePrice, String size) {
|
|
final ratio = sizeRatios[size] ?? 1.0;
|
|
final rawPrice = basePrice * ratio;
|
|
return smartRound(rawPrice);
|
|
}
|
|
|
|
/// 価格フォーマット (カンマ区切り)
|
|
///
|
|
/// 内部データ (int) を表示用文字列に変換します:
|
|
/// - 3桁ごとにカンマを挿入
|
|
/// - 「円」は付けない (表示側で追加)
|
|
///
|
|
/// [price] 価格 (int)
|
|
/// 戻り値: カンマ区切りの文字列 (例: "1,800")
|
|
static String formatPrice(int price) {
|
|
if (price <= 0) return '0';
|
|
return price.toString().replaceAllMapped(
|
|
RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'),
|
|
(Match m) => '${m[1]},',
|
|
);
|
|
}
|
|
|
|
/// 価格パース (カンマ除去)
|
|
///
|
|
/// ユーザー入力 (カンマ付き文字列) を int に変換します。
|
|
///
|
|
/// [priceString] 価格文字列 (例: "1,800" or "1800")
|
|
/// 戻り値: パースされた価格 (失敗時は null)
|
|
static int? parsePrice(String priceString) {
|
|
final cleaned = priceString.replaceAll(',', '').trim();
|
|
return int.tryParse(cleaned);
|
|
}
|
|
|
|
/// サイズ表示名
|
|
///
|
|
/// 内部ID (45ml) を表示用の名称に変換します。
|
|
///
|
|
/// [size] サイズID
|
|
/// 戻り値: 表示名 (例: "45ml")
|
|
static String getSizeDisplayName(String size) {
|
|
// 現状はそのまま返すが、将来的に「グラス (45ml)」などに拡張可能
|
|
return size;
|
|
}
|
|
|
|
/// 利用可能なサイズ一覧
|
|
///
|
|
/// MVPで提供するサイズの一覧。
|
|
/// デモでは3種類に絞る。
|
|
static List<String> get availableSizes => ['45ml', '90ml', '180ml'];
|
|
}
|