@@ -12,6 +12,7 @@ import {
1212 InterestStatement ,
1313 OptionStatement ,
1414 Portfolio ,
15+ SalesTaxes ,
1516 Statement ,
1617 StatementStatus ,
1718 TaxStatement ,
@@ -70,8 +71,10 @@ const transactionStatusFromElement = (element: any): StatementStatus => {
7071 else if ( element . notes == "Ca" )
7172 return StatementStatus . CANCELLED_STATUS ; // Cancelled
7273 else if ( element . openCloseIndicator == "O" ) return StatementStatus . OPEN_STATUS ;
74+ else if ( element . openCloseIndicator == "C;O" ) return StatementStatus . OPEN_STATUS ;
7375 else if ( element . openCloseIndicator == "C" ) return StatementStatus . CLOSE_STATUS ;
7476 else if ( element . assetCategory == "CASH" ) return StatementStatus . UNDEFINED_STATUS ;
77+ else if ( element . openCloseIndicator === undefined ) return StatementStatus . UNDEFINED_STATUS ;
7578 else {
7679 logger . error ( MODULE + ".transactionStatusFromElement" , "unknown status: " , element ) ;
7780 throw Error ( "undefined status" ) ;
@@ -95,7 +98,7 @@ const transactionDescriptionFromElement = (element: any): string => {
9598 let description = "" ;
9699 switch ( transactionStatusFromElement ( element ) ) {
97100 case StatementStatus . ASSIGNED_STATUS :
98- console . log ( MODULE + ".transactionDescriptionFromElement" , element ) ;
101+ // console.log(MODULE + ".transactionDescriptionFromElement", element);
99102 description += "Assigned" ;
100103 break ;
101104 case StatementStatus . EXPIRED_STATUS :
@@ -304,6 +307,7 @@ export class ImporterBot extends ITradingBot {
304307 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
305308 protected async processStockTrade ( element : any ) : Promise < void > {
306309 logger . log ( LogLevel . Trace , MODULE + ".processStockTrade" , element . symbol as string , element ) ;
310+ // if (element.symbol == "SHYL") console.log(element);
307311 return this . findOrCreateContract ( ibContractFromElement ( element ) ) . then ( async ( contract ) =>
308312 Statement . findOrCreate ( {
309313 where : { transactionId : element . transactionID } ,
@@ -814,17 +818,103 @@ export class ImporterBot extends ITradingBot {
814818 } ) ;
815819 }
816820
821+ /*
822+ {
823+ "accountId": "***",
824+ "acctAlias": "",
825+ "model": "",
826+ "currency": "EUR",
827+ "fxRateToBase": "1",
828+ "assetCategory": "",
829+ "subCategory": "",
830+ "symbol": "",
831+ "description": "",
832+ "conid": "",
833+ "securityID": "",
834+ "securityIDType": "",
835+ "cusip": "",
836+ "isin": "",
837+ "figi": "",
838+ "listingExchange": "",
839+ "underlyingConid": "",
840+ "underlyingSymbol": "",
841+ "underlyingSecurityID": "",
842+ "underlyingListingExchange": "",
843+ "issuer": "",
844+ "issuerCountryCode": "",
845+ "multiplier": "",
846+ "strike": "",
847+ "expiry": "",
848+ "putCall": "",
849+ "principalAdjustFactor": "",
850+ "date": "2024-08-02",
851+ "country": "France",
852+ "taxType": "VAT",
853+ "payer": "U7802803",
854+ "taxableDescription": "r******99:COMEX(Globex)(NP,L2)",
855+ "taxableAmount": "-10.16",
856+ "taxRate": "0.2",
857+ "salesTax": "-2.032",
858+ "taxableTransactionID": "2947603793",
859+ "transactionID": "3220505865",
860+ "code": "",
861+ "serialNumber": "",
862+ "deliveryType": "",
863+ "commodityType": "",
864+ "fineness": "",
865+ "weight": ""
866+ }
867+ */
817868 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
818869 protected async processSalesTax ( element : any ) : Promise < void > {
819870 // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
820871 logger . log ( LogLevel . Trace , MODULE + ".processSalesTaxes" , element . symbol , element ) ;
821- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
822- logger . log ( LogLevel . Warning , MODULE + ".processSalesTaxes" , element . symbol , "not implemented" , element ) ;
872+ const taxableTransaction = await Statement . findOne ( {
873+ where : { transactionId : element . taxableTransactionID } ,
874+ } ) ;
875+ if ( taxableTransaction ) {
876+ return Statement . findOrCreate ( {
877+ where : { transactionId : element . transactionID } ,
878+ defaults : {
879+ portfolio_id : this . portfolio . id ,
880+ statementType : StatementTypes . SalesTaxStatement ,
881+ date : taxableTransaction . date ,
882+ currency : element . currency ,
883+ netCash : element . salesTax ,
884+ description : `${ element . country } ${ element . taxType } tax for ${ element . taxableDescription } ` ,
885+ transactionId : element . transactionID ,
886+ fxRateToBase : element . fxRateToBase ,
887+ } ,
888+ } )
889+ . then ( async ( [ statement , _created ] ) => {
890+ return SalesTaxes . findOrCreate ( {
891+ where : { id : statement . id } ,
892+ defaults : {
893+ id : statement . id ,
894+ taxableTransactionID : taxableTransaction . id ,
895+ country : element . country ,
896+ taxType : element . taxType ,
897+ taxableAmount : element . taxableAmount ,
898+ taxRate : element . taxRate ,
899+ salesTax : element . salesTax ,
900+ } ,
901+ } ) ;
902+ } )
903+ . then ( ( [ _taxStatement , _created ] ) : void => undefined ) ;
904+ } else {
905+ logger . log (
906+ LogLevel . Error ,
907+ MODULE + ".processSalesTaxes" ,
908+ element . symbol as string ,
909+ "taxableTransactionID not found" ,
910+ element . taxableTransactionID ,
911+ ) ;
912+ }
913+
823914 return Promise . resolve ( ) ;
824915 }
825916
826917 private async processAllSalesTaxes ( flexReport : FlexStatement ) : Promise < FlexStatement > {
827- console . debug ( "processAllSalesTaxes" , flexReport ) ;
828918 let elements : any [ ] ;
829919 if ( ! flexReport . SalesTaxes || ! flexReport . SalesTaxes . SalesTax ) {
830920 elements = [ ] ;
0 commit comments