Transaction* GncPreTrans::create_trans (QofBook* book, gnc_commodity* currency) { if (created) return nullptr; /* Gently refuse to create the transaction if the basics are not set correctly * This should have been tested before calling this function though! */ auto check = verify_essentials(); if (!check.empty()) { PWARN ("Refusing to create transaction because essentials not set properly: %s", check.c_str()); return nullptr; } auto trans = xaccMallocTransaction (book); xaccTransBeginEdit (trans); xaccTransSetCurrency (trans, m_commodity ? *m_commodity : currency); xaccTransSetDatePostedSecsNormalized (trans, static_cast<time64>(GncDateTime(*m_date, DayPart::neutral))); if (m_num) xaccTransSetNum (trans, m_num->c_str()); if (m_desc) xaccTransSetDescription (trans, m_desc->c_str()); if (m_notes) xaccTransSetNotes (trans, m_notes->c_str()); created = true; return trans; }
/** Adds a split to a transaction. * @param trans The transaction to add a split to * @param account The split's account * @param amount The split's amount * @param rec_state The split's reconcile status * @param rec_date The split's reconcile date * @param price The split's conversion rate from account commodity to transaction commodity */ static void trans_add_split (Transaction* trans, Account* account, GncNumeric amount, const boost::optional<std::string>& action, const boost::optional<std::string>& memo, const boost::optional<char>& rec_state, const boost::optional<GncDate>& rec_date, const boost::optional<GncNumeric> price) { QofBook* book = xaccTransGetBook (trans); auto split = xaccMallocSplit (book); xaccSplitSetAccount (split, account); xaccSplitSetParent (split, trans); xaccSplitSetAmount (split, static_cast<gnc_numeric>(amount)); auto trans_curr = xaccTransGetCurrency(trans); auto acct_comm = xaccAccountGetCommodity(account); GncNumeric value; if (gnc_commodity_equiv(trans_curr, acct_comm)) value = amount; else if (price) value = amount * *price; else { auto time = xaccTransRetDatePosted (trans); /* Import data didn't specify price, let's lookup the nearest in time */ auto nprice = gnc_pricedb_lookup_nearest_in_time64(gnc_pricedb_get_db(book), acct_comm, trans_curr, time); if (nprice) { /* Found a usable price. Let's check if the conversion direction is right */ GncNumeric rate; if (gnc_commodity_equiv(gnc_price_get_currency(nprice), trans_curr)) rate = gnc_price_get_value(nprice); else rate = static_cast<GncNumeric>(gnc_price_get_value(nprice)).inv(); value = amount * rate; } else { PWARN("No price found, using a price of 1."); value = amount; } } xaccSplitSetValue (split, static_cast<gnc_numeric>(value)); if (memo) xaccSplitSetMemo (split, memo->c_str()); /* Note, this function assumes the num/action switch is done at a higher level * if needed by the book option */ if (action) xaccSplitSetAction (split, action->c_str()); if (rec_state && *rec_state != 'n') xaccSplitSetReconcile (split, *rec_state); if (rec_state && *rec_state == YREC && rec_date) xaccSplitSetDateReconciledSecs (split, static_cast<time64>(GncDateTime(*rec_date, DayPart::neutral))); }
struct tm* gnc_localtime_r (const time64 *secs, struct tm* time) { try { *time = static_cast<struct tm>(GncDateTime(*secs)); return time; } catch(std::invalid_argument) { return NULL; } }
time64 gnc_timegm (struct tm* time) { try { normalize_struct_tm(time); return static_cast<time64>(GncDateTime(*time)); } catch(std::invalid_argument) { return 0; } }
static Timespec gnc_dmy2timespec_internal (int day, int month, int year, DayPart day_part) { try { auto date = GncDate(year, month, day); return { static_cast<time64>(GncDateTime (date, day_part)), 0 }; } catch(const std::logic_error& err) { PWARN("Date computation error from Y-M-D %d-%d-%d: %s", year, month, day, err.what()); return {INT64_MAX, 0}; } catch(const std::runtime_error& err) { PWARN("Date computation error from Y-M-D %d-%d-%d: %s", year, month, day, err.what()); return {INT64_MAX, 0}; } }