use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SaleLine {
pub item_id: Uuid,
pub revenue_account_id: Uuid,
pub quantity: Decimal,
pub unit_price: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SaleInvoiceRequest {
pub customer_id: Uuid,
pub currency: String,
pub source_pos_id: Uuid,
pub receivable_account_id: Uuid,
pub posting_date: chrono::NaiveDate,
pub lines: Vec<SaleLine>,
pub tax_total: Decimal,
pub tax_account_id: Option<Uuid>,
pub tax_rate: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct InvoiceAck {
pub invoice_id: Uuid,
pub journal_id: Uuid,
pub grand_total: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SettlementRequest {
pub customer_id: Uuid,
pub currency: String,
pub invoice_ref: Uuid,
pub bank_account_id: Uuid,
pub party_account_id: Uuid,
pub posting_date: chrono::NaiveDate,
pub amount: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct SettlementAck {
pub payment_id: Uuid,
pub journal_id: Uuid,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PosRejected {
pub code: String,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CreditLine {
pub item_id: Uuid,
pub quantity: Decimal,
pub unit_price: Decimal,
pub revenue_account_id: Uuid,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PartialCredit {
pub lines: Vec<CreditLine>,
pub amount: Option<Decimal>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CreditNoteRequest {
pub invoice_ref: Uuid,
#[serde(default)]
pub partial: Option<PartialCredit>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct RefundRequest {
pub invoice_ref: Uuid,
pub payment_id: Uuid,
pub amount: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ReversalAck {
pub journal_id: Uuid,
}
#[async_trait::async_trait]
pub trait BillingPort: Send + Sync {
async fn raise_and_post(&self, req: &SaleInvoiceRequest) -> Result<InvoiceAck, PosRejected>;
async fn credit_note(&self, req: &CreditNoteRequest) -> Result<ReversalAck, PosRejected>;
}
#[async_trait::async_trait]
pub trait PaymentPort: Send + Sync {
async fn settle(&self, req: &SettlementRequest) -> Result<SettlementAck, PosRejected>;
async fn refund(&self, req: &RefundRequest) -> Result<ReversalAck, PosRejected>;
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct StockIssueLine {
pub item_id: Uuid,
pub quantity: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct StockIssueRequest {
pub company_id: Uuid,
pub branch_id: Option<Uuid>,
pub customer_id: Uuid,
pub source_pos_id: Uuid,
pub warehouse_id: Uuid,
pub cogs_account_id: Uuid,
pub inventory_account_id: Uuid,
pub posting_date: chrono::NaiveDate,
pub lines: Vec<StockIssueLine>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct StockIssueAck {
pub delivery_note_id: Uuid,
pub journal_id: Option<Uuid>,
}
#[async_trait::async_trait]
pub trait InventoryPort: Send + Sync {
async fn issue(&self, req: &StockIssueRequest) -> Result<StockIssueAck, PosRejected>;
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PosTaxLineIn {
pub line_ref: Uuid,
pub template_id: Uuid,
pub net_amount: Decimal,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum PosTaxDocumentType {
Invoice,
Refund,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PosTaxComputeRequest {
pub document_type: PosTaxDocumentType,
pub on_date: chrono::NaiveDate,
pub lines: Vec<PosTaxLineIn>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PosTaxComponent {
pub line_ref: Uuid,
pub template_id: Uuid,
pub account_id: Option<Uuid>,
pub real_account_id: Option<Uuid>,
pub rate: Decimal,
pub tax_amount: Decimal,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct PosTaxComputeResult {
pub net_amounts: Vec<(Uuid, Decimal)>,
pub components: Vec<PosTaxComponent>,
pub excluded_total: Decimal,
pub tax_total: Decimal,
pub included_total: Decimal,
}
#[async_trait::async_trait]
pub trait PosTaxComputePort: Send + Sync {
async fn compute_document(&self, req: &PosTaxComputeRequest) -> Result<PosTaxComputeResult, PosRejected>;
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum CashVarianceDirection {
Over,
Short,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CashVarianceRequest {
pub company_id: Uuid,
pub opening_entry_id: Uuid,
pub closing_entry_id: Uuid,
pub posting_date: chrono::NaiveDate,
pub currency: String,
pub cash_account_id: Uuid,
pub difference_account_id: Uuid,
pub amount: Decimal,
pub direction: CashVarianceDirection,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CashVarianceAck {
pub journal_id: Uuid,
}
#[async_trait::async_trait]
pub trait PosCashVariancePort: Send + Sync {
async fn book_cash_variance(&self, req: &CashVarianceRequest) -> Result<CashVarianceAck, PosRejected>;
}