[IMP] account: edi export/import review

bzr revid: odo@openerp.com-20111005003409-7umxxyebrh6jf8r2
This commit is contained in:
Olivier Dony 2011-10-05 02:34:09 +02:00
parent 77180a5bcc
commit 05497056de
6 changed files with 189 additions and 241 deletions

View File

@ -35,5 +35,5 @@ import product
import sequence
import company
import res_currency
import edi_invoice
import edi
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -53,7 +53,7 @@ module named account_voucher.
'website': 'http://www.openerp.com',
'images' : ['images/accounts.jpeg','images/bank_statement.jpeg','images/cash_register.jpeg','images/chart_of_accounts.jpeg','images/customer_invoice.jpeg','images/journal_entries.jpeg'],
'init_xml': [],
"depends" : ["base_setup", "product", "analytic", "process","board", "email_template"],
"depends" : ["base_setup", "product", "analytic", "process", "board", "edi", "email_template"],
'update_xml': [
'security/account_security.xml',
'security/ir.model.access.csv',
@ -124,7 +124,7 @@ module named account_voucher.
'board_account_view.xml',
"wizard/account_report_profit_loss_view.xml",
"wizard/account_report_balance_sheet_view.xml",
"edi_invoice_action_data.xml",
"edi/invoice_action_data.xml",
"account_bank_view.xml",
],
'demo_xml': [

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import invoice

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
# OpenERP, Open Source Business Applications
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -20,10 +20,10 @@
##############################################################################
from osv import fields, osv, orm
from base.ir import ir_edi
from edi import EDIMixin
from tools.translate import _
class account_invoice(osv.osv, ir_edi.edi):
class account_invoice(osv.osv, EDIMixin):
_inherit = 'account.invoice'
def edi_export(self, cr, uid, records, edi_struct=None, context=None):
@ -35,24 +35,19 @@ class account_invoice(osv.osv, ir_edi.edi):
'type': True, # -> reversed at import
'internal_number': True, # -> reference at import
'comment': True,
'reference': True,
'amount_untaxed': True,
'amount_tax': True,
'amount_total': True,
'reconciled': True,
'date_invoice': True,
'date_due': True,
'partner_id': True,
'address_invoice_id': True, #only one address needed
'payment_term': True,
'currency_id': True,
'currency_id': True, # TODO: should perhaps include sample rate + rounding
'invoice_line': {
'name': True,
'origin': True,
'uos_id': True,
'product_id': True,
'price_unit': True,
'price_subtotal': True,
#'price_subtotal': True,
'quantity': True,
'discount': True,
'note': True,
@ -66,40 +61,20 @@ class account_invoice(osv.osv, ir_edi.edi):
'base_amount': True,
'tax_amount': True,
},
#'paid': True,
}
company_pool = self.pool.get('res.company')
res_company = self.pool.get('res.company')
edi_doc_list = []
for invoice in records:
# Get EDI doc based on struct. The result will also contain all metadata fields and attachments.
edi_doc = super(account_invoice,self).edi_export(cr, uid, [invoice], edi_struct, context)
if not edi_doc:
continue
edi_doc = edi_doc[0]
# Add company info and address
edi_company_document = company_pool.edi_export_address(cr, uid, [invoice.company_id], context=context)[invoice.company_id.id]
edi_doc = super(account_invoice,self).edi_export(cr, uid, [invoice], edi_struct, context)[0]
edi_doc.update({
'company_address': edi_company_document['company_address'],
#'company_logo': edi_company_document['company_logo'],#TODO
'company_address': res_company.edi_export_address(cr, uid, invoice.company_id, context=context),
#'company_logo': #TODO
})
edi_doc_list.append(edi_doc)
return edi_doc_list
def get_invoice_journal(self, cr, uid, invoice_type, context=None):
if context is None:
context = {}
account_journal_pool = self.pool.get('account.journal')
journal_context = context.copy()
journal_context.update({'type':invoice_type})
journal_id = self._get_journal(cr, uid, context=journal_context)
journal = False
if journal_id:
journal = account_journal_pool.browse(cr, uid, journal_id, context=context)
return journal
def get_tax_account(self, cr, uid, invoice_type='out_invoice', context=None):
#TOCHECK: should select account of output VAT for Customer Invoice and Input VAT for Supplier Invoice
def _edi_tax_account(self, cr, uid, invoice_type='out_invoice', context=None):
#TODO/FIXME: should select proper Tax Account
account_pool = self.pool.get('account.account')
account_ids = account_pool.search(cr, uid, [('type','<>','view'),('type','<>','income'), ('type', '<>', 'closed')])
tax_account = False
@ -107,7 +82,7 @@ class account_invoice(osv.osv, ir_edi.edi):
tax_account = account_pool.browse(cr, uid, account_ids[0])
return tax_account
def get_invoice_account(self, cr, uid, partner_id, invoice_type, context=None):
def _edi_invoice_account(self, cr, uid, partner_id, invoice_type, context=None):
partner_pool = self.pool.get('res.partner')
partner = partner_pool.browse(cr, uid, partner_id, context=context)
if invoice_type in ('out_invoice', 'out_refund'):
@ -116,43 +91,45 @@ class account_invoice(osv.osv, ir_edi.edi):
invoice_account = partner.property_account_payable
return invoice_account
def get_product_account(self, cr, uid, product_id, invoice_type, context=None):
def _edi_product_account(self, cr, uid, product_id, invoice_type, context=None):
product_pool = self.pool.get('product.product')
product = product_pool.browse(cr, uid, product_id, context=context)
account = False
if invoice_type in ('out_invoice','out_refund'):
account = product.product_tmpl_id.property_account_income
if not account:
account = product.categ_id.property_account_income_categ
account = product.property_account_income or product.categ_id.property_account_income_categ
else:
account = product.product_tmpl_id.property_account_expense
if not account:
account = product.categ_id.property_account_expense_categ
account = product.property_account_expense or product.categ_id.property_account_expense_categ
return account
def edi_import_company(self, cr, uid, edi_document, context=None):
partner_address_pool = self.pool.get('res.partner.address')
partner_pool = self.pool.get('res.partner')
company_pool = self.pool.get('res.company')
def _edi_import_company(self, cr, uid, edi_document, context=None):
self._edi_requires_attributes(('company_id','company_address','type'), edi_document)
res_partner_address = self.pool.get('res.partner.address')
res_partner = self.pool.get('res.partner')
# import company as a new partner, if type==in then supplier=1, else customer=1
# company_address data used to add address to new partner
# imported company = new partner
company_id, company_name = edi_document['company_id']
partner_id = self.edi_import_relation(cr, uid, 'res.partner', company_name,
company_id, context=context)
invoice_type = edi_document['type']
partner_value = {}
if invoice_type in ('out_invoice', 'in_refund'):
if invoice_type in ('out_invoice', 'out_refund'):
partner_value.update({'customer': True})
if invoice_type in ('in_invoice', 'out_refund'):
if invoice_type in ('in_invoice', 'in_refund'):
partner_value.update({'supplier': True})
partner_id = company_pool.edi_import_as_partner(cr, uid, edi_document, values=partner_value, context=context)
partner_id = res_partner.write(cr, uid, [partner_id], partner_value, context=context)
# partner_id field is modified to point to the new partner
res = partner_pool.address_get(cr, uid, [partner_id], ['contact', 'invoice'])
address_id = res['invoice']
partner = partner_pool.browse(cr, uid, partner_id, context=context)
partner_address = partner_address_pool.browse(cr, uid, address_id, context=context)
edi_document['partner_id'] = self.edi_m2o(cr, uid, partner, context=context)
edi_document['address_invoice_id'] = self.edi_m2o(cr, uid, partner_address, context=context)
# imported company_address = new partner address
address_info = edi_document['company_address']
address_info['partner_id'] = (company_id, company_name)
address_info['type'] = 'invoice'
address_id = res_partner_address.edi_import(cr, uid, address_info, context=context)
# modify edi_document to refer to new partner
del edi_document['company_id']
del edi_document['company_address']
partner_address = res_partner_address.browse(cr, uid, address_id, context=context)
edi_document['partner_id'] = (company_id, company_name)
edi_document['address_invoice_id'] = self.edi_m2o(cr, uid, partner_address, context=context)
return partner_id
@ -180,17 +157,18 @@ class account_invoice(osv.osv, ir_edi.edi):
"""
if context is None:
context = {}
#import company as a new partner
partner_id = self.edi_import_company(cr, uid, edi_document, context=context)
self._edi_requires_attributes(('company_id','company_address','type','invoice_line'), edi_document)
# change type: out_invoice'<->'in_invoice','out_refund'<->'in_refund'
invoice_type = edi_document['type']
invoice_type = invoice_type.startswith('in_') and invoice_type.replace('in_','out_') or invoice_type.replace('out_','in_')
edi_document['type'] = invoice_type
#import company as a new partner
partner_id = self._edi_import_company(cr, uid, edi_document, context=context)
# Set Account
invoice_account = self.get_invoice_account(cr, uid, partner_id, invoice_type, context=context)
invoice_account = self._edi_invoice_account(cr, uid, partner_id, invoice_type, context=context)
edi_document['account_id'] = invoice_account and self.edi_m2o(cr, uid, invoice_account, context=context) or False
# reference: should contain the value of the 'internal_number'
@ -201,43 +179,33 @@ class account_invoice(osv.osv, ir_edi.edi):
# internal number: reset to False, auto-generated
edi_document['internal_number'] = False
# journal_id: should be selected based on type: simply put the 'type' in the context when calling create(), will be selected correctly
journal = self.get_invoice_journal(cr, uid, invoice_type, context=context)
edi_document['journal_id'] = journal and self.edi_m2o(cr, uid, journal, context=context) or False
context.update(type=invoice_type)
# for invoice lines, the account_id value should be taken from the product's default, i.e. from the default category, as it will not be provided.
for edi_invoice_line in edi_document.get('invoice_line', []):
product_id = edi_invoice_line.get('product_id', False)
account = False
if product_id:
product_name = product_id and product_id[1]
product_id = self.edi_import_relation(cr, uid, 'product.product', product_name, context=context)
account = self.get_product_account(cr, uid, product_id, invoice_type, context=context)
# TODO: add effect of fiscal position
for edi_invoice_line in edi_document['invoice_line']:
product_info = edi_invoice_line['product_id']
product_id = self.edi_import_relation(cr, uid, 'product.product', product_info[1],
product_info[0], context=context)
account = self._edi_product_account(cr, uid, product_id, invoice_type, context=context)
# TODO: could be improved with fiscal positions perhaps
# account = fpos_obj.map_account(cr, uid, fiscal_position_id, account.id)
edi_invoice_line['account_id'] = account and self.edi_m2o(cr, uid, account, context=context) or False
edi_invoice_line['account_id'] = self.edi_m2o(cr, uid, account, context=context) if account else False
# for tax lines, we disconnect from the invoice.line, so all tax lines will be of type 'manual', and default accounts should be picked based
# on the tax config of the DB where it is imported.
tax_account = self._edi_tax_account(cr, uid, context=context)
tax_account_info = self.edi_m2o(cr, uid, tax_account, context=context)
for edi_tax_line in edi_document.get('tax_line', []):
tax_account = self.get_tax_account(cr, uid, context=context)
if tax_account:
edi_tax_line['account_id'] = self.edi_m2o(cr, uid, tax_account, context=context)
edi_tax_line['account_id'] = tax_account_info
edi_tax_line['manual'] = True
# TODO :=> payment_term: if set, create a default one based on name...
return super(account_invoice,self).edi_import(cr, uid, edi_document, context=context)
account_invoice()
class account_invoice_line(osv.osv, ir_edi.edi):
class account_invoice_line(osv.osv, EDIMixin):
_inherit='account.invoice.line'
account_invoice_line()
class account_invoice_tax(osv.osv, ir_edi.edi):
class account_invoice_tax(osv.osv, EDIMixin):
_inherit = "account.invoice.tax"
account_invoice_tax()

View File

@ -3,7 +3,7 @@
<data>
<!-- EDI Export + Send email Action -->
<record id="ir_actions_server_edi_invoice" model="ir.actions.server">
<field name="code">
<field name="code"><![CDATA[
try:
if not object.partner_id.opt_out:
web_root_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default="<WEB_ROOT_URL>")
@ -12,11 +12,11 @@ try:
tmpl = self.pool.get('ir.model.data').get_object(cr, uid, 'account', 'email_template_edi_invoice')[1]
edi_token = self.pool.get('ir.edi.document').export_edi(cr, uid, [object], context = context)[0]
context.update(edi_web_invoice_url_view='%s/web/view_edi?db=%s&token=%s' %(web_root_url,cr.dbname, edi_token))
context.update(edi_web_invoice_url_view='%s/web/view_edi?db=%s&token=%s' %(web_root_url, cr.dbname, edi_token))
self.pool.get('email.template').send_mail(cr, uid,tmpl.id,object.id,context=context)
except:
pass
</field>
]]></field>
<field eval="6" name="sequence"/>
<field name="state">code</field>
<field name="type">ir.actions.server</field>
@ -41,75 +41,75 @@ except:
<field name="subject">${object.company_id.name} Invoice (Ref ${object.number or 'n/a' })</field>
<field name="email_to">${object.address_invoice_id.email or ''}</field>
<field name="model_id" ref="account.model_account_invoice"/>
<field name="body_html">
&lt;div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, 255, 255); "&gt;
<field name="body_html"><![CDATA[
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); background-color: rgb(255, 255, 255); ">
&lt;p&gt;Hello${object.address_invoice_id.name and ' ' or ''}${object.address_invoice_id.name or ''},&lt;/p&gt;
<p>Hello${object.address_invoice_id.name and ' ' or ''}${object.address_invoice_id.name or ''},</p>
&lt;p&gt;A new invoice is available for ${object.partner_id.name}: &lt;/p&gt;
<p>A new invoice is available for ${object.partner_id.name}: </p>
&lt;p style="border-left: 1px solid #8e0000; margin-left: 30px;"&gt;
&nbsp;&nbsp;&lt;strong&gt;REFERENCES&lt;/strong&gt;&lt;br /&gt;
&nbsp;&nbsp;Invoice number: &lt;strong&gt;${object.number}&lt;/strong&gt;&lt;br /&gt;
&nbsp;&nbsp;Invoice amount: &lt;strong&gt;${object.amount_total} ${object.currency_id.name}&lt;/strong&gt;&lt;br /&gt;
&nbsp;&nbsp;Invoice date: ${object.date_invoice or 'n/a'}&lt;br /&gt;
&nbsp;&nbsp;Order reference: ${object.origin or 'n/a'}&lt;br /&gt;
&nbsp;&nbsp;Your contact: &lt;a href="mailto:${object.user_id.user_email or ''}?subject=Invoice%20${object.number}"&gt;${object.user_id.name}&lt;/a&gt;
&lt;/p&gt;
<p style="border-left: 1px solid #8e0000; margin-left: 30px;">
&nbsp;&nbsp;<strong>REFERENCES</strong><br />
&nbsp;&nbsp;Invoice number: <strong>${object.number}</strong><br />
&nbsp;&nbsp;Invoice amount: <strong>${object.amount_total} ${object.currency_id.name}</strong><br />
&nbsp;&nbsp;Invoice date: ${object.date_invoice or 'n/a'}<br />
&nbsp;&nbsp;Order reference: ${object.origin or 'n/a'}<br />
&nbsp;&nbsp;Your contact: <a href="mailto:${object.user_id.user_email or ''}?subject=Invoice%20${object.number}">${object.user_id.name}</a>
</p>
&lt;p&gt;
<p>
You can view the invoice document, download it and pay online using the following link:
&lt;/p&gt;
&lt;a style="display:block; width: 150px; height:20px; margin-left: 120px; color: #FFF; font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: bold; text-align: center; text-decoration: none !important; line-height: 1; padding: 5px 0px 0px 0px; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(142, 0, 0); border-radius: 2px 2px; background-position: 0% 0%; background-repeat: repeat no-repeat;"
href="${ctx.get('edi_web_invoice_url_view') or ''}"&gt;View Invoice&lt;/a&gt;
</p>
<a style="display:block; width: 150px; height:20px; margin-left: 120px; color: #FFF; font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: bold; text-align: center; text-decoration: none !important; line-height: 1; padding: 5px 0px 0px 0px; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(142, 0, 0); border-radius: 2px 2px; background-position: 0% 0%; background-repeat: repeat no-repeat;"
href="${ctx.get('edi_web_invoice_url_view') or ''}">View Invoice</a>
% if object.company_id.paypal_account:
&lt;br/&gt;
&lt;p&gt;It is also possible to directly pay with Paypal:&lt;/p&gt;
&lt;a style="display:block; width: 150px; height:20px; margin-left: 120px; color: #FFF; font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: bold; text-align: center; text-decoration: none !important; line-height: 1; padding: 5px 0px 0px 0px; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(142, 0, 0); border-radius: 2px 2px; background-position: 0% 0%; background-repeat: repeat no-repeat;"
<br/>
<p>It is also possible to directly pay with Paypal:</p>
<a style="display:block; width: 150px; height:20px; margin-left: 120px; color: #FFF; font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; font-size: 13px; font-weight: bold; text-align: center; text-decoration: none !important; line-height: 1; padding: 5px 0px 0px 0px; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(142, 0, 0); border-radius: 2px 2px; background-position: 0% 0%; background-repeat: repeat no-repeat;"
href="${"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=%s&amp;item_name=OpenERP%%20Invoice%%20%s&amp;invoice=%s&amp;amount=%s&amp;currency_code=%s&amp;button_subtype=services&amp;no_note=1&amp;bn=OpenERP_Invoice_PayNow_%s"%(object.company_id.paypal_account,object.number and object.number.replace('/','%2f') or '', object.number and object.number.replace('/','%2f') or '', object.amount_total, object.currency_id.name, object.currency_id.name)}"
&gt;Pay with Paypal&lt;/a&gt;
>Pay with Paypal</a>
% endif
&lt;br/&gt;
&lt;p&gt;If you have any question, do not hesitate to contact us.&lt;/p&gt;
&lt;p&gt;Thank you for choosing ${object.company_id.name or 'us'}!&lt;/p&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;div style="width: 375px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; zoom: 1; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(142, 0, 0); border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; border-bottom-right-radius: 0px 0px; border-bottom-left-radius: 0px 0px; background-position: 0% 0%; background-repeat: repeat no-repeat; "&gt;
&lt;h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 9px; padding-right: 14px; padding-bottom: 9px; padding-left: 14px; font-size: 12px; font-weight: normal; font-style: normal; color: rgb(255, 255, 255); "&gt;
&lt;strong style="text-transform:uppercase;"&gt;${object.company_id.name}&lt;/strong&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;div style="width: 347px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 12px; padding-right: 14px; padding-bottom: 12px; padding-left: 14px; overflow-x: hidden; overflow-y: hidden; zoom: 1; line-height: 16px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(242, 242, 242); "&gt;
&lt;span style="color: rgb(38, 72, 149); margin-bottom: 5px; display: block; "&gt;
<br/>
<p>If you have any question, do not hesitate to contact us.</p>
<p>Thank you for choosing ${object.company_id.name or 'us'}!</p>
<br/>
<br/>
<div style="width: 375px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; zoom: 1; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(142, 0, 0); border-top-left-radius: 5px 5px; border-top-right-radius: 5px 5px; border-bottom-right-radius: 0px 0px; border-bottom-left-radius: 0px 0px; background-position: 0% 0%; background-repeat: repeat no-repeat; ">
<h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 9px; padding-right: 14px; padding-bottom: 9px; padding-left: 14px; font-size: 12px; font-weight: normal; font-style: normal; color: rgb(255, 255, 255); ">
<strong style="text-transform:uppercase;">${object.company_id.name}</strong></h3>
</div>
<div style="width: 347px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 12px; padding-right: 14px; padding-bottom: 12px; padding-left: 14px; overflow-x: hidden; overflow-y: hidden; zoom: 1; line-height: 16px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(242, 242, 242); ">
<span style="color: rgb(38, 72, 149); margin-bottom: 5px; display: block; ">
% if object.company_id.street:
${object.company_id.street}&lt;br/&gt;
${object.company_id.street}<br/>
% endif
% if object.company_id.street2:
${object.company_id.street2}&lt;br/&gt;
${object.company_id.street2}<br/>
% endif
% if object.company_id.city or object.company_id.zip:
${object.company_id.zip} ${object.company_id.city}&lt;br/&gt;
${object.company_id.zip} ${object.company_id.city}<br/>
% endif
% if object.company_id.country_id:
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}&lt;br/&gt;
${object.company_id.state_id and ('%s, ' % object.company_id.state_id.name) or ''} ${object.company_id.country_id.name or ''}<br/>
% endif
&lt;/span&gt;
</span>
% if object.company_id.phone:
&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "&gt;
<div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">
Phone:&nbsp; ${object.company_id.phone}
&lt;/div&gt;
</div>
% endif
% if object.company_id.website:
&lt;div&gt;
Web :&nbsp;&lt;a href="${object.company_id.website}"&gt;${object.company_id.website}&lt;/a&gt;
&lt;/div&gt;
<div>
Web :&nbsp;<a href="${object.company_id.website}">${object.company_id.website}</a>
</div>
%endif
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</field>
<field name="body_text">
<p></p>
</div>
</div>
]]></field>
<field name="body_text"><![CDATA[
Hello${object.address_invoice_id.name and ' ' or ''}${object.address_invoice_id.name or ''},
A new invoice is available for ${object.partner_id.name}:
@ -154,7 +154,7 @@ Phone: ${object.company_id.phone}
% if object.company_id.website:
${object.company_id.website or ''}
% endif
</field>
]]></field>
</record>
</data>
</openerp>

View File

@ -1,38 +1,20 @@
-
I create a company for Customer
In order to test the EDI export features of Invoices
-
!record {model: res.company, id: res_company_test11}:
name: Thomson pvt. ltd.
partner_id: 1
rml_header: 1
rml_header2: 1
rml_header3: 1
currency_id: 1
First I create a draft customer invoice
-
I create a partner which is a my customer
-
!record {model: res.partner, id: res_partner_test20}:
name: Junjun wala
supplier: False
company_id: res_company_test11
opt_out: True
-
I create one customer invoice
-
!record {model: account.invoice, id: customer_invoice_test}:
!record {model: account.invoice, id: invoice_edi_1}:
journal_id: 1
partner_id: res_partner_test20
partner_id: base.res_partner_agrolait
currency_id: base.EUR
address_invoice_id: base.res_partner_address_11
company_id: res_company_test11
address_invoice_id: base.res_partner_address_8invoice
company_id: 1
account_id: account.a_pay
date_invoice: '2011-06-22'
name: selling product
type: 'out_invoice'
invoice_line:
- product_id: product.product_product_pc1
partner_id: res_partner_test20
uos_id: 1
quantity: 1.0
price_unit: 10.0
@ -40,117 +22,93 @@
account_id: account.a_pay
invoice_line:
- product_id: product.product_product_pc3
partner_id: res_partner_test20
uos_id: 1
quantity: 5.0
price_unit: 100.0
name: 'Medium PC'
account_id: account.a_pay
tax_line:
- name: sale tax
account_id: account.a_pay
manual: True
amount: 1000.00
-
I Open the Invoice
I confirm and open the invoice
-
!workflow {model: account.invoice, ref: invoice_edi_1, action: invoice_open}
-
Then I export the customer invoice
-
!python {model: edi.document}: |
invoice_pool = self.pool.get('account.invoice')
invoice = invoice_pool.browse(cr, uid, ref("invoice_edi_1"))
token = self.export_edi(cr, uid, [invoice])
assert token, 'Invalid EDI Token'
-
Then I import a sample EDI document of another customer invoice
-
!python {model: account.invoice}: |
invoices = self.browse(cr, uid, ref("customer_invoice_test"))
import netsvc
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, 'account.invoice',invoices.id,'invoice_open', cr)
-
I Testing of EDI functionality. First I export customer invoice from my company than import that invoice into customer company
-
!python {model: ir.edi.document}: |
invoice_pool = self.pool.get('account.invoice')
invoice = invoice_pool.browse(cr, uid, ref("customer_invoice_test"))
tokens = self.export_edi(cr, uid, [invoice])
assert tokens, 'Token is not generated'
-
I import of EDI document of custmer invoice
-
!python {model: ir.edi.document}: |
invoice_pool = self.pool.get('account.invoice')
edi_document = {
"__id": "account:b22acf7a-ddcd-11e0-a4db-701a04e25543.random_invoice_763jsms",
"__module": "account",
"__model": "account.invoice",
"__version": [6,1,0],
"internal_number": "SAJ/2011/002",
"company_address": {
"__id": "base:b22acf7a-ddcd-11e0-a4db-701a04e25543.main_address",
"__module": "base",
"__model": "res.partner.address",
"city": "Gerompont",
"zip": "1367",
"__last_update": False,
"country_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:base.be", "Belgium"],
"__id": "b22acf7a-ddcd-11e0-a4db-701a04e25543:base.main_address",
"country_id": ["base:b22acf7a-ddcd-11e0-a4db-701a04e25543.be", "Belgium"],
"phone": "(+32).81.81.37.00",
"street": "Chaussee de Namur 40"
},
"company_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:account.res_company_test11", "Thomson pvt. ltd."],
"currency_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:base.EUR", "EUR (\u20ac)"],
"address_invoice_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:base.res_partner_address_11", "Sebastien LANGE, France, Alencon, 1 place de l'\u00c9glise"],
"partner_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:account.res_partner_test20", "Junjun wala"],
"__attachments": [],
"__module": "account",
"amount_total": 1010.0,
"company_id": ["account:b22acf7a-ddcd-11e0-a4db-701a04e25543.res_company_test11", "Thomson pvt. ltd."],
"currency_id": ["base:b22acf7a-ddcd-11e0-a4db-701a04e25543.EUR", "EUR (€)"],
"address_invoice_id": ["base:b22acf7a-ddcd-11e0-a4db-701a04e25543.res_partner_address_11", "Sebastien LANGE, France, Alencon, 1 place de l'\u00c9glise"],
"partner_id": ["account:b22acf7a-ddcd-11e0-a4db-701a04e25543.res_partner_test20", "Junjun wala"],
"date_invoice": "2011-06-22",
"amount_untaxed": 10.0,
"name": "selling product",
"__model": "account.invoice",
"__last_update": False,
"name": "sample invoice",
"tax_line": [{
"__id": "account:b22acf7a-ddcd-11e0-a4db-701a04e25543.account_invoice_tax-4g4EutbiEMVl",
"__module": "account",
"__model": "account.invoice.tax",
"amount": 1000.0,
"manual": True,
"__id": "b22acf7a-ddcd-11e0-a4db-701a04e25543:b22acf7a-ddcd-11e0-a4db-701a04e25543:account.account_invoice_tax-4g4EutbiEMVl",
"name": "sale tax",
"__last_update": False
}],
"__id": "b22acf7a-ddcd-11e0-a4db-701a04e25543:account.customer_invoice_test",
"amount_tax": 1000.0,
"__version": [6, 1],
"type": "out_invoice",
"invoice_line": [{
"uos_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:product.product_uom_unit", "PCE"],
"name": "basic pc",
"__last_update": False,
"__module": "account",
"__model": "account.invoice.line",
"__id": "account:b22acf7a-ddcd-11e0-a4db-701a04e25543.account_invoice_line-1RP3so",
"uos_id": ["product:b22acf7a-ddcd-11e0-a4db-701a04e25543.product_uom_unit", "PCE"],
"name": "Basic PC",
"price_unit": 10.0,
"price_subtotal": 10.0,
"__id": "b22acf7a-ddcd-11e0-a4db-701a04e25543:b22acf7a-ddcd-11e0-a4db-701a04e25543:account.account_invoice_line-1RP3so-u2vV4",
"product_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:product.product_product_pc1", "[PC1] Basic PC"],
"product_id": ["product:b22acf7a-ddcd-11e0-a4db-701a04e25543.product_product_pc1", "[PC1] Basic PC"],
"quantity": 1.0
},
{
"uos_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:product.product_uom_unit", "PCE"],
"name": "Medim PC",
"__last_update": False,
"__module": "account",
"__model": "account.invoice.line",
"__id": "account:b22acf7a-ddcd-11e0-a4db-701a04e25543.account_invoice_line-u2XV5",
"uos_id": ["product:b22acf7a-ddcd-11e0-a4db-701a04e25543.product_uom_unit", "PCE"],
"name": "Medium PC",
"price_unit": 100.0,
"price_subtotal": 100.0,
"__id": "b22acf7a-ddcd-11e0-a4db-701a04e25543:b22acf7a-ddcd-11e0-a4db-701a04e25543:account.account_invoice_line-1RP3so-u2vV4",
"product_id": ["b22acf7a-ddcd-11e0-a4db-701a04e25543:product.product_product_pc3", "[PC3] Medium PC"],
"product_id": ["product:b22acf7a-ddcd-11e0-a4db-701a04e25543.product_product_pc3", "[PC3] Medium PC"],
"quantity": 5.0
}]
}
invoice_id = invoice_pool.edi_import(cr, uid, edi_document, context=context)
invoice_new = invoice_pool.browse(cr, uid, invoice_id, context=context)
assert invoice_id, 'Invoice is not imported'
-
I Checking the out invoice become in invoice or not after import
-
!python {model: account.invoice}: |
new_partner_id = self.pool.get('res.partner').name_search(cr, uid, "Thomson pvt. ltd.")
assert new_partner_id, 'Partner is not created of Supplier'
ids = self.search(cr, uid, [('partner_id','=',new_partner_id[0][0]),('reference','=',"SAJ/2011/002")])
assert ids, 'Invoice does not have created of party'
invoice_new = self.browse(cr, uid, ids[0])
invoice_id = self.edi_import(cr, uid, edi_document, context=context)
assert invoice_id, 'EDI import failed'
invoice_new = self.browse(cr, uid, invoice_id)
assert invoice_new.partner_id.supplier, 'Imported Partner is not marked as supplier'
assert invoice_new.reference == "SAJ/2011/002", "internal number is not stored in reference"
assert invoice_new.reference_type == 'none', "reference type is not set to 'None'"
assert invoice_new.reference_type == 'none', "reference type is not set to 'none'"
assert invoice_new.internal_number == False, "internal number is not reset"
assert invoice_new.journal_id.id, "journal id is not selected"
assert invoice_new.type == 'in_invoice', "Imported in voice is not supplier invoice"
assert invoice_new.type == 'in_invoice', "Invoice type was not set properly"
assert len(invoice_new.invoice_line) == 2, "invoice lines are not same"
for inv_line in invoice_new.invoice_line:
if inv_line.name == 'basic pc':
@ -162,7 +120,7 @@
assert inv_line.uos_id.name == "PCE" , "uom is not same"
assert inv_line.price_unit == 100 , "price unit is not same"
assert inv_line.quantity == 5 , "product qty is not same"
assert inv_line.price_subtotal == 100, "price sub total is not same"
assert inv_line.price_subtotal == 500, "price sub total is not same"
else:
assert 'wrong product imported in invoice lines'
for inv_tax in invoice_new.tax_line: