use crate::wire::OperationCode;
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize, Serializer};
use super::{EmptyResponse, Operation};
use rust_decimal::serde::float as dec;
use rust_decimal::serde::float_option as dec_opt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum PrintMode {
Simple = 1,
Products = 2,
Prepayment = 3,
}
impl Serialize for PrintMode {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
ser.serialize_u8(*self as u8)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DiscountKind {
Percent,
UnitPriceReduction,
LineTotalReduction,
AdditionalPercent,
AdditionalMonetary,
}
impl DiscountKind {
#[must_use]
pub const fn code(self) -> u32 {
match self {
Self::Percent => 1,
Self::UnitPriceReduction => 2,
Self::LineTotalReduction => 4,
Self::AdditionalPercent => 8,
Self::AdditionalMonetary => 16,
}
}
}
impl Serialize for DiscountKind {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
ser.serialize_u32(self.code())
}
}
impl<'de> Deserialize<'de> for DiscountKind {
fn deserialize<D: serde::Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
let code = u32::deserialize(de)?;
Ok(match code {
1 => Self::Percent,
2 => Self::UnitPriceReduction,
4 => Self::LineTotalReduction,
8 => Self::AdditionalPercent,
16 => Self::AdditionalMonetary,
other => {
return Err(serde::de::Error::custom(format!(
"unknown discount kind code {other} (expected 1, 2, 4, 8, or 16)"
)));
}
})
}
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct PrintReceiptRequest {
#[cfg_attr(feature = "schema", schemars(with = "u8"))]
pub mode: PrintMode,
#[serde(rename = "paidAmount", with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub paid_amount: Decimal,
#[serde(rename = "paidAmountCard", with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub paid_amount_card: Decimal,
#[serde(rename = "partialAmount", with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub partial_amount: Decimal,
#[serde(rename = "prePaymentAmount", with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub pre_payment_amount: Decimal,
#[serde(skip_serializing_if = "Option::is_none")]
pub dep: Option<u32>,
#[serde(rename = "partnerTin")]
pub partner_tin: Option<String>,
#[serde(rename = "useExtPOS")]
pub use_ext_pos: bool,
#[serde(rename = "PaymentSystem", skip_serializing_if = "Option::is_none")]
pub payment_system: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rrn: Option<String>,
#[serde(rename = "terminalId", skip_serializing_if = "Option::is_none")]
pub terminal_id: Option<String>,
#[serde(rename = "eMarks")]
pub e_marks: Vec<String>,
pub items: Vec<ReceiptItem>,
}
impl Operation for PrintReceiptRequest {
const CODE: OperationCode = OperationCode::PrintReceipt;
type Response = ReceiptResponse;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ReceiptItem {
pub dep: u32,
#[serde(with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub qty: Decimal,
#[serde(with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub price: Decimal,
#[serde(rename = "productCode")]
pub product_code: String,
#[serde(rename = "productName")]
pub product_name: String,
#[serde(rename = "adgCode", skip_serializing_if = "Option::is_none")]
pub adg_code: Option<String>,
pub unit: String,
#[serde(with = "dec_opt", skip_serializing_if = "Option::is_none", default)]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub discount: Option<Decimal>,
#[serde(rename = "discountType", skip_serializing_if = "Option::is_none")]
#[cfg_attr(feature = "schema", schemars(with = "Option<u32>"))]
pub discount_kind: Option<DiscountKind>,
#[serde(
rename = "additionalDiscount",
with = "dec_opt",
skip_serializing_if = "Option::is_none",
default
)]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub additional_discount: Option<Decimal>,
#[serde(
rename = "additionalDiscountType",
skip_serializing_if = "Option::is_none"
)]
#[cfg_attr(feature = "schema", schemars(with = "Option<u32>"))]
pub additional_discount_kind: Option<DiscountKind>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub struct ReceiptResponse {
pub rseq: i64,
#[serde(default)]
pub crn: String,
#[serde(default)]
pub sn: String,
#[serde(default)]
pub tin: String,
#[serde(default)]
pub taxpayer: String,
#[serde(default)]
pub address: String,
#[serde(default)]
pub time: i64,
#[serde(default)]
pub fiscal: String,
#[serde(default)]
pub lottery: String,
#[serde(default)]
pub prize: u32,
#[serde(default, with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub total: Decimal,
#[serde(default, with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub change: Decimal,
#[serde(default)]
pub qr: Option<String>,
#[serde(rename = "emarksCount", default)]
pub emarks_count: Option<String>,
#[serde(rename = "verificationNumber", default)]
pub verification_number: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct PrintLastReceiptRequest {}
impl Operation for PrintLastReceiptRequest {
const CODE: OperationCode = OperationCode::PrintLastReceipt;
type Response = EmptyResponse;
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct GetReturnableReceiptRequest {
#[serde(rename = "receiptId")]
pub receipt_id: String,
pub crn: String,
}
impl Operation for GetReturnableReceiptRequest {
const CODE: OperationCode = OperationCode::GetReturnableReceipt;
type Response = ReturnableReceiptResponse;
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub struct ReturnableReceiptResponse {
#[serde(default)]
pub rseq: Option<i64>,
#[serde(default)]
pub cid: Option<i64>,
#[serde(default)]
pub time: Option<i64>,
#[serde(rename = "type", default)]
pub kind: Option<i64>,
#[serde(rename = "saleType", default)]
pub sale_type: Option<i64>,
#[serde(rename = "subType", default)]
pub sub_type: Option<i64>,
#[serde(default)]
pub did: Option<i64>,
#[serde(default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub ta: Option<Decimal>,
#[serde(default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub cash: Option<Decimal>,
#[serde(default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub card: Option<Decimal>,
#[serde(default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub ppa: Option<Decimal>,
#[serde(default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub ppu: Option<Decimal>,
#[serde(rename = "pTin", default)]
pub partner_tin: Option<String>,
#[serde(rename = "ref", default)]
pub returned_receipt: Option<i64>,
#[serde(rename = "refcrn", default)]
pub returned_crn: Option<String>,
#[serde(rename = "eMarks", default)]
pub e_marks: Vec<String>,
#[serde(default)]
pub totals: Vec<ReturnableReceiptItem>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub struct ReturnableReceiptItem {
#[serde(rename = "gc", default)]
pub product_code: Option<String>,
#[serde(rename = "gn", default)]
pub product_name: Option<String>,
#[serde(default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub qty: Option<Decimal>,
#[serde(rename = "p", default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub price: Option<Decimal>,
#[serde(rename = "mu", default)]
pub unit: Option<String>,
#[serde(default)]
pub rpid: Option<i64>,
#[serde(rename = "dsc", default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub discount: Option<Decimal>,
#[serde(rename = "adsc", default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub additional_discount: Option<Decimal>,
#[serde(rename = "dsct", default)]
pub discount_kind: Option<i64>,
#[serde(default)]
pub did: Option<i64>,
#[serde(rename = "dt", default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub vat_amount: Option<Decimal>,
#[serde(rename = "dtm", default)]
pub tax_regime: Option<i64>,
#[serde(rename = "t", default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub total_without_vat: Option<Decimal>,
#[serde(rename = "tt", default, with = "dec_opt")]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub total_with_vat: Option<Decimal>,
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct PrintReturnReceiptRequest {
pub crn: String,
#[serde(rename = "returnTicketId")]
pub return_ticket_id: u64,
#[serde(
rename = "cashAmountForReturn",
with = "dec_opt",
skip_serializing_if = "Option::is_none",
default
)]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub cash_amount_for_return: Option<Decimal>,
#[serde(
rename = "cardAmountForReturn",
with = "dec_opt",
skip_serializing_if = "Option::is_none",
default
)]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub card_amount_for_return: Option<Decimal>,
#[serde(
rename = "prePaymentAmountForReturn",
with = "dec_opt",
skip_serializing_if = "Option::is_none",
default
)]
#[cfg_attr(feature = "schema", schemars(with = "Option<f64>"))]
pub pre_payment_amount_for_return: Option<Decimal>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rrn: Option<String>,
#[serde(rename = "terminalId", skip_serializing_if = "Option::is_none")]
pub terminal_id: Option<String>,
#[serde(rename = "eMarks", skip_serializing_if = "Vec::is_empty")]
pub e_marks: Vec<String>,
#[serde(rename = "returnItemList", skip_serializing_if = "Vec::is_empty")]
pub return_item_list: Vec<ReturnItem>,
}
impl Operation for PrintReturnReceiptRequest {
const CODE: OperationCode = OperationCode::PrintReturnReceipt;
type Response = ReturnReceiptResponse;
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub struct ReturnItem {
pub rpid: i64,
#[serde(with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub quantity: Decimal,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub struct ReturnReceiptResponse {
pub rseq: i64,
#[serde(default)]
pub crn: String,
#[serde(default)]
pub sn: String,
#[serde(default)]
pub tin: String,
#[serde(default)]
pub taxpayer: String,
#[serde(default)]
pub address: String,
#[serde(default)]
pub time: i64,
#[serde(default)]
pub rtime: i64,
#[serde(default)]
pub fiscal: String,
#[serde(default)]
pub lottery: String,
#[serde(default)]
pub prize: u32,
#[serde(default, with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub total: Decimal,
#[serde(default, with = "dec")]
#[cfg_attr(feature = "schema", schemars(with = "f64"))]
pub change: Decimal,
#[serde(rename = "emarksCount", default)]
pub emarks_count: Option<String>,
#[serde(rename = "verificationNumber", default)]
pub verification_number: Option<String>,
}