bober-bbq-bot/webapp/src/types.ts
byrsapty 699a73c8a0 Add per-100g product pricing and editable order line prices
Some items (grilled shashlik) can't have a flat price since the cooked
weight varies. Product gains pricing_mode ("fixed"/"per_100g") and
reference_weight_g; Product.effective_unit_price computes an estimated
per-unit charge (price-per-100g * reference_weight_g / 100) that every
cart/order call site now reads instead of raw Product.price, so the
customer sees a ready "≈" estimate everywhere (menu, cart, checkout) with
zero changes to the actual cart/checkout math.

Also adds a general per-line price override to the admin order create/edit
forms (unit_price), so staff can correct the charged amount after weighing
an item — for any product, not just weight-priced ones. This incidentally
fixes an existing bug where editing an order for an unrelated reason (e.g.
a phone number) silently re-snapshotted every line item to today's catalog
price instead of preserving what was actually charged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 20:33:04 +03:00

128 lines
2.6 KiB
TypeScript

export interface Category {
id: number;
name: string;
slug: string;
sort_order: number;
}
export interface Allergen {
code: string;
label: string;
emoji: string;
}
export interface Product {
id: number;
category_id: number;
name: string;
description: string;
weight: string;
price: number;
is_estimated_price: boolean;
image_url: string;
allergens: Allergen[];
}
export interface CartLine {
product_id: number;
name: string;
weight: string;
image_url: string;
price: number;
is_estimated_price: boolean;
quantity: number;
line_total: number;
}
export interface Cart {
items: CartLine[];
items_total: number;
count: number;
}
export interface OrderItemDto {
name: string;
quantity: number;
price: number;
}
export interface OrderDto {
id: number;
number: string;
order_type: "delivery" | "pickup" | "dine_in";
status: string;
status_label: string;
payment_method: "cash" | "card" | null;
payment_status: "unpaid" | "paid";
items_total: number;
delivery_fee: number;
discount_amount: number;
promo_code: string | null;
promo_discount_amount: number;
total: number;
created_at: string | null;
pickup_time: string | null;
address_street: string | null;
address_house: string | null;
table_number: string | null;
can_cancel: boolean;
can_pay: boolean;
items: OrderItemDto[];
}
export interface CheckoutPrefill {
has_orders: boolean;
name: string | null;
phone: string | null;
delivery: {
address_city: string | null;
address_street: string | null;
address_house: string | null;
address_apartment: string | null;
} | null;
}
export interface CheckoutResult {
order_id: number;
order_number: string;
total: number;
payment_method: "cash" | "card";
pay_url: string | null;
card_unavailable_message: string | null;
track_url: string | null;
}
export interface PromoValidateResult {
valid: boolean;
message?: string;
code?: string;
discount_percent?: number;
discount_amount?: number;
}
export interface PublicSettings {
cafe_name: string;
logo_url: string;
phone: string;
address: string;
work_hours_from: string;
work_hours_to: string;
is_open: boolean;
instagram_url: string;
maps_url: string;
delivery_fee: number;
free_delivery_threshold: number;
min_delivery_order_amount: number;
pickup_discount_percent: number;
force_closed: boolean;
force_closed_message: string;
announcement_enabled: boolean;
announcement_message: string;
has_active_promos: boolean;
theme: {
accent: string;
accent_2: string;
accent_grad: string;
accent_ink: string;
};
}