reports.accrual: Outgoing report uses payment-to custom field. RT#10656.
This commit is contained in:
		
							parent
							
								
									3c77f8b3c7
								
							
						
					
					
						commit
						55de5627f2
					
				
					 3 changed files with 35 additions and 8 deletions
				
			
		| 
						 | 
					@ -218,10 +218,10 @@ def outgoing_report(groups: PostGroups,
 | 
				
			||||||
            rt_requestor = None
 | 
					            rt_requestor = None
 | 
				
			||||||
        if rt_requestor is None:
 | 
					        if rt_requestor is None:
 | 
				
			||||||
            requestor = ''
 | 
					            requestor = ''
 | 
				
			||||||
            payee = ''
 | 
					            requestor_name = ''
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            requestor = '{RealName} <{EmailAddress}>'.format_map(rt_requestor)
 | 
					            requestor = '{RealName} <{EmailAddress}>'.format_map(rt_requestor)
 | 
				
			||||||
            payee = rt_requestor['RealName']
 | 
					            requestor_name = rt_requestor['RealName']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        contract_links = related.all_meta_links('contract')
 | 
					        contract_links = related.all_meta_links('contract')
 | 
				
			||||||
        if contract_links:
 | 
					        if contract_links:
 | 
				
			||||||
| 
						 | 
					@ -232,15 +232,14 @@ def outgoing_report(groups: PostGroups,
 | 
				
			||||||
            contract_s = "NO CONTRACT GOVERNS THIS TRANSACTION"
 | 
					            contract_s = "NO CONTRACT GOVERNS THIS TRANSACTION"
 | 
				
			||||||
        projects = [v for v in related.meta_values('project')
 | 
					        projects = [v for v in related.meta_values('project')
 | 
				
			||||||
                    if isinstance(v, str)]
 | 
					                    if isinstance(v, str)]
 | 
				
			||||||
        payment_method = ticket.get('CF.{payment-method}', '')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print(
 | 
					        print(
 | 
				
			||||||
            "PAYMENT FOR APPROVAL:",
 | 
					            "PAYMENT FOR APPROVAL:",
 | 
				
			||||||
            f"REQUESTOR: {requestor}",
 | 
					            f"REQUESTOR: {requestor}",
 | 
				
			||||||
            f"TOTAL TO PAY: {-related.balance()}",
 | 
					            f"TOTAL TO PAY: {-related.balance()}",
 | 
				
			||||||
            f"AGREEMENT: {contract_s}",
 | 
					            f"AGREEMENT: {contract_s}",
 | 
				
			||||||
            f"PAYMENT TO: {payee}",
 | 
					            f"PAYMENT TO: {ticket.get('CF.{payment-to}', requestor_name)}",
 | 
				
			||||||
            f"PAYMENT METHOD: {payment_method}",
 | 
					            f"PAYMENT METHOD: {ticket.get('CF.{payment-method}', '')}",
 | 
				
			||||||
            f"PROJECT: {', '.join(projects)}",
 | 
					            f"PROJECT: {', '.join(projects)}",
 | 
				
			||||||
            "\nBEANCOUNT ENTRIES:",
 | 
					            "\nBEANCOUNT ENTRIES:",
 | 
				
			||||||
            sep='\n', file=out_file,
 | 
					            sep='\n', file=out_file,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -312,7 +312,7 @@ def test_outgoing_report(accrual_postings):
 | 
				
			||||||
        r'^REQUESTOR: Mx\. 510 <mx510@example\.org>$',
 | 
					        r'^REQUESTOR: Mx\. 510 <mx510@example\.org>$',
 | 
				
			||||||
        r'^TOTAL TO PAY: 280\.00 USD$',
 | 
					        r'^TOTAL TO PAY: 280\.00 USD$',
 | 
				
			||||||
        fr'^AGREEMENT: {contract_url}',
 | 
					        fr'^AGREEMENT: {contract_url}',
 | 
				
			||||||
        r'^PAYMENT TO: Mx\. 510$',
 | 
					        r'^PAYMENT TO: Hon\. Mx\. 510$',
 | 
				
			||||||
        r'^PAYMENT METHOD: payment method 510$',
 | 
					        r'^PAYMENT METHOD: payment method 510$',
 | 
				
			||||||
        r'^BEANCOUNT ENTRIES:$',
 | 
					        r'^BEANCOUNT ENTRIES:$',
 | 
				
			||||||
        # For each transaction, check for the date line, a metadata, and the
 | 
					        # For each transaction, check for the date line, a metadata, and the
 | 
				
			||||||
| 
						 | 
					@ -325,6 +325,29 @@ def test_outgoing_report(accrual_postings):
 | 
				
			||||||
        r'^\s+Expenses:FilingFees\s+60\.00 USD$',
 | 
					        r'^\s+Expenses:FilingFees\s+60\.00 USD$',
 | 
				
			||||||
    ])
 | 
					    ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_outgoing_report_custom_field_fallbacks(accrual_postings):
 | 
				
			||||||
 | 
					    invoice = 'rt:510/6100'
 | 
				
			||||||
 | 
					    related = core.RelatedPostings(
 | 
				
			||||||
 | 
					        post for post in accrual_postings
 | 
				
			||||||
 | 
					        if post.meta.get('invoice') == invoice
 | 
				
			||||||
 | 
					        and post.account.is_under('Assets:Receivable', 'Liabilities:Payable')
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    output = io.StringIO()
 | 
				
			||||||
 | 
					    errors = io.StringIO()
 | 
				
			||||||
 | 
					    rt_client = RTClient(want_cfs=False)
 | 
				
			||||||
 | 
					    rt_cache = rtutil.RT(rt_client)
 | 
				
			||||||
 | 
					    accrual.outgoing_report({invoice: related}, output, errors, rt_client, rt_cache)
 | 
				
			||||||
 | 
					    assert not errors.getvalue()
 | 
				
			||||||
 | 
					    rt_url = rt_client.DEFAULT_URL[:-9]
 | 
				
			||||||
 | 
					    rt_id_url = re.escape(f'<{rt_url}Ticket/Display.html?id=510>')
 | 
				
			||||||
 | 
					    contract_url = re.escape(f'<{rt_url}Ticket/Attachment/4000/4000/contract.pdf>')
 | 
				
			||||||
 | 
					    check_output(output, [
 | 
				
			||||||
 | 
					        r'^PAYMENT FOR APPROVAL:$',
 | 
				
			||||||
 | 
					        r'^REQUESTOR: Mx\. 510 <mx510@example\.org>$',
 | 
				
			||||||
 | 
					        r'^PAYMENT TO: Mx\. 510$',
 | 
				
			||||||
 | 
					        r'^PAYMENT METHOD:\s*$',
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def run_main(arglist, config):
 | 
					def run_main(arglist, config):
 | 
				
			||||||
    output = io.StringIO()
 | 
					    output = io.StringIO()
 | 
				
			||||||
    errors = io.StringIO()
 | 
					    errors = io.StringIO()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -281,6 +281,7 @@ class RTClient:
 | 
				
			||||||
                 skip_login=False,
 | 
					                 skip_login=False,
 | 
				
			||||||
                 verify_cert=True,
 | 
					                 verify_cert=True,
 | 
				
			||||||
                 http_auth=None,
 | 
					                 http_auth=None,
 | 
				
			||||||
 | 
					                 want_cfs=True,
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        self.url = url
 | 
					        self.url = url
 | 
				
			||||||
        if http_auth is None:
 | 
					        if http_auth is None:
 | 
				
			||||||
| 
						 | 
					@ -294,6 +295,7 @@ class RTClient:
 | 
				
			||||||
            self.auth_method = type(http_auth).__name__
 | 
					            self.auth_method = type(http_auth).__name__
 | 
				
			||||||
            self.login_result = True
 | 
					            self.login_result = True
 | 
				
			||||||
        self.last_login = None
 | 
					        self.last_login = None
 | 
				
			||||||
 | 
					        self.want_cfs = want_cfs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def login(self, login=None, password=None):
 | 
					    def login(self, login=None, password=None):
 | 
				
			||||||
        if login is None and password is None:
 | 
					        if login is None and password is None:
 | 
				
			||||||
| 
						 | 
					@ -339,15 +341,18 @@ class RTClient:
 | 
				
			||||||
        ticket_id_s = str(ticket_id)
 | 
					        ticket_id_s = str(ticket_id)
 | 
				
			||||||
        if ticket_id_s not in self.TICKET_DATA:
 | 
					        if ticket_id_s not in self.TICKET_DATA:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        return {
 | 
					        retval = {
 | 
				
			||||||
            'id': 'ticket/{}'.format(ticket_id_s),
 | 
					            'id': 'ticket/{}'.format(ticket_id_s),
 | 
				
			||||||
            'numerical_id': ticket_id_s,
 | 
					            'numerical_id': ticket_id_s,
 | 
				
			||||||
            'CF.{payment-method}': f'payment method {ticket_id_s}',
 | 
					 | 
				
			||||||
            'Requestors': [
 | 
					            'Requestors': [
 | 
				
			||||||
                f'mx{ticket_id_s}@example.org',
 | 
					                f'mx{ticket_id_s}@example.org',
 | 
				
			||||||
                'requestor2@example.org',
 | 
					                'requestor2@example.org',
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if self.want_cfs:
 | 
				
			||||||
 | 
					            retval['CF.{payment-method}'] = f'payment method {ticket_id_s}'
 | 
				
			||||||
 | 
					            retval['CF.{payment-to}'] = f'Hon. Mx. {ticket_id_s}'
 | 
				
			||||||
 | 
					        return retval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_user(self, user_id):
 | 
					    def get_user(self, user_id):
 | 
				
			||||||
        user_id_s = str(user_id)
 | 
					        user_id_s = str(user_id)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue