@@ -96,31 +96,12 @@ def _create_collective_transaction(self, transaction):
9696 amount_str = f"{ amount :.2f} "
9797 split_items_o .append ({"accountId" : cct_account , credit_type : amount_str })
9898
99- payload = dict (
100- dateAdded = self .cct_book_ref .get_date (getattr (transaction , "date" , None )).strftime (
101- "%Y-%m-%d"
102- ),
103- title = getattr (transaction , "description" , "" ),
104- items = json .dumps (split_items_o ),
105- )
106-
107- # Call create endpoint
108- response = self ._construct_request_post ("journal/create.json" , payload = payload )
109- response .raise_for_status ()
110- data = response .json ()
111- self ._raise_for_error (
112- response , f"create collective transaction: len: { len (transaction .splits )} "
99+ payload = self ._get_common_transaction_payload (transaction )
100+ payload ["items" ] = json .dumps (split_items_o )
101+ return self ._create_transaction_api_call (
102+ payload , f"create collective transaction: len: { len (transaction .splits )} "
113103 )
114104
115- txn_id = None
116- if isinstance (data , dict ):
117- if data .get ("success" ):
118- txn_id = data .get ("insertId" )
119- # Record inserted transaction for the current BookTransaction
120- transaction_id = self .cct_book_ref .build_transaction_id (txn_id )
121- self .insert (transaction_id )
122- return transaction_id
123-
124105 def _create_simple_transaction (self , transaction ):
125106 # Expecting two splits: debit and credit
126107 if not getattr (transaction , "splits" , None ) or len (transaction .splits ) != 2 :
@@ -136,29 +117,22 @@ def _create_simple_transaction(self, transaction):
136117 else str (transaction .splits [1 ].amount )
137118 )
138119
139- notes = "Added through API"
140- description = getattr (transaction , "description" , "" )
141- # in case description is longer than 250 chars, truncate and append fully to notes
142- if len (description ) > 250 :
143- notes += "\n " + description
144- description = description [:250 ]
145-
146- date_added = self .cct_book_ref .get_date (getattr (transaction , "date" , None )).strftime (
147- "%Y-%m-%d"
148- )
149- attributes = (
150- f"amount={ amount_str } &creditId={ cct_account_credit } &debitId={ cct_account_debit } "
151- f"&title={ urllib .parse .quote_plus (description )} "
152- f"&dateAdded={ date_added } ¬es={ urllib .parse .quote_plus (notes )} "
120+ payload = self ._get_common_transaction_payload (transaction )
121+ payload ["amount" ] = amount_str
122+ payload ["creditId" ] = cct_account_credit
123+ payload ["debitId" ] = cct_account_debit
124+ return self ._create_transaction_api_call (
125+ payload , f"create:{ cct_account_debit } :{ cct_account_credit } :{ amount_str } "
153126 )
154127
128+ def _create_transaction_api_call (self , payload , request_info ):
155129 # Call create endpoint
156- response = self ._construct_request_post ("journal/create.json?" + attributes , None )
130+ response = self ._construct_request_post ("journal/create.json" , payload = payload )
157131 response .raise_for_status ()
158132 data = response .json ()
159133 self ._raise_for_error (
160134 response ,
161- f"create: { cct_account_debit } : { cct_account_credit } : { amount_str } " ,
135+ request_info ,
162136 )
163137
164138 txn_id = None
@@ -170,6 +144,26 @@ def _create_simple_transaction(self, transaction):
170144 self .insert (transaction_id )
171145 return transaction_id
172146
147+ def _get_common_transaction_payload (self , transaction ):
148+ date_added = self .cct_book_ref .get_date (getattr (transaction , "date" , None )).strftime (
149+ "%Y-%m-%d"
150+ )
151+ description = getattr (transaction , "description" , "" )
152+ # in case description is longer than 250 chars, truncate and append fully to notes
153+ if len (description ) > 250 :
154+ notes = description
155+ description = description [:250 ]
156+ else :
157+ notes = None
158+
159+ payload = dict (
160+ dateAdded = date_added ,
161+ title = description ,
162+ )
163+ if notes :
164+ payload ["notes" ] = notes
165+ return payload
166+
173167 def save (self ):
174168 # inserted transactions can be ignored as they were already saved to CashCtrl via API
175169 self ._inserted_transaction_ids .clear ()
@@ -266,7 +260,13 @@ def _raise_for_error(self, response, request_info=None):
266260 data = response .json ()
267261 if isinstance (data , dict ):
268262 if not data .get ("success" , True ):
269- error_message = data .get ("message" , "Unknown error" )
263+ errors = data .get ("errors" )
264+ if errors :
265+ error_message = "; " .join (
266+ f"{ error .get ('field' )} : { error .get ('message' )} " for error in errors
267+ )
268+ else :
269+ error_message = data .get ("message" ) or "Unknown error"
270270 raise RuntimeError (
271271 f"CashCtrl API error: { error_message } - for request { request_info } "
272272 )
0 commit comments