package pdf import ( "cf-capital/module_server/handlers/aes" "encoding/base64" "fmt" "github.com/johnfercher/maroto/pkg/color" "github.com/johnfercher/maroto/pkg/consts" "github.com/johnfercher/maroto/pkg/pdf" "github.com/johnfercher/maroto/pkg/props" "io/ioutil" "log" "math" "os" "strings" "time" ) type Statement struct { AccountId int64 StatementDate string StatementPeriod statementPeriod InvestorDetails investorDetails InterestSummary interestSummary Account account Transaction []Transaction } type Transaction struct { TxnId int64 Date string TransactionType string TransactionAmount float64 TransactionAmountDebit float64 ClosingPrincipalAsOnDate float64 CurrentValueAsOnDate float64 } type account struct { AccountSummaryAsOfDate string AccountSummary []AccountSummary } type AccountSummary struct { Scheme string SchemeName string Payout string TenureType string HoldingPeriod string NetInvestment float64 NetCurrentValue float64 InterestAccrued float64 InterestRedeemed float64 CurrentReturn float64 } type investorDetails struct { Name string Address string Phone string Email string Bank bank } type bank struct { Name string AccountNumber string IFSCCode string ModeOfPayout string ModeOfHolding string PAN string FinancialAdvisor string } type interestSummary struct { InterestEarnedAsOfDate string InterestEarnedAsOfAmount float64 } type statementPeriod struct { From string To string } func ToPDF(investorName string) (string, error) { m := pdf.NewMaroto(consts.Portrait, consts.A4) m.SetPageMargins(20, 10, 20) dt := getDate() datetime := dt.Format("2006-01-02 15:04:05") m.Row(10, func() { m.Col(12, func() { m.Text("Declaration By The Investor,", props.Text{ Top: 3, Style: consts.Bold, Align: consts.Center, // Color: getDarkPurpleColor(), }) }) }) m.Row(10, func() { m.Col(12, func() { m.Text(" I, " + investorName + ", after registering with an internet based platform on www.lendbox.in (\"The Website\") to find suitable borrower(s), do hereby declare that:") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("1. That I have read all the material, terms and conditions available at the website of M/s. Transactree Technologies Private Limited (\"The Company\"), owners and operators of the Website (www.lendbox.in);") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("2. That I have unconditionally agreed to abide by the terms and conditions, Privacy Policy and other binding material contained on the Website of the Company;") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("3. That the information and financial details furnished by me on the Website of the Company are true and correct;") }) }) m.Row(25, func() { m.Col(12, func() { m.Text("4. That I have on my own wisdom and judgment agreed to lend through the Company and the Company has had no role to play in making me extend any amount as loan to borrower(s) that have or may register on the Website, as I recognise that M/s. Transactree Technologies Private Limited is only a market platform for persons interested in available and granting of loans, to meet independently. The Company does not intervene or in any way get engaged in any loan transaction and I fully recognise that I have to deal directly with the borrower(s) of such transaction;") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("5. That I have not taken any action from the information available on the Website that has influenced my decision for the loan transaction(s) which I would enter into and I understand that in the event of any dispute with the borrower(s) of such loans, the dispute resolution shall be directly between the borrower(s) and me. The Company or any representative of the Company shall not be impleaded in any manner in a dispute with the borrower(s) as they are not privy to such loan transaction(s);") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("6. That my registration on the Website for the loan transaction(s) or otherwise, does not make in any manner the Company a party or privy to the loan transaction(s) whether entered into or to be entered into by me. The Company or any of the representatives of M/s. Transactree Technologies Private Limited shall not be held responsible for either repayment of the loan(s) extended by me, or loss of money, failure to recover the money, or breach of any confidential information;") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("7. That I have undertaken at my own judgment and information assessment to register on the Website and offer the loan(s) and M/s. Transactree Technologies Private Limited shall not responsible for any inaccuracy or any material accessed by me on The Website;") }) }) m.Row(25, func() { m.Col(12, func() { m.Text("8. That I have a bank account with Investor Bank Name and I shall disburse the loan(s) from this bank account or such other account as may be designated by me and informed in writing to the Company. I undertake that I have not borrowed money from any third party, banks or financial institutions to disburse the loan(s). That the Company has taken an authorisation from the borrower(s) for the NACH mandate and will assist in ensuring that the EMI reach my designated bank account from the designated bank account of the borrower(s) as per the NACH mandate.") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("9. That I fully understand that I can seek such information and material directly from borrower(s) as needed by me as I can research, verify and arrive at a judgment myself. The Company does not need to perform any such or other obligation for me. In the event of loss or damage to the Company due to any action or inaction related to this loan transaction(s), I shall keep the Company harmless and indemnified against such losses;") }) }) m.Row(25, func() { m.Col(12, func() { m.Text("10. That I am authorizing the Company on my behalf to retain, the cheques that have been or may be provided as collateral by the borrower(s) and the said cheques shall be presented to me, in my capacity as the Lender in the event the borrower(s) is unable to meet its obligations of repayment of the loan amount(s) as per the repayment schedule agreed between me and such borrower(s) under the loan agreement(s) to be utilized as collateral. I am aware that the Company has no responsibility whatsoever in recovery of the loan(s) extended or to be extended by me to the borrower(s).") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("11. That the Company may send reminders to the borrower(s) via sms/emails/calls of the monthly due date of each instalment due from the borrower(s) to ensure that the borrower(s) have sufficient funds in their bank accounts to be debited.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("12. That the Company may send reminders to the borrower(s) through emails/SMS/calls in the event of a delay for the first 90 days of the delay in paying the loan(s) as per the repayment schedule agreed between the borrower(s) and me.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("13. That the Company may send a legal notice to the defaulting borrower(s) after a delay of 90 days by the borrower(s) in repayment of the loan(s) as per the repayment schedule agreed between the borrower(s) and me, and simultaneously hand over the cheques provided as collateral to me.") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("14. That the Company may after delay of 120 days in repayment of the loan amount(s) as per the repayment schedule agreed between the borrower(s) and me inform the recovery agency as designated by me and the borrower(s) to start collection procedures. The charges for the recovery agency would be incurred by myself and will be based on the loan amount recovered from the borrower(s).") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("15. I confirm that I do not have over ₹ 50,00,000 invested or lent and outstanding across all P2P Lending platforms at the time of sign up and will not exceed the said limit on Lendbox as well. I will inform the Lendbox team in case the said limit is exceeded.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("16. I confirm that I have not invested or lent over ₹ 50,000 to a single borrower across all P2P Lending platforms of sign up and will not exceed the said limit on Lendbox as well. I will inform the Lendbox team in case the said limit is exceeded.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("17. That I have given this declaration upon fully reading and understanding material, terms and conditions available at the website of M/s Transactree Technologies Private Limited and at my own volition.") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("Signed at " + datetime + " By " + investorName) }) }) filename := "agreement_" + time.Now().String() + ".pdf" err := m.OutputFileAndClose(filename) if err != nil { fmt.Println("ould not save PDF:", err) os.Exit(1) } fmt.Println("PDF saved successfully") //Read to base64 bytes, err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err) } //var base64Encoding string //base64Encoding = "data:application/pdf;base64," + toBase64(bytes) // Print the full base64 representation of the image return toBase64(bytes), nil /*err := m.OutputFileAndClose("pdfs/agreement_" + time.Now().String() + ".pdf") if err != nil { fmt.Println("ould not save PDF:", err) os.Exit(1) } fmt.Println("PDF saved successfully") return*/ } func buildHeadingIFA(m pdf.Maroto) { m.RegisterHeader(func() { m.Row(30, func() { //log.Print("file1") mydir, err := os.Getwd() if err != nil { fmt.Println(err) } m.Col(3, func() { err := m.FileImage(mydir+"/assets/CFC_logo.png", props.Rect{ Center: true, Percent: 0, }) if err != nil { fmt.Println("Image file was not loaded - ", err) } }) }) }) } func buildFeeStructure(m pdf.Maroto) { m.Row(10, func() { m.Col(12, func() { m.Text("SCHEDULE ‘A’", props.Text{ Top: 3, Style: consts.Bold, Align: consts.Center, // Color: getDarkPurpleColor(), }) }) }) m.Row(10, func() { m.Col(12, func() { m.Text("*FEE STRUCTURE", props.Text{ Top: 3, Style: consts.Bold, Align: consts.Center, // Color: getDarkPurpleColor(), }) }) }) m.Row(10, func() { m.Col(12, func() { m.Text("Fees will be calculated as per the total AUM of the referred investments.", props.Text{ Top: 3, Size: 8, }) }) }) m.SetBackgroundColor(color.NewWhite()) tableHeadings := []string{"Criteria", "**Fees in percentage"} contents := [][]string{{"AUM below 50 Lakh", "Up to 1% Advisory fee"}, {"AUM between 50 Lakh to 1 Cr", "Up to 1.5% Advisory fees"}, {"AUM above 1 Cr", "Up to 2% advisory fees"}} m.TableList(tableHeadings, contents, props.TableList{ HeaderProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, ContentProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, Align: consts.Left, //AlternatedBackground: &lightPurpleColor, HeaderContentSpace: 1, Line: true, }) } func buildStamp(m pdf.Maroto, name string) { m.Row(20, func() { m.Col(8, func() { m.Text("For K.M. Global Credit Private Limited", props.Text{ Style: consts.Bold, Size: 8, Align: consts.Left, Extrapolate: false, }) m.Text("Name: - Aditya Damani", props.Text{ Top: 5, Size: 8, Align: consts.Left, }) m.Text("Designation: - Founder & CEO", props.Text{ Top: 8, Size: 8, Align: consts.Left, }) }) m.Col(6, func() { m.Text("For. "+name, props.Text{ Style: consts.Bold, Size: 8, Align: consts.Left, Extrapolate: false, }) m.Text("Name:________________", props.Text{ Top: 5, Size: 8, Align: consts.Left, }) m.Text("Designation:________________", props.Text{ Top: 8, Size: 8, Align: consts.Left, }) }) }) } func buildBankDetails(m pdf.Maroto) { m.Row(10, func() { m.Col(12, func() { m.Text("[Account Details]", props.Text{ Top: 2, Size: 9, Color: getDarkPurpleColor(), Style: consts.Bold, //Align: consts.Center, }) }) }) m.SetBackgroundColor(color.NewWhite()) tableHeadings := []string{"", ""} contents := [][]string{{"Bank Name", ""}, {"Account Holder Name", ""}, {"Account Number", ""}, {"IFSC Code", ""}} m.TableList(tableHeadings, contents, props.TableList{ HeaderProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, ContentProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, Align: consts.Left, //AlternatedBackground: &lightPurpleColor, HeaderContentSpace: 1, Line: true, }) } func ToPDFAgreementIFA(name string) (string, error) { m := pdf.NewMaroto(consts.Portrait, consts.A4) m.SetPageMargins(20, 10, 20) dt := getDate() datetime := dt.Format("2006-01-02 15:04:05") buildHeadingIFA(m) m.Row(10, func() { m.Col(12, func() { m.Text("CREDIT FAIR CAPITAL – SOURCING AGREEMENT,", props.Text{ Top: 3, Style: consts.Bold, Align: consts.Center, // Color: getDarkPurpleColor(), }) }) }) m.Row(10, func() { m.Col(12, func() { m.Text("THIS AGREEMENT is made at Mumbai on this "+datetime) }) }) m.Row(10, func() { m.Col(12, func() { m.Text("Between", props.Text{ Style: consts.Bold, }) }) }) m.Row(17, func() { m.Col(12, func() { m.Text("Credit Fair Capital, K. M. Global Credit Private Limited , a company incorporated under the Companies Act, 2013 and having its registered office at Surya Mahal, 4th Floor, 5 Burjori Bharucha Marg, Mumbai – 400001 (hereinafter referred to as “Company”, which expression shall unless repugnant to the meaning or context hereof, include its successors and permitted assigns)") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("And") }) }) m.Row(17, func() { m.Col(12, func() { m.Text(name+" a company incorporated under the Companies Act, 2013 and having its registered office C 503/504 Viniclassic. M G Road, Mumbai Subueban, Maharashtra - 400067, (hereinafter referred to as \"Partner\", which expression shall unless repugnant to the meaning or context hereof, include its successors and permitted assigns).") }) }) m.Row(17, func() { m.Col(12, func() { m.Text("Company and the Partner shall hereinafter be collectively referred to as “Parties” and individually as “Party”.") }) }) m.Row(8, func() { m.Col(12, func() { m.Text("WHEREAS") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("a. The Company is a Non-Banking Financial Company and is engaged into the business of introducing financial products for investments and such beneficial plans as regulated under the Reserve Bank of India.") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("b. The Partner is engaged into the business of financial and investment advisory.") }) }) m.Row(18, func() { m.Col(12, func() { m.Text("c. With a view of introducing potential investors/customers to the Company, the Partner is desirous of being engaged with the Company to discover potential investment opportunities from time to time by the Company and to provide investor sourcing services to the Company.") }) }) m.Row(12, func() { m.Col(12, func() { m.Text("d. The Parties hereby agree that this Agreement is being executed for the purpose of recording the general terms and conditions applicable for the Potential Transactions.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("e. Pursuant to the above, the Parties are therefore desirous of executing this Agreement to record the terms and conditions in relation thereto.") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("NOW IT IS HEREBY AGREED BY AND BETWEEN THE PARTIES HERETO AS FOLLOWS:", props.Text{ Style: consts.Bold, }) }) }) m.Row(10, func() { m.Col(10, func() { m.Text("1. DEFINITIONS", props.Text{ Style: consts.Bold, }) }) }) m.Row(12, func() { m.Col(12, func() { m.Text(" Capitalized terms used in this Agreement, unless the context otherwise requires, shall have the following meanings") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("a. 'Applicable Law' means Indian law and includes the constitution, statute, law, rule, regulation, ordinance, judgment, order, decree, authorization, or any published directive, guideline, requirement or governmental restriction having the force of law, or any determination by, or interpretation of any of the foregoing by, any judicial, quasi-judicial, regulatory, governmental or quasi-governmental authority, whether in effect as of the date of this Agreement or thereafter and each as amended from time to time;") }) }) m.Row(9, func() { m.Col(12, func() { m.Text("b. 'Agreement' means and includes this services agreement together with its Schedules.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("c. 'Customer' shall mean all Persons introduced to the Company to invest money or all Persons who have invested money upon the platform of Company including users of the online platform of Company, as may be applicable, pursuant to this Agreement;") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("d. 'Fee' shall have the meaning ascribed to the term in Schedule A of this Agreement.") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("e. 'Intellectual Property Rights' means and includes all copyrights, designs, inventions, patent, service marks, trademarks (in each case, whether registered or arising at common law, or its overseas equivalent) or applications for any of these, formulations, trade / brand names, business names, logos, discoveries, trade secrets, knowhow, source code, object code, technical information, commercial and financial data and all other intellectual property rights (whether or not registered);") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("f. 'KYC Regulations' means t h e applicable Know Your Customer regulations/directions issued by the RBI (as defined below) or any other statutory authority from time to time under the Applicable Law;") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("g. 'Material' shall mean any material including but not limited to all information, reports, studies, software (including source codes, object codes, derivative works and executables) flowcharts, diagrams, hardware and other tangible and intangible material of any nature whatsoever and Intellectual Property.") }) }) m.Row(9, func() { m.Col(12, func() { m.Text("h. 'RBI' means the Reserve Bank of India;") }) }) m.Row(9, func() { m.Col(12, func() { m.Text("i. 'Schedules' shall mean schedules to this Agreement (including Schedule A) as amended from time to time.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("j. 'Services' shall mean and include all the services as is specified in Schedule A.") }) }) m.Row(10, func() { m.Col(10, func() { m.Text("2. Scope of work", props.Text{ Style: consts.Bold, }) }) }) m.Row(15, func() { m.Col(12, func() { m.Text("a. During the Term of this Agreement, Partner shall provide sourcing services for customers/investors (as more specifically described in Clause 4) to the Company from time to time.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("b. At the time of sourcing the customers /investors the representatives of the Partner shall collect customers /inventor's complete legally applicable personal information and subject to receipt of consent from such customers and compliance with Applicable Laws.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("c. Partner and/or its customers/investors shall pay all applicable taxes, levies or duties, including GST that may be levied on any transactions undertaken pursuant to this Agreement;") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("d. The Parties agree and acknowledge that the agreed engagement of the Partner by the Company under the provision of the Services is non-exclusive in nature.") }) }) m.Row(10, func() { m.Col(10, func() { m.Text("3. DUTIES AND OBLIGATIONS OF COMPANY", props.Text{ Style: consts.Bold, }) }) }) m.Row(15, func() { m.Col(12, func() { m.Text("a. Company shall be entitled to distribute investments of the investors/customers introduced by the Partner into Company’s onboarded P2P, NCD or such other financial institutions. It is clarified that the Company shall restrict its scope up to distribution of investments and not invest money of the customer by its own.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("b. Company shall be entitled to conduct review and assessment of the services, the security practices and control processes at such periodicity in accordance with Applicable Laws to monitor and assess the quality of services been provided by the Partner and any security breaches and to take such action in accordance with Applicable Laws.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("c. Company shall designate one or more point-of-contact who would be person of authority, to facilitate day-to-day coordination with the Partner. If there is a change in the point of contact prior intimation of the same shall be provided to Partner.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("d. At the end of the mandatory lock-in period if any as mentioned in SCHEDULE - A, Company and Partner shall transfer all funds due to an investor by liquidating their portfolio via a secondary market sale on best-effort basis.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("e. Partner shall have no employment relationship whatsoever with the employees of the Company and it shall be Company’s sole responsibility and discretion as an independent employer to decide about the terms and conditions of employment, supervision and termination of services of its employees.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("f. Company shall be responsible for all its liabilities relating to any Govt. Authorities and all applicable statutes, regulations and provisions having the force of law as also all rules, by- laws and other provisions framed there under in pursuance thereof.") }) }) m.Row(10, func() { m.Col(10, func() { m.Text("4. DUTIES AND OBLIGATIONS OF THE PARTNER", props.Text{ Style: consts.Bold, }) }) }) m.Row(15, func() { m.Col(12, func() { m.Text("a. Subject to receipt of consent from its customers, Partner shall provide consent to the Company, to help and distribute the funds of its customers on the platform to optimize returns on investment as Company deems fit.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("b. Partner shall obtain all necessary consents and undertaking from its Customers, prior to the Customer entering into the Loan Agreement.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("c. Partner shall ensure all applicable KYC compliances are met and details shared with the Company while on boarding customers for the P2P marketplace.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("d. Partner shall ensure the availability of an adequate number of customers and investible funds on a best effort basis.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("e. Partner undertakes that its Customers will bear the exit load as mentioned in SCHEDULE - A, if its Customers decide to withdraw funds before the completion of the stipulated lock-in period.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("f. Partner shall provide adequate supervision to ensure suitable performance of the investments of its customers.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("g. Partner shall be responsible for all its liabilities which arise due to direct act or omission of Partner relating to any Govt. Authorities and all applicable statutes, regulations and provisions having the force of law as also all rules, by-laws and other provisions framed there under in pursuance thereof.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("h. Partner shall not wholly or partially assign, transfer or sub-contract any of its rights, duties or benefits under this Agreement for any reason whatsoever to any other person, firm or\n \nCompany without the prior intimation and consent of the Company.") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("i. Partner shall strictly adhere to all privacy laws/data privacy laws including Information Technology (Reasonable Security Practices and Procedures and Sensitive Data or Information) Rules, 2011 including a privacy policy to be duly uploaded on its website.") }) }) m.Row(8, func() { m.Col(10, func() { m.Text("5. REPRESENTATIONS, WARRANTIES AND UNDERTAKINGS", props.Text{ Style: consts.Bold, }) }) }) m.Row(8, func() { m.Col(9, func() { m.Text("Both the Parties hereby represent and warrant that:", props.Text{ Size: 7, }) }) }) m.Row(10, func() { m.Col(12, func() { m.Text("a. it is duly organized and validly existing under the laws of the jurisdiction in which it is established;") }) }) m.Row(15, func() { m.Col(12, func() { m.Text("b. It has full authority to enter into this Agreement and to perform all the obligations hereunder according to the terms hereof;") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("c. This Agreement has been duly authorized, has been duly and validly executed and delivered, and is legal, valid, and binding on them, enforceable in accordance with the terms hereof; and the persons executing this Agreement on behalf of such Party are duly empowered and authorised to execute this Agreement and to perform all its obligations in accordance with the terms herein;") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("d. The execution and delivery of this Agreement and all other agreements contemplated hereby will not result in or constitute a violation of any law, regulation, agreement, undertaking or other obligation to which it is bound or of any, order, writ, judgment, injunction or decree applicable to it or any of its properties or assets, or violate any license, permit, authorization.") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("e. Company does not guarantee the future performance of the investments/borrowers/loans or any specific level of performance in compliance with Master Direction – NBFC-P2P Directions, 2017. The success of any investment suggestion or strategy that Company may use and to which Partner and its customers consent wholly;") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("f. The Partner understands that investment suggestions made for the Partner and its customers by the Company are subject to default risk, and that those investment decisions will not always be profitable, however, Company will diversify the investment across various very low risk profiles to minimize the portfolio at risk") }) }) m.Row(30, func() { m.Col(12, func() { m.Text("6. Force Majeure. Neither Party shall be liable for any breach of its obligations hereunder resulting from causes beyond its reasonable control including but not limited to fires, floods, earthquakes, pandemic or epidemic illness, strikes (of other employees), insurrection or riots, embargoes, or requirements or regulations of any civil or military authority (“Force Majeure”). Each Party hereto agrees to give reasonable notice to the other upon becoming aware of an event of Force Majeure. If a default due to an event of Force Majeure shall continue for more than thirty (30) days then the Party not in default shall be entitled to terminate this Agreement. Neither Party shall have any liability to the other in respect of the termination of this Agreement as a result of an event of Force Majeure.") }) }) m.Row(32, func() { m.Col(12, func() { m.Text("7. Business Continuity. The Partner shall establish, implement and maintain an adequate business continuity plan aimed at ensuring, in the case of an interruption to its systems and procedures, the preservation of essential data and functions, and the maintenance of services and activities, or, where that is not possible, the timely recovery of such data and functions and the timely resumption of its services and activities. The Partner shall\nmaintain a log of all business continuity events. In the event that a material business continuity event occurs, the Partner shall advise Company promptly of such event and the steps proposed in order to minimize any interruption to its services hereunder. The occurrence of a disaster, risk, or force mejure shall not relieve the Partner to perform its obligations under this Agreement.") }) }) m.Row(33, func() { m.Col(12, func() { m.Text("8. Confidentiality. Both parties agree that this Agreement is for its confidential use only and that neither the existence nor the terms thereof will be disclosed by either party to any person other than its officers, directors, employees, accountants, attorneys and other advisors, and then only on a “need to know” basis in connection with the Fund Raise contemplated under this Agreement and on a confidential basis, Save and except that, following the Company’s acceptance of the provisions hereof and return of executed copies of this Agreement to Partner, the Company may (i) make public disclosure of Partner as the “Partner” (ii) file a copy of this Agreement in a public record in which it is required by law to be filed and (iii) make such other public disclosures of the terms and conditions hereof as strictly required by law.") }) }) m.Row(27, func() { m.Col(12, func() { m.Text("A. Any non-public information designated in writing as confidential made by disclosing party, the party receiving such information agrees that it will use such information solely for the purposes contemplated by this Agreement and will not disclose any such information without the consent of the disclosing party except to the rating agencies (if applicable), to\n \nits (and, in the case of Partner, each other member of the Partner’s) professional advisors, directors, officers, servants, employees and agents who need to receive and consider the information for the purpose of the Fund Raise and the purchasers and potential purchasers of the issuances.") }) }) m.Row(27, func() { m.Col(12, func() { m.Text("9. The obligations of confidentiality will not be applicable to any information which is within public domain or becomes available to public hereafter; or is required to be disclosed by law or by any regulatory, governmental; or other competent agency or authority in any jurisdiction or pursuant to any legal proceedings; or is required in the preparation of the offering circular or other offering document or in the distribution of the issuances. Without prejudice to the foregoing, the obligations of confidentiality set out herein shall survive for a period of one (1) year from the date of disclosure of such information.") }) }) m.Row(27, func() { m.Col(12, func() { m.Text("9. Indemnity. Each party shall defend, indemnify, keep indemnified and hold the other party, its affiliates, directors, agents, officers and employees harmless from all claims, actions, suits, damages, costs and expenses (including attorney fees), losses, penalties, fines, charges, liabilities, cause of action, passing off actions by any persons in relation to or arising out of i) breach of any obligation, undertaking, or covenants by the indemnifying party under this Agreement; (ii) any representation or warranty by the indemnifying party being untrue or inaccurate, or (iii) any third party claims raised against the indemnified party that may arise on account of its personnel’s acts or omissions under this Agreement.") }) }) m.Row(27, func() { m.Col(12, func() { m.Text("10. LIMITATION OF LIABILITY. Neither Party shall be liable in contract, tort (including negligence or breach of statutory duty) or otherwise for any indirect or consequential loss or damage of any kind including punitive or exemplary damages or for any loss of profit or loss of contract, loss of opportunity, loss of revenue or third-party loss whether foreseeable or otherwise. Notwithstanding anything stated under this Agreement, the\naggregate liability of the Company to the Partner from any cause whatsoever arising out of the Agreement shall not in any event exceed Rs. 1,00,000/-.") }) }) m.Row(27, func() { m.Col(12, func() { m.Text("11. Term and Termination. The initial term of this Agreement shall be 36 (Thirty-Six) months (“Initial Term”). At the end of the Initial Term, unless otherwise agreed between the Parties in writing, the Agreement shall stand renewed for a further period of 24 (Twenty Four) months without any further act or deed by any Party. Notwithstanding anything to the contrary contained in this Agreement, this Agreement may be terminated (i) by the mutual consent of Company and the Partner, (ii) or by either Party, upon giving 90 (Ninety) days’ notice to the other Party.") }) }) m.Row(27, func() { m.Col(12, func() { m.Text("12. Notices. Any and all notices, invoices, documents and other information to be given by one of the Parties to the other shall be deemed sufficiently given when forwarded by registered post with acknowledgment due or hand delivery to the other Party at the addresses mentioned above, or by way of email at the email addresses provided by one party to the other under this Agreement. Each Party shall notify the other in writing of any changes to such addresses.") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("13. Entire Agreement. This Agreement constitutes the whole and only agreement between the Company and Partner in relation to the Services to be provided by and proposal of Partner.") }) }) m.Row(32, func() { m.Col(12, func() { m.Text("14. Miscellaneous Provisions. This Agreement may not be amended or modified except by both parties in writing. This Agreement shall be binding upon and ensure to the benefit of each party to this Agreement and its or any subsequent successors and assigns. A party to this Agreement may not assign or transfer or purport to assign or transfer a right or obligation underthis Agreement except with the prior written consent of the other party to this Agreement, provided that Partner may transfer its rights and obligations to any other member of the Partner. The invalidity, illegality or unenforceability of a provision of this Agreement does not affect or impair the continuation in force of the remainder of such provision or the remainder of this Agreement. Each party to this Agreement represents that this Agreement has been duly authorised by it and each such party undertakes to furnish to the other party a copy of any such authorisation on request.") }) }) m.Row(10, func() { m.Col(10, func() { m.Text("15. Dispute Resolution", props.Text{ Style: consts.Bold, }) }) }) m.Row(20, func() { m.Col(12, func() { m.Text(" 15.1. In the event a dispute or difference arises in connection with the interpretation or implementation of this Agreement, the Parties to the dispute shall attempt in the first instance to amicably resolve such dispute through mutual consultations. If the dispute is\n \nnot resolved within 15 (Fifteen) days from the date of commencement of discussions or such a longer period as the Parties agree in writing, then a Party may refer the dispute to arbitration.") }) }) m.Row(20, func() { m.Col(12, func() { m.Text(" 15.2. The Parties shall submit all disputes and differences howsoever arising out of or in connection with this Agreement to arbitration by 1 (one) arbitrator mutually\nappointed by the Parties hereto failing which, the arbitrator shall be appointed as per the provisions of the Arbitration and Conciliation Act, 1996 and all matters in the arbitration shall be governed by the Arbitration and Conciliation Act, 1996.\n") }) }) m.Row(20, func() { m.Col(12, func() { m.Text(" 15.3. The place of arbitration shall be Mumbai, India and the language to be used in the arbitration proceedings shall be English. The award of the arbitration proceedings will be final and binding on both Parties to the Agreement.") }) }) m.Row(20, func() { m.Col(12, func() { m.Text("16. Governing Law. This Agreement is governed by and shall be construed in accordance with Indian laws. The Company irrevocably submits for the benefit of Partner and the other Indemnified Persons to the non-exclusive jurisdiction of the courts at Mumbai with respect to any matter arising out of or in connection with this Agreement.") }) }) m.Row(10, func() { m.Col(12, func() { m.Text("IN WITNESS WHEREOF the parties hereto have put their hands the day and year first hereinabove written.") }) }) buildStamp(m, name) buildFeeStructure(m) m.Row(8, func() { m.Col(12, func() { m.Text("*Company solely reserves the right under this agreement to make any corrections to the quoted fees over the time.", props.Text{ Size: 6, }) }) }) m.Row(8, func() { m.Col(12, func() { m.Text("**The advisory fees will be transferred on a monthly basis (Total Aum × advisory fees (% slab) ÷ 12 months), this formula will be solely modified / calculated as per the discretion of the Company. All applicable taxes, levies or duties, including GST levied on any transactions undertaken pursuant to this Agreement shall be borne by the Partner.", props.Text{ Size: 6, }) }) }) m.Row(12, func() { m.Col(12, func() { m.Text("The Partner will raise an invoice to the Company at the beginning of the current month for the preceding month. Company shall then clear all undisputed invoice within 30 (thirty) days of the receipt of the invoice. Company shall raise a dispute within 10 (ten) days of receiving the invoice. Both parties should settle any invoice related disputes within 15 (fifteen) days of the same being raised by either Party. In the event the dispute is not settled amicably, then dispute resolution process under Clause 15 may be invoked.", props.Text{ Size: 6, }) }) }) m.Row(8, func() { m.Col(10, func() { m.Text("SERVICES", props.Text{ Style: consts.Bold, }) }) }) m.Row(5, func() { m.Col(12, func() { m.Text("Services shall include without limitation:", props.Text{ Size: 6, }) }) }) m.Row(5, func() { m.Col(12, func() { m.Text("a. Ensuring investible funds are transferred to the account to be notified to the Partner from time to time.", props.Text{ Size: 5, }) }) }) buildBankDetails(m) m.Row(20, func() { m.Col(12, func() { m.Text("I have read all the terms and conditions mentioned in the agreement and I agreed to it. "+name+" signed this agreement at "+datetime, props.Text{ Size: 8, }) }) }) filename := "agreement_ifa_" + time.Now().String() + ".pdf" err := m.OutputFileAndClose(filename) if err != nil { fmt.Println("ould not save PDF:", err) os.Exit(1) } fmt.Println("PDF saved successfully") //Read to base64 bytes, err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err) } //var base64Encoding string //base64Encoding = "data:application/pdf;base64," + toBase64(bytes) // Print the full base64 representation of the image return toBase64(bytes), nil /*err := m.OutputFileAndClose("pdfs/agreement_" + time.Now().String() + ".pdf") if err != nil { fmt.Println("ould not save PDF:", err) os.Exit(1) } fmt.Println("PDF saved successfully") return*/ } func StatementPDF(statement Statement) (string, error) { m := pdf.NewMaroto(consts.Portrait, consts.A4) m.SetPageMargins(20, 10, 20) buildHeading(m) m.Row(10, func() { m.Col(6, func() { m.Text("Statement Date: "+statement.StatementDate, props.Text{ Top: 2, Size: 7, }) }) m.Col(6, func() { m.Text("Statement Period: From "+statement.StatementPeriod.From+" to "+statement.StatementPeriod.To, props.Text{ Top: 2, Size: 7, }) }) }) buildInvestorBankDetails(m, statement) buildAccountSummary(m, statement) str := fmt.Sprint("Total interest earned as of ", statement.InterestSummary.InterestEarnedAsOfDate, " (accrued + redeemed) : ", FormatMoneyFloat64(statement.InterestSummary.InterestEarnedAsOfAmount, 2)) m.Row(10, func() { m.Col(10, func() { m.Text(str, props.Text{ Top: 2, Size: 8, }) }) }) buildTransactionDetails(m, statement) m.Row(10, func() { m.Col(12, func() { m.Text("Credit Fair Capital, K. M. Global Credit Private Limited", props.Text{ Top: 2, Size: 8, }) }) }) m.Row(8, func() { m.Col(12, func() { m.Text("Registered Address: 4th Floor Surya Mahal, 5 Burjorji Bharucha Marg, Fort, Mumbai – 400001.", props.Text{ Top: 2, Size: 8, }) }) }) m.Row(8, func() { m.Col(12, func() { m.Text("Unless the constituent notifies Credit Fair Capital within 7 days of any discrepancy found by him/her in this statement of Account, it will be taken that he/she has found the account correct. The closing balance as shown/displayed includes only the credit balance, but not the funds which are under clearing. Hence the closing balance displayed may not be the effective available balance. For any further clarifications, please contact the Customer Service at info@creditfaircapital.in . This is an auto generated mail and does not require signature.", props.Text{ Top: 2, Size: 8, }) }) }) m.Row(8, func() { m.Col(12, func() { m.Text("*Current Value numbers displayed are indicative in nature. Actual returns and pay-outs might differ.", props.Text{ Top: 17, Size: 8, }) }) }) m.Row(8, func() { m.Col(12, func() { m.Text("Powered by – Transactree Technologies Private Limited", props.Text{ Top: 6, Size: 8, }) }) }) m.Row(8, func() { m.Col(12, func() { m.Text("Registered Address: Second Floor, L-92, Outer Ring Rd, Baba Gangnath Market, Munirka, New Delhi, Delhi 110067", props.Text{ Top: 2, Size: 8, }) }) }) filename := "agreement_" + statement.InvestorDetails.Name + "_" + time.Now().String() + ".pdf" err := m.OutputFileAndClose(filename) if err != nil { fmt.Println("ould not save PDF:", err) os.Exit(1) } fmt.Println("PDF saved successfully") //Read to base64 bytes, err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err) } //var base64Encoding string //base64Encoding = "data:application/pdf;base64," + toBase64(bytes) // Print the full base64 representation of the image return toBase64(bytes), nil /*err := m.OutputFileAndClose("pdfs/agreement_" + time.Now().String() + ".pdf") if err != nil { fmt.Println("ould not save PDF:", err) os.Exit(1) } fmt.Println("PDF saved successfully") return*/ } func getDarkPurpleColor() color.Color { return color.Color{ Red: 75, Green: 0, Blue: 130, } } func buildHeading(m pdf.Maroto) { m.RegisterHeader(func() { m.Row(50, func() { m.Col(6, func() { m.Text("ACCOUNT STATEMENT", props.Text{ Top: 20, Style: consts.Bold, Align: consts.Center, Size: 20, //Color: color.Color{Red: 10, Green: 10, Blue: 10}, Color: getDarkPurpleColor(), }) }) //log.Print("file1") mydir, err := os.Getwd() if err != nil { fmt.Println(err) } //log.Print(mydir) m.Col(6, func() { err := m.FileImage(mydir+"/assets/CFC_logo.png", props.Rect{ Center: true, Percent: 75, }) if err != nil { fmt.Println("Image file was not loaded - ", err) } }) }) }) } func buildInvestorBankDetails(m pdf.Maroto, statement Statement) { tableHeadings := []string{"", ""} contents := [][]string{{"Investor Name", statement.InvestorDetails.Name}, {"Address", statement.InvestorDetails.Address}, {"Mobile No.", aes.DecryptData(statement.InvestorDetails.Phone)}, {"Email", aes.DecryptData(statement.InvestorDetails.Email)}} tableHeadingsBank := []string{"", ""} contentsBank := [][]string{{"Bank Name", statement.InvestorDetails.Bank.Name}, {"Account Number", statement.InvestorDetails.Bank.AccountNumber}, {"IFSC Code", statement.InvestorDetails.Bank.IFSCCode}, {"Mode of Payout", statement.InvestorDetails.Bank.ModeOfPayout}, {"Mode of Holding", statement.InvestorDetails.Bank.ModeOfHolding}, {"PAN", aes.DecryptData(statement.InvestorDetails.Bank.PAN)}, {"Financial Advisor", statement.InvestorDetails.Bank.FinancialAdvisor}} //lightPurpleColor := getLightPurpleColor() //m.SetBackgroundColor(getTealColor()) m.Row(10, func() { m.Col(12, func() { m.Text("INVESTOR DETAILS", props.Text{ Top: 2, Size: 9, Color: getDarkPurpleColor(), Style: consts.Bold, //Align: consts.Center, }) }) }) m.SetBackgroundColor(color.NewWhite()) m.TableList(tableHeadings, contents, props.TableList{ HeaderProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, ContentProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, Align: consts.Left, //AlternatedBackground: &lightPurpleColor, HeaderContentSpace: 1, Line: true, }) m.Row(10, func() { m.Col(12, func() { m.Text("INVESTOR BANK DETAILS", props.Text{ Top: 2, Size: 9, Color: getDarkPurpleColor(), Style: consts.Bold, //Align: consts.Center, }) }) }) m.TableList(tableHeadingsBank, contentsBank, props.TableList{ HeaderProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, ContentProp: props.TableListContent{ Size: 8, GridSizes: []uint{3, 7, 2}, }, Align: consts.Left, //AlternatedBackground: &lightPurpleColor, HeaderContentSpace: 1, Line: true, }) } func buildAccountSummary(m pdf.Maroto, statement Statement) { tableHeadings := []string{"Net Investment", "Net Current Value", "Interest Accrued", "Interest Redeemed", "Current Return XIRR (%)*"} contents := [][]string{{}} for i := 0; i < len(statement.Account.AccountSummary); i++ { content := []string{} if i == 0 { holdingPeriod := fmt.Sprintf("Holding Period: %s %s", statement.Account.AccountSummary[i].HoldingPeriod, " Month") if statement.Account.AccountSummary[i].TenureType == "D" { holdingPeriod = fmt.Sprintf("Holding Period: %s %s", statement.Account.AccountSummary[i].HoldingPeriod, " Day") } content = []string{"", fmt.Sprintf("Scheme:%s", strings.Title(strings.ToLower(statement.Account.AccountSummary[i].Scheme))), fmt.Sprintf("Payout:%s", statement.Account.AccountSummary[i].Payout), holdingPeriod, ""} } else { content = []string{FormatMoneyFloat64(statement.Account.AccountSummary[i].NetInvestment, 2), FormatMoneyFloat64(statement.Account.AccountSummary[i].NetCurrentValue, 2), FormatMoneyFloat64(statement.Account.AccountSummary[i].InterestAccrued, 2), FormatMoneyFloat64(statement.Account.AccountSummary[i].InterestRedeemed, 2), FormatMoneyFloat64(statement.Account.AccountSummary[i].CurrentReturn, 2)} } contents = append(contents, content) } //lightPurpleColor := getLightPurpleColor() //m.SetBackgroundColor(getTealColor()) m.Row(10, func() { m.Col(12, func() { m.Text("Account Summary As on "+statement.StatementPeriod.To, props.Text{ Top: 2, Size: 9, Color: getDarkPurpleColor(), Style: consts.Bold, //Align: consts.Center, }) }) }) m.SetBackgroundColor(color.NewWhite()) m.TableList(tableHeadings, contents, props.TableList{ HeaderProp: props.TableListContent{ Size: 8, GridSizes: []uint{2, 2, 2, 2, 2}, }, ContentProp: props.TableListContent{ Size: 8, GridSizes: []uint{2, 2, 2, 2, 2}, }, Align: consts.Left, //AlternatedBackground: &lightPurpleColor, HeaderContentSpace: 1, Line: true, }) } func buildTransactionDetails(m pdf.Maroto, statement Statement) { tableHeadings := []string{"Date", "Transaction Type", "Transaction Amount", "Closing Principal as on Date", "Current Value as on Date"} contents := [][]string{{}} var scheme string for i := 0; i < len(statement.Transaction); i++ { content := []string{} if i == 0 { scheme = statement.Account.AccountSummary[0].SchemeName if statement.Transaction[i].TransactionAmount == 0 { statement.Transaction[i].TransactionAmount = statement.Transaction[i].TransactionAmountDebit } //content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), fmt.Sprintf("%f", statement.Transaction[i].TransactionAmount), fmt.Sprintf("%f", statement.Transaction[i].ClosingPrincipalAsOnDate), fmt.Sprintf("%f", statement.Transaction[i].CurrentValueAsOnDate)} /*date, _ := time.Parse("2006-01-02", statement.Transaction[i].Date) if date.Day() == 1 && strings.Contains(statement.Transaction[i].TransactionType, "Interest Accrued") { log.Print("Interest entry") } else { if strings.Contains(statement.Transaction[i].TransactionType, "Interest Accrued") { if statement.Account.AccountSummary[0].Payout == "Monthly" { statement.Transaction[i].TransactionAmount = statement.Transaction[i].ClosingPrincipalAsOnDate - statement.Account.AccountSummary[1].NetInvestment } content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate,2)} } else { if statement.Account.AccountSummary[0].Payout == "Monthly" { //statement.Transaction[i].TransactionAmount = statement.Transaction[i].ClosingPrincipalAsOnDate - statement.Account.AccountSummary[0].NetInvestment } content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} } contents = append(contents, content) }*/ if strings.Contains(statement.Transaction[i].TransactionType, "Interest Accrued") { // We are not showing interest accrued entry for the Cumulative plan if statement.Account.AccountSummary[0].Payout == "Monthly" { NetAmount := statement.Account.AccountSummary[1].NetInvestment if strings.Contains(statement.Transaction[i-1].TransactionType, "Monthly Interest") { NetAmount = statement.Transaction[i-1].ClosingPrincipalAsOnDate } statement.Transaction[i].TransactionAmount = statement.Transaction[i].ClosingPrincipalAsOnDate - NetAmount content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} } } else { if statement.Account.AccountSummary[0].Payout == "Monthly" { //statement.Transaction[i].TransactionAmount = statement.Transaction[i].ClosingPrincipalAsOnDate - statement.Account.AccountSummary[0].NetInvestment } content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} } if len(content) > 0 { contents = append(contents, content) } //contents = append(contents, content) } else { if statement.Transaction[i].TransactionAmount == 0 { statement.Transaction[i].TransactionAmount = statement.Transaction[i].TransactionAmountDebit } /*date, _ := time.Parse("2006-01-02", statement.Transaction[i].Date) if date.Day() == 1 && strings.Contains(statement.Transaction[i].TransactionType, "Interest Accrued") { log.Print("Interest entry") } else { if strings.Contains(statement.Transaction[i].TransactionType, "Interest Accrued") { if statement.Account.AccountSummary[0].Payout == "Monthly" { statement.Transaction[i].TransactionAmount = statement.Transaction[i].CurrentValueAsOnDate - statement.Account.AccountSummary[1].NetInvestment statement.Transaction[i].ClosingPrincipalAsOnDate = statement.Account.AccountSummary[1].NetInvestment } content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} } else { if statement.Account.AccountSummary[0].Payout == "Monthly" { //statement.Transaction[i].TransactionAmount = statement.Transaction[i].ClosingPrincipalAsOnDate - statement.Account.AccountSummary[0].NetInvestment } content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} } contents = append(contents, content) }*/ if strings.Contains(statement.Transaction[i].TransactionType, "Interest Accrued") { if statement.Account.AccountSummary[0].Payout == "Monthly" { NetAmount := statement.Account.AccountSummary[1].NetInvestment if strings.Contains(statement.Transaction[i-1].TransactionType, "Monthly Interest") { NetAmount = statement.Transaction[i-1].ClosingPrincipalAsOnDate } statement.Transaction[i].TransactionAmount = statement.Transaction[i].CurrentValueAsOnDate - NetAmount statement.Transaction[i].ClosingPrincipalAsOnDate = NetAmount content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} } } else { if statement.Account.AccountSummary[0].Payout == "Monthly" { //statement.Transaction[i].TransactionAmount = statement.Transaction[i].ClosingPrincipalAsOnDate - statement.Account.AccountSummary[0].NetInvestment } /*if strings.Contains(statement.Transaction[i].TransactionType, "Withdrawal Amount - Principal"){ if strings.Contains(statement.Transaction[i + 1].TransactionType, "Withdrawal Amount - Interest"){ log.Print(statement.Transaction[i + 1]) log.Print(statement.Transaction[i]) if statement.Transaction[i + 1].TransactionAmount == 0 { statement.Transaction[i + 1].TransactionAmount = statement.Transaction[i + 1].TransactionAmountDebit } //For interest content = []string{fmt.Sprintf("%s", statement.Transaction[i + 1].Date), fmt.Sprintf("%s", statement.Transaction[i + 1].TransactionType), FormatMoneyFloat64(statement.Transaction[i + 1].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i + 1].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i + 1].CurrentValueAsOnDate, 2)} contents = append(contents, content) //For principal content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} contents = append(contents, content) content = []string{} }else{ content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} } }else if strings.Contains(statement.Transaction[i].TransactionType, "Withdrawal Amount - Interest") || strings.Contains(statement.Transaction[i].TransactionType, "Withdrawal Amount - Principal"){ log.Print(statement.Transaction[i].TransactionType) log.Print("empty") content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} }else{ content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} }*/ content = []string{fmt.Sprintf("%s", statement.Transaction[i].Date), fmt.Sprintf("%s", statement.Transaction[i].TransactionType), FormatMoneyFloat64(statement.Transaction[i].TransactionAmount, 2), FormatMoneyFloat64(statement.Transaction[i].ClosingPrincipalAsOnDate, 2), FormatMoneyFloat64(statement.Transaction[i].CurrentValueAsOnDate, 2)} //log.Print(content) } if len(content) > 0 { contents = append(contents, content) } } } //lightPurpleColor := getLightPurpleColor() //m.SetBackgroundColor(getTealColor()) m.Row(10, func() { m.Col(6, func() { m.Text("Transaction Details ", props.Text{ Top: 2, Size: 7, }) }) m.Col(6, func() { m.Text("From "+statement.StatementPeriod.From+" To "+statement.StatementPeriod.To, props.Text{ Top: 2, Size: 7, }) }) }) m.Row(10, func() { m.Col(12, func() { m.Text(fmt.Sprintf("Credit Fair Capital: %s", scheme), props.Text{ Top: 2, Size: 9, Color: getDarkPurpleColor(), Style: consts.Bold, //Align: consts.Center, }) }) }) m.SetBackgroundColor(color.NewWhite()) m.TableList(tableHeadings, contents, props.TableList{ HeaderProp: props.TableListContent{ Size: 8, GridSizes: []uint{2, 2, 2, 2, 2}, }, ContentProp: props.TableListContent{ Size: 8, GridSizes: []uint{2, 2, 2, 2, 2}, }, Align: consts.Left, //AlternatedBackground: &lightPurpleColor, HeaderContentSpace: 1, Line: true, }) } func getLightPurpleColor() color.Color { return color.Color{ Red: 210, Green: 200, Blue: 230, } } func getTealColor() color.Color { return color.Color{ Red: 3, Green: 166, Blue: 166, } } func toBase64(b []byte) string { return base64.StdEncoding.EncodeToString(b) } func getDate() time.Time { loc, _ := time.LoadLocation("Asia/Kolkata") dt := time.Now().In(loc) return dt } func FormatMoneyInt(num int) string { var isNegative bool if num < 0 { isNegative = true } num = int(math.Abs(float64(num))) //negative int to positive int numInStr := fmt.Sprint(num) //int to string numDigits := []rune(numInStr) //string to []rune numDigitsInRevOrder := reverseRunes(numDigits) //reverse above array var commaSapNumStrInRevOrder string for i := 0; i < len(numDigitsInRevOrder); i++ { if i > 2 && i%2 == 1 { commaSapNumStrInRevOrder += "," } commaSapNumStrInRevOrder += string(numDigitsInRevOrder[i]) } commSapNumStr := string(reverseRunes([]rune(commaSapNumStrInRevOrder))) if isNegative { //prefix with sign '-' return "-" + commSapNumStr } return commSapNumStr } // FormatMoneyFloat64 returns comma separated number(Indian Money Format) in string // If precision is zero, it acts returns comma separated decimal part of number func FormatMoneyFloat64(num float64, precision uint) string { decimalPart := FormatMoneyInt(int(num)) if precision == 0 { return decimalPart } numInStr := fmt.Sprintf("%."+fmt.Sprint(precision)+"f", num) floatParts := strings.Split(numInStr, ".") return decimalPart + "." + floatParts[1] } func FormatMoneyInt64(num int64) string { return FormatMoneyInt(int(num)) } //Internal function to reverse the array func reverseRunes(chrs []rune) []rune { for i := 0; i < len(chrs)/2; i++ { j := len(chrs) - i - 1 chrs[i], chrs[j] = chrs[j], chrs[i] } return chrs }